home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / pascal / turbo55 / tp55 / tclstr.pas < prev    next >
Pascal/Delphi Source File  |  1989-05-02  |  9KB  |  243 lines

  1.  
  2. { Copyright (c) 1989 by Borland International, Inc. }
  3.  
  4. unit TCLStr;
  5. { Turbo Pascal 5.5 object-oriented example long string routines.
  6.   This unit is used by TCALC.PAS.
  7.   See TCALC.DOC for an more information about this example.
  8. }
  9.  
  10. {$S-}
  11.  
  12. interface
  13.  
  14. uses Objects, TCUtil;
  15.  
  16. const
  17.   MaxLStringLength = 65521;  { The maximum amount that can be allocated
  18.                                to a pointer }
  19.  
  20. type
  21.   LStringRange = 0..MaxLStringLength;
  22.   LStringData = array [1..MaxLStringLength] of Char;
  23.   LStringDataPtr = ^LStringData;
  24.   LStringPtr = ^LString;
  25.   LString = object
  26.     Len : LStringRange;        { Current length }
  27.     MaxLen : LStringRange;     { Length that has been allocated.  This is
  28.                                  always allocated in blocks of 16 bytes so
  29.                                  that the long string's data doesn't have to 
  30.                                  be reallocated every time the long string 
  31.                                  grows }
  32.     Data : LStringDataPtr;
  33.     constructor Init;
  34.     destructor Done;
  35.     function SetValue(NewLen : LStringRange; NewData : Pointer) : Boolean;
  36.     function FromString(S : String) : Boolean;
  37.     function ToString : String;
  38.     function Length : LStringRange;
  39.     function Copy(Start, Amt : LStringRange) : String;
  40.     function Insert(S : String; Start : LStringRange) : Boolean;
  41.     procedure Delete(Start, Amt : LStringRange);
  42.     function Append(S : String) : Boolean;
  43.     procedure Change(Ch : Char; Start : LStringRange);
  44.     function Assign(LS : LString) : Boolean;
  45.     function FromStream(var S : DosStream) : Boolean;
  46.     procedure ToStream(var S : DosStream);
  47.   end;
  48.  
  49. implementation
  50.  
  51. constructor LString.Init;
  52. { Initializes the long string. }
  53. begin
  54.   Len := 0;
  55.   MaxLen := 0;
  56.   Data := nil;
  57. end; { LString.Init }
  58.  
  59. destructor LString.Done;
  60. { Frees memory used by the long string. }
  61. begin
  62.   if Data <> nil then
  63.     FreeMem(Data, MaxLen);
  64. end; { LString.Done }
  65.  
  66. function LString.SetValue(NewLen : LStringRange;
  67.                           NewData : Pointer) : Boolean;
  68. { Copies an area of memory to the long string }
  69. var
  70.   Size : Word;
  71.   NData : Pointer;
  72. begin
  73.   Size := (NewLen + 15) shr 4 shl 4;   { Calculate the new size }
  74.   if NewLen > MaxLen then        { Allocate new data area if the long string }
  75.   begin                          { needs to grow }
  76.     GetMem(NData, Size);
  77.     if NData = nil then          { The allocation failed.  Return False }
  78.     begin
  79.       SetValue := False;
  80.       Exit;
  81.     end;
  82.     if Data <> nil then          { If there was any data in the long string, }
  83.     begin                        { copy it to the new data area }
  84.       Move(Data^, NData^, Len);
  85.       FreeMem(Data, MaxLen);     { Free the memory used by the long string }
  86.     end;                         { before it was reallocated }
  87.     Data := NData;               { Set Data and MaxLen to their new values }
  88.     MaxLen := Size;
  89.   end;
  90.   Move(NewData^, Data^, NewLen); { Copy the new data to the long string }
  91.   Len := NewLen;                 { Set the length }
  92.   SetValue := True;              { Successful - Return True }
  93. end; { LString.SetValue }
  94.  
  95. function LString.FromString(S : String) : Boolean;
  96. { Converts a string into a long string }
  97. begin
  98.   if not SetValue(System.Length(S), @S[1]) then
  99.   begin                              { Set the long string to be a null }
  100.     FromString := SetValue(0, nil);  { string if it could not be expanded }
  101.     FromString := False;             { Return False }
  102.   end
  103.   else
  104.     FromString := True;              { Successful.  Return True }
  105. end; { LString.FromString }
  106.  
  107. function LString.ToString : String;
  108. { Converts a long string into a string }
  109. var
  110.   S : String;
  111.   NewLen : Byte;
  112. begin
  113.   NewLen := Min(255, Length);   { The maximum length of a string is 255 }
  114.   S[0] := Chr(NewLen);          { Set the length of the new string }
  115.   Move(Data^, S[1], NewLen);    { Copy the data }
  116.   ToString := S;                { Return the new string }
  117. end; { LString.ToString }
  118.  
  119. function LString.Length : LStringRange;
  120. { Returns the current length of a long string }
  121. begin
  122.   Length := Len;
  123. end; { LString.Length }
  124.  
  125. function LString.Copy(Start, Amt : LStringRange) : String;
  126. { Copies part of a long string into a string }
  127. var
  128.   S : String;
  129. begin
  130.   if Start > Len then      { Trying to copy past the end of the long }
  131.     Amt := 0               { string - return a null string }
  132.   else
  133.     Amt := Min(Amt, Succ(Len - Start));   { Calculate length of new string }
  134.   S[0] := Chr(Amt);                  { Set length of new string }
  135.   Move(Data^[Start], S[1], Amt);     { Copy data into new string }
  136.   Copy := S;                         { Return new string }
  137. end; { LString.Copy }
  138.  
  139. function LString.Insert(S : String; Start : LStringRange) : Boolean;
  140. { Inserts a string into a long string }
  141. var
  142.   OldLen : LStringRange;
  143.   Size : Word;
  144.   NData : Pointer;
  145. begin
  146.   OldLen := Len;
  147.   Inc(Len, System.Length(S));
  148.   if Len > MaxLen then               { Allocate new data area if the long }
  149.   begin                              { string needs to grow }
  150.     Size := (Len + 15) shr 4 shl 4;  { Calculate the new size }
  151.     GetMem(NData, Size);             { Allocate new data area }
  152.     if NData = nil then              { The long string could not be expanded }
  153.     begin
  154.       Dec(Len, System.Length(S));    { Restore the old Len value }
  155.       Insert := False;               { Return False }
  156.       Exit;
  157.     end;
  158.     if Data <> nil then              { If there was data in the long string, }
  159.     begin                            { copy it to the new data area }
  160.       Move(Data^, NData^, OldLen);
  161.       FreeMem(Data, MaxLen);         { Free the old data area }
  162.     end;
  163.     Data := NData;                   { Set new values for Data and MaxLen }
  164.     MaxLen := Size;
  165.   end;
  166.   if Start <= OldLen then  { Move the part of the string after the insert to }
  167.                            { the right to make space for the new string }
  168.     Move(Data^[Start], Data^[Start + System.Length(S)], Succ(OldLen - Start));
  169.   Move(S[1], Data^[Start], System.Length(S));   { Insert the new string }
  170.   Insert := True;                { Successful - return True }
  171. end; { LString.Insert }
  172.  
  173. procedure LString.Delete(Start, Amt : LStringRange);
  174. { Deletes part of a long string }
  175. begin
  176.   Amt := Min(Amt, Succ(Len - Start));  { No characters can be deleted past 
  177.                                          the end of the long string }
  178.   if Start + Amt <= Len then  { The delete is in the middle of the long
  179.                                 string - move the rest of the data to the
  180.                                 left }
  181.     Move(Data^[Start + Amt], Data^[Start], Succ(Len - Amt - Start));
  182.   Dec(Len, Amt);              { Fix the length value }
  183. end; { LString.Delete }
  184.  
  185. function LString.Append(S : String) : Boolean;
  186. { Appends a string to a long string }
  187. begin
  188.   Append := Insert(S, Succ(Len));   { Insert the string at the end }
  189. end; { LString.Append }
  190.  
  191. procedure LString.Change(Ch : Char; Start : LStringRange);
  192. { Change a particular character of a long string }
  193. begin
  194.   Move(Ch, Data^[Start], 1);
  195. end; { LString.Change }
  196.  
  197. function LString.Assign(LS : LString) : Boolean;
  198. { Copy one long string to another one }
  199. begin
  200.   Assign := SetValue(LS.Length, LS.Data);
  201. end; { LString.Assign }
  202.  
  203. function LString.FromStream(var S : DosStream) : Boolean;
  204. { Read a long string from a stream }
  205. var
  206.   Counter, NewLen, Size : Word;
  207.   Dummy : Byte;
  208.   NData : Pointer;
  209. begin
  210.   S.Read(NewLen, SizeOf(NewLen));     { Read the length }
  211.   Size := (NewLen + 15) shr 4 shl 4;  { Calculate the new size }
  212.   if NewLen > MaxLen then       { Allocate new data area if the long string }
  213.   begin                         { needs to grow }
  214.     GetMem(NData, Size);
  215.     if NData = nil then         { The allocation failed.  Return False }
  216.     begin
  217.       for Counter := 1 to NewLen do  { Read the string in so that the file }
  218.         S.Read(Dummy, 1);            { position is still correct }
  219.       FromStream := False;
  220.       Exit;
  221.     end;
  222.     if Data <> nil then         { If there was any data in the long string, }
  223.     begin                       { copy it to the new data area }
  224.       Move(Data^, NData^, Len);
  225.       FreeMem(Data, MaxLen);
  226.     end;
  227.     Data := NData;              { Set new values for Data and MaxLen }
  228.     MaxLen := Size;
  229.   end;
  230.   S.Read(Data^, NewLen);        { Read the long string from the stream }
  231.   Len := NewLen;
  232.   FromStream := True;           { Successful - return True }
  233. end; { LString.FromStream }
  234.  
  235. procedure LString.ToStream(var S : DosStream);
  236. { Write a long string to a stream }
  237. begin
  238.   S.Write(Len, SizeOf(Len));    { Write the length }
  239.   S.Write(Data^, Len);          { Write the long string }
  240. end; { LString.ToStream }
  241.  
  242. end.
  243.