Changeset 110 for trunk/NewView/StringUtilsUnit.pas
- Timestamp:
- Apr 25, 2007, 10:26:44 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/NewView/StringUtilsUnit.pas
r106 r110 5 5 // This software is released under the GNU Public License - see readme.txt 6 6 7 // Helper functions to work with strings7 // Helper functions to work with String and AnsiString 8 8 9 9 Interface 10 10 11 11 uses 12 Classes; 12 Classes, 13 CharUtilsUnit; 13 14 14 15 const 15 StrTAB = chr(9);16 StrCR = chr(13);17 StrLF = chr(10);16 StrTAB = CharTAB; 17 StrCR = CharCR; 18 StrLF = CharLF; 18 19 StrCRLF = StrCR + StrLF; 19 20 StrSingleQuote = ''''; … … 36 37 end; 37 38 38 TYPE39 TSetOfChars = set of char;40 41 39 // prefices all occurences of one of the chars in aStringWithChars with anEscape char 42 40 // if the escapeChar itself is found, then it is doubled … … 110 108 // use double quotes if you need blanks in the strings 111 109 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 112 138 113 139 Implementation … … 270 296 Function StrTrimLeftChars(const aReceiver: String; const aSetOfChars: TSetOfChars): String; 271 297 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 274 309 i := 1; 275 310 // mem optimization 276 311 if aReceiver[i] in aSetOfChars then 277 312 begin 278 while i <= Length(aReceiver)do313 while i <= tmpLength do 279 314 begin 280 315 if aReceiver[i] in aSetOfChars then … … 294 329 Function StrTrimRightChars(const aReceiver: String; const aSetOfChars: TSetOfChars): String; 295 330 Var 296 i : Longint;331 i : integer; 297 332 Begin 298 333 i := Length(aReceiver); 334 335 if 1 > i then 336 begin 337 result := aReceiver; 338 exit; 339 end; 299 340 300 341 // mem optimization … … 319 360 Function StrTrimChars(const aReceiver: String; const aSetOfChars: TSetOfChars): String; 320 361 Var 321 i : Longint; 322 j : Longint; 362 i,j : integer; 323 363 tmpNeedCopy : boolean; 324 364 Begin 365 j := Length(aReceiver); 366 367 if 1 > j then 368 begin 369 result := aReceiver; 370 exit; 371 end; 372 325 373 tmpNeedCopy := false; 326 374 i := 1; 327 while i < Length(aReceiver)do375 while i < j do 328 376 begin 329 377 if aReceiver[i] in aSetOfChars then … … 338 386 end; 339 387 340 j := Length(aReceiver);341 388 while j >= i do 342 389 begin … … 701 748 end; 702 749 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 703 986 END.
Note:
See TracChangeset
for help on using the changeset viewer.