如何将 tencoding 的 getstring 与静态数组的一部分一起使用 w/o 块复制
how to use tencoding's getstring with a part of static array w/o block copying
我正在尝试将 Tencoding.UTF8.Getstring 应用于静态字节数组的一部分,而不将其内容复制到动态数组。如果数组是动态的,我可以使用:
stringvar:=Tencoding.utf8.Getstring(dynbytearray,offset,length);
然而,当我有一个静态的预定义长度数组时,语法不起作用,我所能想到的就是声明一个新的动态数组,设置它的长度,然后复制字节。我不喜欢做不必要的复制,因为我怀疑我只是错过了一个语法技巧。到目前为止,我像 "setlength(newdynarr,whatever); newdynarr:=@staticarr [optional offset]" 这样的尝试都失败了。谢谢
您可以使用 System.UnicodeFromLocaleChars
。比如像这样:
uses
SysUtils, SysConst, Windows;
function Utf8BytesToString(Bytes: PByte; ByteCount: Integer): string;
var
Len: Integer;
begin
Len := UnicodeFromLocaleChars(CP_UTF8, MB_ERR_INVALID_CHARS, Pointer(Bytes),
ByteCount, nil, 0);
if (ByteCount>0) and (Len=0) then begin
raise EEncodingError.CreateRes(@SNoMappingForUnicodeCharacter);
end;
SetLength(Result, Len);
UnicodeFromLocaleChars(CP_UTF8, MB_ERR_INVALID_CHARS, Pointer(Bytes),
ByteCount, Pointer(Result), Len);
end;
System.UnicodeFromLocaleChars
函数在 Windows 上包装 MultiByteToWideChar
,在 POSIX 系统上包装 UnicodeFromLocaleChars
。 TEncoding
class 利用 System.UnicodeFromLocaleChars
来执行其转换。如果您想朝相反的方向行驶,System.LocaleCharsFromUnicode
.
public TEncoding.GetString()
方法只支持动态数组,但您可以使用 TEncoding.GetCharCount()
and TEncoding.GetChars()
的受保护 PByte
重载,例如:
type
TEncodingHelper = class(TEncoding)
public
function GetString(Bytes: PByte; ByteCount: Integer): String;
end;
function TEncodingHelper.GetString(Bytes: PByte; ByteCount: Integer): String;
begin
SetLength(Result, GetCharCount(Bytes, ByteCount));
GetChars(Bytes, ByteCount, PChar(Result), Length(Result));
end;
var
S: string;
begin
S := TEncodingHelper(TEncoding.UTF8).GetString(PByte(@arr[index]), ByteCount);
end;
或者:
type
TEncodingHelper = class helper for TEncoding
public
function GetString(Bytes: PByte; ByteCount: Integer): String;
end;
function TEncodingHelper.GetString(Bytes: PByte; ByteCount: Integer): String;
begin
SetLength(Result, Self.GetCharCount(Bytes, ByteCount));
Self.GetChars(Bytes, ByteCount, PChar(Result), Length(Result));
end;
var
S: string;
begin
S := TEncoding.UTF8.GetString(PByte(@arr[index]), ByteCount);
end;
我正在尝试将 Tencoding.UTF8.Getstring 应用于静态字节数组的一部分,而不将其内容复制到动态数组。如果数组是动态的,我可以使用:
stringvar:=Tencoding.utf8.Getstring(dynbytearray,offset,length);
然而,当我有一个静态的预定义长度数组时,语法不起作用,我所能想到的就是声明一个新的动态数组,设置它的长度,然后复制字节。我不喜欢做不必要的复制,因为我怀疑我只是错过了一个语法技巧。到目前为止,我像 "setlength(newdynarr,whatever); newdynarr:=@staticarr [optional offset]" 这样的尝试都失败了。谢谢
您可以使用 System.UnicodeFromLocaleChars
。比如像这样:
uses
SysUtils, SysConst, Windows;
function Utf8BytesToString(Bytes: PByte; ByteCount: Integer): string;
var
Len: Integer;
begin
Len := UnicodeFromLocaleChars(CP_UTF8, MB_ERR_INVALID_CHARS, Pointer(Bytes),
ByteCount, nil, 0);
if (ByteCount>0) and (Len=0) then begin
raise EEncodingError.CreateRes(@SNoMappingForUnicodeCharacter);
end;
SetLength(Result, Len);
UnicodeFromLocaleChars(CP_UTF8, MB_ERR_INVALID_CHARS, Pointer(Bytes),
ByteCount, Pointer(Result), Len);
end;
System.UnicodeFromLocaleChars
函数在 Windows 上包装 MultiByteToWideChar
,在 POSIX 系统上包装 UnicodeFromLocaleChars
。 TEncoding
class 利用 System.UnicodeFromLocaleChars
来执行其转换。如果您想朝相反的方向行驶,System.LocaleCharsFromUnicode
.
public TEncoding.GetString()
方法只支持动态数组,但您可以使用 TEncoding.GetCharCount()
and TEncoding.GetChars()
的受保护 PByte
重载,例如:
type
TEncodingHelper = class(TEncoding)
public
function GetString(Bytes: PByte; ByteCount: Integer): String;
end;
function TEncodingHelper.GetString(Bytes: PByte; ByteCount: Integer): String;
begin
SetLength(Result, GetCharCount(Bytes, ByteCount));
GetChars(Bytes, ByteCount, PChar(Result), Length(Result));
end;
var
S: string;
begin
S := TEncodingHelper(TEncoding.UTF8).GetString(PByte(@arr[index]), ByteCount);
end;
或者:
type
TEncodingHelper = class helper for TEncoding
public
function GetString(Bytes: PByte; ByteCount: Integer): String;
end;
function TEncodingHelper.GetString(Bytes: PByte; ByteCount: Integer): String;
begin
SetLength(Result, Self.GetCharCount(Bytes, ByteCount));
Self.GetChars(Bytes, ByteCount, PChar(Result), Length(Result));
end;
var
S: string;
begin
S := TEncoding.UTF8.GetString(PByte(@arr[index]), ByteCount);
end;