#1 PDF Engine » EMF file Image not rendered » 2022-04-04 05:02:18

Hafedh TRIMECHE
Replies: 1

Hello,

Please note that the image emdeded to the EMF https://mega.nz/file/OxZEXTQT#RVjHvaY1H … Fwe8Y2mq3E is not rendered using Canvas.RenderMetaFile method.

The output PDF file: https://mega.nz/file/C9hW1CSR#F9tCprEGi … A87xkV6bl0

Best regards.

#2 PDF Engine » Compress Embedded Fonts » 2021-12-26 21:40:56

Hafedh TRIMECHE
Replies: 1

A file generated by SynPDF (pdfa3B) is bigger than the same one generated using pdfaNone and converted by GhostSrcipt module (-dPDFA=3).

Would fonts be compressed to reduce the size?

Best regards.

#3 Re: mORMot 1 » Custom Json Serializer for Simple Types » 2021-07-01 16:02:25

The solution I implemented to handle TBytes:

class procedure TCustomJSONSerializer.CustomWriter(W:TTextWriter;Data:pointer;Options:TTextWriterWriteObjectOptions);
var
  Bytes   : TBytes;
  EndChar : AnsiChar;
begin
  Bytes   := TBytes(Data);
  EndChar := W.LastChar;
  W.CancelLastChar;
  if EndChar='[' then
  begin
    W.Add('"');
    if Assigned(Bytes) then W.WrBase64(@Bytes[0],Length(Bytes),False);
    W.Add('"');
  end;
end;

but generates a wrong Json with ] character not removed:

{"I1":0,"I2":0,"S":"String","B":"AQIDBA=="],"D":"2021-07-01T16:56:40","T":44378.7060185417}

Record used:
  TData2=
  record
    I1 : Integer;
    I2 : Integer;
    S  : string;
    B  : TBytes;
    D  : TDateTime;
    T  : TTime;
  end;

Is there a way to replace the hole TBytes content by the Base64 encoded not iterating into the array elements?

#4 Re: mORMot 1 » Custom Json Serializer for Simple Types » 2021-06-30 00:53:02

Hello,

Please how to implement a custom serialization for TBytes?

  TCustomJSONSerializer=class
  private
    class procedure CustomReader(var Context:TJsonParserContext;Data:pointer);
    class procedure CustomWriter(W:TTextWriter;Data:pointer;Options:TTextWriterWriteObjectOptions);
  end;


class procedure TCustomJSONSerializer.CustomReader(var Context:TJsonParserContext;Data:pointer);
begin
  ...
end;

class procedure TCustomJSONSerializer.CustomWriter(W:TTextWriter;Data:pointer;Options:TTextWriterWriteObjectOptions);
begin
  ...
end;

initialization

  TRttiJson.RegisterCustomSerializer(TypeInfo(TBytes),TCustomJSONSerializer.CustomReader,TCustomJSONSerializer.CustomWriter);

#5 Re: mORMot 1 » Custom Json Serializer for Simple Types » 2021-01-04 10:33:07

Demo project: https://mega.nz/file/Dl4wmBhY#-r34M8GP5 … KayXu38Ejo
Please note that:
1- Write Option is set to [twoIgnoreDefaultInRecord,twoEnumSetsAsTextInRecord] but the output Json still including empty fields (Empty record checked)

  Serializer = record
  const
    WriteOptions = [twoIgnoreDefaultInRecord,twoEnumSetsAsTextInRecord];
  public
    class function Marshal<T>(const Data:T):string;overload;inline;static;
    class function Marshal<T>(const Data:T;const Service:Byte):TBytes;overload;inline;static;
    class function Unmarshal<T>(Text:string;out Data:T):Boolean;overload;inline;static;
    class function Unmarshal<T>(const TextBytes:TBytes;out Data:T):Boolean;overload;inline;static;
  end;

class function Serializer.Marshal<T>(const Data:T):string;
var
  rResult : RawUTF8;
begin
  if @Data=nil then Result := '' else
  begin
    try
      mormot.core.json.SaveJson(Data,TypeInfo(T),WriteOptions,rResult);
    except
      rResult := '';
    end;
    Result := string(rResult);
    if Result='' then raise Exception.Create('Serializer.Marshal:');
  end;
end;

2- When embedding an Object into the record, a memory leak is generated:

A memory block has been leaked. The size is: 20

