MORMOT的数据序列

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

原文地址:https://www.cnblogs.com/hnxxcxg/p/10135110.html