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