Delphi XE7 et les AnsiString
sous Delphi XE7, plus d'AnsiString pour Android. C'est mal, mais j'ai toujours aimé utiliser les "string" ou "AnsiString" de Delphi pour stocker toutes sortes d'informations. C'est extrêmement pratique, notamment car la notion
#xx
permet de mixer très facilement du texte et des données binaires, ne serait-ce que le retour chariot #13#10
.Plus de cela sous Android ! le type AnsiString n'existe tout simplement plus, Embarcadero recommande d'utiliser TBytes.
Ce qui est tout à fait dommage c'est que ces types existent en réalité, ils sont juste cachés.
Quoi qu'il en soit, voici une unité qui déclare un nouveau type ByteString qui est codé avec les dernières fonctionnalités du langage.
unit Execute.ByteStrings; { ByteString for Delphi XE7 (c)2014 by Execute SARLDelphi do not provide AnsiString anymore on Android Platform ByteString can do the trick NB: there's no codepage at all, only 8bits BYTE/CHAR, an UnicodeChar will lost it's high value ! Take a look at this link also ! http://andy.jgknet.de/blog/2013/10/the-return-of-the-byte-strings/ var s1, s2: ByteString; begin s1 := 'GET / HTTP/1.0'#13#10; s2 := HttpGet(S1); // not a real function just a sample; if s2.Copy(1, 4) = '200 ' then ... end; } {$ZEROBASEDSTRINGS ON} // just to remember ... interface type // 8bit Char ByteChar = packed record Value: Byte; // Char to ByteChar class operator Implicit(c: Char): ByteChar; inline; // ByteChar to Char class operator Implicit(b: ByteChar): Char; inline; // ByteChar = Char ? class operator Equal(b: ByteChar; c: Char): Boolean; inline; // ByteChar as an AsciiZ (ansi)string function AsPChar: string; end; PByteChar = ^ByteChar; // 8bit binary String ByteString = record // the bytes Bytes: array of ByteChar; // Get length function GetLength: Integer; inline; // Set length procedure SetLength(Value: Integer); inline; // same as above property Length: Integer read GetLength write SetLength; // Pointer to the first Byte = @Bytes[0] function FirstByte: PByteChar; inline; // Needed for some internal use procedure AddWord(Value: Word); // Concat string procedure AddStr(const Value: string); // get 1-based char function GetChar(Index: Integer): ByteChar; inline; // same as above property Chars[Index: Integer]: ByteChar read GetChar; default; // 0-based sub string function SubStr(Start, Len: Integer): string; // 1-based sub string function Copy(Start, Len: Integer): string; inline; // String to ByteString (High values lost) class operator Implicit(const s: string): ByteString; // ByteString to String class operator Implicit(b: ByteString): string; // same as Implicit conversion function AsString: string; inline; // Left part of the string till the first 0 byte if any, or the full string function AsPChar: string; end; implementation procedure ByteString.AddStr(const Value: string); var Len: Integer; Idx: Integer; begin Len := Length; Length := Len + System.Length(Value); for Idx := 0 to System.Length(Value) - 1 do begin Bytes[Len].Value := Ord(Value[Idx]) and 255; Inc(Len); end; end; procedure ByteString.AddWord(Value: Word); var Len: Integer; begin Len := Length; Length := Len + 2; Move(Value, Bytes[Len], 2); end; function ByteString.AsPChar: string; var Len : Integer; Index: Integer; begin Len := Length; for Index := 0 to Len - 1 do begin if Bytes[Index].Value = 0 then begin Len := Index; Break; end; end; System.SetLength(Result, Len); for Index := 0 to Len - 1 do Result[Index] := Bytes[Index]; end; function ByteString.AsString: string; begin Result := Self; end; function ByteString.Copy(Start, Len: Integer): string; begin Result := SubStr(Start - 1, Len); end; function ByteString.SubStr(Start: Integer; Len: Integer): string; var Index: Integer; begin if (Start < 0) or (Start >= Length) then Result := '' else begin if Start + Len > Length then Len := Length - Start; System.SetLength(Result, Len); for Index := 0 to Len - 1 do begin Result[Index] := Bytes[Start + Index]; end; end; end; function ByteString.FirstByte: PByteChar; begin Result := @Bytes[0]; end; function ByteString.GetChar(Index: Integer): ByteChar; begin Result := Bytes[Index - 1]; end; function ByteString.GetLength: Integer; begin Result := System.Length(Bytes); end; class operator ByteString.Implicit(b: ByteString): string; var Index: Integer; begin System.SetLength(Result, b.Length); for Index := 0 to b.Length - 1 do Result[Index] := b.Bytes[Index]; end; class operator ByteString.Implicit(const s: string): ByteString; var Index: Integer; begin Result.SetLength(System.Length(s)); for Index := 0 to System.Length(s) - 1 do Result.Bytes[Index].Value := Byte(Ord(s[Index + 1])); end; procedure ByteString.SetLength(Value: Integer); begin System.SetLength(Bytes, Value); end; { ByteChar } class operator ByteChar.Implicit(c: Char): ByteChar; begin Result.Value := Ord(c) and 255; end; function ByteChar.AsPChar: string; var B: PByte; L: Integer; begin B := @Self; L := 0; while B[L] <> 0 do begin Inc(L); end; SetLength(Result, L); while L > 0 do begin Dec(L); Result[L] := Char(B[L]); end; end; class operator ByteChar.Equal(b: ByteChar; c: Char): Boolean; begin Result := b.Value = Ord(c); end; class operator ByteChar.Implicit(b: ByteChar): Char; begin Result := Chr(b.Value); end; end.
Date de dernière modification : 03/12/2014