fpc/docs/objects.tex
1998-12-24 10:14:29 +00:00

1646 lines
50 KiB
TeX

%
% $Id$
% This file is part of the FPC documentation.
% Copyright (C) 1998, by Michael Van Canneyt
%
% The FPC documentation is free text; you can redistribute it and/or
% modify it under the terms of the GNU Library General Public License as
% published by the Free Software Foundation; either version 2 of the
% License, or (at your option) any later version.
%
% The FPC Documentation is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
% Library General Public License for more details.
%
% You should have received a copy of the GNU Library General Public
% License along with the FPC documentation; see the file COPYING.LIB. If not,
% write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
% Boston, MA 02111-1307, USA.
%
\chapter{The Objects unit.}
This chapter documents the \file{objects} unit. The unit was implemented by
many people, and was mainly taken from the FreeVision sources.
The methods and fields that are in a \var{Private} part of an object
declaration have been left out of this documentation.
\section{Constants}
The following constants are error codes, returned by the various stream
objects.
\begin{verbatim}
CONST
stOk = 0; { No stream error }
stError = -1; { Access error }
stInitError = -2; { Initialize error }
stReadError = -3; { Stream read error }
stWriteError = -4; { Stream write error }
stGetError = -5; { Get object error }
stPutError = -6; { Put object error }
stSeekError = -7; { Seek error in stream }
stOpenError = -8; { Error opening stream }
\end{verbatim}
These constants can be passed to constructors of file streams:
\begin{verbatim}
CONST
stCreate = $3C00; { Create new file }
stOpenRead = $3D00; { Read access only }
stOpenWrite = $3D01; { Write access only }
stOpen = $3D02; { Read/write access }
\end{verbatim}
The following constants are error codes, returned by the collection list
objects:
\begin{verbatim}
CONST
coIndexError = -1; { Index out of range }
coOverflow = -2; { Overflow }
\end{verbatim}
Maximum data sizes (used in determining how many data can be used.
\begin{verbatim}
CONST
MaxBytes = 128*1024*1024; { Maximum data size }
MaxWords = MaxBytes DIV SizeOf(Word); { Max word data size }
MaxPtrs = MaxBytes DIV SizeOf(Pointer); { Max ptr data size }
MaxCollectionSize = MaxBytes DIV SizeOf(Pointer); { Max collection size }
\end{verbatim}
\section{Types}
The follwing auxiliary types are defined:
\begin{verbatim}
TYPE
{ Character set }
TCharSet = SET Of Char;
PCharSet = ^TCharSet;
{ Byte array }
TByteArray = ARRAY [0..MaxBytes-1] Of Byte;
PByteArray = ^TByteArray;
{ Word array }
TWordArray = ARRAY [0..MaxWords-1] Of Word;
PWordArray = ^TWordArray;
{ Pointer array }
TPointerArray = Array [0..MaxPtrs-1] Of Pointer;
PPointerArray = ^TPointerArray;
{ String pointer }
PString = ^String;
{ Filename array }
AsciiZ = Array [0..255] Of Char;
Sw_Word = Cardinal;
Sw_Integer = LongInt;
\end{verbatim}
The following records are used internaly for easy type conversion:
\begin{verbatim}
TYPE
{ Word to bytes}
WordRec = packed RECORD
Lo, Hi: Byte;
END;
{ LongInt to words }
LongRec = packed RECORD
Lo, Hi: Word;
END;
{ Pointer to words }
PtrRec = packed RECORD
Ofs, Seg: Word;
END;
\end{verbatim}
The following record is used when streaming objects:
\begin{verbatim}
TYPE
PStreamRec = ^TStreamRec;
TStreamRec = Packed RECORD
ObjType: Sw_Word;
VmtLink: pointer;
Load : Pointer;
Store: Pointer;
Next : PStreamRec;
END;
\end{verbatim}
The \var{TPoint} basic object is used in the \var{TRect} object (see
\sees{TRect}):
\begin{verbatim}
TYPE
PPoint = ^TPoint;
TPoint = OBJECT
X, Y: Sw_Integer;
END;
\end{verbatim}
\section{TRect}
\label{se:TRect}
The \var{TRect} object is declared as follows:
\begin{verbatim}
TRect = OBJECT
A, B: TPoint;
FUNCTION Empty: Boolean;
FUNCTION Equals (R: TRect): Boolean;
FUNCTION Contains (P: TPoint): Boolean;
PROCEDURE Copy (R: TRect);
PROCEDURE Union (R: TRect);
PROCEDURE Intersect (R: TRect);
PROCEDURE Move (ADX, ADY: Sw_Integer);
PROCEDURE Grow (ADX, ADY: Sw_Integer);
PROCEDURE Assign (XA, YA, XB, YB: Sw_Integer);
END;
\end{verbatim}
\begin{function}{TRect.Empty}
\Declaration
Function TRect.Empty: Boolean;
\Description
\var{Empty} returns \var{True} if the rectangle defined by the corner points
\var{A}, \var{B} has zero or negative surface.
\Errors
None.
\SeeAlso
\seef{TRect.Equals}, \seef{TRect.Contains}
\end{function}
\latex{\inputlisting{objectex/ex1.pp}}
\html{\input{objectex/ex1.tex}}
\begin{function}{TRect.Equals}
\Declaration
Function TRect.Equals (R: TRect): Boolean;
\Description
\var{Equals} returns \var{True} if the rectangle has the
same corner points \var{A,B} as the rectangle R, and \var{False}
otherwise.
\Errors
None.
\SeeAlso
\seefl{Empty}{TRect.Empty}, \seefl{Contains}{TRect.Contains}
\end{function}
For an example, see \seef{TRect.Empty}
\begin{function}{TRect.Contains}
\Declaration
Function TRect.Contains (P: TPoint): Boolean;
\Description
\var{Contains} returns \var{True} if the point \var{P} is contained
in the rectangle (including borders), \var{False} otherwise.
\Errors
None.
\SeeAlso
\seepl{Intersect}{TRect.Intersect}, \seefl{Equals}{TRect.Equals}
\end{function}
\begin{procedure}{TRect.Copy}
\Declaration
Procedure TRect.Copy (R: TRect);
\Description
Assigns the rectangle R to the object. After the call to \var{Copy}, the
rectangle R has been copied to the object that invoked \var{Copy}.
\Errors
None.
\SeeAlso
\seepl{Assign}{TRect.Assign}
\end{procedure}
\latex{\inputlisting{objectex/ex2.pp}}
\html{\input{objectex/ex2.tex}}
\begin{procedure}{TRect.Union}
\Declaration
Procedure TRect.Union (R: TRect);
\Description
\var{Union} enlarges the current rectangle so that it becomes the union
of the current rectangle with the rectangle \var{R}.
\Errors
None.
\SeeAlso
\seepl{Intersect}{TRect.Intersect}
\end{procedure}
\latex{\inputlisting{objectex/ex3.pp}}
\html{\input{objectex/ex3.tex}}
\begin{procedure}{TRect.Intersect}
\Declaration
Procedure TRect.Intersect (R: TRect);
\Description
\var{Intersect} makes the intersection of the current rectangle with
\var{R}. If the intersection is empty, then the rectangle is set to the empty
rectangle at coordinate (0,0).
\Errors
None.
\SeeAlso
\seepl{Union}{TRect.Union}
\end{procedure}
\latex{\inputlisting{objectex/ex4.pp}}
\html{\input{objectex/ex4.tex}}
\begin{procedure}{TRect.Move}
\Declaration
Procedure TRect.Move (ADX, ADY: Sw\_Integer);
\Description
\var{Move} moves the current rectangle along a vector with components
\var{(ADX,ADY)}. It adds \var{ADX} to the X-coordinate of both corner
points, and \var{ADY} to both end points.
\Errors
None.
\SeeAlso
\seepl{Grow}{TRect.Grow}
\end{procedure}
\latex{\inputlisting{objectex/ex5.pp}}
\html{\input{objectex/ex5.tex}}
\begin{procedure}{TRect.Grow}
\Declaration
Procedure TRect.Grow (ADX, ADY: Sw\_Integer);
\Description
\var{Grow} expands the rectangle with an amount \var{ADX} in the \var{X}
direction (both on the left and right side of the rectangle, thus adding a
length 2*ADX to the width of the rectangle), and an amount \var{ADY} in
the \var{Y} direction (both on the top and the bottom side of the rectangle,
adding a length 2*ADY to the height of the rectangle.
\var{ADX} and \var{ADY} can be negative. If the resulting rectangle is empty, it is set
to the empty rectangle at \var{(0,0)}.
\Errors
None.
\SeeAlso
\seepl{Move}{TRect.Move}.
\end{procedure}
\latex{\inputlisting{objectex/ex6.pp}}
\html{\input{objectex/ex7.tex}}
\begin{procedure}{TRect.Assign}
\Declaration
Procedure Trect.Assign (XA, YA, XB, YB: Sw\_Integer);
\Description
\var{Assign} sets the corner points of the rectangle to \var{(XA,YA)} and
\var{(Xb,Yb)}.
\Errors
None.
\SeeAlso
\seepl{Copy}{TRect.Copy}
\end{procedure}
For an example, see \seep{TRect.Copy}.
\section{TObject}
\label{se:TObject}
The full declaration of the \var{TObject} type is:
\begin{verbatim}
TYPE
TObject = OBJECT
CONSTRUCTOR Init;
PROCEDURE Free;
DESTRUCTOR Done;Virtual;
END;
PObject = ^TObject;
\end{verbatim}
\begin{procedure}{TObject.Init}
\Declaration
Constructor TObject.Init;
\Description
Instantiates a new object of type \var{TObject}. It fills the instance up
with Zero bytes.
\Errors
None.
\SeeAlso
\seepl{Free}{TObject.Free}, \seepl{Done}{TObject.Done}
\end{procedure}
For an example, see \seepl{Free}{TObject.Free}
\begin{procedure}{TObject.Free}
\Declaration
Procedure TObject.Free;
\Description
\var{Free} calls the destructor of the object, and releases the memory
occupied by the instance of the object.
\Errors
No checking is performed to see whether \var{self} is \var{nil} and whether
the object is indeed allocated on the heap.
\SeeAlso
\seepl{Init}{TObject.Init}, \seepl{Done}{TObject.Done}
\end{procedure}
\latex{\inputlisting{objectex/ex7.pp}}
\html{\input{objectex/ex7.tex}}
\begin{procedure}{TObject.Done}
\Declaration
Destructor TObject.Done;Virtual;
\Description
\var{Done}, the destructor of \var{TObject} does nothing. It is mainly
intended to be used in the \seep{TObject.Free} method.
\Errors
None.
\SeeAlso
\seepl{Free}{TObject.Free}, \seepl{Init}{TObject.Init}
\end{procedure}
\section{TStream}
\label{se:TStream}
The \var{TStream} object is the ancestor for all streaming objects, i.e.
objects that have the capability to store and retrieve data.
It defines a number of methods that are common to all objects that implement
streaming, many of them are virtual, and are only implemented in the
descendrnt types.
Programs should not instantiate objects of type TStream directly, but
instead instantiate a descendant type, such as \var{TDosStream},
\var{TMemoryStream}.
This is the full declaration of the \var{TStream} object:
\begin{verbatim}
TYPE
TStream = OBJECT (TObject)
Status : Integer; { Stream status }
ErrorInfo : Integer; { Stream error info }
StreamSize: LongInt; { Stream current size }
Position : LongInt; { Current position }
FUNCTION Get: PObject;
FUNCTION StrRead: PChar;
FUNCTION GetPos: Longint; Virtual;
FUNCTION GetSize: Longint; Virtual;
FUNCTION ReadStr: PString;
PROCEDURE Open (OpenMode: Word); Virtual;
PROCEDURE Close; Virtual;
PROCEDURE Reset;
PROCEDURE Flush; Virtual;
PROCEDURE Truncate; Virtual;
PROCEDURE Put (P: PObject);
PROCEDURE StrWrite (P: PChar);
PROCEDURE WriteStr (P: PString);
PROCEDURE Seek (Pos: LongInt); Virtual;
PROCEDURE Error (Code, Info: Integer); Virtual;
PROCEDURE Read (Var Buf; Count: Sw_Word); Virtual;
PROCEDURE Write (Var Buf; Count: Sw_Word); Virtual;
PROCEDURE CopyFrom (Var S: TStream; Count: Longint);
END;
PStream = ^TStream;
\end{verbatim}
\begin{function}{TStream.Get}
\Declaration
Function TStream.Get : PObject;
\Description
\var{Get} reads an object definition from a stream, and returns
a pointer to an instance of this object.
\Errors
On error, \var{TStream.Status} is set, and NIL is returned.
\SeeAlso
\seepl{Put}{TStream.Put}
\end{function}
\begin{function}{TStream.StrRead}
\Declaration
Function TStream.StrRead: PChar;
\Description
\var{StrRead} reads a string from the stream, allocates memory
for it, and returns a pointer to a null-terminated copy of the string
on the heap.
\Errors
On error, \var{Nil} is returned.
\SeeAlso
\seepl{StrWrite}{TStream.StrWrite}, \seefl{ReadStr}{TStream.ReadStr}
\end{function}
\begin{function}{TStream.GetPos}
\Declaration
TSTream.GetPos : Longint; Virtual;
\Description
If the stream's status is \var{stOk}, \var{GetPos} returns the current
position in the stream. Otherwise it returns \var{-1}
\Errors
\var{-1} is returned if the status is an error condition.
\SeeAlso
\seepl{Seek}{TStream.Seek}, \seefl{GetSize}{TStream.GetSize}
\end{function}
\begin{function}{TStream.GetSize}
\Declaration
Function TStream.GetSize: Longint; Virtual;
\Description
If the stream's status is \var{stOk} then \var{GetSize} returns
the size of the stream, otherwise it returns \var{-1}.
\Errors
\var{-1} is returned if the status is an error condition.
\SeeAlso
\seepl{Seek}{TStream.Seek}, \seefl{GetPos}{TStream.GetPos}
\end{function}
\begin{function}{TStream.ReadStr}
\Declaration
Function TStream.ReadStr: PString;
\Description
\var{ReadStr} reads a string from the stream, copies it to the heap
and returns a pointer to this copy. The string is saved as a pascal
string, and hence is NOT null terminated.
\Errors
On error (e.g. not enough memory), \var{Nil} is returned.
\SeeAlso
\seefl{StrRead}{TStream.StrRead}
\end{function}
\begin{procedure}{TStream.Open}
\Declaration
Procedure TStream.Open (OpenMode: Word); Virtual;
\Description
\var{Open} is an abstract method, that should be overridden by descendent
objects. Since opening a stream depends on the stream's type this is not
surprising.
\Errors
None.
\SeeAlso
\seepl{Close}{TStream.Close}, \seepl{Reset}{TStream.Reset}
\end{procedure}
\begin{procedure}{TStream.Close}
\Declaration
Procedure TStream.Close; Virtual;
\Description
\var{Close} is an abstract method, that should be overridden by descendent
objects. Since Closing a stream depends on the stream's type this is not
surprising.
\Errors
None.
\SeeAlso
\seepl{Open}{TStream.Open}, \seepl{Reset}{TStream.Reset}
\end{procedure}
\begin{procedure}{TStream.Reset}
\Declaration
PROCEDURE TStream.Reset;
\Description
\var{Reset} sets the stream's status to \var{0}, as well as the ErrorInfo
\Errors
None.
\SeeAlso
\seepl{Open}{TStream.Open}, \seepl{Close}{TStream.Close}
\end{procedure}
\begin{procedure}{TStream.Flush}
\Declaration
Procedure TStream.Flush; Virtual;
\Description
\var{Flush} is an abstract method that should be overridden by descendent
objects. It serves to enable the programmer to tell streams that implement
a buffer to clear the buffer.
\Errors
None.
\SeeAlso
\seepl{Truncate}{TStream.Truncate}
\end{procedure}
\begin{procedure}{TStream.Truncate}
\Declaration
Procedure TStream.Truncate; Virtual;
\Description
\var{Truncate} is an abstract procedure that should be overridden by
descendent objects. It serves to enable the programmer to truncate the
size of the stream to the current file position.
\Errors
None.
\SeeAlso
\seepl{Seek}{TStream.Seek}
\end{procedure}
\begin{procedure}{TStream.Put}
\Declaration
Procedure TStream.Put (P: PObject);
\Description
\var{Put} writes the object pointed to by \var{P}. \var{P} should be
non-nil. The object type must have been registered with \seep{RegisterType}.
After the object has been written, it can be read again with \seefl{Get}{TStream.Get}.
\Errors
No check is done whether P is \var{Nil} or not. Passing \var{Nil} will cause
a run-time error 216 to be generated. If the object has not been registered,
the status of the stream will be set to \var{stPutError}.
\SeeAlso
\seefl{Get}{TStream.Get}
\end{procedure}
\begin{procedure}{TStream.StrWrite}
\Declaration
Procedure TStream.StrWrite (P: PChar);
\Description
\var{StrWrite} writes the null-terminated string \var{P} to the stream.
\var{P} can only be 65355 bytes long.
\Errors
None.
\SeeAlso
\seepl{WriteStr}{TStream.WriteStr}, \seefl{StrRead}{TStream.StrRead},
\seefl{ReadStr}{TStream.ReadStr}
\end{procedure}
\begin{procedure}{TStream.WriteStr}
\Declaration
Procedure TStream.WriteStr (P: PString);
\Description
\var{StrWrite} writes the pascal string pointed to by \var{P} to the stream.
\Errors
None.
\SeeAlso
\seepl{StrWrite}{TStream.StrWrite}, \seefl{StrRead}{TStream.StrRead},
\seefl{ReadStr}{TStream.ReadStr}
\end{procedure}
\begin{procedure}{TStream.Seek}
\Declaration
PROCEDURE TStream.Seek (Pos: LongInt); Virtual;
\Description
Seek sets the position to \var{Pos}. This position is counted
from the beginning, and is zero based. (i.e. seeek(0) sets the position
pointer on the first byte of the stream)
\Errors
If \var{Pos} is larger than the stream size, \var{Status} is set to
\var{StSeekError}.
\SeeAlso
\seefl{GetPos}{TStream.GetPos}, \seefl{GetSize}{TStream.GetSize}
\end{procedure}
\begin{procedure}{TStream.Error}
\Declaration
Procedure TStream.Error (Code, Info: Integer); Virtual;
\Description
\var{Error} sets the stream's status to \var{Code} and \var{ErrorInfo}
to \var{Info}. If the \var{StreamError} procedural variable is set,
\var{Error} executes it, passing \var{Self} as an argument.
This method should not be called directly from a program. It is intended to
be used in descendent objects.
\Errors
None.
\SeeAlso
\end{procedure}
\begin{procedure}{TStream.Read}
\Declaration
Procedure TStream.Read (Var Buf; Count: Sw\_Word); Virtual;
\Description
\var{Read} is an abstract method that should be overridden by descendent
objects.
\var{Read} reads \var{Count} bytes from the stream into \var{Buf}.
It updates the position pointer, increasing it's value with \var{Count}.
\var{Buf} must be large enough to contain \var{Count} bytes.
\Errors
No checking is done to see if \var{Buf} is large enough to contain
\var{Count} bytes.
\SeeAlso
\seepl{Write}{TStream.Write}, \seefl{ReadStr}{TStream.ReadStr},
\seefl{StrRead}{TStream.StrRead}
\end{procedure}
\begin{procedure}{TStream.Write}
\Declaration
Procedure TStream.Write (Var Buf; Count: Sw\_Word); Virtual;
\Description
\var{Write} is an abstract method that should be overridden by descendent
objects.
\var{Write} writes \var{Count} bytes to the stream from \var{Buf}.
It updates the position pointer, increasing it's value with \var{Count}.
\Errors
No checking is done to see if \var{Buf} actually contains \var{Count} bytes.
\SeeAlso
\seepl{Read}{TStream.Read}, \seepl{WriteStr}{TStream.WriteStr},
\seepl{StrWrite}{TStream.StrWrite}
\end{procedure}
\begin{procedure}{TStream.CopyFrom}
\Declaration
Procedure TStream.CopyFrom (Var S: TStream; Count: Longint);
\Description
\var{CopyFrom} reads Count bytes from stream \var{S} and stores them
in the current stream. It uses the \seepl{Read}{TStream.Read} method
to read the data, and the \seepl{Write}{TStream.Write} method to
write in the current stream.
\Errors
None.
\SeeAlso
\seepl{Read}{TStream.Read}, \seepl{Write}{TStream.Write}
\end{procedure}
\section{TDosStream}
\label{se:TDosStream}
\var{TDosStream} is a steam that stores it's contents in a file.
it overrides a couple of methods of \var{TSteam} for this.
In addition to the fields inherited from \var{TStream} (see \sees{TStream}),
there are some extra fields, that describe the file. (mainly the name and
the OS file handle)
No buffering in memory is done when using \var{TDosStream}.
All data are written directly to the file. For a stream that buffers
in memory, see \sees{TBufStream}.
Here is the full declaration of the \var{TDosStream} object:
\begin{verbatim}
TYPE
TDosStream = OBJECT (TStream)
Handle: THandle; { DOS file handle }
FName : AsciiZ; { AsciiZ filename }
CONSTRUCTOR Init (FileName: FNameStr; Mode: Word);
DESTRUCTOR Done; Virtual;
PROCEDURE Close; Virtual;
PROCEDURE Truncate; Virtual;
PROCEDURE Seek (Pos: LongInt); Virtual;
PROCEDURE Open (OpenMode: Word); Virtual;
PROCEDURE Read (Var Buf; Count: Sw_Word); Virtual;
PROCEDURE Write (Var Buf; Count: Sw_Word); Virtual;
END;
PDosStream = ^TDosStream;
\end{verbatim}
\begin{procedure}{TDosStream.Init}
\Declaration
Constructor Init (FileName: FNameStr; Mode: Word);
\Description
\var{Init} instantiates an instance of \var{TDosStream}. The name of the
file that contains (or will contain) the data of the stream is given in
\var{FileName}. The \var{Mode} parameter determines whether a new file
should be created and what access rights you have on the file.
It can be one of the following constants:
\begin{description}
\item[stCreate] Creates a new file.
\item[stOpenRead] Read access only.
\item[stOpenWrite] Write access only.
\item[stOpen] Read and write access.
\end{description}
\Errors
On error, \var{Status} is set to \var{stInitError}, and \var{ErrorInfo}
is set to the \dos error code.
\SeeAlso
\seepl{Done}{TDosStream.Done}
\end{procedure}
\begin{procedure}{TDosStream.Done}
\Declaration
Destructor TDosStream.Done; Virtual;
\Description
\var{Done} closes the file if it was open and cleans up the
instance of \var{TDosStream}.
\Errors
None.
\SeeAlso
\seepl{Init}{TDosStream.Init},
\seepl{Close}{TDosStream.Close}
\end{procedure}
\begin{procedure}{TDosStream.Close}
\Declaration
Pocedure TDosStream.Close; Virtual;
\Description
\var{Close} closes the file if it was open, and sets \var{Handle} to -1.
Contrary to \seepl{Done}{TDosStream.Done} it does not clean up the instance
of \var{TDosStream}
\Errors
None.
\SeeAlso
\seep{TStream.Close}, \seepl{Init}{TDosStream.Init},
\seepl{Done}{TDosStream.Done}
\end{procedure}
\begin{procedure}{TDosStream.Truncate}
\Declaration
Procedure TDosStream.Truncate; Virtual;
\Description
If the status of the stream is \var{stOK}, then \var{Truncate} tries to
truncate the stream size to the current file position.
\Errors
If an error occurs, the stream's status is set to \var{stError} and
\var{ErrorInfo} is set to the OS error code.
\SeeAlso
\seep{TStream.Truncate}, \seefl{GetSize}{TStream.GetSize}
\end{procedure}
\begin{procedure}{TDosStream.Seek}
\Declaration
Procedure TDosStream.Seek (Pos: LongInt); Virtual;
\Description
If the stream's status is \var{stOK}, then \var{Seek} sets the
file position to \var{Pos}. \var{Pos} is a zero-based offset, counted from
the beginning of the file.
\Errors
In case an error occurs, the stream's status is set to \var{stSeekError},
and the OS error code is stored in \var{ErrorInfo}.
\SeeAlso
\seep{TStream.Seek}, \seefl{GetPos}{TStream.GetPos}
\end{procedure}
\begin{procedure}{TDosStream.Open}
\Declaration
Procedure TDosStream.Open (OpenMode: Word); Virtual;
\Description
If the stream's status is \var{stOK}, and the stream is closed then
\var{Open} re-opens the file stream with mode \var{OpenMode}.
This call can be used after a \seepl{Close}{TDosStream.Close} call.
\Errors
If an error occurs when re-opening the file, then \var{Status} is set
to \var{stOpenError}, and the OS error code is stored in \var{ErrorInfo}
\SeeAlso
\seep{TStream.Open}, \seepl{Close}{TDosStream.Close}
\end{procedure}
\begin{procedure}{TDosStream.Read}
\Declaration
Procedure TDosStream.Read (Var Buf; Count: Sw\_Word); Virtual;
\Description
If the Stream is open and the stream status is \var{stOK} then
\var{Read} will read \var{Count} bytes from the stream and place them
in \var{Buf}.
\Errors
In case of an error, \var{Status} is set to \var{StReadError}, and
\var{ErrorInfo} gets the OS specific error, or 0 when an attempt was
made to read beyond the end of the stream.
\SeeAlso
\seep{TStream.Read}, \seepl{Write}{TDosStream.Write}
\end{procedure}
\begin{procedure}{TDosStream.Write}
\Declaration
Procedure TDosStream.Write (Var Buf; Count: Sw\_Word); Virtual;
\Description
If the Stream is open and the stream status is \var{stOK} then
\var{Write} will write \var{Count} bytes from \var{Buf} and place them
in the stream.
\Errors
In case of an error, \var{Status} is set to \var{StWriteError}, and
\var{ErrorInfo} gets the OS specific error.
\SeeAlso
\seep{TStream.Write}, \seepl{Read}{TDosStream.Read}
\end{procedure}
\section{TBufStream}
\label{se:TBufStream}
\var{Bufstream} implements a buffered file stream. That is, all data written
to the stream is written to memory first. Only when the buffer is full, or
on explicit request, the data is written to disk.
Also, when reading from the stream, first the buffer is checked if there is
any unread data in it. If so, this is read first. If not the buffer is
filled again, and then the data is read from the buffer.
The size of the buffer is fixed and is set when constructing the file.
This is useful if you need heavy throughput for your stream, because it
speeds up operations.
\begin{verbatim}
TYPE
TBufStream = OBJECT (TDosStream)
LastMode: Byte; { Last buffer mode }
BufSize : Sw_Word; { Buffer size }
BufPtr : Sw_Word; { Buffer start }
BufEnd : Sw_Word; { Buffer end }
Buffer : PByteArray; { Buffer allocated }
CONSTRUCTOR Init (FileName: FNameStr; Mode, Size: Word);
DESTRUCTOR Done; Virtual;
PROCEDURE Close; Virtual;
PROCEDURE Flush; Virtual;
PROCEDURE Truncate; Virtual;
PROCEDURE Seek (Pos: LongInt); Virtual;
PROCEDURE Open (OpenMode: Word); Virtual;
PROCEDURE Read (Var Buf; Count: Sw_Word); Virtual;
PROCEDURE Write (Var Buf; Count: Sw_Word); Virtual;
END;
PBufStream = ^TBufStream;
\end{verbatim}
\begin{procedure}{TBufStream.Init}
\Declaration
Constructor Init (FileName: FNameStr; Mode,Size: Word);
\Description
\var{Init} instantiates an instance of \var{TBufStream}. The name of the
file that contains (or will contain) the data of the stream is given in
\var{FileName}. The \var{Mode} parameter determines whether a new file
should be created and what access rights you have on the file.
It can be one of the following constants:
\begin{description}
\item[stCreate] Creates a new file.
\item[stOpenRead] Read access only.
\item[stOpenWrite] Write access only.
\item[stOpen] Read and write access.
\end{description}
The \var{Size} parameter determines the size of the buffer that will be
created. It should be different from zero.
\Errors
On error, \var{Status} is set to \var{stInitError}, and \var{ErrorInfo}
is set to the \dos error code.
\SeeAlso
\seep{TDosStream.Init}, \seepl{Done}{TBufStream.Done}
\end{procedure}
\begin{procedure}{TBufStream.Done}
\Declaration
Destructor TBufStream.Done; Virtual;
\Description
\var{Done} flushes and closes the file if it was open and cleans up the
instance of \var{TBufStream}.
\Errors
None.
\SeeAlso
\seep{TDosStream.Done}, \seepl{Init}{TBufStream.Init},
\seepl{Close}{TBufStream.Close}
\end{procedure}
\begin{procedure}{TBufStream.Close}
\Declaration
Pocedure TBufStream.Close; Virtual;
\Description
\var{Close} flushes and closes the file if it was open, and sets \var{Handle} to -1.
Contrary to \seepl{Done}{TBufStream.Done} it does not clean up the instance
of \var{TBufStream}
\Errors
None.
\SeeAlso
\seep{TStream.Close}, \seepl{Init}{TBufStream.Init},
\seepl{Done}{TBufStream.Done}
\end{procedure}
\begin{procedure}{TBufStream.Flush}
\Declaration
Pocedure TBufStream.Flush; Virtual;
\Description
When the stream is in write mode, the contents of the buffer are written to
disk, and the buffer position is set to zero.
When the stream is in read mode, the buffer position is set to zero.
\Errors
Write errors may occur if the file was in write mode.
see \seepl{Write}{TBufStream.Write} for more info on the errors.
\SeeAlso
\seep{TStream.Close}, \seepl{Init}{TBufStream.Init},
\seepl{Done}{TBufStream.Done}
\end{procedure}
\begin{procedure}{TBufStream.Truncate}
\Declaration
Procedure TBufStream.Truncate; Virtual;
\Description
If the status of the stream is \var{stOK}, then \var{Truncate} tries to
flush the buffer, and then truncates the stream size to the current
file position.
\Errors
Errors can be those of \seepl{Flush}{TBufStream.Flush} or
\seep{TDosStream.Truncate}.
\SeeAlso
\seep{TStream.Truncate}, \seep{TDosStream.Truncate},
\seefl{GetSize}{TStream.GetSize}
\end{procedure}
\begin{procedure}{TBufStream.Seek}
\Declaration
Procedure TBufStream.Seek (Pos: LongInt); Virtual;
\Description
If the stream's status is \var{stOK}, then \var{Seek} sets the
file position to \var{Pos}. \var{Pos} is a zero-based offset, counted from
the beginning of the file.
\Errors
In case an error occurs, the stream's status is set to \var{stSeekError},
and the OS error code is stored in \var{ErrorInfo}.
\SeeAlso
\seep{TStream.Seek}, \seefl{GetPos}{TStream.GetPos}
\end{procedure}
\begin{procedure}{TBufStream.Open}
\Declaration
Procedure TBufStream.Open (OpenMode: Word); Virtual;
\Description
If the stream's status is \var{stOK}, and the stream is closed then
\var{Open} re-opens the file stream with mode \var{OpenMode}.
This call can be used after a \seepl{Close}{TBufStream.Close} call.
\Errors
If an error occurs when re-opening the file, then \var{Status} is set
to \var{stOpenError}, and the OS error code is stored in \var{ErrorInfo}
\SeeAlso
\seep{TStream.Open}, \seepl{Close}{TBufStream.Close}
\end{procedure}
\begin{procedure}{TBufStream.Read}
\Declaration
Procedure TBufStream.Read (Var Buf; Count: Sw\_Word); Virtual;
\Description
If the Stream is open and the stream status is \var{stOK} then
\var{Read} will read \var{Count} bytes from the stream and place them
in \var{Buf}.
\var{Read} will first try to read the data from the stream's internal
buffer. If insufficient data is available, the buffer will be filled before
contiunuing to read. This process is repeated until all needed data
has been read.
\Errors
In case of an error, \var{Status} is set to \var{StReadError}, and
\var{ErrorInfo} gets the OS specific error, or 0 when an attempt was
made to read beyond the end of the stream.
\SeeAlso
\seep{TStream.Read}, \seepl{Write}{TBufStream.Write}
\end{procedure}
\begin{procedure}{TBufStream.Write}
\Declaration
Procedure TBufStream.Write (Var Buf; Count: Sw\_Word); Virtual;
\Description
If the Stream is open and the stream status is \var{stOK} then
\var{Write} will write \var{Count} bytes from \var{Buf} and place them
in the stream.
\var{Write} will first try to write the data to the stream's internal
buffer. When the internal buffer is full, then the contents will be written
to disk. This process is repeated until all data has been written.
\Errors
In case of an error, \var{Status} is set to \var{StWriteError}, and
\var{ErrorInfo} gets the OS specific error.
\SeeAlso
\seep{TStream.Write}, \seepl{Read}{TBufStream.Read}
\end{procedure}
\section{TMemoryStream}
\label{se:TMemoryStream}
The \var{TMemoryStream} object implements a stream that stores it's data
in memory. The data is stored on the heap, with the possibility to specify
the maximum amout of data, and the the size of the memory blocks being used.
\begin{verbatim}
TYPE
TMemoryStream = OBJECT (TStream)
BlkCount: Sw_Word; { Number of segments }
BlkSize : Word; { Memory block size }
MemSize : LongInt; { Memory alloc size }
BlkList : PPointerArray; { Memory block list }
CONSTRUCTOR Init (ALimit: Longint; ABlockSize: Word);
DESTRUCTOR Done; Virtual;
PROCEDURE Truncate; Virtual;
PROCEDURE Read (Var Buf; Count: Sw_Word); Virtual;
PROCEDURE Write (Var Buf; Count: Sw_Word); Virtual;
END;
PMemoryStream = ^TMemoryStream;
\end{verbatim}
\begin{procedure}{TMemoryStream.Init}
\Declaration
Constructor TMemoryStream.Init (ALimit: Longint; ABlockSize: Word);
\Description
\var{Init} instantiates a new \var{TMemoryStream} object. The
memorystreamobject will initially allocate at least \var{ALimit} bytes memory,
divided into memory blocks of size \var{ABlockSize}.
The number of blocks needed to get to \var{ALimit} bytes is rounded up.
By default, the number of blocks is 1, and the size of a block is 8192. This
is selected if you specify 0 as the blocksize.
\Errors
If the stream cannot allocate the initial memory needed for the memory blocks, then
the stream's status is set to \var{stInitError}.
\SeeAlso
\seepl{Done}{TMemoryStream.Done}
\end{procedure}
\begin{procedure}{TMemoryStream.Done}
\Declaration
Destructor TMemoryStream.Done; Virtual;
\Description
\var{Done} releases the memory blocks used by the stream, and then cleans up
the memory used by the stream object itself.
\Errors
None.
\SeeAlso
\seepl{Init}{TMemoryStream.Init}
\end{procedure}
\begin{procedure}{TMemoryStream.Truncate}
\Declaration
Procedure TMemoryStream.Truncate; Virtual;
\Description
\var{Truncate} sets the size of the memory stream equal to the current
position. It de-allocates any memory-blocks that are no longer needed, so
that the new size of the stream is the current position in the stream,
rounded up to the first multiple of the stream blocksize.
\Errors
If an error occurs during memory de-allocation, the stream's status is set
to \var{stError}
\SeeAlso
\seep{TStream.Truncate}
\end{procedure}
\begin{procedure}{TMemoryStream.Read}
\Declaration
Procedure Read (Var Buf; Count: Sw\_Word); Virtual;
\Description
\var{Read} reads \var{Count} bytes from the stream to \var{Buf}. It updates
the position of the stream.
\Errors
If there is not enough data available, no data is read, and the stream's
status is set to \var{stReadError}.
\SeeAlso
\var{TStream.Read}, \seepl{Write}{TMemoryStream.Write}
\end{procedure}
\begin{procedure}{TMemoryStream.Write}
\Declaration
Procedure Write (Var Buf; Count: Sw\_Word); Virtual;
\Description
\var{Write} copies \var{Count} bytes from \var{Buf} to the stream. It
updates the position of the stream.
If not enough memory is available to hold the extra \var{Count} bytes,
then the stream will try to expand, by allocating as much blocks with
size \var{BlkSize} (as specified in the constuctor call
\seepl{Init}{TMemoryStream.Init}) as needed.
\Errors
If the stream cannot allocate more memory, then the status is set to
\var{stWriteError}
\SeeAlso
\seep{TStream.Write}, \seepl{Read}{TMemoryStream.Read}
\end{procedure}
\section{TCollection}
\label{se:TCollection}
The \var{TCollection} object manages a collection of pointers or objects.
It also provides a series of methods to manipulate these pointers or
objects.
Whether or not objects are used depends on the kind of calls you use.
ALl kinds come in 2 flavors, one for objects, one for pointers.
This is the full declaration of the \var{TCollection} object:
\begin{verbatim}
TYPE
TItemList = Array [0..MaxCollectionSize - 1] Of Pointer;
PItemList = ^TItemList;
TCollection = OBJECT (TObject)
Items: PItemList; { Item list pointer }
Count: Sw_Integer; { Item count }
Limit: Sw_Integer; { Item limit count }
Delta: Sw_Integer; { Inc delta size }
Constructor Init (ALimit, ADelta: Sw_Integer);
Constructor Load (Var S: TStream);
Destructor Done; Virtual;
Function At (Index: Sw_Integer): Pointer;
Function IndexOf (Item: Pointer): Sw_Integer; Virtual;
Function GetItem (Var S: TStream): Pointer; Virtual;
Function LastThat (Test: Pointer): Pointer;
Function FirstThat (Test: Pointer): Pointer;
Procedure Pack;
Procedure FreeAll;
Procedure DeleteAll;
Procedure Free (Item: Pointer);
Procedure Insert (Item: Pointer); Virtual;
Procedure Delete (Item: Pointer);
Procedure AtFree (Index: Sw_Integer);
Procedure FreeItem (Item: Pointer); Virtual;
Procedure AtDelete (Index: Sw_Integer);
Procedure ForEach (Action: Pointer);
Procedure SetLimit (ALimit: Sw_Integer); Virtual;
Procedure Error (Code, Info: Integer); Virtual;
Procedure AtPut (Index: Sw_Integer; Item: Pointer);
Procedure AtInsert (Index: Sw_Integer; Item: Pointer);
Procedure Store (Var S: TStream);
Procedure PutItem (Var S: TStream; Item: Pointer); Virtual;
END;
PCollection = ^TCollection;
\end{verbatim}
\begin{procedure}{TCollection.Init}
\Declaration
Constructor TCollection.Init (ALimit, ADelta: Sw\_Integer);
\Description
\var{Init} initializes a new instance of a collection. It sets the (initial) maximum number
of items in the collection to \var{ALimit}. \var{ADelta} is the increase
size : The number of memory places that will be allocatiod in case \var{ALimit} is reached,
and another element is added to the collection.
\Errors
None.
\SeeAlso
\seepl{Load}{TCollection.Load}, \seepl{Done}{TCollection.Done}
\end{procedure}
\begin{procedure}{TCollection.Load}
\Declaration
Constructor TCollection.Load (Var S: TStream);
\Description
\var{Load} initializes a new instance of a collection. It reads from stream
\var{S} the item count, the item limit count, and the increase size. After
that, it reads the specified number of items from the stream.
% Do not call this method if you intend to use only pointers in your collection.
\Errors
Errors returned can be those of \seefl{GetItem}{TCollection.GetItem}.
\SeeAlso
\seepl{Init}{TCollection.Init}, \seefl{GetItem}{TCollection.GetItem},
\seepl{TCollection.Done}.
\end{procedure}
\begin{procedure}{TCollection.Done}
\Declaration
Destructor TCollection.Done; Virtual;
\Description
\var{Done} frees all objects in the collection, and then releases all memory
occupied by the instance.
% Do not call this method if you intend to use only pointers in your collection.
\Errors
None.
\SeeAlso
\seepl{Init}{TCollection.Init}, \seepl{FreeAll}{TCollection.FreeAll}
\end{procedure}
\begin{function}{TCollection.At}
\Declaration
Function TCollection.At (Index: Sw\_Integer): Pointer;
\Description
\var{At} returns the item at position \var{Index}.
\Errors
If \var{Index} is less than zero or larger than the number of items
in the collection, seepl{Error}{TCollection.Error} is called with
\var{coIndexError} and \var{Index} as arguments, resulting in a run-time
error.
\SeeAlso
\seepl{Insert}{TCollection.Insert}
\end{function}
\begin{function}{TCollection.IndexOf}
\Declaration
Function TCollection.IndexOf (Item: Pointer): Sw\_Integer; Virtual;
\Description
\var{IndexOf} returns the index of \var{Item} in the collection.
If \var{Item} isn't present in the collection, -1 is returned.
\Errors
\SeeAlso
\end{function}
\begin{function}{TCollection.GetItem}
\Declaration
Function TCollection.GetItem (Var S: TStream): Pointer; Virtual;
\Description
\var{GetItem} reads a single item off the stream \var{S}, and
returns a pointer to this item.
\Errors
Possible errors are the ones from \seef{TStream.Get}.
\SeeAlso
\seef{TStream.get}, seepl{Store}{TCollection.Store}
\end{function}
\begin{function}{TCollection.LastThat}
\Declaration
Function TCollection.LastThat (Test: Pointer): Pointer;
\Description
This function returns the last item in the collection for which \var{Test}
returns a non-nil result. \var{Test} is a function that accepts 1 argument:
a pointer to an object, and that returns a pointer as a result.
\Errors
None.
\SeeAlso
\seefl{FirstThat}{TCollection.FirstThat}
\end{function}
\begin{function}{TCollection.FirstThat}
\Declaration
Function TCollection.FirstThat (Test: Pointer): Pointer;
\Description
This function returns the first item in the collection for which \var{Test}
returns a non-nil result. \var{Test} is a function that accepts 1 argument:
a pointer to an object, and that returns a pointer as a result.
\Errors
None.
\SeeAlso
\seefl{LastThat}{TCollection.LastThat}
\end{function}
\begin{procedure}{TCollection.Pack}
\Declaration
Procedure TCollection.Pack;
\Description
\var{Pack} removes all \var{Nil} pointers from the collection, and adjusts
\var{Count} to reflect this change. No memory is freed as a result of this
call. In order to free any memory, you can call \var{SetLimit} with an
argument of \var{Count} after a call to \var{Pack}.
\Errors
None.
\SeeAlso
\seepl{SetLimit}{TCollection.SetLimit}
\end{procedure}
\begin{procedure}{TCollection.FreeAll}
\Declaration
Procedure TCollection.FreeAll;
\Description
\var{FreeAll} calls the destructor of each object in the collection.
It doesn't release any memory occumpied by the collection itself, but it
does set \var{Count} to zero.
\Errors
\SeeAlso
\seepl{DeleteAll}{TCollection.DeleteAll}, \seepl{FreeItem}{TCollection.FreeItem}
\end{procedure}
\begin{procedure}{TCollection.DeleteAll}
\Declaration
Procedure TCollection.DeleteAll;
\Description
\var{DeleteAll} deletes all elements from the collection. It just sets
the \var{Count} variable to zero. Contrary to
\seepl{FreeAll}{TCollection.FreeAll}, \var{DeletAll} doesn't call the
destructor of the objects.
\Errors
None.
\SeeAlso
\seepl{FreeAll}{TCollection.FreeAll}, \seepl{Delete}{TCollection.Delete}
\end{procedure}
\begin{procedure}{TCollection.Free}
\Declaration
Procedure TCollection.Free (Item: Pointer);
\Description
\var{Free} Deletes \var{Item} from the collection, and calls the destructor
\var{Done} of the object.
\Errors
If the \var{Item} is not in the collection, \var{Error} will be called with
\var{coIndexError}.
\SeeAlso
\seepl{FreeItem}{TCollection.FreeItem},
\end{procedure}
\begin{procedure}{TCollection.Insert}
\Declaration
Procedure TCollection.Insert (Item: Pointer); Virtual;
\Description
\var{Insert} inserts \var{Item} in the collection. \var{TCollection}
inserts this item at the end, but descendent objects may insert it at
another place.
\Errors
None.
\SeeAlso
\seepl{AtInsert}{TCollection.AtInsert}, \seepl{AtPut}{TCollection.AtPut},
\end{procedure}
\begin{procedure}{TCollection.Delete}
\Declaration
Procedure TCollection.Delete (Item: Pointer);
\Description
\var{Delete} deletes \var{Item} from the collection. It doesn't call the
item's destructor, though. For this the \seepl{Free}{TCollection.Free}
call is provided.
\Errors
If the \var{Item} is not in the collection, \var{Error} will be called with
\var{coIndexError}.
\SeeAlso
\seepl{AtDelete}{TCollection.AtDelete},\seepl{Free}{TCollection.Free}
\end{procedure}
\begin{procedure}{TCollection.AtFree}
\Declaration
Procedure TCollection.AtFree (Index: Sw\_Integer);
\Description
\var{AtFree} deletes the item at position \var{Index} in the collection,
and calls the item's destructor if it is not \var{Nil}.
\Errors
If \var{Index} isn't valid then \seepl{Error}{TCollection.Error} is called
with \var{CoIndexError}.
\SeeAlso
\seepl{Free}{TCollection.Free}, \seepl{AtDelete}{TCollection.AtDelete}
\end{procedure}
\begin{procedure}{TCollection.FreeItem}
\Declaration
Procedure TCollection.FreeItem (Item: Pointer); Virtual;
\Description
\var{FreeItem} calls the destructor of \var{Item} if it is not nil.
\Errors
None.
\SeeAlso
\seepl{Free}{TCollection.AtFree}, seepl{AtFree}{TCollection.AtFree}
\end{procedure}
\begin{procedure}{TCollection.AtDelete}
\Declaration
Procedure TCollection.AtDelete (Index: Sw\_Integer);
\Description
\var{AtDelete} deletes the pointer at position \var{Index} in the
collection. It doesn't call the object's destructor.
\Errors
If \var{Index} isn't valid then \seepl{Error}{TCollection.Error} is called
with \var{CoIndexError}.
\SeeAlso
\seepl{Delete}{TCollection.Delete}
\end{procedure}
\begin{procedure}{TCollection.ForEach}
\Declaration
Procedure TCollection.ForEach (Action: Pointer);
\Description
\var{ForEach} calls \var{Action} for each element in the collection,
and passes the element as an argument to \var{Action}.
\var{Action} is a procedural type variable that accepts a pointer as an
argument.
\Errors
None.
\SeeAlso
\seepl{FirstThat}{TCollection.FirstThat}, \seepl{LastThat}{TCollection.LastThat}
\end{procedure}
\begin{procedure}{TCollection.SetLimit}
\Declaration
Procedure TCollection.SetLimit (ALimit: Sw\_Integer); Virtual;
\Description
\var{SetLimit} sets the maximum number of elements in the collection.
\var{ALimit} must not be less than \var{Count}, and should not be larger
than \var{MaxCollectionSize}
\Errors
None.
\SeeAlso
\seepl{Init}{TCollection.Init}
\end{procedure}
\begin{procedure}{TCollection.Error}
\Declaration
Procedure TCollection.Error (Code, Info: Integer); Virtual;
\Description
\var{Error} is called by the various \var{TCollection} methods
in case of an error condition. The default behaviour is to make
a call to \var{RunError} with an error of \var{212-Code}.
\Errors
\SeeAlso
\end{procedure}
\begin{procedure}{TCollection.AtPut}
\Declaration
Procedure TCollection.AtPut (Index: Sw\_Integer; Item: Pointer);
\Description
\var{AtPut} sets the element at position \var{Index} in the collection
to \var{Item}. Any previous value is overwritten.
\Errors
If \var{Index} isn't valid then \seepl{Error}{TCollection.Error} is called
with \var{CoIndexError}.
\SeeAlso
\end{procedure}
\begin{procedure}{TCollection.AtInsert}
\Declaration
Procedure TCollection.AtInsert (Index: Sw\_Integer; Item: Pointer);
\Description
\var{AtInsert} inserts \var{Item} in the collection at position \var{Index},
shifting all elements by one position. In case the current limit is reached,
the collection will try to expand with a call to \var{SetLimit}
\Errors
If \var{Index} isn't valid then \seepl{Error}{TCollection.Error} is called
with \var{CoIndexError}. If the collection fails to expand, then
\var{coOverFlow} is passd to \var{Error}.
\SeeAlso
\seepl{Insert}{TCollection.Insert}
\end{procedure}
\begin{procedure}{TCollection.Store}
\Declaration
Procedure TCollection.Store (Var S: TStream);
\Description
\var{Store} writes the collection to the stream \var{S}. It does
this by writeing the current \var{Count}, \var{Limit} and \var{Delta}
to the stream, and then writing each item to the stream.
The contents of the stream are then suitable for instantiating another
collection with \seepl{Load}{TCollection.Load}.
\Errors
Errors returned are those by \seep{TStream.Put}.
\SeeAlso
\seepl{Load}{TCollection.Load}, \seepl{PutItem}{TCollection.PutItem}
\end{procedure}
\begin{procedure}{TCollection.PutItem}
\Declaration
Procedure TCollection.PutItem (Var S: TStream; Item: Pointer); Virtual;
\Description
\var{PutItem} writes \var{Item} to stream \var{S}.
\Errors
Errors are those returned by \seep{TStream.Put}.
\SeeAlso
\seepl{Store}{TCollection.Store}, \seefl{GetItem}{TCollection.GetItem}.
\end{procedure}
\section{TSortedCollection}
\label{se:TSortedCollection}
\begin{verbatim}
TYPE
TSortedCollection = OBJECT (TCollection)
Duplicates: Boolean; { Duplicates flag }
Constructor Init (ALimit, ADelta: Sw_Integer);
Constructor Load (Var S: TStream);
Function KeyOf (Item: Pointer): Pointer; Virtual;
Function IndexOf (Item: Pointer): Sw_Integer; Virtual;
Function Compare (Key1, Key2: Pointer): Sw_Integer; Virtual;
Function Search (Key: Pointer; Var Index: Sw_Integer): Boolean;Virtual;
Procedure Insert (Item: Pointer); Virtual;
Procedure Store (Var S: TStream);
END;
PSortedCollection = ^TSortedCollection;
\end{verbatim}
\section{TStringCollection}
\label{se:TStringCollection}
\begin{verbatim}
TYPE
TStringCollection = OBJECT (TSortedCollection)
Function GetItem (Var S: TStream): Pointer; Virtual;
Function Compare (Key1, Key2: Pointer): Sw_Integer; Virtual;
Procedure FreeItem (Item: Pointer); Virtual;
Procedure PutItem (Var S: TStream; Item: Pointer); Virtual;
END;
PStringCollection = ^TStringCollection;
\end{verbatim}
\section{TStrCollection}
\label{se:TStrCollection}
\begin{verbatim}
TYPE
TStrCollection = OBJECT (TSortedCollection)
Function Compare (Key1, Key2: Pointer): Sw_Integer; Virtual;
Function GetItem (Var S: TStream): Pointer; Virtual;
Procedure FreeItem (Item: Pointer); Virtual;
Procedure PutItem (Var S: TStream; Item: Pointer); Virtual;
END;
PStrCollection = ^TStrCollection;
\end{verbatim}
\section{TUnSortedStrCollection}
\label{se:TUnSortedStrCollection}
\begin{verbatim}
TYPE
TUnSortedStrCollection = OBJECT (TStringCollection)
Procedure Insert (Item: Pointer); Virtual;
END;
PUnSortedStrCollection = ^TUnSortedStrCollection;
\end{verbatim}
\section{TResourceCollection}
\label{se:TResourceCollection}
\begin{verbatim}
TYPE
TResourceCollection = OBJECT (TStringCollection)
Function KeyOf (Item: Pointer): Pointer; Virtual;
Function GetItem (Var S: TStream): Pointer; Virtual;
Procedure FreeItem (Item: Pointer); Virtual;
Procedure PutItem (Var S: TStream; Item: Pointer); Virtual;
END;
PResourceCollection = ^TResourceCollection;
\end{verbatim}
\section{TResourceFile}
\label{se:TResourceFile}
\begin{verbatim}
TYPE
TResourceFile = OBJECT (TObject)
Stream : PStream; { File as a stream }
Modified: Boolean; { Modified flag }
Constructor Init (AStream: PStream);
Destructor Done; Virtual;
Function Count: Sw_Integer;
Function KeyAt (I: Sw_Integer): String;
Function Get (Key: String): PObject;
Function SwitchTo (AStream: PStream; Pack: Boolean): PStream;
Procedure Flush;
Procedure Delete (Key: String);
Procedure Put (Item: PObject; Key: String);
END;
PResourceFile = ^TResourceFile;
\end{verbatim}
\section{TStringList}
\label{se:TStringList}
\begin{verbatim}
TYPE
TStrIndexRec = Packed RECORD
Key, Count, Offset: Word;
END;
TStrIndex = Array [0..9999] Of TStrIndexRec;
PStrIndex = ^TStrIndex;
TStringList = OBJECT (TObject)
Constructor Load (Var S: TStream);
Destructor Done; Virtual;
Function Get (Key: Sw_Word): String;
END;
PStringList = ^TStringList;
\end{verbatim}
\section{TStrListMaker}
\label{se:TStrListMaker}
\begin{verbatim}
TYPE
TStrListMaker = OBJECT (TObject)
Constructor Init (AStrSize, AIndexSize: Sw_Word);
Destructor Done; Virtual;
Procedure Put (Key: Sw_Word; S: String);
Procedure Store (Var S: TStream);
END;
PStrListMaker = ^TStrListMaker;
\end{verbatim}
\begin{verbatim}
Function NewStr (Const S: String): PString;
Procedure DisposeStr (P: PString);
Procedure Abstract;
Procedure RegisterObjects;
\end{verbatim}
\begin{procedure}{RegisterType}
\Declaration
Procedure RegisterType (Var S: TStreamRec);
\end{procedure}
\begin{verbatim}
Function LongMul (X, Y: Integer): LongInt;
Function LongDiv (X: Longint; Y: Integer): Integer;
CONST
StreamError: Pointer = Nil; { Stream error ptr }
DosStreamError: Word = $0; { Dos stream error }
CONST
RCollection: TStreamRec = (
ObjType: 50;
VmtLink: Ofs(TypeOf(TCollection)^);
Load: @TCollection.Load;
Store: @TCollection.Store);
RStringCollection: TStreamRec = (
ObjType: 51;
VmtLink: Ofs(TypeOf(TStringCollection)^);
Load: @TStringCollection.Load;
Store: @TStringCollection.Store);
RStrCollection: TStreamRec = (
ObjType: 69;
VmtLink: Ofs(TypeOf(TStrCollection)^);
Load: @TStrCollection.Load;
Store: @TStrCollection.Store);
RStringList: TStreamRec = (
ObjType: 52;
VmtLink: Ofs(TypeOf(TStringList)^);
Load: @TStringList.Load;
Store: Nil);
RStrListMaker: TStreamRec = (
ObjType: 52;
VmtLink: Ofs(TypeOf(TStrListMaker)^);
Load: Nil;
Store: @TStrListMaker.Store);
\end{verbatim}