This block was allocated by thread 0xFEC, and the stack trace (return addresses) at the time was:
0064A753 [uMemory.pas][uMemory][NewAllocMem][73]
00407152 [System.pas][System][AllocMem][4773]
00668CC1 [mormot.core.rtti.pas][mormot.core.rtti][DynArrayNew][4934]
0069C836 [mormot.core.json.pas][mormot.core.json][_JL_DynArray][7395]
0069B6C3 [mormot.core.json.pas][mormot.core.json][_JL_Integer][7059]
0069CBA8 [mormot.core.json.pas][mormot.core.json][JsonLoadProp][7473]
0069D29E [mormot.core.json.pas][mormot.core.json][_JL_RttiCustom][7578]
00418CB2 [FastMM4][CalculateHeaderCheckSum]
00419B20 [FastMM4][DebugGetMem]
0064A828 [uMemory.pas][uMemory][NewAllocMem][83]
0069C87A [mormot.core.json.pas][mormot.core.json][_JL_DynArray][7407]

The block is currently used for an object of class: Unknown

The allocation number is: 3202

3- Custom Serialization of TBytes can't be achieved because the Serializer wont distinguish between TBytes and other dynamic array types.
Uncommenting for testing.

//    RegisterCustomSerializer(TypeInfo(TBytes),BytesReader,BytesWriter);

Best regards.

#6 Re: mORMot 1 » Custom Json Serializer for Simple Types » 2021-01-03 12:36:17

Hello,

Please how to cancel writing an empty string or integer value set to 0 (Zero) so the generated Json file would be as compact as possible?

class procedure TCustomJSONSerializer.StringWriter(W:TTextWriter;Data:pointer;Options:TTextWriterWriteObjectOptions);
var
  Value : string;
begin
  Value := String(Data^)+#0;
  if Value>#0 then .....
              else W.AddTextW(PWord(Value));
end;

Best regards.

#7 Re: mORMot 1 » Custom Json Serializer for Simple Types » 2021-01-02 17:07:18

Using mORMot 2 (mormot.core.json), an error is generated.

[dcc32 Error] Main.pas(215): E2003 Undeclared identifier: 'RegisterCustomJSONSerializer'

#8 Re: mORMot 1 » Custom Json Serializer for Simple Types » 2021-01-02 12:01:20

Thank you for response.

Would you please provide an example related to sub-type custom serialization?

Best regards.

#9 mORMot 1 » Custom Json Serializer for Simple Types » 2020-12-08 11:25:36

Hafedh TRIMECHE
Replies: 13

Hello,

Would a custom Json serializer be used for simple types Char, TDateTime, TTime, ...?

Best regards.

#10 mORMot 1 » Char/WideChar JSON conversion problem » 2020-09-22 19:39:35

Hafedh TRIMECHE
Replies: 1

The Char/WideChar record field is converted to ASCII code instead of its content:

type
  TCharRecord=
  record
    Value : Char;
  end;
procedure SynJSON;
var
  CharRecord : TCharRecord;
  sJSON      : string;
begin
  CharRecord.Value := 'Y';
  TTextWriter.RegisterCustomJSONSerializerSetOptions(TypeInfo(TCharRecord),[soWriteIgnoreDefault],True);
  sJSON := string(RecordSaveJSON(CharRecord,TypeInfo(TCharRecord),True));
  Memo1.Lines.Text := sJSON;
end;

giving {"Value":89} as result instead of {"Value":"Y"}

Would an option be considered to handle such conversion?

#11 mORMot 1 » Json Path » 2020-07-27 19:51:54

Hafedh TRIMECHE
Replies: 3

Hello,

How to get the second phoneNumbers type element using path (phoneNumbers[1].type) giving home

{
  "firstName": "John",
  "lastName" : "doe",
  "age"      : 26,
  "address"  : {
    "streetAddress": "naist street",
    "city"         : "Nara",
    "postalCode"   : "630-0192"
  },
  "phoneNumbers": [
    {
      "type"  : "iPhone",
      "number": "0123-4567-8888"
    },
    {
      "type"  : "home",
      "number": "0123-4567-8910"
    }
  ]
}

Best regards.

#12 Re: mORMot 1 » External SIGSEGV SynCommons.pas » 2020-07-24 11:51:00

The Path to Synopse.inc is included into [Include files (-Fi)]: ..\..\lib\mORMot and [Other unit files (-Fu)]: ..\..\lib\mORMot

It works with the Trunk Branch!

Would you please provide a unit into which the TCustomAttribute is used?

Best regards.

