7
7
Author : Kike Pérez
8
8
Version : 1.12
9
9
Created : 21/05/2018
10
- Modified : 18/02 /2022
10
+ Modified : 17/05 /2022
11
11
12
12
This file is part of QuickLib: https://github.com/exilon/QuickLib
13
13
@@ -86,6 +86,8 @@ TCommentProperty = class(TCustomAttribute)
86
86
property Comment : string read fComment;
87
87
end ;
88
88
89
+ TSerializerOptions = Quick.Serializer.Intf.TSerializerOptions;
90
+
89
91
TCustomNameProperty = class (TCustomAttribute)
90
92
private
91
93
fName : string;
@@ -130,6 +132,9 @@ TRTTIJson = class
130
132
fUseJsonCaseSense : Boolean;
131
133
fUseBase64Stream : Boolean;
132
134
fUseNullStringsAsEmpty : Boolean;
135
+ fUseGUIDWithBrackets : Boolean;
136
+ fUseGUIDLowercase : Boolean;
137
+ fOptions : TSerializerOptions;
133
138
function GetValue (aAddr: Pointer; aType: TRTTIType): TValue; overload;
134
139
{ $IFDEF FPC}
135
140
function GetValue (aAddr: Pointer; aTypeInfo: PTypeInfo): TValue; overload;
@@ -151,12 +156,17 @@ TRTTIJson = class
151
156
function CreateInstance (aClass: TClass): TValue; overload;
152
157
function CreateInstance (aType: TRttiType): TValue; overload;
153
158
{ $ENDIF}
159
+ function GUIDToStringFormated (const aGUID : TGUID) : string;
154
160
public
155
161
constructor Create(aSerializeLevel : TSerializeLevel; aUseEnumNames : Boolean = True);
162
+ destructor Destroy; override;
156
163
property UseEnumNames : Boolean read fUseEnumNames write fUseEnumNames;
157
164
property UseJsonCaseSense : Boolean read fUseJsonCaseSense write fUseJsonCaseSense;
158
165
property UseBase64Stream : Boolean read fUseBase64Stream write fUseBase64Stream;
159
166
property UseNullStringsAsEmpty : Boolean read fUseNullStringsAsEmpty write fUseNullStringsAsEmpty;
167
+ property UseGUIDWithBrackets : Boolean read fUseGUIDWithBrackets write fUseGUIDWithBrackets;
168
+ property UseGUIDLowercase : Boolean read fUseGUIDLowercase write fUseGUIDLowercase;
169
+ property Options : TSerializerOptions read fOptions write fOptions;
160
170
function GetJsonPairValueByName (aJson : TJSONObject; const aName : string) : TJsonValue;
161
171
function GetJsonPairByName (aJson : TJSONObject; const aName : string) : TJSONPair;
162
172
function IsGenericList (aObject : TObject) : Boolean;
@@ -197,6 +207,8 @@ TJsonSerializer = class(TInterfacedObject,IJsonSerializer)
197
207
fUseJsonCaseSense : Boolean;
198
208
fUseBase64Stream : Boolean;
199
209
fUseNullStringsAsEmpty : Boolean;
210
+ fUseGUIDWithBrackets: Boolean;
211
+ fUseGUIDLowercase: Boolean;
200
212
fRTTIJson : TRTTIJson;
201
213
private
202
214
procedure SetUseEnumNames (const Value : Boolean);
@@ -205,6 +217,8 @@ TJsonSerializer = class(TInterfacedObject,IJsonSerializer)
205
217
procedure SetUseBase64Stream (const Value : Boolean);
206
218
// Only Delphi -> Workaround, use this when something passes : {Test : "Null"} but we expect : {Test : ""}
207
219
procedure SetUseNullStringsAsEmpty (const Value : Boolean);
220
+ procedure SetUseGUIDLowerCase (const Value : Boolean);
221
+ procedure SetUseGUIDWithBrackets (const Value : Boolean);
208
222
public
209
223
constructor Create(aSerializeLevel: TSerializeLevel; aUseEnumNames : Boolean = True; aUseNullStringsAsEmpty : Boolean = False);
210
224
destructor Destroy; override;
@@ -213,6 +227,8 @@ TJsonSerializer = class(TInterfacedObject,IJsonSerializer)
213
227
property UseJsonCaseSense : Boolean read fUseJsonCaseSense write SetUseJsonCaseSense;
214
228
property UseBase64Stream : Boolean read fUseBase64Stream write SetUseBase64Stream;
215
229
property UseNullStringsAsEmpty : Boolean read fUseNullStringsAsEmpty write SetUseNullStringsAsEmpty;
230
+ property UseGUIDWithBrackets : Boolean read fUseGUIDWithBrackets write SetUseGUIDWithBrackets;
231
+ property UseGUIDLowerCase : Boolean read fUseGUIDLowercase write SetUseGUIDLowerCase;
216
232
function JsonToObject (aType : TClass; const aJson: string) : TObject; overload;
217
233
function JsonToObject (aObject : TObject; const aJson: string) : TObject; overload;
218
234
function JsonStreamToObject (aObject : TObject; aJsonStream : TStream) : TObject;
@@ -227,6 +243,7 @@ TJsonSerializer = class(TInterfacedObject,IJsonSerializer)
227
243
function JsonToArray <T>(const aJson : string) : TArray<T>;
228
244
function JsonToValue (const aJson: string): TValue;
229
245
{ $ENDIF}
246
+ function Options : TSerializerOptions;
230
247
end ;
231
248
232
249
EJsonSerializerError = class (Exception);
@@ -458,7 +475,7 @@ function TRTTIJson.DeserializeStream(aObject: TObject; const aJson: TJSONValue):
458
475
var
459
476
stream : TStringStream;
460
477
begin
461
- if fUseBase64Stream then stream := TStringStream.Create(Base64Decode(aJson.Value ),TEncoding.Ansi)
478
+ if fOptions.UseBase64Stream then stream := TStringStream.Create(Base64Decode(aJson.Value ),TEncoding.Ansi)
462
479
else stream := TStringStream.Create({ $IFNDEF FPC} aJson.Value { $ELSE} string(aJson.Value ){ $ENDIF} ,TEncoding.Ansi);
463
480
try
464
481
TStream(aObject).CopyFrom(stream,stream.Size);
@@ -470,10 +487,24 @@ function TRTTIJson.DeserializeStream(aObject: TObject; const aJson: TJSONValue):
470
487
471
488
constructor TRTTIJson.Create(aSerializeLevel : TSerializeLevel; aUseEnumNames : Boolean = True);
472
489
begin
490
+ fOptions := TSerializerOptions.Create;
473
491
fSerializeLevel := aSerializeLevel;
474
492
fUseEnumNames := aUseEnumNames;
475
493
fUseJsonCaseSense := False;
476
494
fUseBase64Stream := True;
495
+ fUseGUIDWithBrackets := False;
496
+ fUseGUIDLowerCase := True;
497
+ fOptions.UseEnumNames := aUseEnumNames;
498
+ fOptions.UseJsonCaseSense := False;
499
+ fOptions.UseBase64Stream := True;
500
+ fOptions.UseGUIDLowercase := False;
501
+ fOptions.UseGUIDLowercase := True;
502
+ end ;
503
+
504
+ destructor TRTTIJson.Destroy;
505
+ begin
506
+ fOptions.Free;
507
+ inherited ;
477
508
end ;
478
509
479
510
{ $IFNDEF FPC}
@@ -721,6 +752,7 @@ procedure TRTTIJson.DeserializeXArray(Instance : TObject; aRecord : TValue; aPro
721
752
if not rValue.IsEmpty then rField.SetValue(aRecord.GetReferenceToRawData,rValue);
722
753
aProperty.SetValue(Instance,aRecord);
723
754
end ;
755
+
724
756
{ $ENDIF}
725
757
726
758
function StringToGUIDEx (const aGUID : string) : TGUID;
@@ -729,6 +761,13 @@ function StringToGUIDEx(const aGUID : string) : TGUID;
729
761
else Result := System.SysUtils.StringToGUID(aGUID);
730
762
end ;
731
763
764
+ function TRTTIJson.GUIDToStringFormated (const aGUID : TGUID) : string;
765
+ begin
766
+ if fOptions.UseGUIDWithBrackets then Result := System.SysUtils.GUIDToString(aGUID)
767
+ else Result := GetSubString(System.SysUtils.GUIDToString(aGUID),' {' ,' }' );
768
+ if fOptions.UseGUIDLowercase then Result := Result.ToLower;
769
+ end ;
770
+
732
771
function TRTTIJson.DeserializeProperty (aObject : TObject; const aName : string; aProperty : TRttiProperty; const aJson : TJSONObject) : TObject;
733
772
var
734
773
rValue : TValue;
@@ -855,7 +894,7 @@ function TRTTIJson.DeserializeType(aObject : TObject; aType : TTypeKind; aTypeIn
855
894
case aType of
856
895
tkString, tkLString, tkWString, tkUString :
857
896
begin
858
- if fUseNullStringsAsEmpty and (CompareText(value , ' null' ) = 0 ) then
897
+ if fOptions.UseNullStringsAsEmpty and (CompareText(value , ' null' ) = 0 ) then
859
898
Result := ' '
860
899
else
861
900
Result := value ;
@@ -1060,7 +1099,7 @@ function TRTTIJson.GetJsonPairValueByName(aJson: TJSONObject; const aName: strin
1060
1099
candidate : TJSONPair;
1061
1100
i : Integer;
1062
1101
begin
1063
- if fUseJsonCaseSense then
1102
+ if fOptions.UseJsonCaseSense then
1064
1103
begin
1065
1104
Result := aJson.GetValue(aName);
1066
1105
Exit;
@@ -1081,7 +1120,7 @@ function TRTTIJson.GetJsonPairByName(aJson: TJSONObject; const aName: string): T
1081
1120
var
1082
1121
i : Integer;
1083
1122
begin
1084
- if fUseJsonCaseSense then
1123
+ if fOptions.UseJsonCaseSense then
1085
1124
begin
1086
1125
Result := TJSONPair(aJson.GetValue(aName));
1087
1126
Exit;
@@ -1478,7 +1517,7 @@ function TRTTIJson.SerializeStream(aObject: TObject): TJSONValue;
1478
1517
Result := nil ;
1479
1518
try
1480
1519
stream := TStream(aObject);
1481
- if fUseBase64Stream then Result := TJSONString.Create(Base64Encode(StreamToString(stream,TEncoding.Ansi)))
1520
+ if fOptions.UseBase64Stream then Result := TJSONString.Create(Base64Encode(StreamToString(stream,TEncoding.Ansi)))
1482
1521
else Result := TJSONString.Create(StreamToString(stream,TEncoding.Ansi));
1483
1522
except
1484
1523
on E : Exception do
@@ -1542,7 +1581,7 @@ function TRTTIJson.SerializeRecord(const aValue : TValue) : TJSONValue;
1542
1581
rRec := ctx.GetType(aValue.TypeInfo).AsRecord;
1543
1582
if aValue.TypeInfo = System.TypeInfo(TGUID) then
1544
1583
begin
1545
- Result := TJSONString.Create(GUIDToString (aValue.AsType<TGUID>));
1584
+ Result := TJSONString.Create(GUIDToStringFormated (aValue.AsType<TGUID>));
1546
1585
end
1547
1586
else
1548
1587
begin
@@ -1722,9 +1761,9 @@ constructor TJsonSerializer.Create(aSerializeLevel: TSerializeLevel; aUseEnumNam
1722
1761
fUseBase64Stream := True;
1723
1762
fUseNullStringsAsEmpty := aUseNullStringsAsEmpty;
1724
1763
fRTTIJson := TRTTIJson.Create(aSerializeLevel,aUseEnumNames);
1725
- fRTTIJson.UseJsonCaseSense := fUseJsonCaseSense;
1726
- fRTTIJson.UseBase64Stream := fUseBase64Stream;
1727
- fRTTIJson.UseNullStringsAsEmpty := fUseNullStringsAsEmpty;
1764
+ fRTTIJson.Options. UseJsonCaseSense := fUseJsonCaseSense;
1765
+ fRTTIJson.Options. UseBase64Stream := fUseBase64Stream;
1766
+ fRTTIJson.Options. UseNullStringsAsEmpty := fUseNullStringsAsEmpty;
1728
1767
end ;
1729
1768
1730
1769
destructor TJsonSerializer.Destroy;
@@ -1852,6 +1891,11 @@ function TJsonSerializer.ObjectToJsonString(aObject : TObject; aIndent : Boolean
1852
1891
end ;
1853
1892
end ;
1854
1893
1894
+ function TJsonSerializer.Options : TSerializerOptions;
1895
+ begin
1896
+ Result := fRTTIJson.Options;
1897
+ end ;
1898
+
1855
1899
function TJsonSerializer.ValueToJson (const aValue: TValue; aIndent: Boolean): string;
1856
1900
var
1857
1901
json: TJSONValue;
@@ -1995,25 +2039,37 @@ procedure TJsonSerializer.SetSerializeLevel(const Value: TSerializeLevel);
1995
2039
procedure TJsonSerializer.SetUseBase64Stream (const Value : Boolean);
1996
2040
begin
1997
2041
fUseBase64Stream := Value ;
1998
- if Assigned(fRTTIJson) then fRTTIJson.UseBase64Stream := Value ;
2042
+ if Assigned(fRTTIJson) then fRTTIJson.Options. UseBase64Stream := Value ;
1999
2043
end ;
2000
2044
2001
2045
procedure TJsonSerializer.SetUseEnumNames (const Value : Boolean);
2002
2046
begin
2003
2047
fUseEnumNames := Value ;
2004
- if Assigned(fRTTIJson) then fRTTIJson.UseEnumNames := Value ;
2048
+ if Assigned(fRTTIJson) then fRTTIJson.Options.UseEnumNames := Value ;
2049
+ end ;
2050
+
2051
+ procedure TJsonSerializer.SetUseGUIDLowerCase (const Value : Boolean);
2052
+ begin
2053
+ fUseGUIDLowercase := Value ;
2054
+ if Assigned(fRTTIJson) then fRTTIJson.Options.UseGUIDLowerCase := Value ;
2055
+ end ;
2056
+
2057
+ procedure TJsonSerializer.SetUseGUIDWithBrackets (const Value : Boolean);
2058
+ begin
2059
+ fUseGUIDWithBrackets := Value ;
2060
+ if Assigned(fRTTIJson) then fRTTIJson.Options.UseGUIDWithBrackets := Value ;
2005
2061
end ;
2006
2062
2007
2063
procedure TJsonSerializer.SetUseJsonCaseSense (const Value : Boolean);
2008
2064
begin
2009
- fUseJsonCaseSense := Value ;
2010
- if Assigned(fRTTIJson) then fRTTIJson.UseJsonCaseSense := Value ;
2065
+ fRTTIJson.Options.UseJsonCaseSense := Value ;
2066
+ if Assigned(fRTTIJson) then fRTTIJson.Options. UseJsonCaseSense := Value ;
2011
2067
end ;
2012
2068
2013
2069
procedure TJsonSerializer.SetUseNullStringsAsEmpty (const Value : Boolean);
2014
2070
begin
2015
2071
fUseNullStringsAsEmpty := Value ;
2016
- if Assigned(fRTTIJson) then fRTTIJson.fUseNullStringsAsEmpty := Value ;
2072
+ if Assigned(fRTTIJson) then fRTTIJson.Options.UseNullStringsAsEmpty := Value ;
2017
2073
end ;
2018
2074
2019
2075
{ $IFNDEF FPC}
0 commit comments