Ignore:
Timestamp:
Apr 25, 2007, 10:26:44 AM (18 years ago)
Author:
RBRi
Message:

AnsiString functins added

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/NewView/StringUtilsUnit.pas

    r106 r110  
    55// This software is released under the GNU Public License - see readme.txt
    66
    7 // Helper functions to work with strings
     7// Helper functions to work with String and AnsiString
    88
    99Interface
    1010
    1111uses
    12  Classes;
     12  Classes,
     13  CharUtilsUnit;
    1314
    1415const
    15   StrTAB = chr(9);
    16   StrCR = chr(13);
    17   StrLF = chr(10);
     16  StrTAB = CharTAB;
     17  StrCR = CharCR;
     18  StrLF = CharLF;
    1819  StrCRLF = StrCR + StrLF;
    1920  StrSingleQuote = '''';
     
    3637  end;
    3738
    38   TYPE
    39     TSetOfChars = set of char;
    40 
    4139  // prefices all occurences of one of the chars in aStringWithChars with anEscape char
    4240  // if the escapeChar itself is found, then it is doubled
     
    110108  // use double quotes if you need blanks in the strings
    111109  Procedure StrExtractStringsQuoted(Var aResult: TStrings; const aReceiver: String );
     110
     111
     112  // returns the position of aPart in aString
     113  // case insensitive
     114  Function CaseInsensitivePos(const aPart: String; const aString: String ): longint;
     115
     116  // --------------------
     117  // ---- AnsiString ----
     118  // --------------------
     119
     120 
     121  // removes all occurences of char from aSetOfChars from the beginning
     122  // of a String.
     123  Function AnsiStrTrimLeftChars(const aReceiver: AnsiString; const aSetOfChars: TSetOfChars): AnsiString;
     124
     125  // removes all occurences of char from aSetOfChars from the end
     126  // of a String.
     127  Function AnsiStrTrimRightChars(const aReceiver: AnsiString; const aSetOfChars: TSetOfChars): AnsiString;
     128
     129  // removes all occurences of char from aSetOfChars from the beginning
     130  // end the end of a String.
     131  Function AnsiStrTrimChars(const aReceiver: AnsiString; const aSetOfChars: TSetOfChars): AnsiString;
     132
     133  // removes all blanks from beginning and end
     134  Function AnsiStrTrim(const aReceiver: AnsiString): AnsiString;
     135
     136
     137
    112138
    113139Implementation
     
    270296  Function StrTrimLeftChars(const aReceiver: String; const aSetOfChars: TSetOfChars): String;
    271297  Var
    272     i : Longint;
    273   Begin
     298    tmpLength : integer;
     299    i : integer;
     300  Begin
     301    tmpLength := Length(aReceiver);
     302
     303    if 1 > tmpLength then
     304    begin
     305      result := aReceiver;
     306      exit;
     307    end;
     308
    274309    i := 1;
    275310    // mem optimization
    276311    if aReceiver[i] in aSetOfChars then
    277312    begin
    278       while i <= Length(aReceiver) do
     313      while i <= tmpLength do
    279314      begin
    280315        if aReceiver[i] in aSetOfChars then
     
    294329  Function StrTrimRightChars(const aReceiver: String; const aSetOfChars: TSetOfChars): String;
    295330  Var
    296     i : Longint;
     331    i : integer;
    297332  Begin
    298333    i := Length(aReceiver);
     334
     335    if 1 > i then
     336    begin
     337      result := aReceiver;
     338      exit;
     339    end;
    299340
    300341    // mem optimization
     
    319360  Function StrTrimChars(const aReceiver: String; const aSetOfChars: TSetOfChars): String;
    320361  Var
    321     i : Longint;
    322     j : Longint;
     362    i,j : integer;
    323363    tmpNeedCopy : boolean;
    324364  Begin
     365    j := Length(aReceiver);
     366
     367    if 1 > j then
     368    begin
     369      result := aReceiver;
     370      exit;
     371    end;
     372
    325373    tmpNeedCopy := false;
    326374    i := 1;
    327     while i < Length(aReceiver) do
     375    while i < j do
    328376    begin
    329377      if aReceiver[i] in aSetOfChars then
     
    338386    end;
    339387
    340     j := Length(aReceiver);
    341388    while j >= i do
    342389    begin
     
    701748    end;
    702749  end;
     750
     751
     752  Function CaseInsensitivePos(const aPart: String; const aString: String) : longint;
     753  Var
     754    EndOfPart: longword;
     755  Begin
     756    // Result := Pos(UpperCase(aPart), Uppercase(aString));
     757
     758    // Aarons assembler version :-)
     759    Asm
     760    //Locals:
     761    //a at [EBP+12]
     762    //b at [EBP+8]
     763
     764    // First get and check lengths
     765    MOV   ESI, aPart     // get address of aPart into ESI
     766    MOV   CL,  [ESI]     // get length of aPart
     767    CMP   CL, 0          // if aPart is empty then return null to simulate the behavior of POS
     768    JE    !CIP_NoMatch
     769
     770    MOV   EDI, aString   // get address of aString into EDI
     771    MOV   DL,  [EDI]     // get length of aString
     772    CMP   CL,  DL
     773    JBE   !CIP_PartFitsInString
     774
     775    // aParta longer than aString so aPart can't be in aString
     776
     777    !CIP_NoMatch:
     778      MOV   EAX, 0
     779      LEAVE
     780      RETN32 8
     781
     782    !CIP_PartFitsInString:
     783      INC   ESI            // skip length byte in aPart
     784      INC   EDI            // skip length byte of aString
     785
     786    // get ending address of b into EDX
     787      MOVZX EDX, DL        // widen DL
     788      ADD   EDX, EDI       // add start of aString
     789
     790    // get ending address of a into EndOfA
     791      MOVZX ECX, CL        // widen CL
     792      ADD   ECX, ESI       // add start of aPart
     793      MOV   EndOfPart, ECX    // store to EndOfPart
     794
     795      MOV   ECX, EDI       // set start of current match to start of b
     796
     797      // ESI: current search point in a
     798      // EDI: current search point in b
     799      // EDX: end of b
     800      // ECX: start of current match
     801      // available: eax, ebx
     802
     803      JMP   !CIP_Loop
     804
     805    !CIP_LoopStart:
     806      CMP   EDI, EDX
     807      JE    !CIP_NoMatch   // run out of b
     808
     809      MOV   AL,  [ESI]     // get next char of a
     810      INC   ESI            // next in a
     811
     812      MOV   BL,  [EDI]     // get next char of b
     813      INC   EDI            // next in b
     814
     815    // Convert chars to uppercase
     816      CMP   AL,  97
     817      JB    !CIP_Upcase1
     818      CMP   AL,  122
     819      JA    !CIP_Upcase1
     820      SUB   AL,  32         // convert lower to upper
     821    !CIP_Upcase1:
     822
     823      CMP   BL,97
     824      JB    !CIP_Upcase2
     825      CMP   BL,122
     826      JA    !CIP_Upcase2
     827      SUB   BL,32          // convert lower to upper
     828    !CIP_Upcase2:
     829
     830    // Compare uppercased chars
     831      CMP   AL,BL
     832      JE    !CIP_Loop
     833
     834    // different.
     835
     836    // Back to start of match + 1
     837      INC   ECX            // inc start of match
     838      MOV   EDI, ECX       // back to start of match in b
     839      MOV   ESI, aPart     // back to start of aPart
     840      INC   ESI            // skip length
     841      JMP   !CIP_LoopStart
     842
     843    !CIP_Loop:
     844
     845    // same
     846      CMP   ESI, EndOfPart    // have we reached the end of a
     847      JB    !CIP_LoopStart
     848
     849      // Match, return position
     850      SUB   ECX, [EBP+8]   // position = ( start of match ) - ( start of b ) + 1
     851      MOV   EAX, ECX
     852      LEAVE
     853      RETN32 8
     854    end;
     855  end;
     856
     857
     858  // --------------------
     859  // ---- AnsiString ----
     860  // --------------------
     861
     862
     863  Function AnsiStrTrimLeftChars(const aReceiver: AnsiString; const aSetOfChars: TSetOfChars): AnsiString;
     864  Var
     865    tmpLength : integer;
     866    i : integer;
     867  Begin
     868    tmpLength := Length(aReceiver);
     869
     870    if 1 > tmpLength then
     871    begin
     872      result := aReceiver;
     873      exit;
     874    end;
     875
     876    i := 1;
     877    // mem optimization
     878    if aReceiver[i] in aSetOfChars then
     879    begin
     880      while i <= tmpLength do
     881      begin
     882        if aReceiver[i] in aSetOfChars then
     883          inc(i)
     884        else
     885          break;
     886      end;
     887      result := AnsiCopy(aReceiver, i, Length(aReceiver)-i+1);
     888    end
     889    else
     890    begin
     891      result := aReceiver;
     892    end;
     893  end;
     894
     895
     896  Function AnsiStrTrimRightChars(const aReceiver: AnsiString; const aSetOfChars: TSetOfChars): AnsiString;
     897  Var
     898    i : integer;
     899  Begin
     900    i := Length(aReceiver);
     901
     902    if 1 > i then
     903    begin
     904      result := aReceiver;
     905      exit;
     906    end;
     907
     908    // mem optimization
     909    if aReceiver[i] in aSetOfChars then
     910    begin
     911      while i > 0 do
     912      begin
     913        if aReceiver[i] in aSetOfChars then
     914          dec(i)
     915        else
     916          break;
     917      end;
     918      result := AnsiCopy(aReceiver, 1, i);
     919    end
     920    else
     921    begin
     922      result := aReceiver;
     923    end;
     924  end;
     925
     926
     927  Function AnsiStrTrimChars(const aReceiver: AnsiString; const aSetOfChars: TSetOfChars): AnsiString;
     928  Var
     929    i,j : integer;
     930    tmpNeedCopy : boolean;
     931  Begin
     932    tmpNeedCopy := false;
     933
     934    j := Length(aReceiver);
     935
     936    if 1 > j then
     937    begin
     938      result := aReceiver;
     939      exit;
     940    end;
     941
     942    i := 1;
     943    while i < j do
     944    begin
     945      if aReceiver[i] in aSetOfChars then
     946      begin
     947        inc(i);
     948        tmpNeedCopy := true;
     949      end
     950      else
     951      begin
     952        break;
     953      end;
     954    end;
     955
     956    while j >= i do
     957    begin
     958      if aReceiver[j] in aSetOfChars then
     959      begin
     960        dec(j);
     961        tmpNeedCopy := true;
     962      end
     963      else
     964      begin
     965        break;
     966      end;
     967    end;
     968
     969    if tmpNeedCopy then
     970    begin
     971      result := AnsiCopy(aReceiver, i, j-i+1);
     972    end
     973    else
     974    begin
     975      result := aReceiver;
     976    end;
     977  end;
     978
     979
     980  Function AnsiStrTrim(const aReceiver: AnsiString): AnsiString;
     981  Begin
     982    result := AnsiStrTrimChars(aReceiver, [' ']);
     983  end;
     984
     985
    703986END.
Note: See TracChangeset for help on using the changeset viewer.