MORMOT的数据序列
mormot服务器回复客户端通过Ctxt.OutContent属性。
此属性的类型是:SockString。 // property OutContent: SockString read fOutContent write fOutContent ;
继续跟代码,发现SockString是RawByteString类型。
type
{$ifdef UNICODE}
/// define the fastest Unicode string type of the compiler
SynUnicode = UnicodeString;
/// define a raw 8-bit storage string type, used for data buffer management
SockString = type RawByteString;
{$else}
/// define the fastest 16-bit Unicode string type of the compiler
SynUnicode = WideString;
{$ifdef HASCODEPAGE} // FPC may expect a CP, e.g. to compare two string constants
SockString = type RawByteString;
{$else}
/// define a 8-bit raw storage string type, used for data buffer management
SockString = type AnsiString;
{$endif}
{$endif}
继续跟代码,发现RawByteString是AnsiString类型。从下面的代码可以看出,
RawByteString是跨平台的,针对不同的平台有不同的编译开关。这也是为什么要封装一个RawByteString类型。
{$IFDEF NEXTGEN} UTF8String = type _AnsiString(65001); RawByteString = type _AnsiString($ffff); {$NODEFINE UTF8String} {$NODEFINE RawByteString} {$ELSEIF Defined(LINUX64) or Defined(OSX64)} UTF8String = type AnsiString(65001); RawByteString = type AnsiString($ffff); {$NODEFINE UTF8String} {$NODEFINE RawByteString} {$ELSE} UTF8String = type AnsiString(65001); RawByteString = type AnsiString($ffff); {$ENDIF}
mormot在SynCommons.pas单元定义了一些RawByteString和其它数据类型相互转换的公共函数,一起来看看。
stream和RawByteString相互转换函数:
function StreamToRawByteString(aStream: TStream): RawByteString;
var current, size: Int64;
begin
result := '';
if aStream=nil then
exit;
current := aStream.Position;
if (current=0) and aStream.InheritsFrom(TRawByteStringStream) then begin
result := TRawByteStringStream(aStream).DataString; // fast COW
exit;
end;
size := aStream.Size-current;
if (size=0) or (size>maxInt) then
exit;
SetLength(result,size);
aStream.Read(pointer(result)^,size);
aStream.Position := current;
end;
function RawByteStringToStream(const aString: RawByteString): TStream;
begin
result := TRawByteStringStream.Create(aString);
end;
bytes和RawByteString相互转换函数:
procedure BytesToRawByteString(const bytes: TBytes; out buf: RawByteString);
begin
SetString(buf,PAnsiChar(pointer(bytes)),Length(bytes));
end;
procedure RawByteStringToBytes(const buf: RawByteString; out bytes: TBytes);
var L: Integer;
begin
L := Length(buf);
if L<>0 then begin
SetLength(bytes,L);
MoveFast(pointer(buf)^,pointer(bytes)^,L);
end;
end;
RawByteString和Variant相互转换函数:
procedure RawByteStringToVariant(const Data: RawByteString; var Value: variant);
begin
with TVarData(Value) do begin
{$ifndef FPC}if VType and VTYPE_STATIC<>0 then{$endif}
VarClear(Value);
if Data='' then
VType := varNull else begin
VType := varString;
VAny := nil; // avoid GPF below when assigning a string variable to VAny
RawByteString(VAny) := Data;
end;
end;
end;
procedure VariantToRawByteString(const Value: variant; var Dest: RawByteString);
begin
case TVarData(Value).VType of
varEmpty, varNull:
Dest := '';
varString:
Dest := RawByteString(TVarData(Value).VAny);
else // not from RawByteStringToVariant() -> conversion to string
Dest := {$ifdef UNICODE}RawByteString{$else}string{$endif}(Value);
end;
end;
stream,ansistring,variant基本上代表了常用的数据格式。