8 be provided or otherwise made available to, or used by, any |
8 be provided or otherwise made available to, or used by, any |
9 other person. No title to or ownership of the software is |
9 other person. No title to or ownership of the software is |
10 hereby transferred. |
10 hereby transferred. |
11 " |
11 " |
12 |
12 |
13 'From Smalltalk/X, Version:3.1.9 on 31-aug-1997 at 8:08:34 pm' ! |
13 'From Smalltalk/X, Version:3.2.1 on 14-oct-1997 at 11:16:17 pm' ! |
14 |
14 |
15 PeekableStream subclass:#PositionableStream |
15 PeekableStream subclass:#PositionableStream |
16 instanceVariableNames:'collection position readLimit writeLimit' |
16 instanceVariableNames:'collection position readLimit writeLimit' |
17 classVariableNames:'InvalidPositionErrorSignal ErrorDuringFileInSignal ChunkSeparator' |
17 classVariableNames:'InvalidPositionErrorSignal ErrorDuringFileInSignal ChunkSeparator' |
18 poolDictionaries:'' |
18 poolDictionaries:'' |
63 |
63 |
64 ChunkSeparator := $!! |
64 ChunkSeparator := $!! |
65 ] |
65 ] |
66 ! ! |
66 ! ! |
67 |
67 |
|
68 !PositionableStream class methodsFor:'instance creation'! |
|
69 |
|
70 on:aCollection |
|
71 "return a new PositionableStream streaming on aCollection" |
|
72 |
|
73 ^ (self basicNew) on:aCollection |
|
74 ! |
|
75 |
|
76 on:aCollection from:first to:last |
|
77 "return a new PositionableStream streaming on aCollection |
|
78 from first to last" |
|
79 |
|
80 ^ (self basicNew) on:aCollection from:first to:last |
|
81 ! |
|
82 |
|
83 with:aCollection |
|
84 "return a new PositionableStream streaming on aCollection, |
|
85 the stream is positioned to the end of the collection." |
|
86 |
|
87 ^ (self basicNew) with:aCollection |
|
88 ! ! |
|
89 |
68 !PositionableStream class methodsFor:'Signal constants'! |
90 !PositionableStream class methodsFor:'Signal constants'! |
69 |
91 |
70 invalidPositionErrorSignal |
92 invalidPositionErrorSignal |
71 "return the signal raised if positioning is attempted to an |
93 "return the signal raised if positioning is attempted to an |
72 invalid position (i.e. before the begin of the stream or after |
94 invalid position (i.e. before the begin of the stream or after |
73 the end)" |
95 the end)" |
74 |
96 |
75 ^ InvalidPositionErrorSignal |
97 ^ InvalidPositionErrorSignal |
76 ! ! |
|
77 |
|
78 !PositionableStream class methodsFor:'instance creation'! |
|
79 |
|
80 on:aCollection |
|
81 "return a new PositionableStream streaming on aCollection" |
|
82 |
|
83 ^ (self basicNew) on:aCollection |
|
84 ! |
|
85 |
|
86 on:aCollection from:first to:last |
|
87 "return a new PositionableStream streaming on aCollection |
|
88 from first to last" |
|
89 |
|
90 ^ (self basicNew) on:aCollection from:first to:last |
|
91 ! |
|
92 |
|
93 with:aCollection |
|
94 "return a new PositionableStream streaming on aCollection, |
|
95 the stream is positioned to the end of the collection." |
|
96 |
|
97 ^ (self basicNew) with:aCollection |
|
98 ! ! |
98 ! ! |
99 |
99 |
100 !PositionableStream class methodsFor:'constants'! |
100 !PositionableStream class methodsFor:'constants'! |
101 |
101 |
102 chunkSeparator |
102 chunkSeparator |
384 |
384 |
385 fileInNextChunkNotifying:someone passChunk:passChunk |
385 fileInNextChunkNotifying:someone passChunk:passChunk |
386 "read next chunk, evaluate it and return the result; |
386 "read next chunk, evaluate it and return the result; |
387 someone (which is usually some codeView) is notified of errors. |
387 someone (which is usually some codeView) is notified of errors. |
388 Filein is done as follows: |
388 Filein is done as follows: |
389 read a chunk |
389 read a chunk |
390 if it started with an excla, evaluate it, and let the resulting object |
390 if it started with an excla, evaluate it, and let the resulting object |
391 fileIn more chunks. |
391 fileIn more chunks. |
392 This is a nice trick, since the methodsFor: expression evaluates to |
392 This is a nice trick, since the methodsFor: expression evaluates to |
393 a ClassCategoryReader which reads and compiles chunks for its class. |
393 a ClassCategoryReader which reads and compiles chunks for its class. |
394 However, other than methodsFor expressions are possible - you can |
394 However, other than methodsFor expressions are possible - you can |
395 (in theory) create readers for any syntax. |
395 (in theory) create readers for any syntax. |
396 " |
396 " |
397 |
397 |
398 |aString sawExcla rslt done| |
398 |aString sawExcla rslt done| |
399 |
399 |
400 self skipSeparators. |
400 self skipSeparators. |
401 self atEnd ifFalse:[ |
401 self atEnd ifFalse:[ |
402 sawExcla := self peekFor:ChunkSeparator. |
402 sawExcla := self peekFor:ChunkSeparator. |
403 aString := self nextChunk. |
403 aString := self nextChunk. |
404 aString size ~~ 0 ifTrue:[ |
404 "/ |
405 passChunk ifTrue:[ |
405 "/ handle empty chunks; |
406 someone source:aString |
406 "/ this allows for Squeak code to be filedIn |
407 ]. |
407 "/ |
408 sawExcla ifFalse:[ |
408 [aString size == 0 |
409 rslt := Compiler evaluate:aString notifying:someone. |
409 and:[self atEnd not]] whileTrue:[ |
410 ] ifTrue:[ |
410 aString := self nextChunk. |
411 rslt := Compiler evaluate:aString notifying:someone compile:false. |
411 ]. |
412 |
412 aString size ~~ 0 ifTrue:[ |
413 " |
413 passChunk ifTrue:[ |
414 usually, the above chunk consists of some methodsFor:-expression |
414 someone source:aString |
415 in this case, the returned value is a ClassCategoryReader, |
415 ]. |
416 which is used to load & compile the methods ... |
416 sawExcla ifFalse:[ |
417 " |
417 rslt := Smalltalk::Compiler evaluate:aString notifying:someone. |
418 rslt isNil ifTrue:[ |
418 ] ifTrue:[ |
419 " |
419 Smalltalk::Compiler emptySourceNotificationSignal handle:[:ex | |
420 however, if that was nil (i.e. some error), we skip chunks |
420 ^ nil |
421 up to the next empty chunk. |
421 ] do:[ |
422 " |
422 rslt := Smalltalk::Compiler evaluate:aString notifying:someone compile:false. |
423 Transcript showCR:'skipping chunks ...'. |
423 ]. |
424 done := false. |
424 |
425 [done] whileFalse:[ |
425 " |
426 aString := self nextChunk. |
426 usually, the above chunk consists of some methodsFor:-expression |
427 done := (aString size == 0) or:[aString isEmpty]. |
427 in this case, the returned value is a ClassCategoryReader, |
428 ] |
428 which is used to load & compile the methods ... |
429 ] ifFalse:[ |
429 " |
430 rslt := rslt fileInFrom:self notifying:someone passChunk:passChunk |
430 rslt isNil ifTrue:[ |
431 ] |
431 " |
432 ] |
432 however, if that was nil (i.e. some error), we skip chunks |
433 ] |
433 up to the next empty chunk. |
|
434 " |
|
435 Transcript showCR:'skipping chunks ...'. |
|
436 done := false. |
|
437 [done] whileFalse:[ |
|
438 aString := self nextChunk. |
|
439 done := (aString size == 0) or:[aString isEmpty]. |
|
440 ] |
|
441 ] ifFalse:[ |
|
442 rslt := rslt fileInFrom:self notifying:someone passChunk:passChunk |
|
443 ] |
|
444 ] |
|
445 ] |
434 ]. |
446 ]. |
435 ^ rslt |
447 ^ rslt |
436 |
448 |
437 "Modified: 18.5.1996 / 15:44:21 / cg" |
449 "Modified: 14.10.1997 / 17:10:35 / cg" |
438 ! |
450 ! |
439 |
451 |
440 fileInNotifying:someone passChunk:passChunk |
452 fileInNotifying:someone passChunk:passChunk |
441 "file in from the receiver, i.e. read chunks and evaluate them - |
453 "file in from the receiver, i.e. read chunks and evaluate them - |
442 return the value of the last chunk. |
454 return the value of the last chunk. |