eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'PositionableStream':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: PositionableStream


Inheritance:

   Object
   |
   +--Stream
      |
      +--PeekableStream
         |
         +--PositionableStream
            |
            +--ReadStream
            |
            +--WriteStream

Package:
stx:libbasic
Category:
Streams
Version:
rev: 1.221 date: 2023/12/12 21:52:16
user: cg
file: PositionableStream.st directory: libbasic
module: stx stc-classLibrary: libbasic

Description:


Instances of PositionableStream allow positioning the read pointer.
The PositionableStream class also adds methods for source-chunk reading
and writing, and for filing-in/out of source code.

This is an abstract class.

Compatibility Notice:
    In previous versions of ST/X, streams started with a 1-position (i.e. as in collections),
    while ST-80 has always been using 0-based postions for streams and 1-based positions for collections.

    THIS CERTAINLY IS BAD.

    Although this is confusing ST/X has been changed to now also uses 0-based stream positioning.

[caveat:]
    Basing capabilities like readability/writability/positionability/peekability on inheritance makes
    the class hierarchy ugly and leads to strange and hard to teach redefinitions (aka. NonPositionableStream
    below PositionableStream or ExternalReadStream under WriteStream)

copyright

COPYRIGHT (c) 1989 by Claus Gittinger All Rights Reserved This software is furnished under a license and may be used only in accordance with the terms of that license and with the inclusion of the above copyright notice. This software may not be provided or otherwise made available to, or used by, any other person. No title to or ownership of the software is hereby transferred.

Class protocol:

Signal constants
o  invalidPositionErrorSignal
return the signal raised if positioning is attempted to an
invalid position (i.e. before the begin of the stream or after
the end)

class initialization
o  initialize
changed with stx rel5.1;

constants
o  zeroPosition
return the number, which marks the initial position.
Compatibility Notice:
In previous versions of ST/X, streams started with a 1-position (i.e. as in collections),
while ST-80 has always been using 0-based postions for streams and 1-based positions for collections.

Although this is confusing ST/X has been changed to now also use 0-based stream positioning.

instance creation
o  on: aCollection
return a new PositionableStream streaming on aCollection

o  on: aCollection from: first to: last
return a new PositionableStream streaming on aCollection
from first to last

o  with: aCollection
return a new PositionableStream streaming on aCollection,
the stream is positioned to the end of the collection.

testing
o  isAbstract
Return if this class is an abstract class.
True is returned here for myself only; false for subclasses.
Abstract subclasses must redefine this again.


Instance protocol:

Compatibility-Dolphin
o  endChunk

Compatibility-ST/V
o  skipTo: anElement
ST/V compatibility:
skip for the element given by the argument, anElement;
return nil if not found, self otherwise.
On a successful match, the next read will return the element after anElement.

Usage example(s):

     |s|
     s := ReadStream on:'12345678901234567890'.
     s skipTo:$5.
     s copyFrom:1 to:(s position).    
     s upToEnd      

Compatibility-Squeak
o  back
Go back one element and return it.

o  peekBack
Return the element at the previous position, without changing position. Use indirect messages in case self is a StandardFileStream.

accessing
o  collection
return the underlying collection buffer.
Notice, that this buffer may become invalid after being retrieved,
if more data is written to the stream (because a bigger buffer might be
allocated). Therefore, it should be only used in special situations,
where an already filled buffer needs to be backpatched later
(eg. before being sent out to some external stream or socket)

o  contents
return the entire contents of the stream

o  peekForAll: aCollection
return true and advance if the next elements are the same
as aCollection.
otherwise stay and let the position unchanged

o  readLimit
return the read-limit; that's the position at which EOF is returned

o  readLimit: aNumber
set the read-limit; that's the position at which EOF is returned

o  setCollection: newCollection

o  writeLimit: aNumber
set the writeLimit; that's the position after which writing is prohibited

comparing
o  endsBeforePositionWith: aSequenceableCollection
answer true, if the elements in aSequenceableCollection
are at the current end of the stream up to position.

