?? jclstrings.pas
字號:
end;//--------------------------------------------------------------------------------------------------function StrRefCount(const S: AnsiString): Longint;var P: Pointer;begin Result := 0; if Pointer(S) <> nil then begin P := Pointer(Integer(Pointer(S)) - AnsiRfOffset); Result := Integer(P^); end;end;//--------------------------------------------------------------------------------------------------procedure StrResetLength(var S: AnsiString);begin SetLength(S, StrLen(PChar(S)));end;//==================================================================================================// String Search and Replaces Routines//==================================================================================================function StrCharCount(const S: AnsiString; C: AnsiChar): Integer;var I: Integer;begin Result := 0; for I := 1 to Length(S) do if S[I] = C then Inc(Result);end;//--------------------------------------------------------------------------------------------------function StrCharsCount(const S: AnsiString; Chars: TSysCharSet): Integer;var I: Integer;begin Result := 0; for I := 1 to Length(S) do if S[I] in Chars then Inc(Result);end;//--------------------------------------------------------------------------------------------------function StrStrCount(const S, SubS: AnsiString): Integer;var I: Integer;begin Result := 0; if (Length(SubS) > Length(S)) or (Length(SubS) = 0) or (Length(S) = 0) then Exit; if Length(SubS) = 1 then begin Result := StrCharCount(S, SubS[1]); Exit; end; I := StrSearch(SubS, S, 1); if I > 0 then Inc(Result); while (I > 0) and (Length(S) > I+Length(SubS)) do begin I := StrSearch(SubS, S, I+1); if I > 0 then Inc(Result); endend;//--------------------------------------------------------------------------------------------------function StrCompare(const S1, S2: AnsiString): Integer; assembler;asm // check if pointers are equal CMP EAX, EDX JE @@Equal // if S1 is nil return - Length(S2) TEST EAX, EAX JZ @@Str1Null // if S2 is nill return Length(S1) TEST EDX, EDX JZ @@Str2Null // EBX will hold case map, ESI S1, EDI S2 PUSH EBX PUSH ESI PUSH EDI // move AnsiString pointers MOV ESI, EAX MOV EDI, EDX // get the length of strings MOV EAX, [ESI-AnsiStrRecSize].TAnsiStrRec.Length MOV EDX, [EDI-AnsiStrRecSize].TAnsiStrRec.Length // exit if Length(S1) <> Length(S2) CMP EAX, EDX JNE @@MissMatch // check the length just in case DEC EDX JS @@InvalidStr DEC EAX JS @@InvalidStr // load case map LEA EBX, AnsiCaseMap // make ECX our loop counter MOV ECX, EAX // clear working regs XOR EAX, EAX XOR EDX, EDX // get last chars MOV AL, [ESI+ECX] MOV DL, [EDI+ECX] // lower case them MOV AL, [EBX+EAX] MOV DL, [EBX+EDX] // compare them CMP AL, DL JNE @@MissMatch // if there was only 1 char then exit JECXZ @@Match@@NextChar: // case sensitive compare of strings REPE CMPSB JE @@Match // if there was a missmatch try case insensitive compare, get the chars MOV AL, [ESI-1] MOV DL, [EDI-1] // lowercase and compare them, if equal then continue MOV AL, [EBX+EAX] MOV DL, [EBX+EDX] CMP AL, DL JE @@NextChar // if we make it here then strings don't match, return the difference@@MissMatch: SUB EAX, EDX POP EDI POP ESI POP EBX RET@@Match: // match, return 0 XOR EAX, EAX POP EDI POP ESI POP EBX RET@@InvalidStr: XOR EAX, EAX DEC EAX POP EDI POP ESI POP EBX RET@@Str1Null: // return = - Length(Str2); MOV EDX, [EDX-AnsiStrRecSize].TAnsiStrRec.Length SUB EAX, EDX RET@@Str2Null: // return = Length(Str2); MOV EAX, [EAX-AnsiStrRecSize].TAnsiStrRec.Length RET@@Equal: XOR EAX, EAXend;//--------------------------------------------------------------------------------------------------function StrCompareRange(const S1, S2: AnsiString; const Index, Count: Integer): Integer; assembler;asm TEST EAX, EAX JZ @@Str1Null TEST EDX, EDX JZ @@StrNull DEC ECX JS @@StrNull PUSH EBX PUSH ESI PUSH EDI MOV EBX, Count DEC EBX JS @@NoWork MOV ESI, EAX MOV EDI, EDX MOV EDX, [ESI - AnsiStrRecSize].TAnsiStrRec.Length // # of chars in S1 - (Index - 1) SUB EDX, ECX JLE @@NoWork // # of chars in S1 - (Count - 1) SUB EDX, EBX JLE @@NoWork // move to index'th char ADD ESI, ECX MOV ECX, [EDI - AnsiStrRecSize].TAnsiStrRec.Length DEC ECX JS @@NoWork // if Length(S2) > Count then ECX := Count else ECX := Length(S2) CMP ECX, EBX JLE @@Skip1 MOV ECX, EBX@@Skip1: XOR EAX, EAX XOR EDX, EDX@@Loop: MOV AL, [ESI] INC ESI MOV DL, [EDI] INC EDI CMP AL, DL JNE @@MisMatch DEC ECX JGE @@Loop@@Match: XOR EAX, EAX POP EDI POP ESI POP EBX JMP @@Exit@@MisMatch: SUB EAX, EDX POP EDI POP ESI POP EBX JMP @@Exit@@NoWork: MOV EAX, -2 POP EDI POP ESI POP EBX JMP @@Exit@@Str1Null: MOV EAX, 0 TEST EDX, EDX JZ @@Exit@@StrNull: MOV EAX, -1@@Exit:end;//--------------------------------------------------------------------------------------------------function StrFillChar(const C: AnsiChar; const Count: Integer): AnsiString;begin Assert(Count >= 0); SetLength(Result, Count); if (Count > 0) then FillChar(Result[1], Count, Ord(C));end;//--------------------------------------------------------------------------------------------------function StrFind(const Substr, S: AnsiString; const Index: Integer): Integer; assembler;const SearchChar: Byte = 0; NumberOfChars: Integer = 0;asm // if SubStr = '' then Return := 0; TEST EAX, EAX JZ @@SubstrIsNull // if Str = '' then Return := 0; TEST EDX, EDX JZ @@StrIsNull // Index := Index - 1; if Index < 0 then Return := 0; DEC ECX JL @@IndexIsSmall // EBX will hold the case table, ESI pointer to Str, EDI pointer // to Substr and - # of chars in Substr to compare PUSH EBX PUSH ESI PUSH EDI // set the string pointers MOV ESI, EDX MOV EDI, EAX // save the Index in EDX MOV EDX, ECX // temporary get the length of Substr and Str MOV EBX, [EDI - AnsiStrRecSize].TAnsiStrRec.Length MOV ECX, [ESI - AnsiStrRecSize].TAnsiStrRec.Length // save the address of Str to compute the result PUSH ESI // dec the length of Substr because the first char is brought out of it DEC EBX JS @@NotFound // #positions in Str to look at = Length(Str) - Length(Substr) - Index - 2 SUB ECX, EBX JLE @@NotFound SUB ECX, EDX JLE @@NotFound // # of chars in Substr to compare MOV NumberOfChars, EBX // point Str to Index'th char ADD ESI, EDX // load case map into EBX, and clear EAX LEA EBX, AnsiCaseMap XOR EAX, EAX XOR EDX, EDX // bring the first char out of the Substr and point Substr to the next char MOV DL, [EDI] INC EDI // lower case it MOV DL, [EBX + EDX] MOV SearchChar, DL JMP @@Find@@FindNext: // update the loop counter and check the end of AnsiString. // if we reached the end, Substr was not found. DEC ECX JL @@NotFound@@Find: // get current char from the AnsiString, and point Str to the next one MOV AL, [ESI] INC ESI // lower case current char MOV AL, [EBX + EAX] // does current char match primary search char? if not, go back to the main loop CMP AL, SearchChar JNE @@FindNext@@Compare: // # of chars in Substr to compare MOV EDX, NumberOfChars@@CompareNext: // dec loop counter and check if we re
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -