diff --git a/packages/fcl-json/src/fpjson.pp b/packages/fcl-json/src/fpjson.pp index 528a24a44c..e1f425f59b 100644 --- a/packages/fcl-json/src/fpjson.pp +++ b/packages/fcl-json/src/fpjson.pp @@ -19,7 +19,12 @@ unit fpjson; interface uses + {$ifdef fpc} variants, + {$endif} + {$ifdef pas2js} + JS, RTLConsts, Types, + {$endif} SysUtils, classes, contnrs; @@ -27,13 +32,30 @@ uses type TJSONtype = (jtUnknown, jtNumber, jtString, jtBoolean, jtNull, jtArray, jtObject); - TJSONInstanceType = (jitUnknown, jitNumberInteger,jitNumberInt64,jitNumberQWord,jitNumberFloat, - jitString, jitBoolean, jitNull, jitArray, jitObject); + TJSONInstanceType = ( + jitUnknown, + jitNumberInteger, + {$ifdef fpc} + jitNumberInt64, + jitNumberQWord, + {$endif} + jitNumberFloat, + jitString, + jitBoolean, + jitNull, + jitArray, + jitObject); TJSONFloat = Double; - TJSONStringType = UTF8String; + TJSONStringType = {$ifdef fpc}UTF8String{$else}string{$endif}; TJSONUnicodeStringType = Unicodestring; + {$ifdef fpc} TJSONCharType = AnsiChar; PJSONCharType = ^TJSONCharType; + TJSONVariant = variant; + {$else} + TJSONCharType = char; + TJSONVariant = jsvalue; + {$endif} TFormatOption = (foSingleLineArray, // Array without CR/LF : all on one line foSingleLineObject, // Object without CR/LF : all on one line foDoNotQuoteMembers, // Do not quote object member names. @@ -78,30 +100,36 @@ Type Class Var FCompressedJSON : Boolean; Class Var FElementSep : TJSONStringType; class procedure DetermineElementSeparators; - class function GetCompressedJSON: Boolean; static; - class procedure SetCompressedJSON(AValue: Boolean); static; + class function GetCompressedJSON: Boolean; {$ifdef fpc}static;{$endif} + class procedure SetCompressedJSON(AValue: Boolean); {$ifdef fpc}static;{$endif} protected Class Procedure DoError(Const Msg : String); - Class Procedure DoError(Const Fmt : String; const Args : Array of const); + Class Procedure DoError(Const Fmt : String; const Args : Array of {$ifdef pas2js}jsvalue{$else}Const{$endif}); Function DoFindPath(Const APath : TJSONStringType; Out NotFound : TJSONStringType) : TJSONdata; virtual; function GetAsBoolean: Boolean; virtual; abstract; function GetAsFloat: TJSONFloat; virtual; abstract; function GetAsInteger: Integer; virtual; abstract; + {$ifdef fpc} function GetAsInt64: Int64; virtual; abstract; function GetAsQWord: QWord; virtual; abstract; + {$endif} function GetIsNull: Boolean; virtual; procedure SetAsBoolean(const AValue: Boolean); virtual; abstract; procedure SetAsFloat(const AValue: TJSONFloat); virtual; abstract; procedure SetAsInteger(const AValue: Integer); virtual; abstract; + {$ifdef fpc} procedure SetAsInt64(const AValue: Int64); virtual; abstract; procedure SetAsQword(const AValue: QWord); virtual; abstract; + {$endif} function GetAsJSON: TJSONStringType; virtual; abstract; function GetAsString: TJSONStringType; virtual; abstract; procedure SetAsString(const AValue: TJSONStringType); virtual; abstract; + {$ifdef fpc} function GetAsUnicodeString: TJSONUnicodeStringType; virtual; procedure SetAsUnicodeString(const AValue: TJSONUnicodeStringType); virtual; - function GetValue: variant; virtual; abstract; - procedure SetValue(const AValue: variant); virtual; abstract; + {$endif} + function GetValue: TJSONVariant; virtual; abstract; + procedure SetValue(const AValue: TJSONVariant); virtual; abstract; function GetItem(Index : Integer): TJSONData; virtual; procedure SetItem(Index : Integer; const AValue: TJSONData); virtual; Function DoFormatJSON(Options : TFormatOptions; CurrentIndent, Indent : Integer) : TJSONStringType; virtual; @@ -112,7 +140,9 @@ Type public Constructor Create; virtual; Procedure Clear; virtual; Abstract; + {$ifdef fpc} Procedure DumpJSON(S : TStream); + {$endif} // Get enumerator function GetEnumerator: TBaseJSONEnumerator; virtual; Function FindPath(Const APath : TJSONStringType) : TJSONdata; @@ -121,20 +151,31 @@ Type Function FormatJSON(Options : TFormatOptions = DefaultFormat; Indentsize : Integer = DefaultIndentSize) : TJSONStringType; property Count: Integer read GetCount; property Items[Index: Integer]: TJSONData read GetItem write SetItem; - property Value: variant read GetValue write SetValue; + property Value: TJSONVariant read GetValue write SetValue; Property AsString : TJSONStringType Read GetAsString Write SetAsString; + {$ifdef fpc} Property AsUnicodeString : TJSONUnicodeStringType Read GetAsUnicodeString Write SetAsUnicodeString; + {$endif} Property AsFloat : TJSONFloat Read GetAsFloat Write SetAsFloat; Property AsInteger : Integer Read GetAsInteger Write SetAsInteger; + {$ifdef fpc} Property AsInt64 : Int64 Read GetAsInt64 Write SetAsInt64; Property AsQWord : QWord Read GetAsQWord Write SetAsQword; + {$endif} Property AsBoolean : Boolean Read GetAsBoolean Write SetAsBoolean; Property IsNull : Boolean Read GetIsNull; Property AsJSON : TJSONStringType Read GetAsJSON; end; TJSONDataClass = Class of TJSONData; - TJSONNumberType = (ntFloat,ntInteger,ntInt64,ntQWord); + TJSONNumberType = ( + ntFloat, + ntInteger + {$ifdef fpc} + ,ntInt64 + ,ntQWord + {$endif} + ); TJSONNumber = class(TJSONData) protected @@ -152,18 +193,22 @@ Type function GetAsBoolean: Boolean; override; function GetAsFloat: TJSONFloat; override; function GetAsInteger: Integer; override; + {$ifdef fpc} function GetAsInt64: Int64; override; function GetAsQWord: QWord; override; + {$endif} procedure SetAsBoolean(const AValue: Boolean); override; procedure SetAsFloat(const AValue: TJSONFloat); override; procedure SetAsInteger(const AValue: Integer); override; + {$ifdef fpc} procedure SetAsInt64(const AValue: Int64); override; procedure SetAsQword(const AValue: QWord); override; + {$endif} function GetAsJSON: TJSONStringType; override; function GetAsString: TJSONStringType; override; procedure SetAsString(const AValue: TJSONStringType); override; - function GetValue: variant; override; - procedure SetValue(const AValue: variant); override; + function GetValue: TJSONVariant; override; + procedure SetValue(const AValue: TJSONVariant); override; public Constructor Create(AValue : TJSONFloat); reintroduce; class function NumberType : TJSONNumberType; override; @@ -181,18 +226,22 @@ Type function GetAsBoolean: Boolean; override; function GetAsFloat: TJSONFloat; override; function GetAsInteger: Integer; override; + {$ifdef fpc} function GetAsInt64: Int64; override; function GetAsQWord: QWord; override; + {$endif} procedure SetAsBoolean(const AValue: Boolean); override; procedure SetAsFloat(const AValue: TJSONFloat); override; procedure SetAsInteger(const AValue: Integer); override; + {$ifdef fpc} procedure SetAsInt64(const AValue: Int64); override; procedure SetAsQword(const AValue: QWord); override; + {$endif} function GetAsJSON: TJSONStringType; override; function GetAsString: TJSONStringType; override; procedure SetAsString(const AValue: TJSONStringType); override; - function GetValue: variant; override; - procedure SetValue(const AValue: variant); override; + function GetValue: TJSONVariant; override; + procedure SetValue(const AValue: TJSONVariant); override; public Constructor Create(AValue : Integer); reintroduce; class function NumberType : TJSONNumberType; override; @@ -201,6 +250,7 @@ Type end; TJSONIntegerNumberClass = Class of TJSONIntegerNumber; + {$ifdef fpc} { TJSONInt64Number } TJSONInt64Number = class(TJSONNumber) @@ -220,8 +270,8 @@ Type function GetAsJSON: TJSONStringType; override; function GetAsString: TJSONStringType; override; procedure SetAsString(const AValue: TJSONStringType); override; - function GetValue: variant; override; - procedure SetValue(const AValue: variant); override; + function GetValue: TJSONVariant; override; + procedure SetValue(const AValue: TJSONVariant); override; public Constructor Create(AValue : Int64); reintroduce; class function NumberType : TJSONNumberType; override; @@ -229,7 +279,9 @@ Type Function Clone : TJSONData; override; end; TJSONInt64NumberClass = Class of TJSONInt64Number; + {$endif} + {$ifdef fpc} { TJSONQWordNumber } TJSONQWordNumber = class(TJSONNumber) @@ -249,8 +301,8 @@ Type function GetAsJSON: TJSONStringType; override; function GetAsString: TJSONStringType; override; procedure SetAsString(const AValue: TJSONStringType); override; - function GetValue: variant; override; - procedure SetValue(const AValue: variant); override; + function GetValue: TJSONVariant; override; + procedure SetValue(const AValue: TJSONVariant); override; public Constructor Create(AValue : QWord); reintroduce; class function NumberType : TJSONNumberType; override; @@ -258,7 +310,7 @@ Type Function Clone : TJSONData; override; end; TJSONQWordNumberClass = Class of TJSONQWordNumber; - + {$endif} { TJSONString } @@ -266,18 +318,22 @@ Type Private FValue: TJSONStringType; protected - function GetValue: Variant; override; - procedure SetValue(const AValue: Variant); override; + function GetValue: TJSONVariant; override; + procedure SetValue(const AValue: TJSONVariant); override; function GetAsBoolean: Boolean; override; function GetAsFloat: TJSONFloat; override; function GetAsInteger: Integer; override; + {$ifdef fpc} function GetAsInt64: Int64; override; function GetAsQWord: QWord; override; + {$endif} procedure SetAsBoolean(const AValue: Boolean); override; procedure SetAsFloat(const AValue: TJSONFloat); override; procedure SetAsInteger(const AValue: Integer); override; + {$ifdef fpc} procedure SetAsInt64(const AValue: Int64); override; procedure SetAsQword(const AValue: QWord); override; + {$endif} function GetAsJSON: TJSONStringType; override; function GetAsString: TJSONStringType; override; procedure SetAsString(const AValue: TJSONStringType); override; @@ -285,7 +341,9 @@ Type Class var StrictEscaping : Boolean; public Constructor Create(const AValue : TJSONStringType); reintroduce; + {$ifdef fpc} Constructor Create(const AValue : TJSONUnicodeStringType); reintroduce; + {$endif} class function JSONType: TJSONType; override; Procedure Clear; override; Function Clone : TJSONData; override; @@ -298,18 +356,22 @@ Type Private FValue: Boolean; protected - function GetValue: Variant; override; - procedure SetValue(const AValue: Variant); override; + function GetValue: TJSONVariant; override; + procedure SetValue(const AValue: TJSONVariant); override; function GetAsBoolean: Boolean; override; function GetAsFloat: TJSONFloat; override; function GetAsInteger: Integer; override; + {$ifdef fpc} function GetAsInt64: Int64; override; function GetAsQWord: QWord; override; + {$endif} procedure SetAsBoolean(const AValue: Boolean); override; procedure SetAsFloat(const AValue: TJSONFloat); override; procedure SetAsInteger(const AValue: Integer); override; + {$ifdef fpc} procedure SetAsInt64(const AValue: Int64); override; procedure SetAsQword(const AValue: QWord); override; + {$endif} function GetAsJSON: TJSONStringType; override; function GetAsString: TJSONStringType; override; procedure SetAsString(const AValue: TJSONStringType); override; @@ -329,19 +391,23 @@ Type function GetAsBoolean: Boolean; override; function GetAsFloat: TJSONFloat; override; function GetAsInteger: Integer; override; + {$ifdef fpc} function GetAsInt64: Int64; override; function GetAsQWord: QWord; override; + {$endif} function GetIsNull: Boolean; override; procedure SetAsBoolean(const AValue: Boolean); override; procedure SetAsFloat(const AValue: TJSONFloat); override; procedure SetAsInteger(const AValue: Integer); override; + {$ifdef fpc} procedure SetAsInt64(const AValue: Int64); override; procedure SetAsQword(const AValue: QWord); override; + {$endif} function GetAsJSON: TJSONStringType; override; function GetAsString: TJSONStringType; override; procedure SetAsString(const AValue: TJSONStringType); override; - function GetValue: variant; override; - procedure SetValue(const AValue: variant); override; + function GetValue: TJSONVariant; override; + procedure SetValue(const AValue: TJSONVariant); override; public class function JSONType: TJSONType; override; Procedure Clear; override; @@ -361,47 +427,63 @@ Type function GetBooleans(Index : Integer): Boolean; function GetFloats(Index : Integer): TJSONFloat; function GetIntegers(Index : Integer): Integer; + {$ifdef fpc} function GetInt64s(Index : Integer): Int64; + {$endif} function GetNulls(Index : Integer): Boolean; function GetObjects(Index : Integer): TJSONObject; + {$ifdef fpc} function GetQWords(Index : Integer): QWord; + {$endif} function GetStrings(Index : Integer): TJSONStringType; + {$ifdef fpc} function GetUnicodeStrings(Index : Integer): TJSONUnicodeStringType; + {$endif} function GetTypes(Index : Integer): TJSONType; procedure SetArrays(Index : Integer; const AValue: TJSONArray); procedure SetBooleans(Index : Integer; const AValue: Boolean); procedure SetFloats(Index : Integer; const AValue: TJSONFloat); procedure SetIntegers(Index : Integer; const AValue: Integer); + {$ifdef fpc} procedure SetInt64s(Index : Integer; const AValue: Int64); + {$endif} procedure SetObjects(Index : Integer; const AValue: TJSONObject); + {$ifdef fpc} procedure SetQWords(Index : Integer; AValue: QWord); + {$endif} procedure SetStrings(Index : Integer; const AValue: TJSONStringType); + {$ifdef fpc} procedure SetUnicodeStrings(Index : Integer; const AValue: TJSONUnicodeStringType); + {$endif} protected Function DoFindPath(Const APath : TJSONStringType; Out NotFound : TJSONStringType) : TJSONdata; override; Procedure Converterror(From : Boolean); function GetAsBoolean: Boolean; override; function GetAsFloat: TJSONFloat; override; function GetAsInteger: Integer; override; + {$ifdef fpc} function GetAsInt64: Int64; override; function GetAsQWord: QWord; override; + {$endif} procedure SetAsBoolean(const AValue: Boolean); override; procedure SetAsFloat(const AValue: TJSONFloat); override; procedure SetAsInteger(const AValue: Integer); override; + {$ifdef fpc} procedure SetAsInt64(const AValue: Int64); override; procedure SetAsQword(const AValue: QWord); override; + {$endif} function GetAsJSON: TJSONStringType; override; function GetAsString: TJSONStringType; override; procedure SetAsString(const AValue: TJSONStringType); override; - function GetValue: variant; override; - procedure SetValue(const AValue: variant); override; + function GetValue: TJSONVariant; override; + procedure SetValue(const AValue: TJSONVariant); override; function GetCount: Integer; override; function GetItem(Index : Integer): TJSONData; override; procedure SetItem(Index : Integer; const AValue: TJSONData); override; Function DoFormatJSON(Options : TFormatOptions; CurrentIndent, Indent : Integer) : TJSONStringType; override; public Constructor Create; overload; reintroduce; - Constructor Create(const Elements : Array of Const); overload; + Constructor Create(const Elements : Array of {$ifdef pas2js}jsvalue{$else}Const{$endif}); overload; Destructor Destroy; override; class function JSONType: TJSONType; override; Function Clone : TJSONData; override; @@ -413,10 +495,14 @@ Type Procedure Clear; override; function Add(Item : TJSONData): Integer; function Add(I : Integer): Integer; + {$ifdef fpc} function Add(I : Int64): Int64; function Add(I : QWord): QWord; + {$endif} function Add(const S : String): Integer; + {$ifdef fpc} function Add(const S : UnicodeString): Integer; + {$endif} function Add: Integer; function Add(F : TJSONFloat): Integer; function Add(B : Boolean): Integer; @@ -429,10 +515,14 @@ Type procedure Insert(Index: Integer); procedure Insert(Index: Integer; Item : TJSONData); procedure Insert(Index: Integer; I : Integer); + {$ifdef fpc} procedure Insert(Index: Integer; I : Int64); procedure Insert(Index: Integer; I : QWord); + {$endif} procedure Insert(Index: Integer; const S : String); + {$ifdef fpc} procedure Insert(Index: Integer; const S : UnicodeString); + {$endif} procedure Insert(Index: Integer; F : TJSONFloat); procedure Insert(Index: Integer; B : Boolean); procedure Insert(Index: Integer; AnArray : TJSONArray); @@ -445,10 +535,14 @@ Type Property Types[Index : Integer] : TJSONType Read GetTypes; Property Nulls[Index : Integer] : Boolean Read GetNulls; Property Integers[Index : Integer] : Integer Read GetIntegers Write SetIntegers; + {$ifdef fpc} Property Int64s[Index : Integer] : Int64 Read GetInt64s Write SetInt64s; Property QWords[Index : Integer] : QWord Read GetQWords Write SetQWords; + {$endif} Property Strings[Index : Integer] : TJSONStringType Read GetStrings Write SetStrings; + {$ifdef fpc} Property UnicodeStrings[Index : Integer] : TJSONUnicodeStringType Read GetUnicodeStrings Write SetUnicodeStrings; + {$endif} Property Floats[Index : Integer] : TJSONFloat Read GetFloats Write SetFloats; Property Booleans[Index : Integer] : Boolean Read GetBooleans Write SetBooleans; Property Arrays[Index : Integer] : TJSONArray Read GetArrays Write SetArrays; @@ -473,58 +567,80 @@ Type function DoAdd(const AName: TJSONStringType; AValue: TJSONData; FreeOnError: Boolean=True): Integer; Class procedure DetermineElementQuotes; Private + {$ifdef pas2js} + FCount: integer; + FHash: TJSObject; + FNames: TStringDynArray; + {$else} FHash : TFPHashObjectList; // Careful : Names limited to 255 chars. + {$endif} function GetArrays(const AName : String): TJSONArray; function GetBooleans(const AName : String): Boolean; function GetElements(const AName: string): TJSONData; function GetFloats(const AName : String): TJSONFloat; function GetIntegers(const AName : String): Integer; + {$ifdef fpc} function GetInt64s(const AName : String): Int64; + {$endif} function GetIsNull(const AName : String): Boolean; reintroduce; function GetNameOf(Index : Integer): TJSONStringType; function GetObjects(const AName : String): TJSONObject; + {$ifdef fpc} function GetQWords(AName : String): QWord; + {$endif} function GetStrings(const AName : String): TJSONStringType; + {$ifdef fpc} function GetUnicodeStrings(const AName : String): TJSONUnicodeStringType; + {$endif} function GetTypes(const AName : String): TJSONType; procedure SetArrays(const AName : String; const AValue: TJSONArray); procedure SetBooleans(const AName : String; const AValue: Boolean); procedure SetElements(const AName: string; const AValue: TJSONData); procedure SetFloats(const AName : String; const AValue: TJSONFloat); procedure SetIntegers(const AName : String; const AValue: Integer); + {$ifdef fpc} procedure SetInt64s(const AName : String; const AValue: Int64); + {$endif} procedure SetIsNull(const AName : String; const AValue: Boolean); procedure SetObjects(const AName : String; const AValue: TJSONObject); + {$ifdef fpc} procedure SetQWords(AName : String; AValue: QWord); + {$endif} procedure SetStrings(const AName : String; const AValue: TJSONStringType); + {$ifdef fpc} procedure SetUnicodeStrings(const AName : String; const AValue: TJSONUnicodeStringType); - class function GetUnquotedMemberNames: Boolean; static; - class procedure SetUnquotedMemberNames(AValue: Boolean); static; + {$endif} + class function GetUnquotedMemberNames: Boolean; {$ifdef fpc}static;{$endif} + class procedure SetUnquotedMemberNames(AValue: Boolean); {$ifdef fpc}static;{$endif} protected Function DoFindPath(Const APath : TJSONStringType; Out NotFound : TJSONStringType) : TJSONdata; override; Procedure Converterror(From : Boolean); function GetAsBoolean: Boolean; override; function GetAsFloat: TJSONFloat; override; function GetAsInteger: Integer; override; + {$ifdef fpc} function GetAsInt64: Int64; override; function GetAsQWord: QWord; override; + {$endif} procedure SetAsBoolean(const AValue: Boolean); override; procedure SetAsFloat(const AValue: TJSONFloat); override; procedure SetAsInteger(const AValue: Integer); override; + {$ifdef fpc} procedure SetAsInt64(const AValue: Int64); override; procedure SetAsQword(const AValue: QWord); override; + {$endif} function GetAsJSON: TJSONStringType; override; function GetAsString: TJSONStringType; override; procedure SetAsString(const AValue: TJSONStringType); override; - function GetValue: variant; override; - procedure SetValue(const AValue: variant); override; + function GetValue: TJSONVariant; override; + procedure SetValue(const AValue: TJSONVariant); override; function GetCount: Integer; override; function GetItem(Index : Integer): TJSONData; override; procedure SetItem(Index : Integer; const AValue: TJSONData); override; Function DoFormatJSON(Options : TFormatOptions; CurrentIndent, Indent : Integer) : TJSONStringType; override; public constructor Create; reintroduce; - Constructor Create(const Elements : Array of Const); overload; + Constructor Create(const Elements : Array of {$ifdef pas2js}jsvalue{$else}Const{$endif}); overload; destructor Destroy; override; class function JSONType: TJSONType; override; Class Property UnquotedMemberNames : Boolean Read GetUnquotedMemberNames Write SetUnquotedMemberNames; @@ -542,14 +658,18 @@ Type function Find(const key: TJSONStringType; out AValue: TJSONString): boolean; function Find(const key: TJSONStringType; out AValue: TJSONBoolean): boolean; function Find(const key: TJSONStringType; out AValue: TJSONNumber): boolean; - Function Get(Const AName : String) : Variant; + Function Get(Const AName : String) : TJSONVariant; Function Get(Const AName : String; ADefault : TJSONFloat) : TJSONFloat; Function Get(Const AName : String; ADefault : Integer) : Integer; + {$ifdef fpc} Function Get(Const AName : String; ADefault : Int64) : Int64; Function Get(Const AName : String; ADefault : QWord) : QWord; + {$endif} Function Get(Const AName : String; ADefault : Boolean) : Boolean; Function Get(Const AName : String; ADefault : TJSONStringType) : TJSONStringType; + {$ifdef fpc} Function Get(Const AName : String; ADefault : TJSONUnicodeStringType) : TJSONUnicodeStringType; + {$endif} Function Get(Const AName : String; ADefault : TJSONArray) : TJSONArray; Function Get(Const AName : String; ADefault : TJSONObject) : TJSONObject; // Manipulate @@ -558,17 +678,23 @@ Type function Add(const AName: TJSONStringType; AValue: Boolean): Integer; overload; function Add(const AName: TJSONStringType; AValue: TJSONFloat): Integer; overload; function Add(const AName, AValue: TJSONStringType): Integer; overload; + {$ifdef fpc} function Add(const AName : String; AValue: TJSONUnicodeStringType): Integer; overload; + {$endif} function Add(const AName: TJSONStringType; Avalue: Integer): Integer; overload; + {$ifdef fpc} function Add(const AName: TJSONStringType; Avalue: Int64): Integer; overload; function Add(const AName: TJSONStringType; Avalue: QWord): Integer; overload; + {$endif} function Add(const AName: TJSONStringType): Integer; overload; function Add(const AName: TJSONStringType; AValue : TJSONArray): Integer; overload; procedure Delete(Index : Integer); procedure Delete(Const AName : string); procedure Remove(Item : TJSONData); + {$ifdef fpc} Function Extract(Index : Integer) : TJSONData; Function Extract(Const AName : string) : TJSONData; + {$endif} // Easy access properties. property Names[Index : Integer] : TJSONStringType read GetNameOf; @@ -578,10 +704,14 @@ Type Property Nulls[AName : String] : Boolean Read GetIsNull Write SetIsNull; Property Floats[AName : String] : TJSONFloat Read GetFloats Write SetFloats; Property Integers[AName : String] : Integer Read GetIntegers Write SetIntegers; + {$ifdef fpc} Property Int64s[AName : String] : Int64 Read GetInt64s Write SetInt64s; Property QWords[AName : String] : QWord Read GetQWords Write SetQWords; + {$endif} Property Strings[AName : String] : TJSONStringType Read GetStrings Write SetStrings; + {$ifdef fpc} Property UnicodeStrings[AName : String] : TJSONUnicodeStringType Read GetUnicodeStrings Write SetUnicodeStrings; + {$endif} Property Booleans[AName : String] : Boolean Read GetBooleans Write SetBooleans; Property Arrays[AName : String] : TJSONArray Read GetArrays Write SetArrays; Property Objects[AName : String] : TJSONObject Read GetObjects Write SetObjects; @@ -590,7 +720,9 @@ Type EJSON = Class(Exception); + {$ifdef fpc} TJSONParserHandler = Procedure(AStream : TStream; Const AUseUTF8 : Boolean; Out Data : TJSONData); + {$endif} Function SetJSONInstanceType(AType : TJSONInstanceType; AClass : TJSONDataClass) : TJSONDataClass; Function GetJSONInstanceType(AType : TJSONInstanceType) : TJSONDataClass; @@ -603,20 +735,26 @@ Function JSONTypeName(JSONType : TJSONType) : String; Function CreateJSON : TJSONNull; Function CreateJSON(Data : Boolean) : TJSONBoolean; Function CreateJSON(Data : Integer) : TJSONIntegerNumber; +{$ifdef fpc} Function CreateJSON(Data : Int64) : TJSONInt64Number; Function CreateJSON(Data : QWord) : TJSONQWordNumber; +{$endif} Function CreateJSON(Data : TJSONFloat) : TJSONFloatNumber; Function CreateJSON(const Data : TJSONStringType) : TJSONString; +{$ifdef fpc} Function CreateJSON(const Data : TJSONUnicodeStringType) : TJSONString; -Function CreateJSONArray(const Data : Array of const) : TJSONArray; -Function CreateJSONObject(const Data : Array of const) : TJSONObject; +{$endif} +Function CreateJSONArray(const Data : Array of {$ifdef pas2js}jsvalue{$else}Const{$endif}) : TJSONArray; +Function CreateJSONObject(const Data : Array of {$ifdef pas2js}jsvalue{$else}Const{$endif}) : TJSONObject; // These functions rely on a callback. If the callback is not set, they will raise an error. // When the jsonparser unit is included in the project, the callback is automatically set. +{$ifdef fpc} Function GetJSON(Const JSON : TJSONStringType; Const UseUTF8 : Boolean = True) : TJSONData; Function GetJSON(Const JSON : TStream; Const UseUTF8 : Boolean = True) : TJSONData; Function SetJSONParserHandler(AHandler : TJSONParserHandler) : TJSONParserHandler; Function GetJSONParserHandler : TJSONParserHandler; +{$endif} implementation @@ -635,25 +773,48 @@ Resourcestring SErrCannotAddObjectTwice = 'Adding an object to an array twice is not allowed'; SErrUnknownTypeInConstructor = 'Unknown type in JSON%s constructor: %d'; SErrNotJSONData = 'Cannot add object of type %s to TJSON%s'; - SErrPointerNotNil = 'Cannot add non-nil pointer to JSON%s'; SErrOddNumber = 'TJSONObject must be constructed with name,value pairs'; SErrNameMustBeString = 'TJSONObject constructor element name at pos %d is not a string'; SErrNonexistentElement = 'Unknown object member: "%s"'; SErrDuplicateValue = 'Duplicate object member: "%s"'; SErrPathElementNotFound = 'Path "%s" invalid: element "%s" not found.'; SErrWrongInstanceClass = 'Cannot set instance class: %s does not descend from %s.'; + {$ifdef fpc} + SErrPointerNotNil = 'Cannot add non-nil pointer to JSON%s'; SErrNoParserHandler = 'No JSON parser handler installed. Recompile your project with the jsonparser unit included'; + {$endif} Var DefaultJSONInstanceTypes : - Array [TJSONInstanceType] of TJSONDataClass = (TJSONData, TJSONIntegerNumber, - TJSONInt64Number, TJSONQWordNumber, TJSONFloatNumber, TJSONString, TJSONBoolean, TJSONNull, TJSONArray, - TJSONObject); + Array [TJSONInstanceType] of TJSONDataClass = ( + TJSONData, + TJSONIntegerNumber, + {$ifdef fpc} + TJSONInt64Number, + TJSONQWordNumber, + {$endif} + TJSONFloatNumber, + TJSONString, + TJSONBoolean, + TJSONNull, + TJSONArray, + TJSONObject); Const MinJSONInstanceTypes : - Array [TJSONInstanceType] of TJSONDataClass = (TJSONData, TJSONIntegerNumber, - TJSONInt64Number, TJSONQWordNumber, TJSONFloatNumber, TJSONString, TJSONBoolean, TJSONNull, TJSONArray, - TJSONObject); + Array [TJSONInstanceType] of TJSONDataClass = ( + TJSONData, + TJSONIntegerNumber, + {$ifdef fpc} + TJSONInt64Number, + TJSONQWordNumber, + {$endif} + TJSONFloatNumber, + TJSONString, + TJSONBoolean, + TJSONNull, + TJSONArray, + TJSONObject + ); function SetJSONInstanceType(AType: TJSONInstanceType; AClass: TJSONDataClass): TJSONDataClass; begin @@ -674,18 +835,16 @@ function StringToJSONString(const S: TJSONStringType; Strict : Boolean = False): Var I,J,L : Integer; - P : PJSONCharType; - C : AnsiChar; + C : Char; begin I:=1; J:=1; Result:=''; L:=Length(S); - P:=PJSONCharType(S); While I<=L do begin - C:=AnsiChar(P^); + C:=S[I]; if (C in ['"','/','\',#0..#31]) then begin Result:=Result+Copy(S,J,I-J); @@ -707,7 +866,6 @@ begin J:=I+1; end; Inc(I); - Inc(P); end; Result:=Result+Copy(S,J,I-1); end; @@ -716,7 +874,6 @@ function JSONStringToString(const S: TJSONStringType): TJSONStringType; Var I,J,L : Integer; - P : PJSONCharType; w : String; begin @@ -724,19 +881,17 @@ begin J:=1; L:=Length(S); Result:=''; - P:=PJSONCharType(S); While (I<=L) do begin - if (P^='\') then + if (S[I]='\') then begin Result:=Result+Copy(S,J,I-J); - Inc(P); - If (P^<>#0) then + If I0) end; +{$ifdef fpc} procedure TJSONBoolean.SetAsInt64(const AValue: Int64); begin FValue:=(AValue<>0) @@ -1421,6 +1597,7 @@ procedure TJSONBoolean.SetAsQword(const AValue: QWord); begin FValue:=(AValue<>0) end; +{$endif} function TJSONBoolean.GetAsJSON: TJSONStringType; begin @@ -1460,18 +1637,22 @@ end; function TJSONNull.GetAsBoolean: Boolean; begin ConvertError(True); + Result:=false; end; function TJSONNull.GetAsFloat: TJSONFloat; begin ConvertError(True); + Result:=0.0; end; function TJSONNull.GetAsInteger: Integer; begin ConvertError(True); + Result:=0; end; +{$ifdef fpc} function TJSONNull.GetAsInt64: Int64; begin ConvertError(True); @@ -1481,6 +1662,7 @@ function TJSONNull.GetAsQWord: QWord; begin ConvertError(True); end; +{$endif} function TJSONNull.GetIsNull: Boolean; begin @@ -1505,6 +1687,7 @@ begin if AValue>0 then ; end; +{$ifdef fpc} procedure TJSONNull.SetAsInt64(const AValue: Int64); begin ConvertError(False); @@ -1516,6 +1699,7 @@ begin ConvertError(False); if AValue>0 then ; end; +{$endif} function TJSONNull.GetAsJSON: TJSONStringType; begin @@ -1525,6 +1709,7 @@ end; function TJSONNull.GetAsString: TJSONStringType; begin ConvertError(True); + Result:=''; end; procedure TJSONNull.SetAsString(const AValue: TJSONStringType); @@ -1534,15 +1719,19 @@ begin end; -function TJSONNull.GetValue: variant; +function TJSONNull.GetValue: TJSONVariant; begin - Result:=variants.Null; + Result:={$ifdef pas2js}js.Null{$else}variants.Null{$endif}; end; -procedure TJSONNull.SetValue(const AValue: variant); +procedure TJSONNull.SetValue(const AValue: TJSONVariant); begin ConvertError(False); + {$ifdef pas2js} + if AValue=0 then ; + {$else} if VarType(AValue)=0 then ; + {$endif} end; class function TJSONNull.JSONType: TJSONType; @@ -1581,6 +1770,7 @@ begin Result:=Round(FValue); end; +{$ifdef fpc} function TJSONFloatNumber.GetAsInt64: Int64; begin Result:=Round(FValue); @@ -1590,6 +1780,7 @@ function TJSONFloatNumber.GetAsQWord: QWord; begin Result:=Round(FValue); end; +{$endif} procedure TJSONFloatNumber.SetAsBoolean(const AValue: Boolean); begin @@ -1606,6 +1797,7 @@ begin FValue:=AValue; end; +{$ifdef fpc} procedure TJSONFloatNumber.SetAsInt64(const AValue: Int64); begin FValue:=AValue; @@ -1615,6 +1807,7 @@ procedure TJSONFloatNumber.SetAsQword(const AValue: QWord); begin FValue:=AValue; end; +{$endif} function TJSONFloatNumber.GetAsJSON: TJSONStringType; begin @@ -1639,14 +1832,14 @@ begin end; -function TJSONFloatNumber.GetValue: variant; +function TJSONFloatNumber.GetValue: TJSONVariant; begin Result:=FValue; end; -procedure TJSONFloatNumber.SetValue(const AValue: variant); +procedure TJSONFloatNumber.SetValue(const AValue: TJSONVariant); begin - FValue:=AValue; + FValue:={$ifdef pas2js}TJSONFloat(AValue){$else}AValue{$endif}; end; constructor TJSONFloatNumber.Create(AValue: TJSONFloat); @@ -1679,7 +1872,7 @@ end; function TJSONIntegerNumber.GetAsFloat: TJSONFloat; begin - Result:=Ord(FValue); + Result:=FValue; end; function TJSONIntegerNumber.GetAsInteger: Integer; @@ -1687,6 +1880,7 @@ begin Result:=FValue; end; +{$ifdef fpc} function TJSONIntegerNumber.GetAsInt64: Int64; begin Result:=FValue; @@ -1696,6 +1890,7 @@ function TJSONIntegerNumber.GetAsQWord: QWord; begin result:=FValue; end; +{$endif} procedure TJSONIntegerNumber.SetAsBoolean(const AValue: Boolean); begin @@ -1712,6 +1907,7 @@ begin FValue:=AValue; end; +{$ifdef fpc} procedure TJSONIntegerNumber.SetAsInt64(const AValue: Int64); begin FValue:=AValue; @@ -1721,6 +1917,7 @@ procedure TJSONIntegerNumber.SetAsQword(const AValue: QWord); begin FValue:=AValue; end; +{$endif} function TJSONIntegerNumber.GetAsJSON: TJSONStringType; begin @@ -1738,14 +1935,14 @@ begin end; -function TJSONIntegerNumber.GetValue: variant; +function TJSONIntegerNumber.GetValue: TJSONVariant; begin Result:=FValue; end; -procedure TJSONIntegerNumber.SetValue(const AValue: variant); +procedure TJSONIntegerNumber.SetValue(const AValue: TJSONVariant); begin - FValue:=AValue; + FValue:={$ifdef pas2js}Integer(AValue){$else}AValue{$endif}; end; constructor TJSONIntegerNumber.Create(AValue: Integer); @@ -1769,6 +1966,7 @@ begin Result:=TJSONIntegerNumberClass(ClassType).Create(Self.FValue); end; +{$ifdef fpc} { TJSONInt64Number } function TJSONInt64Number.GetAsInt64: Int64; @@ -1836,12 +2034,12 @@ begin FValue:=StrToInt64(AValue); end; -function TJSONInt64Number.GetValue: variant; +function TJSONInt64Number.GetValue: TJSONVariant; begin Result:=FValue; end; -procedure TJSONInt64Number.SetValue(const AValue: variant); +procedure TJSONInt64Number.SetValue(const AValue: TJSONVariant); begin FValue:=AValue; end; @@ -1866,6 +2064,7 @@ function TJSONInt64Number.Clone: TJSONData; begin Result:=TJSONInt64NumberClass(ClassType).Create(Self.FValue); end; +{$endif} { TJSONArray } @@ -1889,10 +2088,12 @@ begin Result:=Items[Index].AsInteger; end; +{$ifdef fpc} function TJSONArray.GetInt64s(Index : Integer): Int64; begin Result:=Items[Index].AsInt64; end; +{$endif} function TJSONArray.GetNulls(Index : Integer): Boolean; begin @@ -1904,20 +2105,24 @@ begin Result:=Items[Index] as TJSONObject; end; +{$ifdef fpc} function TJSONArray.GetQWords(Index : Integer): QWord; begin Result:=Items[Index].AsQWord; end; +{$endif} function TJSONArray.GetStrings(Index : Integer): TJSONStringType; begin Result:=Items[Index].AsString; end; +{$ifdef fpc} function TJSONArray.GetUnicodeStrings(Index : Integer): TJSONUnicodeStringType; begin Result:=Items[Index].AsUnicodeString; end; +{$endif} function TJSONArray.GetTypes(Index : Integer): TJSONType; begin @@ -1945,31 +2150,37 @@ begin Items[Index]:=CreateJSON(AValue); end; +{$ifdef fpc} procedure TJSONArray.SetInt64s(Index : Integer; const AValue: Int64); begin Items[Index]:=CreateJSON(AValue); end; +{$endif} procedure TJSONArray.SetObjects(Index : Integer; const AValue: TJSONObject); begin Items[Index]:=AValue; end; +{$ifdef fpc} procedure TJSONArray.SetQWords(Index : Integer; AValue: QWord); begin Items[Index]:=CreateJSON(AValue); end; +{$endif} procedure TJSONArray.SetStrings(Index : Integer; const AValue: TJSONStringType); begin Items[Index]:=CreateJSON(AValue); end; +{$ifdef fpc} procedure TJSONArray.SetUnicodeStrings(Index: Integer; const AValue: TJSONUnicodeStringType); begin Items[Index]:=CreateJSON(AValue); end; +{$endif} function TJSONArray.DoFindPath(const APath: TJSONStringType; out NotFound: TJSONStringType): TJSONdata; @@ -2016,18 +2227,22 @@ end; function TJSONArray.GetAsBoolean: Boolean; begin ConvertError(True); + Result:=false; end; function TJSONArray.GetAsFloat: TJSONFloat; begin ConvertError(True); + Result:=0.0; end; function TJSONArray.GetAsInteger: Integer; begin ConvertError(True); + Result:=0; end; +{$ifdef fpc} function TJSONArray.GetAsInt64: Int64; begin ConvertError(True); @@ -2037,6 +2252,7 @@ function TJSONArray.GetAsQWord: QWord; begin ConvertError(True); end; +{$endif} procedure TJSONArray.SetAsBoolean(const AValue: Boolean); begin @@ -2056,6 +2272,7 @@ begin if AValue>0 then ; end; +{$ifdef fpc} procedure TJSONArray.SetAsInt64(const AValue: Int64); begin ConvertError(False); @@ -2067,6 +2284,7 @@ begin ConvertError(False); if AValue>0 then ; end; +{$endif} {$warnings on} @@ -2096,8 +2314,6 @@ begin Result:=Result+']'; end; -{$warnings off} - Function IndentString(Options : TFormatOptions; Indent : Integer) : TJSONStringType; begin @@ -2145,9 +2361,11 @@ begin end; +{$warnings off} function TJSONArray.GetAsString: TJSONStringType; begin ConvertError(True); + Result:=''; end; procedure TJSONArray.SetAsString(const AValue: TJSONStringType); @@ -2156,21 +2374,26 @@ begin if AValue='' then ; end; -function TJSONArray.GetValue: variant; +function TJSONArray.GetValue: TJSONVariant; begin ConvertError(True); + Result:=0; end; -procedure TJSONArray.SetValue(const AValue: variant); +procedure TJSONArray.SetValue(const AValue: TJSONVariant); begin ConvertError(False); + {$ifdef pas2js} + if AValue=0 then ; + {$else} if VarType(AValue)=0 then ; + {$endif} end; {$warnings on} function TJSONArray.GetCount: Integer; begin - Result:=Flist.Count; + Result:=FList.Count; end; function TJSONArray.GetItem(Index: Integer): TJSONData; @@ -2191,6 +2414,44 @@ begin Flist:=TFPObjectList.Create(True); end; +{$ifdef pas2js} +Function VarRecToJSON(Const Element : jsvalue; const SourceType : String) : TJSONData; +var + i: NativeInt; + VObject: TObject; +begin + Result:=nil; + if Element=nil then + Result:=CreateJSON // TJSONNull + else if isBoolean(Element) then + Result:=CreateJSON(boolean(Element)) + else if isString(Element) then + Result:=CreateJSON(String(Element)) + else if isNumber(Element) then + begin + if isInteger(Element) then + begin + i:=NativeInt(Element); + if (i>=low(integer)) and (i<=high(integer)) then + Result:=CreateJSON(Integer(Element)) + else + Result:=CreateJSON(TJSONFloat(Element)); + end + else + Result:=CreateJSON(TJSONFloat(Element)); + end + else if isObject(Element) and (Element is TObject) then + begin + VObject:=TObject(Element); + if VObject is TJSONData then + Result:=TJSONData(VObject) + else + TJSONData.DoError(SErrNotJSONData,[VObject.ClassName,SourceType]); + end + else + TJSONData.DoError(SErrUnknownTypeInConstructor,[SourceType,jsTypeOf(Element)]); +end; +{$else} Function VarRecToJSON(Const Element : TVarRec; const SourceType : String) : TJSONData; begin @@ -2219,8 +2480,9 @@ begin TJSONData.DoError(SErrUnknownTypeInConstructor,[SourceType,VType]) end; end; +{$endif} -constructor TJSONArray.Create(const Elements: array of const); +constructor TJSONArray.Create(const Elements: array of {$ifdef pas2js}jsvalue{$else}Const{$endif}); Var I : integer; @@ -2305,6 +2567,7 @@ begin Result:=Add(CreateJSON(I)); end; +{$ifdef fpc} function TJSONArray.Add(I: Int64): Int64; begin Result:=Add(CreateJSON(I)); @@ -2314,16 +2577,19 @@ function TJSONArray.Add(I: QWord): QWord; begin Result:=Add(CreateJSON(I)); end; +{$endif} function TJSONArray.Add(const S: String): Integer; begin Result:=Add(CreateJSON(S)); end; +{$ifdef fpc} function TJSONArray.Add(const S: UnicodeString): Integer; begin Result:=Add(CreateJSON(S)); end; +{$endif} function TJSONArray.Add: Integer; begin @@ -2389,6 +2655,7 @@ begin FList.Insert(Index, CreateJSON(I)); end; +{$ifdef fpc} procedure TJSONArray.Insert(Index: Integer; I: Int64); begin FList.Insert(Index, CreateJSON(I)); @@ -2398,16 +2665,19 @@ procedure TJSONArray.Insert(Index: Integer; I: QWord); begin FList.Insert(Index, CreateJSON(I)); end; +{$endif} procedure TJSONArray.Insert(Index: Integer; const S: String); begin FList.Insert(Index, CreateJSON(S)); end; +{$ifdef fpc} procedure TJSONArray.Insert(Index: Integer; const S: UnicodeString); begin FList.Insert(Index, CreateJSON(S)); end; +{$endif} procedure TJSONArray.Insert(Index: Integer; F: TJSONFloat); begin @@ -2462,9 +2732,16 @@ end; function TJSONObject.GetElements(const AName: string): TJSONData; begin + {$ifdef pas2js} + if FHash.hasOwnProperty(AName) then + Result:=TJSONData(FHash[AName]) + else + DoError(SErrNonexistentElement,[AName]); + {$else} Result:=TJSONData(FHash.Find(AName)); If (Result=Nil) then DoError(SErrNonexistentElement,[AName]); + {$endif} end; function TJSONObject.GetFloats(const AName: String): TJSONFloat; @@ -2477,10 +2754,12 @@ begin Result:=GetElements(AName).AsInteger; end; +{$ifdef fpc} function TJSONObject.GetInt64s(const AName: String): Int64; begin Result:=GetElements(AName).AsInt64; end; +{$endif} function TJSONObject.GetIsNull(const AName: String): Boolean; begin @@ -2489,7 +2768,15 @@ end; function TJSONObject.GetNameOf(Index: Integer): TJSONStringType; begin + {$ifdef pas2js} + if FNames=nil then + FNames:=TJSObject.getOwnPropertyNames(FHash); + if (Index<0) or (Index>=FCount) then + DoError(SListIndexError,[Index]); + Result:=FNames[Index]; + {$else} Result:=FHash.NameOfIndex(Index); + {$endif} end; function TJSONObject.GetObjects(const AName : String): TJSONObject; @@ -2497,28 +2784,32 @@ begin Result:=GetElements(AName) as TJSONObject; end; +{$ifdef fpc} function TJSONObject.GetQWords(AName : String): QWord; begin Result:=GetElements(AName).AsQWord; end; +{$endif} function TJSONObject.GetStrings(const AName : String): TJSONStringType; begin Result:=GetElements(AName).AsString; end; +{$ifdef fpc} function TJSONObject.GetUnicodeStrings(const AName: String ): TJSONUnicodeStringType; begin Result:=GetElements(AName).AsUnicodeString; end; +{$endif} function TJSONObject.GetTypes(const AName : String): TJSONType; begin Result:=Getelements(Aname).JSONType; end; -class function TJSONObject.GetUnquotedMemberNames: Boolean; static; +class function TJSONObject.GetUnquotedMemberNames: Boolean; {$ifdef fpc}static;{$endif} begin Result:=FUnquotedMemberNames; end; @@ -2535,6 +2826,14 @@ begin end; procedure TJSONObject.SetElements(const AName: string; const AValue: TJSONData); +{$ifdef pas2js} +begin + if not FHash.hasOwnProperty(AName) then + inc(FCount); + FHash[AName]:=AValue; + FNames:=nil; +end; +{$else} Var Index : Integer; @@ -2545,6 +2844,7 @@ begin else FHash.Items[Index]:=AValue; // Will free the previous value. end; +{$endif} procedure TJSONObject.SetFloats(const AName : String; const AValue: TJSONFloat); begin @@ -2556,10 +2856,12 @@ begin SetElements(AName,CreateJSON(AVAlue)); end; +{$ifdef fpc} procedure TJSONObject.SetInt64s(const AName : String; const AValue: Int64); begin SetElements(AName,CreateJSON(AVAlue)); end; +{$endif} procedure TJSONObject.SetIsNull(const AName : String; const AValue: Boolean); begin @@ -2573,21 +2875,25 @@ begin SetElements(AName,AValue); end; +{$ifdef fpc} procedure TJSONObject.SetQWords(AName : String; AValue: QWord); begin SetElements(AName,CreateJSON(AVAlue)); end; +{$endif} procedure TJSONObject.SetStrings(const AName : String; const AValue: TJSONStringType); begin SetElements(AName,CreateJSON(AValue)); end; +{$ifdef fpc} procedure TJSONObject.SetUnicodeStrings(const AName: String; const AValue: TJSONUnicodeStringType); begin SetElements(AName,CreateJSON(AValue)); end; +{$endif} class procedure TJSONObject.DetermineElementQuotes; @@ -2601,7 +2907,7 @@ begin FElementStart:=ElementStart[FUnquotedMemberNames] end; -class procedure TJSONObject.SetUnquotedMemberNames(AValue: Boolean); static; +class procedure TJSONObject.SetUnquotedMemberNames(AValue: Boolean); {$ifdef fpc}static;{$endif} begin if FUnquotedMemberNames=AValue then exit; @@ -2655,18 +2961,22 @@ end; function TJSONObject.GetAsBoolean: Boolean; begin ConvertError(True); + Result:=false; end; function TJSONObject.GetAsFloat: TJSONFloat; begin ConvertError(True); + Result:=0.0; end; function TJSONObject.GetAsInteger: Integer; begin ConvertError(True); + Result:=0; end; +{$ifdef fpc} function TJSONObject.GetAsInt64: Int64; begin ConvertError(True); @@ -2676,6 +2986,7 @@ function TJSONObject.GetAsQWord: QWord; begin ConvertError(True); end; +{$endif} procedure TJSONObject.SetAsBoolean(const AValue: Boolean); begin @@ -2695,6 +3006,7 @@ begin if AValue>0 then ; end; +{$ifdef fpc} procedure TJSONObject.SetAsInt64(const AValue: Int64); begin ConvertError(False); @@ -2706,12 +3018,12 @@ begin ConvertError(False); if AValue>0 then ; end; +{$endif} {$warnings on} function TJSONObject.GetAsJSON: TJSONStringType; - Var I : Integer; Sep : String; @@ -2742,6 +3054,7 @@ end; function TJSONObject.GetAsString: TJSONStringType; begin ConvertError(True); + Result:=''; end; procedure TJSONObject.SetAsString(const AValue: TJSONStringType); @@ -2750,41 +3063,60 @@ begin if AValue='' then ; end; -function TJSONObject.GetValue: variant; +function TJSONObject.GetValue: TJSONVariant; begin ConvertError(True); + Result:=0; end; -procedure TJSONObject.SetValue(const AValue: variant); +procedure TJSONObject.SetValue(const AValue: TJSONVariant); begin ConvertError(False); + {$ifdef pas2js} + if AValue=0 then ; + {$else} if VarType(AValue)=0 then ; + {$endif} end; {$warnings on} function TJSONObject.GetCount: Integer; begin + {$ifdef pas2js} + Result:=FCount; + {$else} Result:=FHash.Count; + {$endif} end; function TJSONObject.GetItem(Index: Integer): TJSONData; begin + {$ifdef pas2js} + Result:=GetElements(GetNameOf(Index)); + {$else} Result:=TJSONData(FHash.Items[Index]); + {$endif} end; procedure TJSONObject.SetItem(Index: Integer; const AValue: TJSONData); begin + {$ifdef pas2js} + SetElements(GetNameOf(Index),AValue); + {$else} FHash.Items[Index]:=AValue; + {$endif} end; constructor TJSONObject.Create; begin + {$ifdef pas2js} + FHash:=TJSObject.new; + {$else} FHash:=TFPHashObjectList.Create(True); + {$endif} end; - - -constructor TJSONObject.Create(const Elements: array of const); +constructor TJSONObject.Create(const Elements: array of {$ifdef pas2js}jsvalue{$else}Const{$endif}); Var I : integer; @@ -2798,6 +3130,12 @@ begin I:=Low(Elements); While I<=High(Elements) do begin + {$ifdef pas2js} + if isString(Elements[I]) then + AName:=String(Elements[I]) + else + DoError(SErrNameMustBeString,[I+1]); + {$else} With Elements[i] do Case VType of vtChar : AName:=VChar; @@ -2807,7 +3145,8 @@ begin else DoError(SErrNameMustBeString,[I+1]); end; - If (ANAme='') then + {$endif} + If (AName='') then DoError(SErrNameMustBeString,[I+1]); Inc(I); J:=VarRecToJSON(Elements[i],'Object'); @@ -2816,10 +3155,13 @@ begin end; end; - destructor TJSONObject.Destroy; begin + {$ifdef pas2js} + FHash:=nil; + {$else} FreeAndNil(FHash); + {$endif} inherited Destroy; end; @@ -2908,7 +3250,21 @@ begin end; procedure TJSONObject.Iterate(Iterator: TJSONObjectIterator; Data: TObject); - +{$ifdef pas2js} +var + i: Integer; + Cont: Boolean; +begin + if FNames=nil then + FNames:=TJSObject.getOwnPropertyNames(FHash); + Cont:=True; + for i:=0 to length(FNames) do + begin + Iterator(FNames[I],TJSONData(FHash[FNames[i]]),Data,Cont); + if not Cont then break; + end; +end; +{$else} Var I : Integer; Cont : Boolean; @@ -2916,23 +3272,37 @@ Var begin I:=0; Cont:=True; - While (I=0) and (CompareText(Names[Result],AName)<>0) do @@ -2942,18 +3312,31 @@ end; procedure TJSONObject.Clear; begin + {$ifdef pas2js} + FCount:=0; + FHash:=TJSObject.new; + FNames:=nil; + {$else} FHash.Clear; + {$endif} end; function TJSONObject.DoAdd(const AName: TJSONStringType; AValue: TJSONData; FreeOnError : Boolean = True): Integer; begin - if (IndexOfName(aName)<>-1) then + if {$ifdef pas2js}FHash.hasOwnProperty(AName){$else}(IndexOfName(aName)<>-1){$endif} then begin if FreeOnError then FreeAndNil(AValue); DoError(SErrDuplicateValue,[aName]); end; + {$ifdef pas2js} + FHash[AName]:=AValue; + FNames:=nil; + inc(FCount); + Result:=FCount; + {$else} Result:=FHash.Add(AName,AValue); + {$endif} end; function TJSONObject.Add(const AName: TJSONStringType; AValue: TJSONData @@ -2978,17 +3361,20 @@ begin Result:=DoAdd(AName,CreateJSON(AValue)); end; +{$ifdef fpc} function TJSONObject.Add(const AName: String; AValue: TJSONUnicodeStringType ): Integer; begin Result:=DoAdd(AName,CreateJSON(AValue)); end; +{$endif} function TJSONObject.Add(const AName: TJSONStringType; Avalue: Integer): Integer; begin Result:=DoAdd(AName,CreateJSON(AValue)); end; +{$ifdef fpc} function TJSONObject.Add(const AName: TJSONStringType; Avalue: Int64): Integer; begin Result:=DoAdd(AName,CreateJSON(AValue)); @@ -2998,6 +3384,7 @@ function TJSONObject.Add(const AName: TJSONStringType; Avalue: QWord): Integer; begin Result:=DoAdd(AName,CreateJSON(AValue)); end; +{$endif} function TJSONObject.Add(const AName: TJSONStringType): Integer; begin @@ -3012,11 +3399,26 @@ end; procedure TJSONObject.Delete(Index: Integer); begin + {$ifdef pas2js} + if (Index<0) or (Index>=FCount) then + DoError(SListIndexError,[Index]); + JSDelete(FHash,GetNameOf(Index)); + FNames:=nil; + dec(FCount); + {$else} FHash.Delete(Index); + {$endif} end; procedure TJSONObject.Delete(const AName: string); - +{$ifdef pas2js} +begin + if not FHash.hasOwnProperty(AName) then exit; + JSDelete(FHash,AName); + FNames:=nil; + dec(FCount); +end; +{$else} Var I : Integer; @@ -3025,12 +3427,28 @@ begin if (I<>-1) then Delete(I); end; +{$endif} procedure TJSONObject.Remove(Item: TJSONData); +{$ifdef pas2js} +var AName: String; +begin + for AName in FHash do + if FHash.hasOwnProperty(AName) and (FHash[AName]=Item) then + begin + JSDelete(FHash,AName); + FNames:=nil; + dec(FCount); + exit; + end; +end; +{$else} begin FHash.Remove(Item); end; +{$endif} +{$ifdef fpc} function TJSONObject.Extract(Index: Integer): TJSONData; begin Result:=Items[Index]; @@ -3049,8 +3467,17 @@ begin else Result:=Nil end; +{$endif} -function TJSONObject.Get(const AName: String): Variant; +function TJSONObject.Get(const AName: String): TJSONVariant; +{$ifdef pas2js} +begin + if FHash.hasOwnProperty(AName) then + Result:=TJSONData(FHash[AName]).Value + else + Result:=nil; +end; +{$else} Var I : Integer; @@ -3061,6 +3488,7 @@ begin else Result:=Null; end; +{$endif} function TJSONObject.Get(const AName: String; ADefault: TJSONFloat ): TJSONFloat; @@ -3090,6 +3518,7 @@ begin Result:=ADefault; end; +{$ifdef fpc} function TJSONObject.Get(const AName: String; ADefault: Int64): Int64; Var D : TJSONData; @@ -3113,6 +3542,7 @@ begin else Result:=ADefault; end; +{$endif} function TJSONObject.Get(const AName: String; ADefault: Boolean ): Boolean; @@ -3140,6 +3570,7 @@ begin Result:=ADefault; end; +{$ifdef fpc} function TJSONObject.Get(const AName: String; ADefault: TJSONUnicodeStringType ): TJSONUnicodeStringType; Var @@ -3152,6 +3583,7 @@ begin else Result:=ADefault; end; +{$endif} function TJSONObject.Get(const AName: String; ADefault: TJSONArray ): TJSONArray; @@ -3180,7 +3612,14 @@ begin end; function TJSONObject.Find(const AName: String): TJSONData; - +{$ifdef pas2js} +begin + if FHash.hasOwnProperty(AName) then + Result:=TJSONData(FHash[AName]) + else + Result:=nil; +end; +{$else} Var I : Integer; @@ -3191,6 +3630,7 @@ begin else Result:=Nil; end; +{$endif} function TJSONObject.Find(const AName: String; AType: TJSONType): TJSONData; begin @@ -3202,7 +3642,7 @@ end; function TJSONObject.Find(const key: TJSONStringType; out AValue: TJSONData): boolean; begin AValue := Find(key); - result := assigned(AValue); + Result := assigned(AValue); end; function TJSONObject.Find(const key: TJSONStringType; out AValue: TJSONObject): boolean; @@ -3210,14 +3650,9 @@ var v: TJSONData; begin v := Find(key); - if assigned(v) then - begin - result := v.JSONType = jtObject; - if result then - AValue := TJSONObject(v); - end - else - result := false; + Result := assigned(v) and (v.JSONType = jtObject); + if Result then + AValue := TJSONObject(v); end; function TJSONObject.Find(const key: TJSONStringType; out AValue: TJSONArray): boolean; @@ -3225,14 +3660,9 @@ var v: TJSONData; begin v := Find(key); - if assigned(v) then - begin - result := v.JSONType = jtArray; - if result then - AValue := TJSONArray(v); - end - else - result := false; + Result := assigned(v) and (v.JSONType = jtArray); + if Result then + AValue := TJSONArray(v); end; function TJSONObject.Find(const key: TJSONStringType; out AValue: TJSONString): boolean; @@ -3240,14 +3670,9 @@ var v: TJSONData; begin v := Find(key); - if assigned(v) then - begin - result := v.JSONType = jtString; - if result then - AValue := TJSONString(v); - end - else - result := false; + Result := assigned(v) and (v.JSONType = jtString); + if Result then + AValue := TJSONString(v); end; function TJSONObject.Find(const key: TJSONStringType; out AValue: TJSONBoolean): boolean; @@ -3255,14 +3680,9 @@ var v: TJSONData; begin v := Find(key); - if assigned(v) then - begin - result := v.JSONType = jtBoolean; - if result then - AValue := TJSONBoolean(v); - end - else - result := false; + Result := assigned(v) and (v.JSONType = jtBoolean); + if Result then + AValue := TJSONBoolean(v); end; function TJSONObject.Find(const key: TJSONStringType; out AValue: TJSONNumber): boolean; @@ -3270,14 +3690,9 @@ var v: TJSONData; begin v := Find(key); - if assigned(v) then - begin - result := v.JSONType = jtNumber; - if result then - AValue := TJSONNumber(v); - end - else - result := false; + Result := assigned(v) and (v.JSONType = jtNumber); + if Result then + AValue := TJSONNumber(v); end; initialization