#13 Re: mORMot 1 » External SIGSEGV SynCommons.pas » 2020-07-24 11:14:04

Please not that switching to FPC 3.2 and Lazarus 2.0.10 raised another  exception related to CustomAttributes. I think that this functionality is only available under Trunk.

Error: Identifier not found "TCustomAttribute"

Best regards.

#14 mORMot 1 » External SIGSEGV SynCommons.pas » 2020-07-24 00:40:24

Hafedh TRIMECHE
Replies: 5

FPC: 3.3.1 (Trunk)
Lazarus: 2.0.10
SynCommons: 1.18.6093

Project xxxxxx raised exception class 'External: SIGSEGV'.

 In file 'D:\Developer\lib\mORMot\SynCommons.pas' at line 51119:
fElemType := PPointer(fElemType)^;

#15 mORMot 1 » RecordLoadJSON & soReadIgnoreUnknownFields Boolean problem » 2020-07-18 15:54:20

Hafedh TRIMECHE
Replies: 1

Varsion: 1.18.6089
When a Boolean value not initialized (not exists in the Json document), the returned value is always set to True.
The problem is solved only if the variable is set to its default value using Data := default(T) before invoking RecordLoadJSON

class function _J_.Decode<T>(Text:string;out Data:T):Boolean;
var
  RttiInfo : Pointer;
begin
  while (Text<>'') and (Text[Length(Text)]<>'}') do SetLength(Text,Length(Text)-1);
  if Text='' then
  begin
    Data := default(T);
    Exit(False);
  end;
  RttiInfo := TypeInfo(T);
  try
    TTextWriter.RegisterCustomJSONSerializerSetOptions(RttiInfo,[soReadIgnoreUnknownFields],True);
    Result := RecordLoadJSON(Data,RawUTF8(Text),RttiInfo);
  except
    Result := False;
  end;
  if (not Result) then Data := default(T);
end;

the modified function:

class function _J_.Decode<T>(Text:string;out Data:T):Boolean;
var
  RttiInfo : Pointer;
begin
  Data := default(T);
  while (Text<>'') and (Text[Length(Text)]<>'}') do SetLength(Text,Length(Text)-1);
  if Text='' then Exit(False);
  RttiInfo := TypeInfo(T);
  try
    TTextWriter.RegisterCustomJSONSerializerSetOptions(RttiInfo,[soReadIgnoreUnknownFields],True);
    Result := RecordLoadJSON(Data,RawUTF8(Text),RttiInfo);
  except
    Result := False;
  end;
  if (not Result) then Data := default(T);
end;

#16 Re: mORMot 1 » FPC 3.3.1 Compiler Error Syncommons » 2020-07-16 13:33:39

Please not that the problem persisted with:
Lazarus: 2.0.10
FPC: 3.2.0

SynCommons.pas(24977,17) Error: Unknown identifier "R8D"

#17 Re: mORMot 1 » FPC 3.3.1 Compiler Error Syncommons » 2020-07-16 08:14:37

Please note this repository : https://github.com/synopse/mORMot

Code is checked out  using https://github.com/synopse/mORMot.git/trunk and TortoiseSVN giving 9577 as revision.

I'll try FPC 3.2.

Best regards.

#18 mORMot 1 » FPC 3.3.1 Compiler Error Syncommons » 2020-07-15 23:46:59

Hafedh TRIMECHE
Replies: 5

mORMot: SVN 9577
FPC: 3.3.1
SynCommons.pas(24987,19) Error: Assembler syntax error

{$ifdef FPC} nostackframe; assembler; asm {$else} asm .noframe {$endif FPC}
        {$ifndef win64}
        mov     r8d, len
        {$endif}
        mov     eax, crc
        xor     ecx, ecx
        test    buf, buf // buf=rdx/rsi len=r8
        jz      @z
        neg     r8
        jz      @z
        not     eax
        lea     r9, [rip + crc32ctab]
        cmp     r8, -8
        jb      @head
@sml:   mov     cl, byte ptr[buf]
        inc     buf
        xor     cl, al

#19 PDF Engine » Access Violation SaveToStream (Splwow64.exe) » 2020-06-14 15:58:09

Hafedh TRIMECHE
Replies: 1

An exception is raised when saving to stream and the TaskManager shows that splwow64.exe attached to the application as child process crashed.

