Mercurial > projects > ldc
comparison tango/tango/io/GrowBuffer.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.GrowBuffer; | |
14 | |
15 private import tango.io.Buffer; | |
16 | |
17 public import tango.io.model.IBuffer; | |
18 | |
19 /******************************************************************************* | |
20 | |
21 Subclass to provide support for content growth. This is handy when | |
22 you want to keep a buffer around as a scratchpad. | |
23 | |
24 *******************************************************************************/ | |
25 | |
26 class GrowBuffer : Buffer | |
27 { | |
28 private uint increment; | |
29 | |
30 alias Buffer.slice slice; | |
31 alias Buffer.append append; | |
32 | |
33 /*********************************************************************** | |
34 | |
35 Create a GrowBuffer with the specified initial size. | |
36 | |
37 ***********************************************************************/ | |
38 | |
39 this (uint size = 1024, uint increment = 1024) | |
40 { | |
41 super (size); | |
42 | |
43 assert (increment >= 32); | |
44 this.increment = increment; | |
45 } | |
46 | |
47 /*********************************************************************** | |
48 | |
49 Create a GrowBuffer with the specified initial size. | |
50 | |
51 ***********************************************************************/ | |
52 | |
53 this (IConduit conduit, uint size = 1024) | |
54 { | |
55 this (size, size); | |
56 setConduit (conduit); | |
57 } | |
58 | |
59 /*********************************************************************** | |
60 | |
61 Read a chunk of data from the buffer, loading from the | |
62 conduit as necessary. The specified number of bytes is | |
63 loaded into the buffer, and marked as having been read | |
64 when the 'eat' parameter is set true. When 'eat' is set | |
65 false, the read position is not adjusted. | |
66 | |
67 Returns the corresponding buffer slice when successful. | |
68 | |
69 ***********************************************************************/ | |
70 | |
71 override void[] slice (uint size, bool eat = true) | |
72 { | |
73 if (size > readable) | |
74 { | |
75 if (source is null) | |
76 error (underflow); | |
77 | |
78 if (size + index > dimension) | |
79 makeRoom (size); | |
80 | |
81 // populate tail of buffer with new content | |
82 do { | |
83 if (fill(source) is IConduit.Eof) | |
84 error (eofRead); | |
85 } while (size > readable); | |
86 } | |
87 | |
88 uint i = index; | |
89 if (eat) | |
90 index += size; | |
91 return data [i .. i + size]; | |
92 } | |
93 | |
94 /*********************************************************************** | |
95 | |
96 Append an array of data to this buffer. This is often used | |
97 in lieu of a Writer. | |
98 | |
99 ***********************************************************************/ | |
100 | |
101 override IBuffer append (void *src, uint length) | |
102 { | |
103 if (length > writable) | |
104 makeRoom (length); | |
105 | |
106 copy (src, length); | |
107 return this; | |
108 } | |
109 | |
110 /*********************************************************************** | |
111 | |
112 Try to fill the available buffer with content from the | |
113 specified conduit. | |
114 | |
115 Returns the number of bytes read, or IConduit.Eof | |
116 | |
117 ***********************************************************************/ | |
118 | |
119 override uint fill (InputStream src) | |
120 { | |
121 if (writable <= increment/8) | |
122 makeRoom (increment); | |
123 | |
124 return write (&src.read); | |
125 } | |
126 | |
127 /*********************************************************************** | |
128 | |
129 Expand and consume the conduit content, up to the maximum | |
130 size indicated by the argument or until conduit.Eof | |
131 | |
132 Returns the number of bytes in the buffer | |
133 | |
134 ***********************************************************************/ | |
135 | |
136 uint fill (uint size = uint.max) | |
137 { | |
138 while (readable < size) | |
139 if (fill(source) is IConduit.Eof) | |
140 break; | |
141 return readable; | |
142 } | |
143 | |
144 /*********************************************************************** | |
145 | |
146 make some room in the buffer | |
147 | |
148 ***********************************************************************/ | |
149 | |
150 private uint makeRoom (uint size) | |
151 { | |
152 if (size < increment) | |
153 size = increment; | |
154 | |
155 dimension += size; | |
156 data.length = dimension; | |
157 return writable(); | |
158 } | |
159 } |