author | Stefan Vogel <sv@exept.de> |
Sat, 18 Jul 2015 01:26:11 +0200 | |
changeset 18598 | 913ebad954df |
parent 18590 | 7528bf27e91c |
child 18608 | 7d521f25267c |
child 18613 | cef8d2d9f29f |
permissions | -rw-r--r-- |
18282 | 1 |
"{ Encoding: utf8 }" |
2 |
||
10846 | 3 |
" |
4 |
COPYRIGHT (c) 2005 by eXept Software AG |
|
5 |
All Rights Reserved |
|
6 |
||
7 |
This software is furnished under a license and may be used |
|
8 |
only in accordance with the terms of that license and with the |
|
9 |
inclusion of the above copyright notice. This software may not |
|
10 |
be provided or otherwise made available to, or used by, any |
|
11 |
other person. No title to or ownership of the software is |
|
12 |
hereby transferred. |
|
13 |
" |
|
8299 | 14 |
"{ Package: 'stx:libbasic' }" |
8298 | 15 |
|
17622 | 16 |
"{ NameSpace: Smalltalk }" |
17 |
||
8298 | 18 |
WriteStream subclass:#CharacterWriteStream |
19 |
instanceVariableNames:'currentCharacterSize' |
|
20 |
classVariableNames:'' |
|
21 |
poolDictionaries:'' |
|
22 |
category:'Streams' |
|
23 |
! |
|
24 |
||
8321 | 25 |
!CharacterWriteStream class methodsFor:'documentation'! |
26 |
||
10846 | 27 |
copyright |
28 |
" |
|
29 |
COPYRIGHT (c) 2005 by eXept Software AG |
|
30 |
All Rights Reserved |
|
31 |
||
32 |
This software is furnished under a license and may be used |
|
33 |
only in accordance with the terms of that license and with the |
|
34 |
inclusion of the above copyright notice. This software may not |
|
35 |
be provided or otherwise made available to, or used by, any |
|
36 |
other person. No title to or ownership of the software is |
|
37 |
hereby transferred. |
|
38 |
" |
|
39 |
! |
|
40 |
||
8321 | 41 |
documentation |
42 |
" |
|
43 |
This is a WriteStream, which automagically changes the underlying collection, |
|
10280 | 44 |
if a character does fit into the current collection. |
8321 | 45 |
|
46 |
String -> Unicode16String -> Unicode32Sting |
|
47 |
||
48 |
[author:] |
|
49 |
Stefan Vogel (stefan@zwerg) |
|
50 |
||
51 |
[instance variables:] |
|
52 |
||
53 |
[class variables:] |
|
54 |
||
55 |
[see also:] |
|
10280 | 56 |
String Unicode16String Unicode32Sting |
8321 | 57 |
" |
58 |
! |
|
59 |
||
60 |
examples |
|
61 |
" |
|
62 |
||
63 |
[exBegin] |
|
64 |
|stream| |
|
65 |
||
66 |
stream := CharacterWriteStream on:(String new:32). |
|
67 |
stream nextPutAll:'abc'. |
|
68 |
stream nextPut:(Character value:16r2c00). |
|
69 |
stream contents inspect |
|
70 |
[exEnd] |
|
71 |
||
72 |
" |
|
73 |
! ! |
|
74 |
||
18265 | 75 |
!CharacterWriteStream class methodsFor:'instance creation'! |
76 |
||
77 |
new |
|
78 |
"I know, that I operate on strings" |
|
79 |
||
18282 | 80 |
^ self on:(String uninitializedNew:10) |
18265 | 81 |
! |
82 |
||
83 |
new:count |
|
84 |
"I know, that I operate on strings" |
|
85 |
||
18282 | 86 |
^ self on:(String uninitializedNew:count) |
18265 | 87 |
! ! |
88 |
||
14607 | 89 |
!CharacterWriteStream methodsFor:'accessing'! |
90 |
||
91 |
reset |
|
92 |
"reset the stream; write anew. |
|
93 |
See the comment in WriteStream>>contents" |
|
94 |
||
95 |
collection := String new:collection size. |
|
96 |
currentCharacterSize := collection bitsPerCharacter. |
|
97 |
super resetPosition. |
|
98 |
! ! |
|
99 |
||
8321 | 100 |
!CharacterWriteStream methodsFor:'private'! |
101 |
||
18598 | 102 |
characterSizeChangedTo:newCharacterSize size:additionalSize |
103 |
"change aCollection to fit the size of newCharacterSize" |
|
8321 | 104 |
|
18598 | 105 |
|sz newSz| |
8321 | 106 |
|
18598 | 107 |
currentCharacterSize < newCharacterSize ifTrue:[ |
108 |
newSz := sz := collection size. |
|
17622 | 109 |
position + additionalSize >= sz ifTrue:[ |
18598 | 110 |
newSz := newSz + additionalSize + 100. "add some more space, maybe more will be added" |
8321 | 111 |
]. |
18598 | 112 |
collection := ((CharacterArray speciesForCharacterSize:newCharacterSize) new:newSz) |
8321 | 113 |
replaceFrom:1 to:sz with:collection startingAt:1. |
18598 | 114 |
currentCharacterSize := collection bitsPerCharacter. |
8321 | 115 |
]. |
116 |
! ! |
|
117 |
||
118 |
!CharacterWriteStream methodsFor:'private-accessing'! |
|
119 |
||
120 |
on:aCollection |
|
121 |
currentCharacterSize := aCollection bitsPerCharacter. |
|
122 |
^ super on:aCollection. |
|
123 |
! |
|
124 |
||
125 |
on:aCollection from:start to:stop |
|
126 |
currentCharacterSize := aCollection bitsPerCharacter. |
|
127 |
^ super on:aCollection from:start to:stop. |
|
128 |
! |
|
129 |
||
130 |
with:aCollection |
|
131 |
currentCharacterSize := aCollection bitsPerCharacter. |
|
132 |
^ super with:aCollection. |
|
133 |
! ! |
|
134 |
||
8298 | 135 |
!CharacterWriteStream methodsFor:'writing'! |
136 |
||
8321 | 137 |
next:count put:aCharacter |
138 |
"append anObject count times to the receiver. |
|
139 |
Redefined to avoid count grows of the underlying collection - |
|
140 |
instead a single grow on the final size is performed." |
|
141 |
||
18598 | 142 |
|needCharacterSize| |
143 |
||
144 |
needCharacterSize := aCharacter characterSize. |
|
145 |
needCharacterSize > currentCharacterSize ifTrue:[ |
|
146 |
self characterSizeChangedTo:needCharacterSize size:count. |
|
8321 | 147 |
]. |
12133 | 148 |
super next:count put:aCharacter |
8321 | 149 |
! |
150 |
||
151 |
nextPut:aCharacter |
|
152 |
"append the argument, aCharacter to the stream. |
|
18598 | 153 |
Specially tuned for appending to String, Unicode16String and Unicode32String streams." |
8298 | 154 |
|
155 |
%{ /* NOCONTEXT */ |
|
156 |
||
157 |
#ifndef NO_PRIM_STREAM |
|
18598 | 158 |
OBJ coll = __INST(collection); |
159 |
OBJ p = __INST(position); |
|
8298 | 160 |
|
8321 | 161 |
if (__isNonNilObject(coll) && __isSmallInteger(p) && __isCharacter(aCharacter)) { |
18598 | 162 |
REGISTER int pos = __intVal(p) + 1; /* make 1-based */ |
163 |
OBJ wL = __INST(writeLimit); |
|
8298 | 164 |
|
165 |
if ((wL == nil) |
|
166 |
|| (__isSmallInteger(wL) && (pos <= __intVal(wL)))) { |
|
18598 | 167 |
OBJ cls = __qClass(coll); |
168 |
unsigned ch = __intVal(__characterVal(aCharacter)); |
|
169 |
OBJ rL = __INST(readLimit); |
|
170 |
int __readLimit = -1; |
|
8298 | 171 |
|
172 |
if (__isSmallInteger(rL)) { |
|
173 |
__readLimit = __intVal(rL); |
|
174 |
} |
|
175 |
||
176 |
if (cls == @global(String)) { |
|
177 |
if (ch > 0xFF) { |
|
178 |
goto resize; |
|
179 |
} |
|
180 |
if (pos <= __stringSize(coll)) { |
|
181 |
__StringInstPtr(coll)->s_element[pos-1] = ch; |
|
182 |
if ((__readLimit >= 0) && (pos >= __readLimit)) { |
|
8913 | 183 |
__INST(readLimit) = __mkSmallInteger(pos); |
8298 | 184 |
} |
8913 | 185 |
__INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1); |
8321 | 186 |
RETURN ( aCharacter ); |
8298 | 187 |
} |
188 |
} else if (cls == @global(Unicode16String)) { |
|
189 |
if (ch > 0xFFFF) { |
|
190 |
goto resize; |
|
191 |
} |
|
192 |
if (pos <= __unicode16StringSize(coll)) { |
|
193 |
__Unicode16StringInstPtr(coll)->s_element[pos-1] = ch; |
|
194 |
if ((__readLimit >= 0) && (pos >= __readLimit)) { |
|
8913 | 195 |
__INST(readLimit) = __mkSmallInteger(pos); |
8298 | 196 |
} |
8913 | 197 |
__INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1); |
8321 | 198 |
RETURN ( aCharacter ); |
8298 | 199 |
} |
200 |
} else if (cls == @global(Unicode32String)) { |
|
201 |
if ((pos <= __unicode32StringSize(coll))) { |
|
202 |
__Unicode32StringInstPtr(coll)->s_element[pos-1] = ch; |
|
203 |
if ((__readLimit >= 0) && (pos >= __readLimit)) { |
|
8913 | 204 |
__INST(readLimit) = __mkSmallInteger(pos); |
8298 | 205 |
} |
8913 | 206 |
__INST(position) = __mkSmallInteger(__intVal(__INST(position)) + 1); |
8321 | 207 |
RETURN ( aCharacter ); |
8298 | 208 |
} |
209 |
} |
|
210 |
} |
|
211 |
} |
|
212 |
resize:; |
|
213 |
#endif |
|
214 |
%}. |
|
215 |
||
8321 | 216 |
|
8298 | 217 |
(writeLimit isNil |
15349
7c2c460c5feb
class: CharacterWriteStream
Claus Gittinger <cg@exept.de>
parents:
14607
diff
changeset
|
218 |
or:[(position + 1) <= writeLimit]) ifTrue:[ |
18598 | 219 |
|needCharacterSize| |
220 |
||
221 |
needCharacterSize := aCharacter characterSize. |
|
222 |
needCharacterSize > currentCharacterSize ifTrue:[ |
|
223 |
self characterSizeChangedTo:needCharacterSize size:1. |
|
224 |
] ifFalse:[ |
|
225 |
(position >= collection size) ifTrue:[self growCollection]. |
|
8321 | 226 |
]. |
15349
7c2c460c5feb
class: CharacterWriteStream
Claus Gittinger <cg@exept.de>
parents:
14607
diff
changeset
|
227 |
collection at:(position + 1) put:aCharacter. |
15358
6b69ebd9785c
class: CharacterWriteStream
Claus Gittinger <cg@exept.de>
parents:
15349
diff
changeset
|
228 |
(position >= readLimit) ifTrue:[readLimit := (position + 1)]. |
8298 | 229 |
position := position + 1. |
230 |
] ifFalse:[ |
|
8321 | 231 |
WriteError raiseErrorString:'write beyond writeLimit' |
232 |
]. |
|
233 |
^ aCharacter |
|
234 |
! |
|
235 |
||
236 |
nextPutAll:aCollection |
|
11319 | 237 |
"append aCollection to the receiver. |
238 |
Redefined to convert to a string of the needed charcter size." |
|
8321 | 239 |
|
18598 | 240 |
|needCharacterSize| |
241 |
||
242 |
needCharacterSize := aCollection characterSize. |
|
243 |
needCharacterSize > currentCharacterSize ifTrue:[ |
|
244 |
self characterSizeChangedTo:needCharacterSize size:aCollection size. |
|
8298 | 245 |
]. |
12133 | 246 |
super nextPutAll:aCollection |
8321 | 247 |
! |
248 |
||
249 |
nextPutAll:aCollection startingAt:start to:stop |
|
18598 | 250 |
|needCharacterSize| |
251 |
||
252 |
needCharacterSize := aCollection characterSize. |
|
253 |
needCharacterSize > currentCharacterSize ifTrue:[ |
|
254 |
self characterSizeChangedTo:needCharacterSize size:stop-start+1. |
|
8321 | 255 |
]. |
256 |
^ super nextPutAll:aCollection startingAt:start to:stop |
|
11319 | 257 |
! |
258 |
||
259 |
nextPutAllUnicode:aCollection |
|
260 |
^ self nextPutAll:aCollection |
|
261 |
! |
|
262 |
||
263 |
nextPutUnicode:aCharacter |
|
264 |
^ self nextPut:aCharacter |
|
8298 | 265 |
! ! |
266 |
||
8321 | 267 |
!CharacterWriteStream class methodsFor:'documentation'! |
268 |
||
269 |
version |
|
18590 | 270 |
^ '$Header$' |
12133 | 271 |
! |
272 |
||
273 |
version_CVS |
|
18590 | 274 |
^ '$Header$' |
8321 | 275 |
! ! |
14607 | 276 |