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基本上代表了常用的数据格式。