diff --git a/wst/trunk/basex_encode.pas b/wst/trunk/basex_encode.pas index b75854b43..7f709a58a 100644 --- a/wst/trunk/basex_encode.pas +++ b/wst/trunk/basex_encode.pas @@ -32,19 +32,26 @@ type function Base64Decode(const AInBuffer : string; const AOptions : TBaseXOptions) : TByteDynArray;overload; function Base32Encode(const ALength : PtrInt; const AInBuffer) : string; overload; - function Base32Encode(const AInBuffer : TBinaryString) : string; overload; + function Base32Encode(const AInBuffer : TBinaryString) : string; overload; function Base32Decode(const AInBuffer : string; const AOptions : TBaseXOptions) : TByteDynArray; - - procedure Base16Encode(const ABin; const ALen : Integer; AOutBuffer : PChar); overload; + + procedure Base16Encode(const ABin; const ALen : Integer; AOutBuffer : PAnsiChar); overload; + procedure Base16Encode(const ABin; const ALen : Integer; AOutBuffer : PWideChar); overload; function Base16Encode(const ABin; const ALen : Integer) : string; overload; function Base16Encode(const AInBuffer : TBinaryString) : string;overload; function Base16Decode( - const AHex : PChar; + const AHex : PAnsiChar; var ABin; const ABinLen : Integer; const AOptions : TBaseXOptions = [xoDecodeIgnoreIllegalChar] ) : Integer;overload; - function Base16Decode(const AInBuffer : string; const AOptions : TBaseXOptions) : TByteDynArray;overload; + function Base16Decode( + const AHex : PWideChar; + var ABin; + const ABinLen : Integer; + const AOptions : TBaseXOptions = [xoDecodeIgnoreIllegalChar] + ) : Integer;overload; + function Base16Decode(const AInBuffer : ansistring; const AOptions : TBaseXOptions) : TByteDynArray;overload; implementation @@ -398,12 +405,12 @@ begin end; end; -procedure Base16Encode(const ABin; const ALen : Integer; AOutBuffer : PChar); +procedure Base16Encode(const ABin; const ALen : Integer; AOutBuffer : PAnsiChar); const - HEX_MAP : array[0..15] of Char = '0123456789ABCDEF'; + HEX_MAP : array[0..15] of AnsiChar = '0123456789ABCDEF'; var p : PByte; - pres : PChar; + pres : PAnsiChar; i : Integer; begin if ( ALen > 0 ) then begin @@ -411,7 +418,27 @@ begin p := PByte(@Abin); for i := 1 to ALen do begin pres^ := HEX_MAP[p^ shr 4]; - PChar(PtrUInt(pres) + SizeOf(Char))^ := HEX_MAP[p^ and $F]; + PAnsiChar(PtrUInt(pres) + SizeOf(AnsiChar))^ := HEX_MAP[p^ and $F]; + Inc(pres,2); + Inc(p); + end; + end; +end; + +procedure Base16Encode(const ABin; const ALen : Integer; AOutBuffer : PWideChar); +const + HEX_MAP : array[0..15] of WideChar = ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'); +var + p : PByte; + pres : PWideChar; + i : Integer; +begin + if ( ALen > 0 ) then begin + pres := AOutBuffer; + p := PByte(@Abin); + for i := 1 to ALen do begin + pres^ := HEX_MAP[p^ shr 4]; + PWideChar(PtrUInt(pres) + SizeOf(WideChar))^ := HEX_MAP[p^ and $F]; Inc(pres,2); Inc(p); end; @@ -422,7 +449,7 @@ function Base16Encode(const ABin; const ALen : Integer) : string; begin if ( ALen > 0 ) then begin SetLength(Result,(2 * ALen)); - Base16Encode(ABin,ALen,@Result[1]); + Base16Encode(ABin,ALen,PChar(@Result[1])); end else begin Result := ''; end; @@ -435,7 +462,7 @@ end; // Returns the actual bytes count. function Base16Decode( - const AHex : PChar; + const AHex : PAnsiChar; var ABin; const ABinLen : Integer; const AOptions : TBaseXOptions = [xoDecodeIgnoreIllegalChar] @@ -446,7 +473,7 @@ const ALPHA_LOW_MAP : array['a'..'f'] of Byte = ( 10, 11, 12, 13, 14, 15 ); var i : Integer; - hp : PChar; + hp : PAnsiChar; bp : PByte; binVal : Byte; locFailOnIllegalChar : Boolean; @@ -522,13 +549,102 @@ begin end; end; -function Base16Decode(const AInBuffer : string; const AOptions : TBaseXOptions) : TByteDynArray; +// Returns the actual bytes count. +function Base16Decode( + const AHex : PWideChar; + var ABin; + const ABinLen : Integer; + const AOptions : TBaseXOptions = [xoDecodeIgnoreIllegalChar] +) : Integer; +const + DIGIT_MAP : array['0'..'9'] of Byte = ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9); + ALPHA_UP_MAP : array['A'..'F'] of Byte = ( 10, 11, 12, 13, 14, 15 ); + ALPHA_LOW_MAP : array['a'..'f'] of Byte = ( 10, 11, 12, 13, 14, 15 ); +var + i : Integer; + hp : PWideChar; + bp : PByte; + binVal : Byte; + locFailOnIllegalChar : Boolean; +begin + Result := 0; + if ( ABinLen > 0 ) then begin + binVal := 0; + bp := PByte(@Abin); + hp := AHex; + locFailOnIllegalChar := not ( xoDecodeIgnoreIllegalChar in AOptions ); + for i := 0 to Pred(ABinLen) do begin + if ( hp^ = #0 ) then + Break; + while ( hp^ <> #0 ) do begin + case hp^ of + '0'..'9' : + begin + binVal := ( DIGIT_MAP[AnsiChar(hp^)] shl 4); + Break; + end; + 'A'..'Z' : + begin + binVal := ( ALPHA_UP_MAP[AnsiChar(hp^)] shl 4); + Break; + end; + 'a'..'z' : + begin + binVal := ( ALPHA_LOW_MAP[AnsiChar(hp^)] shl 4); + Break; + end; + else + begin + if locFailOnIllegalChar then + raise EBase16Exception.Create(SERR_UnexpectedEndOfData); + end; + end; + Inc(hp); + end; + if ( hp^ = #0 ) then + raise EBase16Exception.Create(SERR_UnexpectedEndOfData); + Inc(hp); + while ( hp^ <> #0 ) do begin + case hp^ of + '0'..'9' : + begin + bp^ := binVal or DIGIT_MAP[AnsiChar(hp^)]; + Break; + end; + 'A'..'Z' : + begin + bp^ := binVal or ALPHA_UP_MAP[AnsiChar(hp^)]; + Break; + end; + 'a'..'z' : + begin + bp^ := binVal or ALPHA_LOW_MAP[AnsiChar(hp^)]; + Break; + end; + else + begin + if locFailOnIllegalChar then + raise EBase16Exception.CreateFmt(SERR_IllegalChar,[hp^]); + end; + end; + Inc(hp); + end; + if ( hp^ = #0 ) then + raise EBase16Exception.Create(SERR_UnexpectedEndOfData); + Inc(hp); + Inc(bp); + end; + Result := PtrUInt(bp) - PtrUInt(@Abin); + end; +end; + +function Base16Decode(const AInBuffer : ansistring; const AOptions : TBaseXOptions) : TByteDynArray; var i : Integer; begin if ( Length(AInBuffer) > 0 ) then begin SetLength(Result,Length(AInBuffer) div 2); - i := Base16Decode(PChar(AInBuffer),Result[0],Length(Result),AOptions); + i := Base16Decode(PAnsiChar(AInBuffer),Result[0],Length(Result),AOptions); if ( i <> Length(Result) ) then SetLength(Result,i); end;