Skip to content

Commit 99aa60e

Browse files
committed
[jsonSerializer] more accesible serializer options
1 parent a0bccbb commit 99aa60e

File tree

2 files changed

+89
-15
lines changed

2 files changed

+89
-15
lines changed

Quick.Json.Serializer.pas

+71-15
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
Author : Kike Pérez
88
Version : 1.12
99
Created : 21/05/2018
10-
Modified : 18/02/2022
10+
Modified : 17/05/2022
1111
1212
This file is part of QuickLib: https://github.com/exilon/QuickLib
1313
@@ -86,6 +86,8 @@ TCommentProperty = class(TCustomAttribute)
8686
property Comment : string read fComment;
8787
end;
8888

89+
TSerializerOptions = Quick.Serializer.Intf.TSerializerOptions;
90+
8991
TCustomNameProperty = class(TCustomAttribute)
9092
private
9193
fName : string;
@@ -130,6 +132,9 @@ TRTTIJson = class
130132
fUseJsonCaseSense : Boolean;
131133
fUseBase64Stream : Boolean;
132134
fUseNullStringsAsEmpty : Boolean;
135+
fUseGUIDWithBrackets : Boolean;
136+
fUseGUIDLowercase : Boolean;
137+
fOptions : TSerializerOptions;
133138
function GetValue(aAddr: Pointer; aType: TRTTIType): TValue; overload;
134139
{$IFDEF FPC}
135140
function GetValue(aAddr: Pointer; aTypeInfo: PTypeInfo): TValue; overload;
@@ -151,12 +156,17 @@ TRTTIJson = class
151156
function CreateInstance(aClass: TClass): TValue; overload;
152157
function CreateInstance(aType: TRttiType): TValue; overload;
153158
{$ENDIF}
159+
function GUIDToStringFormated(const aGUID : TGUID) : string;
154160
public
155161
constructor Create(aSerializeLevel : TSerializeLevel; aUseEnumNames : Boolean = True);
162+
destructor Destroy; override;
156163
property UseEnumNames : Boolean read fUseEnumNames write fUseEnumNames;
157164
property UseJsonCaseSense : Boolean read fUseJsonCaseSense write fUseJsonCaseSense;
158165
property UseBase64Stream : Boolean read fUseBase64Stream write fUseBase64Stream;
159166
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;
160170
function GetJsonPairValueByName(aJson : TJSONObject; const aName : string) : TJsonValue;
161171
function GetJsonPairByName(aJson : TJSONObject; const aName : string) : TJSONPair;
162172
function IsGenericList(aObject : TObject) : Boolean;
@@ -197,6 +207,8 @@ TJsonSerializer = class(TInterfacedObject,IJsonSerializer)
197207
fUseJsonCaseSense : Boolean;
198208
fUseBase64Stream : Boolean;
199209
fUseNullStringsAsEmpty : Boolean;
210+
fUseGUIDWithBrackets: Boolean;
211+
fUseGUIDLowercase: Boolean;
200212
fRTTIJson : TRTTIJson;
201213
private
202214
procedure SetUseEnumNames(const Value: Boolean);
@@ -205,6 +217,8 @@ TJsonSerializer = class(TInterfacedObject,IJsonSerializer)
205217
procedure SetUseBase64Stream(const Value: Boolean);
206218
//Only Delphi -> Workaround, use this when something passes : {Test : "Null"} but we expect : {Test : ""}
207219
procedure SetUseNullStringsAsEmpty(const Value : Boolean);
220+
procedure SetUseGUIDLowerCase(const Value: Boolean);
221+
procedure SetUseGUIDWithBrackets(const Value: Boolean);
208222
public
209223
constructor Create(aSerializeLevel: TSerializeLevel; aUseEnumNames : Boolean = True; aUseNullStringsAsEmpty : Boolean = False);
210224
destructor Destroy; override;
@@ -213,6 +227,8 @@ TJsonSerializer = class(TInterfacedObject,IJsonSerializer)
213227
property UseJsonCaseSense : Boolean read fUseJsonCaseSense write SetUseJsonCaseSense;
214228
property UseBase64Stream : Boolean read fUseBase64Stream write SetUseBase64Stream;
215229
property UseNullStringsAsEmpty : Boolean read fUseNullStringsAsEmpty write SetUseNullStringsAsEmpty;
230+
property UseGUIDWithBrackets : Boolean read fUseGUIDWithBrackets write SetUseGUIDWithBrackets;
231+
property UseGUIDLowerCase : Boolean read fUseGUIDLowercase write SetUseGUIDLowerCase;
216232
function JsonToObject(aType : TClass; const aJson: string) : TObject; overload;
217233
function JsonToObject(aObject : TObject; const aJson: string) : TObject; overload;
218234
function JsonStreamToObject(aObject : TObject; aJsonStream : TStream) : TObject;
@@ -227,6 +243,7 @@ TJsonSerializer = class(TInterfacedObject,IJsonSerializer)
227243
function JsonToArray<T>(const aJson : string) : TArray<T>;
228244
function JsonToValue(const aJson: string): TValue;
229245
{$ENDIF}
246+
function Options : TSerializerOptions;
230247
end;
231248

