Skip to content
galkahana edited this page Aug 8, 2012 · 7 revisions

Unless you are extending the library or writing free text, you will not normally stumble upon IO classes of the library.
if you do, this passage contains useful information on how IO is done with the library.

All IO is split between input streams and output streams. Note that currently all streams are either input or output, not both.

Input Streams

All input streams implement the IByteReader interface.
The IByteReader interface has 2 methods:

  1. virtual LongBufferSizeType Read(Byte* inBuffer,LongBufferSizeType inBufferSize)
    Read from the stream to a buffer of a designated length.
  2. virtual bool NotEnded()
    Returns true if a stream has not been consumed completely.
    Some streams, that allow positioning, may implement an extension of the IByteReader interface by implementing IByteReaderWithPosition
    which adds 4 other methods:
    virtual void SetPosition(LongFilePositionType inOffsetFromStart)
    This method sets the file position to the input location.
    virtual LongFilePositionType GetCurrentPosition()
    This method retrieves the current position in the stream.
    virtual void Skip(LongBufferSizeType inSkipSize)
    This method skips a certain number of bytes.
    virtual void SetPositionFromEnd(LongFilePositionType inOffsetFromEnd)
    Sets position from end. The input location is the distance from the end (non negative!). for example SetPositionFromEnd(1) will place the reader just before the last byte.

There are currently 7 implementations of IByteReader:

  1. InputFileStream reads input from a file.
  2. InputStringBufferStream reads input from a string buffer.
  3. InputByteArrayStream reads from a C string (char array with a set length)
  4. InputBufferedStream reads input from another stream (passed to the constructor as a pointer) using buffers. It is normally good to use this stream on a file stream.
  5. InputFlateDecodeStream reads input from another stream, encoded in Flate encoding (zip), and decodes on the fly.
  6. InputDCTDecodeStream reads input from another stream, encoded in DCT encoding (JPG), and decodes on the fly.
  7. InputAscii85DecodeStream reads input from another stream, encoded in Ascii 85 encoding, and decodes on the fly.
  8. InputLimitedStream, for reading subset of another stream. user provides a stream and a certain position limit, and InputLimitedStream uses the limit as EOF mark.
  9. InputStreamSkipperStream, implements some IByteReaderWithPosition activities for streams that only implement IByteReader. This is useful when a stream does not have a “current position” functionality. implementation simply reads how many bytes were read. simple positioning by skipping “to” or “by” are also possible.

Apart from the stream there is also a class for an input file named InputFile. This class is simply a combination of a buffered input file stream and a file path.

Output Streams

All output streams implement the IByteWriter interface.
The IByteWriter interface has a single method:
virtual LongBufferSizeType Write(const Byte* inBuffer,LongBufferSizeType inSize)
This method write a buffer of the input size to the stream.
Some streams may implement an extension of the IByteWriter interface by implementing IByteWriterWithPosition
which adds another method:
virtual LongFilePositionType GetCurrentPosition()
This method retrieves the current position in the stream.

There are currently 5 implementations of IByteWriter:

  1. OutputFileStream
    Outputs to a file stream
  2. OutputStringBufferStream
    Outputs to a string
  3. OutputFlateDecodeStream
    Decodes all buffer with flate decoding and write them to an underlying stream
  4. OutputFlateEncodeStream
    Encodes all buffer with flate Encoding and write them to an underlying stream
  5. OutputBufferedStream
    Writes buffered output to an underlying stream.

The class OutputFile is simply a buffered output stream and a file path joined together.

Streams usage

Streams are used a lot throughout the library. Due to their implementation of the decorator paradigm it is easy to have them contain one another, making such things as writing encoded output to a file or a string a very easy task. Thanks to the buffered streams you don’t have to worry a lot about IO costs.

A user may want to extend streams, where the most common usage is to extend the Compression capabilities of the library.
Note the class OutputStreamTraits. This class is meant to develop as a generic helper class for output streams. right now it just has a single method that allows copying an input stream to the contained output stream.

There are some samples existing in the testing area, for streams usage:

  1. BufferedOutputStreamTest is a short code showing how to use buffered output to an output file stream.
  2. FlateEncryptionTest is showing a string which is first encoded to flate, and then decoded, using the flate streams.
  3. OutputFileStreamTest is showing how to write to an output file.
Clone this wiki locally