Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#4

Re: ReverseString für ältere Delphi-Versionen

  Alt 11. Dez 2009, 23:08
Delphi-Quellcode:
Function ReverseString(Const Text: String): String;
Var L: Integer;
  S, D: PChar;
Begin
  L := Length(Text) - 1;
  SetLength(Result, L + 1);
  S := PChar(Text);
  D := PChar(Result) + L;
  For L := L downto 0 do Begin
    D^ := S^;
    Inc(S);
    Dec(D);
  End;
End;
Ihr wißt aber, daß die/unsere Ansi-Varianten nur mit Singelbyte-Zeichensätzen richtig arbeiten?


Und weil ich grad mal 'nen Sekündchen lang Lange Weile hatte:
Delphi-Quellcode:
Function ReverseString(Const Text: AnsiString): AnsiString; Overload;
  ASM
    PUSH EDI
    PUSH ESI
    PUSH EDX
    PUSH EAX
    XCHG EAX, EDX
    TEST EDX, EDX
    JZ @@ZeroSet
    SUB EDX, 4
    MOV EDX, [EDX]
    @@ZeroSet:
    CALL _LStrSetLength
    POP ESI
    POP EDI
    MOV EDI, [EDI]
    SUB EDI, 4
    MOV ECX, ESI
    TEST ECX, ECX
    JZ @@Exit
    SUB ECX, 4
    MOV ECX, [ECX]
    //XOR EAX, EAX
    //@@Loop:
    //MOV DL, [ESI + EAX]
    //MOV [EDI + ECX], DL
    //INC EAX
    //LOOP @@Loop
    //@@Exit:
    PUSH ECX
    MOV EAX, ECX
    AND EAX, $3
    ADD EDI, EAX
    SHR ECX, 2
    // TEST ECX, ECX // wenn SHR das Zero-Flag nicht setzt, dann dieses einfügen
    JZ @@None4
    XOR EAX, EAX
    @@Loop4:
    MOV EDX, [ESI + EAX * 4]
    BSWAP EDX
    MOV [EDI + ECX * 4], EDX
    INC EAX
    LOOP @@Loop4
    @@None4:
    POP EAX
    MOV ECX, EAX
    AND ECX, $3
    JZ @@Exit
    AND EAX, $FFFFFFFC
    @@Loop:
    MOV DL, [ESI + EAX]
    MOV [EDI + ECX + 1], DL
    INC EAX
    LOOP @@Loop
    @@Exit:
    POP ESI
    POP EDI
  End;

{$IFDEF UNICODE}
Function ReverseString(Const Text: UnicodeString): UnicodeString; Overload;
  ASM
    PUSH EDX
    PUSH EAX
    XCHG EAX, EDX
    TEST EDX, EDX
    JZ @@ZeroSet
    SUB EDX, 4
    MOV EDX, [EDX]
    @@ZeroSet:
    CALL _UStrSetLength
    POP ESI
    POP EDI
    MOV EDI, [EDI]
    SUB EDI, 2
    MOV ECX, ESI
    TEST ECX, ECX
    JZ @@Exit
    SUB ECX, 4
    MOV ECX, [ECX]
    XOR EAX, EAX
    @@Loop:
    MOV DX, [ESI + EAX * 2]
    MOV [EDI + ECX * 2], DX
    INC EAX
    LOOP @@Loop
    @@Exit:
  End;
{$ENDIF}

Function ReverseString(Const Text: WideString): WideString; Overload;
  ASM
    PUSH EDX
    PUSH EAX
    XCHG EAX, EDX
    TEST EDX, EDX
    JZ @@ZeroSet
    SUB EDX, 4
    MOV EDX, [EDX]
    SHR EDX, 1
    @@ZeroSet:
    CALL _WStrSetLength
    POP ESI
    POP EDI
    MOV EDI, [EDI]
    SUB EDI, 2
    MOV ECX, ESI
    TEST ECX, ECX
    JZ @@Exit
    SUB ECX, 4
    MOV ECX, [ECX]
    SHR ECX, 1
    XOR EAX, EAX
    @@Loop:
    MOV DX, [ESI + EAX * 2]
    MOV [EDI + ECX * 2], DX
    INC EAX
    LOOP @@Loop
    @@Exit:
  End;
Und weil ich einfach zu doof bin, um die Funktionen der System-Unit aufzurufen
(ich hasse es, daß die Namen der System.pas nicht mit der System.dcu und der CPU-Anzeige übereinstimmen)
Delphi-Quellcode:
Procedure _LStrSetLength(Var Text: AnsiString; Len: Integer);
  Begin
    SetLength(Text, Len);
  End;

{$IFDEF UNICODE}
Procedure _WStrSetLength(Var Text: WideString; Len: Integer);
  Begin
    SetLength(Text, Len);
  End;
{$ENDIF}

Procedure _UStrSetLength(Var Text: UnicodeString; Len: Integer);
  Begin
    SetLength(Text, Len);
  End;
$2B or not $2B
  Mit Zitat antworten Zitat