Skip to content

EF.Streams

This unit contains a set of stream decorators to add buffering, textline support and other features to rtl streams.

Some code in this unit is based on code by Julian M. Bucknall and published on The Delphi Magazine.

TEFStreamDecorator class

Base class for all EF stream decorators and filters. It just forwards read and write requestes to an internal stream object, a reference to which is passed to the constructor.

pascal
constructor Create(const AStream: TStream;

Creates an object that decorates AStream. If AOwnsStream is True, then the decorator acquires ownership of the stream and will destroy it when it is itself destroyed.

pascal
destructor Destroy;

Frees the decorated stream if the decorator owns it.

pascal
function Read(var Buffer;

Reads from the decorated stream, firing OnEndOfStream when fewer bytes than requested are read.

pascal
function Write(const Buffer;

Writes to the decorated stream.

pascal
function Seek(Offset: Longint;

Seeks on the decorated stream (32-bit overload).

pascal
function Seek(const Offset: Int64;

Seeks on the decorated stream (64-bit overload).

pascal
property OnEndOfStream: TNotifyEvent read FOnEndOfStream write FOnEndOfStream;

Fired when the end of the stream is reached while reading. IOW, when Read's return value is less than its Count argument. Handle this event if you do not have control over reads but still want to be notified when the stream is over.

TEFReadFilter class

A stream filter that only allows sequential reading.

pascal
function Read(var Buffer;

Reads sequentially from the decorated stream.

pascal
function Seek(const Offset: Int64;

Only supports the special Seek calls used to query the stream's size; any other seek raises an exception.

pascal
function Write(const Buffer;

Not supported on a read-only filter; always raises an exception.

TEFBufferedReadFilter class

Adds buffering to the read stream filter. Use this class for efficient reading from a file or other medium.

pascal
procedure AfterConstruction;

Allocates the internal read buffer.

pascal
destructor Destroy;

Frees the internal read buffer.

pascal
function Read(var Buffer;

Reads the requested number of bytes, refilling the internal buffer from the decorated stream as needed.

pascal
function Seek(const Offset: Int64;

Returns the current logical position (accounting for buffered data); other seeks are delegated to the inherited filter.

TEFTextStream class

A stream decorator that is able to read and write text lines to the decorated stream. Use it with a buffered read filter to efficiently read text lines from a file.

The stream is UTF-8, in both directions: WriteLn encodes to UTF-8 and ReadLn decodes from it. It has to be one encoding for both, or a file this class writes is not a file it can read back — which is what used to happen, ReadLn reading two bytes per character as if it were UTF-16. No byte-order mark is written; one found at the start of the stream is skipped on reading.

pascal
procedure AfterConstruction;

Initializes LineBreak to the platform default (sLineBreak).

pascal
property LineBreak: string read FLineBreak write FLineBreak;

Line breaking sequence used to terminate lines written by WriteLn. Defaults to sLineBreak.

Note: Currently it is NOT used by ReadLn.

pascal
function ReadLn: string;

Reads text from the current position up to (but not including) the next LF character, skipping any CR characters found. This supports both LF (Linux) and CR+LF (Windows) line breaking styles. It doesn't currently support the CR-only line breaking style. Returns EOT when there's no more text.

The bytes are read one at a time and decoded as UTF-8 once the line is complete, which is the encoding WriteLn produces. A byte-order mark at the start of the stream is not part of the first line and is skipped.

Note: the value of the LineBreak property is ignored.

pascal
procedure WriteLn(const AString: string);

Writes AString plus LineBreak to the stream.

TEFXMLOutputStream class

A stream decorator that is capable of outputting XML data such as tags and attributes, keeping track of the indent. It only supports UTF-8 encoding.

pascal
procedure AfterConstruction;

Inherits any indentation offset when this stream decorates another XML output stream.

pascal
destructor Destroy;

Closes any still-open tags and frees the open-tags stack.

pascal
procedure WriteProlog;

Writes the XML prolog. Call this before writing anything else if you are producing a well-formed XML document.

pascal
procedure OpenTag(const ATagName: string);

Opens a tag, optionally with attributes. AAttributeNames must have the same length as AAttributeValues.

pascal
procedure WriteTag(const ATagName: string;

Opens a tag, writes ATagCharacters and closes it all in a single call. If ATagCharacter is empty, it uses the "<ATagName />" syntax. Optionally writes also the attributes in the opening tag (in which case the tag cannot be empty).

pascal
procedure WriteCDATATag(const ATagName, ATagCharacters: string);

Like WriteTag, but embeds ATagCharacters in a CDATA section.

pascal
function CloseTag: string;

Closes the last opened tag, if any, and returns its name. If no tag to close was found, it returns ''.

pascal
procedure CloseAllOpenTags;

Iteratively calls CloseTag until the stack of open tags is empty. It is called automatically upon destruction.

Released under Apache License, Version 2.0.