author | Martin Kobetic |
Sun, 17 Nov 2013 00:23:18 -0500 | |
changeset 147 | bd6be28aa924 |
parent 136 | 69496d69c4b5 |
permissions | -rw-r--r-- |
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
1 |
"{ Package: 'stx:goodies/xtreams/transforms' }"! |
10 | 2 |
|
3 |
!Xtreams::ReadStream methodsFor:'transforming'! |
|
4 |
||
5 |
collecting: aBlock |
|
6 |
"Transform each element using #collect: style block." |
|
7 |
" aBlock <BlockClosure> a #collect: style block used to tranform each element |
|
8 |
^<CollectReadSteam> |
|
9 |
"" |
|
10 |
((1 to: 5) reading collecting: [ :e | e * e ]) rest |
|
11 |
"" |
|
12 |
((65 to: 90) reading collecting: [ :e | e asCharacter ]) contentsSpecies: String; rest |
|
13 |
" |
|
14 |
^CollectReadStream on: self block: aBlock |
|
15 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
16 |
|
10 | 17 |
!Xtreams::ReadStream methodsFor:'transforming'! |
18 |
||
19 |
depairing |
|
20 |
"Transform a stream of associations in to a stream of elements made up of the key and value association components." |
|
21 |
||
22 |
^self transforming: [:in :out | |
|
23 |
| association | |
|
24 |
association := in get. |
|
25 |
out put: association key. |
|
26 |
out put: association value] |
|
27 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
28 |
|
10 | 29 |
!Xtreams::ReadStream methodsFor:'transforming'! |
30 |
||
31 |
doing: aBlock |
|
32 |
"Perform and action with each passing element using #do: style block." |
|
33 |
" aBlock <BlockClosure> a #do: style block invoked with each element as it passes through the stream |
|
34 |
^<CollectReadSteam> |
|
35 |
"" |
|
36 |
((1 to: 5) reading doing: [ :e | Transcript space; print: e * e ]) rest |
|
37 |
" |
|
38 |
^self collecting: [:each | (aBlock value: each). each] |
|
39 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
40 |
|
10 | 41 |
!Xtreams::ReadStream methodsFor:'transforming'! |
42 |
||
43 |
duplicating: aWriteStream |
|
44 |
"Duplicate all the contents written into @aWriteStream" |
|
45 |
" aWriteStream <WriteStream> a stream to copy into |
|
46 |
^<DuplicatingReadSteam> |
|
47 |
"" |
|
48 |
| copy | |
|
49 |
copy := ByteArray new writing. |
|
50 |
((0 to: 15) reading duplicating: copy) rest -> copy conclusion |
|
51 |
" |
|
52 |
^DuplicateReadStream on: self duplicate: aWriteStream |
|
53 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
54 |
|
10 | 55 |
!Xtreams::ReadStream methodsFor:'transforming'! |
56 |
||
57 |
encoding: anEncoding |
|
58 |
"Transform bytes into characters using @anEncoding such as #utf8 or #ascii, etc. Any encoding supported by StreamEncoder is allowed. |
|
59 |
The encoding steam also performs automatic line end conversion from arbitrary platform convention to CRs, unless set into a transparent mode" |
|
60 |
" anEncoding <Symbol> encoding identifier recognized by StreamEncoder class>>new: |
|
61 |
^<EncodedReadStream> |
|
62 |
"" |
|
63 |
((65 to: 90) reading encoding: #ascii) rest |
|
64 |
"" |
|
65 |
| crlf text | |
|
66 |
crlf := String with: Character cr with: Character lf. |
|
67 |
text := ('Hello', crlf, 'World') asByteArrayEncoding: #ascii. |
|
68 |
(text reading encoding: #ascii) rest. |
|
69 |
(text reading encoding: #ascii) setLineEndTransparent; rest |
|
70 |
" |
|
71 |
^EncodeReadStream on: self encoding: anEncoding |
|
72 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
73 |
|
10 | 74 |
!Xtreams::ReadStream methodsFor:'transforming'! |
75 |
||
76 |
encodingBase64 |
|
124
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
77 |
"Decodes characters of base-64 encoding into bytes. Ignores any intervening whitespace. |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
78 |
Automatically ends the stream if it encounters final padding characters $=." |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
79 |
" ^<TransformReadStream>" |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
80 |
" |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
81 |
'AAECAwQFBgcICQo= and the rest should be ignored' reading encodingBase64 rest |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
82 |
" |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
83 |
| map cache | |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
84 |
map := [ :char | ('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' indexOf: char) - 1 ]. |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
85 |
cache := String new: 4. |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
86 |
^(self transforming: [ :in :out || count end block filter | |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
87 |
filter := in rejecting: #isSeparator. |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
88 |
count := [ filter read: 4 into: cache at: 1. 4 ] on: Incomplete do: [ :incomplete | incomplete count]. |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
89 |
count isZero ifTrue: [ Incomplete zero raise ]. |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
90 |
(end := cache indexOf: $=) isZero ifFalse: [ count := count min: end - 1 ]. |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
91 |
count < 2 ifTrue: [ Incomplete zero signal ]. |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
92 |
block := (1 to: 4) inject: 0 into: [ :total :i || sextet | |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
93 |
sextet := count < i ifTrue: [ 0 ] ifFalse: [ map value: (cache at: i) ]. |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
94 |
sextet negative ifTrue: [ count := i ]. |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
95 |
(total bitShift: 6) + sextet ]. |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
96 |
2 to: count do: [ :i | out put: ((block bitShift: (i - 4) * 8) bitAnd: 255) ]. |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
97 |
count < 4 ifTrue: [ (Incomplete count: count) raise ] ]) |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
98 |
buffer: (RingBuffer on: (ByteArray new: 3)); |
1afacc9c2a6f
* fixed up ReadStream>>encodingBase64 (replace reference to ByteString with String)
joe
parents:
111
diff
changeset
|
99 |
yourself |
10 | 100 |
! ! |
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
101 |
|
10 | 102 |
!Xtreams::ReadStream methodsFor:'transforming'! |
103 |
||
104 |
encodingHex |
|
105 |
"Decodes bytes hex characters." |
|
106 |
" ^<TransformReadStream>" |
|
107 |
" |
|
108 |
(ByteArray withAll: (1 to: 20)) reading encodingHex rest |
|
109 |
" |
|
110 |
| i2c | |
|
111 |
i2c := [ :i | '0123456789abcdef' at: i + 1 ]. |
|
112 |
^(self transforming: [ :in :out || byte | |
|
113 |
byte := in get. |
|
114 |
out put: (i2c value: (byte bitShift: -4)). |
|
115 |
out put: (i2c value: (byte bitAnd: 15)) ]) |
|
116 |
contentsSpecies: ByteString; |
|
117 |
yourself |
|
118 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
119 |
|
10 | 120 |
!Xtreams::ReadStream methodsFor:'transforming'! |
121 |
||
122 |
injecting: initialObject into: aBlock |
|
123 |
"Accumulates a running value combined with each passing element using the binary aBlock. aBlock takes the result of the last evaluation and the next element as its arguments. Notable difference from the collection analog is that the streaming variant is a stream of all the intermediate values of the running value." |
|
124 |
" initialObject <Object> initial value used as the previous result for the evaluation of the first element |
|
125 |
aBlock <BlockClosure> binary block combining the value of each element with previous result of its evaluation |
|
126 |
^<CollectingReadStream>" |
|
127 |
" |
|
128 |
((1 to: 10) reading injecting: 0 into: [ :total :each | each + total ]) rest |
|
129 |
" |
|
130 |
| nextObject | |
|
131 |
nextObject := initialObject. |
|
132 |
^self collecting: [:each | nextObject := aBlock cull: nextObject cull: each] |
|
133 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
134 |
|
72 | 135 |
!Xtreams::ReadStream methodsFor:'interpreting'! |
10 | 136 |
|
72 | 137 |
interpreting: type |
138 |
"Converts bytes from a binary source according to provided @type. It produces elements of corresponding class, e.g. #float -> Float, #double -> Double, etc. Supported types are defined by the Interpretations shared class variable. |
|
139 |
"" type <Symbol> identifies a (primitive) CType, e.g. #float, #long (mapped via Interpretations) |
|
140 |
^ <InterpretedReadStream> |
|
141 |
"" |
|
142 |
| doubles bytes | |
|
143 |
doubles := [ Random new next ] reading. |
|
144 |
bytes := (ByteArray new writing interpreting: #double) |
|
145 |
write: 10 from: doubles; |
|
146 |
close; |
|
147 |
terminal. |
|
148 |
(bytes reading interpreting: #double) read: 10 |
|
149 |
" |
|
150 |
^self interpreting: type cacheSize: 1 |
|
151 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
152 |
|
72 | 153 |
!Xtreams::ReadStream methodsFor:'interpreting'! |
154 |
||
155 |
interpreting: type cacheSize: size |
|
156 |
"Converts bytes from a binary source according to provided @type. It produces elements of corresponding class, e.g. #float -> Float, #double -> Double, etc. Supported types are defined on class side of InterpretedBytes. |
|
157 |
"" type <Symbol> identifies a (primitive) CType, e.g. #float, #long (mapped via InterpretatedBytes) |
|
158 |
size <Integer> requested cache size (in number of elements) |
|
159 |
^ <InterpretedReadStream> |
|
160 |
"" |
|
161 |
| doubles bytes | |
|
162 |
doubles := [ Random new next ] reading. |
|
163 |
bytes := (ByteArray new writing interpreting: #double cacheSize: 10) |
|
164 |
write: 10 from: doubles; |
|
165 |
close; |
|
166 |
terminal. |
|
167 |
(bytes reading interpreting: #double) read: 10 |
|
168 |
" |
|
169 |
^InterpretedReadStream on: self type: type cacheSize: size |
|
170 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
171 |
|
72 | 172 |
!Xtreams::ReadStream methodsFor:'interpreting'! |
173 |
||
174 |
interpreting: reader size: byteSize |
|
175 |
"Converts bytes from a binary source according to provided @reader block. The block is evaluated with an instance of InterpretedBytes and and index into it from which it should use byteSize bytes to make an object to return. |
|
176 |
"" reader <BlockClosure> reading block, e.g. [ :b :i | (b at: i) @ (b at: i + 1) ] |
|
177 |
byteSize <Integer> byte size of an element |
|
178 |
^ <InterpretedReadStream> |
|
179 |
"" |
|
180 |
| doubles bytes | |
|
181 |
doubles := [ Random new next ] reading. |
|
182 |
bytes := (ByteArray new writing interpreting: #double) |
|
183 |
write: 10 from: doubles; |
|
184 |
close; |
|
185 |
terminal. |
|
186 |
(bytes reading interpreting: [ :b :i | (b floatAt: i) @ (b floatAt: i + 4) ] size: 8) read: 5 |
|
187 |
" |
|
188 |
^InterpretedReadStream on: self bytesPerElement: byteSize contentsSpecies: Array operation: reader cacheSize: 1 |
|
189 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
190 |
|
72 | 191 |
!Xtreams::ReadStream methodsFor:'interpreting'! |
192 |
||
193 |
interpreting: reader size: byteSize cacheSize: cacheSize |
|
194 |
"Converts bytes from a binary source according to provided @reader block. The block is evaluated with an instance of InterpretedBytes and and index into it from which it should use byteSize bytes to make an object to return. |
|
195 |
"" reader <BlockClosure> reading block, e.g. [ :b :i | (b at: i) @ (b at: i + 1) ] |
|
196 |
byteSize <Integer> byte size of an element |
|
197 |
cacheSize <Integer> requested cache size (in number of elements) |
|
198 |
^ <InterpretedReadStream> |
|
199 |
"" |
|
200 |
| points bytes | |
|
201 |
points := Random new reading transforming: [ :in :out | out put: in get @ in get ]. |
|
202 |
bytes := (ByteArray new writing interpreting: [ :b :i :o | (b floatAt: i put: o x) @ (b floatAt: i + 4 put: o y) ] size: 8 ) |
|
203 |
write: 10 from: points; |
|
204 |
close; |
|
205 |
terminal. |
|
206 |
(bytes reading interpreting: [ :b :i | (b floatAt: i) @ (b floatAt: i + 4) ] size: 8 cacheSize: 5) read: 5 |
|
207 |
" |
|
208 |
^InterpretedReadStream on: self bytesPerElement: byteSize contentsSpecies: Array operation: reader cacheSize: cacheSize |
|
209 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
210 |
|
72 | 211 |
!Xtreams::ReadStream methodsFor:'interpreting'! |
212 |
||
213 |
marshaling |
|
214 |
"Marshaling streams are used to encode arbitrary smalltalk objects into a sequence of bytes suitable for binary storage or transport. The format of the binary encoding is defined by an ObjectMarshaler and is identified by particular version ID. A marshaling read stream decodes objects from a binary source previously encoded by a marshaling write stream. |
|
215 |
"" ^ <ObjectReadSteam> |
|
216 |
"" |
|
217 |
| rectangle bytes | |
|
218 |
rectangle := 5 @ 5 extent: 5 @ 5. |
|
219 |
bytes := ByteArray new writing marshaling put: rectangle; conclusion. |
|
220 |
bytes reading marshaling get |
|
221 |
" |
|
222 |
^ObjectReadStream on: self |
|
223 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
224 |
|
72 | 225 |
!Xtreams::ReadStream methodsFor:'interpreting'! |
226 |
||
227 |
marshaling: aMarshaler |
|
228 |
"Marshaling streams are used to encode arbitrary smalltalk objects into a sequence of bytes suitable for binary storage or transport. The format of the binary encoding is defined by an ObjectMarshaler and is identified by particular version ID. Custom marshaling schemes can be derived by subclassing ObjectMarshaler. Custom schemes must declare their own (unique) version ID. This method allows to employ a cusomt marshaler instead of the default one (STST2.0). |
|
229 |
A marshaling read stream decodes objects from a binary source previously encoded by a marshaling write stream. |
|
230 |
"" aMarshaler <ObjectMarshaler> implements custom marshaling format |
|
231 |
^ <ObjectReadSteam> |
|
232 |
"" |
|
233 |
| rectangle bytes | |
|
234 |
rectangle := 5 @ 5 extent: 5 @ 5. |
|
235 |
bytes := (ByteArray new writing marshaling: ObjectMarshaler new) put: rectangle; conclusion. |
|
236 |
bytes reading marshaling get |
|
237 |
" |
|
238 |
^ObjectReadStream on: self marshaler: aMarshaler |
|
239 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
240 |
|
10 | 241 |
!Xtreams::ReadStream methodsFor:'transforming'! |
242 |
||
243 |
monitoring: aNotificationBlock every: aNotificationInterval |
|
244 |
"Monitor the through-put of the receiver." |
|
245 |
" aNotificationBlock <BlockClosure> the block to execute when notifying |
|
246 |
aNotificationInterval <Duration> how often to notify |
|
247 |
^<PositionReadSubstream> |
|
248 |
" |
|
249 |
||
250 |
" |
|
251 |
| monitor | |
|
252 |
monitor := ObjectMemory imageFilename reading |
|
253 |
monitoring: [:totalTransferred :deltaTransferred :elapsedMicroseconds | |
|
254 |
throughputSpeed := deltaTransferred. |
|
255 |
averageSpeed := (totalTransferred / elapsedMicroseconds) * 1000000. |
|
256 |
Transcript writing cr; |
|
257 |
write: 'average speed: '; print: averageSpeed asFloat; |
|
258 |
write: ' through-put speed: '; print: throughputSpeed asFloat; |
|
259 |
write: ' elapsed-time: '; print: elapsedMicroseconds / 1000000.0] |
|
260 |
every: 1 milliseconds. |
|
261 |
[monitor rest] ensure: [monitor close]. |
|
262 |
" |
|
263 |
||
264 |
| previousPosition timer start notifyBlock monitoring notifyProcess notifyFinished | |
|
265 |
||
266 |
start := Time microsecondClock. |
|
267 |
previousPosition := 0. |
|
268 |
monitoring := nil. |
|
269 |
timer := nil. |
|
270 |
notifyFinished := false. |
|
271 |
||
272 |
notifyBlock := [ |
|
273 |
aNotificationBlock cull: monitoring position cull: monitoring position - previousPosition cull: Time microsecondClock - start. |
|
274 |
previousPosition := monitoring position]. |
|
275 |
||
276 |
notifyProcess := nil. |
|
277 |
notifyProcess := [ |
|
278 |
[notifyBlock value. notifyFinished] whileFalse: [notifyProcess suspend]] newProcess. |
|
279 |
notifyProcess priority: ((Processor activeProcess priority + 1) min: 99). |
|
280 |
||
281 |
monitoring := self closing: [ |
|
282 |
timer stop. |
|
283 |
notifyProcess resume. |
|
284 |
notifyFinished := true. |
|
285 |
notifyProcess resume. |
|
286 |
self close]. |
|
287 |
||
288 |
timer := Timer every: aNotificationInterval resume: notifyProcess. |
|
289 |
^monitoring |
|
290 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
291 |
|
10 | 292 |
!Xtreams::ReadStream methodsFor:'transforming'! |
293 |
||
294 |
pairing |
|
295 |
"Transform a stream of elements in to a stream of associations between even+odd elements of the stream. This expects the stream to have an even number of elements" |
|
296 |
||
297 |
^self transforming: [:in :out | out put: (Association key: in get value: in get)] |
|
298 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
299 |
|
72 | 300 |
!Xtreams::ReadStream methodsFor:'transforming'! |
40 | 301 |
|
72 | 302 |
positioning |
303 |
"If necessary add positioning layer. Note that positiong layer employs buffering to implement the positioning ability. The default buffering strategy will grow the buffer up to the full size of the underlying stream if not released. Consequently other Buffer types might be more suitable for specific circumstances, e.g. if only last n elements need to be buffered, a fixed size RingBuffer can be substitued with #buffer: accessor." |
|
304 |
" ^ <ReadStream> a positionable read stream |
|
305 |
"" |
|
306 |
[ Time now ] reading positioning ++ 3; -- 2; get |
|
307 |
" |
|
308 |
^self isPositionable |
|
309 |
ifTrue: [self] |
|
310 |
ifFalse: [PositionReadStream on: self] |
|
311 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
312 |
|
10 | 313 |
!Xtreams::ReadStream methodsFor:'transforming'! |
314 |
||
315 |
rejecting: aBlock |
|
316 |
"Filters elements from the source using aBlock. aBlock has the same form and semantics as the #reject: block on collections." |
|
317 |
" aBlock <BlockClosure> usual #reject: style block used to filter the elements passing through |
|
318 |
^<TransformReadStream>" |
|
319 |
" |
|
320 |
((1 to: 10) reading rejecting: [ :e | e odd ]) rest |
|
321 |
" |
|
322 |
^self transforming: [:input :output | |
|
323 |
| value | |
|
324 |
[value := input get. |
|
325 |
aBlock cull: value] whileTrue. |
|
326 |
output put: value] |
|
327 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
328 |
|
10 | 329 |
!Xtreams::ReadStream methodsFor:'transforming'! |
330 |
||
331 |
selecting: aBlock |
|
332 |
"Filters elements from the source using aBlock. aBlock has the same form and semantics as the #select: block on collections." |
|
333 |
" aBlock <BlockClosure> usual #select: style block used to filter the elements passing through |
|
334 |
^<TransformReadStream>" |
|
335 |
" |
|
336 |
((1 to: 10) reading selecting: [ :e | e odd ]) rest |
|
337 |
" |
|
338 |
^self transforming: [:input :output | |
|
339 |
| value | |
|
340 |
[value := input get. |
|
341 |
aBlock cull: value] whileFalse. |
|
342 |
output put: value] |
|
343 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
344 |
|
10 | 345 |
!Xtreams::ReadStream methodsFor:'transforming'! |
346 |
||
347 |
transforming: aBlock |
|
348 |
"This is the most general form of transform stream. The block receives two streams, the source (input) and a virtual stream of elements to be produced by the stream (output). The block can read arbitrary number of elements from input (including none) and write arbitrary number of elements into the output (including none). The block will be invoked as many times as necessary to produce the required number of elements, or until an Incomplete is raised. Consequently if the block handles Incomplete from the input, it has to raise another Incomplete at some point, otherwise the stream will never end. |
|
349 |
Note that if the contentSpecies of the source doesn't fit the output of the transformation, the contents species of the transform stream has to be set explicitly. |
|
350 |
"" aBlock <BlockClosure> binary transformation block that reads elements from input (first argument) and writes elements into output (second argument) |
|
351 |
^<TransformReadStream> |
|
352 |
"" Convert text into a stream of words |
|
353 |
('hello world!! bye world!!' reading transforming: [ :in :out || word char | |
|
354 |
word := String new writing. |
|
355 |
[ [ (char := in get) = Character space ] whileFalse: [ word put: char ]. |
|
356 |
] ensure: [ out put: (word close; destination) ] ] |
|
357 |
) contentsSpecies: Array; |
|
358 |
rest |
|
359 |
"" Convert a hex-string into a byte array (2 characters per byte) |
|
360 |
| c2d | |
|
361 |
c2d := [ :char | ('0123456789abcdef' indexOf: char) - 1 ]. |
|
362 |
('0123456789abcdef' reading transforming: [ :in :out | |
|
363 |
out put: (c2d value: in get) * 16 + (c2d value: in get) ] |
|
364 |
) buffer: (RingBuffer on: (ByteArray new: 1)); |
|
365 |
rest |
|
366 |
" |
|
367 |
^TransformReadStream on: self block: aBlock |
|
368 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
369 |
|
72 | 370 |
!Xtreams::WriteStream methodsFor:'transforming'! |
59 | 371 |
|
372 |
collecting: aBlock |
|
373 |
"Transform each written element using #collect: style block." |
|
374 |
" aBlock <BlockClosure> a #collect: style block used to tranform each element |
|
375 |
^<CollectWriteSteam> |
|
376 |
"" |
|
377 |
(Array new writing collecting: [ :e | e * e ]) write: (1 to: 5); conclusion |
|
378 |
"" |
|
379 |
(String new writing collecting: [ :e | e asCharacter ]) write: (65 to: 90); conclusion |
|
380 |
" |
|
381 |
^CollectWriteStream on: self block: aBlock |
|
382 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
383 |
|
59 | 384 |
!Xtreams::WriteStream methodsFor:'transforming'! |
385 |
||
386 |
depairing |
|
387 |
"Transform a stream of associations in to a stream of elements made up of the key and value association components." |
|
388 |
||
389 |
^self transforming: [:in :out | |
|
390 |
| association | |
|
391 |
association := in get. |
|
392 |
out put: association key. |
|
393 |
out put: association value] |
|
394 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
395 |
|
59 | 396 |
!Xtreams::WriteStream methodsFor:'transforming'! |
397 |
||
398 |
doing: aBlock |
|
399 |
"Perform and action with each passing element using #do: style block." |
|
400 |
" aBlock <BlockClosure> a #do: style block invoked with each element as it passes through the stream |
|
401 |
^<CollectWriteSteam> |
|
402 |
"" |
|
403 |
(Array new writing doing: [ :e | Transcript space; print: e * e ]) write: (1 to: 10); conclusion |
|
404 |
" |
|
405 |
^self collecting: [:each | (aBlock value: each). each] |
|
406 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
407 |
|
59 | 408 |
!Xtreams::WriteStream methodsFor:'transforming'! |
409 |
||
410 |
duplicating: aWriteStream |
|
411 |
"Duplicate all the contents written into @aWriteStream" |
|
412 |
" aWriteStream <WriteStream> a stream to copy into |
|
413 |
^<DuplicateWriteSteam> |
|
414 |
"" |
|
415 |
| original copy | |
|
416 |
original := Array new writing. |
|
417 |
copy := ByteArray new writing. |
|
418 |
(original duplicating: copy) write: (0 to: 15). |
|
419 |
original conclusion -> copy conclusion |
|
420 |
" |
|
421 |
^DuplicateWriteStream on: self duplicate: aWriteStream |
|
422 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
423 |
|
59 | 424 |
!Xtreams::WriteStream methodsFor:'transforming'! |
425 |
||
426 |
encoding: anEncoding |
|
427 |
"Transform characters into bytes using @anEncoding such as #utf8 or #ascii, etc. Any encoding supported by StreamEncoder is allowed. |
|
428 |
The encoding steam also performs automatic conversion of CRs into the native line-end convention of the underlying platform, |
|
429 |
unless set into a different line-end convention mode" |
|
430 |
" anEncoding <Symbol> encoding identifier recognized by StreamEncoder class>>new: |
|
431 |
^<EncodedWriteStream> |
|
432 |
"" |
|
433 |
(ByteArray new writing encoding: #ascii) write: 'abcdefghi'; conclusion |
|
434 |
"" |
|
435 |
(ByteArray new writing encoding: #ascii) write: 'Hello\World' withCRs; conclusion |
|
436 |
"" |
|
437 |
(ByteArray new writing encoding: #ascii) setLineEndCRLF; write: 'Hello\World' withCRs; conclusion |
|
438 |
" |
|
439 |
^EncodeWriteStream on: self encoding: anEncoding |
|
440 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
441 |
|
59 | 442 |
!Xtreams::WriteStream methodsFor:'transforming'! |
443 |
||
444 |
encodingBase64 |
|
445 |
"Encodes bytes into characters of base-64 encoding. |
|
446 |
Emits final padding characters ($=) as required, when the stream is closed." |
|
447 |
" ^<TransformWriteStream>" |
|
448 |
" |
|
449 |
String new writing encodingBase64 write: (ByteArray withAll: (1 to: 20)); conclusion |
|
450 |
" |
|
451 |
| map cache | |
|
452 |
map := [ :i | 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' at: i + 1 ]. |
|
453 |
cache := ByteArray new: 3. |
|
454 |
^(self transforming: [ :in :out | | count block shift | |
|
455 |
count := [ in read: 3 into: cache at: 1. 3 ] on: Incomplete do: [ :incomplete | incomplete count]. |
|
456 |
count isZero ifTrue: [ Incomplete zero raise ]. |
|
457 |
block := (1 to: count) inject: 0 into: [ :total :byte | (total bitShift: 8) + (cache at: byte)]. |
|
458 |
shift := count * -8. |
|
459 |
1 to: count + 1 do: [:i | out put: (map value: ((block bitShift: (shift + (i * 6))) bitAnd: 63))]. |
|
460 |
count < 3 ifTrue: [ |
|
461 |
3 - count timesRepeat: [ out put: $= ]. |
|
462 |
(Incomplete count: count) raise]]) |
|
463 |
buffer: (RingBuffer on: (ByteArray new: 3)); |
|
464 |
yourself |
|
465 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
466 |
|
59 | 467 |
!Xtreams::WriteStream methodsFor:'transforming'! |
468 |
||
469 |
encodingHex |
|
470 |
"Encodes hex characters into bytes." |
|
471 |
" ^<TransformReadStream>" |
|
472 |
" |
|
473 |
ByteArray new writing encodingHex write: '010203fdfeff'; terminal |
|
474 |
" |
|
475 |
| c2i | |
|
476 |
c2i := [ :c | ('0123456789abcdef' indexOf: c asLowercase) - 1 ]. |
|
477 |
^(self transforming: [ :in :out | |
|
478 |
out put: ((c2i value: in get) bitShift: 4) + (c2i value: in get) ]) |
|
479 |
contentsSpecies: ByteString; |
|
480 |
yourself |
|
481 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
482 |
|
59 | 483 |
!Xtreams::WriteStream methodsFor:'transforming'! |
484 |
||
485 |
injecting: initialObject into: aBlock |
|
486 |
"Accumulates a running value combined with each passing element using the binary aBlock. aBlock takes the result of the last evaluation and the next element as arguments. Notable difference from the collection analog is that the streaming variant is a stream of all the intermediate values of the running value." |
|
487 |
" initialObject <Object> initial value used as the previous result for the evaluation of the first element |
|
488 |
aBlock <BlockClosure> binary block combining the value of each element with previous result of its evaluation |
|
489 |
^<CollectingWriteStream>" |
|
490 |
" |
|
491 |
(Array new writing injecting: 0 into: [ :total :each | each + total ]) write: (1 to: 10); conclusion |
|
492 |
" |
|
493 |
| nextObject | |
|
494 |
nextObject := initialObject. |
|
495 |
^self collecting: [:each | nextObject := aBlock cull: nextObject cull: each] |
|
496 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
497 |
|
72 | 498 |
!Xtreams::WriteStream methodsFor:'interpreting'! |
59 | 499 |
|
72 | 500 |
interpreting: type |
501 |
"Converts consumed elements into bytes of pre-configured (primitive) CType, e.g. float, long etc. The type of the written elements must match the CType and the underlying destination must be binary. |
|
502 |
"" type <Symbol> identifies a (primitive) CType, e.g. #float, #long (mapped via Interpretations) |
|
503 |
^ <InterpretedWriteStream> |
|
504 |
"" |
|
505 |
| doubles bytes | |
|
506 |
doubles := [ Random new next ] reading. |
|
507 |
bytes := (ByteArray new writing interpreting: #double) |
|
508 |
write: 10 from: doubles; |
|
509 |
close; |
|
510 |
terminal. |
|
511 |
(bytes reading interpreting: #double) read: 10 |
|
512 |
" |
|
513 |
^self interpreting: type cacheSize: 1 |
|
514 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
515 |
|
72 | 516 |
!Xtreams::WriteStream methodsFor:'interpreting'! |
517 |
||
518 |
interpreting: type cacheSize: size |
|
519 |
"Converts consumed elements into bytes of pre-configured (primitive) CType, e.g. float, long etc. The type of the written elements must match the CType and the underlying destination must be binary. |
|
520 |
"" type <Symbol> identifies a (primitive) CType, e.g. #float, #long (mapped via Interpretations) |
|
521 |
size <Integer> requested buffer size (in number of elements) |
|
522 |
^ <InterpretedWriteStream> |
|
523 |
"" |
|
524 |
| doubles bytes | |
|
525 |
doubles := [ Random new next ] reading. |
|
526 |
bytes := (ByteArray new writing interpreting: #double size: 10) |
|
527 |
write: 10 from: doubles; |
|
528 |
close; |
|
529 |
terminal. |
|
530 |
(bytes reading interpreting: #double) read: 10 |
|
531 |
" |
|
532 |
^InterpretedWriteStream on: self type: type cacheSize: size |
|
533 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
534 |
|
72 | 535 |
!Xtreams::WriteStream methodsFor:'interpreting'! |
536 |
||
537 |
interpreting: writer size: byteSize |
|
538 |
"Converts objects into bytes in a binary destination according to provided @writer block. The block is evaluated with an instance of InterpretedBytes an index and object to write into the bytes. |
|
539 |
"" type <Symbol> identifies a (primitive) CType, e.g. #float, #long (mapped via Interpretations) |
|
540 |
byteSize <Integer> byte size of an element |
|
541 |
^ <InterpretedWriteStream> |
|
542 |
"" |
|
543 |
| points bytes | |
|
544 |
points := Random new reading transforming: [ :in :out | out put: in get @ in get ]. |
|
545 |
bytes := (ByteArray new writing interpreting: [ :b :i :o | (b floatAt: i put: o x) @ (b floatAt: i + 4 put: o y) ] size: 8 ) |
|
546 |
write: 10 from: points; |
|
547 |
close; |
|
548 |
terminal. |
|
549 |
(bytes reading interpreting: [ :b :i | (b floatAt: i) @ (b floatAt: i + 4) ] size: 8 cacheSize: 5) read: 5 |
|
550 |
" |
|
551 |
^InterpretedWriteStream on: self bytesPerElement: byteSize contentsSpecies: Array operation: writer cacheSize: 1 |
|
552 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
553 |
|
72 | 554 |
!Xtreams::WriteStream methodsFor:'interpreting'! |
555 |
||
556 |
interpreting: writer size: byteSize cacheSize: cacheSize |
|
557 |
"Converts objects into bytes in a binary destination according to provided @writer block. The block is evaluated with an instance of InterpretedBytes an index and object to write into the bytes. |
|
558 |
"" type <Symbol> identifies a (primitive) CType, e.g. #float, #long (mapped via Interpretations) |
|
559 |
byteSize <Integer> byte size of an element |
|
560 |
cacheSize <Integer> requested cache size (in number of elements) |
|
561 |
^ <InterpretedWriteStream> |
|
562 |
"" |
|
563 |
| points bytes | |
|
564 |
points := Random new reading transforming: [ :in :out | out put: in get @ in get ]. |
|
565 |
bytes := (ByteArray new writing interpreting: [ :b :i :o | (b floatAt: i put: o x) @ (b floatAt: i + 4 put: o y) ] size: 8 ) |
|
566 |
write: 10 from: points; |
|
567 |
close; |
|
568 |
terminal. |
|
569 |
(bytes reading interpreting: [ :b :i | (b floatAt: i) @ (b floatAt: i + 4) ] size: 8 cacheSize: 5) read: 5 |
|
570 |
" |
|
571 |
^InterpretedWriteStream on: self bytesPerElement: byteSize contentsSpecies: Array operation: writer cacheSize: cacheSize |
|
572 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
573 |
|
72 | 574 |
!Xtreams::WriteStream methodsFor:'interpreting'! |
575 |
||
576 |
marshaling |
|
577 |
"Marshaling streams are used to encode arbitrary smalltalk objects into a sequence of bytes suitable for binary storage or transport. The format of the binary encoding is defined by an ObjectMarshaler and is identified by particular version ID. |
|
578 |
A marshaling write stream encodes objects into a binary destination stream. |
|
579 |
"" ^ <ObjectWriteSteam> |
|
580 |
"" |
|
581 |
| rectangle bytes | |
|
582 |
rectangle := 5 @ 5 extent: 5 @ 5. |
|
583 |
bytes := ByteArray new writing marshaling put: rectangle; conclusion. |
|
584 |
bytes reading marshaling get |
|
585 |
" |
|
586 |
^ObjectWriteStream on: self |
|
587 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
588 |
|
72 | 589 |
!Xtreams::WriteStream methodsFor:'interpreting'! |
590 |
||
591 |
marshaling: aMarshaler |
|
592 |
"Marshaling streams are used to encode arbitrary smalltalk objects into a sequence of bytes suitable for binary storage or transport. The format of the binary encoding is defined by an ObjectMarshaler and is identified by particular version ID. Custom marshaling schemes can be derived by subclassing ObjectMarshaler. Custom schemes must declare their own (unique) version ID. This method allows to employ a cusomt marshaler instead of the default one (STST2.0). |
|
593 |
A marshaling write stream encodes objects into a binary destination stream. |
|
594 |
"" aMarshaler <ObjectMarshaler> implements custom marshaling format |
|
595 |
^ <ObjectWriteSteam> |
|
596 |
"" |
|
597 |
| rectangle bytes | |
|
598 |
rectangle := 5 @ 5 extent: 5 @ 5. |
|
599 |
bytes := (ByteArray new writing marshaling: ObjectMarshaler new) put: rectangle; conclusion. |
|
600 |
bytes reading marshaling get |
|
601 |
" |
|
602 |
^ObjectWriteStream on: self marshaler: aMarshaler |
|
603 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
604 |
|
59 | 605 |
!Xtreams::WriteStream methodsFor:'transforming'! |
606 |
||
607 |
monitoring: aNotificationBlock every: aNotificationInterval |
|
608 |
"Monitor the through-put of the receiver." |
|
609 |
" aNotificationBlock <BlockClosure> the block to execute when notifying |
|
610 |
aNotificationInterval <Duration> how often to notify |
|
611 |
^<PositionWriteSubstream> |
|
612 |
" |
|
613 |
||
614 |
| previousPosition timer start notifyBlock monitoring notifyProcess notifyFinished | |
|
615 |
||
616 |
start := Time microsecondClock. |
|
617 |
previousPosition := 0. |
|
618 |
monitoring := nil. |
|
619 |
timer := nil. |
|
620 |
notifyFinished := false. |
|
621 |
||
622 |
notifyBlock := [ |
|
623 |
aNotificationBlock cull: monitoring position cull: monitoring position - previousPosition cull: Time microsecondClock - start. |
|
624 |
previousPosition := monitoring position]. |
|
625 |
||
626 |
notifyProcess := nil. |
|
627 |
notifyProcess := [ |
|
628 |
[notifyBlock value. notifyFinished] whileFalse: [notifyProcess suspend]] newProcess. |
|
629 |
notifyProcess priority: ((Processor activeProcess priority + 1) min: 99). |
|
630 |
||
631 |
monitoring := self closing: [ |
|
632 |
timer stop. |
|
633 |
notifyProcess resume. |
|
634 |
notifyFinished := true. |
|
635 |
notifyProcess resume. |
|
636 |
self close]. |
|
637 |
||
638 |
timer := Timer every: aNotificationInterval resume: notifyProcess. |
|
639 |
^monitoring |
|
640 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
641 |
|
59 | 642 |
!Xtreams::WriteStream methodsFor:'transforming'! |
643 |
||
644 |
pairing |
|
645 |
"Transform a stream of elements in to a stream of associations between even+odd elements of the stream. This expects the stream to have an even number of elements" |
|
646 |
||
647 |
^self transforming: [:in :out | out put: (Association key: in get value: in get)] |
|
648 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
649 |
|
72 | 650 |
!Xtreams::WriteStream methodsFor:'transforming'! |
59 | 651 |
|
72 | 652 |
positioning |
653 |
"If necessary add positioning layer. Note that positiong layer employs buffering to implement the positioning ability. The default buffering strategy will grow the buffer up to the full size of the underlying stream if not released. Consequently other Buffer types might be more suitable for specific circumstances, e.g. if only last n elements need to be buffered, a fixed size RingBuffer can be substitued with #buffer: accessor." |
|
654 |
" ^ <WriteStream> a positionable read stream |
|
655 |
"" |
|
656 |
[ :x | Transcript space; print: x ] writing positioning write: (1 to: 10); -- 5; write: (11 to: 15); close |
|
657 |
" |
|
658 |
^self isPositionable |
|
659 |
ifTrue: [self] |
|
660 |
ifFalse: [PositionWriteStream on: self] |
|
661 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
662 |
|
59 | 663 |
!Xtreams::WriteStream methodsFor:'transforming'! |
664 |
||
665 |
rejecting: aBlock |
|
666 |
"Filters written elements using aBlock. aBlock has the same form and semantics as the #reject: block on collections." |
|
667 |
" aBlock <BlockClosure> usual #reject: style block used to filter the elements passing through |
|
668 |
^<TransformWriteStream>" |
|
669 |
" |
|
670 |
(Array new writing rejecting: [ :e | e odd ]) write: (1 to: 10); conclusion |
|
671 |
" |
|
672 |
^self selecting: [:each | (aBlock cull: each) not] |
|
673 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
674 |
|
59 | 675 |
!Xtreams::WriteStream methodsFor:'transforming'! |
676 |
||
677 |
selecting: aBlock |
|
678 |
"Filters written elements using aBlock. aBlock has the same form and semantics as the #select: block on collections." |
|
679 |
" aBlock <BlockClosure> usual #select: style block used to filter the elements passing through |
|
680 |
^<TransformWriteStream>" |
|
681 |
" |
|
682 |
(Array new writing selecting: [ :e | e odd ]) write: (1 to: 10); conclusion |
|
683 |
" |
|
684 |
^self transforming: [:input :output | |
|
685 |
| value | |
|
686 |
[value := input get. |
|
687 |
aBlock cull: value] whileFalse. |
|
688 |
output put: value] |
|
689 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
690 |
|
59 | 691 |
!Xtreams::WriteStream methodsFor:'transforming'! |
692 |
||
693 |
transforming: aBlock |
|
694 |
"This is the most general form of transform stream. The block receives two streams, a virtual stream of written elements (input) and the destination (output). The block can read arbitrary number of elements from input (including none) and write arbitrary number of elements into the output (including none). The block will be invoked as many times as necessary to consume any written elements, or until an Incomplete is raised by the destination. |
|
695 |
Note that if the #contentSpecies of the destination doesn't fit the input of the transformation, the #contentsSpecies of the transform stream has to be set explicitly. |
|
696 |
"" aBlock <BlockClosure> binary transformation block that reads elements from input (first argument) and writes elements into output (second argument) |
|
697 |
^<TransformWriteStream> |
|
698 |
"" Convert text into a stream of words |
|
699 |
(Array new writing transforming: [ :in :out || word char | |
|
700 |
word := String new writing. |
|
701 |
[ [ (char := in get) = Character space ] whileFalse: [ word put: char ]. |
|
702 |
] ensure: [ out put: (word close; destination) ] ] |
|
703 |
) write: 'hello world!! bye world!!'; |
|
704 |
close; |
|
705 |
terminal |
|
706 |
"" Convert a hex-string into a byte array (2 characters per byte) |
|
707 |
| c2d | |
|
708 |
c2d := [ :char | ('0123456789abcdef' indexOf: char) - 1 ]. |
|
709 |
(ByteArray new writing transforming: [ :in :out | |
|
710 |
out put: (c2d value: in get) * 16 + (c2d value: in get) ] |
|
711 |
) contentsSpecies: String; |
|
712 |
write: '0123456789abcdef'; |
|
713 |
close; |
|
714 |
terminal |
|
715 |
" |
|
716 |
^TransformWriteStream on: self block: aBlock |
|
717 |
! ! |
|
111
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
718 |
|
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
719 |
!stx_goodies_xtreams_transforms class methodsFor:'documentation'! |
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
720 |
|
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
721 |
extensionsVersion_HG |
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
722 |
|
44ac233b2f83
* removed namespace from pool references and stray extension methods
joe
parents:
97
diff
changeset
|
723 |
^ '$Changeset: <not expanded> $' |
136 | 724 |
! ! |