232249
EJsonSerializerError = class(Exception);
@@ -458,7 +475,7 @@ function TRTTIJson.DeserializeStream(aObject: TObject; const aJson: TJSONValue):
458475
var
459476
stream : TStringStream;
460477
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)
462479
else stream := TStringStream.Create({$IFNDEF FPC}aJson.Value{$ELSE}string(aJson.Value){$ENDIF},TEncoding.Ansi);
463480
try
464481
TStream(aObject).CopyFrom(stream,stream.Size);
@@ -470,10 +487,24 @@ function TRTTIJson.DeserializeStream(aObject: TObject; const aJson: TJSONValue):
470487

471488
constructor TRTTIJson.Create(aSerializeLevel : TSerializeLevel; aUseEnumNames : Boolean = True);
472489
begin
490+
fOptions := TSerializerOptions.Create;
473491
fSerializeLevel := aSerializeLevel;
474492
fUseEnumNames := aUseEnumNames;
475493
fUseJsonCaseSense := False;
476494
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;
477508
end;
478509

479510
{$IFNDEF FPC}
@@ -721,6 +752,7 @@ procedure TRTTIJson.DeserializeXArray(Instance : TObject; aRecord : TValue; aPro
721752
if not rValue.IsEmpty then rField.SetValue(aRecord.GetReferenceToRawData,rValue);
722753
aProperty.SetValue(Instance,aRecord);
723754
end;
755+
724756
{$ENDIF}
725757

726758
function StringToGUIDEx(const aGUID : string) : TGUID;
@@ -729,6 +761,13 @@ function StringToGUIDEx(const aGUID : string) : TGUID;
729761
else Result := System.SysUtils.StringToGUID(aGUID);
730762
end;
731763

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+
732771
function TRTTIJson.DeserializeProperty(aObject : TObject; const aName : string; aProperty : TRttiProperty; const aJson : TJSONObject) : TObject;
733772
var
734773
rValue : TValue;
@@ -855,7 +894,7 @@ function TRTTIJson.DeserializeType(aObject : TObject; aType : TTypeKind; aTypeIn
855894
case aType of
856895
tkString, tkLString, tkWString, tkUString :
857896
begin
858-
if fUseNullStringsAsEmpty and (CompareText(value, 'null') = 0) then
897+
if fOptions.UseNullStringsAsEmpty and (CompareText(value, 'null') = 0) then
859898
Result := ''
860899
else
861900
Result := value;
@@ -1060,7 +1099,7 @@ function TRTTIJson.GetJsonPairValueByName(aJson: TJSONObject; const aName: strin
10601099
candidate : TJSONPair;
10611100
i : Integer;
10621101
begin
1063-
if fUseJsonCaseSense then
1102+
if fOptions.UseJsonCaseSense then
10641103
begin
10651104
Result := aJson.GetValue(aName);
10661105
Exit;
@@ -1081,7 +1120,7 @@ function TRTTIJson.GetJsonPairByName(aJson: TJSONObject; const aName: string): T
10811120
var
10821121
i : Integer;
10831122
begin
1084-
if fUseJsonCaseSense then
1123+
if fOptions.UseJsonCaseSense then
10851124
begin
10861125
Result := TJSONPair(aJson.GetValue(aName));
10871126
Exit;
@@ -1478,7 +1517,7 @@ function TRTTIJson.SerializeStream(aObject: TObject): TJSONValue;
14781517
Result := nil;
14791518
try
14801519
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)))
14821521
else Result := TJSONString.Create(StreamToString(stream,TEncoding.Ansi));
14831522
except
14841523
on E : Exception do
@@ -1542,7 +1581,7 @@ function TRTTIJson.SerializeRecord(const aValue : TValue) : TJSONValue;
15421581
rRec := ctx.GetType(aValue.TypeInfo).AsRecord;
15431582
if aValue.TypeInfo = System.TypeInfo(TGUID) then
15441583
begin
1545-
Result := TJSONString.Create(GUIDToString(aValue.AsType<TGUID>));
1584+
Result := TJSONString.Create(GUIDToStringFormated(aValue.AsType<TGUID>));
15461585
end
15471586
else
15481587
begin
@@ -1722,9 +1761,9 @@ constructor TJsonSerializer.Create(aSerializeLevel: TSerializeLevel; aUseEnumNam
17221761
fUseBase64Stream := True;
17231762
fUseNullStringsAsEmpty := aUseNullStringsAsEmpty;
17241763
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;
17281767
end;
17291768

17301769
destructor TJsonSerializer.Destroy;
@@ -1852,6 +1891,11 @@ function TJsonSerializer.ObjectToJsonString(aObject : TObject; aIndent : Boolean
18521891
end;
18531892
end;
18541893

1894+
function TJsonSerializer.Options: TSerializerOptions;
1895+
begin
1896+
Result := fRTTIJson.Options;
1897+
end;
1898+
18551899
function TJsonSerializer.ValueToJson(const aValue: TValue; aIndent: Boolean): string;
18561900
var
18571901
json: TJSONValue;
@@ -1995,25 +2039,37 @@ procedure TJsonSerializer.SetSerializeLevel(const Value: TSerializeLevel);
19952039
procedure TJsonSerializer.SetUseBase64Stream(const Value: Boolean);
19962040
begin
19972041
fUseBase64Stream := Value;
1998-
if Assigned(fRTTIJson) then fRTTIJson.UseBase64Stream := Value;
2042+
if Assigned(fRTTIJson) then fRTTIJson.Options.UseBase64Stream := Value;
19992043
end;
20002044

20012045
procedure TJsonSerializer.SetUseEnumNames(const Value: Boolean);
20022046
begin
20032047
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;
20052061
end;
20062062

20072063
procedure TJsonSerializer.SetUseJsonCaseSense(const Value: Boolean);
20082064
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;
20112067
end;
20122068

20132069
procedure TJsonSerializer.SetUseNullStringsAsEmpty(const Value: Boolean);
20142070
begin
20152071
fUseNullStringsAsEmpty := Value;
2016-
if Assigned(fRTTIJson) then fRTTIJson.fUseNullStringsAsEmpty := Value;
2072+
if Assigned(fRTTIJson) then fRTTIJson.Options.UseNullStringsAsEmpty := Value;
20172073
end;
20182074

20192075
{$IFNDEF FPC}

Quick.Serializer.Intf.pas

+18
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,30 @@ interface
1212
{$ENDIF}
1313

1414
type
15+
TSerializerOptions = class
16+
private
17+
fUseEnumNames : Boolean;
18+
fUseJsonCaseSense : Boolean;
19+
fUseBase64Stream : Boolean;
20+
fUseNullStringsAsEmpty : Boolean;
21+
fUseGUIDWithBrackets: Boolean;
22+
fUseGUIDLowercase: Boolean;
23+
public
24+
property UseEnumNames : Boolean read fUseEnumNames write fUseEnumNames;
25+
property UseJsonCaseSense : Boolean read fUseJsonCaseSense write fUseJsonCaseSense;
26+
property UseBase64Stream : Boolean read fUseBase64Stream write fUseBase64Stream;
27+
property UseNullStringsAsEmpty : Boolean read fUseNullStringsAsEmpty write fUseNullStringsAsEmpty;
28+
property UseGUIDWithBrackets : Boolean read fUseGUIDWithBrackets write fUseGUIDWithBrackets;
29+
property UseGUIDLowercase : Boolean read fUseGUIDLowercase write fUseGUIDLowercase;
30+
end;
31+
1532
ISerializer = interface
1633
['{CA26F7AE-F1FE-41BE-9C23-723A687F60D1}']
1734
function JsonToObject(aType: TClass; const aJson: string): TObject; overload;
1835
function JsonToObject(aObject: TObject; const aJson: string): TObject; overload;
1936
function ObjectToJson(aObject : TObject; aIndent : Boolean = False): string;
2037
function ValueToJson(const aValue : TValue; aIndent : Boolean = False) : string;
38+
function Options : TSerializerOptions;
2139
end;
2240

2341
implementation

0 commit comments

Comments
 (0)