Ваш пример кода не будет работать, поскольку вы смешиваете shortstring const
и pointer
из string
- как Роб заявил в своем комментарии.
И ваш код не имеет ничего общего ни с кодировкой KLV, ни с кодировкой TLV.
Здесь может быть пример кодировки TLV (я показываю только строковое кодирование, но вы можете добавить другие типы):
type
TTLVType = (tlvUnknown, tlvString, tlvInteger);
function EncodeToTLV(const aString: WideString): TBytes;
var Len: integer;
begin
Len := length(aString)*2;
SetLength(result,Len+sizeof(TTLVType)+sizeof(integer));
Result[0] := ord(tlvString); // Type
PInteger(@Result[sizeof(TTLVType)])^ := Len; // Length
move(pointer(aString)^,Result[sizeof(TTLVType)+sizeof(integer)],Len); // Value
end;
function DecodeStringFromTLV(const aValue: TBytes): WideString;
begin
if (length(aValue)<3) or (aValue[0]<>ord(tlvString)) or
(PInteger(@aValue[sizeof(TTLVType)])^<>length(aValue)-sizeof(TTLVType)-sizeof(integer)) then
raise EXception.Create('Invalid input format');
SetString(result,PWideChar(@Result[sizeof(TTLVType)+sizeof(integer)]),PInteger(@aValue[sizeof(TTLVType)])^ div 2);
end;
Я использовал WideString
здесь, потому что он может безопасно хранить любой контент Unicode, даже в версии компилятора до Delphi 2009.
Вы можете использовать запись вместо моей арифметики указателя:
type
TTLVHeader = packed record
ContentType: TTLVType;
ContentLength: integer;
Content: array[0..1000] of byte; // but real length will vary
end;
PTLVHeader = ^TTLVHeader;
function EncodeToTLV(const aString: WideString): TBytes;
var Len: integer;
begin
Len := length(aString)*2;
SetLength(result,Len+sizeof(TTLVType)+sizeof(integer));
with PTLVHeader(result)^ do
begin
ContentType := tlvString;
ContentLength := Len;
move(pointer(aString)^,Content,Len);
end;
end;
Аналогичное кодирование может использоваться для KLV, но с добавлением целочисленного ключа в заголовок.