===============================================================================
Application Name      : PGFClient.exe
Memory manager        : msvcrt.dll
Compiler Version      : Delphi: 33
Indy Version          : 10.6.2.0
Zeos Version          : 7.2.6-stable
Report Unique ID      : {A282DE21-643F-46E2-B4AE-AF544FF66F45}
Start Time            : 2020-06-14 15:39:48.345
Exception Time        : 2020-06-14 16:34:53.111
Application up time   :  55 minutes 4 seconds 766 milliseconds
===============================================================================
Processor             : eMachines, eMachines G640, AMD64 Family 16 Model 6 Stepping 3, AMD Athlon(tm) II P320 Dual-Core Processor, 2.095 GHz
System                : Windows 10 (Version 10.0, Build 18362, 64-bit Edition)
Display               : 1680x1050 pixels, 96 bpp
Total Physical Memory :   5.748 GB
Free Physical Memory  :   1.988 GB
Max used Memory       :   169.383 MB
===============================================================================
Exception class       : EAccessViolation
Access violation at address 00408F7E in module 'PGFClient.exe'. Read of address 0000000D
Exception trigger     : UnhandledException
-------------------------------------------------------------------------------
Module                : System
Command Line          : _RESTARTTRATSER_432
Procedure             : System.TObject.Free
-------------------------------------------------------------------------------
[00408F7E] System.TObject.Free + $6
[00C5AB54] SynPdf.TPdfDocument.SaveToStreamDirectBegin (Line 5855, "SynPdf.pas" + 37) + $22
[00C6347A] SynPdf.TPdfPageGDI.FlushVCLCanvas (Line 8841, "SynPdf.pas" + 3) + $15
[00C63091] SynPdf.TPdfDocumentGDI.SaveToStream (Line 8765, "SynPdf.pas" + 6) + $3
[00D0975F] uHTMLViewer.THTMLDisplay.ExportToPDF (Line 108, "uHTMLViewer.pas" + 36) + $18
[00DEA258] uClient.TMainForm.ExportHTMLReport (Line 1994, "uClient.pas" + 8) + $B
[00DFC650] uClient.TMainForm.TxRequestSelectRow (Line 5230, "uClient.pas" + 5) + $7
[00BB0FF7] ucStringGrid.TUStringGrid.dodbClick (Line 229, "ucStringGrid.pas" + 5) + $18
[00575CE5] Vcl.Controls.TControl.DblClick + $15
[00BA8EB2] Vcl.Grids.TCustomGrid.MouseDown (Line 685, "" + 0) + $9DD5
[00BB0EB5] ucStringGrid.TUStringGrid.MouseDown (Line 201, "ucStringGrid.pas" + 1) + $D
[00409346] System.@CallDynaInst + $6
[00575DB0] Vcl.Controls.TControl.DoMouseDown + $88
[00574167] Vcl.Controls.TControl.SetMouseCapture + $17
[00575E6F] Vcl.Controls.TControl.WMLButtonDblClk + $47
[0057576E] Vcl.Controls.TControl.WndProc + $2BE
[0066C665] Vcl.Forms.TCustomForm.WndProc + $64D
[0057A223] Vcl.Controls.TWinControl.WndProc + $63B
[00409F18] System.TMonitor.TryEnter + $28
[00409A40] System.TMonitor.Enter + $10
[00BC698D] uMainForm.TUForm.WndProc (Line 1581, "uMainForm.pas" + 65) + $23
[004098AC] System.TMonitor.CheckOwningThread + $4
[00409BCE] System.TMonitor.Exit + $6
[00409C2A] System.TMonitor.Exit + $1A
[00548EEB] Vcl.Graphics.FreeMemoryContexts + $9B
[005797F0] Vcl.Controls.TWinControl.MainWndProc + $2C
[00579805] Vcl.Controls.TWinControl.MainWndProc + $41
[004DDDC0] System.Classes.StdWndProc + $14
[00579A31] Vcl.Controls.TWinControl.IsControlMouseMsg + $65
[0057A223] Vcl.Controls.TWinControl.WndProc + $63B
[005797F0] Vcl.Controls.TWinControl.MainWndProc + $2C
[004DDDC0] System.Classes.StdWndProc + $14
[00676053] Vcl.Forms.TApplication.ProcessMessage + $F3
[00676096] Vcl.Forms.TApplication.HandleMessage + $A
[006763C9] Vcl.Forms.TApplication.Run + $C9
[00E2C30D] PGFClient.PGFClient (Line 18, "" + -935) + $7

#20 Source Code repository » Email notification not working » 2020-04-07 20:14:47

