home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / DYRA.ZIP / DYARRAYS.PAS next >
Encoding:
Pascal/Delphi Source File  |  1993-01-04  |  4.8 KB  |  195 lines

  1. UNIT DyArrays;
  2.  
  3. {------------------ DARRAY ---- Version 4.0 -- 88/04/14 ---------------}
  4. {
  5.      Implements Dynamic Arrays using the Heap.
  6.  
  7.  
  8.      THIS SOFTWARE IS DONATED TO THE PUBLIC DOMAIN.
  9.  
  10.  
  11.        Author: Mike Babulic
  12.                3827 Charleswood Dr. N.W.
  13.                Calgary, Alberta
  14.                CANADA
  15.                T2L 2C7
  16.  
  17.        Compuserve: 72307,314
  18.  
  19.        Also reachable on a friend's Fido BBS:  1:134/1
  20.  
  21. }
  22.  
  23. INTERFACE
  24.  
  25. type
  26.  
  27.      DyArray = Pointer;          {Dynamic Array Type}
  28.  
  29.      DyHeader = ^DyArrayHeader;
  30.  
  31.      DyArrayHeader = record
  32.        size,                     { # of array elements }
  33.        max,                      { max. size before more heapspace needed}
  34.        mul,                      { length of an array element }
  35.        inc : LongInt;            { after "growing";  max := size + inc }
  36.      end;
  37.  
  38.  
  39. procedure DyOpen(var ra; ra_size,ra_mul,ra_inc:LongInt);
  40.    {Initialize a Dynamic Array:    size := ra_size;
  41.                                    mul  := ra_mul;
  42.                                    inc  := ra_inc;
  43.                                    max  := size + inc;
  44.    }
  45.  
  46. procedure DyClose(var ra);
  47.    {Close a Dynamic Array}
  48.  
  49. function DySize(var ra):LongInt;
  50.    {Returns the number of array elements}
  51.  
  52. procedure DyResize(var ra; newSize:LongInt);
  53.    {Change size of array to newSize *ELEMENTS*}
  54.  
  55. procedure DyGrow(var ra; increment:LongInt);
  56.    {Add increment  *ELEMENTS* to the array}
  57.  
  58. procedure DyClone(a:DyArray; var clone);
  59.    {Make a copy of the array}
  60.  
  61. procedure DyCopy(a:DyArray; var destination);
  62.    {Copy a's contents into the destination}
  63.  
  64. function Dy(a:DyArray; n:LongInt): Pointer;
  65.    {Return pointer element # n}
  66.  
  67. function DyInfo(a:DyArray): DyHeader;
  68.    {Return pointer to Header info for DyArray}
  69.  
  70. procedure PtrInc(var p:Pointer; n: Longint);
  71.    {Increment pointer by n bytes}
  72.  
  73.  
  74. IMPLEMENTATION
  75.  
  76.  
  77. {$R-} {Turn range checking off so this executes faster/properly}
  78.  
  79. procedure DyOpen(var ra; ra_size,ra_mul,ra_inc:LongInt);
  80.   var b: DyHeader  absolute  ra;
  81.       a: DyArrayHeader;
  82.   begin
  83.     if ra_size < 0 then ra_size :=  0;
  84.     if ra_inc  < 1 then ra_inc  := 15;
  85.     if ra_mul  < 1 then begin
  86.         writeln('Can''t DyOpen(ra,',ra_size,',',ra_mul,',',ra_inc,')');
  87.         HALT;
  88.     end;
  89.     with a do begin
  90.       size := ra_size;      max  := ra_size + ra_inc;
  91.       mul   := ra_mul;      inc  := ra_inc;
  92.       GetMem(b, mul * max + SizeOf(DyArrayHeader));
  93.       if b = NIL then begin
  94.         writeln('   GetMem failed! ');
  95.         writeln('Can''t DyOpen(ra,',size,',',ra_mul,',',ra_inc,')');
  96.         HALT;
  97.       end;
  98.     end;
  99.     b^ := a;
  100.     PtrInc(Pointer(b),SizeOf(DyArrayHeader));  {Point after the Header}
  101.   end;
  102.  
  103.  
  104. procedure DyClose(var ra);
  105.   var a: DyHeader  absolute  ra;
  106.   begin
  107.     if a<>NIL then begin
  108.       PtrInc(Pointer(a),-SizeOf(DyArrayHeader)); {Point to the Header}
  109.       with a^ do
  110.         FreeMem(a, mul * max + SizeOf(DyArrayHeader));
  111.       a := NIL;
  112.     end
  113.   end;
  114.  
  115.  
  116. function DySize(var ra):LongInt;
  117.   begin
  118.     DySize := DyInfo(DyArray(ra))^.size;
  119.   end;
  120.  
  121.  
  122. procedure DyResize(var ra; newSize:LongInt);
  123.   var a: DyHeader  absolute  ra;
  124.       newMax: LongInt;
  125.       newRa: DyHeader;
  126.       s : LongInt;
  127.   begin  if a<>NIL then begin
  128.     if newSize < 0 then newSize := 0;
  129.     with DyInfo(a)^ do begin
  130.       if (newSize > max)  or  (newSize+inc+inc < max) then begin
  131.         DyOpen(newRa,newSize,mul,inc);
  132.         if size < newSize then
  133.           move(a^,newRa^, size * mul)
  134.         else
  135.           move(a^,newRa^, newSize * mul);
  136.         DyClose(ra);
  137.         a := newRa;
  138.         end
  139.       else
  140.         size := newSize;
  141.     end;
  142.   end  end;
  143.  
  144.  
  145. procedure DyGrow(var ra; increment:LongInt);
  146.   var a: DyArray  absolute  ra;
  147.   begin
  148.     DyResize(ra, DyInfo(a)^.size + increment);
  149.   end;
  150.  
  151. procedure DyClone(a:DyArray; var clone);
  152.   var b : DyArray   ABSOLUTE   clone;
  153.   begin
  154.     With DyInfo(a)^ do begin
  155.       DyOpen(b,size,mul,inc);
  156.       move(a^,b^,mul * size);
  157.     end;
  158.   end;
  159.  
  160. procedure DyCopy(a:DyArray; var destination);
  161.   var b : DyArray   ABSOLUTE   destination;
  162.   begin
  163.     With DyInfo(a)^ do begin
  164.       DyResize(b,size);
  165.       move(a^,b^,mul * size);
  166.     end;
  167.   end;
  168.  
  169.  
  170. function Dy(a:DyArray; n:LongInt): Pointer;
  171.   begin
  172.     PtrInc( a, (n-1) * DyInfo(a)^.mul );
  173.     Dy := a;
  174.   end;
  175.  
  176.  
  177. function DyInfo(a:DyArray): DyHeader;   {Return pointer to Header info for DyArray}
  178.   begin
  179.     PtrInc( a, -SizeOf(DyArrayHeader)); {Point to the Header}
  180.     DyInfo :=  DyHeader(a);
  181.   end;
  182.  
  183. procedure PtrInc(var p:Pointer; n: Longint);   {Increment pointer by n}
  184.   type pointr = record  lo,hi: word  end;
  185.   var
  186.      pt : pointr   absolute  p;
  187.      c  : pointr   absolute  n;
  188.   begin
  189.     n := pt.lo + n;
  190.     pt.hi := pt.hi + n shr 4;
  191.     pt.lo := c.lo and $F;
  192.   end;
  193.  
  194.  
  195. end. {UNIT}