33 " |
33 " |
34 ! |
34 ! |
35 |
35 |
36 documentation |
36 documentation |
37 " |
37 " |
38 Streams for writing into - this implementation currently DOES change the |
38 Streams for writing into. |
|
39 WriteStreams are especially useful, if big strings are to be constructed |
|
40 from pieces - create a writeStream, add the pieces (with #nextPut or |
|
41 #nextPutAll) and finally fetch the concatenated string via #contents. |
|
42 This is much better than constructing the big string by concatenating via |
|
43 the comma (,) operator, since less intermediate garbage objects are created. |
|
44 |
|
45 This implementation currently DOES change the |
39 identity if the streamed-upon collection IF it cannot grow easily. |
46 identity if the streamed-upon collection IF it cannot grow easily. |
40 Collections which cannot grow easily are for example: Array, ByteArray and String. |
47 Collections which cannot grow easily are for example: Array, ByteArray and String. |
41 Thus it is slightly incompatible to ST-80 since 'aStream contents' does |
48 Thus it is slightly incompatible to ST-80 since 'aStream contents' does |
42 not always return the original collection. This may change. |
49 not always return the original collection. This may change. |
43 |
50 |
44 [author:] |
51 [author:] |
45 Claus Gittinger |
52 Claus Gittinger |
46 " |
53 " |
|
54 ! |
|
55 |
|
56 examples |
|
57 " |
|
58 [exBegin] |
|
59 |s| |
|
60 |
|
61 s := WriteStream on:''. |
|
62 s nextPutAll:'hello'; |
|
63 space; |
|
64 nextPutAll:'world'. |
|
65 |
|
66 s contents inspect |
|
67 [exEnd] |
|
68 |
|
69 [exBegin] |
|
70 |s| |
|
71 |
|
72 s := WriteStream on:''. |
|
73 s nextPutAll:'hello'; |
|
74 space; |
|
75 nextPutAll:'world'. |
|
76 |
|
77 Transcript nextPutLine:(s contents) |
|
78 [exEnd] |
|
79 |
|
80 [exBegin] |
|
81 |s| |
|
82 |
|
83 s := '' writeStream. |
|
84 s nextPutAll:'hello'; |
|
85 space; |
|
86 nextPutAll:'world'. |
|
87 |
|
88 Transcript nextPutLine:(s contents) |
|
89 [exEnd] |
|
90 " |
|
91 |
47 ! ! |
92 ! ! |
48 |
93 |
49 !WriteStream methodsFor:'accessing'! |
94 !WriteStream methodsFor:'accessing'! |
50 |
95 |
51 contents |
96 contents |
196 %{ /* NOCONTEXT */ |
241 %{ /* NOCONTEXT */ |
197 |
242 |
198 REGISTER int pos; |
243 REGISTER int pos; |
199 unsigned ch; |
244 unsigned ch; |
200 OBJ coll; |
245 OBJ coll; |
201 OBJ p, l, rL; |
246 OBJ p, wL, rL; |
202 int __readLimit = -1; |
247 int __readLimit = -1; |
203 |
248 |
204 coll = __INST(collection); |
249 coll = __INST(collection); |
205 p = __INST(position); |
250 p = __INST(position); |
206 |
251 |
207 if (__isNonNilObject(coll) && __isSmallInteger(p)) { |
252 if (__isNonNilObject(coll) && __isSmallInteger(p)) { |
208 pos = __intVal(p); |
253 pos = __intVal(p); |
209 l = __INST(writeLimit); |
254 wL = __INST(writeLimit); |
210 |
255 |
211 if ((l == nil) |
256 if ((wL == nil) |
212 || (__isSmallInteger(l) && (pos <= __intVal(l)))) { |
257 || (__isSmallInteger(wL) && (pos <= __intVal(wL)))) { |
213 OBJ cls; |
258 OBJ cls; |
214 |
259 |
215 cls = __qClass(coll); |
260 cls = __qClass(coll); |
216 |
261 |
217 rL = __INST(readLimit); |
262 rL = __INST(readLimit); |
219 __readLimit = __intVal(rL); |
264 __readLimit = __intVal(rL); |
220 } |
265 } |
221 |
266 |
222 if (cls == @global(String)) { |
267 if (cls == @global(String)) { |
223 if (__isCharacter(anObject) |
268 if (__isCharacter(anObject) |
|
269 && ((ch = __intVal(__characterVal(anObject))) <= 255) /* ch is unsigned */ |
224 && (pos <= __stringSize(coll))) { |
270 && (pos <= __stringSize(coll))) { |
225 ch = __intVal(_characterVal(anObject)); |
271 __StringInstPtr(coll)->s_element[pos-1] = ch; |
226 if (ch <= 255) { /* ch is unsigned */ |
272 __INST(position) = __MKSMALLINT(pos + 1); |
227 __StringInstPtr(coll)->s_element[pos-1] = ch; |
273 if ((__readLimit >= 0) && (pos >= __readLimit)) { |
228 __INST(position) = __MKSMALLINT(pos + 1); |
274 __INST(readLimit) = __MKSMALLINT(pos); |
229 if ((__readLimit >= 0) && (pos >= __readLimit)) { |
|
230 __INST(readLimit) = __MKSMALLINT(pos); |
|
231 } |
|
232 RETURN ( anObject ); |
|
233 } |
275 } |
|
276 RETURN ( anObject ); |
234 } |
277 } |
235 } else if (cls == @global(ByteArray)) { |
278 } else if (cls == @global(ByteArray)) { |
236 if (__isSmallInteger(anObject) |
279 if (__isSmallInteger(anObject) |
237 && ((ch = __intVal(anObject)) <= 255) /* ch is unsigned */ |
280 && ((ch = __intVal(anObject)) <= 255) /* ch is unsigned */ |
238 && (pos <= _byteArraySize(coll))) { |
281 && (pos <= __byteArraySize(coll))) { |
239 __ByteArrayInstPtr(coll)->ba_element[pos-1] = ch; |
282 __ByteArrayInstPtr(coll)->ba_element[pos-1] = ch; |
240 __INST(position) = __MKSMALLINT(pos + 1); |
283 __INST(position) = __MKSMALLINT(pos + 1); |
241 if ((__readLimit >= 0) && (pos >= __readLimit)) { |
284 if ((__readLimit >= 0) && (pos >= __readLimit)) { |
242 __INST(readLimit) = __MKSMALLINT(pos); |
285 __INST(readLimit) = __MKSMALLINT(pos); |
243 } |
286 } |
244 RETURN ( anObject ); |
287 RETURN ( anObject ); |
245 } |
288 } |
246 } else if (cls == @global(Array)) { |
289 } else if (cls == @global(Array)) { |
247 if (pos <= _arraySize(coll)) { |
290 if (pos <= __arraySize(coll)) { |
248 __ArrayInstPtr(coll)->a_element[pos-1] = anObject; |
291 __ArrayInstPtr(coll)->a_element[pos-1] = anObject; |
249 __STORE(coll, anObject); |
292 __STORE(coll, anObject); |
250 __INST(position) = __MKSMALLINT(pos + 1); |
293 __INST(position) = __MKSMALLINT(pos + 1); |
251 if ((__readLimit >= 0) && (pos >= __readLimit)) { |
294 if ((__readLimit >= 0) && (pos >= __readLimit)) { |
252 __INST(readLimit) = __MKSMALLINT(pos); |
295 __INST(readLimit) = __MKSMALLINT(pos); |