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