core/Xtreams__WriteStream.st
author mkobetic
Sun, 15 Jan 2012 02:15:02 +0000
changeset 36 cf68c4beeb11
parent 33 c6555f32c9fe
child 44 217e67f9f1a3
permissions -rw-r--r--
sockets and files
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
36
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
     1
'From Smalltalk/X, Version:6.2.1 on 14-01-2012 at 09:12:29 PM'                  !
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
     2
2
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
     3
"{ Package: 'stx:goodies/xtreams/core' }"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
     4
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
     5
"{ NameSpace: Xtreams }"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
     6
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
     7
Object subclass:#WriteStream
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
     8
	instanceVariableNames:'destination'
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
     9
	classVariableNames:'Backspace Bell CarriageReturn Delete DoubleQuote Escape FormFeed
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    10
		LineFeed Quote Space Tab VerticalTab'
36
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
    11
	poolDictionaries:'XtreamsPool'
20
51de794993c3 added XtreamsPool to fix DefaultBufferSize; set proper category names
mkobetic
parents: 7
diff changeset
    12
	category:'Xtreams-Core'
2
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    13
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    14
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    15
WriteStream comment:'Abstract superclass of all write streams; defines the API.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    16
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    17
Write streams are created by sending #writing to a concrete resource (a.k.a terminal), such as a Collection, SocketAccessor, Filename, etc.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    18
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    19
	String new writing write: ''testing''; close; terminal
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    20
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    21
Transform write streams are created through one of the messages in the ''transforming'' protocol sent to other write streams.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    22
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    23
	(String new writing collecting: #asUppercase) write: ''testing''; close; terminal
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    24
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    25
Subclasses must implement the following messages:
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    26
	#read:into:at:
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    27
	#contentsSpecies
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    28
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    29
Instance Variables
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    30
	destination     <Object> a stream or "terminal" consuming written elements
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    31
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    32
Shared Variables
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    33
	Backspace       <Character>
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    34
	Bell    <Character>
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    35
	CarriageReturn  <Character>
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    36
	Delete  <Character>
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    37
	DoubleQuote     <Character>
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    38
	Escape  <Character>
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    39
	FormFeed        <Character>
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    40
	LineFeed        <Character>
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    41
	Quote   <Character>
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    42
	Space   <Character>
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    43
	Tab     <Character>
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    44
	VerticalTab     <Character>
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    45
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    46
'
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    47
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    48
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    49
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    50
!WriteStream class methodsFor:'instance creation'!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    51
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    52
on: aDestination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    53
	^self new on: aDestination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    54
! !
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    55
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    56
!WriteStream class methodsFor:'class initialization'!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    57
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    58
initialize
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    59
        Backspace := String with: Character backspace.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    60
        Bell := String with: (Character value: 7).
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    61
        CarriageReturn := String with: (Character value: 13).
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    62
        Delete := String with: (Character value: 127).
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    63
        DoubleQuote := String with: $".
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    64
        Escape := String with: (Character value: 27).
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    65
        FormFeed := String with: Character newPage.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    66
        LineFeed := String with: Character lf.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    67
        Quote := String with: $'.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    68
        Space := String with: Character space.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    69
        Tab := String with: Character tab.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    70
        VerticalTab := String with: (Character value: 11)
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    71
! !
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    72
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    73
!WriteStream methodsFor:'accessing'!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    74
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    75
conclusion
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    76
	"Close the stream and return the object at the bottom of the stream."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    77
	"       ^<Collection | Buffer | IOAccessor | BlockClosure> "
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    78
	self close.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    79
	^self terminal
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    80
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    81
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    82
destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    83
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    84
	^destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    85
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    86
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    87
insert: aStreamable
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    88
	"Insert aStreamable into self at current position."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    89
	"       aStreamable     <SequenceableCollection | ReadStream | Buffer>  the source to write in to the destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    90
		^<Integer>      the number of elements written to the destination"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    91
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    92
		' World!!' copy writing insert: 'Hello' reading; -= 0; close; destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    93
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    94
	^aStreamable streamingInsertInto: self
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    95
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    96
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    97
insert: anInteger from: aStreamable
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    98
	"Insert anIntegers worth of elements from aStreamable into self at current position."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    99
	"       anInteger       <Integer>       the number of elements to insert
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   100
		aStreamable     <ReadStream | SequenceableCollection | Buffer > the source to write into the destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   101
		startIndex      <Integer>       the index into aSequenceableCollection to start writing from
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   102
		^<Integer>      number of elements inserted
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   103
	""
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   104
		' World!!' copy writing insert: 5 from: 'Hello Underworld!!' reading; -= 0; close; destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   105
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   106
	aStreamable streamingInsert: anInteger into: self.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   107
	^anInteger
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   108
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   109
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   110
insert: anInteger from: aSequenceableCollection at: startIndex
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   111
	"Insert anIntegers worth of elements from aSequenceableCollection starting at startIndex into self at current position."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   112
	"       anInteger       <Integer>       the number of elements to insert
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   113
		aStreamable     <SequenceableCollection>        the source to write into the destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   114
		startIndex      <Integer>       the index into aSequenceableCollection to start writing from
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   115
		^<Integer>      number of elements inserted
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   116
	""
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   117
		' World!!' copy writing insert: 5 from: 'Hello' at: 1; -= 0; close; destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   118
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   119
	self write: anInteger from: aSequenceableCollection at: startIndex.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   120
	^anInteger
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   121
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   122
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   123
put: anObject
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   124
	"Write anObject into self."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   125
	"       anObject                <Object>        the object to write in to the destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   126
		^                               <Object>        the object that was written to the destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   127
	""
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   128
		String new writing put: $h; close; destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   129
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   130
	| cache |
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   131
	cache := self contentsSpecies newRecycled: 1.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   132
	cache at: 1 put: anObject.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   133
	self write: 1 from: cache at: 1.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   134
	cache recycle.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   135
	^anObject
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   136
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   137
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   138
terminal
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   139
	"Return the object at the bottom of the stream."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   140
	"       ^<Collection | Buffer | IOAccessor | BlockClosure>
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   141
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   142
	^(destination isKindOf: WriteStream)
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   143
		ifTrue: [ destination terminal ]
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   144
		ifFalse: [ destination ]
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   145
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   146
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   147
write: aStreamable
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   148
	"Write aStreamable into self."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   149
	"       aStreamable     <SequenceableCollection | ReadStream | Buffer>  the source to write in to the destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   150
		^<Integer>      the number of elements written to the destination"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   151
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   152
		String new writing write: 'Hello' reading; close; destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   153
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   154
	^aStreamable streamingWriteInto: self
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   155
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   156
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   157
write: anInteger from: aStreamable
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   158
	"Write anInteger's worth of elements from aStreamable into self."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   159
	"       anInteger       <Integer>       the number of elements to write
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   160
		aStreamable     <SequenceableCollection | ReadStream | Buffer>  the source to write in to the destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   161
		^<Integer>      number of elements written
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   162
	""
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   163
		String new writing write: 3 from: 'Hello' reading; close; destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   164
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   165
	^aStreamable streamingWrite: anInteger into: self
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   166
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   167
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   168
write: anInteger from: aSequenceableCollection at: startIndex
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   169
	"Write anIntegers worth of elements from aSequenceableCollection starting at startIndex into self."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   170
	"       anInteger       <Integer>       the number of elements to write
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   171
		aStreamable     <SequenceableCollection>        the source to write in to the destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   172
		startIndex      <Integer>       the index into aSequenceableCollection to start writing from
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   173
		^<Integer>      number of elements written
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   174
	""
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   175
		String new writing write: 3 from: 'Hello' at: 2; close; destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   176
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   177
	^self subclassResponsibility
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   178
! !
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   179
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   180
!WriteStream methodsFor:'characters'!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   181
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   182
backspace
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   183
	self write: Backspace
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   184
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   185
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   186
bell
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   187
	self write: Bell
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   188
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   189
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   190
cr
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   191
	self write: CarriageReturn
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   192
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   193
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   194
delete
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   195
	self write: Delete
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   196
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   197
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   198
escape
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   199
	self write: Escape
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   200
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   201
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   202
ff
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   203
	self write: FormFeed
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   204
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   205
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   206
lf
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   207
	self write: LineFeed
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   208
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   209
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   210
print: anObject
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   211
	anObject streamingPrintOn: self
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   212
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   213
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   214
q
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   215
	self write: Quote
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   216
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   217
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   218
qq
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   219
	self write: DoubleQuote
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   220
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   221
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   222
space
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   223
	self write: Space
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   224
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   225
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   226
space: anInteger
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   227
	anInteger timesRepeat: [self space]
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   228
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   229
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   230
tab
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   231
	self write: Tab
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   232
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   233
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   234
tab: anInteger
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   235
	anInteger timesRepeat: [self tab]
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   236
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   237
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   238
vtab
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   239
	self write: VerticalTab
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   240
! !
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   241
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   242
!WriteStream methodsFor:'converting'!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   243
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   244
writing
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   245
	^[:object | self nextPut: object] writing
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   246
		contentsSpecies: self contentsSpecies;
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   247
		yourself
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   248
! !
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   249
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   250
!WriteStream methodsFor:'initialize-release'!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   251
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   252
close
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   253
	"Close the destination from any more writes."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   254
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   255
	self flush.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   256
	destination close
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   257
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   258
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   259
contentsSpecies
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   260
	"The class of collection that is able to hold the kind of elements that this stream consumes."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   261
	"       ^       <Class> collection class
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   262
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   263
	^self subclassResponsibility
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   264
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   265
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   266
flush
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   267
	"Make sure all the previously written elements are pushed down into the destination."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   268
	destination flush
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   269
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   270
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   271
on: aDestination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   272
	destination := aDestination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   273
! !
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   274
36
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   275
!WriteStream methodsFor:'interpreting'!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   276
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   277
interpreting: type
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   278
	"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.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   279
	""	type	<Symbol>	identifies a (primitive) CType, e.g. #float, #long (mapped via Interpretations)
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   280
		^		<InterpretedWriteStream>
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   281
	""
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   282
		| doubles bytes |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   283
		doubles := [ Random new next ] reading.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   284
		bytes := (ByteArray new writing interpreting: #double)
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   285
			write: 10 from: doubles;
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   286
			close;
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   287
			terminal.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   288
		(bytes reading interpreting: #double) read: 10
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   289
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   290
	^self interpreting: type cacheSize: 1
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   291
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   292
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   293
interpreting: type cacheSize: size
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   294
	"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.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   295
	""	type	<Symbol>	identifies a (primitive) CType, e.g. #float, #long (mapped via Interpretations)
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   296
		size		<Integer>	requested buffer size (in number of elements)
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   297
		^		<InterpretedWriteStream>
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   298
	""
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   299
		| doubles bytes |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   300
		doubles := [ Random new next ] reading.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   301
		bytes := (ByteArray new writing interpreting: #double size: 10)
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   302
			write: 10 from: doubles;
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   303
			close;
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   304
			terminal.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   305
		(bytes reading interpreting: #double) read: 10
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   306
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   307
	^InterpretedWriteStream on: self type: type cacheSize: size
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   308
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   309
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   310
interpreting: writer size: byteSize
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   311
	"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.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   312
	""	type		<Symbol>	identifies a (primitive) CType, e.g. #float, #long (mapped via Interpretations)
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   313
		byteSize	<Integer>	byte size of an element
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   314
		^			<InterpretedWriteStream>
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   315
	""
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   316
		| points bytes |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   317
		points := Random new reading transforming: [ :in :out | out put: in get @ in get ].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   318
		bytes := (ByteArray new writing interpreting: [ :b :i :o | (b floatAt: i put: o x) @ (b floatAt: i + 4 put: o y) ] size: 8 )
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   319
			write: 10 from: points;
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   320
			close;
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   321
			terminal.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   322
		(bytes reading interpreting: [ :b :i | (b floatAt: i) @ (b floatAt: i + 4) ] size: 8 cacheSize: 5) read: 5
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   323
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   324
	^InterpretedWriteStream on: self bytesPerElement: byteSize contentsSpecies: Array operation: writer cacheSize: 1
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   325
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   326
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   327
interpreting: writer size: byteSize cacheSize: cacheSize
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   328
	"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.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   329
	""	type		<Symbol>	identifies a (primitive) CType, e.g. #float, #long (mapped via Interpretations)
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   330
		byteSize	<Integer>	byte size of an element
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   331
		cacheSize	<Integer>	requested cache size (in number of elements)
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   332
		^			<InterpretedWriteStream>
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   333
	""
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   334
		| points bytes |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   335
		points := Random new reading transforming: [ :in :out | out put: in get @ in get ].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   336
		bytes := (ByteArray new writing interpreting: [ :b :i :o | (b floatAt: i put: o x) @ (b floatAt: i + 4 put: o y) ] size: 8 )
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   337
			write: 10 from: points;
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   338
			close;
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   339
			terminal.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   340
		(bytes reading interpreting: [ :b :i | (b floatAt: i) @ (b floatAt: i + 4) ] size: 8 cacheSize: 5) read: 5
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   341
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   342
	^InterpretedWriteStream on: self bytesPerElement: byteSize contentsSpecies: Array operation: writer cacheSize: cacheSize
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   343
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   344
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   345
marshaling
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   346
	"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.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   347
	A marshaling write stream encodes objects into a binary destination stream.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   348
	""	^			<ObjectWriteSteam>
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   349
	""
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   350
		| rectangle bytes |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   351
		rectangle := 5 @ 5 extent: 5 @ 5.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   352
		bytes := ByteArray new writing marshaling put: rectangle; conclusion.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   353
		bytes reading marshaling get
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   354
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   355
	^ObjectWriteStream on: self
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   356
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   357
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   358
marshaling: aMarshaler
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   359
	"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).
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   360
	A marshaling write stream encodes objects into a binary destination stream.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   361
	""	aMarshaler	<ObjectMarshaler>	implements custom marshaling format
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   362
		^			<ObjectWriteSteam>
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   363
	""
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   364
		| rectangle bytes |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   365
		rectangle := 5 @ 5 extent: 5 @ 5.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   366
		bytes := (ByteArray new writing marshaling: ObjectMarshaler new) put: rectangle; conclusion.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   367
		bytes reading marshaling get
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   368
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   369
	^ObjectWriteStream on: self marshaler: aMarshaler
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   370
! !
2
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   371
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   372
!WriteStream methodsFor:'printing'!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   373
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   374
printOn: aStream
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   375
	| stream |
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   376
	stream := String new writing.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   377
	self streamingPrintOn: stream.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   378
	aStream nextPutAll: stream conclusion.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   379
	aStream cr.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   380
	destination printOn: aStream.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   381
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   382
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   383
streamingPrintOn: aStream
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   384
	aStream write: self class name
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   385
! !
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   386
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   387
!WriteStream methodsFor:'private'!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   388
36
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   389
nextPut: anObject
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   390
	"This is here for compatibility with the existing StreamEncoders so that they can be re-used with transformation streams for encoding."
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   391
	self put: anObject.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   392
	^anObject
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   393
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   394
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   395
nextPutAll: aCollection
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   396
	"This is here for compatibility with the existing StreamEncoders so that they can be re-used with transformation streams for encoding."
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   397
	self write: aCollection.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   398
	^aCollection
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   399
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   400
2
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   401
streamingInsert: anInteger from: aReadStream
29
mkobetic
parents: 20
diff changeset
   402
        | cache count |
mkobetic
parents: 20
diff changeset
   403
        cache := self contentsSpecies newRecycled: (anInteger max: DefaultBufferSize).
mkobetic
parents: 20
diff changeset
   404
        count := [aReadStream read: anInteger into: cache at: 1. anInteger] on: Incomplete do: [ :ex | ex count ].
mkobetic
parents: 20
diff changeset
   405
        self insert: count from: cache at: 1.
mkobetic
parents: 20
diff changeset
   406
        cache recycle.
mkobetic
parents: 20
diff changeset
   407
        count < anInteger ifTrue: [(Incomplete count: count) raise]
2
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   408
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   409
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   410
streamingInsertFrom: aReadStream
29
mkobetic
parents: 20
diff changeset
   411
        | count cache |
mkobetic
parents: 20
diff changeset
   412
        count := 0.
mkobetic
parents: 20
diff changeset
   413
        cache := self contentsSpecies newRecycled: DefaultBufferSize.
mkobetic
parents: 20
diff changeset
   414
        [[aReadStream read: cache size into: cache at: 1] on: Incomplete do: [:exception |
mkobetic
parents: 20
diff changeset
   415
                self insert: exception.
mkobetic
parents: 20
diff changeset
   416
                cache recycle.
mkobetic
parents: 20
diff changeset
   417
                ^count + exception count].
mkobetic
parents: 20
diff changeset
   418
        self insert: cache size from: cache at: 1.
mkobetic
parents: 20
diff changeset
   419
        count := count + cache size] repeat
2
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   420
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   421
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   422
streamingWrite: anInteger from: aReadStream
29
mkobetic
parents: 20
diff changeset
   423
        | cache toDo continue amount |
mkobetic
parents: 20
diff changeset
   424
        cache := self contentsSpecies newRecycled: DefaultBufferSize.
mkobetic
parents: 20
diff changeset
   425
        toDo := anInteger. continue := true.
mkobetic
parents: 20
diff changeset
   426
        [ continue and: [ toDo > 0 ] ] whileTrue: [
mkobetic
parents: 20
diff changeset
   427
                amount := [ aReadStream read: (cache size min: toDo) into: cache at: 1 ] on: Incomplete do: [ :ex | continue := false. ex count ].
mkobetic
parents: 20
diff changeset
   428
                self write: amount from: cache at: 1.
mkobetic
parents: 20
diff changeset
   429
                toDo := toDo - amount ].
mkobetic
parents: 20
diff changeset
   430
        cache recycle.
mkobetic
parents: 20
diff changeset
   431
        toDo > 0 ifTrue: [(Incomplete count: anInteger - toDo) raise].
mkobetic
parents: 20
diff changeset
   432
        ^anInteger
2
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   433
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   434
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   435
streamingWriteFrom: aReadStream
29
mkobetic
parents: 20
diff changeset
   436
        | count cache |
mkobetic
parents: 20
diff changeset
   437
        count := 0.
mkobetic
parents: 20
diff changeset
   438
        cache := self contentsSpecies newRecycled: DefaultBufferSize.
mkobetic
parents: 20
diff changeset
   439
        [[aReadStream read: cache size into: cache at: 1] on: Incomplete do: [:exception |
mkobetic
parents: 20
diff changeset
   440
                self write: exception.
mkobetic
parents: 20
diff changeset
   441
                cache recycle.
mkobetic
parents: 20
diff changeset
   442
                ^count + exception count].
mkobetic
parents: 20
diff changeset
   443
        self write: cache size from: cache at: 1.
mkobetic
parents: 20
diff changeset
   444
        count := count + cache size] repeat
2
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   445
! !
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   446
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   447
!WriteStream methodsFor:'seeking'!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   448
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   449
++ anInteger
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   450
	"Seek forward by anInteger elements. The stream must be positionable."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   451
	"       anInteger       <Integer>       the number of elements to go forward by.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   452
		^<Integer>      the number of elements actually skipped
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   453
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   454
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   455
		'Hello Would' copy writing ++ 6; write: 'World'; close; destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   456
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   457
	"Subclasses should reimplement this method if the stream is positionable."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   458
	self isPositionable
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   459
		ifFalse:        [Incomplete zero raise]
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   460
		ifTrue: [self subclassResponsibility]
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   461
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   462
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   463
+= anInteger
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   464
	"Seek from the start of the stream by anInteger elements. The stream must be positionable."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   465
	"       anInteger       <Integer>       The number of elements to go forward by."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   466
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   467
		String new writing write: 'Hello Would'; += 6; write: 'World'; close; destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   468
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   469
	^self position: anInteger
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   470
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   471
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   472
-- anInteger
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   473
	"Seek backward by anInteger elements. The stream must be positionable."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   474
	"       anInteger       <Integer>       The number of elements to go back by."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   475
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   476
		String new writing write: 'helio'; -- 2; write: 'lo'; close; destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   477
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   478
	"Subclasses should reimplement this method if the stream is positionable."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   479
	self isPositionable
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   480
		ifFalse:        [self error: 'This stream is not positionable.']
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   481
		ifTrue: [self subclassResponsibility]
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   482
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   483
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   484
-= anInteger
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   485
	"Seek backwards from the end of the stream by anInteger elements. The stream must be positionable."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   486
	"       anInteger       <Integer>       The number of elements to go back by.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   487
		^<Integer>      the number of elements actually skipped"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   488
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   489
		'Hello Would' copy writing -= 3; write: 'rld'; close; terminal
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   490
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   491
	| available |
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   492
	available := anInteger min: self length.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   493
	self position: self length - available.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   494
	available = anInteger ifTrue: [ ^anInteger ].
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   495
	^(Incomplete count: available) raise
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   496
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   497
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   498
available
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   499
	"Return the number of elements from the current position to the end of the stream. The stream must be positionable."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   500
	"       ^       <Integer>       the number of elements available"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   501
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   502
		String new writing write: 'Hello World'; -- 5; available
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   503
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   504
	^self length - self position
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   505
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   506
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   507
explore: aBlock
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   508
	" Explore the stream within the block but return to where we started when the block completes. The stream must be positionable."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   509
	"       aBlock  <BlockClosure>  defines the exploration activity
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   510
		^               <Object>        result of aBlock"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   511
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   512
		String new writing explore: [ :s | s write: 'Hello' ]; write: 'World'; close; destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   513
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   514
	| position |
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   515
	position := self position.
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   516
	^[aBlock cull: self] ensure: [self position: position]
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   517
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   518
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   519
length
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   520
	"Return total length of the stream. The stream must be positionable."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   521
	"       ^       <Integer>       the total number of elements in the stream. (position + available)"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   522
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   523
		'Hello World' copy writing ++ 5; length
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   524
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   525
	"Subclasses should reimplement this method if the stream is positionable."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   526
	^self isPositionable
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   527
		ifFalse:        [self error: 'This stream is not positionable.']
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   528
		ifTrue: [self subclassResponsibility]
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   529
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   530
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   531
position
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   532
	"Return current position of the stream. The stream must be positionable."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   533
	"       ^       <Integer>       current position of the stream."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   534
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   535
		'Hello World' copy writing -= 5; position
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   536
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   537
	"Subclasses should reimplement this method if the stream is positionable."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   538
	^self isPositionable
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   539
		ifFalse:        [self error: 'This stream is not positionable.']
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   540
		ifTrue: [self subclassResponsibility]
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   541
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   542
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   543
position: anInteger
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   544
	"Change current position of the stream to anInteger. The stream must be positionable."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   545
	"       anInteger       <Integer>       current position of the stream."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   546
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   547
		'Hello Would' copy writing position: 6; write: 'World'; close; destination
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   548
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   549
	"Subclasses should reimplement this method if the stream is positionable."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   550
	self isPositionable
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   551
		ifFalse:        [self error: 'This stream is not positionable.']
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   552
		ifTrue: [self subclassResponsibility]
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   553
! !
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   554
36
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   555
!WriteStream methodsFor:'substreaming'!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   556
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   557
closing: aBlock
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   558
	^(PositionWriteSubstream on: self)
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   559
		closeBlock: aBlock;
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   560
		yourself
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   561
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   562
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   563
ending: aMatchable
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   564
	"Creates a substream that will end when aMatchable finds a match in the content passing through. aMatchable is either
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   565
		* a block that is evaluated with each element - the stream ends when the block returns true
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   566
		* a collection that is matched against the last elements written - the stream ends when the collection matches
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   567
		* any other object - the stream ends when an equal object is written into the stream"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   568
	"	aMatchable	<BlockClosure | Collection | Object> the substream ending criteria
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   569
		^<TransformWriteStream>
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   570
	""	
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   571
		| stream slice |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   572
		stream := String new writing.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   573
		slice := stream ending: $j.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   574
		[ slice write: 'abcdefghijklmnopqrstuvxyz' ] on: Incomplete do: [].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   575
		stream conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   576
	""
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   577
		| stream slice |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   578
		stream := String new writing.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   579
		slice := stream ending: 'mno'.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   580
		[ slice write: 'abcdefghijklmnopqrstuvxyz' ] on: Incomplete do: [].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   581
		stream conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   582
	""
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   583
		| stream slice |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   584
		stream := String new writing.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   585
		slice := stream ending: [ :e | 'gmt' includes: e ].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   586
		[ slice write: 'abcdefghijklmnopqrstuvxyz' ] on: Incomplete do: [].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   587
		stream conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   588
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   589
	^self ending: aMatchable inclusive: false
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   590
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   591
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   592
ending: aMatchable inclusive: inclusive
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   593
	"Creates a substream that will end when aMatchable finds a match in the content passing through. aMatchable is either
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   594
		* a block that is evaluated with each element - the stream ends when the block returns true
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   595
		* a collection that is matched against the last elements written - the stream ends when the collection matches
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   596
		* any other object - the stream ends when an equal object is written into the stream"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   597
	"	aMatchable	<BlockClosure | Collection | Object> the substream ending criteria
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   598
		inclusive <Boolean> should the matched elements be included in the stream contents or not
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   599
		^<TransformWriteStream>
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   600
	""
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   601
		| stream slice |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   602
		stream := String new writing.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   603
		slice := stream ending: $j inclusive: true.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   604
		[ slice write: 'abcdefghijklmnopqrstuvxyz' ] on: Incomplete do: [].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   605
		stream conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   606
	""
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   607
		| stream slice |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   608
		stream := String new writing.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   609
		slice := stream ending: 'mno' inclusive: true.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   610
		[ slice write: 'abcdefghijklmnopqrstuvxyz' ] on: Incomplete do: [].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   611
		stream conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   612
	""
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   613
		| stream slice |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   614
		stream := String new writing.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   615
		slice := stream ending: [ :e | 'gmt' includes: e ] inclusive: true.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   616
		[ slice write: 'abcdefghijklmnopqrstuvxyz' ] on: Incomplete do: [].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   617
		stream conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   618
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   619
	^aMatchable streamingWriteMatching: self inclusive: inclusive
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   620
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   621
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   622
limiting: limit
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   623
	"Create a substream that will allow at most @limit number of elements written into the destination."
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   624
	"	limit	<Integer>	maximum number of elements that can be written into destination
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   625
		^<LimitWriteStream>"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   626
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   627
		| stream slice |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   628
		stream := String new writing.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   629
		slice := stream limiting: 5.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   630
		[ slice write: 'abcdefghi' ] on: Incomplete do: [].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   631
		stream conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   632
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   633
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   634
	^LimitWriteSubstream on: self limit: limit
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   635
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   636
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   637
slicing
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   638
	"From a writable stream, return a readable stream that acts as a prototype factory for the writable stream."
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   639
	"	^<ReadStream>"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   640
	"(destination limiting: 10) slicing"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   641
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   642
	| substream |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   643
	substream := nil.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   644
	^[substream == nil ifFalse:
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   645
		[substream substreamClosed ifFalse: [substream close].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   646
		substream subseekend.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   647
		substream destinationAtEnd ifTrue: [Incomplete zero raise]].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   648
		substream := self copy]
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   649
		reading
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   650
			closeBlock: [destination close];
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   651
			yourself
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   652
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   653
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   654
stitching
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   655
	^self error: 'You can only stitch a read stream, however that read stream can return write streams and in so doing, you will create a stitching write stream.'
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   656
! !
2
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   657
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   658
!WriteStream methodsFor:'testing'!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   659
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   660
isPositionable
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   661
	"Can this stream be positioned. Positionable streams come with extra API: #position, #position:, etc."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   662
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   663
	^false
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   664
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   665
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   666
isReadable
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   667
	^false
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   668
!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   669
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   670
isWritable
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   671
	^true
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   672
! !
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   673
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   674
!WriteStream methodsFor:'transforming'!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   675
36
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   676
buffering: bufferSize
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   677
	"Delays committing its content to its underlying stream until it has reached a certain size ,#flush is sent, or the stream is closed."
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   678
	"       bufferSize      <Integer> The size of the buffer to start with.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   679
		^<PositionWriteStream>"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   680
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   681
		(ByteArray new writing buffering: 5)
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   682
			write: (ByteArray withAll: (1 to: 11));
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   683
			conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   684
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   685
	^BufferedWriteStream on: self bufferSize: bufferSize
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   686
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   687
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   688
collecting: aBlock
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   689
	"Transform each written element using #collect: style block."
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   690
	"	aBlock	<BlockClosure>	a #collect: style block used to tranform each element
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   691
		^<CollectWriteSteam>
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   692
	""
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   693
		(Array new writing collecting: [ :e | e * e ]) write: (1 to: 5); conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   694
	""
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   695
		(String new writing collecting: [ :e | e asCharacter ]) write: (65 to: 90); conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   696
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   697
	^CollectWriteStream on: self block: aBlock
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   698
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   699
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   700
depairing
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   701
	"Transform a stream of associations in to a stream of elements made up of the key and value association components."
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   702
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   703
	^self transforming: [:in :out |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   704
		| association |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   705
		association := in get.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   706
		out put: association key.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   707
		out put: association value]
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   708
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   709
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   710
doing: aBlock
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   711
	"Perform and action with each passing element using #do: style block."
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   712
	"	aBlock	<BlockClosure>	a #do: style block invoked with each element as it passes through the stream
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   713
		^<CollectWriteSteam>
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   714
	""
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   715
		(Array new writing doing: [ :e | Transcript space; print: e * e ]) write: (1 to: 10); conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   716
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   717
	^self collecting: [:each | (aBlock value: each). each]
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   718
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   719
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   720
duplicating: aWriteStream
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   721
	"Duplicate all the contents written into @aWriteStream"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   722
	"	aWriteStream <WriteStream>	a stream to copy into
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   723
		^<DuplicateWriteSteam>
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   724
	""
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   725
		| original copy |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   726
		original := Array new writing.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   727
		copy := ByteArray new writing.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   728
		(original duplicating: copy) write: (0 to: 15).
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   729
		original conclusion -> copy conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   730
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   731
	^DuplicateWriteStream on: self duplicate: aWriteStream
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   732
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   733
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   734
encoding: anEncoding
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   735
	"Transform characters into bytes using @anEncoding such as #utf8 or #ascii, etc. Any encoding supported by StreamEncoder is allowed.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   736
	The encoding steam also performs automatic conversion of CRs into the native line-end convention of the underlying platform,
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   737
	unless set into a different line-end convention mode"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   738
	"	anEncoding	<Symbol> encoding identifier recognized by StreamEncoder class>>new:
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   739
		^<EncodedWriteStream>
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   740
	""
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   741
		(ByteArray new writing encoding: #ascii) write: 'abcdefghi'; conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   742
	""
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   743
		(ByteArray new writing encoding: #ascii) write: 'Hello\World' withCRs; conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   744
	""
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   745
		(ByteArray new writing encoding: #ascii) setLineEndCRLF; write: 'Hello\World' withCRs; conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   746
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   747
	^EncodeWriteStream on: self encoding: anEncoding
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   748
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   749
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   750
encodingBase64
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   751
	"Encodes bytes into characters of base-64 encoding.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   752
	Emits final padding characters ($=) as required, when the stream is closed."
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   753
	"	^<TransformWriteStream>"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   754
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   755
		String new writing encodingBase64 write: (ByteArray withAll: (1 to: 20)); conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   756
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   757
	| map cache |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   758
	map := [ :i | 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' at: i + 1 ].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   759
	cache := ByteArray new: 3.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   760
	^(self transforming: [ :in :out | | count block shift |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   761
		count := [ in read: 3 into: cache at: 1. 3 ] on: Incomplete do: [ :incomplete | incomplete count].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   762
		count isZero ifTrue: [ Incomplete zero raise ].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   763
		block := (1 to: count) inject: 0 into: [ :total :byte | (total bitShift: 8) + (cache at: byte)].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   764
		shift := count * -8.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   765
		1 to: count + 1 do: [:i | out put: (map value: ((block bitShift: (shift + (i * 6))) bitAnd: 63))].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   766
		count < 3 ifTrue: [
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   767
			3 - count timesRepeat: [ out put: $= ].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   768
			(Incomplete count: count) raise]])
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   769
		buffer: (RingBuffer on: (ByteArray new: 3));
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   770
		yourself
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   771
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   772
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   773
encodingHex
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   774
	"Encodes hex characters into bytes."
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   775
	"	^<TransformReadStream>"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   776
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   777
		ByteArray new writing encodingHex write: '010203fdfeff'; terminal
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   778
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   779
	| c2i |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   780
	c2i := [ :c | ('0123456789abcdef' indexOf: c asLowercase) - 1 ].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   781
	^(self transforming: [ :in :out |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   782
		out put: ((c2i value: in get) bitShift: 4) + (c2i value: in get) ])
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   783
		contentsSpecies: ByteString;
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   784
		yourself
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   785
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   786
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   787
injecting: initialObject into: aBlock
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   788
	"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."
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   789
	"	initialObject	<Object> initial value used as the previous result for the evaluation of the first element
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   790
		aBlock	<BlockClosure> binary block combining the value of each element with previous result of its evaluation
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   791
		^<CollectingWriteStream>"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   792
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   793
		(Array new writing injecting: 0 into: [ :total :each | each + total ]) write: (1 to: 10); conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   794
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   795
	| nextObject |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   796
	nextObject := initialObject.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   797
	^self collecting: [:each | nextObject := aBlock cull: nextObject cull: each]
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   798
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   799
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   800
monitoring: aNotificationBlock every: aNotificationInterval
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   801
	"Monitor the through-put of the receiver."
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   802
	"	aNotificationBlock <BlockClosure>	the block to execute when notifying
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   803
		aNotificationInterval <Duration>	how often to notify
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   804
		^<PositionWriteSubstream>
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   805
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   806
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   807
	| previousPosition timer start notifyBlock monitoring notifyProcess notifyFinished |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   808
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   809
	start := Time microsecondClock.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   810
	previousPosition := 0.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   811
	monitoring := nil.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   812
	timer := nil.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   813
	notifyFinished := false.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   814
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   815
	notifyBlock := [
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   816
		aNotificationBlock cull: monitoring position cull: monitoring position - previousPosition cull: Time microsecondClock - start.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   817
		previousPosition := monitoring position].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   818
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   819
	notifyProcess := nil.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   820
	notifyProcess := [
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   821
		[notifyBlock value. notifyFinished] whileFalse: [notifyProcess suspend]] newProcess.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   822
	notifyProcess priority: ((Processor activeProcess priority + 1) min: 99).
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   823
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   824
	monitoring := self closing: [
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   825
		timer stop.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   826
		notifyProcess resume.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   827
		notifyFinished := true.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   828
		notifyProcess resume.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   829
		self close].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   830
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   831
	timer := Timer every: aNotificationInterval resume: notifyProcess.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   832
	^monitoring
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   833
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   834
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   835
pairing
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   836
	"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"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   837
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   838
	^self transforming: [:in :out | out put: (Association key: in get value: in get)]
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   839
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   840
2
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   841
positioning
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   842
	"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."
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   843
	"       ^       <WriteStream>   a positionable read stream
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   844
	""
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   845
		[ :x | Transcript space; print: x ] writing positioning write: (1 to: 10); -- 5; write: (11 to: 15); close
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   846
	"
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   847
	^self isPositionable
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   848
		ifTrue: [self]
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   849
		ifFalse:        [PositionWriteStream on: self]
36
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   850
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   851
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   852
rejecting: aBlock
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   853
	"Filters written elements using aBlock. aBlock has the same form and semantics as the #reject: block on collections."
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   854
	"	aBlock	<BlockClosure>	usual #reject: style block used to filter the elements passing through
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   855
		^<TransformWriteStream>"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   856
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   857
		(Array new writing rejecting: [ :e | e odd ]) write: (1 to: 10); conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   858
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   859
	^self selecting: [:each | (aBlock cull: each) not]
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   860
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   861
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   862
selecting: aBlock
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   863
	"Filters written elements using aBlock. aBlock has the same form and semantics as the #select: block on collections."
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   864
	"	aBlock	<BlockClosure>	usual #select: style block used to filter the elements passing through
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   865
		^<TransformWriteStream>"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   866
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   867
		(Array new writing selecting: [ :e | e odd ]) write: (1 to: 10); conclusion
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   868
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   869
	^self transforming: [:input :output |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   870
		| value |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   871
		[value := input get.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   872
		aBlock cull: value] whileFalse.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   873
		output put: value]
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   874
!
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   875
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   876
transforming: aBlock
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   877
	"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.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   878
	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.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   879
	""	aBlock	<BlockClosure>	binary transformation block that reads elements from input (first argument) and writes elements into output (second argument)
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   880
		^<TransformWriteStream>
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   881
	""	Convert text into a stream of words
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   882
		(Array new writing transforming: [ :in :out || word char |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   883
			word := String new writing.
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   884
			[	[  (char := in get) = Character space ] whileFalse: [ word put: char ].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   885
			] ensure: [ out put: (word close; destination) ] ]
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   886
		)	write: 'hello world!! bye world!!';
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   887
			close;
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   888
			terminal
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   889
	""	Convert a hex-string into a byte array (2 characters per byte)
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   890
		| c2d |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   891
		c2d := [ :char | ('0123456789abcdef' indexOf: char) - 1 ].
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   892
		(ByteArray new writing transforming: [ :in :out |
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   893
			out put: (c2d value: in get) * 16 + (c2d value: in get) ]
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   894
		)	contentsSpecies: String;
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   895
			write: '0123456789abcdef';
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   896
			close;
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   897
			terminal
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   898
	"
cf68c4beeb11 sockets and files
mkobetic
parents: 33
diff changeset
   899
	^TransformWriteStream on: self block: aBlock
2
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   900
! !
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   901
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   902
!WriteStream class methodsFor:'documentation'!
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   903
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   904
version_SVN
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   905
    ^ '$Id$'
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   906
! !
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   907
faf220cbe5b9 first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   908
WriteStream initialize!