📄 jclstrings.pas
字号:
end;//--------------------------------------------------------------------------------------------------// Uppercases or Lowercases a give AnsiString depending on the// passed offset. (UpOffset or LoOffset)procedure StrCase{(var Str: AnsiString; const Offset: Integer)}; assembler;asm // make sure that the string is not null TEST EAX, EAX JZ @@StrIsNull // create unique string if this one is ref-counted PUSH EDX CALL UniqueString POP EDX // make sure that the new string is not null TEST EAX, EAX JZ @@StrIsNull // get the length, and prepare the counter MOV ECX, [EAX - AnsiStrRecSize].TAnsiStrRec.Length DEC ECX JS @@StrIsNull // ebx will hold the case map, esi pointer to Str PUSH EBX PUSH ESI PUSH EDI // load case map and prepare variables } LEA EBX,[AnsiCaseMap + EDX] MOV ESI, EAX XOR EDX, EDX XOR EAX, EAX@@NextChar: // get current char from the AnsiString MOV DL, [ESI] // get corresponding char from the case map MOV AL, [EBX + EDX] // store it back in the string MOV [ESI], AL // update the loop counter and check the end of stirng DEC ECX JL @@Done // do the same thing with next 3 chars MOV DL, [ESI + 1] MOV AL, [EBX + EDX] MOV [ESI + 1], AL DEC ECX JL @@Done MOV DL, [ESI + 2] MOV AL, [EBX+EDX] MOV [ESI + 2], AL DEC ECX JL @@Done MOV DL, [ESI + 3] MOV AL, [EBX + EDX] MOV [ESI + 3], AL // point AnsiString to next 4 chars ADD ESI, 4 // update the loop counter and check the end of stirng DEC ECX JGE @@NextChar@@Done: POP EDI POP ESI POP EBX@@StrIsNull:end;//--------------------------------------------------------------------------------------------------// Internal utility function// Uppercases or Lowercases a give null terminated string depending on the// passed offset. (UpOffset or LoOffset)procedure StrCaseBuff{(S: PAnsiChar; const Offset: Integer)}; assembler;asm // make sure the string is not null TEST EAX, EAX JZ @@StrIsNull // ebx will hold the case map, esi pointer to Str PUSH EBX PUSH ESI // load case map and prepare variables LEA EBX, [AnsiCaseMap + EDX] MOV ESI, EAX XOR EDX, EDX XOR EAX, EAX@@NextChar: // get current char from the string MOV DL, [ESI] // check for null char TEST DL, DL JZ @@Done // get corresponding char from the case map MOV AL, [EBX + EDX] // store it back in the string MOV [ESI], AL // do the same thing with next 3 chars MOV DL, [ESI + 1] TEST DL, DL JZ @@Done MOV AL, [EBX+EDX] MOV [ESI + 1], AL MOV DL, [ESI + 2] TEST DL, DL JZ @@Done MOV AL, [EBX+EDX] MOV [ESI + 2], AL MOV DL, [ESI + 3] TEST DL, DL JZ @@Done MOV AL, [EBX+EDX] MOV [ESI + 3], AL // point string to next 4 chars ADD ESI, 4 JMP @@NextChar@@Done: POP ESI POP EBX@@StrIsNull:end;//==================================================================================================// String Test Routines//==================================================================================================function StrIsAlpha(const S: AnsiString): Boolean;var I: Integer;begin Result := S <> ''; for I := 1 to Length(S) do begin if not CharIsAlpha(S[I]) then begin Result := False; Exit; end; end;end;//--------------------------------------------------------------------------------------------------function StrIsAlphaNum(const S: AnsiString): Boolean;var I: Integer;begin Result := S <> ''; for I := 1 to Length(S) do begin if not CharIsAlphaNum(S[I]) then begin Result := False; Exit; end; end;end;//--------------------------------------------------------------------------------------------------function StrContainsChars(const S: AnsiString; Chars: TSysCharSet; CheckAll: Boolean): Boolean;var I: Integer; C: Char;begin Result := False; if CheckAll then begin for I := 1 to Length(S) do begin C := S[I]; if C in Chars then begin Chars := Chars - [C]; if Chars = [] then Break; end; end; Result := (Chars = []); end else begin {!CheckAll TODO S = '' Chars = [] => False Should return True S = '' Chars <> [] => False S <> '' Chars = [] => False Should return True S <> '' Chars <> [] => False } for I := 1 to Length(S) do if S[I] in Chars then begin Result := True; Break; end; end;end;//--------------------------------------------------------------------------------------------------function StrIsAlphaNumUnderscore(const S: AnsiString): Boolean;var I: Integer; C: AnsiChar;begin for i := 1 to Length(s) do begin C := S[I]; if not (CharIsAlphaNum(C) or (C = '_')) then begin Result := False; Exit; end; end; Result := True and (Length(S) > 0);end;//--------------------------------------------------------------------------------------------------function StrIsDigit(const S: AnsiString): Boolean;var I: Integer;begin Result := S <> ''; for I := 1 to Length(S) do begin if not CharIsDigit(S[I]) then begin Result := False; Exit; end; end;end;//--------------------------------------------------------------------------------------------------function StrIsNumber(const S: AnsiString): Boolean;var I: Integer;begin Result := S <> ''; for I := 1 to Length(S) do begin if not CharIsNumber(S[I]) then begin Result := False; Exit; end; end;end;//--------------------------------------------------------------------------------------------------function StrIsSubset(const S: AnsiString; const ValidChars: TSysCharSet): Boolean;var I: Integer;begin for I := 1 to Length(S) do begin if not (S[I] in ValidChars) then begin Result := False; Exit; end; end; Result := True and (Length(S) > 0);end;//--------------------------------------------------------------------------------------------------function StrSame(const S1, S2: AnsiString): Boolean;begin Result := StrCompare(S1, S2) = 0;end;//==================================================================================================// String Transformation Routines//==================================================================================================function StrCenter(const S: AnsiString; L: Integer; C: AnsiChar = ' '): AnsiString;begin if Length(S) < L then begin Result := StringOfChar(C, (L - Length(S)) div 2) + S; Result := Result + StringOfChar(C, L - Length(Result)); end else Result := S;end;//--------------------------------------------------------------------------------------------------function StrCharPosLower(const S: AnsiString; CharPos: Integer): AnsiString;begin Result := S; if (CharPos > 0) and (CharPos <= Length(S)) then Result[CharPos] := JclStrings.CharLower(Result[CharPos]);end;//--------------------------------------------------------------------------------------------------function StrCharPosUpper(const S: AnsiString; CharPos: Integer): AnsiString;begin Result := S; if (CharPos > 0) and (CharPos <= Length(S)) then Result[CharPos] := JclStrings.CharUpper(Result[CharPos]);end;//--------------------------------------------------------------------------------------------------function StrDoubleQuote(const S: AnsiString): AnsiString;begin Result := AnsiDoubleQuote + S + AnsiDoubleQuote;end;//--------------------------------------------------------------------------------------------------function StrEnsurePrefix(const Prefix, Text: AnsiString): AnsiString;var PrefixLen: Integer;begin PrefixLen := Length(Prefix); if Copy(Text, 1, PrefixLen) = Prefix then Result := Text else Result := Prefix + Text;end;//--------------------------------------------------------------------------------------------------function StrEnsureSuffix(const Suffix, Text: AnsiString): AnsiString;var SuffixLen: Integer;begin SuffixLen := Length(Suffix); if Copy(Text, Length(Text) - SuffixLen + 1, SuffixLen) = Suffix then Result := Text else Result := Text + Suffix;end;//--------------------------------------------------------------------------------------------------function StrEscapedToString(const S: AnsiString): AnsiString;var I, Len, N, Val: Integer; procedure HandleHexEscapeSeq; const HexDigits = AnsiString('0123456789abcdefABCDEF'); begin N := Pos(S[I + 1], HexDigits) - 1; if N < 0 then // '\x' without hex digit following is not escape sequence Result := Result + '\x' else begin Inc(I); // Jump over x if N >= 16 then N := N - 6; Val := N; // Same for second digit if I < Len then begin N := Pos(S[I + 1], HexDigits) - 1; if N >= 0 then begin Inc(I); // Jump over first digit if N >= 16 then N := N - 6; Val := Val * 16 + N; end; end; {if val > 255 then //raise EJclStringError.CreateResRec(@RsNumericConstantTooLarge);} Result := Result + Chr(Val); end; end; procedure HandleOctEscapeSeq; const OctDigits = AnsiString('01234567'); begin // first digit Val := Pos(S[I], OctDigits) - 1; if I < Len then begin N := Pos(S[I + 1], OctDigits) - 1; if N >= 0 then begin Inc(I); Val := Val * 8 + N;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -