home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 8 / CDASC08.ISO / NEWS / 552 / GSOB_OBJ.PAS < prev    next >
Pascal/Delphi Source File  |  1993-10-07  |  11KB  |  446 lines

  1. unit GSOB_OBJ;
  2. {-----------------------------------------------------------------------------
  3.                             Collection Handler
  4.  
  5.        GSOB_Obj Copyright (c)  Richard F. Griffin
  6.  
  7.        10 August 1992
  8.  
  9.        102 Molded Stone Pl
  10.        Warner Robins, GA  31088
  11.  
  12.        -------------------------------------------------------------
  13.        This unit handles the objects for collections.  This is an
  14.        abbreviated version of the BorLand TP6 Objects unit.  It is
  15.        intended as a substitute for use in TP5.5.
  16.  
  17.        Changes:
  18.  
  19. ------------------------------------------------------------------------------}
  20.  
  21. interface
  22.  
  23. {$IFDEF WINDOWS}
  24.    Uses Objects;
  25. {$ELSE}
  26. const
  27.  
  28.    MaxCollectionSize = 65520 div SizeOf(Pointer);
  29.  
  30.    coAbstrError = 211;            { Call to Abstract Method }
  31.    coIndexError = 213;            { Index out of range }
  32.    coOverflow   = 214;            { Overflow }
  33.  
  34.  
  35. type
  36.  
  37.    PObject = ^TObject;
  38.    TObject = object
  39.       constructor Init;
  40.       procedure   Error(Code, Info: Integer); virtual;
  41.       procedure   Free;
  42.       destructor  Done; virtual;
  43.    end;
  44.  
  45.    PString = ^String;
  46.  
  47.    PByteArray = ^TByteArray;
  48.    TByteArray = array [0..32767] of byte;
  49.  
  50.    PColPntrs = ^TColPntrs;
  51.    TColPntrs = array[0..MaxCollectionSize - 1] of Pointer;
  52.  
  53.  
  54.    PCollection = ^TCollection;
  55.    TCollection = object(TObject)
  56.       Items       : PColPntrs;
  57.       Count       : Integer;
  58.       Limit       : Integer;
  59.       Delta       : Integer;
  60.       constructor Init(ALimit, ADelta: Integer);
  61.       destructor  Done; virtual;
  62.       function    At(Index: Integer): Pointer;
  63.       procedure   AtDelete(Index: Integer);
  64.       procedure   AtInsert(Index: Integer; Item: Pointer);
  65.       procedure   AtPut(Index: Integer; Item: Pointer);
  66.       procedure   Delete(Item: Pointer);
  67.       procedure   DeleteAll;
  68.       procedure   Free(Item: Pointer);
  69.       procedure   FreeAll;
  70.       procedure   FreeItem(Item: Pointer); virtual;
  71.       function    IndexOf(Item: Pointer): Integer; virtual;
  72.       procedure   Insert(Item: Pointer); virtual;
  73.       procedure   SetLimit(ALimit: Integer); virtual;
  74.    end;
  75.  
  76.    PSortedCollection = ^TSortedCollection;
  77.    TSortedCollection = object(TCollection)
  78.       Duplicates  : Boolean;
  79.       constructor Init(ALimit, ADelta: Integer);
  80.       function    Compare(Key1, Key2: Pointer): Integer; virtual;
  81.       function    IndexOf(Item: Pointer): Integer; virtual;
  82.       procedure   Insert(Item: Pointer); virtual;
  83.       function    KeyOf(Item: Pointer): Pointer; virtual;
  84.       function    Search(Key: Pointer; var Index: Integer): Boolean; virtual;
  85.    end;
  86.  
  87.    PStringCollection = ^TStringCollection;
  88.    TStringCollection = object(TSortedCollection)
  89.       function    Compare(Key1, Key2: Pointer): Integer; virtual;
  90.       procedure   FreeItem(Item: Pointer); virtual;
  91.    end;
  92.  
  93.  
  94. procedure DisposeStr(p: PString);
  95. function  NewStr(s: string): PString;
  96.  
  97.  
  98. {$ENDIF}
  99.  
  100. type
  101.    GSP_LineBuf = ^GSR_LineBuf;
  102.    GSR_LineBuf = record
  103.       LineRetn :  byte;
  104.       LineText :  string;
  105.    end;
  106.  
  107.    GSP_LineCollection = ^GSO_LineCollection;
  108.    GSO_LineCollection = object(TCollection)
  109.       function   ByteCount : longint; virtual;
  110.       procedure  FreeItem(Item : pointer); virtual;
  111.       procedure  InsertItem(rtn : byte; var st : string); virtual;
  112.       procedure  InsertItemAt(rtn : byte;var st : string;i : integer); virtual;
  113.    end;
  114.  
  115.  
  116. implementation
  117.  
  118. {$IFNDEF WINDOWS}
  119. {------------------------------------------------------------------------------
  120.                              Global Procedures/Functions
  121. ------------------------------------------------------------------------------}
  122.  
  123. procedure Abstract;
  124. begin
  125.   RunError(coAbstrError);
  126. end;
  127.  
  128. procedure DisposeStr(p: PString);
  129. begin
  130.   if P <> nil then FreeMem(p, Length(p^) + 1);
  131. end;
  132.  
  133. function NewStr(S: String): PString;
  134. var
  135.   p: PString;
  136. begin
  137.   if s = '' then p := nil else
  138.   begin
  139.     GetMem(p, Length(s) + 1);
  140.     p^ := s;
  141.   end;
  142.   NewStr := p;
  143. end;
  144.  
  145. {------------------------------------------------------------------------------
  146.                                   TObject
  147. ------------------------------------------------------------------------------}
  148.  
  149. constructor TObject.Init;
  150. begin
  151. end;
  152.  
  153. Procedure TObject.Error(Code, Info : integer);
  154. begin
  155.    RunError(Code);
  156. end;
  157.  
  158. procedure TObject.Free;
  159. begin
  160.    Dispose(PObject(@Self), Done);
  161. end;
  162.  
  163. destructor TObject.Done;
  164. begin
  165. end;
  166.  
  167.  
  168. {------------------------------------------------------------------------------
  169.                                   TCollection
  170. ------------------------------------------------------------------------------}
  171.  
  172. constructor TCollection.Init(ALimit, ADelta: Integer);
  173. begin
  174.    TObject.Init;
  175.    Items := nil;
  176.    Count := 0;
  177.    Limit := 0;
  178.    Delta := ADelta;
  179.    SetLimit(ALimit);
  180. end;
  181.  
  182. destructor TCollection.Done;
  183. begin
  184.    FreeAll;
  185.    SetLimit(0);
  186. end;
  187.  
  188. function TCollection.At(Index: Integer): Pointer;
  189. begin
  190.    if (Index < 0) or (Index >= Count) then
  191.    begin
  192.       Error(coIndexError,0);
  193.       At := nil;
  194.    end
  195.       else At := Items^[Index];
  196. end;
  197.  
  198. procedure TCollection.AtDelete(Index: Integer);
  199. begin
  200.    if (Index >= 0) and (Index < Count) then
  201.    begin
  202.       if Index < Count-1 then
  203.          move(Items^[Index+1],Items^[Index],((Count-1)-Index)*4);
  204.       dec(Count);
  205.    end
  206.    else Error(coIndexError,0);
  207. end;
  208.  
  209. procedure TCollection.AtInsert(Index: Integer; Item: Pointer);
  210. begin
  211.    if (Index >= 0) and (Index <= Count) then
  212.    begin
  213.       if Count = Limit then SetLimit(Limit+Delta);
  214.       if Index <> Count then
  215.          move(Items^[Index],Items^[Index+1],(Count-Index)*4);
  216.       Items^[Index] := Item;
  217.       inc(Count);
  218.    end
  219.    else Error(coIndexError,0);
  220. end;
  221.  
  222. procedure TCollection.AtPut(Index: Integer; Item: Pointer);
  223. begin
  224.    if (Index >= 0) and (Index <= Count) then
  225.       Items^[Index] := Item
  226.    else Error(coIndexError,0);
  227. end;
  228.  
  229. procedure TCollection.Delete(Item: Pointer);
  230. begin
  231.    AtDelete(IndexOf(Item));
  232. end;
  233.  
  234. procedure TCollection.DeleteAll;
  235. begin
  236.    Count := 0;
  237. end;
  238.  
  239. procedure TCollection.Free(Item: Pointer);
  240. begin
  241.    Delete(Item);
  242.    FreeItem(Item);
  243. end;
  244.  
  245. procedure TCollection.FreeAll;
  246. var
  247.   I: Integer;
  248. begin
  249.    for I := 0 to Count - 1 do FreeItem(At(I));
  250.    Count := 0;
  251. end;
  252.  
  253. procedure TCollection.FreeItem(Item: Pointer);
  254. begin
  255.    if Item <> nil then Dispose(PObject(Item), Done);
  256. end;
  257.  
  258. function TCollection.IndexOf(Item: Pointer): Integer;
  259. var
  260.    i          : integer;
  261.    foundit    : boolean;
  262. begin
  263.    foundit := false;
  264.    i := 0;
  265.    while not foundit and (i < Count) do
  266.    begin
  267.       foundit := Item = Items^[i];
  268.       if not foundit then inc(i);
  269.    end;
  270.    if foundit then IndexOf := i else IndexOf := -1;
  271. end;
  272.  
  273. procedure TCollection.Insert(Item: Pointer);
  274. begin
  275.    AtInsert(Count, Item);
  276. end;
  277.  
  278. procedure TCollection.SetLimit(ALimit: Integer);
  279. var
  280.    AItems: PColPntrs;
  281. begin
  282.    if ALimit < Count then ALimit := Count;
  283.    if ALimit > MaxCollectionSize then ALimit := MaxCollectionSize;
  284.    if ALimit <> Limit then
  285.    begin
  286.       if ALimit = 0 then AItems := nil else
  287.       begin
  288.          GetMem(AItems, ALimit * SizeOf(Pointer));
  289.          if (Count <> 0) and (Items <> nil) then
  290.             Move(Items^, AItems^, Count * SizeOf(Pointer));
  291.       end;
  292.       if Limit <> 0 then FreeMem(Items, Limit * SizeOf(Pointer));
  293.       Items := AItems;
  294.       Limit := ALimit;
  295.    end;
  296. end;
  297.  
  298. {------------------------------------------------------------------------------
  299.                                TSortedCollection
  300. ------------------------------------------------------------------------------}
  301.  
  302. constructor TSortedCollection.Init(ALimit, ADelta: Integer);
  303. begin
  304.    TCollection.Init(ALimit, ADelta);
  305.    Duplicates := False;
  306. end;
  307.  
  308. function TSortedCollection.Compare(Key1, Key2: Pointer): Integer;
  309. begin
  310.    Abstract;
  311. end;
  312.  
  313. function TSortedCollection.IndexOf(Item: Pointer): Integer;
  314. var
  315.    I: Integer;
  316. begin
  317.    IndexOf := -1;
  318.    if Search(KeyOf(Item), I) then
  319.    begin
  320.       if Duplicates then
  321.          while (I < Count) and (Item <> Items^[I]) do Inc(I);
  322.       if I < Count then IndexOf := I;
  323.    end;
  324. end;
  325.  
  326. procedure TSortedCollection.Insert(Item: Pointer);
  327. var
  328.    I: Integer;
  329. begin
  330.    if not Search(KeyOf(Item), I) or Duplicates then AtInsert(I, Item);
  331. end;
  332.  
  333. function TSortedCollection.KeyOf(Item: Pointer): Pointer;
  334. begin
  335.    KeyOf := Item;
  336. end;
  337.  
  338. function TSortedCollection.Search(Key: Pointer; var Index: Integer): Boolean;
  339. var
  340.    L, H, I, C: Integer;
  341. begin
  342.    Search := False;
  343.    L := 0;
  344.    H := Count - 1;
  345.    while L <= H do
  346.    begin
  347.       I := (L + H) shr 1;
  348.       C := Compare(KeyOf(Items^[I]), Key);
  349.       if C < 0 then L := I + 1 else
  350.       begin
  351.          H := I - 1;
  352.          if C = 0 then
  353.          begin
  354.             Search := True;
  355.             if not Duplicates then L := I;
  356.          end;
  357.       end;
  358.    end;
  359.    Index := L;
  360. end;
  361.  
  362. { ----------------------------------------------------------------------------
  363.                                TStringCollection
  364. -----------------------------------------------------------------------------}
  365.  
  366. function TStringCollection.Compare(Key1, Key2: Pointer): Integer;
  367. var
  368.    PSt1 : PString absolute Key1;
  369.    PSt2 : PString absolute Key2;
  370.    flg : integer;
  371.    eql : boolean;
  372. begin
  373.    eql := PSt1^ = PSt2^;
  374.    Inline(              {Get flag register in flg}
  375.      $9C/                   {  PUSHF           ;Push flag register}
  376.      $59/                   {  POP     CX      ;Get flag register in CX}
  377.      $89/$4E/<flg);         {  MOV     <flg,CX ;Store CX in flg}
  378.    if eql then Compare := 0
  379.       else if (flg and $0080) = 0 then
  380.              Compare := 1             {Key1 > Key2 if sign flag 0}
  381.            else Compare := -1;        {Key1 < Key2 if sign flag 1}
  382. end;
  383.  
  384. procedure TStringCollection.FreeItem(Item: Pointer);
  385. begin
  386.    DisposeStr(Item);
  387. end;
  388.  
  389.  
  390. {$ENDIF}
  391. {------------------------------------------------------------------------------
  392.                               GSO_LineCollection
  393. ------------------------------------------------------------------------------}
  394.  
  395. function GSO_LineCollection.ByteCount : longint;
  396. var
  397.    i : longint;
  398.    v : integer;
  399.    p : GSP_LineBuf;
  400. begin
  401.    i := 0;
  402.    for v := 0 to Count-1 do
  403.    begin
  404.       p := At(v);
  405.       if p <> nil then
  406.       begin
  407.          i := i + byte(p^.LineText[0]);
  408.          inc(i,2);
  409.       end;
  410.    end;
  411.    ByteCount := i;
  412. end;
  413.  
  414. procedure GSO_LineCollection.FreeItem(Item: Pointer);
  415. var
  416.    p : GSP_LineBuf absolute Item;
  417. begin
  418.    FreeMem(p, byte(p^.LineText[0])+2);
  419. end;
  420.  
  421. Procedure GSO_LineCollection.InsertItem(rtn : byte; var st : string);
  422. var
  423.    p : GSP_LineBuf;
  424. begin
  425.    GetMem(p, byte(st[0])+2);
  426.    p^.LineRetn := rtn;
  427.    p^.LineText := st;
  428.    Insert(p);
  429. end;
  430.  
  431. Procedure GSO_LineCollection.InsertItemAt(rtn : byte; var st : string;
  432.                                           i : integer);
  433. var
  434.    p : GSP_LineBuf;
  435. begin
  436.    GetMem(p, byte(st[0])+2);
  437.    p^.LineRetn := rtn;
  438.    p^.LineText := st;
  439.    AtInsert(i,p);
  440. end;
  441.  
  442.  
  443.  
  444. end.
  445.  
  446.