% % $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 chapte documents te \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 \seef{TRect.Empty}, \seef{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 \seep{TRect.Intersect}, \seef{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 \seep{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 \seep{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 \var{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 \seep{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. X and Y can be negative. If the resulting rectangle is empty, it is set to the empty rectangle at \var{(0,0)}. \Errors None. \SeeAlso \seep{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. \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 \seep{TObject.Free}, \seep{TObject.Done} \end{procedure} For an example, see \seep{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 \seep{TObject.Init}, \seep{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 \seep{TObject.Free}, \seep{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 descendant types. Programs should not instantiate objects of type TStream directly, but instead instantiate a descendant type. 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} \section{TDosStream} \label{se:TDosStream} \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} \section{TBufStream} \label{se:TBufStream} \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} \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; PROCEDURE RegisterType (Var S: TStreamRec); 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}