Subsections

- 1 Constants
- 2 Types
- 3 Procedures and Functions
  - 1 NewStr
  - 2 DisposeStr
  - 3 Abstract
  - 4 RegisterObjects
  - 5 RegisterType
  - 6 LongMul
  - 7 LongDiv
- 4 TRect
  - 1 TRect.Empty
  - 2 TRect.Equals
  - 3 TRect.Contains
  - 4 TRect.Copy
  - 5 TRect.Union
  - 6 TRect.Intersect
  - 7 TRect.Move
  - 8 TRect.Grow
  - 9 TRect.Assign
- 5 TObject
  - 1 TObject.Init
  - 2 TObject.Free
  - 3 TObject.Done
- 6 TStream
  - 1 TStream.Get
  - 2 TStream.StrRead
  - 3 TStream.GetPos
  - 4 TStream.GetSize
  - 5 TStream.ReadStr
  - 6 TStream.Open
  - 7 TStream.Close
  - 8 TStream.Reset
  - 9 TStream.Flush
  - 10 TStream.Truncate
  - 11 TStream.Put
  - 12 TStream.StrWrite
  - 13 TStream.WriteStr
  - 14 TStream.Seek
  - 15 TStream.Error
  - 16 TStream.Read
  - 17 TStream.Write
  - 18 TStream.CopyFrom
- 7 TDosStream
  - 1 TDosStream.Init
  - 2 TDosStream.Done
  - 3 TDosStream.Close
  - 4 TDosStream.Truncate
  - 5 TDosStream.Seek
  - 6 TDosStream.Open
  - 7 TDosStream.Read
  - 8 TDosStream.Write
- 8 TBufStream
  - 1 TBufStream.Init
  - 2 TBufStream.Done
  - 3 TBufStream.Close
  - 4 TBufStream.Flush
  - 5 TBufStream.Truncate
  - 6 TBufStream.Seek
  - 7 TBufStream.Open
  - 8 TBufStream.Read
  - 9 TBufStream.Write
- 9 TMemoryStream
  - 1 TMemoryStream.Init
  - 2 TMemoryStream.Done
  - 3 TMemoryStream.Truncate
  - 4 TMemoryStream.Read
  - 5 TMemoryStream.Write
- 10 TCollection
  - 1 TCollection.Init
  - 2 TCollection.Load
  - 3 TCollection.Done
  - 4 TCollection.At
  - 5 TCollection.IndexOf
  - 6 TCollection.GetItem
  - 7 TCollection.LastThat
  - 8 TCollection.FirstThat
  - 9 TCollection.Pack
  - 10 TCollection.FreeAll
  - 11 TCollection.DeleteAll
  - 12 TCollection.Free
  - 13 TCollection.Insert
  - 14 TCollection.Delete
  - 15 TCollection.AtFree
  - 16 TCollection.FreeItem
  - 17 TCollection.AtDelete
  - 18 TCollection.ForEach
  - 19 TCollection.SetLimit
  - 20 TCollection.Error
  - 21 TCollection.AtPut
  - 22 TCollection.AtInsert
  - 23 TCollection.Store
  - 24 TCollection.PutItem
- 11 TSortedCollection
  - 1 TSortedCollection.Init
  - 2 TSortedCollection.Load
  - 3 TSortedCollection.KeyOf
  - 4 TSortedCollection.IndexOf
  - 5 TSortedCollection.Compare
  - 6 TSortedCollection.Search
  - 7 TSortedCollection.Insert
  - 8 TSortedCollection.Store
- 12 TStringCollection
  - 1 TStringCollection.GetItem
  - 2 TStringCollection.Compare
  - 3 TStringCollection.FreeItem
  - 4 TStringCollection.PutItem
- 13 TStrCollection
  - 1 TStrCollection.GetItem
  - 2 TStrCollection.Compare
  - 3 TStrCollection.FreeItem
  - 4 TStrCollection.PutItem
- 14 TUnSortedStrCollection
  - 1 TUnSortedStrCollection.Insert
- 15 TResourceCollection
  - 1 TResourceCollection.KeyOf
  - 2 TResourceCollection.GetItem
  - 3 TResourceCollection.FreeItem
  - 4 TResourceCollection.PutItem
- 16 TResourceFile
  - 1 TResourceFile Fields
  - 2 TResourceFile.Init
  - 3 TResourceFile.Done
  - 4 TResourceFile.Count
  - 5 TResourceFile.KeyAt
  - 6 TResourceFile.Get
  - 7 TResourceFile.SwitchTo
  - 8 TResourceFile.Flush
  - 9 TResourceFile.Delete
  - 10 TResourceFile.Put
- 17 TStringList
  - 1 TStringList.Load
  - 2 TStringList.Done
  - 3 TStringList.Get
- 18 TStrListMaker
  - 1 TStrListMaker.Init
  - 2 TStrListMaker.Done
  - 3 TStrListMaker.Put
  - 4 TStrListMaker.Store

# 17 The Objects unit.

This chapter documents the objects unit. The unit was implemented by many people, and was mainly taken from the FreeVision sources. It has been ported to all supported platforms.

The methods and fields that are in a `Private` part of an object declaration have been left out of this documentation.

# 1 Constants

The following constants are error codes, returned by the various stream objects.

    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 }

These constants can be passed to constructors of file streams:

    CONST
       stCreate    = $3C00; { Create new file }
       stOpenRead  = $3D00; { Read access only }
       stOpenWrite = $3D01; { Write access only }
       stOpen      = $3D02; { Read/write access }

The following constants are error codes, returned by the collection list objects:

    CONST
       coIndexError = -1; { Index out of range }
       coOverflow   = -2; { Overflow }

Maximum data sizes (used in determining how many data can be used.

    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 }

# 2 Types

The follwing auxiliary types are defined:

    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;

The following records are used internaly for easy type conversion:

    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;

The following record is used when streaming objects:

    TYPE
       PStreamRec = ^TStreamRec;
       TStreamRec = Packed RECORD
          ObjType: Sw_Word;
          VmtLink: pointer;
          Load : Pointer;
          Store: Pointer;
          Next : PStreamRec;
       END;

The `TPoint` basic object is used in the `TRect` object (see section TRect):

    TYPE
       PPoint = ^TPoint;
       TPoint = OBJECT
          X, Y: Sw_Integer;
       END;

# 3 Procedures and Functions

##
1 NewStr

Declaration
  `Function NewStr (Const S: String): PString;`
Description
  NewStr makes a copy of the string `S` on the heap, and returns a pointer to this copy.

  The allocated memory is not based on the declared size of the string passed to `NewStr`, but is baed on the actual length of the string.

Errors
  If not enough memory is available, an 'out of memory' error will occur.
See also
  DisposeStr

Example

      Program ex40;

      { Program to demonstrate the NewStr function }

      Uses Objects;

      Var S : String;
          P : PString;

      begin
        S:='Some really cute string';
        Writeln ('Memavail : ',Memavail);
        P:=NewStr(S);
        If P^<>S then
          Writeln ('Oh-oh... Something is wrong !!');
        Writeln ('Allocated string. Memavail : ',Memavail);
        DisposeStr(P);
        Writeln ('Deallocated string. Memavail : ',Memavail);
      end.

##
2 DisposeStr

Declaration
  `Procedure DisposeStr (P: PString);`
Description
  DisposeStr removes a dynamically allocated string from the heap.
Errors
  None.
See also
  NewStr

For an example, see NewStr.

##
3 Abstract

Declaration
  `Procedure Abstract;`
Description
  When implementing abstract methods, do not declare them as `abstract`. Instead, define them simply as `virtual`. In the implementation of such abstract methods, call the `Abstract` procedure. This allows explicit control of what happens when an abstract method is called.

  The current implementation of `Abstract` terminates the program with a run-time error 211.

Errors
  None.
See also
  Most abstract types.

##
4 RegisterObjects

Declaration
  `Procedure RegisterObjects;`
Description
  RegisterObjects registers the following objects for streaming:
  1. `TCollection`, see section TCollection.
  2. `TStringCollection`, see section TStringCollection.
  3. `TStrCollection`, see section TStrCollection.
Errors
  None.
See also
  RegisterType

##
5 RegisterType

Declaration
  `Procedure RegisterType (Var S: TStreamRec);`
Description
  RegisterType registers a new type for streaming. An object cannot be streamed unless it has been registered first. The stream record `S` needs to have the following fields set:

  ObjType: Sw_Word
    This should be a unique identifier. Each possible type should have it's own identifier.
  VmtLink: pointer
    This should contain a pointer to the VMT (Virtual Method Table) of the object you try to register. You can get it with the following expression:

             VmtLink: Ofs(TypeOf(MyType)^);

  Load : Pointer
    is a pointer to a method that initializes an instance of that object, and reads the initial values from a stream. This method should accept as it's sole argument a `PStream` type variable.
  Store: Pointer
    is a pointer to a method that stores an instance of the object to a stream. This method should accept as it's sole argument a `PStream` type variable.
Errors
  In case of error (if a object with the same `ObjType`) is already registered), run-time error 212 occurs.

Example

      Unit MyObject;

      Interface

      Uses Objects;

      Type
           PMyObject = ^TMyObject;
           TMyObject = Object(TObject)
             Field : Longint;
             Constructor Init;
             Constructor Load (Var Stream : TStream);
             Destructor Done;
             Procedure Store (Var Stream : TStream);
             Function  GetField : Longint;
             Procedure SetField (Value : Longint);
             end;

      Implementation

      Constructor TMyobject.Init;

      begin
        Inherited Init;
        Field:=-1;
      end;

      Constructor TMyobject.Load (Var Stream : TStream);

      begin
        Stream.Read(Field,Sizeof(Field));
      end;

      Destructor TMyObject.Done;

      begin
      end;

      Function TMyObject.GetField : Longint;

      begin
        GetField:=Field;
      end;

      Procedure TMyObject.SetField (Value : Longint);

      begin
        Field:=Value;
      end;

      Procedure TMyObject.Store (Var Stream : TStream);

      begin
        Stream.Write(Field,SizeOf(Field));
      end;

      Const MyObjectRec : TStreamRec = (
              Objtype : 666;
              vmtlink : Ofs(TypeOf(TMyObject)^);
              Load : @TMyObject.Load;
              Store : @TMyObject.Store;
              );

      begin
        RegisterObjects;
        RegisterType (MyObjectRec);
      end.

##
6 LongMul

Declaration
  `Function LongMul (X, Y: Integer): LongInt;`
Description
  LongMul multiplies `X` with `Y`. The result is of type `Longint`. This avoids possible overflow errors you would normally get when multiplying `X` and `Y` that are too big.
Errors
  None.
See also
  LongDiv

##
7 LongDiv

Declaration
  `Function LongDiv (X: Longint; Y: Integer): Integer;`
