Mercurial > projects > ldc
comparison tango/tango/io/model/IBuffer.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: Mar 2004: Initial release | |
8 Dec 2006: Outback release | |
9 | |
10 author: Kris | |
11 | |
12 *******************************************************************************/ | |
13 | |
14 module tango.io.model.IBuffer; | |
15 | |
16 private import tango.io.model.IConduit; | |
17 | |
18 /******************************************************************************* | |
19 | |
20 Buffer is central concept in Tango I/O. Each buffer acts | |
21 as a queue (line) where items are removed from the front | |
22 and new items are added to the back. Buffers are modeled | |
23 by this interface and implemented in various ways. | |
24 | |
25 Buffer can be read from and written to directly, though | |
26 various data-converters and filters are often leveraged | |
27 to apply structure to what might otherwise be simple raw | |
28 data. | |
29 | |
30 Buffers may also be tokenized by applying an Iterator. | |
31 This can be handy when one is dealing with text input, | |
32 and/or the content suits a more fluid format than most | |
33 typical converters support. Iterator tokens are mapped | |
34 directly onto buffer content (sliced), making them quite | |
35 efficient in practice. Like other types of buffer client, | |
36 multiple iterators can be mapped onto one common buffer | |
37 and access will be serialized. | |
38 | |
39 Buffers are sometimes memory-only, in which case there | |
40 is nothing left to do when a client has consumed all the | |
41 content. Other buffers are themselves bound to an external | |
42 device called a conduit. When this is the case, a consumer | |
43 will eventually cause a buffer to reload via its associated | |
44 conduit and previous buffer content will be lost. | |
45 | |
46 A similar approach is applied to clients which populate a | |
47 buffer, whereby the content of a full buffer will be flushed | |
48 to a bound conduit before continuing. Another variation is | |
49 that of a memory-mapped buffer, whereby the buffer content | |
50 is mapped directly to virtual memory exposed via the OS. This | |
51 can be used to address large files as an array of content. | |
52 | |
53 See tango.io.Buffer for more info. | |
54 | |
55 *******************************************************************************/ | |
56 | |
57 abstract class IBuffer : IConduit, Buffered | |
58 { | |
59 alias append opCall; | |
60 alias flush opCall; | |
61 | |
62 /*********************************************************************** | |
63 | |
64 implements Buffered interface | |
65 | |
66 ***********************************************************************/ | |
67 | |
68 abstract IBuffer buffer (); | |
69 | |
70 /*********************************************************************** | |
71 | |
72 Return the backing array | |
73 | |
74 ***********************************************************************/ | |
75 | |
76 abstract void[] getContent (); | |
77 | |
78 /*********************************************************************** | |
79 | |
80 Return a void[] slice of the buffer up to the limit of | |
81 valid content. | |
82 | |
83 ***********************************************************************/ | |
84 | |
85 abstract void[] slice (); | |
86 | |
87 /*********************************************************************** | |
88 | |
89 Set the backing array with all content readable. Writing | |
90 to this will either flush it to an associated conduit, or | |
91 raise an Eof condition. Use IBuffer.clear() to reset the | |
92 content (make it all writable). | |
93 | |
94 ***********************************************************************/ | |
95 | |
96 abstract IBuffer setContent (void[] data); | |
97 | |
98 /*********************************************************************** | |
99 | |
100 Set the backing array with some content readable. Writing | |
101 to this will either flush it to an associated conduit, or | |
102 raise an Eof condition. Use IBuffer.clear() to reset the | |
103 content (make it all writable). | |
104 | |
105 ***********************************************************************/ | |
106 | |
107 abstract IBuffer setContent (void[] data, uint readable); | |
108 | |
109 /*********************************************************************** | |
110 | |
111 Append an array of data into this buffer, and flush to the | |
112 conduit as necessary. Returns a chaining reference if all | |
113 data was written; throws an IOException indicating eof or | |
114 eob if not. | |
115 | |
116 This is often used in lieu of a Writer. | |
117 | |
118 ***********************************************************************/ | |
119 | |
120 abstract IBuffer append (void* content, uint length); | |
121 | |
122 /*********************************************************************** | |
123 | |
124 Append an array of data into this buffer, and flush to the | |
125 conduit as necessary. Returns a chaining reference if all | |
126 data was written; throws an IOException indicating eof or | |
127 eob if not. | |
128 | |
129 This is often used in lieu of a Writer. | |
130 | |
131 ***********************************************************************/ | |
132 | |
133 abstract IBuffer append (void[] content); | |
134 | |
135 /*********************************************************************** | |
136 | |
137 Append another buffer to this one, and flush to the | |
138 conduit as necessary. Returns a chaining reference if all | |
139 data was written; throws an IOException indicating eof or | |
140 eob if not. | |
141 | |
142 This is often used in lieu of a Writer. | |
143 | |
144 ***********************************************************************/ | |
145 | |
146 abstract IBuffer append (IBuffer other); | |
147 | |
148 /*********************************************************************** | |
149 | |
150 Consume content from a producer | |
151 | |
152 Params: | |
153 The content to consume. This is consumed verbatim, and in | |
154 raw binary format ~ no implicit conversions are performed. | |
155 | |
156 Remarks: | |
157 This is often used in lieu of a Writer, and enables simple | |
158 classes, such as FilePath and Uri, to emit content directly | |
159 into a buffer (thus avoiding potential heap activity) | |
160 | |
161 Examples: | |
162 --- | |
163 auto path = new FilePath (somepath); | |
164 | |
165 path.produce (&buffer.consume); | |
166 --- | |
167 | |
168 ***********************************************************************/ | |
169 | |
170 abstract void consume (void[] src); | |
171 | |
172 /*********************************************************************** | |
173 | |
174 Read a chunk of data from the buffer, loading from the | |
175 conduit as necessary. The requested number of bytes are | |
176 loaded into the buffer, and marked as having been read | |
177 when the 'eat' parameter is set true. When 'eat' is set | |
178 false, the read position is not adjusted. | |
179 | |
180 Returns the corresponding buffer slice when successful, | |
181 or null if there's not enough data available (Eof; Eob). | |
182 | |
183 ***********************************************************************/ | |
184 | |
185 abstract void[] slice (uint size, bool eat = true); | |
186 | |
187 /*********************************************************************** | |
188 | |
189 Access buffer content | |
190 | |
191 Params: | |
192 dst = destination of the content | |
193 bytes = size of dst | |
194 | |
195 Returns: | |
196 A reference to the populated content | |
197 | |
198 Remarks: | |
199 Fill the provided array with content. We try to satisfy | |
200 the request from the buffer content, and read directly | |
201 from an attached conduit where more is required. | |
202 | |
203 ***********************************************************************/ | |
204 | |
205 abstract void[] readExact (void* dst, uint bytes); | |
206 | |
207 /********************************************************************** | |
208 | |
209 Fill the provided buffer. Returns the number of bytes | |
210 actually read, which will be less than dst.length when | |
211 Eof has been reached and IConduit.Eof thereafter. | |
212 | |
213 **********************************************************************/ | |
214 | |
215 abstract uint fill (void[] dst); | |
216 | |
217 /*********************************************************************** | |
218 | |
219 Exposes the raw data buffer at the current write position, | |
220 The delegate is provided with a void[] representing space | |
221 available within the buffer at the current write position. | |
222 | |
223 The delegate should return the approriate number of bytes | |
224 if it writes valid content, or IConduit.Eof on error. | |
225 | |
226 Returns whatever the delegate returns. | |
227 | |
228 ***********************************************************************/ | |
229 | |
230 abstract uint write (uint delegate (void[]) writer); | |
231 | |
232 /*********************************************************************** | |
233 | |
234 Exposes the raw data buffer at the current read position. The | |
235 delegate is provided with a void[] representing the available | |
236 data, and should return zero to leave the current read position | |
237 intact. | |
238 | |
239 If the delegate consumes data, it should return the number of | |
240 bytes consumed; or IConduit.Eof to indicate an error. | |
241 | |
242 Returns whatever the delegate returns. | |
243 | |
244 ***********************************************************************/ | |
245 | |
246 abstract uint read (uint delegate (void[]) reader); | |
247 | |
248 /*********************************************************************** | |
249 | |
250 If we have some data left after an export, move it to | |
251 front-of-buffer and set position to be just after the | |
252 remains. This is for supporting certain conduits which | |
253 choose to write just the initial portion of a request. | |
254 | |
255 Limit is set to the amount of data remaining. Position | |
256 is always reset to zero. | |
257 | |
258 ***********************************************************************/ | |
259 | |
260 abstract IBuffer compress (); | |
261 | |
262 /*********************************************************************** | |
263 | |
264 Skip ahead by the specified number of bytes, streaming from | |
265 the associated conduit as necessary. | |
266 | |
267 Can also reverse the read position by 'size' bytes. This may | |
268 be used to support lookahead-type operations. | |
269 | |
270 Returns true if successful, false otherwise. | |
271 | |
272 ***********************************************************************/ | |
273 | |
274 abstract bool skip (int size); | |
275 | |
276 /*********************************************************************** | |
277 | |
278 Support for tokenizing iterators. | |
279 | |
280 Upon success, the delegate should return the byte-based | |
281 index of the consumed pattern (tail end of it). Failure | |
282 to match a pattern should be indicated by returning an | |
283 IConduit.Eof. | |
284 | |
285 Each pattern is expected to be stripped of the delimiter. | |
286 An end-of-file condition causes trailing content to be | |
287 placed into the token. Requests made beyond Eof result | |
288 in empty matches (length == zero). | |
289 | |
290 Note that additional iterator and/or reader instances | |
291 will stay in lockstep when bound to a common buffer. | |
292 | |
293 Returns true if a token was isolated, false otherwise. | |
294 | |
295 ***********************************************************************/ | |
296 | |
297 abstract bool next (uint delegate (void[])); | |
298 | |
299 /*********************************************************************** | |
300 | |
301 Try to _fill the available buffer with content from the | |
302 specified conduit. We try to read as much as possible | |
303 by clearing the buffer when all current content has been | |
304 eaten. If there is no space available, nothing will be | |
305 read. | |
306 | |
307 Returns the number of bytes read, or Conduit.Eof. | |
308 | |
309 ***********************************************************************/ | |
310 | |
311 abstract uint fill (InputStream src); | |
312 | |
313 /*********************************************************************** | |
314 | |
315 Write as much of the buffer that the associated conduit | |
316 can consume. | |
317 | |
318 Returns the number of bytes written, or Conduit.Eof. | |
319 | |
320 ***********************************************************************/ | |
321 | |
322 abstract uint drain (OutputStream dst); | |
323 | |
324 /*********************************************************************** | |
325 | |
326 Truncate the buffer within its extent. Returns true if | |
327 the new 'extent' is valid, false otherwise. | |
328 | |
329 ***********************************************************************/ | |
330 | |
331 abstract bool truncate (uint extent); | |
332 | |
333 /*********************************************************************** | |
334 | |
335 Return count of readable bytes remaining in buffer. This is | |
336 calculated simply as limit() - position(). | |
337 | |
338 ***********************************************************************/ | |
339 | |
340 abstract uint readable (); | |
341 | |
342 /*********************************************************************** | |
343 | |
344 Return count of writable bytes available in buffer. This is | |
345 calculated simply as capacity() - limit(). | |
346 | |
347 ***********************************************************************/ | |
348 | |
349 abstract uint writable (); | |
350 | |
351 /*********************************************************************** | |
352 | |
353 Returns the limit of readable content within this buffer. | |
354 | |
355 ***********************************************************************/ | |
356 | |
357 abstract uint limit (); | |
358 | |
359 /*********************************************************************** | |
360 | |
361 Returns the total capacity of this buffer. | |
362 | |
363 ***********************************************************************/ | |
364 | |
365 abstract uint capacity (); | |
366 | |
367 /*********************************************************************** | |
368 | |
369 Returns the current position within this buffer. | |
370 | |
371 ***********************************************************************/ | |
372 | |
373 abstract uint position (); | |
374 | |
375 /*********************************************************************** | |
376 | |
377 Sets the external conduit associated with this buffer. | |
378 | |
379 Buffers do not require an external conduit to operate, but | |
380 it can be convenient to associate one. For example, methods | |
381 read and write use it to import/export content as necessary. | |
382 | |
383 ***********************************************************************/ | |
384 | |
385 abstract IBuffer setConduit (IConduit conduit); | |
386 | |
387 /*********************************************************************** | |
388 | |
389 Set output stream | |
390 | |
391 Params: | |
392 sink = the stream to attach to | |
393 | |
394 Remarks: | |
395 Sets the external output stream associated with this buffer. | |
396 | |
397 Buffers do not require an external stream to operate, but | |
398 it can be convenient to associate one. For example, methods | |
399 fill & drain use them to import/export content as necessary. | |
400 | |
401 ***********************************************************************/ | |
402 | |
403 abstract IBuffer output (OutputStream sink); | |
404 | |
405 /*********************************************************************** | |
406 | |
407 Set input stream | |
408 | |
409 Params: | |
410 source = the stream to attach to | |
411 | |
412 Remarks: | |
413 Sets the external input stream associated with this buffer. | |
414 | |
415 Buffers do not require an external stream to operate, but | |
416 it can be convenient to associate one. For example, methods | |
417 fill & drain use them to import/export content as necessary. | |
418 | |
419 ***********************************************************************/ | |
420 | |
421 abstract IBuffer input (InputStream source); | |
422 | |
423 /*********************************************************************** | |
424 | |
425 Transfer content into the provided dst. | |
426 | |
427 Params: | |
428 dst = destination of the content | |
429 | |
430 Returns: | |
431 Return the number of bytes read, which may be less than | |
432 dst.length. Eof is returned when no further content is | |
433 available. | |
434 | |
435 Remarks: | |
436 Populates the provided array with content. We try to | |
437 satisfy the request from the buffer content, and read | |
438 directly from an attached conduit when the buffer is | |
439 empty. | |
440 | |
441 ***********************************************************************/ | |
442 | |
443 abstract uint read (void[] dst); | |
444 | |
445 /*********************************************************************** | |
446 | |
447 Emulate OutputStream.write() | |
448 | |
449 Params: | |
450 src = the content to write | |
451 | |
452 Returns: | |
453 Return the number of bytes written, which will be Eof when | |
454 the content cannot be written. | |
455 | |
456 Remarks: | |
457 Appends all of dst to the buffer, flushing to an attached | |
458 conduit as necessary. | |
459 | |
460 ***********************************************************************/ | |
461 | |
462 abstract uint write (void[] src); | |
463 | |
464 /*********************************************************************** | |
465 | |
466 Exposes configured output stream | |
467 | |
468 Returns: | |
469 Returns the OutputStream associated with this buffer. Returns | |
470 null if the buffer is not attached to an output; that is, it's | |
471 not backed by some external medium. | |
472 | |
473 Remarks: | |
474 Buffers do not require an external stream to operate, but | |
475 it can be convenient to associate them. For example, methods | |
476 fill & drain use them to import/export content as necessary. | |
477 | |
478 ***********************************************************************/ | |
479 | |
480 abstract OutputStream output (); | |
481 | |
482 /*********************************************************************** | |
483 | |
484 Exposes configured input stream | |
485 | |
486 Returns: | |
487 Returns the InputStream associated with this buffer. Returns | |
488 null if the buffer is not attached to an input; that is, it's | |
489 not backed by some external medium. | |
490 | |
491 Remarks: | |
492 Buffers do not require an external stream to operate, but | |
493 it can be convenient to associate them. For example, methods | |
494 fill & drain use them to import/export content as necessary. | |
495 | |
496 ***********************************************************************/ | |
497 | |
498 abstract InputStream input (); | |
499 | |
500 /*********************************************************************** | |
501 | |
502 Throw an exception with the provided message | |
503 | |
504 ***********************************************************************/ | |
505 | |
506 abstract void error (char[] msg); | |
507 | |
508 /*********************************************************************** | |
509 | |
510 Access configured conduit | |
511 | |
512 Returns: | |
513 Returns the conduit associated with this buffer. Returns | |
514 null if the buffer is purely memory based; that is, it's | |
515 not backed by some external medium. | |
516 | |
517 Remarks: | |
518 Buffers do not require an external conduit to operate, but | |
519 it can be convenient to associate one. For example, methods | |
520 fill() & drain() use it to import/export content as necessary. | |
521 | |
522 ***********************************************************************/ | |
523 | |
524 abstract IConduit conduit (); | |
525 | |
526 /*********************************************************************** | |
527 | |
528 Return a preferred size for buffering conduit I/O. | |
529 | |
530 ***********************************************************************/ | |
531 | |
532 abstract uint bufferSize (); | |
533 | |
534 /*********************************************************************** | |
535 | |
536 Return the name of this conduit. | |
537 | |
538 ***********************************************************************/ | |
539 | |
540 abstract char[] toString (); | |
541 | |
542 /*********************************************************************** | |
543 | |
544 Is the conduit alive? | |
545 | |
546 ***********************************************************************/ | |
547 | |
548 abstract bool isAlive (); | |
549 | |
550 /*********************************************************************** | |
551 | |
552 Flush the contents of this buffer to the related conduit. | |
553 Throws an IOException on premature eof. | |
554 | |
555 ***********************************************************************/ | |
556 | |
557 abstract OutputStream flush (); | |
558 | |
559 /*********************************************************************** | |
560 | |
561 Reset position and limit to zero. | |
562 | |
563 ***********************************************************************/ | |
564 | |
565 abstract InputStream clear (); | |
566 | |
567 /*********************************************************************** | |
568 | |
569 Copy content via this buffer from the provided src | |
570 conduit. | |
571 | |
572 Remarks: | |
573 The src conduit has its content transferred through | |
574 this buffer via a series of fill & drain operations, | |
575 until there is no more content available. The buffer | |
576 content should be explicitly flushed by the caller. | |
577 | |
578 Throws an IOException on premature Eof. | |
579 | |
580 ***********************************************************************/ | |
581 | |
582 abstract OutputStream copy (InputStream src); | |
583 | |
584 /*********************************************************************** | |
585 | |
586 Release external resources | |
587 | |
588 ***********************************************************************/ | |
589 | |
590 abstract void detach (); | |
591 | |
592 /*********************************************************************** | |
593 | |
594 Close the stream | |
595 | |
596 Remarks: | |
597 Propagate request to an attached OutputStream (this is a | |
598 requirement for the OutputStream interface) | |
599 | |
600 ***********************************************************************/ | |
601 | |
602 abstract void close (); | |
603 } | |
604 | |
605 | |
606 /******************************************************************************* | |
607 | |
608 Supported by streams which are prepared to share an internal buffer | |
609 instance. This is intended to avoid a situation whereby content is | |
610 shunted unnecessarily from one buffer to another when "decorator" | |
611 streams are connected together in arbitrary ways. | |
612 | |
613 Do not implement this if the internal buffer should not be accessed | |
614 directly by another stream e.g. if wrapper methods manipulate content | |
615 on the way in or out of the buffer. | |
616 | |
617 *******************************************************************************/ | |
618 | |
619 interface Buffered | |
620 { | |
621 IBuffer buffer(); | |
622 } |