Neon.Core.Serializers.RTL.pas 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. {******************************************************************************}
  2. { }
  3. { Neon: Serialization Library for Delphi }
  4. { Copyright (c) 2018-2019 Paolo Rossi }
  5. { https://github.com/paolo-rossi/neon-library }
  6. { }
  7. {******************************************************************************}
  8. { }
  9. { Licensed under the Apache License, Version 2.0 (the "License"); }
  10. { you may not use this file except in compliance with the License. }
  11. { You may obtain a copy of the License at }
  12. { }
  13. { http://www.apache.org/licenses/LICENSE-2.0 }
  14. { }
  15. { Unless required by applicable law or agreed to in writing, software }
  16. { distributed under the License is distributed on an "AS IS" BASIS, }
  17. { WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. }
  18. { See the License for the specific language governing permissions and }
  19. { limitations under the License. }
  20. { }
  21. {******************************************************************************}
  22. unit Neon.Core.Serializers.RTL;
  23. interface
  24. uses
  25. System.SysUtils, System.Classes, System.Rtti, System.SyncObjs, System.TypInfo,
  26. System.Generics.Collections, System.Math.Vectors, System.JSON,
  27. Neon.Core.Types,
  28. Neon.Core.Attributes,
  29. Neon.Core.Persistence;
  30. type
  31. TGUIDSerializer = class(TCustomSerializer)
  32. protected
  33. class function GetTargetInfo: PTypeInfo; override;
  34. class function CanHandle(AType: PTypeInfo): Boolean; override;
  35. public
  36. function Serialize(const AValue: TValue; ANeonObject: TNeonRttiObject; AContext: ISerializerContext): TJSONValue; override;
  37. function Deserialize(AValue: TJSONValue; const AData: TValue; ANeonObject: TNeonRttiObject; AContext: IDeserializerContext): TValue; override;
  38. end;
  39. TStreamSerializer = class(TCustomSerializer)
  40. protected
  41. class function GetTargetInfo: PTypeInfo; override;
  42. class function CanHandle(AType: PTypeInfo): Boolean; override;
  43. public
  44. function Serialize(const AValue: TValue; ANeonObject: TNeonRttiObject; AContext: ISerializerContext): TJSONValue; override;
  45. function Deserialize(AValue: TJSONValue; const AData: TValue; ANeonObject: TNeonRttiObject; AContext: IDeserializerContext): TValue; override;
  46. end;
  47. procedure RegisterDefaultSerializers(ARegistry: TNeonSerializerRegistry);
  48. implementation
  49. uses
  50. Neon.Core.Utils;
  51. procedure RegisterDefaultSerializers(ARegistry: TNeonSerializerRegistry);
  52. begin
  53. ARegistry.RegisterSerializer(TGUIDSerializer);
  54. ARegistry.RegisterSerializer(TStreamSerializer);
  55. end;
  56. { TGUIDSerializer }
  57. class function TGUIDSerializer.GetTargetInfo: PTypeInfo;
  58. begin
  59. Result := TypeInfo(TGUID);
  60. end;
  61. function TGUIDSerializer.Serialize(const AValue: TValue; ANeonObject:
  62. TNeonRttiObject; AContext: ISerializerContext): TJSONValue;
  63. var
  64. LGUID: TGUID;
  65. begin
  66. LGUID := AValue.AsType<TGUID>;
  67. Result := TJSONString.Create(Format('%.8x-%.4x-%.4x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x',
  68. [LGUID.D1, LGUID.D2, LGUID.D3, LGUID.D4[0], LGUID.D4[1], LGUID.D4[2],
  69. LGUID.D4[3], LGUID.D4[4], LGUID.D4[5], LGUID.D4[6], LGUID.D4[7]])
  70. );
  71. end;
  72. class function TGUIDSerializer.CanHandle(AType: PTypeInfo): Boolean;
  73. begin
  74. if AType = GetTargetInfo then
  75. Result := True
  76. else
  77. Result := False;
  78. end;
  79. function TGUIDSerializer.Deserialize(AValue: TJSONValue; const AData: TValue;
  80. ANeonObject: TNeonRttiObject; AContext: IDeserializerContext): TValue;
  81. var
  82. LGUID: TGUID;
  83. begin
  84. LGUID := StringToGUID(Format('{%s}', [AValue.Value]));
  85. Result := TValue.From<TGUID>(LGUID);
  86. end;
  87. { TStreamSerializer }
  88. class function TStreamSerializer.GetTargetInfo: PTypeInfo;
  89. begin
  90. Result := TStream.ClassInfo;
  91. end;
  92. class function TStreamSerializer.CanHandle(AType: PTypeInfo): Boolean;
  93. begin
  94. Result := TypeInfoIs(AType);
  95. end;
  96. function TStreamSerializer.Serialize(const AValue: TValue;
  97. ANeonObject: TNeonRttiObject; AContext: ISerializerContext): TJSONValue;
  98. var
  99. LStream: TStream;
  100. LBase64: string;
  101. begin
  102. LStream := AValue.AsObject as TStream;
  103. if LStream.Size = 0 then
  104. begin
  105. case ANeonObject.NeonInclude.Value of
  106. IncludeIf.NotEmpty, IncludeIf.NotDefault: Exit(nil);
  107. else
  108. Exit(TJSONString.Create(''));
  109. end;
  110. end;
  111. LStream.Position := soFromBeginning;
  112. LBase64 := TBase64.Encode(LStream);
  113. Result := TJSONString.Create(LBase64);
  114. end;
  115. function TStreamSerializer.Deserialize(AValue: TJSONValue; const AData: TValue;
  116. ANeonObject: TNeonRttiObject; AContext: IDeserializerContext): TValue;
  117. var
  118. LStream: TStream;
  119. begin
  120. Result := AData;
  121. LStream := AData.AsObject as TStream;
  122. LStream.Position := soFromBeginning;
  123. TBase64.Decode(AValue.Value, LStream);
  124. end;
  125. end.