Description
  LongDiv divides `X` by `Y`. The result is of type `Integer` instead of type `Longint`, as you would get normally.
Errors
  If Y is zero, a run-time error will be generated.
See also
  LongMul

#
4 TRect

The `TRect` object is declared as follows:

       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;

##
1 TRect.Empty

Declaration
  `Function TRect.Empty: Boolean;`
Description
  Empty returns `True` if the rectangle defined by the corner points `A`, `B` has zero or negative surface.
Errors
  None.
See also
  TRect.Equals, TRect.Contains

Example

      Program ex1;

      { Program to demonstrate TRect.Empty }

      Uses objects;

      Var ARect,BRect : TRect;
          P : TPoint;

      begin
        With ARect.A do
          begin
          X:=10;
          Y:=10;
          end;
        With ARect.B do
          begin
          X:=20;
          Y:=20;
          end;
        { Offset B by (5,5) }
        With BRect.A do
          begin
          X:=15;
          Y:=15;
          end;
        With BRect.B do
          begin
          X:=25;
          Y:=25;
          end;
        { Point }
        With P do
          begin
          X:=15;
          Y:=15;
          end;
        Writeln ('A empty : ',ARect.Empty);
        Writeln ('B empty : ',BRect.Empty);
        Writeln ('A Equals B : ',ARect.Equals(BRect));
        Writeln ('A Contains (15,15) : ',ARect.Contains(P));
      end.

##
2 TRect.Equals

Declaration
  `Function TRect.Equals (R: TRect): Boolean;`
Description
  Equals returns `True` if the rectangle has the same corner points `A,B` as the rectangle R, and `False` otherwise.
Errors
  None.
See also
  Empty, Contains

For an example, see TRect.Empty

##
3 TRect.Contains

Declaration
  `Function TRect.Contains (P: TPoint): Boolean;`
Description
  Contains returns `True` if the point `P` is contained in the rectangle (including borders), `False` otherwise.
Errors
  None.
See also
  Intersect, Equals

##
4 TRect.Copy

Declaration
  `Procedure TRect.Copy (R: TRect);`
Description
  Assigns the rectangle R to the object. After the call to `Copy`, the rectangle R has been copied to the object that invoked `Copy`.
Errors
  None.
See also
  Assign

Example

      Program ex2;

      { Program to demonstrate TRect.Copy }

      Uses objects;

      Var ARect,BRect,CRect : TRect;

      begin
        ARect.Assign(10,10,20,20);
        BRect.Assign(15,15,25,25);
        CRect.Copy(ARect);
        If ARect.Equals(CRect) Then
          Writeln ('ARect equals CRect')
        Else
          Writeln ('ARect does not equal CRect !');
      end.

##
5 TRect.Union

Declaration
  `Procedure TRect.Union (R: TRect);`
Description
  Union enlarges the current rectangle so that it becomes the union of the current rectangle with the rectangle `R`.
Errors
  None.
See also
  Intersect

Example

      Program ex3;

      { Program to demonstrate TRect.Union }

      Uses objects;

      Var ARect,BRect,CRect : TRect;

      begin
        ARect.Assign(10,10,20,20);
        BRect.Assign(15,15,25,25);
        { CRect is union of ARect and BRect }
        CRect.Assign(10,10,25,25);
        { Calculate it explicitly}
        ARect.Union(BRect);
        If ARect.Equals(CRect) Then
          Writeln ('ARect equals CRect')
        Else
          Writeln ('ARect does not equal CRect !');
      end.

##
6 TRect.Intersect

Declaration
  `Procedure TRect.Intersect (R: TRect);`
Description
  Intersect makes the intersection of the current rectangle with `R`. If the intersection is empty, then the rectangle is set to the empty rectangle at coordinate (0,0).
Errors
  None.
See also
  Union

Example

      Program ex4;

      { Program to demonstrate TRect.Intersect }

      Uses objects;

      Var ARect,BRect,CRect : TRect;

      begin
        ARect.Assign(10,10,20,20);
        BRect.Assign(15,15,25,25);
        { CRect is intersection of ARect and BRect }
        CRect.Assign(15,15,20,20);
        { Calculate it explicitly}
        ARect.Intersect(BRect);
        If ARect.Equals(CRect) Then
          Writeln ('ARect equals CRect')
        Else
          Writeln ('ARect does not equal CRect !');
        BRect.Assign(25,25,30,30);
        Arect.Intersect(BRect);
        If ARect.Empty Then
          Writeln ('ARect is empty');
      end.

##
7 TRect.Move

Declaration
  `Procedure TRect.Move (ADX, ADY: Sw_Integer);`
Description
  Move moves the current rectangle along a vector with components `(ADX,ADY)`. It adds `ADX` to the X-coordinate of both corner points, and `ADY` to both end points.
Errors
  None.
See also
  Grow

Example

      Program ex5;

      { Program to demonstrate TRect.Move }

      Uses objects;

      Var ARect,BRect : TRect;

      begin
        ARect.Assign(10,10,20,20);
        ARect.Move(5,5);
        // Brect should be where new ARect is.
        BRect.Assign(15,15,25,25);
        If ARect.Equals(BRect) Then
          Writeln ('ARect equals BRect')
        Else
          Writeln ('ARect does not equal BRect !');
      end.

##
8 TRect.Grow

Declaration
  `Procedure TRect.Grow (ADX, ADY: Sw_Integer);`
Description
  Grow expands the rectangle with an amount `ADX` in the `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 `ADY` in the `Y` direction (both on the top and the bottom side of the rectangle, adding a length 2*ADY to the height of the rectangle.

  `ADX` and `ADY` can be negative. If the resulting rectangle is empty, it is set to the empty rectangle at `(0,0)`.

Errors
  None.
See also
  Move.

Example

      program ex7;

      { Program to demonstrate the TObject.Free call }

      Uses Objects;

      Var O : PObject;

      begin
        Writeln ('Memavail : ',Memavail);
        // Allocate memory for object.
        O:=New(PObject,Init);
        Writeln ('Memavail : ',Memavail);
        // Free memory of object.
        O^.free;
        Writeln ('Memavail : ',Memavail);
      end.

##
9 TRect.Assign

Declaration
  `Procedure Trect.Assign (XA, YA, XB, YB: Sw_Integer);`
Description
  Assign sets the corner points of the rectangle to `(XA,YA)` and `(Xb,Yb)`.
Errors
  None.
See also
  Copy

For an example, see TRect.Copy.

#
5 TObject

The full declaration of the `TObject` type is:

    TYPE
       TObject = OBJECT
          CONSTRUCTOR Init;
          PROCEDURE Free;
          DESTRUCTOR Done;Virtual;
       END;
       PObject = ^TObject;

##
1 TObject.Init

Declaration
  `Constructor TObject.Init;`
Description
  Instantiates a new object of type `TObject`. It fills the instance up with Zero bytes.
Errors
  None.
See also
  Free, Done

For an example, see Free

##
2 TObject.Free

Declaration
  `Procedure TObject.Free;`
Description
  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 `self` is `nil` and whether the object is indeed allocated on the heap.
See also
  Init, Done

Example

      program ex7;

      { Program to demonstrate the TObject.Free call }

      Uses Objects;

      Var O : PObject;

      begin
        Writeln ('Memavail : ',Memavail);
        // Allocate memory for object.
        O:=New(PObject,Init);
        Writeln ('Memavail : ',Memavail);
        // Free memory of object.
        O^.free;
        Writeln ('Memavail : ',Memavail);
      end.

##
3 TObject.Done

Declaration
  `Destructor TObject.Done;Virtual;`
Description
  Done, the destructor of `TObject` does nothing. It is mainly intended to be used in the TObject.Free method.

  The destructore Done does not free the memory occupied by the object.

Errors
  None.
See also
  Free, Init

Example

      program ex8;

      { Program to demonstrate the TObject.Done call }

      Uses Objects;

      Var O : PObject;

      begin
        Writeln ('Memavail : ',Memavail);
        // Allocate memory for object.
        O:=New(PObject,Init);
        Writeln ('Memavail : ',Memavail);
        O^.Done;
        Writeln ('Memavail : ',Memavail);
      end.

#
6 TStream

The `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 `TDosStream`, `TMemoryStream`.

This is the full declaration of the `TStream` object:

    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;

##
1 TStream.Get

Declaration
  `Function TStream.Get : PObject;`
Description
  Get reads an object definition from a stream, and returns a pointer to an instance of this object.
Errors
  On error, `TStream.Status` is set, and NIL is returned.
See also
  Put

Example

      Program ex9;

      { Program to demonstrate TStream.Get and TStream.Put }

      Uses Objects,MyObject;  { Definition and registration of TMyObject}

      Var Obj : PMyObject;
          S : PStream;

      begin
        Obj:=New(PMyObject,Init);
        Obj^.SetField($1111) ;
        Writeln ('Field value : ',Obj^.GetField);
        { Since Stream is an abstract type, we instantiate a TMemoryStream }
        S:=New(PMemoryStream,Init(100,10));
        S^.Put(Obj);
        Writeln ('Disposing object');
        S^.Seek(0);
        Dispose(Obj,Done);
        Writeln ('Reading object');
        Obj:=PMyObject(S^.Get);
        Writeln ('Field Value : ',Obj^.GetField);
        Dispose(Obj,Done);
      end.

##
2 TStream.StrRead

Declaration
  `Function TStream.StrRead: PChar;`
Description
  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, `Nil` is returned.
See also
  StrWrite, ReadStr

Example

      Program ex10;

      {
      Program to demonstrate the TStream.StrRead TStream.StrWrite functions
      }

      Uses objects;

      Var P : PChar;
          S : PStream;

      begin
        P:='Constant Pchar string';
        Writeln ('Writing to stream : "',P,'"');
        S:=New(PMemoryStream,Init(100,10));
        S^.StrWrite(P);
        S^.Seek(0);
        P:=Nil;
        P:=S^.StrRead;
        DisPose (S,Done);
        Writeln ('Read from stream : "',P,'"');
        Freemem(P,Strlen(P)+1);
      end.

##
3 TStream.GetPos

Declaration
  `TSTream.GetPos : Longint; Virtual;`
Description
  If the stream's status is `stOk`, `GetPos` returns the current position in the stream. Otherwise it returns `-1`
Errors
  `-1` is returned if the status is an error condition.
See also
  Seek, GetSize

Example

      Program ex11;

      { Program to demonstrate the TStream.GetPos function }

      Uses objects;

      Var L : String;
          S : PStream;

      begin
        L:='Some kind of string';
        S:=New(PMemoryStream,Init(100,10));
        Writeln ('Stream position before write: ',S^.GetPos);
        S^.WriteStr(@L);
        Writeln ('Stream position after write : ',S^.GetPos);
        Dispose(S,Done);
      end.

##
4 TStream.GetSize

Declaration
  `Function TStream.GetSize: Longint; Virtual;`
Description
  If the stream's status is `stOk` then `GetSize` returns the size of the stream, otherwise it returns `-1`.
Errors
  `-1` is returned if the status is an error condition.
See also
  Seek, GetPos

Example

      Program ex12;

      { Program to demonstrate the TStream.GetSize function }

      Uses objects;

      Var L : String;
          S : PStream;

      begin
        L:='Some kind of string';
        S:=New(PMemoryStream,Init(100,10));
        Writeln ('Stream size before write: ',S^.GetSize);
        S^.WriteStr(@L);
        Writeln ('Stream size after write : ',S^.GetSize);
        Dispose(S,Done);
      end.

##
5 TStream.ReadStr

Declaration
  `Function TStream.ReadStr: PString;`
Description
  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), `Nil` is returned.
See also
  StrRead

Example

      Program ex13;

      {
      Program to demonstrate the TStream.ReadStr TStream.WriteStr functions
      }

      Uses objects;

      Var P : PString;
          L : String;
          S : PStream;

      begin
        L:='Constant string line';
        Writeln ('Writing to stream : "',L,'"');
        S:=New(PMemoryStream,Init(100,10));
        S^.WriteStr(@L);
        S^.Seek(0);
        P:=S^.ReadStr;
        L:=P^;
        DisposeStr(P);
        DisPose (S,Done);
        Writeln ('Read from stream : "',L,'"');
      end.

##
6 TStream.Open

Declaration
  `Procedure TStream.Open (OpenMode: Word); Virtual;`
Description
  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.
See also
  Close, Reset

For an example, see TDosStream.Open.

##
7 TStream.Close

Declaration
  `Procedure TStream.Close; Virtual;`
Description
  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.
See also
  Open, Reset

for an example, see TDosStream.Open.

##
8 TStream.Reset

Declaration
  `PROCEDURE TStream.Reset;`
Description
  Reset sets the stream's status to `0`, as well as the ErrorInfo
Errors
  None.
See also
  Open, Close

##
9 TStream.Flush

Declaration
  `Procedure TStream.Flush; Virtual;`
Description
  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.
See also
  Truncate

for an example, see TBufStream.Flush.

##
10 TStream.Truncate

Declaration
  `Procedure TStream.Truncate; Virtual;`
Description
  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.
See also
  Seek

For an example, see TDosStream.Truncate.

##
11 TStream.Put

Declaration
  `Procedure TStream.Put (P: PObject);`
Description
  Put writes the object pointed to by `P`. `P` should be non-nil. The object type must have been registered with RegisterType.

  After the object has been written, it can be read again with Get.

Errors
  No check is done whether P is `Nil` or not. Passing `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 `stPutError`.
See also
  Get

For an example, see TStream.Get;

##
12 TStream.StrWrite

Declaration
  `Procedure TStream.StrWrite (P: PChar);`
Description
  StrWrite writes the null-terminated string `P` to the stream. `P` can only be 65355 bytes long.
Errors
  None.
See also
  WriteStr, StrRead, ReadStr

For an example, see TStream.StrRead.

##
13 TStream.WriteStr

Declaration
  `Procedure TStream.WriteStr (P: PString);`
Description
  StrWrite writes the pascal string pointed to by `P` to the stream.
Errors
  None.
See also
  StrWrite, StrRead, ReadStr

For an example, see TStream.ReadStr.

##
14 TStream.Seek

Declaration
  `PROCEDURE TStream.Seek (Pos: LongInt); Virtual;`
Description
  Seek sets the position to `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 `Pos` is larger than the stream size, `Status` is set to `StSeekError`.
See also
  GetPos, GetSize

For an example, see TDosStream.Seek.

##
15 TStream.Error

Declaration
  `Procedure TStream.Error (Code, Info: Integer); Virtual;`
Description
  Error sets the stream's status to `Code` and `ErrorInfo` to `Info`. If the `StreamError` procedural variable is set, `Error` executes it, passing `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.
See also

##
16 TStream.Read

Declaration
  `Procedure TStream.Read (Var Buf; Count: Sw_Word); Virtual;`
Description
  Read is an abstract method that should be overridden by descendent objects.

  `Read` reads `Count` bytes from the stream into `Buf`. It updates the position pointer, increasing it's value with `Count`. `Buf` must be large enough to contain `Count` bytes.

Errors
  No checking is done to see if `Buf` is large enough to contain `Count` bytes.
See also
  Write, ReadStr, StrRead

Example

      program ex18;

      { Program to demonstrate the TStream.Read method }

      Uses Objects;

      Var Buf1,Buf2 : Array[1..1000] of Byte;
          I : longint;
          S : PMemorySTream;

      begin
        For I:=1 to 1000 do
          Buf1[I]:=Random(1000);
        Buf2:=Buf1;
        S:=New(PMemoryStream,Init(100,10));
        S^.Write(Buf1,SizeOf(Buf1));
        S^.Seek(0);
        For I:=1 to 1000 do
          Buf1[I]:=0;
        S^.Read(Buf1,SizeOf(Buf1));
        For I:=1 to 1000 do
          If Buf1[I]<>buf2[i] then
            Writeln ('Buffer differs at position ',I);
        Dispose(S,Done);
      end.

##
17 TStream.Write

Declaration
  `Procedure TStream.Write (Var Buf; Count: Sw_Word); Virtual;`
Description
  Write is an abstract method that should be overridden by descendent objects.

  `Write` writes `Count` bytes to the stream from `Buf`. It updates the position pointer, increasing it's value with `Count`.

Errors
  No checking is done to see if `Buf` actually contains `Count` bytes.
See also
  Read, WriteStr, StrWrite

For an example, see TStream.Read.

##
18 TStream.CopyFrom

Declaration
  `Procedure TStream.CopyFrom (Var S: TStream; Count: Longint);`
Description
  CopyFrom reads Count bytes from stream `S` and stores them in the current stream. It uses the Read method to read the data, and the Write method to write in the current stream.
Errors
  None.
See also
  Read, Write

Example

      Program ex19;

      { Program to demonstrate the TStream.CopyFrom function }

      Uses objects;

      Var P : PString;
          L : String;
          S1,S2 : PStream;

      begin
        L:='Constant string line';
        Writeln ('Writing to stream 1 : "',L,'"');
        S1:=New(PMemoryStream,Init(100,10));
        S2:=New(PMemoryStream,Init(100,10));
        S1^.WriteStr(@L);
        S1^.Seek(0);
        Writeln ('Copying contents of stream 1 to stream 2');
        S2^.Copyfrom(S1^,S1^.GetSize);
        S2^.Seek(0);
        P:=S2^.ReadStr;
        L:=P^;
        DisposeStr(P);
        Dispose (S1,Done);
        Dispose (S2,Done);
        Writeln ('Read from stream 2 : "',L,'"');
      end.

#
7 TDosStream

`TDosStream` is a stream that stores it's contents in a file. it overrides a couple of methods of `TSteam` for this.

