Created
August 20, 2020 19:50
-
-
Save edsonmsantos/a0742b48af9ea17f9cd7deb2aadad98a to your computer and use it in GitHub Desktop.
[JSON delphi] Unit para manipulação fácil de JSON no delphi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{**************************************************************************** | |
Copyright (c) 2014 Randolph | |
mail: [email protected] | |
Permission is hereby granted, free of charge, to any person obtaining a copy | |
of this software and associated documentation files (the "Software"), to deal | |
in the Software without restriction, including without limitation the rights | |
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
copies of the Software, and to permit persons to whom the Software is | |
furnished to do so, subject to the following conditions: | |
The above copyright notice and this permission notice shall be included in | |
all copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
THE SOFTWARE. | |
****************************************************************************} | |
unit Jsons; | |
interface | |
uses Classes, SysUtils; | |
type | |
TJsonValueType = (jvNone, jvNull, jvString, jvNumber, jvBoolean, jvObject, jvArray); | |
TJsonStructType = (jsNone, jsArray, jsObject); | |
TJsonNull = (null); | |
TJsonEmpty = (empty); | |
type | |
TJsonBase = class(TObject) | |
private | |
FOwner: TJsonBase; | |
function GetOwner: TJsonBase; | |
protected | |
function GetOwnerName: String; | |
procedure RaiseError(const Msg: String); | |
procedure RaiseParseError(const JsonString: String); | |
procedure RaiseAssignError(Source: TJsonBase); | |
public | |
constructor Create(AOwner: TJsonBase); | |
destructor Destroy; override; | |
procedure Parse(JsonString: String); virtual; abstract; | |
function Stringify: String; virtual; abstract; | |
procedure Assign(Source: TJsonBase); virtual; abstract; | |
function Encode(const S: String): String; | |
function Decode(const S: String): String; | |
procedure Split(const S: String; const Delimiter: Char; Strings: TStrings); | |
function IsJsonObject(const S: String): Boolean; | |
function IsJsonArray(const S: String): Boolean; | |
function IsJsonString(const S: String): Boolean; | |
function IsJsonNumber(const S: String): Boolean; | |
function IsJsonBoolean(const S: String): Boolean; | |
function IsJsonNull(const S: String): Boolean; | |
function AnalyzeJsonValueType(const S: String): TJsonValueType; | |
public | |
property Owner: TJsonBase read GetOwner; | |
end; | |
TJsonObject = class; | |
TJsonArray = class; | |
TJsonValue = class(TJsonBase) | |
private | |
FValueType: TJsonValueType; | |
FStringValue: String; | |
FNumberValue: Extended; | |
FBooleanValue: Boolean; | |
FObjectValue: TJsonObject; | |
FArrayValue: TJsonArray; | |
function GetAsArray: TJsonArray; | |
function GetAsBoolean: Boolean; | |
function GetAsInteger: Integer; | |
function GetAsNumber: Extended; | |
function GetAsObject: TJsonObject; | |
function GetAsString: String; | |
function GetIsNull: Boolean; | |
procedure SetAsBoolean(const Value: Boolean); | |
procedure SetAsInteger(const Value: Integer); | |
procedure SetAsNumber(const Value: Extended); | |
procedure SetAsString(const Value: String); | |
procedure SetIsNull(const Value: Boolean); | |
procedure SetAsArray(const Value: TJsonArray); | |
procedure SetAsObject(const Value: TJsonObject); | |
function GetIsEmpty: Boolean; | |
procedure SetIsEmpty(const Value: Boolean); | |
protected | |
procedure RaiseValueTypeError(const AsValueType: TJsonValueType); | |
public | |
constructor Create(AOwner: TJsonBase); | |
destructor Destroy; override; | |
procedure Parse(JsonString: String); override; | |
function Stringify: String; override; | |
procedure Assign(Source: TJsonBase); override; | |
procedure Clear; | |
public | |
property ValueType: TJsonValueType read FValueType; | |
property AsString: String read GetAsString write SetAsString; | |
property AsNumber: Extended read GetAsNumber write SetAsNumber; | |
property AsInteger: Integer read GetAsInteger write SetAsInteger; | |
property AsBoolean: Boolean read GetAsBoolean write SetAsBoolean; | |
property AsObject: TJsonObject read GetAsObject write SetAsObject; | |
property AsArray: TJsonArray read GetAsArray write SetAsArray; | |
property IsNull: Boolean read GetIsNull write SetIsNull; | |
property IsEmpty: Boolean read GetIsEmpty write SetIsEmpty; | |
end; | |
TJsonArray = class(TJsonBase) | |
private | |
FList: TList; | |
function GetItems(Index: Integer): TJsonValue; | |
function GetCount: Integer; | |
public | |
constructor Create(AOwner: TJsonBase = nil); | |
destructor Destroy; override; | |
procedure Parse(JsonString: String); override; | |
function Stringify: String; override; | |
procedure Assign(Source: TJsonBase); override; | |
procedure Merge(Addition: TJsonArray); | |
function Add: TJsonValue; | |
function Insert(const Index: Integer): TJsonValue; | |
function Put(const Value: TJsonEmpty): TJsonValue; overload; | |
function Put(const Value: TJsonNull): TJsonValue; overload; | |
function Put(const Value: Boolean): TJsonValue; overload; | |
function Put(const Value: Integer): TJsonValue; overload; | |
function Put(const Value: Extended): TJsonValue; overload; | |
function Put(const Value: String): TJsonValue; overload; | |
function Put(const Value: TJsonArray): TJsonValue; overload; | |
function Put(const Value: TJsonObject): TJsonValue; overload; | |
function Put(const Value: TJsonValue): TJsonValue; overload; | |
procedure Delete(const Index: Integer); | |
procedure Clear; | |
public | |
property Count: Integer read GetCount; | |
property Items[Index: Integer]: TJsonValue read GetItems; default; | |
end; | |
TJsonPair = class(TJsonBase) | |
private | |
FName: String; | |
FValue: TJsonValue; | |
procedure SetName(const Value: String); | |
public | |
constructor Create(AOwner: TJsonBase; const AName: String = ''); | |
destructor Destroy; override; | |
procedure Parse(JsonString: String); override; | |
function Stringify: String; override; | |
procedure Assign(Source: TJsonBase); override; | |
public | |
property Name: String read FName write SetName; | |
property Value: TJsonValue read FValue; | |
end; | |
TJsonObject = class(TJsonBase) | |
private | |
FList: TList; | |
FAutoAdd: Boolean; | |
function GetCount: Integer; | |
function GetItems(Index: Integer): TJsonPair; | |
function GetValues(Name: String): TJsonValue; | |
public | |
constructor Create(AOwner: TJsonBase = nil); | |
destructor Destroy; override; | |
procedure Parse(JsonString: String); override; | |
function Stringify: String; override; | |
procedure Assign(Source: TJsonBase); override; | |
procedure Merge(Addition: TJsonObject); | |
function Add(const Name: String = ''): TJsonPair; | |
function Insert(const Index: Integer; const Name: String = ''): TJsonPair; | |
function Put(const Name: String; const Value: TJsonEmpty): TJsonValue; overload; | |
function Put(const Name: String; const Value: TJsonNull): TJsonValue; overload; | |
function Put(const Name: String; const Value: Boolean): TJsonValue; overload; | |
function Put(const Name: String; const Value: Integer): TJsonValue; overload; | |
function Put(const Name: String; const Value: Extended): TJsonValue; overload; | |
function Put(const Name: String; const Value: String): TJsonValue; overload; | |
function Put(const Name: String; const Value: TJsonArray): TJsonValue; overload; | |
function Put(const Name: String; const Value: TJsonObject): TJsonValue; overload; | |
function Put(const Name: String; const Value: TJsonValue): TJsonValue; overload; | |
function Put(const Value: TJsonPair): TJsonValue; overload; | |
function Find(const Name: String): Integer; | |
procedure Delete(const Index: Integer); overload; | |
procedure Delete(const Name: String); overload; | |
procedure Clear; | |
public | |
property Count: Integer read GetCount; | |
property Items[Index: Integer]: TJsonPair read GetItems; | |
property Values[Name: String]: TJsonValue read GetValues; default; | |
property AutoAdd: Boolean read FAutoAdd write FAutoAdd; | |
end; | |
TJson = class(TJsonBase) | |
private | |
FStructType: TJsonStructType; | |
FJsonArray: TJsonArray; | |
FJsonObject: TJsonObject; | |
function GetCount: Integer; | |
function GetJsonArray: TJsonArray; | |
function GetJsonObject: TJsonObject; | |
function GetValues(Name: String): TJsonValue; | |
protected | |
procedure CreateArrayIfNone; | |
procedure CreateObjectIfNone; | |
procedure RaiseIfNone; | |
procedure RaiseIfNotArray; | |
procedure RaiseIfNotObject; | |
procedure CheckJsonArray; | |
procedure CheckJsonObject; | |
public | |
constructor Create; | |
destructor Destroy; override; | |
procedure Parse(JsonString: String); override; | |
function Stringify: String; override; | |
procedure Assign(Source: TJsonBase); override; | |
procedure Delete(const Index: Integer); overload; | |
procedure Delete(const Name: String); overload; | |
procedure Clear; | |
function Get(const Index: Integer): TJsonValue; overload; //for both | |
function Get(const Name: String): TJsonValue; overload; //for JsonObject | |
//for JsonArray | |
function Put(const Value: TJsonEmpty): TJsonValue; overload; | |
function Put(const Value: TJsonNull): TJsonValue; overload; | |
function Put(const Value: Boolean): TJsonValue; overload; | |
function Put(const Value: Integer): TJsonValue; overload; | |
function Put(const Value: Extended): TJsonValue; overload; | |
function Put(const Value: String): TJsonValue; overload; | |
function Put(const Value: TJsonArray): TJsonValue; overload; | |
function Put(const Value: TJsonObject): TJsonValue; overload; | |
function Put(const Value: TJsonValue): TJsonValue; overload; | |
function Put(const Value: TJson): TJsonValue; overload; | |
//for JsonObject | |
function Put(const Name: String; const Value: TJsonEmpty): TJsonValue; overload; | |
function Put(const Name: String; const Value: TJsonNull): TJsonValue; overload; | |
function Put(const Name: String; const Value: Boolean): TJsonValue; overload; | |
function Put(const Name: String; const Value: Integer): TJsonValue; overload; | |
function Put(const Name: String; const Value: Extended): TJsonValue; overload; | |
function Put(const Name: String; const Value: String): TJsonValue; overload; | |
function Put(const Name: String; const Value: TJsonArray): TJsonValue; overload; | |
function Put(const Name: String; const Value: TJsonObject): TJsonValue; overload; | |
function Put(const Name: String; const Value: TJsonValue): TJsonValue; overload; | |
function Put(const Name: String; const Value: TJson): TJsonValue; overload; | |
function Put(const Value: TJsonPair): TJsonValue; overload; | |
public | |
property StructType: TJsonStructType read FStructType; | |
property JsonObject: TJsonObject read GetJsonObject; | |
property JsonArray: TJsonArray read GetJsonArray; | |
property Count: Integer read GetCount; | |
property Values[Name: String]: TJsonValue read GetValues; default; //for JsonObject | |
end; | |
implementation | |
{$ifndef fpc} | |
{$if not defined(CompilerVersion) or (CompilerVersion < 15)} | |
{$define fixfloattostrreplace} | |
{$ifend} | |
{$endif} | |
{** | |
* Fixed FloatToStr to convert DecimalSeparator to dot (.) decimal separator, FloatToStr returns | |
* DecimalSeparator as decimal separator, but JSON uses dot (.) as decimal separator. | |
*} | |
function FixedFloatToStr(const Value: Extended): string; | |
{$ifdef fixfloattostrreplace} | |
var | |
S, DecimalSeparator: string; | |
begin | |
try | |
S := FloatToStr(Value); | |
if (DecimalSeparator <> '.') and (Pos(DecimalSeparator, S) <> 0) then | |
Result := StringReplace(S, DecimalSeparator, '.', [rfReplaceAll]) | |
else | |
Result := S; | |
finally | |
SetLength(S, 0); | |
end; | |
end; | |
{$else} | |
var | |
LFormatSettings: TFormatSettings; | |
begin | |
LFormatSettings := DefaultFormatSettings; | |
with LFormatSettings do | |
begin | |
DecimalSeparator:= '.'; | |
end; | |
Result := FloatToStr(Value, LFormatSettings); | |
end; | |
{$endif} | |
{** | |
* Fixed TryStrToFloat to convert dot (.) decimal separator to DecimalSeparator, TryStrToFloat expects | |
* decimal separator to be DecimalSeparator, but JSON uses dot (.) as decimal separator. | |
*} | |
function FixedTryStrToFloat(const S: string; out Value: Extended): Boolean; | |
{$ifdef fixfloattostrreplace} | |
var | |
FixedS, DecimalSeparator: string; | |
begin | |
try | |
if (DecimalSeparator <> '.') and (Pos('.', S) <> 0) then | |
FixedS := StringReplace(S, '.', DecimalSeparator, [rfReplaceAll]) | |
else | |
FixedS := S; | |
Result := TryStrToFloat(FixedS, Value); | |
finally | |
SetLength(FixedS, 0); | |
end; | |
end; | |
{$else} | |
var | |
LFormatSettings: TFormatSettings; | |
begin | |
LFormatSettings := DefaultFormatSettings; | |
with LFormatSettings do | |
begin | |
DecimalSeparator:= '.'; | |
end; | |
Result := TryStrToFloat(S, Value, LFormatSettings); | |
end; | |
{$endif} | |
{** | |
* Fixed StrToFloat to convert dot (.) decimal separator to DecimalSeparator, StrToFloat expects | |
* decimal separator to be DecimalSeparator, but JSON uses dot (.) as decimal separator. | |
*} | |
function FixedStrToFloat(const S: string): Extended; | |
{$ifdef fixfloattostrreplace} | |
var | |
FixedS, DecimalSeparator: string; | |
begin | |
try | |
if (DecimalSeparator <> '.') and (Pos('.', S) <> 0) then | |
FixedS := StringReplace(S, '.', DecimalSeparator, [rfReplaceAll]) | |
else | |
FixedS := S; | |
Result := StrToFloat(FixedS); | |
finally | |
SetLength(FixedS, 0); | |
end; | |
end; | |
{$else} | |
var | |
LFormatSettings: TFormatSettings; | |
begin | |
LFormatSettings := DefaultFormatSettings; | |
with LFormatSettings do | |
begin | |
DecimalSeparator:= '.'; | |
end; | |
Result := StrToFloat(S, LFormatSettings); | |
end; | |
{$endif} | |
{ TJsonBase } | |
function TJsonBase.AnalyzeJsonValueType(const S: String): TJsonValueType; | |
var | |
Len: Integer; | |
Number: Extended; | |
begin | |
Result := jvNone; | |
Len := Length(S); | |
if Len >= 2 then | |
begin | |
if (S[1] = '{') and (S[Len] = '}') then Result := jvObject | |
else if (S[1] = '[') and (S[Len] = ']') then Result := jvArray | |
else if (S[1] = '"') and (S[Len] = '"') then Result := jvString | |
else if SameText(S, 'null') then Result := jvNull | |
else if SameText(S, 'true') or SameText(S, 'false') then Result := jvBoolean | |
else if FixedTryStrToFloat(S, Number) then Result := jvNumber; | |
end | |
else if FixedTryStrToFloat(S, Number) then Result := jvNumber; | |
end; | |
constructor TJsonBase.Create(AOwner: TJsonBase); | |
begin | |
FOwner := AOwner; | |
end; | |
function TJsonBase.Decode(const S: String): String; | |
function HexValue(C: Char): Byte; | |
begin | |
case C of | |
'0'..'9': Result := Byte(C) - Byte('0'); | |
'a'..'f': Result := (Byte(C) - Byte('a')) + 10; | |
'A'..'F': Result := (Byte(C) - Byte('A')) + 10; | |
else raise Exception.Create('Illegal hexadecimal characters "' + C + '"'); | |
end; | |
end; | |
function HexToUnicode(Hex: String): String; | |
begin | |
try | |
Result := Char((HexValue(Hex[3]) shl 4) + HexValue(Hex[4])) | |
+ Char((HexValue(Hex[1]) shl 4) + HexValue(Hex[2])); | |
except | |
raise Exception.Create('Illegal four-hex-digits "' + Hex + '"'); | |
end; | |
end; | |
var | |
I: Integer; | |
C: Char; | |
begin | |
Result := ''; | |
I := 1; | |
while I <= Length(S) do | |
begin | |
C := S[I]; | |
Inc(I); | |
if C = '\' then | |
begin | |
C := S[I]; | |
Inc(I); | |
case C of | |
'b': Result := Result + #8; | |
't': Result := Result + #9; | |
'n': Result := Result + #10; | |
'f': Result := Result + #12; | |
'r': Result := Result + #13; | |
'u': | |
begin | |
Result := Result + HexToUnicode(Copy(S, I, 4)); | |
Inc(I, 4); | |
end; | |
else Result := Result + C; | |
end; | |
end | |
else Result := Result + C; | |
end; | |
end; | |
destructor TJsonBase.Destroy; | |
begin | |
inherited Destroy; | |
end; | |
function TJsonBase.Encode(const S: String): String; | |
var | |
I: Integer; | |
C: Char; | |
begin | |
Result := ''; | |
for I := 1 to Length(S) do | |
begin | |
C := S[I]; | |
case C of | |
'"', '\', '/': Result := Result + '\' + C; | |
#8: Result := Result + '\b'; | |
#9: Result := Result + '\t'; | |
#10: Result := Result + '\n'; | |
#12: Result := Result + '\f'; | |
#13: Result := Result + '\r'; | |
else Result := Result + C; | |
end; | |
end; | |
end; | |
function TJsonBase.GetOwner: TJsonBase; | |
begin | |
Result := FOwner; | |
end; | |
function TJsonBase.GetOwnerName: String; | |
var | |
TheOwner: TJsonBase; | |
begin | |
Result := ''; | |
TheOwner := Owner; | |
while True do | |
begin | |
if not Assigned(TheOwner) then Break | |
else if TheOwner is TJsonPair then | |
begin | |
Result := (TheOwner as TJsonPair).Name; | |
Break; | |
end | |
else TheOwner := TheOwner.Owner; | |
end; | |
end; | |
function TJsonBase.IsJsonArray(const S: String): Boolean; | |
var | |
Len: Integer; | |
begin | |
Len := Length(S); | |
Result := (Len >= 2) and (S[1] = '[') and (S[Len] = ']'); | |
end; | |
function TJsonBase.IsJsonBoolean(const S: String): Boolean; | |
begin | |
Result := SameText(S, 'true') or SameText(S, 'false'); | |
end; | |
function TJsonBase.IsJsonNull(const S: String): Boolean; | |
begin | |
Result := SameText(S, 'null'); | |
end; | |
function TJsonBase.IsJsonNumber(const S: String): Boolean; | |
var | |
Number: Extended; | |
begin | |
Result := FixedTryStrToFloat(S, Number); | |
end; | |
function TJsonBase.IsJsonObject(const S: String): Boolean; | |
var | |
Len: Integer; | |
begin | |
Len := Length(S); | |
Result := (Len >= 2) and (S[1] = '{') and (S[Len] = '}'); | |
end; | |
function TJsonBase.IsJsonString(const S: String): Boolean; | |
var | |
Len: Integer; | |
begin | |
Len := Length(S); | |
Result := (Len >= 2) and (S[1] = '"') and (S[Len] = '"'); | |
end; | |
procedure TJsonBase.RaiseAssignError(Source: TJsonBase); | |
var | |
SourceClassName: String; | |
begin | |
if Source is TObject then SourceClassName := Source.ClassName | |
else SourceClassName := 'nil'; | |
RaiseError(Format('assign error: %s to %s', [SourceClassName, ClassName])); | |
end; | |
procedure TJsonBase.RaiseError(const Msg: String); | |
var | |
S: String; | |
begin | |
S := Format('<%s>%s', [ClassName, Msg]); | |
raise Exception.Create(S); | |
end; | |
procedure TJsonBase.RaiseParseError(const JsonString: String); | |
begin | |
RaiseError(Format('"%s" parse error: %s', [GetOwnerName, JsonString])); | |
end; | |
procedure TJsonBase.Split(const S: String; const Delimiter: Char; | |
Strings: TStrings); | |
function IsPairBegin(C: Char): Boolean; | |
begin | |
Result := (C = '{') or (C = '[') or (C = '"'); | |
end; | |
function GetPairEnd(C: Char): Char; | |
begin | |
case C of | |
'{': Result := '}'; | |
'[': Result := ']'; | |
'"': Result := '"'; | |
else Result := #0; | |
end; | |
end; | |
function MoveToPair(P: PChar): PChar; | |
var | |
PairBegin, PairEnd: Char; | |
C: Char; | |
begin | |
PairBegin := P^; | |
PairEnd := GetPairEnd(PairBegin); | |
Result := P; | |
while Result^ <> #0 do | |
begin | |
Inc(Result); | |
C := Result^; | |
if C = PairEnd then Break | |
else if (PairBegin = '"') and (C = '\') then Inc(Result) | |
else if (PairBegin <> '"') and IsPairBegin(C) then Result := MoveToPair(Result); | |
end; | |
end; | |
var | |
PtrBegin, PtrEnd: PChar; | |
C: Char; | |
StrItem: String; | |
begin | |
PtrBegin := PChar(S); | |
PtrEnd := PtrBegin; | |
while PtrEnd^ <> #0 do | |
begin | |
C := PtrEnd^; | |
if C = Delimiter then | |
begin | |
StrItem := Trim(Copy(PtrBegin, 1, PtrEnd - PtrBegin)); | |
Strings.Add(StrItem); | |
PtrBegin := PtrEnd + 1; | |
PtrEnd := PtrBegin; | |
Continue; | |
end | |
else if IsPairBegin(C) then PtrEnd := MoveToPair(PtrEnd); | |
Inc(PtrEnd); | |
end; | |
StrItem := Trim(Copy(PtrBegin, 1, PtrEnd - PtrBegin)); | |
if StrItem <> '' then Strings.Add(StrItem); | |
end; | |
{ TJsonValue } | |
procedure TJsonValue.Assign(Source: TJsonBase); | |
var | |
Src: TJsonValue; | |
begin | |
Clear; | |
if not(Source is TJsonValue) and not(Source is TJsonObject) and not(Source is TJsonArray) then | |
RaiseAssignError(Source); | |
if Source is TJsonObject then | |
begin | |
FValueType := jvObject; | |
FObjectValue := TJsonObject.Create(Self); | |
FObjectValue.Assign(Source); | |
end | |
else if Source is TJsonArray then | |
begin | |
FValueType := jvArray; | |
FArrayValue := TJsonArray.Create(Self); | |
FArrayValue.Assign(Source); | |
end | |
else if Source is TJsonValue then | |
begin | |
Src := Source as TJsonValue; | |
FValueType := Src.FValueType; | |
case FValueType of | |
jvNone, jvNull: ; | |
jvString: FStringValue := Src.FStringValue; | |
jvNumber: FNumberValue := Src.FNumberValue; | |
jvBoolean: FBooleanValue := Src.FBooleanValue; | |
jvObject: | |
begin | |
FObjectValue := TJsonObject.Create(Self); | |
FObjectValue.Assign(Src.FObjectValue); | |
end; | |
jvArray: | |
begin | |
FArrayValue := TJsonArray.Create(Self); | |
FArrayValue.Assign(Src.FArrayValue); | |
end; | |
end; | |
end; | |
end; | |
procedure TJsonValue.Clear; | |
begin | |
case FValueType of | |
jvNone, jvNull: ; | |
jvString: FStringValue := ''; | |
jvNumber: FNumberValue := 0; | |
jvBoolean: FBooleanValue := False; | |
jvObject: | |
begin | |
FObjectValue.Free; | |
FObjectValue := nil; | |
end; | |
jvArray: | |
begin | |
FArrayValue.Free; | |
FArrayValue := nil; | |
end; | |
end; | |
FValueType := jvNone; | |
end; | |
constructor TJsonValue.Create(AOwner: TJsonBase); | |
begin | |
inherited Create(AOwner); | |
FStringValue := ''; | |
FNumberValue := 0; | |
FBooleanValue := False; | |
FObjectValue := nil; | |
FArrayValue := nil; | |
FValueType := jvNone; | |
end; | |
destructor TJsonValue.Destroy; | |
begin | |
Clear; | |
inherited Destroy; | |
end; | |
function TJsonValue.GetAsArray: TJsonArray; | |
begin | |
if IsEmpty then | |
begin | |
FValueType := jvArray; | |
FArrayValue := TJsonArray.Create(Self); | |
end; | |
if FValueType <> jvArray then RaiseValueTypeError(jvArray); | |
Result := FArrayValue; | |
end; | |
function TJsonValue.GetAsBoolean: Boolean; | |
begin | |
Result := False; | |
case FValueType of | |
jvNone, jvNull: Result := False; | |
jvString: Result := SameText(FStringValue, 'true'); | |
jvNumber: Result := (FNumberValue <> 0); | |
jvBoolean: Result := FBooleanValue; | |
jvObject, jvArray: RaiseValueTypeError(jvBoolean); | |
end; | |
end; | |
function TJsonValue.GetAsInteger: Integer; | |
begin | |
Result := 0; | |
case FValueType of | |
jvNone, jvNull: Result := 0; | |
jvString: Result := Trunc(FixedStrToFloat(FStringValue)); | |
jvNumber: Result := Trunc(FNumberValue); | |
jvBoolean: Result := Ord(FBooleanValue); | |
jvObject, jvArray: RaiseValueTypeError(jvNumber); | |
end; | |
end; | |
function TJsonValue.GetAsNumber: Extended; | |
begin | |
Result := 0; | |
case FValueType of | |
jvNone, jvNull: Result := 0; | |
jvString: Result := FixedStrToFloat(FStringValue); | |
jvNumber: Result := FNumberValue; | |
jvBoolean: Result := Ord(FBooleanValue); | |
jvObject, jvArray: RaiseValueTypeError(jvNumber); | |
end; | |
end; | |
function TJsonValue.GetAsObject: TJsonObject; | |
begin | |
if IsEmpty then | |
begin | |
FValueType := jvObject; | |
FObjectValue := TJsonObject.Create(Self); | |
end; | |
if FValueType <> jvObject then RaiseValueTypeError(jvObject); | |
Result := FObjectValue; | |
end; | |
function TJsonValue.GetAsString: String; | |
const | |
BooleanStr: array[Boolean] of String = ('false', 'true'); | |
begin | |
Result := ''; | |
case FValueType of | |
jvNone, jvNull: Result := ''; | |
jvString: Result := FStringValue; | |
jvNumber: Result := FloatToStr(FNumberValue); | |
jvBoolean: Result := BooleanStr[FBooleanValue]; | |
jvObject, jvArray: RaiseValueTypeError(jvString); | |
end; | |
end; | |
function TJsonValue.GetIsEmpty: Boolean; | |
begin | |
Result := (FValueType = jvNone); | |
end; | |
function TJsonValue.GetIsNull: Boolean; | |
begin | |
Result := (FValueType = jvNull); | |
end; | |
procedure TJsonValue.Parse(JsonString: String); | |
begin | |
Clear; | |
FValueType := AnalyzeJsonValueType(JsonString); | |
case FValueType of | |
jvNone: RaiseParseError(JsonString); | |
jvNull: ; | |
jvString: FStringValue := Decode(Copy(JsonString, 2, Length(JsonString) - 2)); | |
jvNumber: FNumberValue := StrToFloat(StringReplace(JsonString, '.', ',', [rfReplaceAll, rfIgnoreCase])); | |
jvBoolean: FBooleanValue := SameText(JsonString, 'true'); | |
jvObject: | |
begin | |
FObjectValue := TJsonObject.Create(Self); | |
FObjectValue.Parse(JsonString); | |
end; | |
jvArray: | |
begin | |
FArrayValue := TJsonArray.Create(Self); | |
FArrayValue.Parse(JsonString); | |
end; | |
end; | |
end; | |
procedure TJsonValue.RaiseValueTypeError(const AsValueType: TJsonValueType); | |
const | |
StrJsonValueType: array[TJsonValueType] of String = ('jvNone', 'jvNull', 'jvString', 'jvNumber', 'jvBoolean', 'jvObject', 'jvArray'); | |
var | |
S: String; | |
begin | |
S := Format('"%s" value type error: %s to %s', [GetOwnerName, StrJsonValueType[FValueType], StrJsonValueType[AsValueType]]); | |
RaiseError(S); | |
end; | |
procedure TJsonValue.SetAsArray(const Value: TJsonArray); | |
begin | |
if FValueType <> jvArray then | |
begin | |
Clear; | |
FValueType := jvArray; | |
FArrayValue := TJsonArray.Create(Self); | |
end; | |
FArrayValue.Assign(Value); | |
end; | |
procedure TJsonValue.SetAsBoolean(const Value: Boolean); | |
begin | |
if FValueType <> jvBoolean then | |
begin | |
Clear; | |
FValueType := jvBoolean; | |
end; | |
FBooleanValue := Value; | |
end; | |
procedure TJsonValue.SetAsInteger(const Value: Integer); | |
begin | |
SetAsNumber(Value); | |
end; | |
procedure TJsonValue.SetAsNumber(const Value: Extended); | |
begin | |
if FValueType <> jvNumber then | |
begin | |
Clear; | |
FValueType := jvNumber; | |
end; | |
FNumberValue := Value; | |
end; | |
procedure TJsonValue.SetAsObject(const Value: TJsonObject); | |
begin | |
if FValueType <> jvObject then | |
begin | |
Clear; | |
FValueType := jvObject; | |
FObjectValue := TJsonObject.Create(Self); | |
end; | |
FObjectValue.Assign(Value); | |
end; | |
procedure TJsonValue.SetAsString(const Value: String); | |
begin | |
if FValueType <> jvString then | |
begin | |
Clear; | |
FValueType := jvString; | |
end; | |
FStringValue := Value; | |
end; | |
procedure TJsonValue.SetIsEmpty(const Value: Boolean); | |
const | |
EmptyValueType: array[Boolean] of TJsonValueType = (jvNull, jvNone); | |
begin | |
if FValueType <> EmptyValueType[Value] then | |
begin | |
Clear; | |
FValueType := EmptyValueType[Value]; | |
end; | |
end; | |
procedure TJsonValue.SetIsNull(const Value: Boolean); | |
const | |
NullValueType: array[Boolean] of TJsonValueType = (jvNone, jvNull); | |
begin | |
if FValueType <> NullValueType[Value] then | |
begin | |
Clear; | |
FValueType := NullValueType[Value]; | |
end; | |
end; | |
function TJsonValue.Stringify: String; | |
const | |
StrBoolean: array[Boolean] of String = ('false', 'true'); | |
begin | |
Result := ''; | |
case FValueType of | |
jvNone, jvNull: Result := 'null'; | |
jvString: Result := '"' + Encode(FStringValue) + '"'; | |
jvNumber: Result := FixedFloatToStr(FNumberValue); | |
jvBoolean: Result := StrBoolean[FBooleanValue]; | |
jvObject: Result := FObjectValue.Stringify; | |
jvArray: Result := FArrayValue.Stringify; | |
end; | |
end; | |
{ TJsonArray } | |
function TJsonArray.Add: TJsonValue; | |
begin | |
Result := TJsonValue.Create(Self); | |
FList.Add(Result); | |
end; | |
procedure TJsonArray.Assign(Source: TJsonBase); | |
var | |
Src: TJsonArray; | |
I: Integer; | |
begin | |
Clear; | |
if not(Source is TJsonArray) then RaiseAssignError(Source); | |
Src := Source as TJsonArray; | |
for I := 0 to Src.Count - 1 do Add.Assign(Src[I]); | |
end; | |
procedure TJsonArray.Clear; | |
var | |
I: Integer; | |
Item: TJsonValue; | |
begin | |
for I := 0 to FList.Count - 1 do | |
begin | |
Item := TJsonValue(FList[I]); | |
Item.Free; | |
end; | |
FList.Clear; | |
end; | |
constructor TJsonArray.Create(AOwner: TJsonBase); | |
begin | |
inherited Create(AOwner); | |
FList := TList.Create; | |
end; | |
procedure TJsonArray.Delete(const Index: Integer); | |
var | |
Item: TJsonValue; | |
begin | |
Item := TJsonValue(FList[Index]); | |
Item.Free; | |
FList.Delete(Index); | |
end; | |
destructor TJsonArray.Destroy; | |
begin | |
Clear; | |
FList.Free; | |
inherited; | |
end; | |
function TJsonArray.GetCount: Integer; | |
begin | |
Result := FList.Count; | |
end; | |
function TJsonArray.GetItems(Index: Integer): TJsonValue; | |
begin | |
Result := TJsonValue(FList[Index]); | |
end; | |
function TJsonArray.Insert(const Index: Integer): TJsonValue; | |
begin | |
Result := TJsonValue.Create(Self); | |
FList.Insert(Index, Result); | |
end; | |
procedure TJsonArray.Merge(Addition: TJsonArray); | |
var | |
I: Integer; | |
begin | |
for I := 0 to Addition.Count - 1 do Add.Assign(Addition[I]); | |
end; | |
procedure TJsonArray.Parse(JsonString: String); | |
var | |
I: Integer; | |
S: String; | |
List: TStringList; | |
Item: TJsonValue; | |
begin | |
Clear; | |
JsonString := Trim(JsonString); | |
if not IsJsonArray(JsonString) then RaiseParseError(JsonString); | |
S := Trim(Copy(JsonString, 2, Length(JsonString) - 2)); | |
List := TStringList.Create; | |
try | |
Split(S, ',', List); | |
for I := 0 to List.Count - 1 do | |
begin | |
Item := Add; | |
Item.Parse(List[I]); | |
end; | |
finally | |
List.Free; | |
end; | |
end; | |
function TJsonArray.Put(const Value: Boolean): TJsonValue; | |
begin | |
Result := Add; | |
Result.AsBoolean := Value; | |
end; | |
function TJsonArray.Put(const Value: Integer): TJsonValue; | |
begin | |
Result := Add; | |
Result.AsInteger := Value; | |
end; | |
function TJsonArray.Put(const Value: TJsonEmpty): TJsonValue; | |
begin | |
Result := Add; | |
Result.IsEmpty := True; | |
end; | |
function TJsonArray.Put(const Value: TJsonNull): TJsonValue; | |
begin | |
Result := Add; | |
Result.IsNull := True; | |
end; | |
function TJsonArray.Put(const Value: Extended): TJsonValue; | |
begin | |
Result := Add; | |
Result.AsNumber := Value; | |
end; | |
function TJsonArray.Put(const Value: TJsonObject): TJsonValue; | |
begin | |
Result := Add; | |
Result.Assign(Value); | |
end; | |
function TJsonArray.Put(const Value: TJsonValue): TJsonValue; | |
begin | |
Result := Add; | |
Result.Assign(Value); | |
end; | |
function TJsonArray.Put(const Value: String): TJsonValue; | |
begin | |
Result := Add; | |
Result.AsString := Value; | |
end; | |
function TJsonArray.Put(const Value: TJsonArray): TJsonValue; | |
begin | |
Result := Add; | |
Result.Assign(Value); | |
end; | |
function TJsonArray.Stringify: String; | |
var | |
I: Integer; | |
Item: TJsonValue; | |
begin | |
Result := '['; | |
for I := 0 to FList.Count - 1 do | |
begin | |
Item := TJsonValue(FList[I]); | |
if I > 0 then Result := Result + ','; | |
Result := Result + Item.Stringify; | |
end; | |
Result := Result + ']'; | |
end; | |
{ TJsonPair } | |
procedure TJsonPair.Assign(Source: TJsonBase); | |
var | |
Src: TJsonPair; | |
begin | |
if not(Source is TJsonPair) then RaiseAssignError(Source); | |
Src := Source as TJsonPair; | |
FName := Src.FName; | |
FValue.Assign(Src.FValue); | |
end; | |
constructor TJsonPair.Create(AOwner: TJsonBase; const AName: String); | |
begin | |
inherited Create(AOwner); | |
FName := AName; | |
FValue := TJsonValue.Create(Self); | |
end; | |
destructor TJsonPair.Destroy; | |
begin | |
FValue.Free; | |
inherited Destroy; | |
end; | |
procedure TJsonPair.Parse(JsonString: String); | |
var | |
List: TStringList; | |
StrName: String; | |
begin | |
List := TStringList.Create; | |
try | |
Split(JsonString, ':', List); | |
if List.Count <> 2 then RaiseParseError(JsonString); | |
StrName := List[0]; | |
if not IsJsonString(StrName) then RaiseParseError(StrName); | |
FName := Decode(Copy(StrName, 2, Length(StrName) - 2)); | |
FValue.Parse(List[1]); | |
finally | |
List.Free; | |
end; | |
end; | |
procedure TJsonPair.SetName(const Value: String); | |
begin | |
FName := Value; | |
end; | |
function TJsonPair.Stringify: String; | |
begin | |
Result := Format('"%s":%s', [Encode(FName), FValue.Stringify]); | |
end; | |
{ TJsonObject } | |
function TJsonObject.Add(const Name: String): TJsonPair; | |
begin | |
Result := TJsonPair.Create(Self, Name); | |
FList.Add(Result); | |
end; | |
procedure TJsonObject.Assign(Source: TJsonBase); | |
var | |
Src: TJsonObject; | |
I: Integer; | |
begin | |
Clear; | |
if not(Source is TJsonObject) then RaiseAssignError(Source); | |
Src := Source as TJsonObject; | |
for I := 0 to Src.Count - 1 do Add.Assign(Src.Items[I]); | |
end; | |
procedure TJsonObject.Clear; | |
var | |
I: Integer; | |
Item: TJsonPair; | |
begin | |
for I := 0 to FList.Count - 1 do | |
begin | |
Item := TJsonPair(FList[I]); | |
Item.Free; | |
end; | |
FList.Clear; | |
end; | |
constructor TJsonObject.Create(AOwner: TJsonBase); | |
begin | |
inherited Create(AOwner); | |
FList := TList.Create; | |
FAutoAdd := True; | |
end; | |
procedure TJsonObject.Delete(const Index: Integer); | |
var | |
Item: TJsonPair; | |
begin | |
Item := TJsonPair(FList[Index]); | |
Item.Free; | |
FList.Delete(Index); | |
end; | |
procedure TJsonObject.Delete(const Name: String); | |
var | |
Index: Integer; | |
begin | |
Index := Find(Name); | |
if Index < 0 then RaiseError(Format('"%s" not found', [Name])); | |
Delete(Index); | |
end; | |
destructor TJsonObject.Destroy; | |
begin | |
Clear; | |
FList.Free; | |
inherited Destroy; | |
end; | |
function TJsonObject.Find(const Name: String): Integer; | |
var | |
I: Integer; | |
Pair: TJsonPair; | |
begin | |
Result := -1; | |
for I := 0 to FList.Count - 1 do | |
begin | |
Pair := TJsonPair(FList[I]); | |
if SameText(Name, Pair.Name) then | |
begin | |
Result := I; | |
Break; | |
end; | |
end; | |
end; | |
function TJsonObject.GetCount: Integer; | |
begin | |
Result := FList.Count; | |
end; | |
function TJsonObject.GetItems(Index: Integer): TJsonPair; | |
begin | |
Result := TJsonPair(FList[Index]); | |
end; | |
function TJsonObject.GetValues(Name: String): TJsonValue; | |
var | |
Index: Integer; | |
Pair: TJsonPair; | |
begin | |
Index := Find(Name); | |
if Index < 0 then | |
begin | |
if not FAutoAdd then RaiseError(Format('%s not found', [Name])); | |
Pair := Add(Name); | |
end | |
else Pair := TJsonPair(FList[Index]); | |
Result := Pair.Value; | |
end; | |
function TJsonObject.Insert(const Index: Integer; | |
const Name: String): TJsonPair; | |
begin | |
Result := TJsonPair.Create(Self, Name); | |
FList.Insert(Index, Result); | |
end; | |
procedure TJsonObject.Merge(Addition: TJsonObject); | |
var | |
I: Integer; | |
begin | |
for I := 0 to Addition.Count - 1 do Add.Assign(Addition.Items[I]); | |
end; | |
procedure TJsonObject.Parse(JsonString: String); | |
var | |
I: Integer; | |
S: String; | |
List: TStringList; | |
Item: TJsonPair; | |
begin | |
Clear; | |
JsonString := Trim(JsonString); | |
if not IsJsonObject(JsonString) then RaiseParseError(JsonString); | |
S := Trim(Copy(JsonString, 2, Length(JsonString) - 2)); | |
List := TStringList.Create; | |
try | |
Split(S, ',', List); | |
for I := 0 to List.Count - 1 do | |
begin | |
Item := Add; | |
Item.Parse(List[I]); | |
end; | |
finally | |
List.Free; | |
end; | |
end; | |
function TJsonObject.Put(const Name: String; | |
const Value: Integer): TJsonValue; | |
begin | |
Result := Add(Name).Value; | |
Result.AsInteger := Value; | |
end; | |
function TJsonObject.Put(const Name: String; | |
const Value: Extended): TJsonValue; | |
begin | |
Result := Add(Name).Value; | |
Result.AsNumber := Value; | |
end; | |
function TJsonObject.Put(const Name: String; | |
const Value: Boolean): TJsonValue; | |
begin | |
Result := Add(Name).Value; | |
Result.AsBoolean := Value; | |
end; | |
function TJsonObject.Put(const Name: String; | |
const Value: TJsonEmpty): TJsonValue; | |
begin | |
Result := Add(Name).Value; | |
Result.IsEmpty := True; | |
end; | |
function TJsonObject.Put(const Name: String; | |
const Value: TJsonNull): TJsonValue; | |
begin | |
Result := Add(Name).Value; | |
Result.IsNull := True; | |
end; | |
function TJsonObject.Put(const Name: String; | |
const Value: TJsonValue): TJsonValue; | |
begin | |
Result := Add(Name).Value; | |
Result.Assign(Value); | |
end; | |
function TJsonObject.Put(const Value: TJsonPair): TJsonValue; | |
var | |
Pair: TJsonPair; | |
begin | |
Pair := Add; | |
Pair.Assign(Value); | |
Result := Pair.Value; | |
end; | |
function TJsonObject.Put(const Name: String; | |
const Value: TJsonObject): TJsonValue; | |
begin | |
Result := Add(Name).Value; | |
Result.Assign(Value); | |
end; | |
function TJsonObject.Put(const Name, Value: String): TJsonValue; | |
begin | |
Result := Add(Name).Value; | |
Result.AsString := Value; | |
end; | |
function TJsonObject.Put(const Name: String; | |
const Value: TJsonArray): TJsonValue; | |
begin | |
Result := Add(Name).Value; | |
Result.Assign(Value); | |
end; | |
function TJsonObject.Stringify: String; | |
var | |
I: Integer; | |
Item: TJsonPair; | |
begin | |
Result := '{'; | |
for I := 0 to FList.Count - 1 do | |
begin | |
Item := TJsonPair(FList[I]); | |
if I > 0 then Result := Result + ','; | |
Result := Result + Item.Stringify; | |
end; | |
Result := Result + '}'; | |
end; | |
{ TJson } | |
procedure TJson.Assign(Source: TJsonBase); | |
begin | |
Clear; | |
if Source is TJson then | |
begin | |
case (Source as TJson).FStructType of | |
jsNone: ; | |
jsArray: | |
begin | |
CreateArrayIfNone; | |
FJsonArray.Assign((Source as TJson).FJsonArray); | |
end; | |
jsObject: | |
begin | |
CreateObjectIfNone; | |
FJsonObject.Assign((Source as TJson).FJsonObject); | |
end; | |
end; | |
end | |
else if Source is TJsonArray then | |
begin | |
CreateArrayIfNone; | |
FJsonArray.Assign(Source); | |
end | |
else if Source is TJsonObject then | |
begin | |
CreateObjectIfNone; | |
FJsonObject.Assign(Source); | |
end | |
else if Source is TJsonValue then | |
begin | |
if (Source as TJsonValue).ValueType = jvArray then | |
begin | |
CreateArrayIfNone; | |
FJsonArray.Assign((Source as TJsonValue).AsArray); | |
end | |
else if (Source as TJsonValue).ValueType = jvObject then | |
begin | |
CreateObjectIfNone; | |
FJsonObject.Assign((Source as TJsonValue).AsObject); | |
end | |
else RaiseAssignError(Source); | |
end | |
else RaiseAssignError(Source); | |
end; | |
procedure TJson.CheckJsonArray; | |
begin | |
CreateArrayIfNone; | |
RaiseIfNotArray; | |
end; | |
procedure TJson.CheckJsonObject; | |
begin | |
CreateObjectIfNone; | |
RaiseIfNotObject; | |
end; | |
procedure TJson.Clear; | |
begin | |
case FStructType of | |
jsNone: ; | |
jsArray: | |
begin | |
FJsonArray.Free; | |
FJsonArray := nil; | |
end; | |
jsObject: | |
begin | |
FJsonObject.Free; | |
FJsonObject := nil; | |
end; | |
end; | |
FStructType := jsNone; | |
end; | |
constructor TJson.Create; | |
begin | |
inherited Create(nil); | |
FStructType := jsNone; | |
FJsonArray := nil; | |
FJsonObject := nil; | |
end; | |
procedure TJson.CreateArrayIfNone; | |
begin | |
if FStructType = jsNone then | |
begin | |
FStructType := jsArray; | |
FJsonArray := TJsonArray.Create(Self); | |
end; | |
end; | |
procedure TJson.CreateObjectIfNone; | |
begin | |
if FStructType = jsNone then | |
begin | |
FStructType := jsObject; | |
FJsonObject := TJsonObject.Create(Self); | |
end; | |
end; | |
procedure TJson.Delete(const Index: Integer); | |
begin | |
RaiseIfNone; | |
case FStructType of | |
jsArray: FJsonArray.Delete(Index); | |
jsObject: FJsonObject.Delete(Index); | |
end; | |
end; | |
procedure TJson.Delete(const Name: String); | |
begin | |
RaiseIfNotObject; | |
FJsonObject.Delete(Name); | |
end; | |
destructor TJson.Destroy; | |
begin | |
Clear; | |
inherited Destroy; | |
end; | |
function TJson.Get(const Index: Integer): TJsonValue; | |
begin | |
Result := nil; | |
RaiseIfNone; | |
case FStructType of | |
jsArray: Result := FJsonArray.Items[Index]; | |
jsObject: Result := FJsonObject.Items[Index].Value; | |
end; | |
end; | |
function TJson.Get(const Name: String): TJsonValue; | |
begin | |
CheckJsonObject; | |
Result := FJsonObject.Values[Name]; | |
end; | |
function TJson.GetCount: Integer; | |
begin | |
case FStructType of | |
jsArray: Result := FJsonArray.Count; | |
jsObject: Result := FJsonObject.Count; | |
else Result := 0; | |
end; | |
end; | |
function TJson.GetJsonArray: TJsonArray; | |
begin | |
CheckJsonArray; | |
Result := FJsonArray; | |
end; | |
function TJson.GetJsonObject: TJsonObject; | |
begin | |
CheckJsonObject; | |
Result := FJsonObject; | |
end; | |
function TJson.GetValues(Name: String): TJsonValue; | |
begin | |
Result := Get(Name); | |
end; | |
procedure TJson.Parse(JsonString: String); | |
begin | |
Clear; | |
JsonString := Trim(JsonString); | |
if IsJsonArray(JsonString) then | |
begin | |
CreateArrayIfNone; | |
FJsonArray.Parse(JsonString); | |
end | |
else if IsJsonObject(JsonString) then | |
begin | |
CreateObjectIfNone; | |
FJsonObject.Parse(JsonString); | |
end | |
else RaiseParseError(JsonString); | |
end; | |
function TJson.Put(const Value: Integer): TJsonValue; | |
begin | |
CheckJsonArray; | |
Result := FJsonArray.Put(Value); | |
end; | |
function TJson.Put(const Value: Extended): TJsonValue; | |
begin | |
CheckJsonArray; | |
Result := FJsonArray.Put(Value); | |
end; | |
function TJson.Put(const Value: Boolean): TJsonValue; | |
begin | |
CheckJsonArray; | |
Result := FJsonArray.Put(Value); | |
end; | |
function TJson.Put(const Value: TJsonEmpty): TJsonValue; | |
begin | |
CheckJsonArray; | |
Result := FJsonArray.Put(Value); | |
end; | |
function TJson.Put(const Value: TJsonNull): TJsonValue; | |
begin | |
CheckJsonArray; | |
Result := FJsonArray.Put(Value); | |
end; | |
function TJson.Put(const Value: String): TJsonValue; | |
begin | |
CheckJsonArray; | |
Result := FJsonArray.Put(Value); | |
end; | |
function TJson.Put(const Value: TJsonValue): TJsonValue; | |
begin | |
CheckJsonArray; | |
Result := FJsonArray.Put(Value); | |
end; | |
function TJson.Put(const Value: TJsonObject): TJsonValue; | |
begin | |
CheckJsonArray; | |
Result := FJsonArray.Put(Value); | |
end; | |
function TJson.Put(const Value: TJsonArray): TJsonValue; | |
begin | |
CheckJsonArray; | |
Result := FJsonArray.Put(Value); | |
end; | |
function TJson.Put(const Name: String; const Value: Integer): TJsonValue; | |
begin | |
CheckJsonObject; | |
Result := FJsonObject.Put(Name, Value); | |
end; | |
function TJson.Put(const Name: String; const Value: Extended): TJsonValue; | |
begin | |
CheckJsonObject; | |
Result := FJsonObject.Put(Name, Value); | |
end; | |
function TJson.Put(const Name: String; const Value: Boolean): TJsonValue; | |
begin | |
CheckJsonObject; | |
Result := FJsonObject.Put(Name, Value); | |
end; | |
function TJson.Put(const Name: String; | |
const Value: TJsonEmpty): TJsonValue; | |
begin | |
CheckJsonObject; | |
Result := FJsonObject.Put(Name, Value); | |
end; | |
function TJson.Put(const Name: String; const Value: TJsonNull): TJsonValue; | |
begin | |
CheckJsonObject; | |
Result := FJsonObject.Put(Name, Value); | |
end; | |
function TJson.Put(const Name: String; | |
const Value: TJsonValue): TJsonValue; | |
begin | |
CheckJsonObject; | |
Result := FJsonObject.Put(Name, Value); | |
end; | |
function TJson.Put(const Value: TJsonPair): TJsonValue; | |
begin | |
CheckJsonObject; | |
Result := FJsonObject.Put(Value); | |
end; | |
function TJson.Put(const Name: String; | |
const Value: TJsonObject): TJsonValue; | |
begin | |
CheckJsonObject; | |
Result := FJsonObject.Put(Name, Value); | |
end; | |
function TJson.Put(const Name, Value: String): TJsonValue; | |
begin | |
CheckJsonObject; | |
Result := FJsonObject.Put(Name, Value); | |
end; | |
function TJson.Put(const Name: String; | |
const Value: TJsonArray): TJsonValue; | |
begin | |
CheckJsonObject; | |
Result := FJsonObject.Put(Name, Value); | |
end; | |
function TJson.Put(const Value: TJson): TJsonValue; | |
begin | |
CheckJsonArray; | |
case Value.FStructType of | |
jsArray: Result := Put(Value.FJsonArray); | |
jsObject: Result := Put(Value.FJsonObject); | |
else Result := nil; | |
end; | |
end; | |
function TJson.Put(const Name: String; const Value: TJson): TJsonValue; | |
begin | |
CheckJsonObject; | |
case Value.FStructType of | |
jsArray: Result := Put(Name, Value.FJsonArray); | |
jsObject: Result := Put(Name, Value.FJsonObject); | |
else Result := nil; | |
end; | |
end; | |
procedure TJson.RaiseIfNone; | |
begin | |
if FStructType = jsNone then RaiseError('json struct type is jsNone'); | |
end; | |
procedure TJson.RaiseIfNotArray; | |
begin | |
if FStructType <> jsArray then RaiseError('json struct type is not jsArray'); | |
end; | |
procedure TJson.RaiseIfNotObject; | |
begin | |
if FStructType <> jsObject then RaiseError('json struct type is not jsObject'); | |
end; | |
function TJson.Stringify: String; | |
begin | |
case FStructType of | |
jsArray: Result := FJsonArray.Stringify; | |
jsObject: Result := FJsonObject.Stringify; | |
else Result := ''; | |
end; | |
end; | |
end. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment