|
@@ -7,7 +7,7 @@
|
|
|
Author : Kike Pérez
|
|
|
Version : 1.11
|
|
|
Created : 21/05/2018
|
|
|
- Modified : 05/04/2020
|
|
|
+ Modified : 07/04/2020
|
|
|
|
|
|
This file is part of QuickLib: https://github.com/exilon/QuickLib
|
|
|
|
|
@@ -45,7 +45,7 @@ uses
|
|
|
strUtils,
|
|
|
//jsonreader,
|
|
|
//fpjsonrtti,
|
|
|
- Quick.Json.fpc.Compatibility,
|
|
|
+ Quick.Json.fpc.Compatibility,
|
|
|
{$ELSE}
|
|
|
{$IFDEF DELPHIXE7_UP}
|
|
|
System.Json,
|
|
@@ -90,7 +90,7 @@ type
|
|
|
function JsonToObject(aType: TClass; const aJson: string): TObject; overload;
|
|
|
function JsonToObject(aObject: TObject; const aJson: string): TObject; overload;
|
|
|
function ObjectToJson(aObject : TObject; aIndent : Boolean = False): string;
|
|
|
- function ValueToJson(aValue : TValue; aIndent : Boolean = False) : string;
|
|
|
+ function ValueToJson(const aValue : TValue; aIndent : Boolean = False) : string;
|
|
|
end;
|
|
|
|
|
|
TSerializeLevel = (slPublicProperty, slPublishedProperty);
|
|
@@ -108,7 +108,7 @@ type
|
|
|
function GetPropertyValue(Instance : TObject; const PropertyName : string) : TValue;
|
|
|
function GetPropertyValueFromObject(Instance : TObject; const PropertyName : string) : TValue;
|
|
|
{$IFNDEF FPC}
|
|
|
- function GetFieldValueFromRecord(aValue : TValue; const FieldName : string) : TValue;
|
|
|
+ function GetFieldValueFromRecord(const aValue : TValue; const FieldName : string) : TValue;
|
|
|
{$ENDIF}
|
|
|
procedure SetPropertyValue(Instance : TObject; aPropInfo : PPropInfo; aValue : TValue); overload;
|
|
|
procedure SetPropertyValue(Instance : TObject; const PropertyName : string; aValue : TValue); overload;
|
|
@@ -121,33 +121,31 @@ type
|
|
|
constructor Create(aSerializeLevel : TSerializeLevel; aUseEnumNames : Boolean = True);
|
|
|
property UseEnumNames : Boolean read fUseEnumNames write fUseEnumNames;
|
|
|
property UseJsonCaseSense : Boolean read fUseJsonCaseSense write fUseJsonCaseSense;
|
|
|
+ function GetJsonPairValueByName(aJson : TJSONObject; const aName : string) : TJsonValue;
|
|
|
+ function GetJsonPairByName(aJson : TJSONObject; const aName : string) : TJSONPair;
|
|
|
+ //serialize methods
|
|
|
+ function SerializeValue(const aValue : TValue) : TJSONValue;
|
|
|
+ function SerializeObject(aObject : TObject) : TJSONObject; overload;
|
|
|
{$IFNDEF FPC}
|
|
|
- function DeserializeDynArray(aTypeInfo : PTypeInfo; aObject : TObject; const aJsonArray: TJSONArray) : TValue;
|
|
|
- function DeserializeRecord(aRecord : TValue; aObject : TObject; const aJson : TJSONObject) : TValue;
|
|
|
+ function SerializeDynArray(const aValue: TValue) : TJsonArray;
|
|
|
+ function SerializeRecord(const aValue : TValue) : TJSONValue;
|
|
|
{$ELSE}
|
|
|
- procedure DeserializeDynArray(aTypeInfo: PTypeInfo; const aPropertyName : string; aObject: TObject; const aJsonArray: TJSONArray);
|
|
|
+ function SerializeObject(aObject : TObject; aType : TTypeKind; const aPropertyName : string) : TJSONPair;
|
|
|
{$ENDIF}
|
|
|
+ //deserialize methods
|
|
|
function DeserializeClass(aType : TClass; const aJson : TJSONObject) : TObject;
|
|
|
function DeserializeObject(aObject : TObject; const aJson : TJSONObject) : TObject; overload;
|
|
|
- {$IFNDEF FPC}
|
|
|
- function DeserializeList(aObject: TObject; const aName : string; const aJson: TJSONObject) : TObject;
|
|
|
- procedure DeserializeXArray(Instance : TObject; aRecord : TValue; aProperty : TRttiProperty; const aPropertyName : string; aJson : TJsonObject);
|
|
|
- {$ENDIF}
|
|
|
function DeserializeProperty(aObject : TObject; const aName : string; aProperty : TRttiProperty; const aJson : TJSONObject) : TObject; overload;
|
|
|
{$IFNDEF FPC}
|
|
|
function DeserializeType(aObject : TObject; aType : TTypeKind; aTypeInfo : PTypeInfo; const aValue: string) : TValue;
|
|
|
+ function DeserializeDynArray(aTypeInfo : PTypeInfo; aObject : TObject; const aJsonArray: TJSONArray) : TValue;
|
|
|
+ function DeserializeRecord(const aRecord : TValue; aObject : TObject; const aJson : TJSONObject) : TValue;
|
|
|
+ function DeserializeList(aObject: TObject; const aName : string; const aJson: TJSONObject) : TObject;
|
|
|
+ procedure DeserializeXArray(Instance : TObject; aRecord : TValue; aProperty : TRttiProperty; const aPropertyName : string; aJson : TJsonObject);
|
|
|
{$ELSE}
|
|
|
function DeserializeType(aObject : TObject; aType : TTypeKind; const aPropertyName, aValue: string) : TValue;
|
|
|
+ procedure DeserializeDynArray(aTypeInfo: PTypeInfo; const aPropertyName : string; aObject: TObject; const aJsonArray: TJSONArray);
|
|
|
{$ENDIF}
|
|
|
- {$IFNDEF FPC}
|
|
|
- function Serialize(const aName : string; aValue : TValue) : TJSONPair; overload;
|
|
|
- {$ELSE}
|
|
|
- function Serialize(aObject : TObject; aType : TTypeKind; const aPropertyName : string) : TJSONPair;
|
|
|
- function Serialize(const aName : string; aValue : TValue) : TJSONPair;
|
|
|
- {$ENDIF}
|
|
|
- function Serialize(aObject : TObject) : TJSONObject; overload;
|
|
|
- function GetJsonPairValueByName(aJson : TJSONObject; const aName : string) : TJsonValue;
|
|
|
- function GetJsonPairByName(aJson : TJSONObject; const aName : string) : TJSONPair;
|
|
|
end;
|
|
|
|
|
|
TJsonSerializer = class(TInterfacedObject,IJsonSerializer)
|
|
@@ -169,20 +167,26 @@ type
|
|
|
function JsonToObject(aObject : TObject; const aJson: string) : TObject; overload;
|
|
|
function ObjectToJson(aObject : TObject; aIndent : Boolean = False): string;
|
|
|
function ObjectToJsonString(aObject : TObject; aIndent : Boolean = False): string;
|
|
|
- function ValueToJson(aValue : TValue; aIndent : Boolean = False) : string;
|
|
|
- function ValueToJsonString(aValue : TValue; aIndent : Boolean = False) : string;
|
|
|
+ function ValueToJson(const aValue : TValue; aIndent : Boolean = False) : string;
|
|
|
+ function ValueToJsonString(const aValue : TValue; aIndent : Boolean = False) : string;
|
|
|
function ArrayToJson<T>(aArray : TArray<T>; aIndent : Boolean = False) : string;
|
|
|
function ArrayToJsonString<T>(aArray : TArray<T>; aIndent : Boolean = False) : string;
|
|
|
{$IFNDEF FPC}
|
|
|
function JsonToArray<T>(const aJson : string) : TArray<T>;
|
|
|
+ function JsonToValue(const aJson: string): TValue;
|
|
|
{$ENDIF}
|
|
|
end;
|
|
|
|
|
|
+ EJsonSerializerError = class(Exception);
|
|
|
+
|
|
|
PPByte = ^PByte;
|
|
|
|
|
|
resourcestring
|
|
|
- cNotSupportedDataType = 'Not supported "%s" data type "%s"';
|
|
|
+ cNotSupportedDataType = 'Not supported data type "%s"';
|
|
|
+ cSerializeObjectError = 'Serialize object "%s" error: %s';
|
|
|
+ cSerializePropertyError = 'Property "%s" ("%s")';
|
|
|
cNotSerializable = 'Object is not serializable';
|
|
|
+ cNotValidJson = 'Not a valid Json';
|
|
|
|
|
|
implementation
|
|
|
|
|
@@ -323,7 +327,7 @@ end;
|
|
|
{$ENDIF}
|
|
|
|
|
|
{$IFNDEF FPC}
|
|
|
-function TRTTIJson.DeserializeRecord(aRecord : TValue; aObject : TObject; const aJson : TJSONObject) : TValue;
|
|
|
+function TRTTIJson.DeserializeRecord(const aRecord : TValue; aObject : TObject; const aJson : TJSONObject) : TValue;
|
|
|
var
|
|
|
ctx : TRttiContext;
|
|
|
rRec : TRttiRecordType;
|
|
@@ -501,7 +505,7 @@ begin
|
|
|
rProp := rType.GetProperty('List');
|
|
|
if rProp = nil then Exit;
|
|
|
|
|
|
-
|
|
|
+ //check if exists List (denotes delphi json serialized) or not (normal json serialized)
|
|
|
member := GetJsonPairValueByName(aJson,aName);
|
|
|
if member = nil then jArray := TJSONObject.ParseJSONValue(aJson.ToJSON) as TJSONArray
|
|
|
else jArray := TJSONObject.ParseJSONValue(member.ToJSON) as TJSONArray;
|
|
@@ -890,9 +894,8 @@ begin
|
|
|
for i := 0 to aJson.Count - 1 do
|
|
|
begin
|
|
|
candidate := aJson.Pairs[I];
|
|
|
- if candidate.JsonValue = nil then Exit(nil);
|
|
|
- if CompareText(candidate.JsonString{$IFNDEF FPC}.Value{$ENDIF},aName) = 0 then
|
|
|
- Exit(candidate.JsonValue);
|
|
|
+ if candidate.JsonValue = nil then continue;
|
|
|
+ if CompareText(candidate.JsonString{$IFNDEF FPC}.Value{$ENDIF},aName) = 0 then Exit(candidate.JsonValue);
|
|
|
end;
|
|
|
end;
|
|
|
Result := nil;
|
|
@@ -914,7 +917,7 @@ begin
|
|
|
for i := 0 to aJson.Count - 1 do
|
|
|
begin
|
|
|
Result := aJson.Pairs[I];
|
|
|
- if Result.JsonValue = nil then Exit(nil);
|
|
|
+ if Result.JsonValue = nil then continue;
|
|
|
if CompareText(Result.JsonString{$IFNDEF FPC}.Value{$ENDIF},aName) = 0 then Exit;
|
|
|
end;
|
|
|
end;
|
|
@@ -976,7 +979,7 @@ begin
|
|
|
end;
|
|
|
|
|
|
{$IFNDEF FPC}
|
|
|
-function TRTTIJson.GetFieldValueFromRecord(aValue : TValue; const FieldName : string) : TValue;
|
|
|
+function TRTTIJson.GetFieldValueFromRecord(const aValue : TValue; const FieldName : string) : TValue;
|
|
|
var
|
|
|
ctx : TRttiContext;
|
|
|
rec : TRttiRecordType;
|
|
@@ -1054,7 +1057,7 @@ begin
|
|
|
end;
|
|
|
{$ENDIF}
|
|
|
|
|
|
-function TRTTIJson.Serialize(aObject: TObject): TJSONObject;
|
|
|
+function TRTTIJson.SerializeObject(aObject: TObject): TJSONObject;
|
|
|
var
|
|
|
ctx: TRttiContext;
|
|
|
{$IFNDEF FPC}
|
|
@@ -1076,8 +1079,8 @@ begin
|
|
|
|
|
|
Result := TJSONObject.Create;
|
|
|
try
|
|
|
+ propertyname := '';
|
|
|
rType := ctx.GetType(aObject.ClassInfo);
|
|
|
- //s := rType.ToString;
|
|
|
for rProp in TRTTI.GetProperties(rType,roFirstBase) do
|
|
|
begin
|
|
|
ExcludeSerialize := False;
|
|
@@ -1102,33 +1105,32 @@ begin
|
|
|
{$ENDIF}
|
|
|
begin
|
|
|
propvalue := rProp.GetValue(aObject);
|
|
|
+ jpair := TJSONPair.Create(propertyName,nil);
|
|
|
if (propvalue.IsObject) and (IsGenericList(propvalue.AsObject)) then
|
|
|
begin
|
|
|
- jpair := Serialize(propertyname,GetPropertyValueFromObject(propvalue.AsObject,'List'));
|
|
|
+ jpair.JsonValue := SerializeValue(GetPropertyValueFromObject(propvalue.AsObject,'List'));
|
|
|
end
|
|
|
{$IFNDEF FPC}
|
|
|
else if (not propvalue.IsObject) and (IsGenericXArray(propvalue{$IFNDEF NEXTGEN}.TypeInfo.Name{$ELSE}.TypeInfo.NameFld.ToString{$ENDIF})) then
|
|
|
begin
|
|
|
- jpair := Serialize(propertyname,GetFieldValueFromRecord(propvalue,'fArray'));
|
|
|
+ jpair.JsonValue := SerializeValue(GetFieldValueFromRecord(propvalue,'fArray'));
|
|
|
end
|
|
|
{$ENDIF}
|
|
|
else
|
|
|
begin
|
|
|
{$IFNDEF FPC}
|
|
|
- jpair := Serialize(propertyname,propvalue);
|
|
|
+ jpair.JsonValue := SerializeValue(propvalue);
|
|
|
{$ELSE}
|
|
|
- jpair := Serialize(aObject,rProp.PropertyType.TypeKind,propertyname);
|
|
|
+ jpair.JsonValue := SerializeValue(propvalue);// SerializeObject(aObject,rProp.PropertyType.TypeKind,propertyname);
|
|
|
{$ENDIF}
|
|
|
end;
|
|
|
//s := jpair.JsonValue.ToString;
|
|
|
- if jpair <> nil then
|
|
|
+ if jpair.JsonValue <> nil then
|
|
|
begin
|
|
|
Result.AddPair(jpair);
|
|
|
end
|
|
|
else jpair.Free;
|
|
|
end;
|
|
|
- //Result.AddPair(Serialize(rProp.Name,rProp.GetValue(aObject)));
|
|
|
- //s := Result.ToJSON;
|
|
|
end;
|
|
|
end;
|
|
|
end;
|
|
@@ -1136,7 +1138,8 @@ begin
|
|
|
on E : Exception do
|
|
|
begin
|
|
|
Result.Free;
|
|
|
- raise EJsonSerializeError.CreateFmt('Serialize error object "%s" : %s',[aObject.ClassName,e.Message]);
|
|
|
+ if not propertyname.IsEmpty then raise EJsonSerializeError.CreateFmt('Serialize Error -> Object property: "%s" (%s)',[propertyname,e.Message])
|
|
|
+ else raise EJsonSerializeError.CreateFmt('Serialize Error -> Object (%s)',[e.Message]);
|
|
|
end;
|
|
|
end;
|
|
|
end;
|
|
@@ -1151,154 +1154,183 @@ begin
|
|
|
TValue.Make(aAddr,aTypeInfo,Result);
|
|
|
end;
|
|
|
|
|
|
-{$IFNDEF FPC}
|
|
|
-function TRTTIJson.Serialize(const aName : string; aValue : TValue) : TJSONPair;
|
|
|
-var
|
|
|
- ctx: TRttiContext;
|
|
|
- rRec : TRttiRecordType;
|
|
|
- rField : TRttiField;
|
|
|
- rDynArray : TRTTIDynamicArrayType;
|
|
|
- json : TJSONObject;
|
|
|
- jArray : TJSONArray;
|
|
|
- jPair : TJSONPair;
|
|
|
- jValue : TJSONValue;
|
|
|
- i : Integer;
|
|
|
+function TRTTIJson.SerializeValue(const aValue : TValue) : TJSONValue;
|
|
|
begin
|
|
|
- Result := TJSONPair.Create(aName,nil);
|
|
|
- //Result.JsonString := TJSONString(aName);
|
|
|
- try
|
|
|
- case avalue.Kind of
|
|
|
- tkDynArray :
|
|
|
- begin
|
|
|
- jArray := TJSONArray.Create;
|
|
|
- rDynArray := ctx.GetType(aValue.TypeInfo) as TRTTIDynamicArrayType;
|
|
|
- for i := 0 to aValue.GetArrayLength - 1 do
|
|
|
- begin
|
|
|
- if not GetValue(PPByte(aValue.GetReferenceToRawData)^ + rDynArray.ElementType.TypeSize * i, rDynArray.ElementType).IsEmpty then
|
|
|
- begin
|
|
|
- jValue := nil;
|
|
|
- jPair := Serialize(aName,GetValue(PPByte(aValue.GetReferenceToRawData)^ + rDynArray.ElementType.TypeSize * i, rDynArray.ElementType));
|
|
|
- try
|
|
|
- //jValue := TJsonValue(jPair.JsonValue.Clone);
|
|
|
- jValue := jPair.JsonValue;
|
|
|
- if jValue <> nil then
|
|
|
- begin
|
|
|
- jArray.AddElement(jValue);
|
|
|
- jPair.JsonValue.Owned := False;
|
|
|
- end;
|
|
|
- finally
|
|
|
- jPair.Free;
|
|
|
- if jValue <> nil then jValue.Owned := True;
|
|
|
- end;
|
|
|
- end;
|
|
|
- end;
|
|
|
- Result.JsonValue := jArray;
|
|
|
- end;
|
|
|
- tkClass :
|
|
|
- begin
|
|
|
- Result.JsonValue := TJSONValue(Serialize(aValue.AsObject));
|
|
|
- end;
|
|
|
- tkString, tkLString, tkWString, tkUString :
|
|
|
- begin
|
|
|
- Result.JsonValue := TJSONString.Create(aValue.AsString);
|
|
|
- end;
|
|
|
- tkChar, tkWChar :
|
|
|
- begin
|
|
|
- Result.JsonValue := TJSONString.Create(aValue.AsString);
|
|
|
- end;
|
|
|
- tkInteger :
|
|
|
+ Result := nil;
|
|
|
+ case avalue.Kind of
|
|
|
+ tkDynArray :
|
|
|
+ begin
|
|
|
+ {$IFNDEF FPC}
|
|
|
+ Result := SerializeDynArray(aValue);
|
|
|
+ {$ENDIF}
|
|
|
+ end;
|
|
|
+ tkClass :
|
|
|
+ begin
|
|
|
+ Result := TJSONValue(SerializeObject(aValue.AsObject));
|
|
|
+ end;
|
|
|
+ tkString, tkLString, tkWString, tkUString :
|
|
|
+ begin
|
|
|
+ Result := TJSONString.Create(aValue.AsString);
|
|
|
+ end;
|
|
|
+ tkChar, tkWChar :
|
|
|
+ begin
|
|
|
+ Result := TJSONString.Create(aValue.AsString);
|
|
|
+ end;
|
|
|
+ tkInteger :
|
|
|
+ begin
|
|
|
+ Result := TJSONNumber.Create(aValue.AsInteger);
|
|
|
+ end;
|
|
|
+ tkInt64 :
|
|
|
+ begin
|
|
|
+ Result := TJSONNumber.Create(aValue.AsInt64);
|
|
|
+ end;
|
|
|
+ tkFloat :
|
|
|
+ begin
|
|
|
+ if aValue.TypeInfo = TypeInfo(TDateTime) then
|
|
|
begin
|
|
|
- Result.JsonValue := TJSONNumber.Create(aValue.AsInteger);
|
|
|
- end;
|
|
|
- tkInt64 :
|
|
|
+ if aValue.AsExtended <> 0.0 then Result := TJSONString.Create(DateTimeToJsonDate(aValue.AsExtended));
|
|
|
+ end
|
|
|
+ else if aValue.TypeInfo = TypeInfo(TDate) then
|
|
|
begin
|
|
|
- Result.JsonValue := TJSONNumber.Create(aValue.AsInt64);
|
|
|
- end;
|
|
|
- tkFloat :
|
|
|
+ if aValue.AsExtended <> 0.0 then Result := TJSONString.Create(DateToStr(aValue.AsExtended));
|
|
|
+ end
|
|
|
+ else if aValue.TypeInfo = TypeInfo(TTime) then
|
|
|
begin
|
|
|
- if aValue.TypeInfo = TypeInfo(TDateTime) then
|
|
|
- begin
|
|
|
- if aValue.AsExtended <> 0.0 then Result.JsonValue := TJSONString.Create(DateTimeToJsonDate(aValue.AsExtended));
|
|
|
- end
|
|
|
- else if aValue.TypeInfo = TypeInfo(TDate) then
|
|
|
- begin
|
|
|
- if aValue.AsExtended <> 0.0 then Result.JsonValue := TJSONString.Create(DateToStr(aValue.AsExtended));
|
|
|
- end
|
|
|
- else if aValue.TypeInfo = TypeInfo(TTime) then
|
|
|
- begin
|
|
|
- Result.JsonValue := TJSONString.Create(TimeToStr(aValue.AsExtended));
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- Result.JsonValue := TJSONNumber.Create(aValue.AsExtended);
|
|
|
- end;
|
|
|
- end;
|
|
|
- tkEnumeration :
|
|
|
+ Result := TJSONString.Create(TimeToStr(aValue.AsExtended));
|
|
|
+ end
|
|
|
+ else
|
|
|
begin
|
|
|
- if (aValue.TypeInfo = System.TypeInfo(Boolean)) then
|
|
|
- begin
|
|
|
- {$IFDEF DELPHIRX10_UP}
|
|
|
- Result.JsonValue := TJSONBool.Create(aValue.AsBoolean);
|
|
|
- {$ELSE}
|
|
|
- if aValue.AsBoolean then Result.JsonValue := TJsonTrue.Create
|
|
|
- else Result.JsonValue := TJsonFalse.Create;
|
|
|
- {$ENDIF}
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- //Result.JsonValue := TJSONString.Create(GetEnumName(aValue.TypeInfo,aValue.AsOrdinal));
|
|
|
- if fUseEnumNames then Result.JsonValue := TJSONString.Create(aValue.ToString)
|
|
|
- else Result.JsonValue := TJSONNumber.Create(GetEnumValue(aValue.TypeInfo,aValue.ToString));
|
|
|
- end;
|
|
|
+ Result := TJSONNumber.Create(aValue.AsExtended);
|
|
|
end;
|
|
|
- tkSet :
|
|
|
+ end;
|
|
|
+ tkEnumeration :
|
|
|
+ begin
|
|
|
+ if (aValue.TypeInfo = System.TypeInfo(Boolean)) then
|
|
|
begin
|
|
|
- Result.JsonValue := TJSONString.Create(aValue.ToString);
|
|
|
- end;
|
|
|
- tkRecord :
|
|
|
+ {$IF Defined(DELPHIRX10_UP) OR Defined(FPC)}
|
|
|
+ Result := TJSONBool.Create(aValue.AsBoolean);
|
|
|
+ {$ELSE}
|
|
|
+ if aValue.AsBoolean then Result := TJsonTrue.Create
|
|
|
+ else Result := TJsonFalse.Create;
|
|
|
+ {$ENDIF}
|
|
|
+ end
|
|
|
+ else
|
|
|
begin
|
|
|
- rRec := ctx.GetType(aValue.TypeInfo).AsRecord;
|
|
|
- if aValue.TypeInfo = System.TypeInfo(TGUID) then
|
|
|
- begin
|
|
|
- Result.JsonValue := TJSONString.Create(GUIDToString(aValue.AsType<TGUID>));
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- json := TJSONObject.Create;
|
|
|
- for rField in rRec.GetFields do
|
|
|
- begin
|
|
|
- json.AddPair(Serialize(rField.name,rField.GetValue(aValue.GetReferenceToRawData)));
|
|
|
- end;
|
|
|
- Result.JsonValue := json;
|
|
|
- end;
|
|
|
+ //Result.JsonValue := TJSONString.Create(GetEnumName(aValue.TypeInfo,aValue.AsOrdinal));
|
|
|
+ if fUseEnumNames then Result := TJSONString.Create(aValue.ToString)
|
|
|
+ else Result := TJSONNumber.Create(GetEnumValue(aValue.TypeInfo,aValue.ToString));
|
|
|
end;
|
|
|
- tkVariant :
|
|
|
- begin
|
|
|
- case VarType(aValue.AsVariant) and VarTypeMask of
|
|
|
- varInteger, varInt64 : Result.JsonValue := TJSONNumber.Create(aValue.AsInteger);
|
|
|
- varString, varUString, varEmpty : Result.JsonValue := TJSONString.Create(aValue.AsString);
|
|
|
- varDouble : Result.JsonValue := TJSONNumber.Create(aValue.AsExtended);
|
|
|
- end;
|
|
|
+ end;
|
|
|
+ {$IFDEF FPC}
|
|
|
+ tkBool :
|
|
|
+ begin
|
|
|
+ Result := TJSONBool.Create(aValue.AsBoolean);
|
|
|
+ end;
|
|
|
+ {$ENDIF}
|
|
|
+ tkSet :
|
|
|
+ begin
|
|
|
+ Result := TJSONString.Create(aValue.ToString);
|
|
|
+ end;
|
|
|
+ tkRecord :
|
|
|
+ begin
|
|
|
+ {$IFNDEF FPC}
|
|
|
+ Result := SerializeRecord(aValue);
|
|
|
+ {$ENDIF}
|
|
|
+ end;
|
|
|
+ tkVariant :
|
|
|
+ begin
|
|
|
+ {$IFNDEF FPC}
|
|
|
+ case VarType(aValue.AsVariant) and VarTypeMask of
|
|
|
+ varInteger, varInt64 : Result := TJSONNumber.Create(aValue.AsInteger);
|
|
|
+ varString, varUString, varEmpty : Result := TJSONString.Create(aValue.AsString);
|
|
|
+ varDouble : Result := TJSONNumber.Create(aValue.AsExtended);
|
|
|
end;
|
|
|
- tkMethod, tkPointer, tkClassRef ,tkInterface, tkProcedure :
|
|
|
- begin
|
|
|
- //skip these properties
|
|
|
- //FreeAndNil(Result);
|
|
|
- end
|
|
|
+ {$ENDIF}
|
|
|
+ end;
|
|
|
+ tkMethod, tkPointer, tkClassRef ,tkInterface, tkProcedure, tkUnknown :
|
|
|
+ begin
|
|
|
+ //skip these properties
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ {$IFNDEF FPC}
|
|
|
+ raise EJsonSerializeError.CreateFmt(cNotSupportedDataType,[GetTypeName(aValue.TypeInfo)]);
|
|
|
+ {$ELSE}
|
|
|
+ raise EJsonSerializeError.Create('Not supported Data Type');
|
|
|
+ {$ENDIF}
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ if Result = nil then Result := TJSONNull.Create;
|
|
|
+end;
|
|
|
+
|
|
|
+{$IFNDEF FPC}
|
|
|
+function TRTTIJson.SerializeDynArray(const aValue: TValue) : TJsonArray;
|
|
|
+var
|
|
|
+ ctx : TRttiContext;
|
|
|
+ rDynArray : TRTTIDynamicArrayType;
|
|
|
+ i : Integer;
|
|
|
+ jValue : TJSONValue;
|
|
|
+ element : Integer;
|
|
|
+ list : TList<TJSONValue>;
|
|
|
+begin
|
|
|
+ element := -1;
|
|
|
+ Result := TJSONArray.Create;
|
|
|
+ try
|
|
|
+ rDynArray := ctx.GetType(aValue.TypeInfo) as TRTTIDynamicArrayType;
|
|
|
+ list := TList<TJSONValue>.Create;
|
|
|
+ list.Capacity := aValue.GetArrayLength;
|
|
|
+ for i := 0 to aValue.GetArrayLength - 1 do
|
|
|
+ begin
|
|
|
+ if not GetValue(PPByte(aValue.GetReferenceToRawData)^ + rDynArray.ElementType.TypeSize * i, rDynArray.ElementType).IsEmpty then
|
|
|
+ begin
|
|
|
+ element := i;
|
|
|
+ jValue := SerializeValue(GetValue(PPByte(aValue.GetReferenceToRawData)^ + rDynArray.ElementType.TypeSize * i, rDynArray.ElementType));
|
|
|
+ if jValue = nil then jValue := TJSONNull.Create;
|
|
|
+ list.Add(jValue);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ Result.SetElements(list);
|
|
|
+ except
|
|
|
+ on E : Exception do
|
|
|
+ begin
|
|
|
+ if element > -1 then raise EJsonSerializeError.CreateFmt('Serialize Error -> Array[%d] (%s)',[element,e.Message])
|
|
|
+ else raise EJsonSerializeError.CreateFmt('Serialize Error -> Array (%s)',[e.Message]);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+function TRTTIJson.SerializeRecord(const aValue : TValue) : TJSONValue;
|
|
|
+var
|
|
|
+ ctx : TRttiContext;
|
|
|
+ json : TJSONObject;
|
|
|
+ rRec : TRttiRecordType;
|
|
|
+ rField : TRttiField;
|
|
|
+begin
|
|
|
+ rField := nil;
|
|
|
+ try
|
|
|
+ rRec := ctx.GetType(aValue.TypeInfo).AsRecord;
|
|
|
+ if aValue.TypeInfo = System.TypeInfo(TGUID) then
|
|
|
+ begin
|
|
|
+ Result := TJSONString.Create(GUIDToString(aValue.AsType<TGUID>));
|
|
|
+ end
|
|
|
else
|
|
|
+ begin
|
|
|
+ json := TJSONObject.Create;
|
|
|
+ for rField in rRec.GetFields do
|
|
|
begin
|
|
|
- raise EJsonSerializeError.CreateFmt(cNotSupportedDataType,[aName,GetTypeName(aValue.TypeInfo)]);
|
|
|
+ json.AddPair(rField.Name,SerializeValue(rField.GetValue(aValue.GetReferenceToRawData)));
|
|
|
end;
|
|
|
+ Result := json;
|
|
|
end;
|
|
|
- if Result.JsonValue = nil then Result.JsonValue := TJSONNull.Create;
|
|
|
except
|
|
|
on E : Exception do
|
|
|
begin
|
|
|
- Result.Free;
|
|
|
- raise EJsonSerializeError.CreateFmt('Serialize error class "%s.%s" : %s',[aName,aValue.ToString,e.Message]);
|
|
|
+ if rField <> nil then raise EJsonSerializeError.CreateFmt('Serialize Error -> Record property "%s" (%s)',[rField.Name,e.Message])
|
|
|
+ else raise EJsonSerializeError.CreateFmt('Serialize Error -> Record (%s)',[e.Message]);
|
|
|
end;
|
|
|
end;
|
|
|
end;
|
|
|
+
|
|
|
{$ELSE}
|
|
|
function TRTTIJson.GetPropType(aPropInfo: PPropInfo): PTypeInfo;
|
|
|
begin
|
|
@@ -1317,80 +1349,7 @@ begin
|
|
|
'.',fsettings.DecimalSeparator,[rfReplaceAll]);
|
|
|
end;
|
|
|
|
|
|
-function TRTTIJson.Serialize(const aName : string; aValue : TValue) : TJSONPair;
|
|
|
-begin
|
|
|
- Result := TJSONPair.Create(aName,nil);
|
|
|
- //Result.JsonString := TJSONString(aName);
|
|
|
- try
|
|
|
- case avalue.Kind of
|
|
|
- tkClass :
|
|
|
- begin
|
|
|
- Result.JsonValue := TJSONValue(Serialize(aValue.AsObject));
|
|
|
- end;
|
|
|
- tkString, tkLString, tkWString, tkUString :
|
|
|
- begin
|
|
|
- Result.JsonValue := TJSONString.Create(aValue.AsString);
|
|
|
- end;
|
|
|
- tkChar, tkWChar :
|
|
|
- begin
|
|
|
- Result.JsonValue := TJSONString.Create(aValue.AsString);
|
|
|
- end;
|
|
|
- tkInteger :
|
|
|
- begin
|
|
|
- Result.JsonValue := TJSONNumber.Create(aValue.AsInteger);
|
|
|
- end;
|
|
|
- tkInt64 :
|
|
|
- begin
|
|
|
- Result.JsonValue := TJSONNumber.Create(aValue.AsInt64);
|
|
|
- end;
|
|
|
- tkFloat :
|
|
|
- begin
|
|
|
- if aValue.TypeInfo = TypeInfo(TDateTime) then
|
|
|
- begin
|
|
|
- if aValue.AsExtended <> 0.0 then Result.JsonValue := TJSONString.Create(DateTimeToJsonDate(aValue.AsExtended));
|
|
|
- end
|
|
|
- else if aValue.TypeInfo = TypeInfo(TDate) then
|
|
|
- begin
|
|
|
- if aValue.AsExtended <> 0.0 then Result.JsonValue := TJSONString.Create(DateToStr(aValue.AsExtended));
|
|
|
- end
|
|
|
- else if aValue.TypeInfo = TypeInfo(TTime) then
|
|
|
- begin
|
|
|
- Result.JsonValue := TJSONString.Create(TimeToStr(aValue.AsExtended));
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- Result.JsonValue := TJSONNumber.Create(aValue.AsExtended);
|
|
|
- end;
|
|
|
- end;
|
|
|
- tkEnumeration :
|
|
|
- begin
|
|
|
- if (aValue.TypeInfo = System.TypeInfo(Boolean)) then
|
|
|
- begin
|
|
|
- Result.JsonValue := TJSONBool.Create(aValue.AsBoolean);
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- //Result.JsonValue := TJSONString.Create(GetEnumName(aValue.TypeInfo,aValue.AsOrdinal));
|
|
|
- if fUseEnumNames then Result.JsonValue := TJSONString.Create(aValue.ToString)
|
|
|
- else Result.JsonValue := TJSONNumber.Create(GetEnumValue(aValue.TypeInfo,aValue.ToString));
|
|
|
- end;
|
|
|
- end;
|
|
|
- tkSet :
|
|
|
- begin
|
|
|
- Result.JsonValue := TJSONString.Create(aValue.ToString);
|
|
|
- end;
|
|
|
- else
|
|
|
- begin
|
|
|
- //raise EJsonDeserializeError.CreateFmt('Not supported type "%s":%d',[aName,Integer(aValue.Kind)]);
|
|
|
- end;
|
|
|
- end;
|
|
|
- if Result.JsonValue = nil then Result.JsonValue := TJSONNull.Create;
|
|
|
- except
|
|
|
- Result.Free;
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-function TRTTIJson.Serialize(aObject : TObject; aType : TTypeKind; const aPropertyName : string) : TJSONPair;
|
|
|
+function TRTTIJson.SerializeObject(aObject : TObject; aType : TTypeKind; const aPropertyName : string) : TJSONPair;
|
|
|
var
|
|
|
propinfo : PPropInfo;
|
|
|
jArray : TJsonArray;
|
|
@@ -1421,16 +1380,8 @@ begin
|
|
|
for i := 0 to len - 1 do
|
|
|
begin
|
|
|
rItemValue := rValue.GetArrayElement(i);
|
|
|
- jPair := Serialize(aPropertyName,rItemValue);
|
|
|
- try
|
|
|
- //jValue := TJsonValue(jPair.JsonValue.Clone);
|
|
|
- jValue := jPair.JsonValue;
|
|
|
- jArray.Add(jValue);
|
|
|
- //jPair.JsonValue.Owned := False;
|
|
|
- finally
|
|
|
- jPair.Free;
|
|
|
- //jValue.Owned := True;
|
|
|
- end;
|
|
|
+ jValue := SerializeValue(rItemValue);
|
|
|
+ jArray.Add(jValue);
|
|
|
end;
|
|
|
end;
|
|
|
Result.JsonValue := jArray;
|
|
@@ -1441,7 +1392,7 @@ begin
|
|
|
end;
|
|
|
tkClass :
|
|
|
begin
|
|
|
- Result.JsonValue := TJSONValue(Serialize(GetObjectProp(aObject,aPropertyName)));
|
|
|
+ Result.JsonValue := TJSONValue(SerializeObject(GetObjectProp(aObject,aPropertyName)));
|
|
|
end;
|
|
|
tkString, tkLString, tkWString, tkUString, tkAString :
|
|
|
begin
|
|
@@ -1463,11 +1414,11 @@ begin
|
|
|
begin
|
|
|
if propinfo.PropType = TypeInfo(TDateTime) then
|
|
|
begin
|
|
|
- if aValue.AsExtended <> 0.0 then Result.JsonValue := TJSONString.Create(DateTimeToJsonDate(GetFloatProp(aObject,aPropertyName)));
|
|
|
+ Result.JsonValue := TJSONString.Create(DateTimeToJsonDate(GetFloatProp(aObject,aPropertyName)));
|
|
|
end
|
|
|
else if propinfo.PropType = TypeInfo(TDate) then
|
|
|
begin
|
|
|
- if aValue.AsExtended <> 0.0 then Result.JsonValue := TJSONString.Create(DateToStr(GetFloatProp(aObject,aPropertyName)));
|
|
|
+ Result.JsonValue := TJSONString.Create(DateToStr(GetFloatProp(aObject,aPropertyName)));
|
|
|
end
|
|
|
else if propinfo.PropType = TypeInfo(TTime) then
|
|
|
begin
|
|
@@ -1499,13 +1450,7 @@ begin
|
|
|
{$IFNDEF FPC}
|
|
|
tkRecord :
|
|
|
begin
|
|
|
- rRec := ctx.GetType(aValue.TypeInfo).AsRecord;
|
|
|
- json := TJSONObject.Create;
|
|
|
- for rField in rRec.GetFields do
|
|
|
- begin
|
|
|
- json.AddPair(Serialize(rField.name,rField.GetValue(aValue.GetReferenceToRawData)));
|
|
|
- end;
|
|
|
- Result.JsonValue := json;
|
|
|
+ Result.JsonValue := SerializeRecord(aValue);
|
|
|
end;
|
|
|
{$ENDIF}
|
|
|
tkMethod, tkPointer, tkClassRef ,tkInterface, tkProcedure :
|
|
@@ -1557,15 +1502,19 @@ function TJsonSerializer.JsonToObject(aType: TClass; const aJson: string): TObje
|
|
|
var
|
|
|
json: TJSONObject;
|
|
|
begin
|
|
|
- {$IFDEF DELPHIRX10_UP}
|
|
|
- json := TJSONObject.ParseJSONValue(aJson,True) as TJSONObject;
|
|
|
- {$ELSE}
|
|
|
- {$IFDEF FPC}
|
|
|
- json := TJSONObject(TJSONObject.ParseJSONValue(aJson,True));
|
|
|
- {$ELSE}
|
|
|
- json := TJsonObject.ParseJSONValue(TEncoding.UTF8.GetBytes(aJson),0,True) as TJSONObject;
|
|
|
- {$ENDIF}
|
|
|
- {$ENDIF}
|
|
|
+ try
|
|
|
+ {$IFDEF DELPHIRX10_UP}
|
|
|
+ json := TJSONObject.ParseJSONValue(aJson,True) as TJSONObject;
|
|
|
+ {$ELSE}
|
|
|
+ {$IFDEF FPC}
|
|
|
+ json := TJSONObject(TJSONObject.ParseJSONValue(aJson,True));
|
|
|
+ {$ELSE}
|
|
|
+ json := TJsonObject.ParseJSONValue(TEncoding.UTF8.GetBytes(aJson),0,True) as TJSONObject;
|
|
|
+ {$ENDIF}
|
|
|
+ {$ENDIF}
|
|
|
+ except
|
|
|
+ raise EJsonDeserializeError.Create(cNotValidJson);
|
|
|
+ end;
|
|
|
try
|
|
|
Result := fRTTIJson.DeserializeClass(aType,json);
|
|
|
finally
|
|
@@ -1577,15 +1526,19 @@ function TJsonSerializer.JsonToObject(aObject: TObject; const aJson: string): TO
|
|
|
var
|
|
|
json: TJSONObject;
|
|
|
begin;
|
|
|
- {$IFDEF DELPHIRX10_UP}
|
|
|
- json := TJSONObject.ParseJSONValue(aJson,True) as TJSONObject;
|
|
|
- {$ELSE}
|
|
|
- {$IFDEF FPC}
|
|
|
- json := TJSONObject(TJSONObject.ParseJSONValue(aJson,True));
|
|
|
- {$ELSE}
|
|
|
- json := TJsonObject.ParseJSONValue(TEncoding.UTF8.GetBytes(aJson),0,True) as TJSONObject;
|
|
|
- {$ENDIF}
|
|
|
- {$ENDIF}
|
|
|
+ try
|
|
|
+ {$IFDEF DELPHIRX10_UP}
|
|
|
+ json := TJSONObject.ParseJSONValue(aJson,True) as TJSONObject;
|
|
|
+ {$ELSE}
|
|
|
+ {$IFDEF FPC}
|
|
|
+ json := TJSONObject(TJSONObject.ParseJSONValue(aJson,True));
|
|
|
+ {$ELSE}
|
|
|
+ json := TJsonObject.ParseJSONValue(TEncoding.UTF8.GetBytes(aJson),0,True) as TJSONObject;
|
|
|
+ {$ENDIF}
|
|
|
+ {$ENDIF}
|
|
|
+ except
|
|
|
+ raise EJsonDeserializeError.Create(cNotValidJson);
|
|
|
+ end;
|
|
|
try
|
|
|
Result := fRTTIJson.DeserializeObject(aObject,json);
|
|
|
finally
|
|
@@ -1597,7 +1550,7 @@ function TJsonSerializer.ObjectToJson(aObject : TObject; aIndent : Boolean = Fal
|
|
|
var
|
|
|
json: TJSONObject;
|
|
|
begin
|
|
|
- json := fRTTIJson.Serialize(aObject);
|
|
|
+ json := fRTTIJson.SerializeObject(aObject);
|
|
|
try
|
|
|
if aIndent then Result := TJsonUtils.JsonFormat(json.ToJSON)
|
|
|
else Result := json.ToJSON;
|
|
@@ -1610,7 +1563,7 @@ function TJsonSerializer.ObjectToJsonString(aObject : TObject; aIndent : Boolean
|
|
|
var
|
|
|
json: TJSONObject;
|
|
|
begin
|
|
|
- json := fRTTIJson.Serialize(aObject);
|
|
|
+ json := fRTTIJson.SerializeObject(aObject);
|
|
|
try
|
|
|
if aIndent then Result := TJsonUtils.JsonFormat(json.ToString)
|
|
|
else Result := json.ToString;
|
|
@@ -1619,38 +1572,29 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-{$IFNDEF FPC}
|
|
|
-function TJsonSerializer.ValueToJson(aValue: TValue; aIndent: Boolean): string;
|
|
|
+function TJsonSerializer.ValueToJson(const aValue: TValue; aIndent: Boolean): string;
|
|
|
var
|
|
|
- json: TJSONObject;
|
|
|
+ json: TJSONValue;
|
|
|
begin
|
|
|
- json := TJSONObject.Create.AddPair(fRTTIJson.Serialize('value',aValue));
|
|
|
+ json:= fRTTIJson.SerializeValue(aValue);
|
|
|
+ if json = nil then raise EJsonSerializerError.Create('Error serializing TValue');
|
|
|
try
|
|
|
- {$IFDEF DELPHI103_UP}
|
|
|
- if aIndent then Result := TJsonUtils.JsonFormat(json.P['value'].ToJSON)
|
|
|
- else Result := json.P['value'].ToJSON;
|
|
|
- {$ELSE}
|
|
|
- if aIndent then Result := TJsonUtils.JsonFormat(json.GetValue('value').ToJSON)
|
|
|
- else Result := json.GetValue('value').ToJSON;
|
|
|
- {$ENDIF}
|
|
|
+ if aIndent then Result := TJsonUtils.JsonFormat(json{$IFNDEF FPC}.ToJSON{$ELSE}.AsJson{$ENDIF})
|
|
|
+ else Result := json{$IFNDEF FPC}.ToJSON{$ELSE}.AsJson{$ENDIF};
|
|
|
finally
|
|
|
json.Free;
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
-function TJsonSerializer.ValueToJsonString(aValue: TValue; aIndent: Boolean): string;
|
|
|
+function TJsonSerializer.ValueToJsonString(const aValue: TValue; aIndent: Boolean): string;
|
|
|
var
|
|
|
- json: TJSONObject;
|
|
|
+ json: TJSONValue;
|
|
|
begin
|
|
|
- json := TJSONObject.Create.AddPair(fRTTIJson.Serialize('value',aValue));
|
|
|
+ json:= fRTTIJson.SerializeValue(aValue);
|
|
|
+ if json = nil then raise EJsonSerializerError.Create('Error serializing TValue');
|
|
|
try
|
|
|
- {$IFDEF DELPHI103_UP}
|
|
|
- if aIndent then Result := TJsonUtils.JsonFormat(json.P['value'].ToJSON)
|
|
|
- else Result := json.P['value'].ToJSON;
|
|
|
- {$ELSE}
|
|
|
- if aIndent then Result := TJsonUtils.JsonFormat(json.GetValue('value').ToJSON)
|
|
|
- else Result := json.GetValue('value').ToJSON;
|
|
|
- {$ENDIF}
|
|
|
+ if aIndent then Result := TJsonUtils.JsonFormat(json.ToString)
|
|
|
+ else Result := json.ToString;
|
|
|
finally
|
|
|
json.Free;
|
|
|
end;
|
|
@@ -1658,17 +1602,13 @@ end;
|
|
|
|
|
|
function TJsonSerializer.ArrayToJson<T>(aArray: TArray<T>; aIndent: Boolean): string;
|
|
|
var
|
|
|
- json: TJSONObject;
|
|
|
+ json: TJSONValue;
|
|
|
begin
|
|
|
- json := TJSONObject.Create.AddPair(fRTTIJson.Serialize('array',TValue.From<TArray<T>>(aArray)));
|
|
|
+ json:= fRTTIJson.SerializeValue(TValue.From<TArray<T>>(aArray));
|
|
|
+ if json = nil then raise EJsonSerializerError.Create('Error serializing Array');
|
|
|
try
|
|
|
- {$IFDEF DELPHI103_UP}
|
|
|
- if aIndent then Result := TJsonUtils.JsonFormat(json.P['array'].ToJSON)
|
|
|
- else Result := json.P['array'].ToJSON;
|
|
|
- {$ELSE}
|
|
|
- if aIndent then Result := TJsonUtils.JsonFormat(json.GetValue('array').ToJSON)
|
|
|
- else Result := json.GetValue('array').ToJSON;
|
|
|
- {$ENDIF}
|
|
|
+ if aIndent then Result := TJsonUtils.JsonFormat(json{$IFNDEF FPC}.ToJSON{$ELSE}.AsJson{$ENDIF})
|
|
|
+ else Result := json{$IFNDEF FPC}.ToJSON{$ELSE}.AsJson{$ENDIF};
|
|
|
finally
|
|
|
json.Free;
|
|
|
end;
|
|
@@ -1676,32 +1616,33 @@ end;
|
|
|
|
|
|
function TJsonSerializer.ArrayToJsonString<T>(aArray: TArray<T>; aIndent: Boolean): string;
|
|
|
var
|
|
|
- json: TJSONObject;
|
|
|
+ json: TJSONValue;
|
|
|
begin
|
|
|
- json := TJSONObject.Create.AddPair(fRTTIJson.Serialize('array',TValue.From<TArray<T>>(aArray)));
|
|
|
+ json:= fRTTIJson.SerializeValue(TValue.From<TArray<T>>(aArray));
|
|
|
+ if json = nil then raise EJsonSerializerError.Create('Error serializing Array');
|
|
|
try
|
|
|
- {$IFDEF DELPHI103_UP}
|
|
|
- if aIndent then Result := TJsonUtils.JsonFormat(json.P['array'].ToJSON)
|
|
|
- else Result := json.P['array'].ToJSON;
|
|
|
- {$ELSE}
|
|
|
- if aIndent then Result := TJsonUtils.JsonFormat(json.GetValue('array').ToJSON)
|
|
|
- else Result := json.GetValue('array').ToJSON;
|
|
|
- {$ENDIF}
|
|
|
+ if aIndent then Result := TJsonUtils.JsonFormat(json.ToString)
|
|
|
+ else Result := json.ToString;
|
|
|
finally
|
|
|
json.Free;
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
+{$IFNDEF FPC}
|
|
|
function TJsonSerializer.JsonToArray<T>(const aJson: string): TArray<T>;
|
|
|
var
|
|
|
jarray: TJSONArray;
|
|
|
value : TValue;
|
|
|
begin;
|
|
|
- {$If Defined(FPC) OR Defined(DELPHIRX10_UP)}
|
|
|
- jarray := TJSONObject.ParseJSONValue(aJson,True) as TJSONArray;
|
|
|
- {$ELSE}
|
|
|
- jarray := TJsonObject.ParseJSONValue(TEncoding.UTF8.GetBytes(aJson),0,True) as TJSONArray;
|
|
|
+ try
|
|
|
+ {$If Defined(FPC) OR Defined(DELPHIRX10_UP)}
|
|
|
+ jarray := TJSONObject.ParseJSONValue(aJson,True) as TJSONArray;
|
|
|
+ {$ELSE}
|
|
|
+ jarray := TJsonObject.ParseJSONValue(TEncoding.UTF8.GetBytes(aJson),0,True) as TJSONArray;
|
|
|
{$ENDIF}
|
|
|
+ except
|
|
|
+ raise EJsonDeserializeError.Create(cNotValidJson);
|
|
|
+ end;
|
|
|
try
|
|
|
value := fRTTIJson.DeserializeDynArray(PTypeInfo(TypeInfo(TArray<T>)),nil,jarray);
|
|
|
Result := value.AsType<TArray<T>>;
|
|
@@ -1709,58 +1650,24 @@ begin;
|
|
|
jarray.Free;
|
|
|
end;
|
|
|
end;
|
|
|
-{$ELSE}
|
|
|
-function TJsonSerializer.ValueToJson(aValue: TValue; aIndent: Boolean): string;
|
|
|
-var
|
|
|
- json: TJSONObject;
|
|
|
-begin
|
|
|
- json := TJSONObject.Create;
|
|
|
- json.AddPair(fRTTIJson.Serialize('value',aValue));
|
|
|
- try
|
|
|
- if aIndent then Result := TJsonUtils.JsonFormat(json.Get('value').ToJSON)
|
|
|
- else Result := json.Get('value').ToJSON;
|
|
|
- finally
|
|
|
- json.Free;
|
|
|
- end;
|
|
|
-end;
|
|
|
|
|
|
-function TJsonSerializer.ValueToJsonString(aValue: TValue; aIndent: Boolean): string;
|
|
|
+function TJsonSerializer.JsonToValue(const aJson: string): TValue;
|
|
|
var
|
|
|
json: TJSONObject;
|
|
|
-begin
|
|
|
- json := TJSONObject.Create;
|
|
|
- json.AddPair(fRTTIJson.Serialize('value',aValue));
|
|
|
- try
|
|
|
- if aIndent then Result := TJsonUtils.JsonFormat(json.Get('value').ToString)
|
|
|
- else Result := json.Get('value').ToString;
|
|
|
- finally
|
|
|
- json.Free;
|
|
|
- end;
|
|
|
-end;
|
|
|
-
|
|
|
-function TJsonSerializer.ArrayToJson<T>(aArray: TArray<T>; aIndent: Boolean): string;
|
|
|
-var
|
|
|
- json: TJSONObject;
|
|
|
-begin
|
|
|
- json := TJSONObject.Create;
|
|
|
- json.AddPair(fRTTIJson.Serialize('array',TValue.From<TArray<T>>(aArray)));
|
|
|
+ value : TValue;
|
|
|
+begin;
|
|
|
try
|
|
|
- if aIndent then Result := TJsonUtils.JsonFormat(json.Get('array').ToJSON)
|
|
|
- else Result := json.Get('array').ToJSON;
|
|
|
- finally
|
|
|
- json.Free;
|
|
|
+ {$If Defined(FPC) OR Defined(DELPHIRX10_UP)}
|
|
|
+ json := TJSONObject.ParseJSONValue(aJson,True) as TJSONObject;
|
|
|
+ {$ELSE}
|
|
|
+ json := TJsonObject.ParseJSONValue(TEncoding.UTF8.GetBytes(aJson),0,True) as TJSONObject;
|
|
|
+ {$ENDIF}
|
|
|
+ except
|
|
|
+ raise EJsonDeserializeError.Create(cNotValidJson);
|
|
|
end;
|
|
|
-end;
|
|
|
-
|
|
|
-function TJsonSerializer.ArrayToJsonString<T>(aArray: TArray<T>; aIndent: Boolean): string;
|
|
|
-var
|
|
|
- json: TJSONObject;
|
|
|
-begin
|
|
|
- json := TJSONObject.Create;
|
|
|
- json.AddPair(fRTTIJson.Serialize('array',TValue.From<TArray<T>>(aArray)));
|
|
|
try
|
|
|
- if aIndent then Result := TJsonUtils.JsonFormat(json.Get('array').ToString)
|
|
|
- else Result := json.Get('array').ToString;
|
|
|
+ value := fRTTIJson.DeserializeRecord(value,nil,json);
|
|
|
+ Result := value; // value.AsType<TArray<T>>;
|
|
|
finally
|
|
|
json.Free;
|
|
|
end;
|