Usage example(s):

        ('' writeStream nextPutAll:'Hello World') endsBeforePositionWith:'World'
        ('' writeStream nextPutAll:'Hello World') endsBeforePositionWith:'Hello World'
        ('' writeStream nextPutAll:'Hello World') endsBeforePositionWith:'Hello Worldx'
        ('' writeStream nextPutAll:'Hello World') endsBeforePositionWith:'Bla'
        ('' writeStream) endsBeforePositionWith:'Bla'
        ('' writeStream) endsBeforePositionWith:''
        ''  endsWith:''

o  isContentsEqualTo: aSequenceableCollection
answer true, if the contents of myself from the current position
to the end is equal to aStringOrByteArray.

non homogenous reading
o  nextBytes: numBytes into: aCollection startingAt: initialIndex
return the next numBytes from the stream. If the end is
reached before, only that many bytes are copied into the
collection.
Returns the number of bytes that have been actually read.
The receiver must support reading of binary bytes.

Notice: this method is provided here for protocol completeness
with externalStreams - it is normally not used with other
streams.

Usage example(s):

     |s n buffer|

     buffer := ByteArray new:10.

     s := ReadStream on:#[1 2 3 4 5 6 7 8 9].
     s next:3.
     n := s nextBytes:9 into:buffer startingAt:1.
     Transcript showCR:('n = %1; buffer = <%2>' bindWith:n with:buffer)

obsolete positioning
o  position0Based
return the read position 0-based

** This is an obsolete interface - do not use it (it may vanish in future versions) **

o  position1Based
return the read position 1-based

** This is an obsolete interface - do not use it (it may vanish in future versions) **

positioning
o  backStep
ReadStream: move backward read position by one;
WriteStream: forget the last written element

o  match: subCollection
Set the access position of the receiver to be past the next occurrence of the subCollection.
Answer whether subCollection is found.
No wildcards, and case does matter.

Usage example(s):

     'abc def ghi' readStream match:'def'; upToEnd  

o  position
return the read position (0-based)

o  position0Based: index0Based
set the read (or write) position

** This is an obsolete interface - do not use it (it may vanish in future versions) **

o  position1Based: index1Based
set the read (or write) position

** This is an obsolete interface - do not use it (it may vanish in future versions) **

o  position: index0Based
set the read (or write) position

o  reset
set the read position to the beginning of the collection

Usage example(s):

     |s|

     s := 'hello world' readStream.
     Transcript showCR:(s next:5).
     s reset.
     Transcript showCR:(s next:10).

o  resetPosition
set the read position to the beginning of the collection

** This is an obsolete interface - do not use it (it may vanish in future versions) **

