Explorar el Código

* Do not generate access violations on empty json-strings
* Added DoBeforeReadObject and DoAfterReadObject
* Ability to alter the mapping between properties and JSON-elements

git-svn-id: trunk@39536 -

joost hace 7 años
padre
commit
5eb97ce700
Se han modificado 1 ficheros con 39 adiciones y 9 borrados
  1. 39 9
      packages/fcl-json/src/fpjsonrtti.pp

+ 39 - 9
packages/fcl-json/src/fpjsonrtti.pp

@@ -134,6 +134,9 @@ Type
     Function ExtractDateTime(S : String): TDateTime;
     Function ExtractDateTime(S : String): TDateTime;
     function GetObject(AInstance : TObject; const APropName: TJSONStringType; D: TJSONObject; PropInfo: PPropInfo): TObject;
     function GetObject(AInstance : TObject; const APropName: TJSONStringType; D: TJSONObject; PropInfo: PPropInfo): TObject;
     procedure DoRestoreProperty(AObject: TObject; PropInfo: PPropInfo;  PropData: TJSONData); virtual;
     procedure DoRestoreProperty(AObject: TObject; PropInfo: PPropInfo;  PropData: TJSONData); virtual;
+    function DoMapProperty(AObject: TObject; PropInfo: PPropInfo; JSON: TJSONObject): TJSONData; virtual;
+    procedure DoBeforeReadObject(Const JSON: TJSONObject; AObject: TObject); virtual;
+    procedure DoAfterReadObject(Const JSON: TJSONObject; AObject: TObject); virtual;
     Function ObjectFromString(Const JSON : TJSONStringType) : TJSONData; virtual;
     Function ObjectFromString(Const JSON : TJSONStringType) : TJSONData; virtual;
     procedure RestoreProperty(AObject: TObject; PropInfo: PPropInfo; PropData: TJSONData);
     procedure RestoreProperty(AObject: TObject; PropInfo: PPropInfo; PropData: TJSONData);
   Public
   Public
@@ -240,6 +243,10 @@ Var
 
 
 begin
 begin
   D:=ObjectFromString(JSON);
   D:=ObjectFromString(JSON);
+
+  if not Assigned(D) then
+    Exit;
+
   try
   try
     If D.JSONType=jtObject then
     If D.JSONType=jtObject then
       JSONToObject(D as TJSONObject,AObject)
       JSONToObject(D as TJSONObject,AObject)
@@ -505,15 +512,38 @@ begin
   end;
   end;
 end;
 end;
 
 
+function TJSONDeStreamer.DoMapProperty(AObject: TObject; PropInfo: PPropInfo; JSON: TJSONObject): TJSONData;
+var
+  J: Integer;
+begin
+  J := JSON.IndexOfName(PropInfo^.Name,(jdoCaseInsensitive in Options));
+  if J > -1 then
+    Result := JSON.Items[J]
+  else
+    Result := nil;
+end;
+
+procedure TJSONDeStreamer.DoBeforeReadObject(Const JSON: TJSONObject; AObject: TObject);
+begin
+  If Assigned(FBeforeReadObject) then
+    FBeforeReadObject(Self,AObject,JSON);
+end;
+
+procedure TJSONDeStreamer.DoAfterReadObject(Const JSON: TJSONObject; AObject: TObject);
+begin
+  If Assigned(FAfterReadObject) then
+    FAfterReadObject(Self,AObject,JSON)
+end;
+
 procedure TJSONDeStreamer.JSONToObject(const JSON: TJSONObject; AObject: TObject
 procedure TJSONDeStreamer.JSONToObject(const JSON: TJSONObject; AObject: TObject
   );
   );
 Var
 Var
-  I,J : Integer;
+  I : Integer;
   PIL : TPropInfoList;
   PIL : TPropInfoList;
+  JD: TJSONData;
 
 
 begin
 begin
-  If Assigned(FBeforeReadObject) then
-    FBeforeReadObject(Self,AObject,JSON);
+  DoBeforeReadObject(JSON, AObject);
   If (AObject is TStrings) then
   If (AObject is TStrings) then
     JSONToStrings(JSON,AObject as TStrings)
     JSONToStrings(JSON,AObject as TStrings)
   else If (AObject is TCollection) then
   else If (AObject is TCollection) then
@@ -524,16 +554,15 @@ begin
     try
     try
       For I:=0 to PIL.Count-1 do
       For I:=0 to PIL.Count-1 do
         begin
         begin
-        J:=JSON.IndexOfName(Pil.Items[i]^.Name,(jdoCaseInsensitive in Options));
-        If (J<>-1) then
-          RestoreProperty(AObject,PIL.Items[i],JSON.Items[J]);
+        JD:=DoMapProperty(AObject, Pil.Items[i], JSON);
+        If Assigned(JD) then
+          RestoreProperty(AObject,PIL.Items[i],JD);
         end;
         end;
     finally
     finally
       FreeAndNil(PIL);
       FreeAndNil(PIL);
     end;
     end;
     end;
     end;
-  If Assigned(FAfterReadObject) then
-    FAfterReadObject(Self,AObject,JSON)
+  DoAfterReadObject(JSON, AObject);
 end;
 end;
 
 
 procedure TJSONDeStreamer.JSONToCollection(const JSON: TJSONStringType;
 procedure TJSONDeStreamer.JSONToCollection(const JSON: TJSONStringType;
@@ -544,7 +573,8 @@ Var
 begin
 begin
   D:=ObjectFromString(JSON);
   D:=ObjectFromString(JSON);
   try
   try
-    JSONToCollection(D,ACollection);
+    if Assigned(D) then
+      JSONToCollection(D,ACollection);
   finally
   finally
     D.Free;
     D.Free;
   end;
   end;