Hafedh TRIMECHE
Replies: 0

Please note that notification related to new post I submit is not sent when Subscribe to this topic is checked

Best regards.

#21 mORMot 1 » Base64 decoding problem » 2020-04-07 13:09:25

Hafedh TRIMECHE
Replies: 4

This Base64 encoded message won't be decoded because of the LineBreak after each 76 characters!

MIIBuTCCASKgAwIBAgIQNdNhtuV5GbNHYZsf+LvM0zANBgkqhkiG9w0BAQUFADAb
MRkwFwYDVQQDExBFZGlkZXYgU21va2VUZXN0MB4XDTA4MTExMjE5NTEzNVoXDTM5
MTIzMTIzNTk1OVowGzEZMBcGA1UEAxMQRWRpZGV2IFNtb2tlVGVzdDCBnzANBgkq
hkiG9w0BAQEFAAOBjQAwgYkCgYEAm6zGzqxejwswWTNLcSsa7P8xqODspX9VQBuq
5W1RoTgQ0LNR64+7ywLjH8+wrb/lB6QV7s2SFUiWDeduVesvMJkWtZ5zzQyl3iUa
CBpT4S5AaO3/wkYQSKdI108pXH7Aue0e/ZOwgEEX1N6OaPQn7AmAB4uq1h+ffw+r
RKNHqnsCAwEAATANBgkqhkiG9w0BAQUFAAOBgQCZmj+pgRsN6HpoICawK3XXNAmi
cgfQkailX9akIjD3xSCwEQx4nG6tZjTz30u4NoSffW7pch58SxuZQDqW5NsJcQNq
Ngo/dMoqqpXdi2/0BYEcJ8pjsngrFm+fM2BnyGpXH7aWuKsWjVFGlWlF+yi8I35Q
8wFJt2Z/XGA7WWDjvw==

Please note that Base64ToBinSafe is used for decoding.

#22 Re: mORMot 1 » Convert Data to Json failed [TypeInfo] » 2020-04-01 11:15:03

Thank you.

It worked well with revision: 8984

Best regards.

#23 PDF Engine » HTMLViewer SynPDF vs llPDFLib » 2020-03-29 22:29:46

Hafedh TRIMECHE
Replies: 0

Hello,

Using this library https://github.com/BerndGabriel/HtmlViewer to render HTML document and convert it to PDF using SynPDF or llPDFLib (https://github.com/sybrexsys/llPDFLib).

The result is quite faithful using the llPDFLib.

SynPDF generates margin issues.

Please find the 2 documents linked:
-SynPDF Report-SynPDF.pdf
-llPDFLib Report-llPDFLib.pdf

Best regards.

#24 mORMot 1 » Convert Data to Json failed [TypeInfo] » 2020-03-29 22:09:09

Hafedh TRIMECHE
Replies: 2

https://github.com/synopse/mORMot

SVN Version: 8975
-------------------------------
This structure used to generate Json by invoking the function _J_.Encode.
The function failed giving the file linked TCPAuth.Json.

  TTCPAuthentication =
  packed record
    HostUniqueID       : string;
    ApplicationName    : string;
    ApplicationVersion : Extended;
    LicenseRequired    : Boolean;
    JsonLicense        : string;
    LicenseRequested   : Boolean;
    Cert               : string;
    SessionID          : Int64;
    Challenge          : string;
    Signature          : TBytes;
    CompressAlgo       : string;
    UserProfile        : Byte;
    function  Marshal:TBytes;
    procedure Unmarshal(Bytes:TBytes);
  end;

class function _J_.Encode<T>(Data:T):string;
var
  RttiInfo : Pointer;
begin
  try
    RttiInfo := TypeInfo(T);
    TTextWriter.RegisterCustomJSONSerializerSetOptions(RttiInfo,[soWriteIgnoreDefault],True);
    Result := string(RecordSaveJSON(Data,RttiInfo,True));
  except
    Result := '';
  end;
end;

SVN Version: 8777
-------------------------------
Please note that Json conversion worked well with this version.

Best regards.

#25 mORMot 1 » SynCommons Exception Class External:SIGSEGV » 2019-10-06 23:09:20

Hafedh TRIMECHE
Replies: 8

Lazarus: 2.0.4
FPC: 3.3.1

Unit SynFPCTypInfo modified