o  setToEnd
set the read position to the end of the collection.
#next will return EOF, #nextPut: will append to the stream.
(same Behavior as FileStream.

o  skip: numberToSkip
skip the next numberToSkip elements;
returns the receiver

o  skipThroughAll: aCollection
skip for and through the sequence given by the argument, aCollection;
return nil if not found, self otherwise.
On a successful match, the next read will return elements after aCollection;
if no match was found, the receiver will be positioned at the end.
This is redefined here, to make use of positioning.

Usage example(s):

     |s|
     s := ReadStream on:'12345678901234567890a'.
     s skipThroughAll:'90ab'.
     s upToEnd  

Usage example(s):

     |s|
     s := ReadStream on:'12345678901234567890'.
     s skipThroughAll:'1234'.
     s upToEnd  

Usage example(s):

     |s|
     s := ReadStream on:'12345678901234567890'.
     s skipThroughAll:'999'.
     s atEnd  

o  skipToAll: aCollection
skip for the sequence given by the argument, aCollection;
return nil if not found, self otherwise.
On a successful match, the next read will return elements of aCollection.

Usage example(s):

     |s|
     s := ReadStream on:'12345678901234567890'.
     s skipToAll:'901'.
     s upToEnd  

Usage example(s):

     |s|
     s := ReadStream on:'1234567890'.
     s skipToAll:'901'.
     s upToEnd  

Usage example(s):

     |s|
     s := 'Makefile' asFilename readStream.
     [
         (s skipToAll:'EDIT') notNil ifTrue:[
            s next:100.
         ].
     ] ensure:[
        s close.
     ]

printing & storing
o  printOn: aStream
'' readStream printString
'' writeStream printString

private
o  on: aCollection
setup for streaming on aCollection

o  on: aCollection from: first to: last
setup for streaming on aCollection from first to last

o  positionError
report an error when positioning past the end
or before the beginning.

o  positionError: badPostition
report an error when positioning past the end
or before the beginning.

o  with: aCollection
setup for streaming to the end of aCollection

Usage example(s):

      (WriteStream with:#(1 2 3 4 5)) 
            nextPut:6;
            contents

queries
o  atEnd
return true, if the read-position is at the end

o  collectionSize
common stream protocol: return the size of the stream

** This method must be redefined in concrete classes (subclassResponsibility) **

o  contentsSpecies
return a class of which instances will be returned, when
parts of the collection are asked for.
(see upTo-kind of methods in Stream)

o  encoding
for compatibility with encoded stream

Usage example(s):

        'abcde' readStream encoding
        'abcdeАБВГДЕ' readStream encoding

o  remainingSize

reading
o  nextAvailable: count
return the next count elements of the stream as aCollection.
If the stream reaches the end before count elements have been read,
return what is available. (i.e. a shorter collection).

Usage example(s):

        'abc' readStream nextAvailable:1.
        'abc' readStream nextAvailable:2.
        'abc' readStream nextAvailable:3.
        'abc' readStream nextAvailable:4.

        'abc' readStream nextAvailable:2; nextAvailable:2.
        'abc' readStream nextAvailable:3; nextAvailable:3.

o  nextAvailable: count into: aCollection startingAt: initialIndex
return the next count objects from the stream. If the end is
reached before, only that many objects are copied into the
collection.
Returns the number of objects that have been actually read.

o  peek
look ahead for and return the next element

o  peek: n
look ahead n elements and return them after positioning back to the
position we had before

Usage example(s):

     |s|

     s := '1234567890' readStream.
     s peek:4.
     s next:5.

o  upTo: anObject
slightly less optimized version for UnicodeStrings

Usage example(s):

        '12345678' readStream upTo:$5; upToEnd
        '12345678' asUnicodeString readStream upTo:$5; upToEnd
        '12345678' readStream upTo:$z.
        '12345678' asUnicodeString readStream upTo:$z.

o  upToAll: aCollection
read until a subcollection consisisting of the elements in aCollection is encountered.
Return everything read excluding the elements in aCollection.
The position is left before the collection; i.e. the next
read operations will return those elements.
If no such subcollection is encountered, all elements up to the end
are read and returned.
See also #throughAll: which also reads up to some objects
but positions behind it and DOES include it in the returned
collection.
See also #upToAllExcluding:, which returns the same, but leaves the
read pointer after the matched subcollection.

Note: this behavior is inconsistent with the other upTo.. methods,
which position after the found item. We implement the method
this way for the sake of ST80-compatibility.

Usage example(s):

     |s|
     s := ReadStream on:'hello world'.
     Transcript show:'<'; show:(s upToAll:'wo'); showCR:'>'. 
     Transcript showCR:s atEnd.
     Transcript show:'<'; show:(s upToEnd); showCR:'>'. 

Usage example(s):

     |s|
     s := ReadStream on:'hello world'.
     Transcript show:'<'; show:(s upToAll:'wo'); showCR:'>'. 
     Transcript showCR:s atEnd.
     Transcript show:'<'; show:(s upToAll:'wo'); showCR:'>'. 

Usage example(s):

     |s|
     s := ReadStream on:'hello world'.
     Transcript show:'<'; show:(s upToAll:'xx'); showCR:'>'. 
     Transcript showCR:s atEnd.
     Transcript show:'<'; show:(s upToEnd); showCR:'>'. 

o  upToAll_positionBefore: aCollection
read until a subcollection consisisting of the elements in aCollection is encountered.
Return everything read excluding the elements in aCollection.
The position is left before the collection; i.e. the next
read operations will return those elements.
If no such subcollection is encountered, all elements up to the end
are read and returned.
See also #throughAll: which also reads up to some objects
but positions behind it and DOES include it in the returned
collection.

Usage example(s):

     |s|
     s := ReadStream on:'hello world'.
     Transcript show:'<'; show:(s upToAll_positionBefore:'wo'); showCR:'>'. 
     Transcript showCR:s atEnd.
     Transcript show:'<'; show:(s upToEnd); showCR:'>'. 

Usage example(s):

     |s|
     s := ReadStream on:'hello world'.
     Transcript show:'<'; show:(s upToAll_positionBefore:'wo'); showCR:'>'. 
     Transcript showCR:s atEnd.
     Transcript show:'<'; show:(s upToAll_positionBefore:'wo'); showCR:'>'. 

Usage example(s):

     |s|
     s := ReadStream on:'hello world'.
     Transcript show:'<'; show:(s upToAll_positionBefore:'xx'); showCR:'>'. 
     Transcript showCR:s atEnd.
     Transcript show:'<'; show:(s upToEnd); showCR:'>'. 

o  upToEnd
return a collection of the elements up-to the end.
Return an empty collection, if the stream is already at the end.

Usage example(s):

     'abc' readStream upToEnd.

reading-strings
o  nextLine
return the characters upTo (but excluding) the next lf (line feed)
character (i.e. read a single line of text).
If the previous-to-last character is a cr, this is also removed,
so it's possible to read alien (i.e. ms-dos) text as well.
Added for protocol compatibility with externalStreams.

Usage example(s):

        '12345678' readStream nextLine
        '12345678' allBold readStream nextLine
        '12\34\56\78' withCRs readStream nextLine
        '12\34\56\78' withCRs readStream nextLine; nextLine
        (ReadStream on:('12\34\56\78' withCRs) from:1 to:4) nextLine; nextLine
        ('12\' withCRs, Character return, '34') readStream nextLine; nextLine
        Character cr asString readStream nextLine
        Character return asString readStream nextLine
        (Character return, Character cr) asString readStream nextLine
        Character return asString readStream nextLine; nextLine

stream-to-stream copy
o  copy: numberOfElementsOrNil into: aWriteStream
read from the receiver, and write numberOfElementsOrNil data to another aWriteStream.
If numberOfElementsOrNil is nil, copy until the end of myself.
Return the number of elements which have been transferred.
Redefined here to avoid intermediate buffers/garbage.

Usage example(s):

      'hello world' readStream copy:5 into:'/tmp/mist' asFilename writeStream.
      'hello world' readStream 
                        copy:5 into:Transcript;
                        copy:20 into:Transcript.
      'hello world' readStream copy:5 into:'' writeStream inspect.
      #[1 2 3 4 5 6 7] readStream copy:2 into:'/tmp/mist' asFilename writeStream binary.
      #[1 2 3 4 5 6 7] readStream copy:3 into:#[] writeStream.

o  copy: numberOfElementsOrNil into: aWriteStream bufferSize: bufferSize
read from the receiver, and write numberOfElementsOrNil to another aWriteStream.
If numberOfElementsOrNil is nil, copy until the end of myself.
Return the number of elements which have been transferred.
Redefined here to avoid intermediate buffers/garbage
- bufferSize does not matter here.

o  copyToEndInto: aWriteStream
read from the receiver, and write up to the end of nyself data to another aWriteStream.
Return the number of elements which have been transferred.
Redefined here to avoid intermediate buffers/garbage.

testing
o  isEmpty
return true, if the contents of the stream is empty

o  isInternalByteStream
return true, if the stream is an internal stream reading bytes

Usage example(s):

      '' readStream isInternalByteStream.
      #[] readStream isInternalByteStream.
      UnicodeString new readStream isInternalByteStream.

o  isPositionable
return true, if the stream supports positioning (this one is)

o  isUnicodeEncoded
return true, if the streamed collection is any string (8-, 16- or 32-bit),
which definitly is not using UTF-x or JIS or any other encoding.
I.e. 'self next' always returns a unicode character.
Note: the answer of false does not mean that it is not unicode,
but it does mean that we don't know for sure.

Usage example(s):

     '' readStream isUnicodeEncoded 



ST/X 7.7.0.0; WebServer 1.702 at 20f6060372b9.unknown:8081; Sat, 27 Jul 2024 03:05:01 GMT