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 }