In addition to the fields inherited from `TStream` (see section 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 `TDosStream`. All data are written directly to the file. For a stream that buffers in memory, see section TBufStream.

Here is the full declaration of the `TDosStream` object:

    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;

##
1 TDosStream.Init

Declaration
  `Constructor Init (FileName: FNameStr; Mode: Word);`
Description
  Init instantiates an instance of `TDosStream`. The name of the file that contains (or will contain) the data of the stream is given in `FileName`. The `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:
  stCreate
    Creates a new file.
  stOpenRead
    Read access only.
  stOpenWrite
    Write access only.
  stOpen
    Read and write access.
Errors
  On error, `Status` is set to `stInitError`, and `ErrorInfo` is set to the DOS error code.
See also
  Done

For an example, see TDosStream.Truncate.

##
2 TDosStream.Done

Declaration
  `Destructor TDosStream.Done; Virtual;`
Description
  Done closes the file if it was open and cleans up the instance of `TDosStream`.
Errors
  None.
See also
  Init, Close

for an example, see e.g. TDosStream.Truncate.

##
3 TDosStream.Close

Declaration
  `Pocedure TDosStream.Close; Virtual;`
Description
  Close closes the file if it was open, and sets `Handle` to -1. Contrary to Done it does not clean up the instance of `TDosStream`
Errors
  None.
See also
  TStream.Close, Init, Done

For an example, see TDosStream.Open.

##
4 TDosStream.Truncate

Declaration
  `Procedure TDosStream.Truncate; Virtual;`
Description
  If the status of the stream is `stOK`, then `Truncate` tries to truncate the stream size to the current file position.
Errors
  If an error occurs, the stream's status is set to `stError` and `ErrorInfo` is set to the OS error code.
See also
  TStream.Truncate, GetSize

Example

      Program ex16;

      { Program to demonstrate the TStream.Truncate method }

      Uses Objects;

      Var L : String;
          P : PString;
          S : PDosStream; { Only one with Truncate implemented. }

      begin
        L:='Some constant string';
        { Buffer size of 100 }
        S:=New(PDosStream,Init('test.dat',stcreate));
        Writeln ('Writing "',L,'" to stream with handle ',S^.Handle);
        S^.WriteStr(@L);
        S^.WriteStr(@L);
        { Close calls flush first }
        S^.Close;
        S^.Open (stOpen);
        Writeln ('Size of stream is : ',S^.GetSize);
        P:=S^.ReadStr;
        L:=P^;
        DisposeStr(P);
        Writeln ('Read "',L,'" from stream with handle ',S^.Handle);
        S^.Truncate;
        Writeln ('Truncated stream. Size is : ',S^.GetSize);
        S^.Close;
        Dispose (S,Done);
      end.

##
5 TDosStream.Seek

Declaration
  `Procedure TDosStream.Seek (Pos: LongInt); Virtual;`
Description
  If the stream's status is `stOK`, then `Seek` sets the file position to `Pos`. `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 `stSeekError`, and the OS error code is stored in `ErrorInfo`.
See also
  TStream.Seek, GetPos

Example

      Program ex17;

      { Program to demonstrate the TStream.Seek method }

      Uses Objects;

      Var L : String;
          Marker : Word;
          P : PString;
          S : PDosStream;

      begin
        L:='Some constant string';
        { Buffer size of 100 }
        S:=New(PDosStream,Init('test.dat',stcreate));
        Writeln ('Writing "',L,'" to stream.');
        S^.WriteStr(@L);
        Marker:=S^.GetPos;
        Writeln ('Set marker at ',Marker);
        L:='Some other constant String';
        Writeln ('Writing "',L,'" to stream.');
        S^.WriteStr(@L);
        S^.Close;
        S^.Open (stOpenRead);
        Writeln ('Size of stream is : ',S^.GetSize);
        Writeln ('Seeking to marker');
        S^.Seek(Marker);
        P:=S^.ReadStr;
        L:=P^;
        DisposeStr(P);
        Writeln ('Read "',L,'" from stream.');
        S^.Close;
        Dispose (S,Done);
      end.

##
6 TDosStream.Open

Declaration
  `Procedure TDosStream.Open (OpenMode: Word); Virtual;`
Description
  If the stream's status is `stOK`, and the stream is closed then `Open` re-opens the file stream with mode `OpenMode`. This call can be used after a Close call.
Errors
  If an error occurs when re-opening the file, then `Status` is set to `stOpenError`, and the OS error code is stored in `ErrorInfo`
See also
  TStream.Open, Close

Example

      Program ex14;

      { Program to demonstrate the TStream.Close method }

      Uses Objects;

      Var L : String;
          P : PString;
          S : PDosStream; { Only one with Close implemented. }

      begin
        L:='Some constant string';
        S:=New(PDosStream,Init('test.dat',stcreate));
        Writeln ('Writing "',L,'" to stream with handle ',S^.Handle);
        S^.WriteStr(@L);
        S^.Close;
        Writeln ('Closed stream. File handle is ',S^.Handle);
        S^.Open (stOpenRead);
        P:=S^.ReadStr;
        L:=P^;
        DisposeStr(P);
        Writeln ('Read "',L,'" from stream with handle ',S^.Handle);
        S^.Close;
        Dispose (S,Done);
      end.

##
7 TDosStream.Read

Declaration
  `Procedure TDosStream.Read (Var Buf; Count: Sw_Word); Virtual;`
Description
  If the Stream is open and the stream status is `stOK` then `Read` will read `Count` bytes from the stream and place them in `Buf`.
Errors
  In case of an error, `Status` is set to `StReadError`, and `ErrorInfo` gets the OS specific error, or 0 when an attempt was made to read beyond the end of the stream.
See also
  TStream.Read, Write

For an example, see TStream.Read.

##
8 TDosStream.Write

Declaration
  `Procedure TDosStream.Write (Var Buf; Count: Sw_Word); Virtual;`
Description
  If the Stream is open and the stream status is `stOK` then `Write` will write `Count` bytes from `Buf` and place them in the stream.
Errors
  In case of an error, `Status` is set to `StWriteError`, and `ErrorInfo` gets the OS specific error.
See also
  TStream.Write, Read

For an example, see TStream.Read.

#
8 TBufStream

`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.

    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;

##
1 TBufStream.Init

Declaration
  `Constructor Init (FileName: FNameStr; Mode,Size: Word);`
Description
  Init instantiates an instance of `TBufStream`. The name of the file that contains (or will contain) the data of the stream is given in `FileName`. The `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:
  stCreate
    Creates a new file.
  stOpenRead
    Read access only.
  stOpenWrite
    Write access only.
  stOpen
    Read and write access.
  The `Size` parameter determines the size of the buffer that will be created. It should be different from zero.
Errors
  On error, `Status` is set to `stInitError`, and `ErrorInfo` is set to the DOS error code.
See also
  TDosStream.Init, Done

For an example see TBufStream.Flush.

##
2 TBufStream.Done

Declaration
  `Destructor TBufStream.Done; Virtual;`
Description
  Done flushes and closes the file if it was open and cleans up the instance of `TBufStream`.
Errors
  None.
See also
  TDosStream.Done, Init, Close

For an example see TBufStream.Flush.

##
3 TBufStream.Close

Declaration
  `Pocedure TBufStream.Close; Virtual;`
Description
  Close flushes and closes the file if it was open, and sets `Handle` to -1. Contrary to Done it does not clean up the instance of `TBufStream`
Errors
  None.
See also
  TStream.Close, Init, Done

For an example see TBufStream.Flush.

##
4 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 Write for more info on the errors.
See also
  TStream.Close, Init, Done

Example

      Program ex15;

      { Program to demonstrate the TStream.Flush method }

      Uses Objects;

      Var L : String;
          P : PString;
          S : PBufStream; { Only one with Flush implemented. }

      begin
        L:='Some constant string';
        { Buffer size of 100 }
        S:=New(PBufStream,Init('test.dat',stcreate,100));
        Writeln ('Writing "',L,'" to stream with handle ',S^.Handle);
        S^.WriteStr(@L);
        { At this moment, there is no data on disk yet. }
        S^.Flush;
        { Now there is. }
        S^.WriteStr(@L);
        { Close calls flush first }
        S^.Close;
        Writeln ('Closed stream. File handle is ',S^.Handle);
        S^.Open (stOpenRead);
        P:=S^.ReadStr;
        L:=P^;
        DisposeStr(P);
        Writeln ('Read "',L,'" from stream with handle ',S^.Handle);
        S^.Close;
        Dispose (S,Done);
      end.

##
5 TBufStream.Truncate

Declaration
  `Procedure TBufStream.Truncate; Virtual;`
Description
  If the status of the stream is `stOK`, then `Truncate` tries to flush the buffer, and then truncates the stream size to the current file position.
Errors
  Errors can be those of Flush or TDosStream.Truncate.
See also
  TStream.Truncate, TDosStream.Truncate, GetSize

For an example, see TDosStream.Truncate.

##
6 TBufStream.Seek

Declaration
  `Procedure TBufStream.Seek (Pos: LongInt); Virtual;`
Description
  If the stream's status is `stOK`, then `Seek` sets the file position to `Pos`. `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 `stSeekError`, and the OS error code is stored in `ErrorInfo`.
See also
  TStream.Seek, GetPos

For an example, see TStream.Seek;

##
7 TBufStream.Open

Declaration
  `Procedure TBufStream.Open (OpenMode: Word); Virtual;`
Description
  If the stream's status is `stOK`, and the stream is closed then `Open` re-opens the file stream with mode `OpenMode`. This call can be used after a Close call.
Errors
  If an error occurs when re-opening the file, then `Status` is set to `stOpenError`, and the OS error code is stored in `ErrorInfo`
See also
  TStream.Open, Close

For an example, see TDosStream.Open.

##
8 TBufStream.Read

Declaration
  `Procedure TBufStream.Read (Var Buf; Count: Sw_Word); Virtual;`
Description
  If the Stream is open and the stream status is `stOK` then `Read` will read `Count` bytes from the stream and place them in `Buf`.

  `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, `Status` is set to `StReadError`, and `ErrorInfo` gets the OS specific error, or 0 when an attempt was made to read beyond the end of the stream.
See also
  TStream.Read, Write

For an example, see TStream.Read.

##
9 TBufStream.Write

Declaration
  `Procedure TBufStream.Write (Var Buf; Count: Sw_Word); Virtual;`
Description
  If the Stream is open and the stream status is `stOK` then `Write` will write `Count` bytes from `Buf` and place them in the stream.

  `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, `Status` is set to `StWriteError`, and `ErrorInfo` gets the OS specific error.
See also
  TStream.Write, Read

For an example, see TStream.Read.

#
9 TMemoryStream

The `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.

    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;

##
1 TMemoryStream.Init

Declaration
  `Constructor TMemoryStream.Init (ALimit: Longint; ABlockSize: Word);`
Description
  Init instantiates a new `TMemoryStream` object. The memorystreamobject will initially allocate at least `ALimit` bytes memory, divided into memory blocks of size `ABlockSize`. The number of blocks needed to get to `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 `stInitError`.
See also
  Done

For an example, see e.g TStream.CopyFrom.

##
2 TMemoryStream.Done

Declaration
  `Destructor TMemoryStream.Done; Virtual;`
Description
  Done releases the memory blocks used by the stream, and then cleans up the memory used by the stream object itself.
Errors
  None.
See also
  Init

For an example, see e.g TStream.CopyFrom.

##
3 TMemoryStream.Truncate

Declaration
  `Procedure TMemoryStream.Truncate; Virtual;`
Description
  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 `stError`
See also
  TStream.Truncate

Example

      Program ex20;

      { Program to demonstrate the TMemoryStream.Truncate method }

      Uses Objects;

      Var L : String;
          P : PString;
          S : PMemoryStream;
          I,InitMem : Longint;

      begin
        initMem:=Memavail;
        L:='Some constant string';
        { Buffer size of 100 }
        S:=New(PMemoryStream,Init(1000,100));
        Writeln ('Free memory : ',Memavail);
        Writeln ('Writing 100 times "',L,'" to stream.');
        For I:=1 to 100 do
          S^.WriteStr(@L);
        Writeln ('Finished. Free memory : ',Memavail);
        S^.Seek(100);
        S^.Truncate;
        Writeln ('Truncated at byte 100. Free memory : ',Memavail);
        Dispose (S,Done);
        Writeln ('Finished. Lost ',InitMem-Memavail,' Bytes.');
      end.

##
4 TMemoryStream.Read

Declaration
  `Procedure Read (Var Buf; Count: Sw_Word); Virtual;`
Description
  Read reads `Count` bytes from the stream to `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 `stReadError`.
See also
  `TStream.Read`, Write

For an example, see TStream.Read.

##
5 TMemoryStream.Write

Declaration
  `Procedure Write (Var Buf; Count: Sw_Word); Virtual;`
Description
  Write copies `Count` bytes from `Buf` to the stream. It updates the position of the stream.

  If not enough memory is available to hold the extra `Count` bytes, then the stream will try to expand, by allocating as much blocks with size `BlkSize` (as specified in the constuctor call Init) as needed.

Errors
  If the stream cannot allocate more memory, then the status is set to `stWriteError`
See also
  TStream.Write, Read

For an example, see TStream.Read.

#
10 TCollection

The `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 `TCollection` object:

    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;

##
1 TCollection.Init

Declaration
  `Constructor TCollection.Init (ALimit, ADelta: Sw_Integer);`
Description
  Init initializes a new instance of a collection. It sets the (initial) maximum number of items in the collection to `ALimit`. `ADelta` is the increase size : The number of memory places that will be allocatiod in case `ALimit` is reached, and another element is added to the collection.
Errors
  None.
See also
  Load, Done

For an example, see TCollection.ForEach.

##
2 TCollection.Load

Declaration
  `Constructor TCollection.Load (Var S: TStream);`
Description
  Load initializes a new instance of a collection. It reads from stream `S` the item count, the item limit count, and the increase size. After that, it reads the specified number of items from the stream.

Errors
  Errors returned can be those of GetItem.
See also
  Init, GetItem, Done.

Example

      Program ex22;

      { Program to demonstrate the TCollection.Load method }

      Uses Objects,MyObject; { For TMyObject definition and registration }

      Var C : PCollection;
          M : PMyObject;
          I : Longint;
          S : PMemoryStream;

      begin
        C:=New(PCollection,Init(100,10));
        For I:=1 to 100 do
          begin
          M:=New(PMyObject,Init);
          M^.SetField(100-I);
          C^.Insert(M);
          end;
        Writeln ('Inserted ',C^.Count,' objects');
        S:=New(PMemorySTream,Init(1000,10));
        C^.Store(S^);
        C^.FreeAll;
        Dispose(C,Done);
        S^.Seek(0);
        C^.Load(S^);
        Writeln ('Read ',C^.Count,' objects from stream.');
        Dispose(S,Done);
        Dispose(C,Done);
      end.

##
3 TCollection.Done

Declaration
  `Destructor TCollection.Done; Virtual;`
Description
  Done frees all objects in the collection, and then releases all memory occupied by the instance.

Errors
  None.
See also
  Init, FreeAll

For an example, see TCollection.ForEach.

##
4 TCollection.At

Declaration
  `Function TCollection.At (Index: Sw_Integer): Pointer;`
Description
  At returns the item at position `Index`.
Errors
  If `Index` is less than zero or larger than the number of items in the collection, seeplErrorTCollection.Error is called with `coIndexError` and `Index` as arguments, resulting in a run-time error.
See also
  Insert

Example

      Program ex23;

      { Program to demonstrate the TCollection.At method }

      Uses Objects,MyObject; { For TMyObject definition and registration }

      Var C : PCollection;
          M : PMyObject;
          I : Longint;

      begin
        C:=New(PCollection,Init(100,10));
        For I:=1 to 100 do
          begin
          M:=New(PMyObject,Init);
          M^.SetField(100-I);
          C^.Insert(M);
          end;
        For I:=0 to C^.Count-1 do
          begin
          M:=C^.At(I);
          Writeln ('Object ',i,' has field : ',M^.GetField);
          end;
        C^.FreeAll;
        Dispose(C,Done);
      end.

##
5 TCollection.IndexOf

Declaration
  `Function TCollection.IndexOf (Item: Pointer): Sw_Integer; Virtual;`
Description
  IndexOf returns the index of `Item` in the collection. If `Item` isn't present in the collection, -1 is returned.
Errors
See also

Program ex24;

Program to demonstrate the TCollection.IndexOf method

Uses Objects,MyObject; For TMyObject definition and registration

Var C : PCollection; M,Keep : PMyObject; I : Longint;

begin Randomize; C:=New(PCollection,Init(100,10)); Keep:=Nil; For I:=1 to 100 do begin M:=New(PMyObject,Init); M^.SetField(I-1); If Random<0.1 then Keep:=M; C^.Insert(M); end; If Keep=Nil then begin Writeln ('Please run again. No object selected'); Halt(1); end; Writeln ('Selected object has field : ',Keep^.GetField); Write ('Selected object has index : ',C^.IndexOf(Keep)); Writeln (' should match it''s field.'); C^.FreeAll; Dispose(C,Done); end.

##
6 TCollection.GetItem

Declaration
  `Function TCollection.GetItem (Var S: TStream): Pointer; Virtual;`
Description
  GetItem reads a single item off the stream `S`, and returns a pointer to this item. This method is used internally by the Load method, and should not be used directly.
Errors
  Possible errors are the ones from TStream.Get.
See also
  TStream.Get, seeplStoreTCollection.Store

##
7 TCollection.LastThat

Declaration
  `Function TCollection.LastThat (Test: Pointer): Pointer;`
Description
  This function returns the last item in the collection for which `Test` returns a non-nil result. `Test` is a function that accepts 1 argument: a pointer to an object, and that returns a pointer as a result.
Errors
  None.
See also
  FirstThat

Example

      Program ex21;

      { Program to demonstrate the TCollection.Foreach method }

      Uses Objects,MyObject; { For TMyObject definition and registration }

      Var C : PCollection;
          M : PMyObject;
          I : Longint;

      Function CheckField (Dummy: Pointer;P : PMyObject) : Longint;

      begin
        If P^.GetField<56 then
          Checkfield:=1
        else
          CheckField:=0;
      end;

      begin
        C:=New(PCollection,Init(100,10));
        For I:=1 to 100 do
          begin
          M:=New(PMyObject,Init);
          M^.SetField(I);
          C^.Insert(M);
          end;
        Writeln ('Inserted ',C^.Count,' objects');
        Writeln ('Last one for which Field<56  has index (should be 54) : ',
                  C^.IndexOf(C^.LastThat(@CheckField)));
        C^.FreeAll;
        Dispose(C,Done);
      end.

##
8 TCollection.FirstThat

Declaration
  `Function TCollection.FirstThat (Test: Pointer): Pointer;`
Description
  This function returns the first item in the collection for which `Test` returns a non-nil result. `Test` is a function that accepts 1 argument: a pointer to an object, and that returns a pointer as a result.
Errors
  None.
See also
  LastThat

Example

      Program ex21;

      { Program to demonstrate the TCollection.FirstThat method }

      Uses Objects,MyObject; { For TMyObject definition and registration }

      Var C : PCollection;
          M : PMyObject;
          I : Longint;

      Function CheckField (Dummy: Pointer;P : PMyObject) : Longint;

      begin
        If P^.GetField>56 then
          Checkfield:=1
        else
          CheckField:=0;
      end;

      begin
        C:=New(PCollection,Init(100,10));
        For I:=1 to 100 do
          begin
          M:=New(PMyObject,Init);
          M^.SetField(I);
          C^.Insert(M);
          end;
        Writeln ('Inserted ',C^.Count,' objects');
        Writeln ('first one for which Field>56  has index (should be 56) : ',
                  C^.IndexOf(C^.FirstThat(@CheckField)));
        C^.FreeAll;
        Dispose(C,Done);
      end.

##
9 TCollection.Pack

Declaration
  `Procedure TCollection.Pack;`
Description
  Pack removes all `Nil` pointers from the collection, and adjusts `Count` to reflect this change. No memory is freed as a result of this call. In order to free any memory, you can call `SetLimit` with an argument of `Count` after a call to `Pack`.
Errors
  None.
See also
  SetLimit

Example

      Program ex21;

      { Program to demonstrate the TCollection.FirstThat method }

      Uses Objects,MyObject; { For TMyObject definition and registration }

      Var C : PCollection;
          M : PMyObject;
          I : Longint;

      Function CheckField (Dummy: Pointer;P : PMyObject) : Longint;

      begin
        If P^.GetField>56 then
          Checkfield:=1
        else
          CheckField:=0;
      end;

      begin
        C:=New(PCollection,Init(100,10));
        For I:=1 to 100 do
          begin
          M:=New(PMyObject,Init);
          M^.SetField(I);
          C^.Insert(M);
          end;
        Writeln ('Inserted ',C^.Count,' objects');
        Writeln ('first one for which Field>56  has index (should be 56) : ',
                  C^.IndexOf(C^.FirstThat(@CheckField)));
        C^.FreeAll;
        Dispose(C,Done);
      end.

##
10 TCollection.FreeAll

Declaration
  `Procedure TCollection.FreeAll;`
Description
  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 `Count` to zero.
Errors
See also
  DeleteAll, FreeItem

Example

      Program ex28;

      { Program to demonstrate the TCollection.FreeAll method }

      Uses Objects,MyObject; { For TMyObject definition and registration }

      Var C : PCollection;
          M : PMyObject;
          I,InitMem : Longint;

      begin
        Randomize;
        C:=New(PCollection,Init(120,10));
        InitMem:=Memavail;
        Writeln ('Initial memory : ',InitMem);
        For I:=1 to 100 do
          begin
          M:=New(PMyObject,Init);
          M^.SetField(I-1);
          C^.Insert(M);
          end;
        Writeln ('Added 100 Items. Memory available : ',Memavail);
        Write ('Lost : ',Initmem-Memavail,' bytes.');
        Write   ('(Should be 100*',SizeOF(TMyObject));
        Writeln ('=',100*SizeOf(TMyObject),')');
        C^.FreeAll;
        Writeln ('Freed all objects. Memory available : ',Memavail);
        Writeln ('Lost : ',Initmem-Memavail,' bytes.');
        Dispose(C,Done);
      end.

##
11 TCollection.DeleteAll

Declaration
  `Procedure TCollection.DeleteAll;`
Description
  DeleteAll deletes all elements from the collection. It just sets the `Count` variable to zero. Contrary to FreeAll, `DeletAll` doesn't call the destructor of the objects.
Errors
  None.
See also
  FreeAll, Delete

Example

      Program ex29;

      {
       Program to demonstrate the TCollection.DeleteAll method
       Compare with example 28, where FreeAll is used.
      }

      Uses Objects,MyObject; { For TMyObject definition and registration }

      Var C : PCollection;
          M : PMyObject;
          I,InitMem : Longint;

      begin
        Randomize;
        C:=New(PCollection,Init(120,10));
        InitMem:=Memavail;
        Writeln ('Initial memory : ',InitMem);
        For I:=1 to 100 do
          begin
          M:=New(PMyObject,Init);
          M^.SetField(I-1);
          C^.Insert(M);
          end;
        Writeln ('Added 100 Items. Memory available : ',Memavail);
        Write ('Lost : ',Initmem-Memavail,' bytes.');
        Write   ('(Should be 100*',SizeOF(TMyObject));
        Writeln ('=',100*SizeOf(TMyObject),')');
        C^.DeleteAll;
        Writeln ('Deleted all objects. Memory available : ',Memavail);
        Writeln ('Lost : ',Initmem-Memavail,' bytes.');
        Dispose(C,Done);
      end.

##
12 TCollection.Free

Declaration
  `Procedure TCollection.Free (Item: Pointer);`
Description
  Free Deletes `Item` from the collection, and calls the destructor `Done` of the object.
Errors
  If the `Item` is not in the collection, `Error` will be called with `coIndexError`.
See also
  FreeItem,

Example

      Program ex30;

      { Program to demonstrate the TCollection.Free method }

      Uses Objects,MyObject; { For TMyObject definition and registration }

      Var C : PCollection;
          M : PMyObject;
          I,InitMem : Longint;

      begin
        Randomize;
        C:=New(PCollection,Init(120,10));
        InitMem:=Memavail;
        Writeln ('Initial memory : ',InitMem);
        For I:=1 to 100 do
          begin
          M:=New(PMyObject,Init);
          M^.SetField(I-1);
          C^.Insert(M);
          end;
        Writeln ('Added 100 Items. Memory available : ',Memavail);
        Write ('Lost : ',Initmem-Memavail,' bytes.');
        Write   ('(Should be 100*',SizeOF(TMyObject));
        Writeln ('=',100*SizeOf(TMyObject),')');
        With C^ do
          While Count>0 do Free(At(Count-1));
        Writeln ('Freed all objects. Memory available : ',Memavail);
        Writeln ('Lost : ',Initmem-Memavail,' bytes.');
        Dispose(C,Done);
      end.

##
13 TCollection.Insert

Declaration
  `Procedure TCollection.Insert (Item: Pointer); Virtual;`
Description
  Insert inserts `Item` in the collection. `TCollection` inserts this item at the end, but descendent objects may insert it at another place.
Errors
  None.
See also
  AtInsert, AtPut,

##
14 TCollection.Delete

Declaration
  `Procedure TCollection.Delete (Item: Pointer);`
Description
  Delete deletes `Item` from the collection. It doesn't call the item's destructor, though. For this the Free call is provided.
Errors
  If the `Item` is not in the collection, `Error` will be called with `coIndexError`.
See also
  AtDelete,Free

Example

      Program ex31;

      { Program to demonstrate the TCollection.Delete method }

      Uses Objects,MyObject; { For TMyObject definition and registration }

      Var C : PCollection;
          M : PMyObject;
          I,InitMem : Longint;

      begin
        Randomize;
        C:=New(PCollection,Init(120,10));
        InitMem:=Memavail;
        Writeln ('Initial memory : ',InitMem);
        For I:=1 to 100 do
          begin
          M:=New(PMyObject,Init);
          M^.SetField(I-1);
          C^.Insert(M);
          end;
        Writeln ('Added 100 Items. Memory available : ',Memavail);
        Write ('Lost : ',Initmem-Memavail,' bytes.');
        Write   ('(Should be 100*',SizeOF(TMyObject));
        Writeln ('=',100*SizeOf(TMyObject),')');
        With C^ do
          While Count>0 do Delete(At(Count-1));
        Writeln ('Freed all objects. Memory available : ',Memavail);
        Writeln ('Lost : ',Initmem-Memavail,' bytes.');
        Dispose(C,Done);
      end.

##
15 TCollection.AtFree

Declaration
  `Procedure TCollection.AtFree (Index: Sw_Integer);`
Description
  AtFree deletes the item at position `Index` in the collection, and calls the item's destructor if it is not `Nil`.
Errors
  If `Index` isn't valid then Error is called with `CoIndexError`.
See also
  Free, AtDelete

Example

      Program ex32;

      { Program to demonstrate the TCollection.AtFree method }

      Uses Objects,MyObject; { For TMyObject definition and registration }

      Var C : PCollection;
          M : PMyObject;
          I,InitMem : Longint;

      begin
        Randomize;
        C:=New(PCollection,Init(120,10));
        InitMem:=Memavail;
        Writeln ('Initial memory : ',InitMem);
        For I:=1 to 100 do
          begin
          M:=New(PMyObject,Init);
          M^.SetField(I-1);
          C^.Insert(M);
          end;
        Writeln ('Added 100 Items. Memory available : ',Memavail);
        Write ('Lost : ',Initmem-Memavail,' bytes.');
        Write   ('(Should be 100*',SizeOF(TMyObject));
        Writeln ('=',100*SizeOf(TMyObject),')');
        With C^ do
          While Count>0 do AtFree(Count-1);
        Writeln ('Freed all objects. Memory available : ',Memavail);
        Writeln ('Lost : ',Initmem-Memavail,' bytes.');
        Dispose(C,Done);
      end.

##
16 TCollection.FreeItem

Declaration
  `Procedure TCollection.FreeItem (Item: Pointer); Virtual;`
Description
  FreeItem calls the destructor of `Item` if it is not nil.

  This function is used internally by the TCollection object, and should not be called directly.

Errors
  None.
See also
  Free, seeplAtFreeTCollection.AtFree

##
17 TCollection.AtDelete

Declaration
  `Procedure TCollection.AtDelete (Index: Sw_Integer);`
Description
  AtDelete deletes the pointer at position `Index` in the collection. It doesn't call the object's destructor.
Errors
  If `Index` isn't valid then Error is called with `CoIndexError`.
See also
  Delete

Example

      Program ex33;

      { Program to demonstrate the TCollection.AtDelete method }

      Uses Objects,MyObject; { For TMyObject definition and registration }

      Var C : PCollection;
          M : PMyObject;
          I,InitMem : Longint;

      begin
        Randomize;
        C:=New(PCollection,Init(120,10));
        InitMem:=Memavail;
        Writeln ('Initial memory : ',InitMem);
        For I:=1 to 100 do
          begin
          M:=New(PMyObject,Init);
          M^.SetField(I-1);
          C^.Insert(M);
          end;
        Writeln ('Added 100 Items. Memory available : ',Memavail);
        Write ('Lost : ',Initmem-Memavail,' bytes.');
        Write   ('(Should be 100*',SizeOF(TMyObject));
        Writeln ('=',100*SizeOf(TMyObject),')');
        With C^ do
          While Count>0 do AtDelete(Count-1);
        Writeln ('Freed all objects. Memory available : ',Memavail);
        Writeln ('Lost : ',Initmem-Memavail,' bytes.');
        Dispose(C,Done);
      end.

##
18 TCollection.ForEach

Declaration
  `Procedure TCollection.ForEach (Action: Pointer);`
Description
  ForEach calls `Action` for each element in the collection, and passes the element as an argument to `Action`.

  `Action` is a procedural type variable that accepts a pointer as an argument.

Errors
  None.
See also
  FirstThat, LastThat

Example

      Program ex21;

      { Program to demonstrate the TCollection.Foreach method }

      Uses Objects,MyObject; { For TMyObject definition and registration }

      Var C : PCollection;
          M : PMyObject;
          I : Longint;

      Procedure PrintField (Dummy: Pointer;P : PMyObject);

      begin
        Writeln ('Field : ',P^.GetField);
      end;

      begin
        C:=New(PCollection,Init(100,10));
        For I:=1 to 100 do
          begin
          M:=New(PMyObject,Init);
          M^.SetField(100-I);
          C^.Insert(M);
          end;
        Writeln ('Inserted ',C^.Count,' objects');
        C^.ForEach(@PrintField);
        C^.FreeAll;
        Dispose(C,Done);
      end.

##
19 TCollection.SetLimit

Declaration
  `Procedure TCollection.SetLimit (ALimit: Sw_Integer); Virtual;`
Description
  SetLimit sets the maximum number of elements in the collection. `ALimit` must not be less than `Count`, and should not be larger than `MaxCollectionSize`
Errors
  None.
See also
  Init

For an example, see Pack.

##
20 TCollection.Error

Declaration
  `Procedure TCollection.Error (Code, Info: Integer); Virtual;`
Description
  Error is called by the various `TCollection` methods in case of an error condition. The default behaviour is to make a call to `RunError` with an error of `212-Code`.

  This method can be overridden by descendent objects to implement a different error-handling.

Errors
See also
  Abstract

##
21 TCollection.AtPut

Declaration
  `Procedure TCollection.AtPut (Index: Sw_Integer; Item: Pointer);`
Description
  AtPut sets the element at position `Index` in the collection to `Item`. Any previous value is overwritten.
Errors
  If `Index` isn't valid then Error is called with `CoIndexError`.
See also

For an example, see Pack.

##
22 TCollection.AtInsert

Declaration
  `Procedure TCollection.AtInsert (Index: Sw_Integer; Item: Pointer);`
Description
  AtInsert inserts `Item` in the collection at position `Index`, shifting all elements by one position. In case the current limit is reached, the collection will try to expand with a call to `SetLimit`
Errors
  If `Index` isn't valid then Error is called with `CoIndexError`. If the collection fails to expand, then `coOverFlow` is passd to `Error`.
See also
  Insert

Example

      Program ex34;

      { Program to demonstrate the TCollection.AtInsert method }

      Uses Objects,MyObject; { For TMyObject definition and registration }

      Var C : PCollection;
          M : PMyObject;
          I : Longint;

      Procedure PrintField (Dummy: Pointer;P : PMyObject);

      begin
        Writeln ('Field : ',P^.GetField);
      end;

      begin
        Randomize;
        C:=New(PCollection,Init(120,10));
        Writeln ('Inserting 100 records at random places.');
        For I:=1 to 100 do
          begin
          M:=New(PMyObject,Init);
          M^.SetField(I-1);
          If I=1 then
            C^.Insert(M)
          else
            With C^ do
              AtInsert(Random(Count),M);
          end;
        Writeln ('Values : ');
        C^.Foreach(@PrintField);
        Dispose(C,Done);
      end.

##
23 TCollection.Store

Declaration
  `Procedure TCollection.Store (Var S: TStream);`
Description
  Store writes the collection to the stream `S`. It does this by writeing the current `Count`, `Limit` and `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 Load.

Errors
  Errors returned are those by TStream.Put.
See also
  Load, PutItem

For an example, see seeplLoadTCollection.Load.

##
24 TCollection.PutItem

Declaration
  `Procedure TCollection.PutItem (Var S: TStream; Item: Pointer); Virtual;`
Description
  PutItem writes `Item` to stream `S`. This method is used internaly by the `TCollection` object, and should not be called directly.
Errors
  Errors are those returned by TStream.Put.
See also
  Store, GetItem.

#
11 TSortedCollection

`TSortedCollection` is an abstract class, implementing a sorted collection. You should never use an instance of `TSortedCollection` directly, instead you should declare a descendent type, and override the Compare method.

Because the collection is ordered, `TSortedCollection` overrides some `TCollection` methods, to provide faster routines for lookup.

The Compare method decides how elements in the collection should be ordered. Since `TCollection` has no way of knowing how to order pointers, you must override the compare method.

Additionally, `TCollection` provides a means to filter out duplicates. if you set `Duplicates` to `False` (the default) then duplicates will not be allowed.

Here is the complete declaration of `TSortedCollection`

    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;

In the subsequent examples, the following descendent of `TSortedCollection` is used:

Example

      Unit MySortC;

      Interface

      Uses Objects;

      Type
        PMySortedCollection = ^TMySortedCollection;
        TMySortedCollection = Object(TSortedCollection)
             Function Compare (Key1,Key2 : Pointer): Sw_integer; virtual;
             end;

      Implementation

      Uses MyObject;

      Function TMySortedCollection.Compare (Key1,Key2 : Pointer) :sw_integer;

      begin
        Compare:=PMyobject(Key1)^.GetField - PMyObject(Key2)^.GetField;
      end;

      end.

##
1 TSortedCollection.Init

Declaration
  `Constructor TSortedCollection.Init (ALimit, ADelta: Sw_Integer);`
Description
  Init calls the inherited constuctor (see TCollection.Init) and sets the `Duplicates` flag to false.

  You should not call this method directly, since `TSortedCollection` is a abstract class. Instead, the descendent classes should call it via the `inherited` keyword.

Errors
  None.
See also
  Load, Done

For an example, see

##
2 TSortedCollection.Load

Declaration
  `Constructor Load (Var S: TStream);`
Description
  Load calls the inherited constuctor (see TCollection.Load) and reads the `Duplicates` flag from the stream..

  You should not call this method directly, since `TSortedCollection` is a abstract class. Instead, the descendent classes should call it via the `inherited` keyword.

Errors
  None.
See also
  Init, Done

For an example, see TCollection.Load.

##
3 TSortedCollection.KeyOf

Declaration
  `Function TSortedCollection.KeyOf (Item: Pointer): Pointer; Virtual;`
Description
  KeyOf returns the key associated with `Item`. `TSortedCollection` returns the item itself as the key, descendent objects can override this method to calculate a (unique) key based on the item passed (such as hash values).

  `Keys` are used to sort the objects, they are used to search and sort the items in the collection. If descendent types override this method then it allows possibly for faster search/sort methods based on keys rather than on the objects themselves.

Errors
  None.
See also
  IndexOf, Compare.

##
4 TSortedCollection.IndexOf

Declaration
  `Function TSortedCollection.IndexOf (Item: Pointer): Sw_Integer; Virtual;`
Description
  IndexOf returns the index of `Item` in the collection. It searches for the object based on it's key. If duplicates are allowed, then it returns the index of last object that matches `Item`.

  In case `Item` is not found in the collection, -1 is returned.

Errors
  None.
See also
  Search, Compare.

For an example, see TCollection.IndexOf

##
5 TSortedCollection.Compare

Declaration
  `Function TSortedCollection.Compare (Key1, Key2: Pointer): Sw_Integer; Virtual;`
Description
  Compare is an abstract method that should be overridden by descendent objects in order to compare two items in the collection. This method is used in the Search method and in the Insert method to determine the ordering of the objects.

  The function should compare the two keys of items and return the following function results:

  Result < 0
    If `Key1` is logically before `Key2` (`Key1<Key2`)
  Result = 0
    If `Key1` and `Key2` are equal. (`Key1=Key2`)
  Result > 0
    If `Key1` is logically after `Key2` (`Key1>Key2`)
Errors
  An 'abstract run-time error' will be generated if you call `TSortedCollection.Compare` directly.
See also
  IndexOf, Search

Example

      Unit MySortC;

      Interface

      Uses Objects;

      Type
        PMySortedCollection = ^TMySortedCollection;
        TMySortedCollection = Object(TSortedCollection)
             Function Compare (Key1,Key2 : Pointer): Sw_integer; virtual;
             end;

      Implementation

      Uses MyObject;

      Function TMySortedCollection.Compare (Key1,Key2 : Pointer) :sw_integer;

      begin
        Compare:=PMyobject(Key1)^.GetField - PMyObject(Key2)^.GetField;
      end;

      end.

##
6 TSortedCollection.Search

Declaration
  `Function TSortedCollection.Search (Key: Pointer; Var Index: Sw_Integer): Boolean;Virtual;`
Description
  Search looks for the item with key `Key` and returns the position of the item (if present) in the collection in `Index`.

  Instead of a linear search as `TCollection` does, `TSortedCollection` uses a binary search based on the keys of the objects. It uses the Compare function to implement this search.

  If the item is found, `Search` returns `True`, otherwise `False` is returned.

Errors
  None.
See also
  IndexOf.

Example

      Program ex36;

      { Program to demonstrate the TSortedCollection.Insert method }

      Uses Objects,MyObject,MySortC;
       { For TMyObject,TMySortedCollection definition and registration }

      Var C : PSortedCollection;
          M : PMyObject;
          I : Longint;

      Procedure PrintField (Dummy: Pointer;P : PMyObject);

      begin
        Writeln ('Field : ',P^.GetField);
      end;

      begin
        Randomize;
        C:=New(PMySortedCollection,Init(120,10));
        C^.Duplicates:=True;
        Writeln ('Inserting 100 records at random places.');
        For I:=1 to 100 do
          begin
          M:=New(PMyObject,Init);
          M^.SetField(Random(100));
          C^.Insert(M)
          end;
        M:=New(PMyObject,Init);
        Repeat;
          Write ('Value to search for (-1 stops) :');
          read (I);
          If I<>-1 then
            begin
            M^.SetField(i);
            If Not C^.Search (M,I) then
              Writeln ('No such value found')
            else
              begin
              Write ('Value ',PMyObject(C^.At(I))^.GetField);
              Writeln (' present at position ',I);
              end;
            end;
        Until I=-1;
        Dispose(M,Done);
        Dispose(C,Done);
      end.

##
7 TSortedCollection.Insert

Declaration
  `Procedure TSortedCollection.Insert (Item: Pointer); Virtual;`
Description
  Insert inserts an item in the collection at the correct position, such that the collection is ordered at all times. You should never use Atinsert, since then the collection ordering is not guaranteed.

  If `Item` is already present in the collection, and `Duplicates` is `False`, the item will not be inserted.

Errors
  None.
See also
  AtInsert

Example

      Program ex35;

      { Program to demonstrate the TSortedCollection.Insert method }

      Uses Objects,MyObject,MySortC;
       { For TMyObject,TMySortedCollection definition and registration }

      Var C : PSortedCollection;
          M : PMyObject;
          I : Longint;

      Procedure PrintField (Dummy: Pointer;P : PMyObject);

      begin
        Writeln ('Field : ',P^.GetField);
      end;

      begin
        Randomize;
        C:=New(PMySortedCollection,Init(120,10));
        Writeln ('Inserting 100 records at random places.');
        For I:=1 to 100 do
          begin
          M:=New(PMyObject,Init);
          M^.SetField(Random(100));
          C^.Insert(M)
          end;
        Writeln ('Values : ');
        C^.Foreach(@PrintField);
        Dispose(C,Done);
      end.

##
8 TSortedCollection.Store

Declaration
  `Procedure TSortedCollection.Store (Var S: TStream);`
Description
  Store writes the collection to the stream `S`. It does this by calling the inherited TCollection.Store, and then writing the `Duplicates` flag to the stream.

  After a `Store`, the collection can be loaded from the stream with the constructor Load

Errors
  Errors can be those of TStream.Put.
See also
  Load

For an example, see TCollection.Load.

#
12 TStringCollection

The `TStringCollection` object manages a sorted collection of pascal strings. To this end, it overrides the Compare method of `TSortedCollection`, and it introduces methods to read/write strings from a stream.

Here is the full declaration of the `TStringCollection` object:

    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;

##
1 TStringCollection.GetItem

Declaration
  `Function TStringCollection.GetItem (Var S: TStream): Pointer; Virtual;`
Description
  GetItem reads a string from the stream `S` and returns a pointer to it. It doesn't insert the string in the collection.

  This method is primarily introduced to be able to load and store the collection from and to a stream.

Errors
  The errors returned are those of TStream.ReadStr.
See also
  PutItem

##
2 TStringCollection.Compare

Declaration
  `Function TStringCollection.Compare (Key1, Key2: Pointer): Sw_Integer; Virtual;`
Description
  TStringCollection overrides the `Compare` function so it compares the two keys as if they were pointers to strings. The compare is done case sensitive. It returns the following results:
  -1
    if the first string is alphabetically earlier than the second string.
  0
    if the two strings are equal.
  1
    if the first string is alphabetically later than the second string.
Errors
  None.
See also
  TSortedCollection.Compare

Example

      Program ex37;

      { Program to demonstrate the TStringCollection.Compare method }

      Uses Objects;

      Var C : PStringCollection;
          S : String;
          I : longint;

      begin
        Randomize;
        C:=New(PStringCollection,Init(120,10));
        C^.Duplicates:=True; { Duplicates allowed }
        Writeln ('Inserting 100 records at random places.');
        For I:=1 to 100 do
          begin
          Str(Random(100),S);
          S:='String with value '+S;
          C^.Insert(NewStr(S));
          end;
        For I:=0 to 98 do
          With C^ do
          If Compare (At(i),At(I+1))=0 then
            Writeln ('Duplicate string found at position ',i);
        Dispose(C,Done);
      end.

##
3 TStringCollection.FreeItem

Declaration
  `Procedure TStringCollection.FreeItem (Item: Pointer); Virtual;`
Description
  TStringCollection overrides `FreeItem` so that the string pointed to by `Item` is disposed from memory.
Errors
  None.
See also
  TCollection.FreeItem

##
4 TStringCollection.PutItem

Declaration
  `Procedure TStringCollection.PutItem (Var S: TStream; Item: Pointer); Virtual;`
Description
  PutItem writes the string pointed to by `Item` to the stream `S`.

  This method is primarily used in the `Load` and `Store` methods, and should not be used directly.

Errors
  Errors are those of TStream.WriteStr.
See also
  GetItem

#
13 TStrCollection

The `TStrCollection` object manages a sorted collection of null-terminated strings (pchar strings). To this end, it overrides the Compare method of `TSortedCollection`, and it introduces methods to read/write strings from a stream.

Here is the full declaration of the `TStrCollection` object:

    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;

##
1 TStrCollection.GetItem

Declaration
  `Function TStrCollection.GetItem (Var S: TStream): Pointer; Virtual;`
Description
  GetItem reads a null-terminated string from the stream `S` and returns a pointer to it. It doesn't insert the string in the collection.

  This method is primarily introduced to be able to load and store the collection from and to a stream.

Errors
  The errors returned are those of TStream.StrRead.
See also
  PutItem

##
2 TStrCollection.Compare

Declaration
  `Function TStrCollection.Compare (Key1, Key2: Pointer): Sw_Integer; Virtual;`
Description
  TStrCollection overrides the `Compare` function so it compares the two keys as if they were pointers to strings. The compare is done case sensitive. It returns
  -1
    if the first string is alphabetically earlier than the second string.
  0
    if the two strings are equal.
  1
    if the first string is alphabetically later than the second string.
Errors
  None.
See also
  TSortedCollection.Compare

Example

      Program ex38;

      { Program to demonstrate the TStrCollection.Compare method }

      Uses Objects,Strings;

      Var C : PStrCollection;
          S : String;
          I : longint;
          P : Pchar;

      begin
        Randomize;
        C:=New(PStrCollection,Init(120,10));
        C^.Duplicates:=True; { Duplicates allowed }
        Writeln ('Inserting 100 records at random places.');
        For I:=1 to 100 do
          begin
          Str(Random(100),S);
          S:='String with value '+S;
          P:=StrAlloc(Length(S)+1);
          C^.Insert(StrPCopy(P,S));
          end;
        For I:=0 to 98 do
          With C^ do
            If Compare (At(I),At(I+1))=0 then
              Writeln ('Duplicate string found at position ',I);
        Dispose(C,Done);
      end.

##
3 TStrCollection.FreeItem

Declaration
  `Procedure TStrCollection.FreeItem (Item: Pointer); Virtual;`
Description
  TStrCollection overrides `FreeItem` so that the string pointed to by `Item` is disposed from memory.
Errors
  None.
See also
  TCollection.FreeItem

##
4 TStrCollection.PutItem

Declaration
  `Procedure TStrCollection.PutItem (Var S: TStream; Item: Pointer); Virtual;`
Description
  PutItem writes the string pointed to by `Item` to the stream `S`.

  This method is primarily used in the `Load` and `Store` methods, and should not be used directly.

Errors
  Errors are those of TStream.StrWrite.
See also
  GetItem

#
14 TUnSortedStrCollection

The `TUnSortedStrCollection` object manages an unsorted list of objects. To this end, it overrides the TSortedCollection.Insert method to add strings at the end of the collection, rather than in the alphabetically correct position.

Take care, the Search and IndexOf methods will not work on an unsorted string collection.

Here is the full declaration of the TUnsortedStrCollection object:

    TYPE
       TUnSortedStrCollection = OBJECT (TStringCollection)
          Procedure Insert (Item: Pointer); Virtual;
       END;
       PUnSortedStrCollection = ^TUnSortedStrCollection;

##
1 TUnSortedStrCollection.Insert

Declaration
  `Procedure TUnSortedStrCollection.Insert (Item: Pointer); Virtual;`
Description
  Insert inserts a string at the end of the collection, instead of on it's alphabetical place, resulting in an unsorted collection of strings.
Errors
See also

Example

      Program ex39;

      { Program to demonstrate the TUnsortedStrCollection.Insert method }

      Uses Objects,Strings;

      Var C : PUnsortedStrCollection;
          S : String;
          I : longint;
          P : Pchar;

      begin
        Randomize;
        C:=New(PUnsortedStrCollection,Init(120,10));
        Writeln ('Inserting 100 records at random places.');
        For I:=1 to 100 do
          begin
          Str(Random(100),S);
          S:='String with value '+S;
          P:=StrAlloc(Length(S)+1);
          C^.Insert(StrPCopy(P,S));
          end;
        For I:=0 to 99 do
          Writeln (I:2,': ',PChar(C^.At(i)));
        Dispose(C,Done);
      end.

#
15 TResourceCollection

A `TResourceCollection` manages a collection of resource names. It stores the position and the size of a resource, as well as the name of the resource. It stores these items in records that look like this:

    TYPE
       TResourceItem = packed RECORD
          Posn: LongInt;
          Size: LongInt;
          Key : String;
       End;
       PResourceItem = ^TResourceItem;

It overrides some methods of `TStringCollection` in order to accomplish this.

Remark that the `TResourceCollection` manages the names of the resources and their assiciated positions and sizes, it doesn't manage the resources themselves.

Here is the full declaration of the `TResourceCollection` object:

    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;

##
1 TResourceCollection.KeyOf

Declaration
  `Function TResourceCollection.KeyOf (Item: Pointer): Pointer; Virtual;`
Description
  KeyOf returns the key of an item in the collection. For resources, the key is a pointer to the string with the resource name.
Errors
  None.
See also
  TStringCollection.Compare

##
2 TResourceCollection.GetItem

Declaration
  `Function TResourceCollection.GetItem (Var S: TStream): Pointer; Virtual;`
Description
  GetItem reads a resource item from the stream `S`. It reads the position, size and name from the stream, in that order. It DOES NOT read the resource itself from the stream.

  The resulting item is not inserted in the collection. This call is manly for internal use by the TCollection.Load method.

Errors
  Errors returned are those by TStream.Read
See also
  TCollection.Load, TStream.Read

##
3 TResourceCollection.FreeItem

Declaration
  `Procedure TResourceCollection.FreeItem (Item: Pointer); Virtual;`
Description
  FreeItem releases the memory occupied by `Item`. It de-allocates the name, and then the resourceitem record.

  It does NOT remove the item from the collection.

Errors
  None.
See also
  TCollection.FreeItem

##
4 TResourceCollection.PutItem

Declaration
  `Procedure TResourceCollection.PutItem (Var S: TStream; Item: Pointer); Virtual;`
Description
  PutItem writes `Item` to the stream `S`. It does this by writing the position and size and name of the resource item to the stream.

  This method is used primarily by the Store method.

Errors
  Errors returned are those by TStream.Write.
See also
  Store

#
16 TResourceFile

    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;

## 1 TResourceFile Fields

`TResourceFile` has the following fields:

Stream
  contains the (file) stream that has the executable image and the resources. It can be initialized by the Init constructor call.
Modified
  is set to `True` if one of the resources has been changed. It is set by the SwitchTo, Delete and Put methods. Calling Flush will clear the `Modified` flag.

##
2 TResourceFile.Init

Declaration
  `Constructor TResourceFile.Init (AStream: PStream);`
Description
  Init instantiates a new instance of a `TResourceFile` object. If `AStream` is not nil then it is considered as a stream describing an executable image on disk.

  `Init` will try to position the stream on the start of the resources section, and read all resources from the stream.

Errors
  None.
See also
  Done

##
3 TResourceFile.Done

Declaration
  `Destructor TResourceFile.Done; Virtual;`
Description
  Done cleans up the instance of the `TResourceFile` Object. If `Stream` was specified at initialization, then `Stream` is disposed of too.
Errors
  None.
See also
  Init

##
4 TResourceFile.Count

Declaration
  `Function TResourceFile.Count: Sw_Integer;`
Description
  Count returns the number of resources. If no resources were read, zero is returned.
Errors
  None.
See also
  Init

##
5 TResourceFile.KeyAt

Declaration
  `Function TResourceFile.KeyAt (I: Sw_Integer): String;`
Description
  KeyAt returns the key (the name) of the `I`-th resource.
Errors
  In case `I` is invalid, `TCollection.Error` will be executed.
See also
  Get

##
6 TResourceFile.Get

Declaration
  `Function TResourceFile.Get (Key: String): PObject;`
Description
  Get returns a pointer to a instance of a resource identified by `Key`. If `Key` cannot be found in the list of resources, then `Nil` is returned.
Errors
  Errors returned may be those by `TStream.Get`
See also

##
7 TResourceFile.SwitchTo

Declaration
  `Function TResourceFile.SwitchTo (AStream: PStream; Pack: Boolean): PStream;`
Description
  SwitchTo switches to a new stream to hold the resources in. `AStream` will be the new stream after the call to `SwitchTo`.

  If `Pack` is true, then all the known resources will be copied from the current stream to the new stream (`AStream`). If `Pack` is `False`, then only the current resource is copied.

  The return value is the value of the original stream: `Stream`.

  The `Modified` flag is set as a consequence of this call.

Errors
  Errors returned can be those of TStream.Read and TStream.Write.
See also
  Flush

##
8 TResourceFile.Flush

Declaration
  `Procedure TResourceFile.Flush;`
Description
  If the `Modified` flag is set to `True`, then `Flush` writes the resources to the stream `Stream`. It sets the `Modified` flag to true after that.
Errors
  Errors can be those by TStream.Seek and TStream.Write.
See also
  SwitchTo

##
9 TResourceFile.Delete

Declaration
  `Procedure TResourceFile.Delete (Key: String);`
Description
  Delete deletes the resource identified by `Key` from the collection. It sets the `Modified` flag to true.
Errors
  None.
See also
  Flush

##
10 TResourceFile.Put

Declaration
  `Procedure TResourceFile.Put (Item: PObject; Key: String);`
Description
  Put sets the resource identified by `Key` to `Item`. If no such resource exists, a new one is created. The item is written to the stream.
Errors
  Errors returned may be those by TStream.Put and `TStream.Seek`
See also
  Get

#
17 TStringList

A `TStringList` object can be used to read a collection of strings stored in a stream. If you register this object with the RegisterType function, you cannot register the `TStrListMaker` object.

This is the public declaration of the `TStringList` object:

    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;

##
1 TStringList.Load

Declaration
  `Constructor TstringList.Load (Var S: TStream);`
Description
  The `Load` constructor reads the `TStringList` object from the stream `S`. It also reads the descriptions of the strings from the stream. The string descriptions are stored as an array of `TstrIndexrec` records, where each record describes a string on the stream. These records are kept in memory.
Errors
  If an error occurs, a stream error is triggered.
See also
  Done

##
2 TStringList.Done

Declaration
  `Destructor TstringList.Done; Virtual;`
Description
  The `Done` destructor frees the memory occupied by the string descriptions, and destroys the object.
Errors
  None.
See also
  Load, TObject.Done

##
3 TStringList.Get

Declaration
  `Function TStringList.Get (Key: Sw_Word): String;`
Description
  Get reads the string with key `Key` from the list of strings on the stream, and returns this string. If there is no string with such a key, an empty string is returned.
Errors
  If no string with key `Key` is found, an empty string is returned. A stream error may result if the stream doesn't contain the needed strings.
See also
  TStrListMaker.Put

#
18 TStrListMaker

The `TStrListMaker` object can be used to generate a stream with strings, which can be read with the `TStringList` object. If you register this object with the RegisterType function, you cannot register the `TStringList` object.

This is the public declaration of the `TStrListMaker` object:

    TYPE
       TStrListMaker = OBJECT (TObject)
          Constructor Init (AStrSize, AIndexSize: Sw_Word);
          Destructor Done; Virtual;
          Procedure Put (Key: SwWord; S: String);
          Procedure Store (Var S: TStream);
       END;
       PStrListMaker = ^TStrListMaker;

##
1 TStrListMaker.Init

Declaration
  `Constructor TStrListMaker.Init (AStrSize, AIndexSize: SwWord);`
Description
  The `Init` constructor creates a new instance of the `TstrListMaker` object. It allocates `AStrSize` bytes on the heap to hold all the strings you wish to store. It also allocates enough room for `AIndexSize` key description entries (of the type `TStrIndexrec`).

  `AStrSize` must be large enough to contain all the strings you wish to store. If not enough memory is allocated, other memory will be overwritten. The same is true for `AIndexSize` : maximally `AIndexSize` strings can be written to the stream.

Errors
  None.
See also
  TObject.Init, Done

##
2 TStrListMaker.Done

Declaration
  `Destructor TStrListMaker.Done; Virtual;`
Description
  The `Done` destructor de-allocates the memory for the index description records and the string data, and then destroys the object.
Errors
  None.
See also
  TObject.Done, Init

##
3 TStrListMaker.Put

Declaration
  `Procedure TStrListMaker.Put (Key: Sw_Word; S: String);`
Description
  Put adds they string `S` with key `Key` to the collection of strings. This action doesn't write the string to a stream. To write the strings to the stream, see the Store method.
Errors
  None.
See also
  Store.

##
4 TStrListMaker.Store

Declaration
  `Procedure TStrListMaker.Store (Var S: TStream);`
Description
  Store writes the collection of strings to the stream `S`. The collection can then be read with the `TStringList` object.
Errors
  A stream error may occur when writing the strings to the stream.
See also
  TStringList.Load, Put.