Mercurial > projects > ldc
comparison tango/tango/io/Conduit.d @ 132:1700239cab2e trunk
[svn r136] MAJOR UNSTABLE UPDATE!!!
Initial commit after moving to Tango instead of Phobos.
Lots of bugfixes...
This build is not suitable for most things.
author | lindquist |
---|---|
date | Fri, 11 Jan 2008 17:57:40 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
131:5825d48b27d1 | 132:1700239cab2e |
---|---|
1 /******************************************************************************* | |
2 | |
3 copyright: Copyright (c) 2004 Kris Bell. All rights reserved | |
4 | |
5 license: BSD style: $(LICENSE) | |
6 | |
7 version: Initial release: March 2004 | |
8 | |
9 author: Kris | |
10 | |
11 *******************************************************************************/ | |
12 | |
13 module tango.io.Conduit; | |
14 | |
15 private import tango.core.Exception; | |
16 | |
17 public import tango.io.model.IConduit; | |
18 | |
19 /******************************************************************************* | |
20 | |
21 Conduit abstract base-class, implementing interface IConduit. | |
22 Only the conduit-specific read(), write(), fileHandle() and | |
23 bufferSize() need to be implemented for a concrete conduit | |
24 implementation. See FileConduit for an example. | |
25 | |
26 Conduits provide virtualized access to external content, and | |
27 represent things like files or Internet connections. Conduits | |
28 expose a pair of streams, are modelled by tango.io.model.IConduit, | |
29 and are implemented via classes such as FileConduit & SocketConduit. | |
30 | |
31 Additional kinds of conduit are easy to construct: one either | |
32 subclasses tango.io.Conduit, or implements tango.io.model.IConduit. | |
33 A conduit typically reads and writes from/to an IBuffer in large | |
34 chunks, typically the entire buffer. Alternatively, one can invoke | |
35 input.read(dst[]) and/or output.write(src[]) directly. | |
36 | |
37 *******************************************************************************/ | |
38 | |
39 class Conduit : IConduit, ISelectable | |
40 { | |
41 /*********************************************************************** | |
42 | |
43 Return the name of this conduit | |
44 | |
45 ***********************************************************************/ | |
46 | |
47 abstract char[] toString (); | |
48 | |
49 /*********************************************************************** | |
50 | |
51 Return a preferred size for buffering conduit I/O | |
52 | |
53 ***********************************************************************/ | |
54 | |
55 abstract uint bufferSize (); | |
56 | |
57 /*********************************************************************** | |
58 | |
59 Models a handle-oriented device. We need to revisit this | |
60 | |
61 TODO: figure out how to avoid exposing this in the general | |
62 case | |
63 | |
64 ***********************************************************************/ | |
65 | |
66 abstract Handle fileHandle (); | |
67 | |
68 /*********************************************************************** | |
69 | |
70 Read from conduit into a target array. The provided dst | |
71 will be populated with content from the conduit. | |
72 | |
73 Returns the number of bytes read, which may be less than | |
74 requested in dst. Eof is returned whenever an end-of-flow | |
75 condition arises. | |
76 | |
77 ***********************************************************************/ | |
78 | |
79 abstract uint read (void[] dst); | |
80 | |
81 /*********************************************************************** | |
82 | |
83 Write to conduit from a source array. The provided src | |
84 content will be written to the conduit. | |
85 | |
86 Returns the number of bytes written from src, which may | |
87 be less than the quantity provided. Eof is returned when | |
88 an end-of-flow condition arises. | |
89 | |
90 ***********************************************************************/ | |
91 | |
92 abstract uint write (void [] src); | |
93 | |
94 /*********************************************************************** | |
95 | |
96 Disconnect this conduit | |
97 | |
98 ***********************************************************************/ | |
99 | |
100 abstract void detach (); | |
101 | |
102 /*********************************************************************** | |
103 | |
104 Is the conduit alive? Default behaviour returns true | |
105 | |
106 ***********************************************************************/ | |
107 | |
108 bool isAlive () | |
109 { | |
110 return true; | |
111 } | |
112 | |
113 /*********************************************************************** | |
114 | |
115 Return the host. This is part of the Stream interface | |
116 | |
117 ***********************************************************************/ | |
118 | |
119 final IConduit conduit() | |
120 { | |
121 return this; | |
122 } | |
123 | |
124 /*********************************************************************** | |
125 | |
126 clear any buffered input | |
127 | |
128 ***********************************************************************/ | |
129 | |
130 InputStream clear () {return this;} | |
131 | |
132 /*********************************************************************** | |
133 | |
134 Write buffered output | |
135 | |
136 ***********************************************************************/ | |
137 | |
138 OutputStream flush () {return this;} | |
139 | |
140 /*********************************************************************** | |
141 | |
142 Close this conduit | |
143 | |
144 Remarks: | |
145 Both input and output are detached, and are no longer usable | |
146 | |
147 ***********************************************************************/ | |
148 | |
149 final void close () | |
150 { | |
151 this.detach; | |
152 } | |
153 | |
154 /*********************************************************************** | |
155 | |
156 Return the current input stream | |
157 | |
158 ***********************************************************************/ | |
159 | |
160 final InputStream input () | |
161 { | |
162 return this; | |
163 } | |
164 | |
165 /*********************************************************************** | |
166 | |
167 Return the current output stream | |
168 | |
169 ***********************************************************************/ | |
170 | |
171 final OutputStream output () | |
172 { | |
173 return this; | |
174 } | |
175 | |
176 /*********************************************************************** | |
177 | |
178 Throw an IOException, with the provided message | |
179 | |
180 ***********************************************************************/ | |
181 | |
182 final void error (char[] msg) | |
183 { | |
184 throw new IOException (msg); | |
185 } | |
186 | |
187 /*********************************************************************** | |
188 | |
189 Transfer the content of another conduit to this one. Returns | |
190 the dst OutputStream, or throws IOException on failure. | |
191 | |
192 ***********************************************************************/ | |
193 | |
194 final OutputStream copy (InputStream src) | |
195 { | |
196 return transfer (src, this); | |
197 } | |
198 | |
199 /*********************************************************************** | |
200 | |
201 Transfer the content of one stream to another. Returns | |
202 the dst OutputStream, and throws IOException on failure. | |
203 Queries dst to identify what size of buffer to utilize. | |
204 | |
205 ***********************************************************************/ | |
206 | |
207 static OutputStream transfer (InputStream src, OutputStream dst) | |
208 { | |
209 uint len = 0; | |
210 auto con = dst.conduit; | |
211 auto tmp = new byte [con.bufferSize]; | |
212 while ((len = src.read(tmp)) != IConduit.Eof) | |
213 { | |
214 auto p = tmp.ptr; | |
215 for (uint j; len > 0; len -= j, p += j) | |
216 if ((j = dst.write (p[0..len])) is IConduit.Eof) | |
217 con.error ("Conduit.copy :: Eof while writing to: "~con.toString); | |
218 } | |
219 delete tmp; | |
220 return dst; | |
221 } | |
222 } | |
223 | |
224 | |
225 /******************************************************************************* | |
226 | |
227 Base class for input stream filtering | |
228 | |
229 *******************************************************************************/ | |
230 | |
231 class InputFilter : InputStream | |
232 { | |
233 protected InputStream host; | |
234 | |
235 /*********************************************************************** | |
236 | |
237 Attach to the provided stream | |
238 | |
239 ***********************************************************************/ | |
240 | |
241 this (InputStream host) | |
242 { | |
243 assert (host, "input stream host cannot be null"); | |
244 this.host = host; | |
245 } | |
246 | |
247 /*********************************************************************** | |
248 | |
249 Return the hosting conduit | |
250 | |
251 ***********************************************************************/ | |
252 | |
253 IConduit conduit () | |
254 { | |
255 return host.conduit; | |
256 } | |
257 | |
258 /*********************************************************************** | |
259 | |
260 Read from conduit into a target array. The provided dst | |
261 will be populated with content from the conduit. | |
262 | |
263 Returns the number of bytes read, which may be less than | |
264 requested in dst. Eof is returned whenever an end-of-flow | |
265 condition arises. | |
266 | |
267 ***********************************************************************/ | |
268 | |
269 uint read (void[] dst) | |
270 { | |
271 return host.read (dst); | |
272 } | |
273 | |
274 /*********************************************************************** | |
275 | |
276 Clear any buffered content | |
277 | |
278 ***********************************************************************/ | |
279 | |
280 InputStream clear () | |
281 { | |
282 host.clear; | |
283 return this; | |
284 } | |
285 | |
286 /*********************************************************************** | |
287 | |
288 Close the input | |
289 | |
290 ***********************************************************************/ | |
291 | |
292 void close () | |
293 { | |
294 host.close; | |
295 } | |
296 } | |
297 | |
298 | |
299 /******************************************************************************* | |
300 | |
301 Base class for output stream filtering | |
302 | |
303 *******************************************************************************/ | |
304 | |
305 class OutputFilter : OutputStream | |
306 { | |
307 protected OutputStream host; | |
308 | |
309 /*********************************************************************** | |
310 | |
311 Attach to the provided stream | |
312 | |
313 ***********************************************************************/ | |
314 | |
315 this (OutputStream host) | |
316 { | |
317 assert (host, "output stream host cannot be null"); | |
318 this.host = host; | |
319 } | |
320 | |
321 /*********************************************************************** | |
322 | |
323 Return the hosting conduit | |
324 | |
325 ***********************************************************************/ | |
326 | |
327 IConduit conduit () | |
328 { | |
329 return host.conduit; | |
330 } | |
331 | |
332 /*********************************************************************** | |
333 | |
334 Write to conduit from a source array. The provided src | |
335 content will be written to the conduit. | |
336 | |
337 Returns the number of bytes written from src, which may | |
338 be less than the quantity provided. Eof is returned when | |
339 an end-of-flow condition arises. | |
340 | |
341 ***********************************************************************/ | |
342 | |
343 uint write (void[] src) | |
344 { | |
345 return host.write (src); | |
346 } | |
347 | |
348 /*********************************************************************** | |
349 | |
350 Emit/purge buffered content | |
351 | |
352 ***********************************************************************/ | |
353 | |
354 OutputStream flush () | |
355 { | |
356 host.flush; | |
357 return this; | |
358 } | |
359 | |
360 /*********************************************************************** | |
361 | |
362 Close the output | |
363 | |
364 ***********************************************************************/ | |
365 | |
366 void close () | |
367 { | |
368 host.close; | |
369 } | |
370 | |
371 /*********************************************************************** | |
372 | |
373 Transfer the content of another conduit to this one. Returns | |
374 a reference to this class, or throws IOException on failure. | |
375 | |
376 ***********************************************************************/ | |
377 | |
378 OutputStream copy (InputStream src) | |
379 { | |
380 return Conduit.transfer (src, this); | |
381 } | |
382 } | |
383 | |
384 |