PositionableStream.st
changeset 3032 d267a0b1b48d
parent 2966 856dfc8a294a
child 3170 7b299d83c45a
equal deleted inserted replaced
3031:565ba030c404 3032:d267a0b1b48d
     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.
   516                         ex proceed
   528                         ex proceed
   517                     ].
   529                     ].
   518                     action == #abort ifTrue:[
   530                     action == #abort ifTrue:[
   519                         ex return
   531                         ex return
   520                     ].
   532                     ].
   521                     (ex signal) enterDebuggerWith:ex message:what.
   533                     "/ (ex signal) enterDebuggerWith:ex message:what.
   522                     ex reject
   534                     ex reject
   523                 ] do:[
   535                 ] do:[
   524                     [self atEnd] whileFalse:[
   536                     [self atEnd] whileFalse:[
   525                         lastValue := self fileInNextChunkNotifying:someone passChunk:passChunk
   537                         lastValue := self fileInNextChunkNotifying:someone passChunk:passChunk
   526                     ]
   538                     ]
   528             ].
   540             ].
   529         ].
   541         ].
   530     ].
   542     ].
   531     ^ lastValue
   543     ^ lastValue
   532 
   544 
   533     "Modified: 31.8.1997 / 07:39:53 / cg"
   545     "Modified: 14.10.1997 / 15:55:11 / cg"
   534 ! !
   546 ! !
   535 
   547 
   536 !PositionableStream methodsFor:'positioning'!
   548 !PositionableStream methodsFor:'positioning'!
   537 
   549 
   538 backStep
   550 backStep
   722 ! !
   734 ! !
   723 
   735 
   724 !PositionableStream class methodsFor:'documentation'!
   736 !PositionableStream class methodsFor:'documentation'!
   725 
   737 
   726 version
   738 version
   727     ^ '$Header: /cvs/stx/stx/libbasic/PositionableStream.st,v 1.58 1997-09-22 19:05:41 cg Exp $'
   739     ^ '$Header: /cvs/stx/stx/libbasic/PositionableStream.st,v 1.59 1997-10-15 12:33:37 cg Exp $'
   728 ! !
   740 ! !
   729 PositionableStream initialize!
   741 PositionableStream initialize!