#1 2016-12-23 13:23:07

Hafedh TRIMECHE
Member
Registered: 2016-09-18
Posts: 32

Serialization using RecordSave problem

The function RecordSaveLength returned 0 when invoking RecordSave because of the presence of a the static array in the ThreeDConfig structure (array[1..4] of TThreeDConfig).

Non handling  tkArray is the cause of the error.

RecordSaveJSON returned valid content and deserialized to the record with no error.

{
   "Head":{
      "Index":309,
      "Indicator":0
   },
   "BannedIP":"192.168.0.12",
   "BannedBINs":"192.168.0.1,192.168.0.1",
   "CheckSignerSubject":711159,
   "CheckSignerURL":"localhost",
   "CheckSignerP12":[

   ],
   "CheckBIN":123456,
   "ThreeDConfig":[
      {
         "DSSubject":0,
         "DSURL":"",
         "DSP12":[

         ],
         "AHSSubject":0,
         "AHSURL":"",
         "AHSP12":[

         ],
         "ACSSignSubject":0,
         "ACSSignP12":[

         ]
      },
      {
         "DSSubject":0,
         "DSURL":"",
         "DSP12":[

         ],
         "AHSSubject":0,
         "AHSURL":"",
         "AHSP12":[

         ],
         "ACSSignSubject":0,
         "ACSSignP12":[

         ]
      },
      {
         "DSSubject":0,
         "DSURL":"",
         "DSP12":[

         ],
         "AHSSubject":0,
         "AHSURL":"http://visa.com",
         "AHSP12":[

         ],
         "ACSSignSubject":0,
         "ACSSignP12":[

         ]
      },
      {
         "DSSubject":0,
         "DSURL":"",
         "DSP12":[

         ],
         "AHSSubject":0,
         "AHSURL":"",
         "AHSP12":[

         ],
         "ACSSignSubject":0,
         "ACSSignP12":[

         ]
      }
   ]
}
----------------------------------------------------------------------------------------------
type
  TDBRecordHeader=
  packed record
    Index     : Int64;
    Indicator : Int64;
  end;
  TThreeDConfig=
  packed record
    DSSubject       : Int64;
    DSURL           : UnicodeString;
    DSP12           : TBytes;

    AHSSubject      : Int64;
    AHSURL          : UnicodeString;
    AHSP12          : TBytes;

    ACSSignSubject  : Int64;
    ACSSignP12      : TBytes;
  end;
  TProcessingObjects=//https://www.jsecuretestfacility.com/jstat/other.LoginCompliance.do
  packed record
    Head                : TDBRecordHeader;
    BannedIP            : UnicodeString;
    BannedBINs          : UnicodeString;
    CheckSignerSubject  : Int64;
    CheckSignerURL      : UnicodeString;
    CheckSignerP12      : TBytes;
    CheckBIN            : Cardinal;
    ThreeDConfig        : array[1..4] of TThreeDConfig;
  end;

---------------------------------------------------------------
    case Field^.TypeInfo^.Kind of
      tkDynArray: begin
        DynArray.Init(Deref(Field^.TypeInfo),P^);
        inc(result,DynArray.SaveToLength-sizeof(PtrUInt));
      end;
      tkLString,tkWString{$ifdef FPC},tkLStringOld{$endif}:
        // length stored within WideString is in bytes
        if P^=0 then
          dec(result,sizeof(PtrUInt)-1) else
          inc(result,ToVarUInt32LengthWithData(PStrRec(Pointer(P^-STRRECSIZE))^.length)-sizeof(PtrUInt));
      {$ifdef HASVARUSTRING}
      tkUString:
        if P^=0 then
          dec(result,sizeof(PtrUInt)-1) else
          inc(result,ToVarUInt32LengthWithData(PStrRec(Pointer(P^-STRRECSIZE))^.length*2)-sizeof(PtrUInt));
      {$endif}
      tkRecord{$ifdef FPC},tkObject{$endif}: begin
        infoNested := Deref(Field^.TypeInfo); // inlined GetTypeInfo()
        Len := RecordSaveLength(P^,infoNested);
        if Len=0 then begin
          result := 0;
          exit; // invalid/unhandled nested record content
        end;
        inc(result,Len);
        {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
        infoNested := GetFPCAlignPtr(infoNested);
        {$else}
        inc(PtrUInt(infoNested),infoNested^.NameLen);
        {$endif}
        dec(result,infoNested^.recSize);
      end;
      {$ifndef NOVARIANTS}
      tkVariant: begin
        Len := VariantSaveLength(PVariant(P)^);
        if Len=0 then begin
          result := 0;
          exit; // invalid/unhandled variant content
        end;
        inc(result,Len-sizeof(variant));
      end;
      {$endif}
      {$ifndef FPC} // FPC does include RTTI for unmanaged fields! smile
      else begin
        result := 0;  ////////////////////////////////////////////////////////// EXIT POINT ////////////////////////////////////////////////////////
        exit; // invalid/unhandled record content
      end;
      {$endif}
    end;
---------------------------------------------------------------------------------------------------------------------------------------------------------------------

Offline

#2 2016-12-27 09:34:59

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,242
Website

Re: Serialization using RecordSave problem

1. As stated by the forum rules, please do not post big amount of source code in the posts, but use pastebin or other third-party sites.

2. I've just made a big refactory of binary serialization.
tkArray kind of content should be supported now!
See http://synopse.info/fossil/info/9724708fd4
and http://synopse.info/fossil/info/92667d06d4

Offline

Board footer

Powered by FluxBB