fpjson.pp 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188
  1. {
  2. This file is part of the Free Component Library
  3. JSON Data structures
  4. Copyright (c) 2007 by Michael Van Canneyt [email protected]
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$mode objfpc}
  12. {$h+}
  13. unit fpjson;
  14. interface
  15. uses
  16. variants,
  17. SysUtils,
  18. classes,
  19. contnrs;
  20. type
  21. TJSONtype = (jtUnknown, jtNumber, jtString, jtBoolean, jtNull, jtArray, jtObject);
  22. TJSONFloat = Double;
  23. TJSONStringType = AnsiString;
  24. TJSONCharType = AnsiChar;
  25. PJSONCharType = ^TJSONCharType;
  26. TFormatOption = (foSingleLineArray, // Array without CR/LF : all on one line
  27. foSingleLineObject, // Object without CR/LF : all on one line
  28. foDoNotQuoteMembers, // Do not quote object member names.
  29. foUseTabchar); // Use tab characters instead of spaces.
  30. TFormatOptions = set of TFormatOption;
  31. Const
  32. DefaultIndentSize = 2;
  33. DefaultFormat = [];
  34. AsJSONFormat = [foSingleLineArray,foSingleLineObject]; // These options make FormatJSON behave as AsJSON
  35. Type
  36. { TJSONData }
  37. TJSONData = class(TObject)
  38. protected
  39. function GetAsBoolean: Boolean; virtual; abstract;
  40. function GetAsFloat: TJSONFloat; virtual; abstract;
  41. function GetAsInteger: Integer; virtual; abstract;
  42. function GetAsInt64: Int64; virtual; abstract;
  43. function GetIsNull: Boolean; virtual;
  44. procedure SetAsBoolean(const AValue: Boolean); virtual; abstract;
  45. procedure SetAsFloat(const AValue: TJSONFloat); virtual; abstract;
  46. procedure SetAsInteger(const AValue: Integer); virtual; abstract;
  47. procedure SetAsInt64(const AValue: Int64); virtual; abstract;
  48. function GetAsJSON: TJSONStringType; virtual; abstract;
  49. function GetAsString: TJSONStringType; virtual; abstract;
  50. procedure SetAsString(const AValue: TJSONStringType); virtual; abstract;
  51. function GetValue: variant; virtual; abstract;
  52. procedure SetValue(const AValue: variant); virtual; abstract;
  53. function GetItem(Index : Integer): TJSONData; virtual;
  54. procedure SetItem(Index : Integer; const AValue: TJSONData); virtual;
  55. Function DoFormatJSON(Options : TFormatOptions; CurrentIndent, Indent : Integer) : TJSONStringType; virtual;
  56. function GetCount: Integer; virtual;
  57. public
  58. Constructor Create; virtual;
  59. Class function JSONType: TJSONType; virtual;
  60. Procedure Clear; virtual; Abstract;
  61. Function Clone : TJSONData; virtual; abstract;
  62. Function FormatJSON(Options : TFormatOptions = DefaultFormat; Indentsize : Integer = DefaultIndentSize) : TJSONStringType;
  63. property Count: Integer read GetCount;
  64. property Items[Index: Integer]: TJSONData read GetItem write SetItem;
  65. property Value: variant read GetValue write SetValue;
  66. Property AsString : TJSONStringType Read GetAsString Write SetAsString;
  67. Property AsFloat : TJSONFloat Read GetAsFloat Write SetAsFloat;
  68. Property AsInteger : Integer Read GetAsInteger Write SetAsInteger;
  69. Property AsInt64 : Int64 Read GetAsInt64 Write SetAsInt64;
  70. Property AsBoolean : Boolean Read GetAsBoolean Write SetAsBoolean;
  71. Property IsNull : Boolean Read GetIsNull;
  72. Property AsJSON : TJSONStringType Read GetAsJSON;
  73. end;
  74. TJSONDataClass = Class of TJSONData;
  75. TJSONNumberType = (ntFloat,ntInteger,ntInt64);
  76. TJSONNumber = class(TJSONData)
  77. protected
  78. public
  79. class function JSONType: TJSONType; override;
  80. class function NumberType : TJSONNumberType; virtual; abstract;
  81. end;
  82. { TJSONFloatNumber }
  83. TJSONFloatNumber = class(TJSONNumber)
  84. Private
  85. FValue : TJSONFloat;
  86. protected
  87. function GetAsBoolean: Boolean; override;
  88. function GetAsFloat: TJSONFloat; override;
  89. function GetAsInteger: Integer; override;
  90. function GetAsInt64: Int64; override;
  91. procedure SetAsBoolean(const AValue: Boolean); override;
  92. procedure SetAsFloat(const AValue: TJSONFloat); override;
  93. procedure SetAsInteger(const AValue: Integer); override;
  94. procedure SetAsInt64(const AValue: Int64); override;
  95. function GetAsJSON: TJSONStringType; override;
  96. function GetAsString: TJSONStringType; override;
  97. procedure SetAsString(const AValue: TJSONStringType); override;
  98. function GetValue: variant; override;
  99. procedure SetValue(const AValue: variant); override;
  100. public
  101. Constructor Create(AValue : TJSONFloat); reintroduce;
  102. class function NumberType : TJSONNumberType; override;
  103. Procedure Clear; override;
  104. Function Clone : TJSONData; override;
  105. end;
  106. { TJSONIntegerNumber }
  107. TJSONIntegerNumber = class(TJSONNumber)
  108. Private
  109. FValue : Integer;
  110. protected
  111. function GetAsBoolean: Boolean; override;
  112. function GetAsFloat: TJSONFloat; override;
  113. function GetAsInteger: Integer; override;
  114. function GetAsInt64: Int64; override;
  115. procedure SetAsBoolean(const AValue: Boolean); override;
  116. procedure SetAsFloat(const AValue: TJSONFloat); override;
  117. procedure SetAsInteger(const AValue: Integer); override;
  118. procedure SetAsInt64(const AValue: Int64); override;
  119. function GetAsJSON: TJSONStringType; override;
  120. function GetAsString: TJSONStringType; override;
  121. procedure SetAsString(const AValue: TJSONStringType); override;
  122. function GetValue: variant; override;
  123. procedure SetValue(const AValue: variant); override;
  124. public
  125. Constructor Create(AValue : Integer); reintroduce;
  126. class function NumberType : TJSONNumberType; override;
  127. Procedure Clear; override;
  128. Function Clone : TJSONData; override;
  129. end;
  130. { TJSONInt64Number }
  131. TJSONInt64Number = class(TJSONNumber)
  132. Private
  133. FValue : Int64;
  134. protected
  135. function GetAsBoolean: Boolean; override;
  136. function GetAsFloat: TJSONFloat; override;
  137. function GetAsInteger: Integer; override;
  138. function GetAsInt64: Int64; override;
  139. procedure SetAsBoolean(const AValue: Boolean); override;
  140. procedure SetAsFloat(const AValue: TJSONFloat); override;
  141. procedure SetAsInteger(const AValue: Integer); override;
  142. procedure SetAsInt64(const AValue: Int64); override;
  143. function GetAsJSON: TJSONStringType; override;
  144. function GetAsString: TJSONStringType; override;
  145. procedure SetAsString(const AValue: TJSONStringType); override;
  146. function GetValue: variant; override;
  147. procedure SetValue(const AValue: variant); override;
  148. public
  149. Constructor Create(AValue : Int64); reintroduce;
  150. class function NumberType : TJSONNumberType; override;
  151. Procedure Clear; override;
  152. Function Clone : TJSONData; override;
  153. end;
  154. { TJSONString }
  155. TJSONString = class(TJSONData)
  156. Private
  157. FValue: TJSONStringType;
  158. protected
  159. function GetValue: Variant; override;
  160. procedure SetValue(const AValue: Variant); override;
  161. function GetAsBoolean: Boolean; override;
  162. function GetAsFloat: TJSONFloat; override;
  163. function GetAsInteger: Integer; override;
  164. function GetAsInt64: Int64; override;
  165. procedure SetAsBoolean(const AValue: Boolean); override;
  166. procedure SetAsFloat(const AValue: TJSONFloat); override;
  167. procedure SetAsInteger(const AValue: Integer); override;
  168. procedure SetAsInt64(const AValue: Int64); override;
  169. function GetAsJSON: TJSONStringType; override;
  170. function GetAsString: TJSONStringType; override;
  171. procedure SetAsString(const AValue: TJSONStringType); override;
  172. public
  173. Constructor Create(const AValue : TJSONStringType); reintroduce;
  174. class function JSONType: TJSONType; override;
  175. Procedure Clear; override;
  176. Function Clone : TJSONData; override;
  177. end;
  178. { TJSONboolean }
  179. TJSONBoolean = class(TJSONData)
  180. Private
  181. FValue: Boolean;
  182. protected
  183. function GetValue: Variant; override;
  184. procedure SetValue(const AValue: Variant); override;
  185. function GetAsBoolean: Boolean; override;
  186. function GetAsFloat: TJSONFloat; override;
  187. function GetAsInteger: Integer; override;
  188. function GetAsInt64: Int64; override;
  189. procedure SetAsBoolean(const AValue: Boolean); override;
  190. procedure SetAsFloat(const AValue: TJSONFloat); override;
  191. procedure SetAsInteger(const AValue: Integer); override;
  192. procedure SetAsInt64(const AValue: Int64); override;
  193. function GetAsJSON: TJSONStringType; override;
  194. function GetAsString: TJSONStringType; override;
  195. procedure SetAsString(const AValue: TJSONStringType); override;
  196. public
  197. Constructor Create(AValue : Boolean); reintroduce;
  198. class function JSONType: TJSONType; override;
  199. Procedure Clear; override;
  200. Function Clone : TJSONData; override;
  201. end;
  202. { TJSONnull }
  203. TJSONNull = class(TJSONData)
  204. protected
  205. Procedure Converterror(From : Boolean);
  206. function GetAsBoolean: Boolean; override;
  207. function GetAsFloat: TJSONFloat; override;
  208. function GetAsInteger: Integer; override;
  209. function GetAsInt64: Int64; override;
  210. function GetIsNull: Boolean; override;
  211. procedure SetAsBoolean(const AValue: Boolean); override;
  212. procedure SetAsFloat(const AValue: TJSONFloat); override;
  213. procedure SetAsInteger(const AValue: Integer); override;
  214. procedure SetAsInt64(const AValue: Int64); override;
  215. function GetAsJSON: TJSONStringType; override;
  216. function GetAsString: TJSONStringType; override;
  217. procedure SetAsString(const AValue: TJSONStringType); override;
  218. function GetValue: variant; override;
  219. procedure SetValue(const AValue: variant); override;
  220. public
  221. class function JSONType: TJSONType; override;
  222. Procedure Clear; override;
  223. Function Clone : TJSONData; override;
  224. end;
  225. TJSONArrayIterator = procedure(Item: TJSONData; Data: TObject; var Continue: Boolean) of object;
  226. { TJSONArray }
  227. TJSONObject = Class;
  228. TJSONArray = class(TJSONData)
  229. Private
  230. FList : TFPObjectList;
  231. function GetArrays(Index : Integer): TJSONArray;
  232. function GetBooleans(Index : Integer): Boolean;
  233. function GetFloats(Index : Integer): TJSONFloat;
  234. function GetIntegers(Index : Integer): Integer;
  235. function GetInt64s(Index : Integer): Int64;
  236. function GetNulls(Index : Integer): Boolean;
  237. function GetObjects(Index : Integer): TJSONObject;
  238. function GetStrings(Index : Integer): TJSONStringType;
  239. function GetTypes(Index : Integer): TJSONType;
  240. procedure SetArrays(Index : Integer; const AValue: TJSONArray);
  241. procedure SetBooleans(Index : Integer; const AValue: Boolean);
  242. procedure SetFloats(Index : Integer; const AValue: TJSONFloat);
  243. procedure SetIntegers(Index : Integer; const AValue: Integer);
  244. procedure SetInt64s(Index : Integer; const AValue: Int64);
  245. procedure SetObjects(Index : Integer; const AValue: TJSONObject);
  246. procedure SetStrings(Index : Integer; const AValue: TJSONStringType);
  247. protected
  248. Procedure Converterror(From : Boolean);
  249. function GetAsBoolean: Boolean; override;
  250. function GetAsFloat: TJSONFloat; override;
  251. function GetAsInteger: Integer; override;
  252. function GetAsInt64: Int64; override;
  253. procedure SetAsBoolean(const AValue: Boolean); override;
  254. procedure SetAsFloat(const AValue: TJSONFloat); override;
  255. procedure SetAsInteger(const AValue: Integer); override;
  256. procedure SetAsInt64(const AValue: Int64); override;
  257. function GetAsJSON: TJSONStringType; override;
  258. function GetAsString: TJSONStringType; override;
  259. procedure SetAsString(const AValue: TJSONStringType); override;
  260. function GetValue: variant; override;
  261. procedure SetValue(const AValue: variant); override;
  262. function GetCount: Integer; override;
  263. function GetItem(Index : Integer): TJSONData; override;
  264. procedure SetItem(Index : Integer; const AValue: TJSONData); override;
  265. Function DoFormatJSON(Options : TFormatOptions; CurrentIndent, Indent : Integer) : TJSONStringType; override;
  266. public
  267. Constructor Create; overload; reintroduce;
  268. Constructor Create(const Elements : Array of Const); overload;
  269. Destructor Destroy; override;
  270. class function JSONType: TJSONType; override;
  271. Function Clone : TJSONData; override;
  272. // Examine
  273. procedure Iterate(Iterator : TJSONArrayIterator; Data: TObject);
  274. function IndexOf(obj: TJSONData): Integer;
  275. // Manipulate
  276. Procedure Clear; override;
  277. function Add(Item : TJSONData): Integer;
  278. function Add(I : Integer): Integer;
  279. function Add(I : Int64): Int64;
  280. function Add(const S : String): Integer;
  281. function Add: Integer;
  282. function Add(F : TJSONFloat): Integer;
  283. function Add(B : Boolean): Integer;
  284. function Add(AnArray : TJSONArray): Integer;
  285. function Add(AnObject: TJSONObject): Integer;
  286. Procedure Delete(Index : Integer);
  287. procedure Exchange(Index1, Index2: Integer);
  288. procedure Insert(Index: Integer);
  289. procedure Insert(Index: Integer; Item : TJSONData);
  290. procedure Insert(Index: Integer; I : Integer);
  291. procedure Insert(Index: Integer; I : Int64);
  292. procedure Insert(Index: Integer; const S : String);
  293. procedure Insert(Index: Integer; F : TJSONFloat);
  294. procedure Insert(Index: Integer; B : Boolean);
  295. procedure Insert(Index: Integer; AnArray : TJSONArray);
  296. procedure Insert(Index: Integer; AnObject: TJSONObject);
  297. procedure Move(CurIndex, NewIndex: Integer);
  298. Procedure Remove(Item : TJSONData);
  299. // Easy Access Properties.
  300. property Items;default;
  301. Property Types[Index : Integer] : TJSONType Read GetTypes;
  302. Property Nulls[Index : Integer] : Boolean Read GetNulls;
  303. Property Integers[Index : Integer] : Integer Read GetIntegers Write SetIntegers;
  304. Property Int64s[Index : Integer] : Int64 Read GetInt64s Write SetInt64s;
  305. Property Strings[Index : Integer] : TJSONStringType Read GetStrings Write SetStrings;
  306. Property Floats[Index : Integer] : TJSONFloat Read GetFloats Write SetFloats;
  307. Property Booleans[Index : Integer] : Boolean Read GetBooleans Write SetBooleans;
  308. Property Arrays[Index : Integer] : TJSONArray Read GetArrays Write SetArrays;
  309. Property Objects[Index : Integer] : TJSONObject Read GetObjects Write SetObjects;
  310. end;
  311. TJSONObjectIterator = procedure(Const AName : TJSONStringType; Item: TJSONData; Data: TObject; var Continue: Boolean) of object;
  312. { TJSONObject }
  313. TJSONObject = class(TJSONData)
  314. private
  315. FHash : TFPHashObjectList; // Careful : Names limited to 255 chars.
  316. function GetArrays(const AName : String): TJSONArray;
  317. function GetBooleans(const AName : String): Boolean;
  318. function GetElements(const AName: string): TJSONData;
  319. function GetFloats(const AName : String): TJSONFloat;
  320. function GetIntegers(const AName : String): Integer;
  321. function GetInt64s(const AName : String): Int64;
  322. function GetIsNull(const AName : String): Boolean; reintroduce;
  323. function GetNameOf(Index : Integer): TJSONStringType;
  324. function GetObjects(const AName : String): TJSONObject;
  325. function GetStrings(const AName : String): TJSONStringType;
  326. function GetTypes(const AName : String): TJSONType;
  327. procedure SetArrays(const AName : String; const AValue: TJSONArray);
  328. procedure SetBooleans(const AName : String; const AValue: Boolean);
  329. procedure SetElements(const AName: string; const AValue: TJSONData);
  330. procedure SetFloats(const AName : String; const AValue: TJSONFloat);
  331. procedure SetIntegers(const AName : String; const AValue: Integer);
  332. procedure SetInt64s(const AName : String; const AValue: Int64);
  333. procedure SetIsNull(const AName : String; const AValue: Boolean);
  334. procedure SetObjects(const AName : String; const AValue: TJSONObject);
  335. procedure SetStrings(const AName : String; const AValue: TJSONStringType);
  336. protected
  337. Procedure Converterror(From : Boolean);
  338. function GetAsBoolean: Boolean; override;
  339. function GetAsFloat: TJSONFloat; override;
  340. function GetAsInteger: Integer; override;
  341. function GetAsInt64: Int64; override;
  342. procedure SetAsBoolean(const AValue: Boolean); override;
  343. procedure SetAsFloat(const AValue: TJSONFloat); override;
  344. procedure SetAsInteger(const AValue: Integer); override;
  345. procedure SetAsInt64(const AValue: Int64); override;
  346. function GetAsJSON: TJSONStringType; override;
  347. function GetAsString: TJSONStringType; override;
  348. procedure SetAsString(const AValue: TJSONStringType); override;
  349. function GetValue: variant; override;
  350. procedure SetValue(const AValue: variant); override;
  351. function GetCount: Integer; override;
  352. function GetItem(Index : Integer): TJSONData; override;
  353. procedure SetItem(Index : Integer; const AValue: TJSONData); override;
  354. Function DoFormatJSON(Options : TFormatOptions; CurrentIndent, Indent : Integer) : TJSONStringType; override;
  355. public
  356. constructor Create; reintroduce;
  357. Constructor Create(const Elements : Array of Const); overload;
  358. destructor Destroy; override;
  359. class function JSONType: TJSONType; override;
  360. Function Clone : TJSONData; override;
  361. // Examine
  362. procedure Iterate(Iterator : TJSONObjectIterator; Data: TObject);
  363. function IndexOf(Item: TJSONData): Integer;
  364. Function IndexOfName(const AName: TJSONStringType; CaseInsensitive : Boolean = False): Integer;
  365. Function Find(Const AName : String) : TJSONData; overload;
  366. Function Find(Const AName : String; AType : TJSONType) : TJSONData; overload;
  367. Function Get(Const AName : String) : Variant;
  368. Function Get(Const AName : String; ADefault : TJSONFloat) : TJSONFloat;
  369. Function Get(Const AName : String; ADefault : Integer) : Integer;
  370. Function Get(Const AName : String; ADefault : Int64) : Int64;
  371. Function Get(Const AName : String; ADefault : Boolean) : Boolean;
  372. Function Get(Const AName : String; ADefault : TJSONStringType) : TJSONStringTYpe;
  373. Function Get(Const AName : String; ADefault : TJSONArray) : TJSONArray;
  374. Function Get(Const AName : String; ADefault : TJSONObject) : TJSONObject;
  375. // Manipulate
  376. Procedure Clear; override;
  377. function Add(const AName: TJSONStringType; AValue: TJSONData): Integer; overload;
  378. function Add(const AName: TJSONStringType; AValue: Boolean): Integer; overload;
  379. function Add(const AName: TJSONStringType; AValue: TJSONFloat): Integer; overload;
  380. function Add(const AName, AValue: TJSONStringType): Integer; overload;
  381. function Add(const AName: TJSONStringType; Avalue: Integer): Integer; overload;
  382. function Add(const AName: TJSONStringType; Avalue: Int64): Integer; overload;
  383. function Add(const AName: TJSONStringType): Integer; overload;
  384. function Add(const AName: TJSONStringType; AValue : TJSONArray): Integer; overload;
  385. procedure Delete(Index : Integer);
  386. procedure Delete(Const AName : string);
  387. procedure Remove(Item : TJSONData);
  388. Function Extract(Index : Integer) : TJSONData;
  389. Function Extract(Const AName : string) : TJSONData;
  390. // Easy access properties.
  391. property Names[Index : Integer] : TJSONStringType read GetNameOf;
  392. property Elements[AName: string] : TJSONData read GetElements write SetElements; default;
  393. Property Types[AName : String] : TJSONType Read GetTypes;
  394. Property Nulls[AName : String] : Boolean Read GetIsNull Write SetIsNull;
  395. Property Floats[AName : String] : TJSONFloat Read GetFloats Write SetFloats;
  396. Property Integers[AName : String] : Integer Read GetIntegers Write SetIntegers;
  397. Property Int64s[AName : String] : Int64 Read GetInt64s Write SetInt64s;
  398. Property Strings[AName : String] : TJSONStringType Read GetStrings Write SetStrings;
  399. Property Booleans[AName : String] : Boolean Read GetBooleans Write SetBooleans;
  400. Property Arrays[AName : String] : TJSONArray Read GetArrays Write SetArrays;
  401. Property Objects[AName : String] : TJSONObject Read GetObjects Write SetObjects;
  402. end;
  403. EJSON = Class(Exception);
  404. Function StringToJSONString(const S : TJSONStringType) : TJSONStringType;
  405. Function JSONStringToString(const S : TJSONStringType) : TJSONStringType;
  406. Function JSONTypeName(JSONType : TJSONType) : String;
  407. implementation
  408. Uses typinfo;
  409. Resourcestring
  410. SErrCannotConvertFromNull = 'Cannot convert data from Null value';
  411. SErrCannotConvertToNull = 'Cannot convert data to Null value';
  412. SErrCannotConvertFromArray = 'Cannot convert data from array value';
  413. SErrCannotConvertToArray = 'Cannot convert data to array value';
  414. SErrCannotConvertFromObject = 'Cannot convert data from object value';
  415. SErrCannotConvertToObject = 'Cannot convert data to object value';
  416. SErrInvalidFloat = 'Invalid float value : %s';
  417. SErrInvalidInteger = 'Invalid float value : %s';
  418. SErrCannotSetNotIsNull = 'IsNull cannot be set to False';
  419. SErrCannotAddArrayTwice = 'Adding an array object to an array twice is not allowed';
  420. SErrCannotAddObjectTwice = 'Adding an object to an array twice is not allowed';
  421. SErrUnknownTypeInConstructor = 'Unknown type in JSON%s constructor: %d';
  422. SErrNotJSONData = 'Cannot add object of type %s to TJSON%s';
  423. SErrPointerNotNil = 'Cannot add non-nil pointer to JSON%s';
  424. SErrOddNumber = 'TJSONObject must be constructed with name,value pairs';
  425. SErrNameMustBeString = 'TJSONObject constructor element name at pos %d is not a string';
  426. SErrNonexistentElement = 'Unknown object member: "%s"';
  427. Function StringToJSONString(const S : TJSONStringType) : TJSONStringType;
  428. Var
  429. I,J,L : Integer;
  430. P : PJSONCharType;
  431. begin
  432. I:=1;
  433. J:=1;
  434. Result:='';
  435. L:=Length(S);
  436. P:=PJSONCharType(S);
  437. While I<=L do
  438. begin
  439. if (AnsiChar(P^) in ['"','/','\',#8,#9,#10,#12,#13]) then
  440. begin
  441. Result:=Result+Copy(S,J,I-J);
  442. Case P^ of
  443. '\' : Result:=Result+'\\';
  444. '/' : Result:=Result+'\/';
  445. '"' : Result:=Result+'\"';
  446. #8 : Result:=Result+'\b';
  447. #9 : Result:=Result+'\t';
  448. #10 : Result:=Result+'\n';
  449. #12 : Result:=Result+'\f';
  450. #13 : Result:=Result+'\r';
  451. end;
  452. J:=I+1;
  453. end;
  454. Inc(I);
  455. Inc(P);
  456. end;
  457. Result:=Result+Copy(S,J,I-1);
  458. end;
  459. Function JSONStringToString(const S : TJSONStringType) : TJSONStringType;
  460. Var
  461. I,J,L : Integer;
  462. P : PJSONCharType;
  463. w : String;
  464. begin
  465. I:=1;
  466. J:=1;
  467. L:=Length(S);
  468. Result:='';
  469. P:=PJSONCharType(S);
  470. While (I<=L) do
  471. begin
  472. if (P^='\') then
  473. begin
  474. Result:=Result+Copy(S,J,I-J);
  475. Inc(P);
  476. If (P^<>#0) then
  477. begin
  478. Inc(I);
  479. Case AnsiChar(P^) of
  480. '\','"','/'
  481. : Result:=Result+P^;
  482. 'b' : Result:=Result+#8;
  483. 't' : Result:=Result+#9;
  484. 'n' : Result:=Result+#10;
  485. 'f' : Result:=Result+#12;
  486. 'r' : Result:=Result+#13;
  487. 'u' : begin
  488. W:=Copy(S,I+1,4);
  489. Inc(I,4);
  490. Inc(P,4);
  491. Result:=Result+WideChar(StrToInt('$'+W));
  492. end;
  493. end;
  494. end;
  495. J:=I+1;
  496. end;
  497. Inc(I);
  498. Inc(P);
  499. end;
  500. Result:=Result+Copy(S,J,I-J+1);
  501. end;
  502. function JSONTypeName(JSONType: TJSONType): String;
  503. begin
  504. Result:=GetEnumName(TypeInfo(TJSONType),Ord(JSONType));
  505. end;
  506. { TJSONData }
  507. function TJSONData.GetItem(Index : Integer): TJSONData;
  508. begin
  509. Result:=nil;
  510. end;
  511. function TJSONData.GetCount: Integer;
  512. begin
  513. Result:=0;
  514. end;
  515. constructor TJSONData.Create;
  516. begin
  517. Clear;
  518. end;
  519. function TJSONData.GetIsNull: Boolean;
  520. begin
  521. Result:=False;
  522. end;
  523. class function TJSONData.JSONType: TJSONType;
  524. begin
  525. JSONType:=jtUnknown;
  526. end;
  527. procedure TJSONData.SetItem(Index : Integer; const AValue:
  528. TJSONData);
  529. begin
  530. // Do Nothing
  531. end;
  532. Function TJSONData.FormatJSON(Options : TFormatOptions = DefaultFormat; IndentSize : Integer = DefaultIndentSize) : TJSONStringType;
  533. begin
  534. Result:=DoFormatJSON(Options,0,IndentSize);
  535. end;
  536. Function TJSONData.DoFormatJSON(Options : TFormatOptions; CurrentIndent, Indent : Integer) : TJSONStringType;
  537. begin
  538. Result:=AsJSON;
  539. end;
  540. { TJSONnumber }
  541. class function TJSONnumber.JSONType: TJSONType;
  542. begin
  543. Result:=jtNumber;
  544. end;
  545. { TJSONstring }
  546. class function TJSONstring.JSONType: TJSONType;
  547. begin
  548. Result:=jtString;
  549. end;
  550. procedure TJSONString.Clear;
  551. begin
  552. FValue:='';
  553. end;
  554. function TJSONString.Clone: TJSONData;
  555. begin
  556. Result:=TJSONString.Create(Self.FValue);
  557. end;
  558. function TJSONstring.GetValue: Variant;
  559. begin
  560. Result:=FValue;
  561. end;
  562. procedure TJSONstring.SetValue(const AValue: Variant);
  563. begin
  564. FValue:=AValue;
  565. end;
  566. function TJSONstring.GetAsBoolean: Boolean;
  567. begin
  568. Result:=StrToBool(FValue);
  569. end;
  570. function TJSONstring.GetAsFloat: TJSONFloat;
  571. Var
  572. C : Integer;
  573. begin
  574. Val(FValue,Result,C);
  575. If (C<>0) then
  576. If Not TryStrToFloat(FValue,Result) then
  577. Raise EConvertError.CreateFmt(SErrInvalidFloat,[FValue]);
  578. end;
  579. function TJSONstring.GetAsInteger: Integer;
  580. begin
  581. Result:=StrToInt(FValue);
  582. end;
  583. function TJSONstring.GetAsInt64: Int64;
  584. begin
  585. Result:=StrToInt64(FValue);
  586. end;
  587. procedure TJSONstring.SetAsBoolean(const AValue: Boolean);
  588. begin
  589. FValue:=BoolToStr(AValue);
  590. end;
  591. procedure TJSONstring.SetAsFloat(const AValue: TJSONFloat);
  592. begin
  593. FValue:=FloatToStr(AValue);
  594. end;
  595. procedure TJSONstring.SetAsInteger(const AValue: Integer);
  596. begin
  597. FValue:=IntToStr(AValue);
  598. end;
  599. procedure TJSONstring.SetAsInt64(const AValue: Int64);
  600. begin
  601. FValue:=IntToStr(AValue);
  602. end;
  603. function TJSONstring.GetAsJSON: TJSONStringType;
  604. begin
  605. Result:='"'+StringToJSONString(FValue)+'"';
  606. end;
  607. function TJSONstring.GetAsString: TJSONStringType;
  608. begin
  609. Result:=FValue;
  610. end;
  611. procedure TJSONstring.SetAsString(const AValue: TJSONStringType);
  612. begin
  613. FValue:=AValue;
  614. end;
  615. constructor TJSONstring.Create(const AValue: TJSONStringType);
  616. begin
  617. FValue:=AValue;
  618. end;
  619. { TJSONboolean }
  620. function TJSONboolean.GetValue: Variant;
  621. begin
  622. Result:=FValue;
  623. end;
  624. class function TJSONboolean.JSONType: TJSONType;
  625. begin
  626. Result:=jtBoolean;
  627. end;
  628. procedure TJSONBoolean.Clear;
  629. begin
  630. FValue:=False;
  631. end;
  632. function TJSONBoolean.Clone: TJSONData;
  633. begin
  634. Result:=TJSONBoolean.Create(Self.Fvalue);
  635. end;
  636. procedure TJSONboolean.SetValue(const AValue: Variant);
  637. begin
  638. FValue:=boolean(AValue);
  639. end;
  640. function TJSONboolean.GetAsBoolean: Boolean;
  641. begin
  642. Result:=FValue;
  643. end;
  644. function TJSONboolean.GetAsFloat: TJSONFloat;
  645. begin
  646. Result:=Ord(FValue);
  647. end;
  648. function TJSONboolean.GetAsInteger: Integer;
  649. begin
  650. Result:=Ord(FValue);
  651. end;
  652. function TJSONboolean.GetAsInt64: Int64;
  653. begin
  654. Result:=Ord(FValue);
  655. end;
  656. procedure TJSONboolean.SetAsBoolean(const AValue: Boolean);
  657. begin
  658. FValue:=AValue;
  659. end;
  660. procedure TJSONboolean.SetAsFloat(const AValue: TJSONFloat);
  661. begin
  662. FValue:=(AValue<>0)
  663. end;
  664. procedure TJSONboolean.SetAsInteger(const AValue: Integer);
  665. begin
  666. FValue:=(AValue<>0)
  667. end;
  668. procedure TJSONboolean.SetAsInt64(const AValue: Int64);
  669. begin
  670. FValue:=(AValue<>0)
  671. end;
  672. function TJSONboolean.GetAsJSON: TJSONStringType;
  673. begin
  674. If FValue then
  675. Result:='true'
  676. else
  677. Result:='false';
  678. end;
  679. function TJSONboolean.GetAsString: TJSONStringType;
  680. begin
  681. Result:=BoolToStr(FValue, True);
  682. end;
  683. procedure TJSONboolean.SetAsString(const AValue: TJSONStringType);
  684. begin
  685. FValue:=StrToBool(AValue);
  686. end;
  687. constructor TJSONboolean.Create(AValue: Boolean);
  688. begin
  689. FValue:=AValue;
  690. end;
  691. { TJSONnull }
  692. procedure TJSONnull.Converterror(From : Boolean);
  693. begin
  694. If From then
  695. Raise EJSON.Create(SErrCannotConvertFromNull)
  696. else
  697. Raise EJSON.Create(SErrCannotConvertToNull);
  698. end;
  699. {$warnings off}
  700. function TJSONnull.GetAsBoolean: Boolean;
  701. begin
  702. ConvertError(True);
  703. end;
  704. function TJSONnull.GetAsFloat: TJSONFloat;
  705. begin
  706. ConvertError(True);
  707. end;
  708. function TJSONnull.GetAsInteger: Integer;
  709. begin
  710. ConvertError(True);
  711. end;
  712. function TJSONnull.GetAsInt64: Int64;
  713. begin
  714. ConvertError(True);
  715. end;
  716. function TJSONnull.GetIsNull: Boolean;
  717. begin
  718. Result:=True;
  719. end;
  720. procedure TJSONnull.SetAsBoolean(const AValue: Boolean);
  721. begin
  722. ConvertError(False);
  723. end;
  724. procedure TJSONnull.SetAsFloat(const AValue: TJSONFloat);
  725. begin
  726. ConvertError(False);
  727. end;
  728. procedure TJSONnull.SetAsInteger(const AValue: Integer);
  729. begin
  730. ConvertError(False);
  731. end;
  732. procedure TJSONnull.SetAsInt64(const AValue: Int64);
  733. begin
  734. ConvertError(False);
  735. end;
  736. function TJSONnull.GetAsJSON: TJSONStringType;
  737. begin
  738. Result:='null';
  739. end;
  740. function TJSONnull.GetAsString: TJSONStringType;
  741. begin
  742. ConvertError(True);
  743. end;
  744. procedure TJSONnull.SetAsString(const AValue: TJSONStringType);
  745. begin
  746. ConvertError(True);
  747. end;
  748. function TJSONnull.GetValue: Variant;
  749. begin
  750. Result:=variants.Null;
  751. end;
  752. procedure TJSONnull.SetValue(const AValue: variant);
  753. begin
  754. ConvertError(False);
  755. end;
  756. class function TJSONnull.JSONType: TJSONType;
  757. begin
  758. Result:=jtNull;
  759. end;
  760. procedure TJSONNull.Clear;
  761. begin
  762. // Do nothing
  763. end;
  764. function TJSONNull.Clone: TJSONData;
  765. begin
  766. Result:=TJSONNull.Create;
  767. end;
  768. {$warnings on}
  769. { TJSONFloatNumber }
  770. function TJSONFloatNumber.GetAsBoolean: Boolean;
  771. begin
  772. Result:=(FValue<>0);
  773. end;
  774. function TJSONFloatNumber.GetAsFloat: TJSONFloat;
  775. begin
  776. Result:=FValue;
  777. end;
  778. function TJSONFloatNumber.GetAsInteger: Integer;
  779. begin
  780. Result:=Round(FValue);
  781. end;
  782. function TJSONFloatNumber.GetAsInt64: Int64;
  783. begin
  784. Result:=Round(FValue);
  785. end;
  786. procedure TJSONFloatNumber.SetAsBoolean(const AValue: Boolean);
  787. begin
  788. FValue:=Ord(AValue);
  789. end;
  790. procedure TJSONFloatNumber.SetAsFloat(const AValue: TJSONFloat);
  791. begin
  792. FValue:=AValue;
  793. end;
  794. procedure TJSONFloatNumber.SetAsInteger(const AValue: Integer);
  795. begin
  796. FValue:=AValue;
  797. end;
  798. procedure TJSONFloatNumber.SetAsInt64(const AValue: Int64);
  799. begin
  800. FValue:=AValue;
  801. end;
  802. function TJSONFloatNumber.GetAsJSON: TJSONStringType;
  803. begin
  804. Result:=AsString;
  805. end;
  806. function TJSONFloatNumber.GetAsString: TJSONStringType;
  807. begin
  808. Str(FValue,Result);
  809. end;
  810. procedure TJSONFloatNumber.SetAsString(const AValue: TJSONStringType);
  811. Var
  812. C : Integer;
  813. begin
  814. Val(AValue,FValue,C);
  815. If (C<>0) then
  816. Raise EConvertError.CreateFmt(SErrInvalidFloat,[AValue]);
  817. end;
  818. function TJSONFloatNumber.GetValue: variant;
  819. begin
  820. Result:=FValue;
  821. end;
  822. procedure TJSONFloatNumber.SetValue(const AValue: variant);
  823. begin
  824. FValue:=AValue;
  825. end;
  826. constructor TJSONFloatNumber.Create(AValue: TJSONFloat);
  827. begin
  828. FValue:=AValue;
  829. end;
  830. class function TJSONFloatNumber.NumberType: TJSONNumberType;
  831. begin
  832. Result:=ntFloat;
  833. end;
  834. procedure TJSONFloatNumber.Clear;
  835. begin
  836. FValue:=0;
  837. end;
  838. function TJSONFloatNumber.Clone: TJSONData;
  839. begin
  840. Result:=TJSONFloatNumber.Create(Self.FValue);
  841. end;
  842. { TJSONIntegerNumber }
  843. function TJSONIntegerNumber.GetAsBoolean: Boolean;
  844. begin
  845. Result:=FValue<>0;
  846. end;
  847. function TJSONIntegerNumber.GetAsFloat: TJSONFloat;
  848. begin
  849. Result:=Ord(FValue);
  850. end;
  851. function TJSONIntegerNumber.GetAsInteger: Integer;
  852. begin
  853. Result:=FValue;
  854. end;
  855. function TJSONIntegerNumber.GetAsInt64: Int64;
  856. begin
  857. Result:=FValue;
  858. end;
  859. procedure TJSONIntegerNumber.SetAsBoolean(const AValue: Boolean);
  860. begin
  861. FValue:=Ord(AValue);
  862. end;
  863. procedure TJSONIntegerNumber.SetAsFloat(const AValue: TJSONFloat);
  864. begin
  865. FValue:=Round(AValue);
  866. end;
  867. procedure TJSONIntegerNumber.SetAsInteger(const AValue: Integer);
  868. begin
  869. FValue:=AValue;
  870. end;
  871. procedure TJSONIntegerNumber.SetAsInt64(const AValue: Int64);
  872. begin
  873. FValue:=AValue;
  874. end;
  875. function TJSONIntegerNumber.GetAsJSON: TJSONStringType;
  876. begin
  877. Result:=AsString;
  878. end;
  879. function TJSONIntegerNumber.GetAsString: TJSONStringType;
  880. begin
  881. Result:=IntToStr(FValue)
  882. end;
  883. procedure TJSONIntegerNumber.SetAsString(const AValue: TJSONStringType);
  884. begin
  885. FValue:=StrToInt(AValue);
  886. end;
  887. function TJSONIntegerNumber.GetValue: variant;
  888. begin
  889. Result:=FValue;
  890. end;
  891. procedure TJSONIntegerNumber.SetValue(const AValue: variant);
  892. begin
  893. FValue:=AValue;
  894. end;
  895. constructor TJSONIntegerNumber.Create(AValue: Integer);
  896. begin
  897. FValue:=AValue;
  898. end;
  899. class function TJSONIntegerNumber.NumberType: TJSONNumberType;
  900. begin
  901. Result:=ntInteger;
  902. end;
  903. procedure TJSONIntegerNumber.Clear;
  904. begin
  905. FValue:=0;
  906. end;
  907. function TJSONIntegerNumber.Clone: TJSONData;
  908. begin
  909. Result:=TJSONIntegerNumber.Create(Self.FValue);
  910. end;
  911. { TJSONInt64Number }
  912. function TJSONInt64Number.GetAsInt64: Int64;
  913. begin
  914. Result := FValue;
  915. end;
  916. procedure TJSONInt64Number.SetAsInt64(const AValue: Int64);
  917. begin
  918. FValue := AValue;
  919. end;
  920. function TJSONInt64Number.GetAsBoolean: Boolean;
  921. begin
  922. Result:=FValue<>0;
  923. end;
  924. function TJSONInt64Number.GetAsFloat: TJSONFloat;
  925. begin
  926. Result:= FValue;
  927. end;
  928. function TJSONInt64Number.GetAsInteger: Integer;
  929. begin
  930. Result := FValue;
  931. end;
  932. procedure TJSONInt64Number.SetAsBoolean(const AValue: Boolean);
  933. begin
  934. FValue:=Ord(AValue);
  935. end;
  936. procedure TJSONInt64Number.SetAsFloat(const AValue: TJSONFloat);
  937. begin
  938. FValue:=Round(AValue);
  939. end;
  940. procedure TJSONInt64Number.SetAsInteger(const AValue: Integer);
  941. begin
  942. FValue:=AValue;
  943. end;
  944. function TJSONInt64Number.GetAsJSON: TJSONStringType;
  945. begin
  946. Result:=AsString;
  947. end;
  948. function TJSONInt64Number.GetAsString: TJSONStringType;
  949. begin
  950. Result:=IntToStr(FValue)
  951. end;
  952. procedure TJSONInt64Number.SetAsString(const AValue: TJSONStringType);
  953. begin
  954. FValue:=StrToInt64(AValue);
  955. end;
  956. function TJSONInt64Number.GetValue: variant;
  957. begin
  958. Result:=FValue;
  959. end;
  960. procedure TJSONInt64Number.SetValue(const AValue: variant);
  961. begin
  962. FValue:=AValue;
  963. end;
  964. constructor TJSONInt64Number.Create(AValue: Int64);
  965. begin
  966. FValue := AValue;
  967. end;
  968. class function TJSONInt64Number.NumberType: TJSONNumberType;
  969. begin
  970. Result:=ntInt64;
  971. end;
  972. procedure TJSONInt64Number.Clear;
  973. begin
  974. FValue:=0;
  975. end;
  976. function TJSONInt64Number.Clone: TJSONData;
  977. begin
  978. Result:=TJSONInt64Number.Create(Self.FValue);
  979. end;
  980. { TJSONArray }
  981. function TJSONArray.GetBooleans(Index : Integer): Boolean;
  982. begin
  983. Result:=Items[Index].AsBoolean;
  984. end;
  985. function TJSONArray.GetArrays(Index : Integer): TJSONArray;
  986. begin
  987. Result:=Items[Index] as TJSONArray;
  988. end;
  989. function TJSONArray.GetFloats(Index : Integer): TJSONFloat;
  990. begin
  991. Result:=Items[Index].AsFloat;
  992. end;
  993. function TJSONArray.GetIntegers(Index : Integer): Integer;
  994. begin
  995. Result:=Items[Index].AsInteger;
  996. end;
  997. function TJSONArray.GetInt64s(Index : Integer): Int64;
  998. begin
  999. Result:=Items[Index].AsInt64;
  1000. end;
  1001. function TJSONArray.GetNulls(Index : Integer): Boolean;
  1002. begin
  1003. Result:=Items[Index].IsNull;
  1004. end;
  1005. function TJSONArray.GetObjects(Index : Integer): TJSONObject;
  1006. begin
  1007. Result:=Items[Index] as TJSONObject;
  1008. end;
  1009. function TJSONArray.GetStrings(Index : Integer): TJSONStringType;
  1010. begin
  1011. Result:=Items[Index].AsString;
  1012. end;
  1013. function TJSONArray.GetTypes(Index : Integer): TJSONType;
  1014. begin
  1015. Result:=Items[Index].JSONType;
  1016. end;
  1017. procedure TJSONArray.SetArrays(Index : Integer; const AValue: TJSONArray);
  1018. begin
  1019. Items[Index]:=AValue;
  1020. end;
  1021. procedure TJSONArray.SetBooleans(Index : Integer; const AValue: Boolean);
  1022. begin
  1023. Items[Index]:=TJSonBoolean.Create(AValue);
  1024. end;
  1025. procedure TJSONArray.SetFloats(Index : Integer; const AValue: TJSONFloat);
  1026. begin
  1027. Items[Index]:=TJSONFloatNumber.Create(AValue);
  1028. end;
  1029. procedure TJSONArray.SetIntegers(Index : Integer; const AValue: Integer);
  1030. begin
  1031. Items[Index]:=TJSONIntegerNumber.Create(AValue);
  1032. end;
  1033. procedure TJSONArray.SetInt64s(Index : Integer; const AValue: Int64);
  1034. begin
  1035. Items[Index]:=TJSONInt64Number.Create(AValue);
  1036. end;
  1037. procedure TJSONArray.SetObjects(Index : Integer; const AValue: TJSONObject);
  1038. begin
  1039. Items[Index]:=AValue;
  1040. end;
  1041. procedure TJSONArray.SetStrings(Index : Integer; const AValue: TJSONStringType);
  1042. begin
  1043. Items[Index]:=TJSONString.Create(AValue);
  1044. end;
  1045. procedure TJSONArray.Converterror(From: Boolean);
  1046. begin
  1047. If From then
  1048. Raise EJSON.Create(SErrCannotConvertFromArray)
  1049. else
  1050. Raise EJSON.Create(SErrCannotConvertToArray);
  1051. end;
  1052. {$warnings off}
  1053. function TJSONArray.GetAsBoolean: Boolean;
  1054. begin
  1055. ConvertError(True);
  1056. end;
  1057. function TJSONArray.GetAsFloat: TJSONFloat;
  1058. begin
  1059. ConvertError(True);
  1060. end;
  1061. function TJSONArray.GetAsInteger: Integer;
  1062. begin
  1063. ConvertError(True);
  1064. end;
  1065. function TJSONArray.GetAsInt64: Int64;
  1066. begin
  1067. ConvertError(True);
  1068. end;
  1069. procedure TJSONArray.SetAsBoolean(const AValue: Boolean);
  1070. begin
  1071. ConvertError(False);
  1072. end;
  1073. procedure TJSONArray.SetAsFloat(const AValue: TJSONFloat);
  1074. begin
  1075. ConvertError(False);
  1076. end;
  1077. procedure TJSONArray.SetAsInteger(const AValue: Integer);
  1078. begin
  1079. ConvertError(False);
  1080. end;
  1081. procedure TJSONArray.SetAsInt64(const AValue: Int64);
  1082. begin
  1083. ConvertError(False);
  1084. end;
  1085. {$warnings on}
  1086. function TJSONArray.GetAsJSON: TJSONStringType;
  1087. Var
  1088. I : Integer;
  1089. begin
  1090. Result:='[';
  1091. For I:=0 to Count-1 do
  1092. begin
  1093. Result:=Result+Items[i].AsJSON;
  1094. If (I<Count-1) then
  1095. Result:=Result+', '
  1096. end;
  1097. Result:=Result+']';
  1098. end;
  1099. {$warnings off}
  1100. Function IndentString(Options : TFormatOptions; Indent : Integer) : TJSONStringType;
  1101. begin
  1102. If (foUseTabChar in Options) then
  1103. Result:=StringofChar(#9,Indent)
  1104. else
  1105. Result:=StringOfChar(' ',Indent);
  1106. end;
  1107. Function TJSONArray.DoFormatJSON(Options : TFormatOptions; CurrentIndent, Indent : Integer) : TJSONStringType;
  1108. Var
  1109. I : Integer;
  1110. begin
  1111. Result:='[';
  1112. if not (foSingleLineArray in Options) then
  1113. Result:=Result+sLineBreak;
  1114. For I:=0 to Count-1 do
  1115. begin
  1116. if not (foSingleLineArray in Options) then
  1117. Result:=Result+IndentString(Options, CurrentIndent+Indent);
  1118. Result:=Result+Items[i].DoFormatJSON(Options,CurrentIndent+Indent,Indent);
  1119. If (I<Count-1) then
  1120. if (foSingleLineArray in Options) then
  1121. Result:=Result+', '
  1122. else
  1123. Result:=Result+',';
  1124. if not (foSingleLineArray in Options) then
  1125. Result:=Result+sLineBreak
  1126. end;
  1127. if not (foSingleLineArray in Options) then
  1128. Result:=Result+IndentString(Options, CurrentIndent);
  1129. Result:=Result+']';
  1130. end;
  1131. function TJSONArray.GetAsString: TJSONStringType;
  1132. begin
  1133. ConvertError(True);
  1134. end;
  1135. procedure TJSONArray.SetAsString(const AValue: TJSONStringType);
  1136. begin
  1137. ConvertError(False);
  1138. end;
  1139. function TJSONArray.GetValue: variant;
  1140. begin
  1141. ConvertError(True);
  1142. end;
  1143. procedure TJSONArray.SetValue(const AValue: variant);
  1144. begin
  1145. ConvertError(False);
  1146. end;
  1147. {$warnings on}
  1148. function TJSONArray.GetCount: Integer;
  1149. begin
  1150. Result:=Flist.Count;
  1151. end;
  1152. function TJSONArray.GetItem(Index: Integer): TJSONData;
  1153. begin
  1154. Result:=FList[Index] as TJSONData;
  1155. end;
  1156. procedure TJSONArray.SetItem(Index: Integer; const AValue: TJSONData);
  1157. begin
  1158. If (Index=FList.Count) then
  1159. FList.Add(AValue)
  1160. else
  1161. FList[Index]:=AValue;
  1162. end;
  1163. constructor TJSONArray.Create;
  1164. begin
  1165. Flist:=TFPObjectList.Create(True);
  1166. end;
  1167. Function VarRecToJSON(Const Element : TVarRec; const SourceType : String) : TJSONData;
  1168. begin
  1169. Result:=Nil;
  1170. With Element do
  1171. case VType of
  1172. vtInteger : Result:=TJSONIntegerNumber.Create(VInteger);
  1173. vtBoolean : Result:=TJSONBoolean.Create(VBoolean);
  1174. vtChar : Result:=TJSONString.Create(VChar);
  1175. vtExtended : Result:=TJSONFloatNumber.Create(VExtended^);
  1176. vtString : Result:=TJSONString.Create(vString^);
  1177. vtAnsiString : Result:=TJSONString.Create(AnsiString(vAnsiString));
  1178. vtPChar : Result:=TJSONString.Create(StrPas(VPChar));
  1179. vtPointer : If (VPointer<>Nil) then
  1180. Raise EJSON.CreateFmt(SErrPointerNotNil,[SourceType])
  1181. else
  1182. Result:=TJSONNull.Create;
  1183. vtCurrency : Result:=TJSONFloatNumber.Create(vCurrency^);
  1184. vtInt64 : Result:=TJSONInt64Number.Create(vInt64^);
  1185. vtObject : if (VObject is TJSONData) then
  1186. Result:=TJSONData(VObject)
  1187. else
  1188. Raise EJSON.CreateFmt(SErrNotJSONData,[VObject.ClassName,SourceType]);
  1189. //vtVariant :
  1190. else
  1191. Raise EJSON.CreateFmt(SErrUnknownTypeInConstructor,[SourceType,VType])
  1192. end;
  1193. end;
  1194. constructor TJSONArray.Create(Const Elements: array of const);
  1195. Var
  1196. I : integer;
  1197. J : TJSONData;
  1198. begin
  1199. Create;
  1200. For I:=Low(Elements) to High(Elements) do
  1201. begin
  1202. J:=VarRecToJSON(Elements[i],'Array');
  1203. Add(J);
  1204. end;
  1205. end;
  1206. Destructor TJSONArray.Destroy;
  1207. begin
  1208. FreeAndNil(FList);
  1209. inherited Destroy;
  1210. end;
  1211. class function TJSONArray.JSONType: TJSONType;
  1212. begin
  1213. Result:=jtArray;
  1214. end;
  1215. function TJSONArray.Clone: TJSONData;
  1216. Var
  1217. A : TJSONArray;
  1218. I : Integer;
  1219. begin
  1220. A:=TJSONArray.Create;
  1221. try
  1222. For I:=0 to Count-1 do
  1223. A.Add(Self.Items[I].Clone);
  1224. Result:=A;
  1225. except
  1226. A.Free;
  1227. Raise;
  1228. end;
  1229. end;
  1230. procedure TJSONArray.Iterate(Iterator: TJSONArrayIterator; Data: TObject);
  1231. Var
  1232. I : Integer;
  1233. Cont : Boolean;
  1234. begin
  1235. I:=0;
  1236. Cont:=True;
  1237. While (I<FList.Count) and cont do
  1238. begin
  1239. Iterator(Items[i],Data,Cont);
  1240. Inc(I);
  1241. end;
  1242. end;
  1243. function TJSONArray.IndexOf(obj: TJSONData): Integer;
  1244. begin
  1245. Result:=FList.IndexOf(Obj);
  1246. end;
  1247. procedure TJSONArray.Clear;
  1248. begin
  1249. FList.Clear;
  1250. end;
  1251. function TJSONArray.Add(Item: TJSONData): Integer;
  1252. begin
  1253. Result:=FList.Add(Item);
  1254. end;
  1255. function TJSONArray.Add(I: Integer): Integer;
  1256. begin
  1257. Result:=Add(TJSONIntegerNumber.Create(I));
  1258. end;
  1259. function TJSONArray.Add(I: Int64): Int64;
  1260. begin
  1261. Result:=Add(TJSONInt64Number.Create(I));
  1262. end;
  1263. function TJSONArray.Add(const S: String): Integer;
  1264. begin
  1265. Result:=Add(TJSONString.Create(S));
  1266. end;
  1267. function TJSONArray.Add: Integer;
  1268. begin
  1269. Result:=Add(TJSONNull.Create);
  1270. end;
  1271. function TJSONArray.Add(F: TJSONFloat): Integer;
  1272. begin
  1273. Result:=Add(TJSONFloatNumber.Create(F));
  1274. end;
  1275. function TJSONArray.Add(B: Boolean): Integer;
  1276. begin
  1277. Result:=Add(TJSONBoolean.Create(B));
  1278. end;
  1279. function TJSONArray.Add(AnArray: TJSONArray): Integer;
  1280. begin
  1281. If (IndexOf(AnArray)<>-1) then
  1282. Raise EJSON.Create(SErrCannotAddArrayTwice);
  1283. Result:=Add(TJSONData(AnArray));
  1284. end;
  1285. function TJSONArray.Add(AnObject: TJSONObject): Integer;
  1286. begin
  1287. If (IndexOf(AnObject)<>-1) then
  1288. Raise EJSON.Create(SErrCannotAddObjectTwice);
  1289. Result:=Add(TJSONData(AnObject));
  1290. end;
  1291. procedure TJSONArray.Delete(Index: Integer);
  1292. begin
  1293. FList.Delete(Index);
  1294. end;
  1295. procedure TJSONArray.Exchange(Index1, Index2: Integer);
  1296. begin
  1297. FList.Exchange(Index1, Index2);
  1298. end;
  1299. procedure TJSONArray.Insert(Index: Integer);
  1300. begin
  1301. Insert(Index,TJSONNull.Create);
  1302. end;
  1303. procedure TJSONArray.Insert(Index: Integer; Item: TJSONData);
  1304. begin
  1305. FList.Insert(Index, Item);
  1306. end;
  1307. procedure TJSONArray.Insert(Index: Integer; I: Integer);
  1308. begin
  1309. FList.Insert(Index, TJSONIntegerNumber.Create(I));
  1310. end;
  1311. procedure TJSONArray.Insert(Index: Integer; I: Int64);
  1312. begin
  1313. FList.Insert(Index, TJSONInt64Number.Create(I));
  1314. end;
  1315. procedure TJSONArray.Insert(Index: Integer; const S: String);
  1316. begin
  1317. FList.Insert(Index, TJSONString.Create(S));
  1318. end;
  1319. procedure TJSONArray.Insert(Index: Integer; F: TJSONFloat);
  1320. begin
  1321. FList.Insert(Index, TJSONFloatNumber.Create(F));
  1322. end;
  1323. procedure TJSONArray.Insert(Index: Integer; B: Boolean);
  1324. begin
  1325. FList.Insert(Index, TJSONBoolean.Create(B));
  1326. end;
  1327. procedure TJSONArray.Insert(Index: Integer; AnArray: TJSONArray);
  1328. begin
  1329. if (IndexOf(AnArray)<>-1) then
  1330. raise EJSON.Create(SErrCannotAddArrayTwice);
  1331. FList.Insert(Index, AnArray);
  1332. end;
  1333. procedure TJSONArray.Insert(Index: Integer; AnObject: TJSONObject);
  1334. begin
  1335. if (IndexOf(AnObject)<>-1) then
  1336. raise EJSON.Create(SErrCannotAddObjectTwice);
  1337. FList.Insert(Index, AnObject);
  1338. end;
  1339. procedure TJSONArray.Move(CurIndex, NewIndex: Integer);
  1340. begin
  1341. FList.Move(CurIndex, NewIndex);
  1342. end;
  1343. procedure TJSONArray.Remove(Item: TJSONData);
  1344. begin
  1345. FList.Remove(Item);
  1346. end;
  1347. { TJSONObject }
  1348. function TJSONObject.GetArrays(Const AName : String): TJSONArray;
  1349. begin
  1350. Result:=GetElements(AName) as TJSONArray;
  1351. end;
  1352. function TJSONObject.GetBooleans(Const AName : String): Boolean;
  1353. begin
  1354. Result:=GetElements(AName).AsBoolean;
  1355. end;
  1356. function TJSONObject.GetElements(Const AName: string): TJSONData;
  1357. begin
  1358. Result:=TJSONData(FHash.Find(AName));
  1359. If (Result=Nil) then
  1360. Raise EJSON.CreateFmt(SErrNonexistentElement,[AName]);
  1361. end;
  1362. function TJSONObject.GetFloats(Const AName : String): TJSONFloat;
  1363. begin
  1364. Result:=GetElements(AName).AsFloat;
  1365. end;
  1366. function TJSONObject.GetIntegers(Const AName : String): Integer;
  1367. begin
  1368. Result:=GetElements(AName).AsInteger;
  1369. end;
  1370. function TJSONObject.GetInt64s(Const AName : String): Int64;
  1371. begin
  1372. Result:=GetElements(AName).AsInt64;
  1373. end;
  1374. function TJSONObject.GetIsNull(Const AName : String): Boolean;
  1375. begin
  1376. Result:=GetElements(AName).IsNull;
  1377. end;
  1378. function TJSONObject.GetNameOf(Index: Integer): TJSONStringType;
  1379. begin
  1380. Result:=FHash.NameOfIndex(Index);
  1381. end;
  1382. function TJSONObject.GetObjects(const AName : String): TJSONObject;
  1383. begin
  1384. Result:=GetElements(AName) as TJSONObject;
  1385. end;
  1386. function TJSONObject.GetStrings(const AName : String): TJSONStringType;
  1387. begin
  1388. Result:=GetElements(AName).AsString;
  1389. end;
  1390. function TJSONObject.GetTypes(const AName : String): TJSONType;
  1391. begin
  1392. Result:=Getelements(Aname).JSONType;
  1393. end;
  1394. procedure TJSONObject.SetArrays(const AName : String; const AValue: TJSONArray);
  1395. begin
  1396. SetElements(AName,AVAlue);
  1397. end;
  1398. procedure TJSONObject.SetBooleans(const AName : String; const AValue: Boolean);
  1399. begin
  1400. SetElements(AName,TJSONBoolean.Create(AVAlue));
  1401. end;
  1402. procedure TJSONObject.SetElements(const AName: string; const AValue: TJSONData);
  1403. Var
  1404. Index : Integer;
  1405. begin
  1406. Index:=FHash.FindIndexOf(AName);
  1407. If (Index=-1) then
  1408. FHash.Add(AName,AValue)
  1409. else
  1410. FHash.Items[Index]:=AValue; // Will free the previous value.
  1411. end;
  1412. procedure TJSONObject.SetFloats(const AName : String; const AValue: TJSONFloat);
  1413. begin
  1414. SetElements(AName,TJSONFloatNumber.Create(AVAlue));
  1415. end;
  1416. procedure TJSONObject.SetIntegers(const AName : String; const AValue: Integer);
  1417. begin
  1418. SetElements(AName,TJSONIntegerNumber.Create(AVAlue));
  1419. end;
  1420. procedure TJSONObject.SetInt64s(const AName : String; const AValue: Int64);
  1421. begin
  1422. SetElements(AName,TJSONInt64Number.Create(AVAlue));
  1423. end;
  1424. procedure TJSONObject.SetIsNull(const AName : String; const AValue: Boolean);
  1425. begin
  1426. If Not AValue then
  1427. Raise EJSON.Create(SErrCannotSetNotIsNull);
  1428. SetElements(AName,TJSONNull.Create);
  1429. end;
  1430. procedure TJSONObject.SetObjects(const AName : String; const AValue: TJSONObject);
  1431. begin
  1432. SetElements(AName,AValue);
  1433. end;
  1434. procedure TJSONObject.SetStrings(const AName : String; const AValue: TJSONStringType);
  1435. begin
  1436. SetElements(AName,TJSONString.Create(AVAlue));
  1437. end;
  1438. procedure TJSONObject.Converterror(From: Boolean);
  1439. begin
  1440. If From then
  1441. Raise EJSON.Create(SErrCannotConvertFromObject)
  1442. else
  1443. Raise EJSON.Create(SErrCannotConvertToObject);
  1444. end;
  1445. {$warnings off}
  1446. function TJSONObject.GetAsBoolean: Boolean;
  1447. begin
  1448. ConvertError(True);
  1449. end;
  1450. function TJSONObject.GetAsFloat: TJSONFloat;
  1451. begin
  1452. ConvertError(True);
  1453. end;
  1454. function TJSONObject.GetAsInteger: Integer;
  1455. begin
  1456. ConvertError(True);
  1457. end;
  1458. function TJSONObject.GetAsInt64: Int64;
  1459. begin
  1460. ConvertError(True);
  1461. end;
  1462. procedure TJSONObject.SetAsBoolean(const AValue: Boolean);
  1463. begin
  1464. ConvertError(False);
  1465. end;
  1466. procedure TJSONObject.SetAsFloat(const AValue: TJSONFloat);
  1467. begin
  1468. ConvertError(False);
  1469. end;
  1470. procedure TJSONObject.SetAsInteger(const AValue: Integer);
  1471. begin
  1472. ConvertError(False);
  1473. end;
  1474. procedure TJSONObject.SetAsInt64(const AValue: Int64);
  1475. begin
  1476. ConvertError(False);
  1477. end;
  1478. {$warnings on}
  1479. function TJSONObject.GetAsJSON: TJSONStringType;
  1480. Var
  1481. I : Integer;
  1482. begin
  1483. Result:='';
  1484. For I:=0 to Count-1 do
  1485. begin
  1486. If (Result<>'') then
  1487. Result:=Result+', ';
  1488. Result:=Result+'"'+StringToJSONString(Names[i])+'" : '+Items[I].AsJSON;
  1489. end;
  1490. If (Result<>'') then
  1491. Result:='{ '+Result+' }'
  1492. else
  1493. Result:='{}';
  1494. end;
  1495. {$warnings off}
  1496. function TJSONObject.GetAsString: TJSONStringType;
  1497. begin
  1498. ConvertError(True);
  1499. end;
  1500. procedure TJSONObject.SetAsString(const AValue: TJSONStringType);
  1501. begin
  1502. ConvertError(False);
  1503. end;
  1504. function TJSONObject.GetValue: variant;
  1505. begin
  1506. ConvertError(True);
  1507. end;
  1508. procedure TJSONObject.SetValue(const AValue: variant);
  1509. begin
  1510. ConvertError(False);
  1511. end;
  1512. {$warnings on}
  1513. function TJSONObject.GetCount: Integer;
  1514. begin
  1515. Result:=FHash.Count;
  1516. end;
  1517. function TJSONObject.GetItem(Index: Integer): TJSONData;
  1518. begin
  1519. Result:=TJSONData(FHash.Items[Index]);
  1520. end;
  1521. procedure TJSONObject.SetItem(Index: Integer; const AValue: TJSONData);
  1522. begin
  1523. FHash.Items[Index]:=AValue;
  1524. end;
  1525. constructor TJSONObject.Create;
  1526. begin
  1527. FHash:=TFPHashObjectList.Create(True);
  1528. end;
  1529. constructor TJSONObject.Create(const Elements: array of const);
  1530. Var
  1531. I : integer;
  1532. AName : String;
  1533. J : TJSONData;
  1534. begin
  1535. Create;
  1536. If ((High(Elements)-Low(Elements)) mod 2)=0 then
  1537. Raise EJSON.Create(SErrOddNumber);
  1538. I:=Low(Elements);
  1539. While I<=High(Elements) do
  1540. begin
  1541. With Elements[i] do
  1542. Case VType of
  1543. vtChar : AName:=VChar;
  1544. vtString : AName:=vString^;
  1545. vtAnsiString : AName:=(AnsiString(vAnsiString));
  1546. vtPChar : AName:=StrPas(VPChar);
  1547. else
  1548. Raise EJSON.CreateFmt(SErrNameMustBeString,[I+1]);
  1549. end;
  1550. If (ANAme='') then
  1551. Raise EJSON.CreateFmt(SErrNameMustBeString,[I+1]);
  1552. Inc(I);
  1553. J:=VarRecToJSON(Elements[i],'Object');
  1554. Add(AName,J);
  1555. Inc(I);
  1556. end;
  1557. end;
  1558. destructor TJSONObject.Destroy;
  1559. begin
  1560. FreeAndNil(FHash);
  1561. inherited Destroy;
  1562. end;
  1563. class function TJSONObject.JSONType: TJSONType;
  1564. begin
  1565. Result:=jtObject;
  1566. end;
  1567. function TJSONObject.Clone: TJSONData;
  1568. Var
  1569. O : TJSONObject;
  1570. I: Integer;
  1571. begin
  1572. O:=TJSONObject.Create;
  1573. try
  1574. For I:=0 to Count-1 do
  1575. O.Add(Self.Names[I],Self.Items[I].Clone);
  1576. Result:=O;
  1577. except
  1578. FreeAndNil(O);
  1579. Raise;
  1580. end;
  1581. end;
  1582. Function TJSONObject.DoFormatJSON(Options : TFormatOptions; CurrentIndent, Indent : Integer) : TJSONStringType;
  1583. Var
  1584. i : Integer;
  1585. S : TJSONStringType;
  1586. begin
  1587. CurrentIndent:=CurrentIndent+Indent;
  1588. For I:=0 to Count-1 do
  1589. begin
  1590. If (Result<>'') then
  1591. begin
  1592. If (foSingleLineObject in Options) then
  1593. Result:=Result+', '
  1594. else
  1595. Result:=Result+','+SLineBreak;
  1596. end;
  1597. If not (foSingleLineObject in Options) then
  1598. Result:=Result+IndentString(Options,CurrentIndent);
  1599. S:=StringToJSONString(Names[i]);
  1600. If not (foDoNotQuoteMembers in options) then
  1601. S:='"'+S+'"';
  1602. Result:=Result+S+' : '+Items[I].DoFormatJSON(Options,CurrentIndent,Indent);
  1603. end;
  1604. If (Result<>'') then
  1605. begin
  1606. if (foSingleLineObject in Options) then
  1607. Result:='{ '+Result+' }'
  1608. else
  1609. Result:='{'+sLineBreak+Result+sLineBreak+indentString(options,CurrentIndent-Indent)+'}'
  1610. end
  1611. else
  1612. Result:='{}';
  1613. end;
  1614. procedure TJSONObject.Iterate(Iterator: TJSONObjectIterator; Data: TObject);
  1615. Var
  1616. I : Integer;
  1617. Cont : Boolean;
  1618. begin
  1619. I:=0;
  1620. Cont:=True;
  1621. While (I<FHash.Count) and cont do
  1622. begin
  1623. Iterator(Names[I],Items[i],Data,Cont);
  1624. Inc(I);
  1625. end;
  1626. end;
  1627. function TJSONObject.IndexOf(Item: TJSONData): Integer;
  1628. begin
  1629. Result:=FHash.IndexOf(Item);
  1630. end;
  1631. function TJSONObject.IndexOfName(const AName: TJSONStringType; CaseInsensitive : Boolean = False): Integer;
  1632. begin
  1633. Result:=FHash.FindIndexOf(AName);
  1634. if (Result=-1) and CaseInsensitive then
  1635. begin
  1636. Result:=Count-1;
  1637. While (Result>=0) and (CompareText(Names[Result],AName)<>0) do
  1638. Dec(Result);
  1639. end;
  1640. end;
  1641. procedure TJSONObject.Clear;
  1642. begin
  1643. FHash.Clear;
  1644. end;
  1645. function TJSONObject.Add(const AName: TJSONStringType; AValue: TJSONData
  1646. ): Integer;
  1647. begin
  1648. Result:=FHash.Add(AName,AValue);
  1649. end;
  1650. function TJSONObject.Add(const AName: TJSONStringType; AValue: Boolean
  1651. ): Integer;
  1652. begin
  1653. Result:=Add(AName,TJSONBoolean.Create(AValue));
  1654. end;
  1655. function TJSONObject.Add(const AName: TJSONStringType; AValue: TJSONFloat): Integer;
  1656. begin
  1657. Result:=Add(AName,TJSONFloatNumber.Create(AValue));
  1658. end;
  1659. function TJSONObject.Add(const AName, AValue: TJSONStringType): Integer;
  1660. begin
  1661. Result:=Add(AName,TJSONString.Create(AValue));
  1662. end;
  1663. function TJSONObject.Add(const AName: TJSONStringType; Avalue: Integer): Integer;
  1664. begin
  1665. Result:=Add(AName,TJSONIntegerNumber.Create(AValue));
  1666. end;
  1667. function TJSONObject.Add(const AName: TJSONStringType; Avalue: Int64): Integer;
  1668. begin
  1669. Result:=Add(AName,TJSONInt64Number.Create(AValue));
  1670. end;
  1671. function TJSONObject.Add(const AName: TJSONStringType): Integer;
  1672. begin
  1673. Result:=Add(AName,TJSONNull.Create);
  1674. end;
  1675. function TJSONObject.Add(const AName: TJSONStringType; AValue: TJSONArray
  1676. ): Integer;
  1677. begin
  1678. Result:=Add(AName,TJSONData(AValue));
  1679. end;
  1680. procedure TJSONObject.Delete(Index: Integer);
  1681. begin
  1682. FHash.Delete(Index);
  1683. end;
  1684. procedure TJSONObject.Delete(Const AName: string);
  1685. Var
  1686. I : Integer;
  1687. begin
  1688. I:=IndexOfName(AName);
  1689. if (I<>-1) then
  1690. Delete(I);
  1691. end;
  1692. procedure TJSONObject.Remove(Item: TJSONData);
  1693. begin
  1694. FHash.Remove(Item);
  1695. end;
  1696. function TJSONObject.Extract(Index: Integer): TJSONData;
  1697. begin
  1698. Result:=Items[Index];
  1699. FHash.Extract(Result);
  1700. end;
  1701. function TJSONObject.Extract(const AName: string): TJSONData;
  1702. Var
  1703. I : Integer;
  1704. begin
  1705. I:=IndexOfName(AName);
  1706. if (I<>-1) then
  1707. Result:=Extract(I)
  1708. else
  1709. Result:=Nil
  1710. end;
  1711. function TJSONObject.Get(const AName: String): Variant;
  1712. Var
  1713. I : Integer;
  1714. begin
  1715. I:=IndexOfName(AName);
  1716. If (I<>-1) then
  1717. Result:=Items[i].Value
  1718. else
  1719. Result:=Null;
  1720. end;
  1721. function TJSONObject.Get(const AName: String; ADefault: TJSONFloat
  1722. ): TJSONFloat;
  1723. Var
  1724. D : TJSONData;
  1725. begin
  1726. D:=Find(AName,jtNumber);
  1727. If D<>Nil then
  1728. Result:=D.AsFloat
  1729. else
  1730. Result:=ADefault;
  1731. end;
  1732. function TJSONObject.Get(const AName: String; ADefault: Integer
  1733. ): Integer;
  1734. Var
  1735. D : TJSONData;
  1736. begin
  1737. D:=Find(AName,jtNumber);
  1738. If D<>Nil then
  1739. Result:=D.AsInteger
  1740. else
  1741. Result:=ADefault;
  1742. end;
  1743. function TJSONObject.Get(const AName: String; ADefault: Int64): Int64;
  1744. Var
  1745. D : TJSONData;
  1746. begin
  1747. D:=Find(AName,jtNumber);
  1748. If D<>Nil then
  1749. Result:=D.AsInt64
  1750. else
  1751. Result:=ADefault;
  1752. end;
  1753. function TJSONObject.Get(const AName: String; ADefault: Boolean
  1754. ): Boolean;
  1755. Var
  1756. D : TJSONData;
  1757. begin
  1758. D:=Find(AName,jtBoolean);
  1759. If D<>Nil then
  1760. Result:=D.AsBoolean
  1761. else
  1762. Result:=ADefault;
  1763. end;
  1764. function TJSONObject.Get(const AName: String; ADefault: TJSONStringType
  1765. ): TJSONStringType;
  1766. Var
  1767. D : TJSONData;
  1768. begin
  1769. D:=Find(AName,jtString);
  1770. If (D<>Nil) then
  1771. Result:=D.AsString
  1772. else
  1773. Result:=ADefault;
  1774. end;
  1775. function TJSONObject.Get(const AName: String; ADefault: TJSONArray
  1776. ): TJSONArray;
  1777. Var
  1778. D : TJSONData;
  1779. begin
  1780. D:=Find(AName,jtArray);
  1781. If (D<>Nil) then
  1782. Result:=TJSONArray(D)
  1783. else
  1784. Result:=ADefault;
  1785. end;
  1786. function TJSONObject.Get(const AName: String; ADefault: TJSONObject
  1787. ): TJSONObject;
  1788. Var
  1789. D : TJSONData;
  1790. begin
  1791. D:=Find(AName,jtObject);
  1792. If (D<>Nil) then
  1793. Result:=TJSONObject(D)
  1794. else
  1795. Result:=ADefault;
  1796. end;
  1797. function TJSONObject.Find(const AName: String): TJSONData;
  1798. Var
  1799. I : Integer;
  1800. begin
  1801. I:=IndexOfName(AName);
  1802. If (I<>-1) then
  1803. Result:=Items[i]
  1804. else
  1805. Result:=Nil;
  1806. end;
  1807. function TJSONObject.Find(const AName: String; AType: TJSONType): TJSONData;
  1808. begin
  1809. Result:=Find(AName);
  1810. If Assigned(Result) and (Result.JSONType<>AType) then
  1811. Result:=Nil;
  1812. end;
  1813. end.