home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / progtool / pascal / o_gem / units / objects.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-09-22  |  12.5 KB  |  599 lines

  1. {**************************************
  2.  *  O b j e c t G E M   Version 1.17  *
  3.  *  Copyright 1992-94 by Thomas Much  *
  4.  **************************************
  5.  *        Unit  O B J E C T S         *
  6.  **************************************
  7.  *    Softdesign Computer Software    *
  8.  *    Thomas Much, Gerwigstraße 46,   *
  9.  *  76131 Karlsruhe, (0721) 62 28 41  *
  10.  *         Thomas Much @ KA2          *
  11.  *  UK48@ibm3090.rz.uni-karlsruhe.de  *
  12.  **************************************
  13.  *    erstellt am:        13.07.1992  *
  14.  *    letztes Update am:  29.05.1994  *
  15.  **************************************}
  16.  
  17. {
  18.   WICHTIGE ANMERKUNGEN ZUM QUELLTEXT:
  19.  
  20.   ObjectGEM wird mit dem _vollständigen_ Quelltext ausgeliefert, d.h.
  21.   jeder kann sich die Unit selbst compilieren, womit die extrem lästigen
  22.   Kompatibilitätsprobleme mit den PP-Releases beseitigt sind.
  23.   ObjectGEM ist und bleibt aber trotzdem SHAREWARE, d.h. wer die Biblio-
  24.   thek regelmäßig benutzt, muß sich REGISTRIEREN lassen. Dafür gibt es
  25.   die neueste Version und - gegen einen geringen Aufpreis - auch ein
  26.   gedrucktes Handbuch.
  27.  
  28.   WICHTIG: Wer den Quelltext verändert und dann Probleme beim Compilieren,
  29.   Ausführen o.ä. hat, kann nicht damit rechnen, daß ich den Fehler suche;
  30.   tritt der Fehler allerdings auch mit dem Original-Quelltext auf, würde
  31.   ich mich über eine genaue Fehlerbeschreibung freuen. Veränderte Quell-
  32.   texte dürfen _nicht_ weitergegeben werden, dies wäre ein Verstoß gegen
  33.   das Copyright!
  34.  
  35.   Wer beim Durchstöbern des Textes auf vermeintliche Fehler oder verbesse-
  36.   rungswürdige Stellen trifft (von letzterem gibt es sicherlich noch viele),
  37.   kann mir dies gerne mitteilen - ich habe auch ich nichts gegen kostenlos
  38.   zur Verfügung gestellte optimierte Routinen (sofern sich jemand die Mühe
  39.   macht). Wer in anderen Projekten, die nicht in direkter Konkurrenz zu
  40.   ObjectGEM stehen, einzelne Routinen verwenden möchte, wendet sich bitte
  41.   an mich (ein solcher Austausch sollte kein Problem sein).
  42.  
  43.   Wer sich auf nicht dokumentierte "implementation"- oder "private"-Eigen-
  44.   schaften verläßt, darf sich nicht über Inkompatibilitäten zu späteren
  45.   Versionen wundern; wer meint, eine Dokumentationslücke entdeckt zu haben,
  46.   kann mir dies gerne mitteilen.
  47.  
  48.   Kleine Info zum Schluß: Als "default tabsize" verwende ich 2. Wer drei
  49.   Punkte ("...") im Quelltext entdeckt, hat eine Stelle gefunden, an der
  50.   ich z.Z. arbeite ;-)
  51.  
  52.   "Möge die OOP mit Euch sein!"
  53. }
  54.  
  55.  
  56. {$IFDEF DEBUG}
  57.     {$B+,D+,G-,I-,L+,N-,P-,Q+,R+,S+,T-,V-,X+,Z+}
  58. {$ELSE}
  59.     {$B+,D-,G-,I-,L-,N-,P-,Q-,R-,S-,T-,V-,X+,Z+}
  60. {$ENDIF}
  61.  
  62. unit Objects;
  63.  
  64. interface
  65.  
  66. uses
  67.  
  68.     OTypes;
  69.  
  70. type
  71.  
  72.     PObject           = ^TObject;
  73.     TObject           = object
  74.         public
  75.         constructor Init;
  76.         procedure Free;
  77.         destructor Done; virtual;
  78.     end;
  79.  
  80.     PCollection       = ^TCollection;
  81.     TCollection       = object(TObject)
  82.         public
  83.         Items: PItemList;
  84.         Count,
  85.         Limit,
  86.         Delta: longint;
  87.         constructor Init(ALimit,ADelta: longint);
  88.         destructor Done; virtual;
  89.         function At(Index: longint): pointer; virtual;
  90.         procedure AtDelete(Index: longint); virtual;
  91.         procedure AtFree(Index: longint); virtual;
  92.         procedure AtInsert(Index: longint; Item: pointer); virtual;
  93.         procedure AtPut(Index: longint; Item: pointer); virtual;
  94.         procedure Delete(Item: pointer); virtual;
  95.         procedure Error(Code,Info: longint); virtual;
  96.         procedure DeleteAll; virtual;
  97.         function FirstThat(Test: PIterationFunc): pointer;
  98.         procedure ForEach(Action: PIterationProc);
  99.         procedure Free(Item: pointer);
  100.         procedure FreeAll; virtual;
  101.         procedure FreeItem(Item: pointer); virtual;
  102.         function IndexOf(Item: pointer): longint; virtual;
  103.         procedure Insert(Item: pointer); virtual;
  104.         function LastThat(Test: PIterationFunc): pointer; virtual;
  105.         procedure Pack; virtual;
  106.         procedure SetLimit(ALimit: longint); virtual;
  107.     end;
  108.  
  109.     PSortedCollection = ^TSortedCollection;
  110.     TSortedCollection = object(TCollection)
  111.         public
  112.         Duplicates: boolean;
  113.         constructor Init(ALimit,ADelta: longint);
  114.         function IndexOf(Item: pointer): longint; virtual;
  115.         procedure Insert(Item: pointer); virtual;
  116.         function Compare(Key1,Key2: pointer): integer; virtual;
  117.         function KeyOf(Item: pointer): pointer; virtual;
  118.         function Search(Key: pointer; var Index: longint): boolean; virtual;
  119.     end;
  120.  
  121.     PStringCollection = ^TStringCollection;
  122.     TStringCollection = object(TSortedCollection)
  123.         public
  124.         constructor Init(ALimit,ADelta: longint);
  125.         procedure FreeItem(Item: pointer); virtual;
  126.         function Compare(Key1,Key2: pointer): integer; virtual;
  127.     end;
  128.  
  129.     PStrCollection    = ^TStrCollection;
  130.     TStrCollection    = object(TStringCollection)
  131.         public
  132.         procedure FreeItem(Item: pointer); virtual;
  133.         function Compare(Key1,Key2: pointer): integer; virtual;
  134.     end;
  135.  
  136.  
  137.  
  138. implementation
  139.  
  140. uses
  141.  
  142.     Strings,OProcs;
  143.  
  144.  
  145. { *** Objekt TOBJECT *** }
  146.  
  147. constructor TObject.Init;
  148.  
  149.   begin
  150.   end;
  151.  
  152.  
  153. procedure TObject.Free;
  154.  
  155.     begin
  156.         dispose(PObject(@self),Done)
  157.     end;
  158.  
  159.  
  160. destructor TObject.Done;
  161.  
  162.   begin
  163.   end;
  164.  
  165. { *** TOBJECT *** }
  166.  
  167.  
  168.  
  169. { *** Objekt TCOLLECTION *** }
  170.  
  171. constructor TCollection.Init(ALimit,ADelta: longint);
  172.  
  173.     begin
  174.         if not(inherited Init) then fail;
  175.         Items:=nil;
  176.         Count:=0;
  177.         Limit:=0;
  178.         Delta:=ADelta;
  179.         if Delta<0 then Delta:=0;
  180.         SetLimit(ALimit)
  181.     end;
  182.  
  183.  
  184. destructor TCollection.Done;
  185.  
  186.     begin
  187.         FreeAll;
  188.         SetLimit(0);
  189.         inherited Done
  190.     end;
  191.  
  192.  
  193. function TCollection.At(Index: longint): pointer;
  194.  
  195.     begin
  196.         if (Index<0) or (Index>=Count) then
  197.             begin
  198.                 At:=nil;
  199.                 Error(coIndexError,Index)
  200.             end
  201.         else
  202.             At:=Items^[Index]
  203.     end;
  204.  
  205.  
  206. procedure TCollection.AtDelete(Index: longint);
  207.     var q: longint;
  208.  
  209.     begin
  210.         if (Index<0) or (Index>=Count) then Error(coIndexError,Index)
  211.         else
  212.             begin
  213.                 if Index<Count-1 then
  214.                     for q:=Index to (Count-2) do Items^[q]:=Items^[q+1];
  215.                 dec(Count)
  216.             end
  217.     end;
  218.  
  219.  
  220. procedure TCollection.AtFree(Index: longint);
  221.     var p: pointer;
  222.  
  223.     begin
  224.         p:=At(Index);
  225.         AtDelete(Index);
  226.         FreeItem(p)
  227.     end;
  228.  
  229.  
  230. procedure TCollection.AtInsert(Index: longint; Item: pointer);
  231.     var q: longint;
  232.  
  233.     begin
  234.         if (Index<0) or (Index>Count) then Error(coIndexError,Index)
  235.         else
  236.             begin
  237.                 if Count=Limit then SetLimit(Limit+Delta);
  238.                 if Count<Limit then
  239.                     begin
  240.                         if Index<Count then
  241.                             for q:=Count downto Index+1 do Items^[q]:=Items^[q-1];
  242.                         Items^[Index]:=Item;
  243.                         inc(Count)
  244.                     end
  245.                 else
  246.                     if Delta=0 then Error(coIndexError,Index)
  247.             end
  248.     end;
  249.  
  250.  
  251. procedure TCollection.AtPut(Index: longint; Item: pointer);
  252.  
  253.     begin
  254.         if (Index<0) or (Index>=Count) then Error(coIndexError,Index)
  255.         else
  256.             Items^[Index]:=Item
  257.     end;
  258.  
  259.  
  260. procedure TCollection.Delete(Item: pointer);
  261.  
  262.     begin
  263.         AtDelete(IndexOf(Item))
  264.     end;
  265.  
  266.  
  267. procedure TCollection.Error(Code,Info: longint);
  268.  
  269.     begin
  270.         case Code of
  271.             coIndexError: write('Index Range Error (',Info,') ');
  272.             coOverflow:   write('Collection Overflow (',Info,') ')
  273.         end;
  274.         runerror(212-Code)
  275.     end;
  276.  
  277.  
  278. procedure TCollection.DeleteAll;
  279.  
  280.     begin
  281.         Count:=0
  282.     end;
  283.  
  284.  
  285. function TCollection.FirstThat(Test: PIterationFunc): pointer;
  286.     var q : longint;
  287.         p : pointer;
  288.         cl: IterationFunc;
  289.  
  290.     begin
  291.         FirstThat:=nil;
  292.         cl:=IterationFunc(Test);
  293.         if Count>0 then
  294.             for q:=0 to Count-1 do
  295.                 begin
  296.                     p:=At(q);
  297.                     if p<>nil then
  298.                         if cl(p) then
  299.                             begin
  300.                                 FirstThat:=p;
  301.                                 exit
  302.                             end
  303.                 end
  304.     end;
  305.  
  306.  
  307. procedure TCollection.ForEach(Action: PIterationProc);
  308.     var q : longint;
  309.         p : pointer;
  310.         cl: IterationProc;
  311.  
  312.     begin
  313.         cl:=IterationProc(Action);
  314.         if Count>0 then
  315.             for q:=0 to Count-1 do
  316.                 begin
  317.                     p:=At(q);
  318.                     if p<>nil then cl(p)
  319.                 end
  320.     end;
  321.  
  322.  
  323. procedure TCollection.Free(Item: pointer);
  324.  
  325.     begin
  326.         Delete(Item);
  327.         FreeItem(Item)
  328.     end;
  329.  
  330.  
  331. procedure TCollection.FreeAll;
  332.     var q: longint;
  333.  
  334.     begin
  335.         if Count>0 then
  336.             for q:=0 to Count-1 do FreeItem(At(q));
  337.         Count:=0
  338.     end;
  339.  
  340.  
  341. procedure TCollection.FreeItem(Item: pointer);
  342.  
  343.     begin
  344.         if Item<>nil then PObject(Item)^.Free
  345.     end;
  346.  
  347.  
  348. function TCollection.IndexOf(Item: pointer): longint;
  349.     var q: longint;
  350.  
  351.     begin
  352.         IndexOf:=-1;
  353.         if Count>0 then
  354.             for q:=0 to Count-1 do
  355.                 if Item=At(q) then
  356.                     begin
  357.                         IndexOf:=q;
  358.                         exit
  359.                     end
  360.     end;
  361.  
  362.  
  363. procedure TCollection.Insert(Item: pointer);
  364.  
  365.     begin
  366.         AtInsert(Count,Item)
  367.     end;
  368.  
  369.  
  370. function TCollection.LastThat(Test: PIterationFunc): pointer;
  371.     var q : longint;
  372.         p : pointer;
  373.         cl: IterationFunc;
  374.  
  375.     begin
  376.         LastThat:=nil;
  377.         cl:=IterationFunc(Test);
  378.         if Count>0 then
  379.             for q:=Count-1 downto 0 do
  380.                 begin
  381.                     p:=At(q);
  382.                     if p<>nil then
  383.                         if cl(p) then
  384.                             begin
  385.                                 LastThat:=p;
  386.                                 exit
  387.                             end
  388.                 end
  389.     end;
  390.  
  391.  
  392. procedure TCollection.Pack;
  393.     label _again;
  394.  
  395.     var low,cur,pc,q: longint;
  396.  
  397.     begin
  398.         if Count>0 then
  399.             begin
  400.                 pc:=Count-1;
  401.                 low:=0;
  402.                 _again:
  403.                 while (Items^[low]<>nil) and (low<pc) do inc(low);
  404.                 cur:=low;
  405.                 while (Items^[cur]=nil) and (cur<pc) do inc(cur);
  406.                 if cur<pc then
  407.                     begin
  408.                         for q:=low to cur-1 do Items^[q]:=Items^[q+1];
  409.                         Items^[cur]:=nil;
  410.                         goto _again
  411.                     end;
  412.                 low:=0;
  413.                 while (low<Count) and (Items^[low]<>nil) do inc(low);
  414.                 Count:=low
  415.             end;
  416.         SetLimit(0)
  417.     end;
  418.  
  419.  
  420. procedure TCollection.SetLimit(ALimit: longint);
  421.     var dummy: PItemList;
  422.         q    : longint;
  423.  
  424.     begin
  425.         if ALimit<Count then ALimit:=Count;
  426.         if ALimit>MaxCollectionSize then ALimit:=MaxCollectionSize;
  427.         if ALimit<>Limit then
  428.             begin
  429.                 dummy:=nil;
  430.                 if ALimit>0 then getmem(dummy,ALimit shl 2);
  431.                 if (dummy<>nil) or (ALimit=0) then
  432.                     begin
  433.                         if (Items<>nil) and (dummy<>nil) and (Count>0) then
  434.                             for q:=0 to Count-1 do dummy^[q]:=Items^[q];
  435.                         if Items<>nil then freemem(Items,Limit shl 2);
  436.                         Limit:=ALimit;
  437.                         Items:=dummy
  438.                     end
  439.                 else
  440.                     if ALimit>Limit then Error(coOverflow,ALimit)
  441.             end
  442.     end;
  443.  
  444. { *** TCOLLECTION *** }
  445.  
  446.  
  447.  
  448. { *** Objekt TSORTEDCOLLECTION *** }
  449.  
  450. constructor TSortedCollection.Init(ALimit,ADelta: longint);
  451.  
  452.     begin
  453.         if not(inherited Init(ALimit,ADelta)) then fail;
  454.         Duplicates:=false
  455.     end;
  456.  
  457.  
  458. function TSortedCollection.IndexOf(Item: pointer): longint;
  459.     var i: longint;
  460.  
  461.     begin
  462.         if Search(KeyOf(Item),i) then IndexOf:=i
  463.         else
  464.             IndexOf:=-1
  465.     end;
  466.  
  467.  
  468. procedure TSortedCollection.Insert(Item: pointer);
  469.     var i: longint;
  470.  
  471.     begin
  472.         if not(Search(KeyOf(Item),i)) then AtInsert(i,Item)
  473.         else
  474.             begin
  475.                 if Duplicates then AtInsert(i,Item)
  476.                 else
  477.                     begin
  478.                         FreeItem(At(i));
  479.                         AtPut(i,Item)
  480.                     end;
  481.             end
  482.     end;
  483.  
  484.  
  485. function TSortedCollection.Compare(Key1,Key2: pointer): integer;
  486.  
  487.     begin
  488.         Compare:=0;
  489.         Abstract
  490.     end;
  491.  
  492.  
  493. function TSortedCollection.KeyOf(Item: pointer): pointer;
  494.  
  495.     begin
  496.         KeyOf:=Item
  497.     end;
  498.  
  499.  
  500. function TSortedCollection.Search(Key: pointer; var Index: longint): boolean;
  501.     var cur,low,high: longint;
  502.  
  503.     begin
  504.         Search:=false;
  505.         if Count>0 then
  506.             begin
  507.                 low:=0;
  508.                 high:=Count-1;
  509.                 cur:=high shr 1;
  510.                 repeat
  511.                     case Compare(Key,KeyOf(At(cur))) of
  512.                         0: begin
  513.                                  Index:=cur;
  514.                                  Search:=true;
  515.                                  exit
  516.                              end;
  517.                         1: if low=high then
  518.                                  begin
  519.                                      Index:=cur+1;
  520.                                      exit
  521.                                  end
  522.                              else
  523.                                  begin
  524.                                      low:=cur+1;
  525.                                      if low>high then low:=high;
  526.                                      cur:=(low+high) shr 1
  527.                                  end;
  528.                         -1: if low=high then
  529.                                     begin
  530.                                         Index:=cur;
  531.                                         exit
  532.                                     end
  533.                                 else
  534.                                     begin
  535.                                         high:=cur-1;
  536.                                         if high<low then high:=low;
  537.                                         cur:=(low+high) shr 1
  538.                                     end
  539.                     end
  540.                 until false
  541.             end
  542.         else
  543.             Index:=0
  544.     end;
  545.  
  546. { *** TSORTEDCOLLECTION *** }
  547.  
  548.  
  549.  
  550. { *** Objekt TSTRINGCOLLECTION *** }
  551.  
  552. constructor TStringCollection.Init(ALimit,ADelta: longint);
  553.  
  554.     begin
  555.         if not(inherited Init(ALimit,ADelta)) then fail;
  556.         Duplicates:=true
  557.     end;
  558.  
  559.  
  560. procedure TStringCollection.FreeItem(Item: pointer);
  561.  
  562.     begin
  563.         DisposeStr(PString(Item))
  564.     end;
  565.  
  566.  
  567. function TStringCollection.Compare(Key1,Key2: pointer): integer;
  568.  
  569.     begin
  570.         if PString(Key1)^>PString(Key2)^ then Compare:=1
  571.         else
  572.             if PString(Key1)^<PString(Key2)^ then Compare:=-1
  573.             else
  574.                 Compare:=0
  575.     end;
  576.  
  577. { *** TSTRINGCOLLECTION *** }
  578.  
  579.  
  580.  
  581. { *** Objekt TSTRCOLLECTION *** }
  582.  
  583. procedure TStrCollection.FreeItem(Item: pointer);
  584.  
  585.     begin
  586.         ChrDispose(PChar(Item))
  587.     end;
  588.  
  589.  
  590. function TStrCollection.Compare(Key1,Key2: pointer): integer;
  591.  
  592.     begin
  593.         Compare:=Sgn(StrComp(Key1,Key2))
  594.     end;
  595.  
  596. { *** TSTRCOLLECTION *** }
  597.  
  598.  
  599. end.