procedure FPCDynArrayClear(var a: Pointer; TypeInfo: Pointer);external name 'FPC_DYNARRAY_CLEAR';
procedure FPCFinalizeArray(p: Pointer; TypeInfo: Pointer; elemCount: PtrUInt);external name 'FPC_FINALIZE_ARRAY';
procedure FPCFinalize(Data: Pointer; TypeInfo: Pointer);external name 'FPC_FINALIZE';
procedure FPCRecordCopy(const Source; var Dest; TypeInfo: pointer);external name 'FPC_COPY';
procedure FPCRecordAddRef(var Data; TypeInfo : pointer);external name 'FPC_ADDREF';

Running a program only containing SynCommons unit generated this exception:

Project BodetWS raised exception class 'External: SIGSEGV'.

In file '..\..\..\Developer\lib\mORMot\SynCommons.pas' at line 49337

The exception code:

fElemType := PTypeInfo(aTypeInfo)^.elType;
  if fElemType<>nil then begin
    {$ifndef HASDIRECTTYPEINFO}
    // FPC compatibility: if you have a GPF here at startup, your 3.1 trunk
    // revision seems older than June 2016
    // -> enable HASDIRECTTYPEINFO conditional below $ifdef VER3_1 in Synopse.inc
    // or in your project's options
    fElemType := PPointer(fElemType)^; // inlined DeRef()
    {$endif HASDIRECTTYPEINFO}
    {$ifdef FPC}
    if not (PTypeKind(fElemType)^ in tkManagedTypes) then
      fElemType := nil; // as with Delphi
    {$endif FPC}
  end;

#26 mORMot 1 » Lazarus Compilation Error mORMot Version 6745 » 2019-04-06 08:57:43

Hafedh TRIMECHE
Replies: 1

mORMot: 6745
FPC: 3.0.4
Lazarus: 2.0.0
--------------------------
SynFPCTypInfo.pas(92,26) Error: Identifier not found "PRecInitData"

#27 Re: mORMot 1 » JSON Parse problem » 2018-02-06 09:33:54

By activating this option, the problem is solved soReadIgnoreUnknownFields
    TTextWriter.RegisterCustomJSONSerializerSetOptions(TypeInfo(T),[soReadIgnoreUnknownFields]);

#28 Re: mORMot 1 » JSON Parse problem » 2018-02-01 09:29:31

Simply commented the validation line:
FirstChar := JSON^;
    JSON := Reader(JSON,Rec,wasValid);
//    if not wasValid then exit;

Solved the problem which is treated as follows:
The parse continues even the current field doesn't exist in the RTTI schema (Record definition).

Would you please confirm?

Regards

#29 Re: mORMot 1 » JSON Parse problem » 2018-01-31 19:49:59

Would please test the attached program?

The commented text located above then "ProfileID" definition related to the TAffiliate record.

https://mega.nz/#!L1IygQRT!-plkrXfdJISG … sne42MK1M4

#30 Re: mORMot 1 » JSON Parse problem » 2018-01-31 18:53:26

Hello,

4485 is from this repository https://github.com/synopse/mORMot.git/trunk

Please consider this record definition: https://mega.nz/#!7wJ2hLTA!q_b9PDpj_K9g … NrqWGvGlro

Please also note that inserting the last JSON data "ProfileID" as Cardinal in any position into the record definition solved the problem.

Any JSON item not correspond to the RTTI schema should be ignored.

Regards

#31 mORMot 1 » JSON Parse problem » 2018-01-31 16:07:06

Hafedh TRIMECHE
Replies: 6

Version: 4885

This JSON text can't be parsed using RecordLoadJSON function and the reader reported false assigned to wasValid

    FirstChar := JSON^;
    JSON := Reader(JSON,Rec,wasValid);
    if not wasValid then
      exit;


  '{"Head":{"RECORD_AUTOINC":2,"RECORD_INDICATOR":3565564291285041560},"Account":"BA83283277F8999","BIC":"FNBOUS44","InstitutionAccount":"7770100000","FinancialAccount":"12345678901234567890","EncryptionKey":"CCCA01A25A7CF5A98109","Currency":840,"MultiCurrency":true,"CommonName":"MERCHANT.strong-data.COM","Subject":1994948748,"CASubject":1788932080,"Issuer":"Users CA","ProfileID":11}

#32 mORMot 1 » Serialization using RecordSave problem » 2016-12-23 13:23:07

Hafedh TRIMECHE
Replies: 1

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;
---------------------------------------------------------------------------------------------------------------------------------------------------------------------

Board footer

Powered by FluxBB