|
Class: ExternalStream
Object
|
+--Stream
|
+--PeekableStream
|
+--PositionableStream
|
+--WriteStream
|
+--ReadWriteStream
|
+--ExternalStream
|
+--ExternalReadStream
|
+--ExternalWriteStream
|
+--FileStream
|
+--NonPositionableExternalStream
- Package:
- stx:libbasic
- Category:
- Streams-External
- Version:
- rev:
1.599
date: 2024/03/13 13:58:33
- user: cg
- file: ExternalStream.st directory: libbasic
- module: stx stc-classLibrary: libbasic
ExternalStream defines protocol common to Streams which have a file-descriptor and
represent some file or communicationChannel of the underlying OperatingSystem.
ExternalStream is abstract; concrete classes are FileStream, PipeStream etc.
ExternalStreams can be in two modes: text- (the default) and binary-mode.
In text-mode, the elements read/written are characters;
while in binary-mode the basic elements are bytes which read/write as SmallIntegers
in the range 0..255.
Also, the stream can be either in buffered or unbuffered mode. In buffered mode,
data is not written until either a cr is written (in text mode) or a synchronizeOutput
is sent (in both modes).
The underlying OperatingSystem streams may either be closed explicitely (sending a close)
or just forgotten - in this case, the garbage collector will eventually collect the
object AND a close will be performed automatically (but you will NOT know when this
happens - so it is recommended, that you close your files when no longer needed).
Closing is also suggested, since if smalltalk is finished (be it by purpose, or due to
some crash) the data will not be in the file, if unclosed.
All streams understand the close message, so it never hurts to use it (it is defined as
a noop in one of the superclasses).
Most of the methods found here redefine inherited methods for better performance,
since I/O from/to files should be fast.
Recovering a snapshot:
not all streams can be restored to the state they had before - see the implementation of
reOpen in subclasses for more information.
For streams sitting on some communication channel (i.e. Pipes and Sockets) you should
reestablish the stream upon image restart (make someone dependent on ObjectMemory).
FileStreams are reopened and positioned to their offset they had at snapshot time.
This may fail, if the file was removed or renamed - or lead to confusion
if the contents changed in the meantime.
Therefore, it is a good idea to reopen files and check for these things at restart time.
[Instance variables:]
handleType <Symbol> desribes what handle is:
win32: #fileHandle, #socketHandle,
#filePointer, #socketFilePointer, #pipeFilePointer
unix: #filePointer, #socketFilePointer, #pipeFilePointer
needed for win32, which uses different APIs for the different handles (sigh)
handle <Integer> used to be always a filePointer somehow mapped to an integer (FILE* - not the fd);
now, either a filePointer or a handle (win32)
mode <Symbol> #readwrite, #readonly or #writeonly
buffered <Boolean> true, if buffered (i.e. collects characters - does
not output immediately)
binary <Boolean> true if in binary mode (reads bytes instead of chars)
eolMode <Symbol> one of nil, #nl, #cr or #crlf.
determines how lines should be terminated.
nil -> newLine (as in Unix);
#crlf -> with cr-lf (as in MSDOS)
#cr -> with cr (as in VMS)
hitEOF <Boolean> true, if EOF was reached
lastErrorNumber <Integer> the value of errno (only valid right after the error -
updated with next i/o operation)
[Class variables:]
Lobby <Registry> keeps track of used ext-streams (to free up FILE*'s)
StreamErrorSignal <Signal> parent of all stream errors (see Stream class)
InvalidReadSignal <Signal> raised on read from writeonly stream
InvalidWriteSignal <Signal> raised on write to readonly stream
InvalidModeSignal <Signal> raised on text I/O with binary-stream
or binary I/O with text-stream
OpenErrorSignal <Signal> raised if open fails
StreamNotOpenSignal <Signal> raised on I/O with non-open stream
Additional notes:
This class is implemented using the underlying stdio-c library package, which
has both advantages and disadvantages: since it is portable (posix defined), porting
ST/X to non-Unix machines is simplified. The disadvantage is that the stdio library
has big problems handling unbounded Streams, since the EOF handling in stdio is
not prepared for data to arrive after EOF has been reached - time will show, if we need
a complete rewrite for UnboundedStream ...
Also, depending on the system, the stdio library behaves infriendly when signals
occur while reading (for example, timer interrupts) - on real unixes (i.e. BSD) the signal
is handled transparently - on SYS5.3 (i.e. non unixes :-) the read operation returns
an error and errno is set to EINTR.
That's what the ugly code around all getc-calls is for ...
Since things get more and more ugly - we will rewrite ExternalStream
completely, to NOT use any stdio stuff (and do its buffering itself).
Notice that typical stdio's use a single errno global variable to return an error code,
this was bad design in the stdio lib (right from the very beginning), since it's much
harder to deal with this in the presence of lightweight processes, where errno gets
overwritten by an I/O operation done in another thread. (stdio should have been written
to return errno as a negative number ...).
To deal with this, the scheduler treats errno like a per-thread private variable,
and saves/restores the errno setting when switching to another thread.
(Notice that some thread packages do this also, but ST/X's thread implementation
does not depend on those, but instead uses a portable private package).
Finally, if an stdio-stream is open for both reading and writing, we have to call
fseek whenever we are about to read after write and vice versa.
Two macros (__READING__ and __WRITING__) have been defined to be used before every
fread/fgetc and fwrite/putc respectively.
copyrightCOPYRIGHT (c) 1988 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.
Signal constants
-
inaccessibleSignal
-
ST-80 compatibility: return openErrorSignal
-
invalidModeSignal
-
return the signal raised when doing text-I/O with a binary stream
or binary-I/O with a text stream
-
invalidOperationSignal
-
return the signal raised when an unsupported or invalid
I/O operation is attempted
-
invalidReadSignal
-
return the signal raised when reading from writeonly streams
-
invalidWriteSignal
-
return the signal raised when writing to readonly streams
-
openErrorSignal
-
return the signal raised when a file open failed
-
streamIOErrorSignal
-
return the signal raised when an I/O error occurs.
(for example, a device-IO-error, or reading an NFS-dir,
which is no longer available and has been mounted soft)
-
streamNotOpenSignal
-
return the signal raised on I/O with closed streams
accessing
-
openStreams
-
answer a collection of open Streams having this class
Usage example(s):
self openStreams
Socket openStreams
NonPositionableExternalStream openStreams
|
class initialization
-
closeFiles
-
close all files.
To be called on exit of Smalltalk.
-
initDefaultEOLMode
-
unix EOL conventions
-
initModeStrings
-
initialize modeStrings which are passed down to the underlying
fopen/fdopen functions.
-
initialize
-
self patchByteOrderOptimizedMethods
-
patchByteOrderOptimizedMethods
-
EXPERIMENTAL (not yet done by default):
change the underlying implementation of
nextPutInt16MSB / nextPutInt16LSB
nextPutInt32MSB / nextPutInt32LSB
to the corresponding NATIVE methods.
-
reOpenFiles
-
reopen all files (if possible) after a snapShot load.
This is invoked via the #earlyRestart change notification.
-
update: something with: aParameter from: changedObject
-
have to reopen files when returning from snapshot
defaults
-
defaultCopyBufferSize: anInteger
-
allows changing the size of buffer used when copying big
files/buld data from one stream to another.
Due to a bug on older Windows systems, the default used in copyToEndInto:
is chosen very conservatively, as the copy used to fail with big buffers.
However, modern Windows systems seem to not suffer from that bug,
and bigger buffer sizes will dramatically increase the performance of
copies to/from network drives.
This method allows for fine tuning, in case you run into performance problems,
or network buffer failures.
When nil, a somewhat conservative compromise is used.
error handling
-
errorReporter
-
I know about error codes
-
lastErrorNumber
-
return the errno of the last error
Usage example(s):
ExternalStream lastErrorNumber
|
-
lastErrorString
-
return a message string describing the last error
Usage example(s):
ExternalStream lastErrorString
|
-
reportOn: anErrorSymbolOrNumber
-
an error occurred.
Report it via an Exception
instance creation
-
forFileDescriptor: aFileDescriptor mode: modeSymbol
-
given a fileDescriptor, create an ExternalStream object
to operate on this fd.
The modeSymbol-argument is #readonly, #readwrite, ....
This may be used to wrap fd's as returned by user
primitive code, or to wrap pipe-fds into externalStreams.
Usage example(s):
the example below will probably fail (15 is a random FD):
|s|
s := ExternalStream forFileDescriptor:15 mode:'r'.
s next.
|
-
forFileDescriptor: aFileDescriptor mode: modeSymbol buffered: buffered handleType: handleTypeSymbol
-
given a fileDescriptor, create an ExternalStream object
to operate on this fd.
The modeSymbol-argument is #readonly, #readwrite, ....
This may be used to wrap fd's as returned by user
primitive code, or to wrap pipe-fds into externalStreams.
Usage example(s):
the example below will probably fail (15 is a random FD):
|s|
s := ExternalStream forFileDescriptor:15 mode:#readonly buffered:false handleType:#filePointer.
s next.
|
-
forReadWriteToFileDescriptor: aFileDescriptor
-
given a fileDescriptor, create an ExternalStream object
to read/write from/to this fd. This may be used to wrap fd's
as returned by user primitive code, or to wrap pipe-
filedescriptors into externalStreams.
Usage example(s):
the example below will probably fail (15 is a random FD):
|s|
s := ExternalStream forReadWriteToFileDescriptor:15.
s next.
|
-
forReadingFromFileDescriptor: aFileDescriptor
-
given a fileDescriptor, create an ExternalStream object
to read from this fd. This may be used to wrap fd's
as returned by user primitive code, or to wrap pipe-
filedescriptors into externalStreams.
Usage example(s):
the example below will probably fail (15 is a random FD):
|s|
s := ExternalStream forReadingFromFileDescriptor:15.
s next.
|
Usage example(s):
|pipe readFd writeFd rs ws|
'create OS pipe ...'.
pipe := OperatingSystem makePipe.
readFd := pipe at:1.
writeFd := pipe at:2.
'connect Smalltalk streams ...'.
rs := ExternalStream forReadingFromFileDescriptor:readFd.
ws := ExternalStream forWritingToFileDescriptor:writeFd.
'read ...'.
[
1 to:10 do:[:i |
Transcript showCR:rs nextLine
].
rs close.
] forkAt:7.
'write ...'.
[
1 to:10 do:[:i |
ws nextPutAll:'hello world '; nextPutAll:i printString; cr
].
ws close.
] fork.
|
-
forWritingToFileDescriptor: aFileDescriptor
-
given a fileDescriptor, create an ExternalStream object
to write to this fd. This may be used to wrap fd's
as returned by user primitive code, or to wrap pipe-
filedescriptors into externalStreams.
Usage example(s):
the example below will probably fail (15 is a random FD):
|s|
s := ExternalStream forWritingToFileDescriptor:15.
s binary.
s nextPut:1.
|
-
new
-
re-enable new - disabled in Stream superclass
obsolete
-
makePTYPair
-
obsolete since 12-07-2003
** This is an obsolete interface - do not use it (it may vanish in future versions) **
-
makePipe
-
obsolete since 12-07-2003
** This is an obsolete interface - do not use it (it may vanish in future versions) **
resereved filedescriptors
-
ensureReservedFileDescriptors: countOrNil
-
make sure that countOrNil fileDescriptors are reserved for emergency cases.
If countOrNil is nil, use the inital allocation as count.
Answer the number of descriptors that have been allocated.
-
freeReservedFileDescriptors: count
-
free count fileDescriptors;
used for emergency cases (eg. to emergency-save a modified project in expecco)
testing
-
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.
Compatibility-Dolphin
-
beText
-
Compatibility-Squeak
-
nextInto: aByteArrayOrString
-
read elements into the argument, whose size determines the amount
of bytes to read. If not enough elements could be read, return
a copy of the argument; otherwise, return the filled argument.
-
readInto: aContainer startingAt: index count: nElements
-
same as #nextBytes:into:startingAt: for ByteArrays;
for LongArrays, nelements longs are read.
Squeak compatibility.
-
readOnly
-
Squeak compatibility: make the stream readOnly
Signal constants
-
invalidReadSignal
-
-
invalidWriteSignal
-
accessing
-
binary
-
switch to binary mode - default is text
-
binary: beBinaryBool
-
switch to binary mode if beBinaryBool is true.
Returns the previous mode.
The initial default is text
-
buffered: aBoolean
-
turn buffering on or off - default is on.
Answer the previous bufferd state.
-
contents
-
return the contents of the file from the current position up-to
the end. If the stream is in binary mode, a ByteArray containing
the byte values is returned.
In text-mode, a collection of strings, each representing one line,
is returned.
-
contentsAsString
-
to compensate for the bad naming, use this to make things explicit.
See also #contents, which returns the lines as stringCollection for textFiles.
-
contentsOfEntireFile
-
ST-80 compatibility: return contents as a String (or byteArray, if in binary mode).
See also #contents, which returns the lines as stringCollection for text files.
-
contentsSpecies
-
return the kind of object to be returned by sub-collection builders
(such as upTo)
-
dependents
-
(comment from inherited method)
return a Collection of dependents.
The default implementation here uses a global WeakDictionary to store
dependents
This may be too slow for high frequency change&update,
therefore, some classes (Model) redefine this for better performance.
Notice the mentioning of a WeakDictionary - read the classes documentation.
-
dependents: aDependentsCollection
-
(comment from inherited method)
set the collection of dependents.
The default implementation here uses a global Dictionary to store
dependents which may be too slow for high frequency change&update.
Therefore, some classes (Model) redefine this for better performance.
-
eolMode
-
return how end-of-line (EOL) is to be marked.
Returns one one of:
#crlf -> add a CR-NL, as in MSDOS
#cr -> add a CR, as in VMS
#nl -> add a NL, as in Unix
#eot -> add an EOT (= 0x04, as used in some modems/protocols)
#etx -> add an ETX (= 0x03, as used in some modems/protocols)
#nl -> add a NL, as in Unix
nil -> transparent
-
eolMode: aSymbolOrNil
-
specify how end-of-line (EOL) is to be marked.
The argument may be one of:
#crlf -> add a CR-NL, as in MSDOS
#cr -> add a CR, as in VMS
#nl -> add a NL, as in Unix
#eot -> add an EOT (= 0x04, as used in some modems/protocols)
#etx -> add an ETX (= 0x03, as used in some modems/protocols)
anyOther -> like #nl
-
fileDescriptor
-
return the fileDescriptor of the receiver -
notice: this one returns the underlying OSs fileDescriptor -
this may not be available on all platforms (i.e. non unix systems).
NOTE: this may set the handle instance variable to nil
if the file descriptor is no longer valid.
-
fileDescriptorOfFile: aHandle
-
for migration to rel5 only:
return the fileDescriptor of the argument handle -
notice: this one returns the underlying OSs fileDescriptor -
this may not be available on all platforms (i.e. non unix systems).
-
fileHandle
-
return the fileHandle of the receiver.
Under unix, this is the fileDescriptor; under windows, this is the Handle.
NOTE: this may set the handle instance variable to nil
if the file descriptor is no longer valid.
-
filePointer
-
return the filePointer of the receiver -
notice: for portability stdio is used; this means you will get
a FILE * - not a fileDescriptor.
(what you really get is a corresponding integer).
You cannot do much with the returned value
- except passing it to a primitive, for example.
-
handle
-
-
handleType
-
-
lineEndCR
-
(comment from inherited method)
Ignored here, but added to make internalStreams protocol compatible
with externalStreams.
-
lineEndCRLF
-
-
lineEndLF
-
-
lineEndTransparent
-
-
pathName
-
answer the pathName of the stream.
Only FileStreams know the pathName, so we return an empty string here
-
readonly
-
set access mode to readonly
-
readwrite
-
set access mode to readwrite
-
text
-
switch to text mode - default is text
-
useCRLF: aBoolean
-
turn on or off CRLF sending (instead of LF only) - default is off.
This method is provided for backward compatibility - see #eolMode:
which offers another choice.
** This is an obsolete interface - do not use it (it may vanish in future versions) **
-
writeonly
-
set access mode to writeonly
closing
-
abortAndClose
-
close the stream - added for protocol compatibility with Socket and PipeStream.
see comment there
-
close
-
Close the stream.
No error if the stream is not open.
-
shutDown
-
close the stream - added for protocol compatibility with Socket.
see comment there
copying
-
copy
-
answer a copy of myself.
Have to dup the filedescriptor and position the copy
Usage example(s):
|stream1 stream2|
stream1 := Filename newTemporary writeStream.
stream2 := stream1 copy.
stream1 inspect.
stream2 inspect.
|
defaults
-
bufferSizeForBulkCopy
-
return the size of buffer used when copying big files/bulk data
from one stream to another.
Due to a bug on older Windows systems, the default used
is chosen very conservatively, as the copy used to fail with big buffers.
However, modern Windows systems seem to not suffer from that bug,
and bigger buffer sizes will dramatically increase the performance of
copies to/from network drives.
Setting DefaultCopyBufferSize allows for fine tuning,
in case you run into performance problems, or network buffer failures.
When nil, a somewhat conservative compromise is used.
error handling
-
argumentMustBeCharacter
-
report an error, that the argument must be a character in 0..FF
-
argumentMustBeInteger
-
report an error, that the argument must be an integer
-
argumentMustBeString
-
report an error, that the argument must be a string
-
errorAlreadyOpen
-
report an error, that the stream is already opened
Usage example(s):
self new errorAlreadyOpen
|
-
errorBinary
-
report an error, that the stream is in binary mode
-
errorNotBinary
-
report an error, that the stream is not in binary mode
-
errorNotBuffered
-
report an error, that the stream is not in buffered mode
-
errorReadOnly
-
report an error, that the stream is a readOnly stream
-
errorReporter
-
ST-80 mimicry.
-
errorUnsupportedOperation
-
report an error, that some unsupported operation was attempted
-
errorWriteOnly
-
report an error, that the stream is a writeOnly stream
-
ioError
-
report an error, that some I/O error occurred.
(for example, a device-IO-error, or reading an NFS-dir,
which is no longer available and has been mounted soft)
-
ioError: errorNumber
-
report an error, that some I/O error occurred.
(for example, a device-IO-error, or reading an NFS-dir,
which is no longer available and has been mounted soft)
-
lastErrorHolder
-
return an ErrorHolder object for the last error
-
lastErrorNumber
-
return the last error
-
lastErrorString
-
return a message string describing the last error
-
lastErrorSymbol
-
return an error symbol describing the last error
-
openError
-
report an error, that the open failed
** This is an obsolete interface - do not use it (it may vanish in future versions) **
-
openError: errorNumber
-
report an error, that the open failed
-
readError
-
report an error, that some read error occurred
-
readError: errorNumber
-
report an error, that some read error occurred
-
reportLastError
-
raise an error.
To be used with calls (e.g. some socket calls), that do not raise an error but
return false on error.
-
writeError
-
report an error, that some write error occurred
-
writeError: errorNumber
-
report an error, that some write error occurred
finalization
-
beExecutor
-
mark myself as being an executor for finalization.
We mis-use the mode symbol for this.
-
executor
-
return a copy for finalization-registration;
since all we need at finalization time is the fileDescriptor,
a cheaper copy is possible.
-
finalizationLobby
-
answer the registry used for finalization.
ExternalStreams have their own Registry
-
finalize
-
some Stream has been collected - close the file if not already done
-
registerForFinalization
-
keep myself in newSpace, so it will be finalized early
-
unregisterForFinalization
-
probably the object will be collected soon...
initialization
-
initialize
-
(comment from inherited method)
just to ignore initialize to objects which do not need it
-
initializeEOLMode
-
line reading/writing
-
nextLine
-
read the next line (characters up to newline).
Return a string containing those characters excluding the newline.
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.
The line must be shorter than 32K characters - otherwise an error is signalled.
-
nextPutLine: aString
-
write the characters in aString and append an end-of-Line marker
(LF, CR or CRLF - depending in the setting of eolMode)
-
nextPutLinesFrom: aStream upToLineStartingWith: aStringOrNil
-
read from aStream up to and including a line starting with aStringOrNil
and append all lines to self.
Can be used to copy/create large files or copy from a pipe/socket.
If aStringOrNil is nil or not matched, copy proceeds to the end.
-
peekForLineStartingWith: aString
-
read ahead for next line starting with aString;
return the line-string if found, or nil if EOF is encountered.
If matched, do not advance position beyond that line
i.e. nextLine will read the matched line.
If not matched, reposition to original position for further reading.
-
peekForLineStartingWithAny: aCollectionOfStrings
-
read ahead for next line starting with any of aCollectionOfStrings;
return the index in aCollection if found, nil otherwise..
If no match, do not change position; otherwise advance right before the
matched line so that nextLine will return this line.
misc functions
-
async: aBoolean
-
set/clear the async attribute - if set, the availability of data on
the receiver will trigger an ioInterrupt.
If cleared (which is the default) no special notification is made.
Notice:
not every OS supports this
- check with OS>>supportsIOInterrupts before using
-
blocking: aBoolean
-
set/clear the blocking attribute - if set (which is the default)
a read (using next) on the receiver will block until data is available.
If cleared, a read operation will immediately return with a value of
nil.
Turning off blocking is useful when reading from PipeStreams
or Sockets, and the amount of data to be read is not known
in advance. However, the data must then be read using #nextBytes:
methods, in order to avoid other (pastEndRead) exceptions.
-
ioctl: ioctlNumber
-
to provide a simple ioctl facility - an ioctl is performed
on the underlying file; no arguments are passed.
-
ioctl: ioctlNumber with: arg
-
to provide a simple ioctl facility - an ioctl is performed
on the underlying file; the argument is passed as argument.
This is not used by ST/X, but provided for special situations
- for example, to control proprietrary I/O devices.
Since the type of the argument depends on the ioctl being
performed, different arg types are allowed here.
If the argument is nil, an ioctl without argument is performed.
If the argument is an integral number, it's directly passed;
if it's a kind of ByteArray (ByteArray, String or Structure),
or external data (ExternalBytes or ExternalAddress),
a pointer to the data is passed.
This allows performing most ioctls
- however, it might be tricky to setup the buffer.
Be careful in what you pass - ST/X cannot validate its correctness.
-
reset
-
set the read position to the beginning of the collection
-
setToEnd
-
redefined since it must be implemented differently
** This method must be redefined in concrete classes (subclassResponsibility) **
-
sync
-
make sure, that the OS writes cached data to the disk
Usage example(s):
|f|
f := 'x' asFilename writeStream.
f nextPutAll:'hallo'; sync; syncData; close
|
-
syncData
-
make sure, that the OS writes cached data to the disk.
In this case, metadata is only written, if it is
required to read the file's data (so metadata will not be written,
if only access/modification time has changed).
Usage example(s):
|f|
f := 'x' asFilename writeStream.
f nextPutAll:'hallo'; sync; syncData; close
|
-
tcgetattr
-
unix only:
provide the information of a tcgetattr call as a dictionary.
This provides terminal setting values of a tty or pty.
Used by terminal emulators.
On non-unix systems, an unsupported operation error is raised
Usage example(s):
the system does not support tcgetattr
|
Usage example(s):
non homogenous reading
-
next: count into: aCollection startingAt: start
-
return the next count bytes or characters from the stream.
-
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).
The type of collection is specified in #contentsSpecies.
Usage example(s):
(ReadStream on:#(1 2 3 4 5)) nextAvailable:3
(ReadStream on:#(1 2 3 4 5)) nextAvailable:10
(ReadStream on:'hello') nextAvailable:3
(ReadStream on:'hello') nextAvailable:10
|
-
nextAvailable: count into: aCollection startingAt: pos
-
store the next count elements of the stream into aCollection at position pos.
Answer the number of bytes read.
-
nextAvailableBytes: count
-
return the next count bytes of the stream as a byteArray.
If the stream reaches the end before count bytes have been read,
return what is available. (i.e. a shorter byteArray).
-
nextAvailableBytes: count into: anObject startingAt: start
-
read the next count bytes into an object and return the number of
bytes read or the number of bytes read, if EOF is encountered before,
or no more bytes are available for reading (from the pipe/socket).
If the receiver is some socket/pipe-like stream, an exception
is raised if the connection is broken.
Notice, that in contrast to other methods,
this does NOT return nil on EOF, but the actual count.
Thus allowing read of partial blocks.
The object must have non-pointer indexed instvars
(i.e. it must be a ByteArray, String, Float- or DoubleArray).
If anObject is a string or byteArray and reused, this provides the
fastest possible physical I/O (since no new objects are allocated).
Use with care - non object oriented I/O.
Warning: in general, you cannot use this method to pass data from other
architectures since it does not care for byte order or float representation.
-
nextAvailableBytesInto: aBuffer
-
read up to buffer-size bytes of the stream into aBuffer.
Return the number of bytes read
(i.e. either the buffer's size or the number of bytes actually read into it)
-
nextByte
-
read the next byte and return it as an Integer; return nil on error.
This is allowed in both text and binary modes, always returning the
bytes binary value as an integer in 0..255.
-
nextBytes: countIn into: anObject startingAt: startIn
-
read the next count bytes into an object and return the number of
bytes read or the number of bytes read, if EOF is encountered before.
If the receiver is some socket/pipe-like stream, an exception
is raised if the connection is broken.
Warning: if used with a pipe/socket, this blocks until the requested number
of bytes have been read. See #nextAvailableBytes:into:startingAt:
to only read whats there.
Notice, that in contrast to other methods,
this does NOT return nil on EOF, but the actual count.
Thus allowing read of partial blocks.
The object must have non-pointer indexed instvars
(i.e. it must be a ByteArray, String, Float- or DoubleArray),
or an externalBytes object (with known size).
If anObject is a string or byteArray and reused, this provides the
fastest possible physical I/O (since no new objects are allocated).
Use with care - non object oriented I/O.
Warning: in general, you cannot use this method to pass data from other
architectures (unless you prepared the buffer with care),
since it does not care for byte order or float representation.
-
nextInt16MSB: msbFlag
-
Read two bytes and return the value as a 16-bit signed Integer.
If msbFlag is true, value is read with most-significant byte first,
otherwise least-significant byte comes first.
A nil is returned if EOF is reached (also when EOF is hit after the first byte).
Works in both binary and text modes.
-
nextInt32MSB: msbFlag
-
Read four bytes and return the value as a 32-bit signed Integer,
which may be a LargeInteger.
If msbFlag is true, value is read with most-significant byte first,
otherwise least-significant byte comes first.
A nil is returned, if EOF is hit before all 4 bytes have been read.
Works in both binary and text modes.
-
nextUnsignedInt16MSB: msbFlag
-
Read two bytes and return the value as a 16-bit unsigned Integer.
If msbFlag is true, value is read with most-significant byte first,
otherwise least-significant byte comes first.
A nil is returned if EOF is reached (also when EOF is hit after the first byte).
Works in both binary and text modes.
-
nextUnsignedInt32MSB: msbFlag
-
Read four bytes and return the value as a 32-bit unsigned Integer, which may be
a LargeInteger.
If msbFlag is true, value is read with most-significant byte first, otherwise
least-significant byte comes first.
A nil is returned, if endOfFile occurs before all 4 bytes have been read.
Works in both binary and text modes.
-
nextWord
-
in text-mode:
read the alphaNumeric next word (i.e. up to non letter-or-digit).
return a string containing those characters.
in binary-mode:
read two bytes (msb-first) and return the value as a 16-bit
unsigned Integer (for compatibility with other smalltalks)
** This is an obsolete interface - do not use it (it may vanish in future versions) **
non homogenous writing
-
nextPutByte: aByteValue
-
write a byte.
Works in both binary and text modes.
-
nextPutInt16: anIntegerOrCharacter MSB: msbFlag
-
Write the argument, anIntegerOrCharacter as a short (two bytes).
If msbFlag is true, data is written most-significant byte first;
otherwise least first.
Notice that integers in the range 16r-8000 to +16rFFFF can be written
(i.e. both signed and unsigned int32 values can be written.
Works in both binary and text modes.
-
nextPutInt16LSB: anIntegerOrCharacter
-
do not remove.
See #patchByteOrderOptimizedMethods
-
nextPutInt16MSB: anIntegerOrCharacter
-
do not remove.
See #patchByteOrderOptimizedMethods
-
nextPutInt16NATIVE: anIntegerOrCharacter
-
Write the argument, anIntegerOrCharacter as a short (two bytes) in native byte order.
This is the CPU-specific byte order (LSB on x86 and VAX, MSB on sparc, and possibly on ARM).
Notice that integers in the range 16r-8000 to +16rFFFF can be written
(i.e. both signed and unsigned int32 values can be written.
Works in both binary and text modes.
-
nextPutInt32: aNumber MSB: msbFlag
-
Write the argument, aNumber as a long (four bytes).
If msbFlag is true, data is written most-significant byte first;
otherwise least first.
Notice that integers in the range 16r-80000000 to +16rFFFFFFFF can be written
(i.e. both signed and unsigned int32 values can be written.
Works in both binary and text modes.
-
nextPutInt32LSB: anIntegerOrCharacter
-
do not remove.
See #patchByteOrderOptimizedMethods
-
nextPutInt32MSB: anIntegerOrCharacter
-
do not remove.
See #patchByteOrderOptimizedMethods
-
nextPutInt32NATIVE: anInteger
-
Write the argument, anInteger as a long (four bytes) in native byte order.
This is the CPU-specific byte order (LSB on x86 and VAX, MSB on sparc and possibly on ARM).
Notice that integers in the range 16r-80000000 to +16rFFFFFFFF can be written
(i.e. both signed and unsigned int32 values can be written.
Works in both binary and text modes.
Notice: this message should not be sent explicitly by ANY program.
the following implementation replaces the code of either nextPutInt32MSB or LSB
dynamically (see #initialize on the class side)
-
nextPutUtf16: aCharacter
-
append my UTF-16 MSB representation to the argument, aStream.
UTF-16 can encode only characters with code points between 0 to 16r10FFFF.
Usage example(s):
(FileStream newTemporary
nextPutUtf16:$B;
nextPutUtf16:$Ä;
nextPutUtf16:(Character codePoint:16r10CCCC);
reset;
binary;
contents)
|
-
nextPutUtf16: aCharacter MSB: msbFlag
-
append my UTF-16 MSB representation to the argument, aStream.
UTF-16 can encode only characters with code points between 0 to 16r10FFFF.
positioning
-
position
-
(comment from inherited method)
return the read position (0-based)
** This method must be redefined in concrete classes (subclassResponsibility) **
-
position: index0Based
-
(comment from inherited method)
redefined to allow positioning past the readLimit
** This method must be redefined in concrete classes (subclassResponsibility) **
-
skipBufferedData
-
skip (throw away) all data that is currently buffered in myself.
Answer the number of bytes that have been skipped, 0 if nothing was buffered.
printing & storing
-
printOn: aStream
-
(comment from inherited method)
'' readStream printString
'' writeStream printString
private
-
clearEOF
-
-
closeFile
-
low level close - may be redefined in subclasses
Don't send this message, send #close instead
-
closeFile: handle
-
for rel5 only
-
connectTo: aFileDescriptor withMode: modeSymbol handleType: handleTypeSymbol
-
connect a fileDescriptor; openmode is the string defining the way to open.
This can be used to connect an externally provided fileDescriptor (from
primitive code) or a pipeFileDescriptor (as returned by makePipe) to
a Stream object.
The openMode ('r', 'w' etc.) must match the mode in which
the fileDescriptor was originally opened (otherwise i/o errors will be reported later).
-
dupFd
-
duplicate my file descriptor
-
fopenMode
-
answer the mode for fopen.
Only used internally
-
open: aPathArg withMode: openModeString
-
low level open; opens the file/device and sets the handle instance
variable.
Careful: this does not care for any other state.
Also be careful: unless opened with 'b' in the modeString,
Windows will translate written CRs to CRNL;
usually this is NOT wanted; especially for binary files.
-
reOpen
-
USERS WILL NEVER INVOKE THIS METHOD
sent after snapin to reopen streams.
cannot reopen here since I am abstract and have no device knowledge
-
setAccessor: what to: something
-
set the filePointer/fileHandle to the given one;
low level private & friend interface; may also be used to connect to some
externally provided handle.
-
setFileHandle: something
-
set the fileHandle to the given one;
low level private & friend interface; may also be used to connect to some
externally provided file handle.
-
setFileHandle: anIntegerOrExternalAddress mode: openMode
-
set the handle based upon a given fileHandle -
notice: this one is based on the underlying OSs fileDescriptor -
this is a fileDescriptor (Integer) on Unix and Windows, or an Handle (ExternalAddres) on Windows only.
It may not be available on all platforms.
-
setFilePointer: something
-
set the filePointer to the given one;
low level private & friend interface; may also be used to connect to some
externally provided file.
-
setLastError: aNumber
-
-
setSocketHandle: something
-
set the socketHandle to the given one;
low level private & friend interface; may also be used to connect to some
externally provided socket handle.
queries
-
atEnd
-
return true, if position is at end.
If a stream is at the end, the next read operation
would return or raise an exception immediately without waiting.
If a stream is not at the end, this may be a blocking operation
(see NonPositionableExternalStream)
-
nextError
-
return the error by trying to read something.
Should only be used, when we know, that a read operation
will return an error (otherwise a character may be lost).
Return an integer (error number), 0 (EOF) or nil (no error)
-
numAvailable
-
** This is an obsolete interface - do not use it (it may vanish in future versions) **
reading
-
next
-
return the next element; advance read position.
In binary mode, an integer is returned, otherwise a character.
If there are no more elements, either an exception is thrown or nil is returned
- see #pastEndRead.
-
next: count
-
return the next count elements of the stream as a collection.
Redefined to return a String or ByteArray instead of the default: Array.
-
nextOrNil
-
return the next element; advance read position.
In binary mode, an integer is returned, otherwise a character.
If there are no more elements, nil is returned.
This is #atEnd and #next in a single operation - to speed up some code
-
peek
-
return the element to be read next without advancing read position.
In binary mode, an integer is returned, otherwise a character.
If there are no more elements, either an exception is thrown or nil is returned
- see #pastEndRead.
-
peekOrNil
-
return the element to be read next without advancing read position.
In binary mode, an integer is returned, otherwise a character.
If there are no more elements, nil is returned.
Same as #atEnd and #peek in a single operation - speeding up some code
-
peekOrNilNoWait
-
like #peek, this returns the next element, if available.
If nothing is available, this does never raise a read-beyond end signal.
Instead, nil is returned immediately.
It does not wait on pipes and sockets an returns only data, that is already present.
Redefined for NonPositionableExternalStream compatibility.
-
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):
'/dev/null' asFilename readStream upToEnd
'/proc/self/stat' asFilename readStream upToEnd
'librun.so' asFilename readStream binary upToEnd
(PipeStream readingFrom:'tasklist /v') upToEnd
self assert:('smalltalk.rc' asFilename readStream upToEnd size)
= ('smalltalk.rc' asFilename readStream size)
|
rel5 protocol
-
atEndFile: handle
-
for migration to rel5 only
-
nextByteFromFile: handle
-
for migration to rel5 only
-
nextPutByte: aByte toFile: handle
-
for migration to rel5 only
testing
-
gotErrorOrEOF
-
answer true, if amn error or eof has been occurred on the stream
-
isBinary
-
return true, if the stream is in binary (as opposed to text-) mode.
The default when created is false.
-
isBlocking
-
return true, if O_NONBLOCK is NOT set in the fileDescriptor (probably UNIX specific)
-
isBuffered
-
return true, if writes to stream do not cause a system call for each operation.
-
isExecutor
-
am I an executor and no real stream object?
-
isExternalStream
-
return true, if the receiver is some kind of externalStream;
true is returned here - the method redefined from Object.
-
isOpen
-
return true, if this stream is open
Usage example(s):
executors are only used to finalize - they are not really open and are closed with #closeFile,
which does not check for #isOpen
|
-
isPipeStream
-
return true, if this stream is a pipe
-
isReadable
-
return true, if this stream can be read from
-
isSerialPort
-
return false here; to be redefined in subclass(es)
-
isSocket
-
return true, if this stream is a socket
-
isTTYStream
-
return true, if this stream is a tty stream (UNIX)
Usage example(s):
Stdout isTTYStream
Stderr isTTYStream
Stdin isTTYStream
'/dev/null' asFilename readStream isTTYStream
'makefile' asFilename readStream isTTYStream
|
-
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.
ExternalStreams never return unicode characters.
-
isWritable
-
return true, if this stream can be written to
waiting for I/O
-
canBeSelected
-
return true, if this stream can be selected upon
-
numAvailableForRead
-
answer the number of bytes available for reading
Usage example(s):
'/etc/hosts' asFilename readStream numAvailableForRead
|
-
readWaitWithTimeoutMs: timeoutOrNil
-
suspend the current process, until the receiver
becomes ready for reading or a timeout (in milliseconds) expired.
If timeoutOrNil is nil, wait without timeout.
If data is already available, return immediate.
Return true if a timeout occurred (i.e. false, if data is available).
The other threads are not affected by the wait.
-
readWriteWaitWithTimeoutMs: timeoutOrNil
-
suspend the current process, until the receiver
becomes ready for reading or writing or a timeout (in milliseconds) expired.
Return true if a timeout occurred (i.e. false, if data is available).
Return immediate if the receiver is already ready.
The other threads are not affected by the wait.
-
writeExceptionWaitWithTimeoutMs: timeoutOrNil
-
suspend the current process, until the receiver
becomes ready for writing or an exceptional event or a timeout (in milliseconds) expired.
Return true if a timeout occurred (i.e. false, if data is available).
Return immediate if the receiver is already ready.
The other threads are not affected by the wait.
-
writeWaitWithTimeoutMs: timeoutOrNil
-
suspend the current process, until the receiver
becomes ready for writing or a timeout (in milliseconds) expired.
Return true if a timeout occurred (i.e. false, if data is available).
Return immediate if the receiver is already ready.
The other threads are not affected by the wait.
writing
-
contents: aStringOrByteArrayOrCollectionOfLines
-
create (or overwrite) a file given its contents as a collection of lines.
Raises an error, if the file is unwritable.
Usage example(s):
'foo1' asFilename writeStream
contents:#('one' 'two' 'three'); close.
'foo2' asFilename writeStream
contents:'Hello world'; close.
'foo3' asFilename writeStream
contents:#[1 2 3 4 5]; close.
#(foo1 foo2 foo3) do:[:e | e asFilename remove].
|
-
cr
-
append an end-of-line character (or CRLF if in crlf mode).
reimplemented for speed
-
flush
-
write all buffered data
-
nextPut: aCharacter
-
write the argument, aCharacter - raise an error if failed.
Answer aCharacter.
Only single-byte characters are supported here
-
nextPutAll: aCollection
-
write all elements of the argument, aCollection.
Answer the receiver.
Reimplemented for speed when writing strings or byteArrays.
For others, falls back to general method in superclass.
-
nextPutAll: initialWriteCount from: buffer startingAt: initialOffset
-
append count elements with index starting at initialOffset
of the argument, buffer onto the receiver.
This is only allowed, if the receiver supports writing.
Answer the number of elements that were appended.
Buffer should be a byte collection.
I don't know how to write non-bytes to an external stream, but let superclass handle this.
-
nextPutAll: aCollection startingAt: start to: stop
-
write a range of elements of the argument, aCollection.
Reimplemented for speed when writing strings or byteArrays.
For others, falls back to general method in superclass.
-
nextPutAllUnicode: aString
-
normal streams can not handle multi-byte characters, so convert them to utf8.
This is needed, so that you can do ('something' asUnicode16String errorPrintCR)
-
nextPutBytes: count from: anObject startingAt: start
-
write count bytes from an object starting at index start.
return the number of bytes written - which could be 0.
The object must have non-pointer indexed instvars
(i.e. be a ByteArray, String, Float- or DoubleArray),
or an externalBytes object (with known size).
Use with care - non object oriented i/o.
Warning:
in general, you cannot use this method to pass non-byte data to other
architectures (unless you prepared the buffer with care),
since it does not care for byte order or float representation.
-
nextPutUnicode: aCharacter
-
normal streams can not handle multi-byte characters, so convert them to utf8
open a file, read the contents and display it in a textView:
|topView scrollPane textView fileStream text|
topView := StandardSystemView new.
topView label:'contents of Makefile'.
scrollPane := HVScrollableView in:topView.
scrollPane origin:0.0@0.0 corner:1.0@1.0.
textView := EditTextView new.
scrollPane scrolledView:textView.
fileStream := 'Makefile' asFilename readStream.
text := fileStream upToEnd.
fileStream close.
textView contents:text.
topView open.
|
Notice, all of the above can also be done (simply) as:
EditTextView openOn:'Makefile'
|
|