home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 March / Chip_1998-03_cd.bin / zkuste / delphi / WhiteAnts / CONTSTRM.ZIP / Strutils.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1997-01-14  |  16.8 KB  |  590 lines

  1. {
  2. +----------------------------------------------------------------------------+
  3. |                                      ⌐  ⌐                                  |
  4. |                                    ⌐⌐ ⌐ ⌐ ⌐                                |
  5. |                                 ⌐⌐⌐ ⌐   ⌐  ⌐                               |
  6. |                                 ⌐⌐    ⌐ ⌐   ⌐                              |
  7. |                  ⌐             ⌐⌐     ⌐  ⌐                                 |
  8. |                 ⌐ ⌐            ⌐⌐⌐    ⌐⌐  ⌐                                |
  9. |             ⌐⌐  ⌐  ⌐      ⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐  ⌐                                    |
  10. |            ⌐  ⌐⌐  ⌐⌐      ⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐                                  |
  11. |            ⌐ ⌐⌐⌐ ⌐⌐⌐⌐⌐⌐ ⌐⌐⌐ ⌐   ⌐⌐⌐⌐⌐⌐⌐⌐                                   |
  12. |           ⌐ ⌐⌐ ⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐ ⌐   ⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐      Copyright ⌐ 1996-1997 by:  |
  13. |           ⌐ ⌐⌐⌐⌐⌐⌐ ⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐⌐  ⌐ ⌐⌐⌐⌐⌐ ⌐⌐                                 |
  14. |          ⌐ ⌐⌐⌐⌐⌐⌐⌐   ⌐⌐⌐⌐⌐ ⌐⌐⌐⌐    ⌐⌐ ⌐⌐ ⌐      WHITE ANTS SYSTEMHOUSE BV  |
  15. |         ⌐  ⌐⌐⌐⌐⌐⌐⌐ ⌐⌐⌐ ⌐⌐⌐ ⌐⌐ ⌐       ⌐⌐⌐⌐      Geleen 12                  |
  16. |         ⌐ ⌐⌐⌐⌐⌐⌐⌐    ⌐   ⌐⌐   ⌐⌐⌐       ⌐       8032 GB Zwolle             |
  17. |           ⌐⌐⌐⌐⌐⌐     ⌐            ⌐ ⌐           Netherlands                |
  18. |      ⌐⌐⌐  ⌐⌐⌐⌐⌐      ⌐     ⌐⌐     ⌐  ⌐                                     |
  19. |            ⌐⌐       ⌐              ⌐  ⌐⌐⌐ ⌐     Tel. +31 38 453 86 31      |
  20. |      ⌐              ⌐              ⌐            Fax. +31 38 453 41 22      |
  21. |      ⌐             ⌐               ⌐⌐                                      |
  22. |    ⌐              ⌐                  ⌐⌐         www.whiteants.com          |
  23. |  ⌐⌐              ⌐                     ⌐ ⌐      support@whiteants.com      |
  24. |                 ⌐                                                          |
  25. +----------------------------------------------------------------------------+
  26.   file     : StrUtils
  27.   version  : 1.0
  28.   comment  : Part of this file was taken form S_STRING.PAS by RAY LISCHNER
  29.              Book: Secrets of Delphi 2.0
  30.   author   : G. Beuze, R. Post, L. Laarhoven, R. Lischner
  31.   compiler : Delphi 1.0, partly Delphi 2.0
  32. +----------------------------------------------------------------------------+
  33. | DISCLAIMER:                                                                |
  34. | THIS SOURCE IS FREEWARE. YOU ARE ALLOWED TO USE IT IN YOUR OWN PROJECTS    |
  35. | WITHOUT ANY RESTRICTIONS. YOU ARE NOT ALLOWED TO SELL THE SOURCE CODE.     |
  36. | THERE IS NO WARRANTY AT ALL - YOU USE IT ON YOUR OWN RISC. WHITE ANTS DOES |
  37. | NOT ASSUME ANY RESPONSIBILITY FOR ANY DAMAGE OR ANY LOSS OF TIME OR MONEY  |
  38. | DUE THE USE OF ANY PART OF THIS SOURCE CODE.                               |
  39. +----------------------------------------------------------------------------+
  40. }
  41. unit StrUtils;
  42.  
  43. interface
  44.  
  45. { Convert a Pascal string to a PChar. }
  46. function StrToPChar(const Str: string): PChar;
  47.  
  48. { Delimiters use by XXXToBinaryStr procedures }
  49. const
  50.   NibbleDelimiter : Char = '.';
  51.   ByteDelimiter : Char = ' ';
  52.  
  53. {$IFNDEF WIN32}
  54. type
  55.   ShortString = string;
  56.   PShortString = ^ShortString;
  57.   AnsiChar = Char;
  58.   PAnsiChar = ^AnsiChar;
  59.  
  60. { Set the length of string, Str, to Length. }
  61. procedure SetLength(var Str: string; Length: Byte);
  62.  
  63. { Set the contents of string Str, to Length bytes, starting at From. }
  64. procedure SetString(var Str: string; From: PChar; Length: Byte);
  65.  
  66. { Copy and return Str, after trimming leading and trailing white space
  67.   characters. Do not modify Str. }
  68. function Trim(const Str: string): string;
  69.  
  70. { Copy and return Str, after trimming leading white space
  71.   characters. Do not modify Str. }
  72. function TrimLeft(const Str: string): string;
  73.  
  74. { Copy and return Str, after trimming trailing white space
  75.   characters. Do not modify Str. }
  76. function TrimRight(const Str: string): string;
  77. {$ENDIF}
  78.  
  79. function DelChars(const Str: string; C: Char): string;
  80.   { Removes any character C from S }
  81.  
  82. function DelWhiteSpace(const Str: string): string;
  83.   { Removes any characters #0..#32 from Str }
  84.  
  85. function DelLeftChars(const Str: string; C: Char): string;
  86.   { Removes any leading character C from S }
  87.  
  88. function DelRightChars(const Str: string; C: Char): string;
  89.   { Removes any trailing character C from S }
  90.  
  91. function DelLeftRightChars(const Str: string; C: Char): string;
  92.   { Removes any leading and trailing character C from S }
  93.  
  94. function CharString(C: Char; Cnt: Byte): string;
  95.   { Returns a string of length (Cnt), filled with C }
  96.  
  97. function BlankString(Cnt: Byte): string;
  98.   { Returns a string a Cnt blanks }
  99.  
  100. function LeadCharsCnt(const S: string; C: Char): Byte;
  101.   { Returns number of leading chars C }
  102.  
  103. function LeadBlanksCnt(const S: string): Byte;
  104.   { Returns number of leading blanks }
  105.  
  106. function LeadTabCnt(const S: string): Byte;
  107.   { Returns number of leading tabs }
  108.  
  109. function AbbrStr(const Source: string; MaxLen: Byte): string;
  110.   { Returns a string with length <= MaxLen. Abbreviating on words }
  111.  
  112. function MixedCase(const Str: string): string;
  113.   { Returns S in lower case except the first char which is upper:
  114.     'example' -> 'Example', 'EXAMPLE' -> 'Example' }
  115.  
  116. function StringValue(S: PString): string;
  117.   { Returns S^ or '' if s = nil }
  118.  
  119. function ByteToBCD(a: Byte): Byte;
  120.   { Returns BCD coded representation of a }
  121.  
  122. function BCDtoByte(a : Byte) : Byte;
  123.   { Returns Byte value of BCD coded byte a }
  124.  
  125. function ByteToBinaryStr(B: Byte): string;
  126.   { Returns '0001.1100' style string, with . defined by NibbleDelimiter const }
  127.  
  128. function WordToBinaryStr(W: Word): string;
  129.   { Returns '00011100|00011100' style string,
  130.     with | defined by ByteDelimiter const, See NibbleDelimiter }
  131.  
  132. function LongToBinaryStr(L: LongInt): string;
  133.   { Returns '00011100|00011100|00011100|00011100' style string, see Delimiters }
  134.  
  135. function MatchStrings(const Source, Pattern: string): Boolean;
  136.   { Returns True if Source matches Pattern '*Example?*' etc }
  137.   {  Orignal code by Sean Stanley in C, Rewritten in Delphi by David Stidolph }
  138.  
  139. function StrToFloatDef(const Str: string; DefValue: Extended): Extended;
  140.   { Converts S to extended, on exception returns DefValue }
  141.  
  142. function GetTemplate(const Str: string): string;
  143.   { Returns 'template' as in TEMPLATE0001 }
  144.  
  145. function GetIndex(const Str: string): Integer;
  146.   { Returns Index = 1 as in TEMPLATE0001 }
  147.  
  148. function GetTemplateAndIndex(const Str: string; var Template: string;
  149.                              var Index: Integer): Boolean;
  150.   { Returns True if a number was found to the right of Str
  151.     for example as in 'Button123'. Returns Button in Template and 123 in Index
  152.     Returns False if no number was found }
  153.  
  154. function GetName(const S: string): string;
  155.   { Returns Name as iN: Name=Value , or '' if no = was found }
  156.  
  157. function GetValue(const S: string): string;
  158.   { Returns Value as in: Name=Value , or '' if no = was found }
  159.  
  160. function GetNameAndValue(const S: string; var Name, Value: string): Boolean;
  161.   { Returns True is S could be split in name and value as in Name=Value, else False }
  162.  
  163. implementation
  164.  
  165. {$IFDEF WIN32}
  166. { Delphi 2.0 knows how to convert string to PChar. }
  167. function StrToPChar(const Str: string): PChar;
  168. begin
  169.   Result := PChar(Str);
  170. end;
  171.  
  172. {$ELSE}
  173. uses SysUtils;
  174.  
  175. { Return a PChar representation of the string, Str. Allocate a dynamic
  176.   copy of the string. Keep a ring of 8 dynamic strings, and free the
  177.   old strings. Thus, you can usually rely on the returned string being
  178.   valid while it is needed. The most common need is to pass an argument
  179.   to a Windows API function, so the need is temporary, but several
  180.   such strings might be required. That's why the ring has 8 items in it:
  181.   more than enough for most uses. }
  182. type
  183.   TRingIndex = 0..7;
  184. var
  185.   Ring: array[TRingIndex] of PChar;
  186.   RingIndex: TRingIndex;
  187.  
  188. function StrToPChar(const Str: string): PChar;
  189. begin
  190.   { Allocate a PChar and copy the original string. }
  191.   Result := StrAlloc(Length(Str)+1);
  192.   StrPCopy(Result, Str);
  193.  
  194.   { Add the string to the ring. }
  195.   StrDispose(Ring[RingIndex]);
  196.   Ring[RingIndex] := Result;
  197.   RingIndex := (RingIndex + 1) mod (High(TRingIndex) + 1);
  198. end;
  199.  
  200. { Set the length of a string. }
  201. procedure SetLength(var Str: string; Length: Byte);
  202. begin
  203.   Str[0] := Chr(Length)
  204. end;
  205.  
  206. { Set the contents of a string. If there are fewer than Length bytes
  207.   in the string, From, then leave the remaining bytes unchanged. }
  208. procedure SetString(var Str: string; From: PChar; Length: Byte);
  209. var
  210.   FromLen: Integer;
  211. begin
  212.   Str[0] := Chr(Length);
  213.   { In Delphi 2.0, a nil pointer represents an empty string. The representation
  214.     should be hidden by the compiler, but some people use an explicit nil
  215.     pointer to mean an empty string. This is sloppy programming, but some
  216.     people do it anyway. }
  217.   if From <> nil then
  218.   begin
  219.     { Only copy as many bytes as are in the From string. }
  220.     FromLen := StrLen(From);
  221.     if FromLen < Length then
  222.       Length := FromLen;
  223.     Move(From^, Str[1], Length);
  224.   end;
  225. end;
  226.  
  227. { Return whether the character C, is a white space character,
  228.   or a nonprintable control character. }
  229. function IsWhiteSpace(C: Char): Boolean;
  230. begin
  231.   Result := C in [#0..' ']
  232. end;
  233.  
  234. { Trim all leading and trailing white space characters. }
  235. function Trim(const Str: string): string;
  236. var
  237.   L, R: Integer;
  238. begin
  239.   L := 1;
  240.   R := Length(Str);
  241.   while (L <= R) and IsWhiteSpace(Str[L]) do
  242.     Inc(L);
  243.   while (L <= R) and IsWhiteSpace(Str[R]) do
  244.     Dec(R);
  245.   Result := Copy(Str, L, R-L+1);
  246. end;
  247.  
  248. { Trim leading white space characters. }
  249. function TrimLeft(const Str: string): string;
  250. var
  251.   L, R: Integer;
  252. begin
  253.   L := 1;
  254.   R := Length(Str);
  255.   while (L <= R) and IsWhiteSpace(Str[L]) do
  256.     Inc(L);
  257.   Result := Copy(Str, L, 255);
  258. end;
  259.  
  260. { Trim trailing white space characters. }
  261. function TrimRight(const Str: string): string;
  262. var
  263.   R: Integer;
  264. begin
  265.   R := Length(Str);
  266.   while (R >= 1) and IsWhiteSpace(Str[R]) do
  267.     Dec(R);
  268.   Result := Copy(Str, 1, R);
  269. end;
  270. {$ENDIF}
  271.  
  272. function DelChars(const Str: string; C: Char): string;
  273. var I: Integer;
  274. begin
  275.   Result := '';
  276.   for I := 1 to Length(Str) do
  277.     if Str[I] <> C then
  278.       Result := Result + Str[I];
  279. end;
  280.  
  281. function DelWhiteSpace(const Str: string): string;
  282. var I: Integer;
  283. begin
  284.   Result := '';
  285.   for I := 1 to Length(Str) do
  286.     if not IsWhiteSpace(Str[I]) then
  287.       Result := Result + Str[I];
  288. end;
  289.  
  290. function DelLeftChars(const Str: string; C: Char): string;
  291. var
  292.   L, R: Integer;
  293. begin
  294.   L := 1;
  295.   R := Length(Str);
  296.   while (L <= R) and (Str[L] = C) do
  297.     Inc(L);
  298.   Result := Copy(Str, L, 255);
  299. end;
  300.  
  301. function DelRightChars(const Str: string; C: Char): string;
  302. var
  303.   R: Integer;
  304. begin
  305.   R := Length(Str);
  306.   while (R >= 1) and (Str[R] = C) do
  307.     Dec(R);
  308.   Result := Copy(Str, 1, R);
  309. end;
  310.  
  311. function DelLeftRightChars(const Str: string; C: Char): string;
  312. var
  313.   L, R: Integer;
  314. begin
  315.   L := 1;
  316.   R := Length(Str);
  317.   while (L <= R) and (Str[L] = C) do
  318.     Inc(L);
  319.   while (L <= R) and (Str[R] = C) do
  320.     Dec(R);
  321.   Result := Copy(Str, L, R-L+1);
  322. end;
  323.  
  324. function CharString(C: Char; Cnt: Byte): string;
  325. begin
  326.   FillChar(Result, SizeOf(Result), C);
  327.   Result[0] := Chr(Cnt);
  328. end;
  329.  
  330. function BlankString(Cnt: Byte): String;
  331. begin
  332.   Result := CharString(#32, Cnt);
  333. end;
  334.  
  335. function LeadCharsCnt(const S: string; C: Char): Byte;
  336. var I : Integer;
  337. begin
  338.   Result := 0;
  339.   for I := 1 to Length(S) do
  340.     if S[I] <> C then
  341.     begin
  342.       Result := I - 1;
  343.       Exit;
  344.     end;
  345.   Result := Length(S);
  346. end;
  347.  
  348. function LeadBlanksCnt(const S: string): Byte;
  349. begin
  350.   Result := LeadCharsCnt(S, ' ');
  351. end;
  352.  
  353. function LeadTabCnt(const S: string): Byte;
  354. begin
  355.   Result := LeadCharsCnt(S, #9);
  356. end;
  357.  
  358. function AbbrStr(const Source: string; MaxLen: Byte): string;
  359. begin
  360.   if Length(Source) > MaxLen then
  361.   begin
  362.     Result := Copy(Source, 1, MaxLen);
  363.     if (Source[MaxLen] <> ' ') and (Source[MaxLen + 1] <> ' ') then
  364.     if MaxLen > 1 then
  365.     begin
  366.       Result[MaxLen] := '.';
  367.       Result[MaxLen - 1] := '.';
  368.     end;
  369.   end
  370.   else
  371.     Result := Source;
  372. end;
  373.  
  374. function MixedCase(const Str: string): string;
  375. begin
  376.   Result := LowerCase(Str);
  377.   if Length(Result) > 0 then Result[1] := Upcase(Result[1]);
  378. end;
  379.  
  380. function StringValue(S: PString): string;
  381. begin
  382.   if Assigned(S) then
  383.     Result := S^
  384.   else
  385.     Result := '';
  386. end;
  387.  
  388. function ByteToBCD(A: Byte): Byte;
  389. var Decs, Units : Byte;
  390. begin
  391.   if A <= 99  then
  392.   begin
  393.     Decs := A div 10;
  394.     Units := A mod 10;
  395.     Result := (Decs shl 4) or Units;
  396.   end
  397.   else
  398.     Result := A;
  399. end;
  400.  
  401. function BCDtoByte(a : Byte) : Byte;
  402. begin
  403.   if (A >= $A0) or ((A and $0F) > $09) then
  404.     Result := A
  405.   else
  406.     Result := ((A SHR 4) and $0F ) * 10 + (A and $0F);
  407. end;
  408.  
  409. function ByteToBinaryStr(B: Byte): string;
  410. var
  411.   I : Integer;
  412. begin
  413.   Result := '';
  414.   for I := 7 downto 0 do
  415.   begin
  416.     if I = 3 then Result := Result + NibbleDelimiter;
  417.     if ((B SHR i) AND $1) = 0 then
  418.       Result := Result + '0'
  419.     else
  420.       Result := Result + '1';
  421.   end;
  422. end;
  423.  
  424. function WordToBinaryStr(W: Word): string;
  425. begin
  426.   Result := ByteToBinaryStr(WordRec(W).Hi) + ByteDelimiter +
  427.             ByteToBinaryStr(WordRec(W).Lo);
  428. end;
  429.  
  430. function LongToBinaryStr(L: LongInt): string;
  431. begin
  432.   Result := WordToBinaryStr(LongRec(L).Hi) + ByteDelimiter +
  433.             WordToBinaryStr(LongRec(L).Lo);
  434. end;
  435.  
  436.  
  437. {-------------------------------------------------------------------------}
  438. {
  439.   This function takes two strings and compares them.  The first string
  440.   can be anything, but should not contain pattern characters (* or ?).
  441.   The pattern string can have as many of these pattern characters as you want.
  442.   For example: MatchStrings('David Stidolph','*St*') would return True.
  443.  
  444.   Orignal code by Sean Stanley in C
  445.   Rewritten in Delphi by David Stidolph
  446. }
  447. {-------------------------------------------------------------------------}
  448. function MatchStrings(const Source, Pattern: string): Boolean;
  449. var
  450.   pSource: Array [0..255] of Char;
  451.   pPattern: Array [0..255] of Char;
  452.  
  453.   function MatchPattern(Element, Pattern: PChar): Boolean;
  454.  
  455.     function IsPatternWild(Pattern: PChar): Boolean;
  456.     var
  457.       T: Integer;
  458.     begin
  459.       Result := StrScan(Pattern,'*') <> nil;
  460.       if not Result then Result := StrScan(Pattern,'?') <> nil;
  461.     end;
  462.  
  463.   begin
  464.     if 0 = StrComp(Pattern,'*') then
  465.       Result := True
  466.     else if (Element^ = Chr(0)) and (Pattern^ <> Chr(0)) then
  467.       Result := False
  468.     else if Element^ = Chr(0) then
  469.       Result := True
  470.     else begin
  471.       case Pattern^ of
  472.       '*': if MatchPattern(Element,@Pattern[1]) then
  473.              Result := True
  474.            else
  475.              Result := MatchPattern(@Element[1], Pattern);
  476.       '?': Result := MatchPattern(@Element[1], @Pattern[1]);
  477.       else
  478.         if Element^ = Pattern^ then
  479.           Result := MatchPattern(@Element[1], @Pattern[1])
  480.         else
  481.           Result := False;
  482.       end;
  483.     end;
  484.   end;
  485.  
  486. begin
  487.   StrPCopy(pSource, Source);
  488.   StrPCopy(pPattern, Pattern);
  489.   Result := MatchPattern(pSource,pPattern);
  490. end;
  491.  
  492. function StrToFloatDef(const Str: string; DefValue: Extended): Extended;
  493. begin
  494.   try
  495.     Result := StrToFloat(Str);
  496.   except
  497.     Result := DefValue;
  498.   end;
  499. end;
  500.  
  501. const
  502.   Numbers: set of Char = ['0'..'9'];
  503.  
  504. function GetTemplate(const Str: string): string;
  505. var Index: Integer;
  506. begin
  507.   GetTemplateAndIndex(Str, Result, Index);
  508. end;
  509.  
  510. function GetIndex(const Str: string): Integer;
  511. var Template: string;
  512. begin
  513.   GetTemplateAndIndex(Str, Template, Result);
  514. end;
  515.  
  516. function GetTemplateAndIndex(const Str: string; var Template: string;
  517.                              var Index: Integer): Boolean;
  518. var R: Integer;
  519. begin
  520.   R := Length(Str);
  521.   while (R > 0) and (Str[R] in Numbers) do Dec(R);
  522.   Result := R < Length(Str);
  523.   if Result then
  524.   begin
  525.     Template := Copy(Str, 1, R);
  526.     Index := StrToInt(Copy(Str, R+1, 255));
  527.   end
  528.   else
  529.   begin
  530.     Index := -1;
  531.     Template := Str;
  532.   end;
  533. end;
  534.  
  535. function GetName(const S: string): string;
  536. var P: Integer;
  537. begin
  538.   P := Pos('=', S);
  539.   if P > 0 then
  540.     Result := Copy(S, 1, P - 1)
  541.   else
  542.     Result := '';
  543. end;
  544.  
  545. function GetValue(const S: string): string;
  546. var P: Integer;
  547. begin
  548.   P := Pos('=', S);
  549.   if P > 0 then
  550.     Result := Copy(S, P + 1, 255)
  551.   else
  552.     Result := '';
  553. end;
  554.  
  555. function GetNameAndValue(const S: string; var Name, Value: string): Boolean;
  556. var P: Integer;
  557. begin
  558.   P := Pos('=', S);
  559.   Result := P > 0;
  560.   if Result then
  561.   begin
  562.     Name := Copy(S, 1, P - 1);
  563.     Value := Copy(S, P + 1, 255);
  564.   end
  565.   else
  566.   begin
  567.     Name := '';
  568.     Value := '';
  569.   end;
  570. end;
  571.  
  572. {$IFNDEF WIN32}
  573. { Free all the left over strings in the StrToPChar ring. }
  574. procedure Terminate; far;
  575. var
  576.   I: TRingIndex;
  577. begin
  578.   for I := Low(TRingIndex) to High(TRingIndex) do
  579.   begin
  580.     StrDispose(Ring[I]);
  581.     Ring[I] := nil; { just in case StrToPChar is called again }
  582.   end;
  583. end;
  584.  
  585.  
  586. initialization
  587.   AddExitProc(Terminate);
  588. {$ENDIF}
  589. end.
  590.