2 reset { this.pos = 0; }
4 this.pos = this.pos + n;
6 comma { this.put(Char.comma);}
7 space { this.put(Char.space); }
8 nl { this.put(Char.nl); }
9 ff { this.put(Char.ff); }
10 tab { this.put(Char.tab); }
19 collection.printItemsOn(this);
21 <<<* { arg collection;
22 collection.storeItemsOn(this);
25 readUpTo { arg delimiter = $\f;
29 if(char.isNil) { ^nil };
31 char.notNil and: { char != delimiter }
33 string = string.add(char);
39 pos_ { ^this.subclassResponsibility(thisMethod) }
42 CollStream : IOStream {
43 var <>collection, <pos = 0;
45 *new { arg collection;
46 ^super.new.collection_(collection ?? { String.new(128) })
48 *on { arg aCollection;
49 ^super.new.on(aCollection);
52 collection = aCollection;
55 reset { super.reset; collection = collection.extend(0) }
60 pos = toPos.clip(0, collection.size);
67 if (pos >= collection.size, {
71 ^collection.at(pos - 1);
75 ^collection.species.fill(n, { this.next; });
78 ^collection.copyRange(0, collection.size-1);
83 if (pos >= collection.size, {
84 pos = collection.size + 1;
85 collection = collection.add(item);
87 collection.put(pos, item);
91 putAll { arg aCollection;
92 collection = collection.overWrite(aCollection, pos);
93 pos = pos + aCollection.size;
98 // /* writes any of the following items as binary:
103 // the name of a Symbol as chars,
104 // the indexable part of any non-Slot format object,
105 // (i.e. Strings, Int8Arrays, Int16Arrays,
109 // ^this.primitiveFailed;
112 getChar { ^this.next; }
113 getInt8 { ^this.next & 255; }
114 getInt16 { ^this.getInt8 << 8 | this.getInt8; }
115 getInt32 { ^this.getInt16 << 16 | this.getInt16; }
116 getFloat { ^Float.from32Bits(this.getInt32); }
117 getDouble { ^Float.from64Bits(this.getInt32, this.getInt32); }
120 var size = this.getInt8;
121 ^String.fill(size, { this.getChar.asAscii })
124 // array should be some subclass of RawArray
126 array.readFromStream(this);
129 // collection should be an Int8Array
130 putChar { arg aChar; this.put(aChar.ascii); }
131 putInt8 { arg anInteger; this.put(anInteger & 255); }
132 putInt16 { arg anInteger;
133 this.putInt8(anInteger>>8);
134 this.putInt8(anInteger);
136 putInt16LE { arg anInteger;
137 this.putInt8(anInteger);
138 this.putInt8(anInteger>>8);
140 putInt32 { arg anInteger;
141 this.putInt8(anInteger>>24);
142 this.putInt8(anInteger>>16);
143 this.putInt8(anInteger>>8);
144 this.putInt8(anInteger);
146 putInt32LE { arg anInteger;
147 this.putInt8(anInteger);
148 this.putInt8(anInteger>>8);
149 this.putInt8(anInteger>>16);
150 this.putInt8(anInteger>>24);
152 putFloat { arg aFloat;
153 aFloat = aFloat.asFloat;
154 this.putInt32(aFloat.as32Bits);
156 putDouble { arg aFloat;
157 aFloat = aFloat.asFloat;
158 this.putInt32(aFloat.high32Bits);
159 this.putInt32(aFloat.low32Bits);
161 putFloatLE { arg aFloat;
162 aFloat = aFloat.asFloat;
163 this.putInt32LE(aFloat.as32Bits);
165 putDoubleLE { arg aFloat;
166 aFloat = aFloat.asFloat;
167 this.putInt32LE(aFloat.low32Bits);
168 this.putInt32LE(aFloat.high32Bits);
170 putString { arg aString;
171 aString.do({ arg char; this.putChar(char); });
173 putPascalString { arg aString;
174 this.putInt8(aString.size);
175 this.putString(aString);
179 LimitedWriteStream : CollStream {
180 var <>limit, <>limitFunc;
182 atLimit { ^pos >= limit }
186 if (newpos > limit, {
193 putAll { arg aCollection;
195 newpos = pos + aCollection.size;
196 if (newpos > limit, {
197 aCollection = aCollection.copyFromStart(limit - pos - 1);
198 collection = collection.overWrite(aCollection, pos);
203 collection = collection.overWrite(aCollection, pos);
214 formats = IdentityDictionary[
215 $c -> { |x| x.asCompileString },
219 //*flush { this.flushPostBuf }
226 * <<* { arg collection;
227 collection.printItemsOn(this);
229 * <<<* { arg collection;
230 collection.storeItemsOn(this);
235 * putAll { arg aCollection;
238 * comma { this.put(Char.comma);}
239 * space { this.put(Char.space); }
240 * nl { this.put(Char.nl); }
241 * ff { this.put(Char.ff); }
242 * tab { this.put(Char.tab); }
243 * close { this.flush; }
248 var <>out, <>level = 0, <>state;
251 stream = super.new.out_(out);
252 stream.state_(PrettyEcho(stream));
265 ^super.new.pretty_(pretty);
269 PrettyEcho : PrettyState {
271 // echo chars until new line
272 if ((char == $\n) || (char == $\r), {
274 pretty.state_(PrettyEat(pretty));
276 if (char == ${ , /* } */ {
278 pretty.level.do({ pretty.out.put($\t) });
279 pretty.out.put(char);
281 pretty.level = pretty.level + 1;
282 pretty.state_(PrettyEat(pretty));
284 if ( /*{*/ char == $}, {
285 pretty.level = pretty.level - 1;
287 pretty.level.do({ pretty.out.put($\t) });
288 pretty.out.put(char);
290 pretty.state_(PrettyEat(pretty));
292 pretty.out.put(char);
299 PrettyEat : PrettyState {
301 if (char == ${, /*}*/ {
302 pretty.level.do({ pretty.out.put($\t) });
303 pretty.out.put(char);
305 pretty.level = pretty.level + 1;
307 if (((char == $\n) || (char == $\r)) && (pretty.level == 0), {
310 if (char.isSpace.not, {
311 if ( /*{*/ char == $}, {
312 pretty.level = pretty.level - 1;
313 pretty.level.do({ pretty.out.put($\t) });
314 pretty.out.put(char);
317 pretty.level.do({ pretty.out.put($\t) });
318 pretty.out.put(char);
319 pretty.state_(PrettyEcho(pretty));