% % $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} \section{se:TMemoryStream} \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; PRIVATE FUNCTION ChangeListSize (ALimit: Sw_Word): Boolean; END; PMemoryStream = ^TMemoryStream; \end{verbatim} \section{TCollection} \label{se:TCollection} \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} \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}