1. (*
  2. * Super Object Toolkit
  3. *
  4. * Usage allowed under the restrictions of the Lesser GNU General Public License
  5. * or alternatively the restrictions of the Mozilla Public License 1.1
  6. *
  7. * Software distributed under the License is distributed on an "AS IS" basis,
  8. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
  9. * the specific language governing rights and limitations under the License.
  10. *
  11. * Unit owner : Henri Gourvest <hgourvest@gmail.com>
  12. * Web site : http://www.progdigy.com
  13. *
  14. * This unit is inspired from the json c lib:
  15. * Michael Clark <michael@metaparadigm.com>
  16. * http://oss.metaparadigm.com/json-c/
  17. *
  18. * CHANGES:
  19. * v1.2
  20. * + support of currency data type
  21. * + right trim unquoted string
  22. * + read Unicode Files and streams (Litle Endian with BOM)
  23. * + Fix bug on javadate functions + windows nt compatibility
  24. * + Now you can force to parse only the canonical syntax of JSON using the stric parameter
  25. * + Delphi 2010 RTTI marshalling
  26. * v1.1
  27. * + Double licence MPL or LGPL.
  28. * + Delphi 2009 compatibility & Unicode support.
  29. * + AsString return a string instead of PChar.
  30. * + Escaped and Unascaped JSON serialiser.
  31. * + Missed FormFeed added \f
  32. * - Removed @ trick, uses forcepath() method instead.
  33. * + Fixed parse error with uppercase E symbol in numbers.
  34. * + Fixed possible buffer overflow when enlarging array.
  35. * + Added "delete", "pack", "insert" methods for arrays and/or objects
  36. * + Multi parametters when calling methods
  37. * + Delphi Enumerator (for obj1 in obj2 do ...)
  38. * + Format method ex: obj.format('<%name%>%tab[1]%</%name%>')
  39. * + ParseFile and ParseStream methods
  40. * + Parser now understand hexdecimal c syntax ex: \xFF
  41. * + Null Object Design Patern (ex: for obj in values.N['path'] do ...)
  42. * v1.0
  43. * + renamed class
  44. * + interfaced object
  45. * + added a new data type: the method
  46. * + parser can now evaluate properties and call methods
  47. * - removed obselet rpc class
  48. * - removed "find" method, now you can use "parse" method instead
  49. * v0.6
  50. * + refactoring
  51. * v0.5
  52. * + new find method to get or set value using a path syntax
  53. * ex: obj.s['obj.prop[1]'] := 'string value';
  54. * obj.a['@obj.array'].b[n] := true; // @ -> create property if necessary
  55. * v0.4
  56. * + bug corrected: AVL tree badly balanced.
  57. * v0.3
  58. * + New validator partially based on the Kwalify syntax.
  59. * + extended syntax to parse unquoted fields.
  60. * + Freepascal compatibility win32/64 Linux32/64.
  61. * + JavaToDelphiDateTime and DelphiToJavaDateTime improved for UTC.
  62. * + new TJsonObject.Compare function.
  63. * v0.2
  64. * + Hashed string list replaced with a faster AVL tree
  65. * + JsonInt data type can be changed to int64
  66. * + JavaToDelphiDateTime and DelphiToJavaDateTime helper fonctions
  67. * + from json-c v0.7
  68. * + Add escaping of backslash to json output
  69. * + Add escaping of foward slash on tokenizing and output
  70. * + Changes to internal tokenizer from using recursion to
  71. * using a depth state structure to allow incremental parsing
  72. * v0.1
  73. * + first release
  74. *)
  75.  
  76. {$IFDEF FPC}
  77. {$MODE OBJFPC}{$H+}
  78. {$ENDIF}
  79.  
  80. {$DEFINE SUPER_METHOD}
  81. {$DEFINE WINDOWSNT_COMPATIBILITY}
  82. {$DEFINE DEBUG} // track memory leack
  83.  
  84. unit superobject;
  85.  
  86. interface
  87. uses
  88. Classes
  89. {$IFDEF VER210}
  90. ,Generics.Collections, RTTI, TypInfo
  91. {$ENDIF}
  92. ;
  93.  
  94. type
  95. {$IFNDEF FPC}
  96. PtrInt = longint;
  97. PtrUInt = Longword;
  98. {$ENDIF}
  99. SuperInt = Int64;
  100.  
  101. {$if (sizeof(Char) = 1)}
  102. SOChar = WideChar;
  103. SOIChar = Word;
  104. PSOChar = PWideChar;
  105. SOString = WideString;
  106. {$else}
  107. SOChar = Char;
  108. SOIChar = Word;
  109. PSOChar = PChar;
  110. SOString = string;
  111. {$ifend}
  112.  
  113. const
  114. SUPER_ARRAY_LIST_DEFAULT_SIZE = ;
  115. SUPER_TOKENER_MAX_DEPTH = ;
  116.  
  117. SUPER_AVL_MAX_DEPTH = sizeof(longint) * ;
  118. SUPER_AVL_MASK_HIGH_BIT = not ((not longword()) shr );
  119.  
  120. type
  121. // forward declarations
  122. TSuperObject = class;
  123. ISuperObject = interface;
  124. TSuperArray = class;
  125.  
  126. // 2016.01.01 添加了排序方式
  127. TSOSortMode = (sosmDefault {默认的方式}, sosmAdd {添加的顺序}, sosmASC {升序}, sosmDesc {降序});
  128.  
  129. (* AVL Tree
  130. * This is a "special" autobalanced AVL tree
  131. * It use a hash value for fast compare
  132. *)
  133.  
  134. {$IFDEF SUPER_METHOD}
  135. TSuperMethod = procedure(const This, Params: ISuperObject; var Result: ISuperObject);
  136. {$ENDIF}
  137.  
  138. TSuperAvlBitArray = set of ..SUPER_AVL_MAX_DEPTH - ;
  139.  
  140. TSuperAvlSearchType = (stEQual, stLess, stGreater);
  141. TSuperAvlSearchTypes = set of TSuperAvlSearchType;
  142. TSuperAvlIterator = class;
  143.  
  144. TSuperAvlEntry = class
  145. private
  146. FGt, FLt: TSuperAvlEntry;
  147. FBf: integer;
  148. FHash: Cardinal;
  149. FName: SOString;
  150. FPtr: Pointer;
  151. function GetValue: ISuperObject;
  152. procedure SetValue(const val: ISuperObject);
  153. public
  154. class function Hash(const k: SOString): Cardinal; virtual;
  155. constructor Create(const AName: SOString; Obj: Pointer); virtual;
  156. property Name: SOString read FName;
  157. property Ptr: Pointer read FPtr;
  158. property Value: ISuperObject read GetValue write SetValue;
  159. end;
  160.  
  161. TSuperAvlTree = class
  162. private
  163. FRoot: TSuperAvlEntry;
  164. FCount: Integer;
  165. function balance(bal: TSuperAvlEntry): TSuperAvlEntry;
  166. protected
  167. procedure doDeleteEntry(Entry: TSuperAvlEntry; all: boolean); virtual;
  168. function CompareNodeNode(node1, node2: TSuperAvlEntry): integer; virtual;
  169. function CompareKeyNode(const k: SOString; h: TSuperAvlEntry): integer; virtual;
  170. function Insert(h: TSuperAvlEntry): TSuperAvlEntry; virtual;
  171. function Search(const k: SOString; st: TSuperAvlSearchTypes = [stEqual]): TSuperAvlEntry; virtual;
  172. public
  173. constructor Create; virtual;
  174. destructor Destroy; override;
  175. function IsEmpty: boolean;
  176. procedure Clear(all: boolean = false); virtual;
  177. procedure Pack(all: boolean);
  178. function Delete(const k: SOString): ISuperObject;
  179. function GetEnumerator: TSuperAvlIterator;
  180.  
  181. // 2016.01.01 排序功能使用
  182. function CompareForSortModeString(pvKey1, pvKey2: SOString): Integer;
  183.  
  184. property count: Integer read FCount;
  185. end;
  186.  
  187. TSuperTableString = class(TSuperAvlTree)
  188. protected
  189. procedure doDeleteEntry(Entry: TSuperAvlEntry; all: boolean); override;
  190. procedure PutO(const k: SOString; const value: ISuperObject);
  191. function GetO(const k: SOString): ISuperObject;
  192. procedure PutS(const k: SOString; const value: SOString);
  193. function GetS(const k: SOString): SOString;
  194. procedure PutI(const k: SOString; value: SuperInt);
  195. function GetI(const k: SOString): SuperInt;
  196. procedure PutD(const k: SOString; value: Double);
  197. function GetD(const k: SOString): Double;
  198. procedure PutB(const k: SOString; value: Boolean);
  199. function GetB(const k: SOString): Boolean;
  200. {$IFDEF SUPER_METHOD}
  201. procedure PutM(const k: SOString; value: TSuperMethod);
  202. function GetM(const k: SOString): TSuperMethod;
  203. {$ENDIF}
  204. procedure PutN(const k: SOString; const value: ISuperObject);
  205. function GetN(const k: SOString): ISuperObject;
  206. procedure PutC(const k: SOString; value: Currency);
  207. function GetC(const k: SOString): Currency;
  208. public
  209. property O[const k: SOString]: ISuperObject read GetO write PutO; default;
  210. property S[const k: SOString]: SOString read GetS write PutS;
  211. property I[const k: SOString]: SuperInt read GetI write PutI;
  212. property D[const k: SOString]: Double read GetD write PutD;
  213. property B[const k: SOString]: Boolean read GetB write PutB;
  214. {$IFDEF SUPER_METHOD}
  215. property M[const k: SOString]: TSuperMethod read GetM write PutM;
  216. {$ENDIF}
  217. property N[const k: SOString]: ISuperObject read GetN write PutN;
  218. property C[const k: SOString]: Currency read GetC write PutC;
  219.  
  220. function GetValues: ISuperObject;
  221. function GetNames: ISuperObject;
  222. end;
  223.  
  224. TSuperAvlIterator = class
  225. private
  226. FTree: TSuperAvlTree;
  227. FBranch: TSuperAvlBitArray;
  228. FDepth: LongInt;
  229. FPath: array[..SUPER_AVL_MAX_DEPTH - ] of TSuperAvlEntry;
  230. public
  231. constructor Create(tree: TSuperAvlTree); virtual;
  232. procedure Search(const k: SOString; st: TSuperAvlSearchTypes = [stEQual]);
  233. procedure First;
  234. procedure Last;
  235. function GetIter: TSuperAvlEntry;
  236. procedure Next;
  237. procedure Prior;
  238. // delphi enumerator
  239. function MoveNext: Boolean;
  240. property Current: TSuperAvlEntry read GetIter;
  241. end;
  242.  
  243. TSuperObjectArray = array[..(high(PtrInt) div sizeof(TSuperObject))-] of ISuperObject;
  244. PSuperObjectArray = ^TSuperObjectArray;
  245.  
  246. TSuperArray = class
  247. private
  248. FArray: PSuperObjectArray;
  249. FLength: Integer;
  250. FSize: Integer;
  251. procedure Expand(max: Integer);
  252. protected
  253. function GetO(const index: integer): ISuperObject;
  254. procedure PutO(const index: integer; const Value: ISuperObject);
  255. function GetB(const index: integer): Boolean;
  256. procedure PutB(const index: integer; Value: Boolean);
  257. function GetI(const index: integer): SuperInt;
  258. procedure PutI(const index: integer; Value: SuperInt);
  259. function GetD(const index: integer): Double;
  260. procedure PutD(const index: integer; Value: Double);
  261. function GetC(const index: integer): Currency;
  262. procedure PutC(const index: integer; Value: Currency);
  263. function GetS(const index: integer): SOString;
  264. procedure PutS(const index: integer; const Value: SOString);
  265. {$IFDEF SUPER_METHOD}
  266. function GetM(const index: integer): TSuperMethod;
  267. procedure PutM(const index: integer; Value: TSuperMethod);
  268. {$ENDIF}
  269. function GetN(const index: integer): ISuperObject;
  270. procedure PutN(const index: integer; const Value: ISuperObject);
  271. public
  272. constructor Create; virtual;
  273. destructor Destroy; override;
  274. function Add(const Data: ISuperObject): Integer;
  275. function Delete(index: Integer): ISuperObject;
  276. procedure Insert(index: Integer; const value: ISuperObject);
  277. procedure Clear(all: boolean = false);
  278. procedure Pack(all: boolean);
  279. property Length: Integer read FLength;
  280.  
  281. property N[const index: integer]: ISuperObject read GetN write PutN;
  282. property O[const index: integer]: ISuperObject read GetO write PutO; default;
  283. property B[const index: integer]: boolean read GetB write PutB;
  284. property I[const index: integer]: SuperInt read GetI write PutI;
  285. property D[const index: integer]: Double read GetD write PutD;
  286. property C[const index: integer]: Currency read GetC write PutC;
  287. property S[const index: integer]: SOString read GetS write PutS;
  288. {$IFDEF SUPER_METHOD}
  289. property M[const index: integer]: TSuperMethod read GetM write PutM;
  290. {$ENDIF}
  291. // property A[const index: integer]: TSuperArray read GetA;
  292. end;
  293.  
  294. TSuperWriter = class
  295. public
  296. // abstact methods to overide
  297. function Append(buf: PSOChar; Size: Integer): Integer; overload; virtual; abstract;
  298. function Append(buf: PSOChar): Integer; overload; virtual; abstract;
  299. procedure Reset; virtual; abstract;
  300. end;
  301.  
  302. TSuperWriterString = class(TSuperWriter)
  303. private
  304. FBuf: PSOChar;
  305. FBPos: integer;
  306. FSize: integer;
  307. public
  308. function Append(buf: PSOChar; Size: Integer): Integer; overload; override;
  309. function Append(buf: PSOChar): Integer; overload; override;
  310. procedure Reset; override;
  311. procedure TrimRight;
  312. constructor Create; virtual;
  313. destructor Destroy; override;
  314. function GetString: SOString;
  315. property Data: PSOChar read FBuf;
  316. property Size: Integer read FSize;
  317. property Position: integer read FBPos;
  318. end;
  319.  
  320. TSuperWriterStream = class(TSuperWriter)
  321. private
  322. FStream: TStream;
  323. public
  324. function Append(buf: PSOChar): Integer; override;
  325. procedure Reset; override;
  326. constructor Create(AStream: TStream); reintroduce; virtual;
  327. end;
  328.  
  329. TSuperAnsiWriterStream = class(TSuperWriterStream)
  330. public
  331. function Append(buf: PSOChar; Size: Integer): Integer; override;
  332. end;
  333.  
  334. TSuperUnicodeWriterStream = class(TSuperWriterStream)
  335. public
  336. function Append(buf: PSOChar; Size: Integer): Integer; override;
  337. end;
  338.  
  339. TSuperWriterFake = class(TSuperWriter)
  340. private
  341. FSize: Integer;
  342. public
  343. function Append(buf: PSOChar; Size: Integer): Integer; override;
  344. function Append(buf: PSOChar): Integer; override;
  345. procedure Reset; override;
  346. constructor Create; reintroduce; virtual;
  347. property size: integer read FSize;
  348. end;
  349.  
  350. TSuperWriterSock = class(TSuperWriter)
  351. private
  352. FSocket: longint;
  353. FSize: Integer;
  354. public
  355. function Append(buf: PSOChar; Size: Integer): Integer; override;
  356. function Append(buf: PSOChar): Integer; override;
  357. procedure Reset; override;
  358. constructor Create(ASocket: longint); reintroduce; virtual;
  359. property Socket: longint read FSocket;
  360. property Size: Integer read FSize;
  361. end;
  362.  
  363. TSuperTokenizerError = (
  364. teSuccess,
  365. teContinue,
  366. teDepth,
  367. teParseEof,
  368. teParseUnexpected,
  369. teParseNull,
  370. teParseBoolean,
  371. teParseNumber,
  372. teParseArray,
  373. teParseObjectKeyName,
  374. teParseObjectKeySep,
  375. teParseObjectValueSep,
  376. teParseString,
  377. teParseComment,
  378. teEvalObject,
  379. teEvalArray,
  380. teEvalMethod,
  381. teEvalInt
  382. );
  383.  
  384. TSuperTokenerState = (
  385. tsEatws,
  386. tsStart,
  387. tsFinish,
  388. tsNull,
  389. tsCommentStart,
  390. tsComment,
  391. tsCommentEol,
  392. tsCommentEnd,
  393. tsString,
  394. tsStringEscape,
  395. tsIdentifier,
  396. tsEscapeUnicode,
  397. tsEscapeHexadecimal,
  398. tsBoolean,
  399. tsNumber,
  400. tsArray,
  401. tsArrayAdd,
  402. tsArraySep,
  403. tsObjectFieldStart,
  404. tsObjectField,
  405. tsObjectUnquotedField,
  406. tsObjectFieldEnd,
  407. tsObjectValue,
  408. tsObjectValueAdd,
  409. tsObjectSep,
  410. tsEvalProperty,
  411. tsEvalArray,
  412. tsEvalMethod,
  413. tsParamValue,
  414. tsParamPut,
  415. tsMethodValue,
  416. tsMethodPut
  417. );
  418.  
  419. PSuperTokenerSrec = ^TSuperTokenerSrec;
  420. TSuperTokenerSrec = record
  421. state, saved_state: TSuperTokenerState;
  422. obj: ISuperObject;
  423. current: ISuperObject;
  424. field_name: SOString;
  425. parent: ISuperObject;
  426. gparent: ISuperObject;
  427. end;
  428.  
  429. TSuperTokenizer = class
  430. public
  431. str: PSOChar;
  432. pb: TSuperWriterString;
  433. depth, is_double, floatcount, st_pos, char_offset: Integer;
  434. err: TSuperTokenizerError;
  435. ucs_char: Word;
  436. quote_char: SOChar;
  437. stack: array[..SUPER_TOKENER_MAX_DEPTH-] of TSuperTokenerSrec;
  438. line, col: Integer;
  439. public
  440. constructor Create; virtual;
  441. destructor Destroy; override;
  442. procedure ResetLevel(adepth: integer);
  443. procedure Reset;
  444. end;
  445.  
  446. // supported object types
  447. TSuperType = (
  448. stNull,
  449. stBoolean,
  450. stDouble,
  451. stCurrency,
  452. stInt,
  453. stObject,
  454. stArray,
  455. stString
  456. {$IFDEF SUPER_METHOD}
  457. ,stMethod
  458. {$ENDIF}
  459. );
  460.  
  461. TSuperValidateError = (
  462. veRuleMalformated,
  463. veFieldIsRequired,
  464. veInvalidDataType,
  465. veFieldNotFound,
  466. veUnexpectedField,
  467. veDuplicateEntry,
  468. veValueNotInEnum,
  469. veInvalidLength,
  470. veInvalidRange
  471. );
  472.  
  473. TSuperFindOption = (
  474. foCreatePath,
  475. foPutValue,
  476. foDelete
  477. {$IFDEF SUPER_METHOD}
  478. ,foCallMethod
  479. {$ENDIF}
  480. );
  481.  
  482. TSuperFindOptions = set of TSuperFindOption;
  483. TSuperCompareResult = (cpLess, cpEqu, cpGreat, cpError);
  484. TSuperOnValidateError = procedure(sender: Pointer; error: TSuperValidateError; const objpath: SOString);
  485.  
  486. TSuperEnumerator = class
  487. private
  488. FObj: ISuperObject;
  489. FObjEnum: TSuperAvlIterator;
  490. FCount: Integer;
  491. public
  492. constructor Create(const obj: ISuperObject); virtual;
  493. destructor Destroy; override;
  494. function MoveNext: Boolean;
  495. function GetCurrent: ISuperObject;
  496. property Current: ISuperObject read GetCurrent;
  497. end;
  498.  
  499. ISuperObject = interface
  500. ['{4B86A9E3-E094-4E5A-954A-69048B7B6327}']
  501. function GetEnumerator: TSuperEnumerator;
  502. function GetDataType: TSuperType;
  503. function GetProcessing: boolean;
  504. procedure SetProcessing(value: boolean);
  505. function ForcePath(const path: SOString; dataType: TSuperType = stObject): ISuperObject;
  506. function Format(const str: SOString; BeginSep: SOChar = '%'; EndSep: SOChar = '%'): SOString;
  507.  
  508. function GetO(const path: SOString): ISuperObject;
  509. procedure PutO(const path: SOString; const Value: ISuperObject);
  510. function GetB(const path: SOString): Boolean;
  511. procedure PutB(const path: SOString; Value: Boolean);
  512. function GetI(const path: SOString): SuperInt;
  513. procedure PutI(const path: SOString; Value: SuperInt);
  514. function GetD(const path: SOString): Double;
  515. procedure PutC(const path: SOString; Value: Currency);
  516. function GetC(const path: SOString): Currency;
  517. procedure PutD(const path: SOString; Value: Double);
  518. function GetS(const path: SOString): SOString;
  519. procedure PutS(const path: SOString; const Value: SOString);
  520. {$IFDEF SUPER_METHOD}
  521. function GetM(const path: SOString): TSuperMethod;
  522. procedure PutM(const path: SOString; Value: TSuperMethod);
  523. {$ENDIF}
  524. function GetA(const path: SOString): TSuperArray;
  525.  
  526. // Null Object Design patern
  527. function GetN(const path: SOString): ISuperObject;
  528. procedure PutN(const path: SOString; const Value: ISuperObject);
  529.  
  530. // Writers
  531. function Write(writer: TSuperWriter; indent: boolean; escape: boolean; level: integer): Integer;
  532. function SaveTo(stream: TStream; indent: boolean = false; escape: boolean = true): integer; overload;
  533. function SaveTo(const FileName: string; indent: boolean = false; escape: boolean = true): integer; overload;
  534. function SaveTo(socket: longint; indent: boolean = false; escape: boolean = true): integer; overload;
  535. function CalcSize(indent: boolean = false; escape: boolean = true): integer;
  536.  
  537. // convert
  538. function AsBoolean: Boolean;
  539. function AsInteger: SuperInt;
  540. function AsDouble: Double;
  541. function AsCurrency: Currency;
  542. function AsString: SOString;
  543. function AsArray: TSuperArray;
  544. function AsObject: TSuperTableString;
  545. {$IFDEF SUPER_METHOD}
  546. function AsMethod: TSuperMethod;
  547. {$ENDIF}
  548. function AsJSon(indent: boolean = false; escape: boolean = true): SOString;
  549.  
  550. procedure Clear(all: boolean = false);
  551. procedure Pack(all: boolean = false);
  552.  
  553. property N[const path: SOString]: ISuperObject read GetN write PutN;
  554. property O[const path: SOString]: ISuperObject read GetO write PutO; default;
  555. property B[const path: SOString]: boolean read GetB write PutB;
  556. property I[const path: SOString]: SuperInt read GetI write PutI;
  557. property D[const path: SOString]: Double read GetD write PutD;
  558. property C[const path: SOString]: Currency read GetC write PutC;
  559. property S[const path: SOString]: SOString read GetS write PutS;
  560. {$IFDEF SUPER_METHOD}
  561. property M[const path: SOString]: TSuperMethod read GetM write PutM;
  562. {$ENDIF}
  563. property A[const path: SOString]: TSuperArray read GetA;
  564.  
  565. {$IFDEF SUPER_METHOD}
  566. function call(const path: SOString; const param: ISuperObject = nil): ISuperObject; overload;
  567. function call(const path, param: SOString): ISuperObject; overload;
  568. {$ENDIF}
  569. // clone a node
  570. function Clone: ISuperObject;
  571. function Delete(const path: SOString): ISuperObject;
  572. // merges tow objects of same type, if reference is true then nodes are not cloned
  573. procedure Merge(const obj: ISuperObject; reference: boolean = false); overload;
  574. procedure Merge(const str: SOString); overload;
  575.  
  576. // validate methods
  577. function Validate(const rules: SOString; const defs: SOString = ''; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean; overload;
  578. function Validate(const rules: ISuperObject; const defs: ISuperObject = nil; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean; overload;
  579.  
  580. // compare
  581. function Compare(const obj: ISuperObject): TSuperCompareResult; overload;
  582. function Compare(const str: SOString): TSuperCompareResult; overload;
  583.  
  584. // the data type
  585. function IsType(AType: TSuperType): boolean;
  586. property DataType: TSuperType read GetDataType;
  587. property Processing: boolean read GetProcessing write SetProcessing;
  588.  
  589. function GetDataPtr: Pointer;
  590. procedure SetDataPtr(const Value: Pointer);
  591. property DataPtr: Pointer read GetDataPtr write SetDataPtr;
  592. end;
  593.  
  594. TSuperObject = class(TObject, ISuperObject)
  595. private
  596. FRefCount: Integer;
  597. FProcessing: boolean;
  598. FDataType: TSuperType;
  599. FDataPtr: Pointer;
  600. {.$if true}
  601. FO: record
  602. case TSuperType of
  603. stBoolean: (c_boolean: boolean);
  604. stDouble: (c_double: double);
  605. stCurrency: (c_currency: Currency);
  606. stInt: (c_int: SuperInt);
  607. stObject: (c_object: TSuperTableString);
  608. stArray: (c_array: TSuperArray);
  609. {$IFDEF SUPER_METHOD}
  610. stMethod: (c_method: TSuperMethod);
  611. {$ENDIF}
  612. end;
  613. {.$ifend}
  614. FOString: SOString;
  615. function GetDataType: TSuperType;
  616. function GetDataPtr: Pointer;
  617. procedure SetDataPtr(const Value: Pointer);
  618. protected
  619. function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall;
  620. function _AddRef: Integer; virtual; stdcall;
  621. function _Release: Integer; virtual; stdcall;
  622.  
  623. function GetO(const path: SOString): ISuperObject;
  624. procedure PutO(const path: SOString; const Value: ISuperObject);
  625. function GetB(const path: SOString): Boolean;
  626. procedure PutB(const path: SOString; Value: Boolean);
  627. function GetI(const path: SOString): SuperInt;
  628. procedure PutI(const path: SOString; Value: SuperInt);
  629. function GetD(const path: SOString): Double;
  630. procedure PutD(const path: SOString; Value: Double);
  631. procedure PutC(const path: SOString; Value: Currency);
  632. function GetC(const path: SOString): Currency;
  633. function GetS(const path: SOString): SOString;
  634. procedure PutS(const path: SOString; const Value: SOString);
  635. {$IFDEF SUPER_METHOD}
  636. function GetM(const path: SOString): TSuperMethod;
  637. procedure PutM(const path: SOString; Value: TSuperMethod);
  638. {$ENDIF}
  639. function GetA(const path: SOString): TSuperArray;
  640. function Write(writer: TSuperWriter; indent: boolean; escape: boolean; level: integer): Integer; virtual;
  641. public
  642. function GetEnumerator: TSuperEnumerator;
  643. procedure AfterConstruction; override;
  644. procedure BeforeDestruction; override;
  645. class function NewInstance: TObject; override;
  646. property RefCount: Integer read FRefCount;
  647.  
  648. function GetProcessing: boolean;
  649. procedure SetProcessing(value: boolean);
  650.  
  651. // Writers
  652. function SaveTo(stream: TStream; indent: boolean = false; escape: boolean = true): integer; overload;
  653. function SaveTo(const FileName: string; indent: boolean = false; escape: boolean = true): integer; overload;
  654. function SaveTo(socket: longint; indent: boolean = false; escape: boolean = true): integer; overload;
  655. function CalcSize(indent: boolean = false; escape: boolean = true): integer;
  656. function AsJSon(indent: boolean = false; escape: boolean = true): SOString;
  657.  
  658. // parser ... owned!
  659. class function ParseString(s: PSOChar; strict: Boolean; partial: boolean = true; const this: ISuperObject = nil; options: TSuperFindOptions = [];
  660. const put: ISuperObject = nil; dt: TSuperType = stNull): ISuperObject;
  661. class function ParseStream(stream: TStream; strict: Boolean; partial: boolean = true; const this: ISuperObject = nil; options: TSuperFindOptions = [];
  662. const put: ISuperObject = nil; dt: TSuperType = stNull): ISuperObject;
  663. class function ParseFile(const FileName: string; strict: Boolean; partial: boolean = true; const this: ISuperObject = nil; options: TSuperFindOptions = [];
  664. const put: ISuperObject = nil; dt: TSuperType = stNull): ISuperObject;
  665. class function ParseEx(tok: TSuperTokenizer; str: PSOChar; len: integer; strict: Boolean; const this: ISuperObject = nil;
  666. options: TSuperFindOptions = []; const put: ISuperObject = nil; dt: TSuperType = stNull): ISuperObject;
  667.  
  668. // constructors / destructor
  669. constructor Create(jt: TSuperType = stObject); overload; virtual;
  670. constructor Create(b: boolean); overload; virtual;
  671. constructor Create(i: SuperInt); overload; virtual;
  672. constructor Create(d: double); overload; virtual;
  673. constructor CreateCurrency(c: Currency); overload; virtual;
  674. constructor Create(const s: SOString); overload; virtual;
  675. {$IFDEF SUPER_METHOD}
  676. constructor Create(m: TSuperMethod); overload; virtual;
  677. {$ENDIF}
  678. destructor Destroy; override;
  679.  
  680. // convert
  681. function AsBoolean: Boolean; virtual;
  682. function AsInteger: SuperInt; virtual;
  683. function AsDouble: Double; virtual;
  684. function AsCurrency: Currency; virtual;
  685. function AsString: SOString; virtual;
  686. function AsArray: TSuperArray; virtual;
  687. function AsObject: TSuperTableString; virtual;
  688. {$IFDEF SUPER_METHOD}
  689. function AsMethod: TSuperMethod; virtual;
  690. {$ENDIF}
  691. procedure Clear(all: boolean = false); virtual;
  692. procedure Pack(all: boolean = false); virtual;
  693. function GetN(const path: SOString): ISuperObject;
  694. procedure PutN(const path: SOString; const Value: ISuperObject);
  695. function ForcePath(const path: SOString; dataType: TSuperType = stObject): ISuperObject;
  696. function Format(const str: SOString; BeginSep: SOChar = '%'; EndSep: SOChar = '%'): SOString;
  697.  
  698. property N[const path: SOString]: ISuperObject read GetN write PutN;
  699. property O[const path: SOString]: ISuperObject read GetO write PutO; default;
  700. property B[const path: SOString]: boolean read GetB write PutB;
  701. property I[const path: SOString]: SuperInt read GetI write PutI;
  702. property D[const path: SOString]: Double read GetD write PutD;
  703. property C[const path: SOString]: Currency read GetC write PutC;
  704. property S[const path: SOString]: SOString read GetS write PutS;
  705. {$IFDEF SUPER_METHOD}
  706. property M[const path: SOString]: TSuperMethod read GetM write PutM;
  707. {$ENDIF}
  708. property A[const path: SOString]: TSuperArray read GetA;
  709.  
  710. {$IFDEF SUPER_METHOD}
  711. function call(const path: SOString; const param: ISuperObject = nil): ISuperObject; overload; virtual;
  712. function call(const path, param: SOString): ISuperObject; overload; virtual;
  713. {$ENDIF}
  714. // clone a node
  715. function Clone: ISuperObject; virtual;
  716. function Delete(const path: SOString): ISuperObject;
  717. // merges tow objects of same type, if reference is true then nodes are not cloned
  718. procedure Merge(const obj: ISuperObject; reference: boolean = false); overload;
  719. procedure Merge(const str: SOString); overload;
  720.  
  721. // validate methods
  722. function Validate(const rules: SOString; const defs: SOString = ''; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean; overload;
  723. function Validate(const rules: ISuperObject; const defs: ISuperObject = nil; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean; overload;
  724.  
  725. // compare
  726. function Compare(const obj: ISuperObject): TSuperCompareResult; overload;
  727. function Compare(const str: SOString): TSuperCompareResult; overload;
  728.  
  729. // the data type
  730. function IsType(AType: TSuperType): boolean;
  731. property DataType: TSuperType read GetDataType;
  732. // a data pointer to link to something ele, a treeview for example
  733. property DataPtr: Pointer read GetDataPtr write SetDataPtr;
  734. property Processing: boolean read GetProcessing;
  735. end;
  736.  
  737. {$IFDEF VER210}
  738. TSuperRttiContext = class;
  739.  
  740. TSerialFromJson = function(ctx: TSuperRttiContext; const obj: ISuperObject; var Value: TValue): Boolean;
  741. TSerialToJson = function(ctx: TSuperRttiContext; var value: TValue; const index: ISuperObject): ISuperObject;
  742.  
  743. TSuperAttribute = class(TCustomAttribute)
  744. private
  745. FName: string;
  746. public
  747. constructor Create(const AName: string);
  748. property Name: string read FName;
  749. end;
  750.  
  751. SOName = class(TSuperAttribute);
  752. SODefault = class(TSuperAttribute);
  753.  
  754. TSuperRttiContext = class
  755. private
  756. class function GetFieldName(r: TRttiField): string;
  757. class function GetFieldDefault(r: TRttiField; const obj: ISuperObject): ISuperObject;
  758. public
  759. Context: TRttiContext;
  760. SerialFromJson: TDictionary<PTypeInfo, TSerialFromJson>;
  761. SerialToJson: TDictionary<PTypeInfo, TSerialToJson>;
  762. constructor Create; virtual;
  763. destructor Destroy; override;
  764. function FromJson(TypeInfo: PTypeInfo; const obj: ISuperObject; var Value: TValue): Boolean; virtual;
  765. function ToJson(var value: TValue; const index: ISuperObject): ISuperObject; virtual;
  766. function AsType<T>(const obj: ISuperObject): T;
  767. function AsJson<T>(const obj: T; const index: ISuperObject = nil): ISuperObject;
  768. end;
  769.  
  770. TSuperObjectHelper = class helper for TObject
  771. public
  772. function ToJson(ctx: TSuperRttiContext = nil): ISuperObject;
  773. constructor FromJson(const obj: ISuperObject; ctx: TSuperRttiContext = nil); overload;
  774. constructor FromJson(const str: string; ctx: TSuperRttiContext = nil); overload;
  775. end;
  776. {$ENDIF}
  777.  
  778. TSuperObjectIter = record
  779. key: SOString;
  780. val: ISuperObject;
  781. Ite: TSuperAvlIterator;
  782. end;
  783.  
  784. function ObjectIsError(obj: TSuperObject): boolean;
  785. function ObjectIsType(const obj: ISuperObject; typ: TSuperType): boolean;
  786. function ObjectGetType(const obj: ISuperObject): TSuperType;
  787.  
  788. function ObjectFindFirst(const obj: ISuperObject; var F: TSuperObjectIter): boolean;
  789. function ObjectFindNext(var F: TSuperObjectIter): boolean;
  790. procedure ObjectFindClose(var F: TSuperObjectIter);
  791.  
  792. function SO(const s: SOString = '{}'): ISuperObject; overload;
  793. function SO(const value: Variant): ISuperObject; overload;
  794. function SO(const Args: array of const): ISuperObject; overload;
  795.  
  796. function SA(const Args: array of const): ISuperObject; overload;
  797.  
  798. function JavaToDelphiDateTime(const dt: int64): TDateTime;
  799. function DelphiToJavaDateTime(const dt: TDateTime): int64;
  800.  
  801. {$IFDEF VER210}
  802.  
  803. type
  804. TSuperInvokeResult = (
  805. irSuccess,
  806. irMethothodError, // method don't exist
  807. irParamError, // invalid parametters
  808. irError // other error
  809. );
  810.  
  811. function TrySOInvoke(var ctx: TSuperRttiContext; const obj: TValue; const method: string; const params: ISuperObject; var Return: ISuperObject): TSuperInvokeResult; overload;
  812. function SOInvoke(const obj: TValue; const method: string; const params: ISuperObject; ctx: TSuperRttiContext = nil): ISuperObject; overload;
  813. function SOInvoke(const obj: TValue; const method: string; const params: string; ctx: TSuperRttiContext = nil): ISuperObject; overload;
  814. {$ENDIF}
  815.  
  816. /// 2016.01.01 设定排序方式
  817. procedure SetSOSortMode(pvSortMode: TSOSortMode);
  818.  
  819. /// 2016.01.01 添加默认排序方式
  820. var
  821. nowSortMode: TSOSortMode = sosmDefault;
  822.  
  823. implementation
  824. uses sysutils,
  825. {$IFDEF UNIX}
  826. baseunix, unix, DateUtils
  827. {$ELSE}
  828. Windows
  829. {$ENDIF}
  830. {$IFDEF FPC}
  831. ,sockets
  832. {$ELSE}
  833. ,WinSock
  834. {$ENDIF};
  835.  
  836. {$IFDEF DEBUG}
  837. var
  838. debugcount: integer = ;
  839. {$ENDIF}
  840.  
  841. const
  842. super_number_chars_set = [''..'','.','+','-','e','E'];
  843. super_hex_chars: PSOChar = '0123456789abcdef';
  844. super_hex_chars_set = [''..'','a'..'f','A'..'F'];
  845.  
  846. ESC_BS: PSOChar = '\b';
  847. ESC_LF: PSOChar = '\n';
  848. ESC_CR: PSOChar = '\r';
  849. ESC_TAB: PSOChar = '\t';
  850. ESC_FF: PSOChar = '\f';
  851. ESC_QUOT: PSOChar = '\"';
  852. ESC_SL: PSOChar = '\\';
  853. ESC_SR: PSOChar = '\/';
  854. ESC_ZERO: PSOChar = '\u0000';
  855.  
  856. TOK_CRLF: PSOChar = ##;
  857. TOK_SP: PSOChar = #;
  858. TOK_BS: PSOChar = #;
  859. TOK_TAB: PSOChar = #;
  860. TOK_LF: PSOChar = #;
  861. TOK_FF: PSOChar = #;
  862. TOK_CR: PSOChar = #;
  863. // TOK_SL: PSOChar = '\';
  864. // TOK_SR: PSOChar = '/';
  865. TOK_NULL: PSOChar = 'null';
  866. TOK_CBL: PSOChar = '{'; // curly bracket left
  867. TOK_CBR: PSOChar = '}'; // curly bracket right
  868. TOK_ARL: PSOChar = '[';
  869. TOK_ARR: PSOChar = ']';
  870. TOK_ARRAY: PSOChar = '[]';
  871. TOK_OBJ: PSOChar = '{}'; // empty object
  872. TOK_COM: PSOChar = ','; // Comma
  873. TOK_DQT: PSOChar = '"'; // Double Quote
  874. TOK_TRUE: PSOChar = 'true';
  875. TOK_FALSE: PSOChar = 'false';
  876.  
  877. procedure SetSOSortMode(pvSortMode: TSOSortMode);
  878. begin
  879. nowSortMode := pvSortMode;
  880. end;
  881.  
  882. {$if (sizeof(Char) = 1)}
  883. function StrLComp(const Str1, Str2: PSOChar; MaxLen: Cardinal): Integer;
  884. var
  885. P1, P2: PWideChar;
  886. I: Cardinal;
  887. C1, C2: WideChar;
  888. begin
  889. P1 := Str1;
  890. P2 := Str2;
  891. I := ;
  892. while I < MaxLen do
  893. begin
  894. C1 := P1^;
  895. C2 := P2^;
  896.  
  897. if (C1 <> C2) or (C1 = #) then
  898. begin
  899. Result := Ord(C1) - Ord(C2);
  900. Exit;
  901. end;
  902.  
  903. Inc(P1);
  904. Inc(P2);
  905. Inc(I);
  906. end;
  907. Result := ;
  908. end;
  909.  
  910. function StrComp(const Str1, Str2: PSOChar): Integer;
  911. var
  912. P1, P2: PWideChar;
  913. C1, C2: WideChar;
  914. begin
  915. P1 := Str1;
  916. P2 := Str2;
  917. while True do
  918. begin
  919. C1 := P1^;
  920. C2 := P2^;
  921.  
  922. if (C1 <> C2) or (C1 = #) then
  923. begin
  924. Result := Ord(C1) - Ord(C2);
  925. Exit;
  926. end;
  927.  
  928. Inc(P1);
  929. Inc(P2);
  930. end;
  931. end;
  932.  
  933. function StrLen(const Str: PSOChar): Cardinal;
  934. var
  935. p: PSOChar;
  936. begin
  937. Result := ;
  938. if Str <> nil then
  939. begin
  940. p := Str;
  941. while p^ <> # do inc(p);
  942. Result := (p - Str);
  943. end;
  944. end;
  945. {$ifend}
  946.  
  947. function CurrToStr(c: Currency): SOString;
  948. var
  949. p: PSOChar;
  950. i, len: Integer;
  951. begin
  952. Result := IntToStr(Abs(PInt64(@c)^));
  953. len := Length(Result);
  954. SetLength(Result, len+);
  955. if c <> then
  956. begin
  957. while len <= do
  958. begin
  959. Result := '' + Result;
  960. inc(len);
  961. end;
  962.  
  963. p := PSOChar(Result);
  964. inc(p, len-);
  965. i := ;
  966. repeat
  967. if p^ <> '' then
  968. begin
  969. len := len - i + ;
  970. repeat
  971. p[] := p^;
  972. dec(p);
  973. inc(i);
  974. until i > ;
  975. Break;
  976. end;
  977. dec(p);
  978. inc(i);
  979. if i > then
  980. begin
  981. len := len - i + ;
  982. Break;
  983. end;
  984. until false;
  985. p[] := '.';
  986. SetLength(Result, len);
  987. if c < then
  988. Result := '-' + Result;
  989. end;
  990. end;
  991.  
  992. {$IFDEF UNIX}
  993. {$linklib c}
  994. {$ENDIF}
  995. function gcvt(value: Double; ndigit: longint; buf: PAnsiChar): PAnsiChar; cdecl;
  996. external {$IFDEF MSWINDOWS} 'msvcrt.dll' name '_gcvt'{$ENDIF};
  997.  
  998. {$IFDEF UNIX}
  999. type
  1000. ptm = ^tm;
  1001. tm = record
  1002. tm_sec: Integer; (* Seconds: 0-59 (K&R says 0-61?) *)
  1003. tm_min: Integer; (* Minutes: 0-59 *)
  1004. tm_hour: Integer; (* Hours since midnight: 0-23 *)
  1005. tm_mday: Integer; (* Day of the month: 1-31 *)
  1006. tm_mon: Integer; (* Months *since* january: 0-11 *)
  1007. tm_year: Integer; (* Years since 1900 *)
  1008. tm_wday: Integer; (* Days since Sunday (0-6) *)
  1009. tm_yday: Integer; (* Days since Jan. 1: 0-365 *)
  1010. tm_isdst: Integer; (* +1 Daylight Savings Time, 0 No DST, -1 don't know *)
  1011. end;
  1012.  
  1013. function mktime(p: ptm): LongInt; cdecl; external;
  1014. function gmtime(const t: PLongint): ptm; cdecl; external;
  1015. function localtime (const t: PLongint): ptm; cdecl; external;
  1016.  
  1017. function DelphiToJavaDateTime(const dt: TDateTime): Int64;
  1018. var
  1019. p: ptm;
  1020. l, ms: Integer;
  1021. v: Int64;
  1022. begin
  1023. v := Round((dt - ) * );
  1024. ms := v mod ;
  1025. l := v div ;
  1026. p := localtime(@l);
  1027. Result := Int64(mktime(p)) * + ms;
  1028. end;
  1029.  
  1030. function JavaToDelphiDateTime(const dt: int64): TDateTime;
  1031. var
  1032. p: ptm;
  1033. l, ms: Integer;
  1034. begin
  1035. l := dt div ;
  1036. ms := dt mod ;
  1037. p := gmtime(@l);
  1038. Result := EncodeDateTime(p^.tm_year+, p^.tm_mon+, p^.tm_mday, p^.tm_hour, p^.tm_min, p^.tm_sec, ms);
  1039. end;
  1040. {$ELSE}
  1041.  
  1042. {$IFDEF WINDOWSNT_COMPATIBILITY}
  1043. function DayLightCompareDate(const date: PSystemTime;
  1044. const compareDate: PSystemTime): Integer;
  1045. var
  1046. limit_day, dayinsecs, weekofmonth: Integer;
  1047. First: Word;
  1048. begin
  1049. if (date^.wMonth < compareDate^.wMonth) then
  1050. begin
  1051. Result := -; (* We are in a month before the date limit. *)
  1052. Exit;
  1053. end;
  1054.  
  1055. if (date^.wMonth > compareDate^.wMonth) then
  1056. begin
  1057. Result := ; (* We are in a month after the date limit. *)
  1058. Exit;
  1059. end;
  1060.  
  1061. (* if year is 0 then date is in day-of-week format, otherwise
  1062. * it's absolute date.
  1063. *)
  1064. if (compareDate^.wYear = ) then
  1065. begin
  1066. (* compareDate.wDay is interpreted as number of the week in the month
  1067. * 5 means: the last week in the month *)
  1068. weekofmonth := compareDate^.wDay;
  1069. (* calculate the day of the first DayOfWeek in the month *)
  1070. First := ( + compareDate^.wDayOfWeek - date^.wDayOfWeek + date^.wDay) mod + ;
  1071. limit_day := First + * (weekofmonth - );
  1072. (* check needed for the 5th weekday of the month *)
  1073. if (limit_day > MonthDays[(date^.wMonth=) and IsLeapYear(date^.wYear)][date^.wMonth - ]) then
  1074. dec(limit_day, );
  1075. end
  1076. else
  1077. limit_day := compareDate^.wDay;
  1078.  
  1079. (* convert to seconds *)
  1080. limit_day := ((limit_day * + compareDate^.wHour) * + compareDate^.wMinute ) * ;
  1081. dayinsecs := ((date^.wDay * + date^.wHour) * + date^.wMinute ) * + date^.wSecond;
  1082. (* and compare *)
  1083.  
  1084. if dayinsecs < limit_day then
  1085. Result := - else
  1086. if dayinsecs > limit_day then
  1087. Result := else
  1088. Result := ; (* date is equal to the date limit. *)
  1089. end;
  1090.  
  1091. function CompTimeZoneID(const pTZinfo: PTimeZoneInformation;
  1092. lpFileTime: PFileTime; islocal: Boolean): LongWord;
  1093. var
  1094. ret: Integer;
  1095. beforeStandardDate, afterDaylightDate: Boolean;
  1096. llTime: Int64;
  1097. SysTime: TSystemTime;
  1098. ftTemp: TFileTime;
  1099. begin
  1100. llTime := ;
  1101.  
  1102. if (pTZinfo^.DaylightDate.wMonth <> ) then
  1103. begin
  1104. (* if year is 0 then date is in day-of-week format, otherwise
  1105. * it's absolute date.
  1106. *)
  1107. if ((pTZinfo^.StandardDate.wMonth = ) or
  1108. ((pTZinfo^.StandardDate.wYear = ) and
  1109. ((pTZinfo^.StandardDate.wDay < ) or
  1110. (pTZinfo^.StandardDate.wDay > ) or
  1111. (pTZinfo^.DaylightDate.wDay < ) or
  1112. (pTZinfo^.DaylightDate.wDay > )))) then
  1113. begin
  1114. SetLastError(ERROR_INVALID_PARAMETER);
  1115. Result := TIME_ZONE_ID_INVALID;
  1116. Exit;
  1117. end;
  1118.  
  1119. if (not islocal) then
  1120. begin
  1121. llTime := PInt64(lpFileTime)^;
  1122. dec(llTime, Int64(pTZinfo^.Bias + pTZinfo^.DaylightBias) * );
  1123. PInt64(@ftTemp)^ := llTime;
  1124. lpFileTime := @ftTemp;
  1125. end;
  1126.  
  1127. FileTimeToSystemTime(lpFileTime^, SysTime);
  1128.  
  1129. (* check for daylight savings *)
  1130. ret := DayLightCompareDate(@SysTime, @pTZinfo^.StandardDate);
  1131. if (ret = -) then
  1132. begin
  1133. Result := TIME_ZONE_ID_INVALID;
  1134. Exit;
  1135. end;
  1136.  
  1137. beforeStandardDate := ret < ;
  1138.  
  1139. if (not islocal) then
  1140. begin
  1141. dec(llTime, Int64(pTZinfo^.StandardBias - pTZinfo^.DaylightBias) * );
  1142. PInt64(@ftTemp)^ := llTime;
  1143. FileTimeToSystemTime(lpFileTime^, SysTime);
  1144. end;
  1145.  
  1146. ret := DayLightCompareDate(@SysTime, @pTZinfo^.DaylightDate);
  1147. if (ret = -) then
  1148. begin
  1149. Result := TIME_ZONE_ID_INVALID;
  1150. Exit;
  1151. end;
  1152.  
  1153. afterDaylightDate := ret >= ;
  1154.  
  1155. Result := TIME_ZONE_ID_STANDARD;
  1156. if( pTZinfo^.DaylightDate.wMonth < pTZinfo^.StandardDate.wMonth ) then
  1157. begin
  1158. (* Northern hemisphere *)
  1159. if( beforeStandardDate and afterDaylightDate) then
  1160. Result := TIME_ZONE_ID_DAYLIGHT;
  1161. end else (* Down south *)
  1162. if( beforeStandardDate or afterDaylightDate) then
  1163. Result := TIME_ZONE_ID_DAYLIGHT;
  1164. end else
  1165. (* No transition date *)
  1166. Result := TIME_ZONE_ID_UNKNOWN;
  1167. end;
  1168.  
  1169. function GetTimezoneBias(const pTZinfo: PTimeZoneInformation;
  1170. lpFileTime: PFileTime; islocal: Boolean; pBias: PLongint): Boolean;
  1171. var
  1172. bias: LongInt;
  1173. tzid: LongWord;
  1174. begin
  1175. bias := pTZinfo^.Bias;
  1176. tzid := CompTimeZoneID(pTZinfo, lpFileTime, islocal);
  1177.  
  1178. if( tzid = TIME_ZONE_ID_INVALID) then
  1179. begin
  1180. Result := False;
  1181. Exit;
  1182. end;
  1183. if (tzid = TIME_ZONE_ID_DAYLIGHT) then
  1184. inc(bias, pTZinfo^.DaylightBias)
  1185. else if (tzid = TIME_ZONE_ID_STANDARD) then
  1186. inc(bias, pTZinfo^.StandardBias);
  1187. pBias^ := bias;
  1188. Result := True;
  1189. end;
  1190.  
  1191. function SystemTimeToTzSpecificLocalTime(
  1192. lpTimeZoneInformation: PTimeZoneInformation;
  1193. lpUniversalTime, lpLocalTime: PSystemTime): BOOL;
  1194. var
  1195. ft: TFileTime;
  1196. lBias: LongInt;
  1197. llTime: Int64;
  1198. tzinfo: TTimeZoneInformation;
  1199. begin
  1200. if (lpTimeZoneInformation <> nil) then
  1201. tzinfo := lpTimeZoneInformation^ else
  1202. if (GetTimeZoneInformation(tzinfo) = TIME_ZONE_ID_INVALID) then
  1203. begin
  1204. Result := False;
  1205. Exit;
  1206. end;
  1207.  
  1208. if (not SystemTimeToFileTime(lpUniversalTime^, ft)) then
  1209. begin
  1210. Result := False;
  1211. Exit;
  1212. end;
  1213. llTime := PInt64(@ft)^;
  1214. if (not GetTimezoneBias(@tzinfo, @ft, False, @lBias)) then
  1215. begin
  1216. Result := False;
  1217. Exit;
  1218. end;
  1219. (* convert minutes to 100-nanoseconds-ticks *)
  1220. dec(llTime, Int64(lBias) * );
  1221. PInt64(@ft)^ := llTime;
  1222. Result := FileTimeToSystemTime(ft, lpLocalTime^);
  1223. end;
  1224.  
  1225. function TzSpecificLocalTimeToSystemTime(
  1226. const lpTimeZoneInformation: PTimeZoneInformation;
  1227. const lpLocalTime: PSystemTime; lpUniversalTime: PSystemTime): BOOL;
  1228. var
  1229. ft: TFileTime;
  1230. lBias: LongInt;
  1231. t: Int64;
  1232. tzinfo: TTimeZoneInformation;
  1233. begin
  1234. if (lpTimeZoneInformation <> nil) then
  1235. tzinfo := lpTimeZoneInformation^
  1236. else
  1237. if (GetTimeZoneInformation(tzinfo) = TIME_ZONE_ID_INVALID) then
  1238. begin
  1239. Result := False;
  1240. Exit;
  1241. end;
  1242.  
  1243. if (not SystemTimeToFileTime(lpLocalTime^, ft)) then
  1244. begin
  1245. Result := False;
  1246. Exit;
  1247. end;
  1248. t := PInt64(@ft)^;
  1249. if (not GetTimezoneBias(@tzinfo, @ft, True, @lBias)) then
  1250. begin
  1251. Result := False;
  1252. Exit;
  1253. end;
  1254. (* convert minutes to 100-nanoseconds-ticks *)
  1255. inc(t, Int64(lBias) * );
  1256. PInt64(@ft)^ := t;
  1257. Result := FileTimeToSystemTime(ft, lpUniversalTime^);
  1258. end;
  1259. {$ELSE}
  1260. function TzSpecificLocalTimeToSystemTime(
  1261. lpTimeZoneInformation: PTimeZoneInformation;
  1262. lpLocalTime, lpUniversalTime: PSystemTime): BOOL; stdcall; external 'kernel32.dll';
  1263.  
  1264. function SystemTimeToTzSpecificLocalTime(
  1265. lpTimeZoneInformation: PTimeZoneInformation;
  1266. lpUniversalTime, lpLocalTime: PSystemTime): BOOL; stdcall; external 'kernel32.dll';
  1267. {$ENDIF}
  1268.  
  1269. function JavaToDelphiDateTime(const dt: int64): TDateTime;
  1270. var
  1271. t: TSystemTime;
  1272. begin
  1273. DateTimeToSystemTime( + (dt / ), t);
  1274. SystemTimeToTzSpecificLocalTime(nil, @t, @t);
  1275. Result := SystemTimeToDateTime(t);
  1276. end;
  1277.  
  1278. function DelphiToJavaDateTime(const dt: TDateTime): int64;
  1279. var
  1280. t: TSystemTime;
  1281. begin
  1282. DateTimeToSystemTime(dt, t);
  1283. TzSpecificLocalTimeToSystemTime(nil, @t, @t);
  1284. Result := Round((SystemTimeToDateTime(t) - ) * )
  1285. end;
  1286. {$ENDIF}
  1287.  
  1288. function SO(const s: SOString): ISuperObject; overload;
  1289. begin
  1290. Result := TSuperObject.ParseString(PSOChar(s), False);
  1291. end;
  1292.  
  1293. function SA(const Args: array of const): ISuperObject; overload;
  1294. type
  1295. TByteArray = array[..sizeof(integer) - ] of byte;
  1296. PByteArray = ^TByteArray;
  1297. var
  1298. j: Integer;
  1299. intf: IInterface;
  1300. begin
  1301. Result := TSuperObject.Create(stArray);
  1302. for j := to length(Args) - do
  1303. with Result.AsArray do
  1304. case TVarRec(Args[j]).VType of
  1305. vtInteger : Add(TSuperObject.Create(TVarRec(Args[j]).VInteger));
  1306. vtInt64 : Add(TSuperObject.Create(TVarRec(Args[j]).VInt64^));
  1307. vtBoolean : Add(TSuperObject.Create(TVarRec(Args[j]).VBoolean));
  1308. vtChar : Add(TSuperObject.Create(SOString(TVarRec(Args[j]).VChar)));
  1309. vtWideChar: Add(TSuperObject.Create(SOChar(TVarRec(Args[j]).VWideChar)));
  1310. vtExtended: Add(TSuperObject.Create(TVarRec(Args[j]).VExtended^));
  1311. vtCurrency: Add(TSuperObject.CreateCurrency(TVarRec(Args[j]).VCurrency^));
  1312. vtString : Add(TSuperObject.Create(SOString(TVarRec(Args[j]).VString^)));
  1313. vtPChar : Add(TSuperObject.Create(SOString(TVarRec(Args[j]).VPChar^)));
  1314. vtAnsiString: Add(TSuperObject.Create(SOString(AnsiString(TVarRec(Args[j]).VAnsiString))));
  1315. vtWideString: Add(TSuperObject.Create(SOString(PWideChar(TVarRec(Args[j]).VWideString))));
  1316. vtInterface:
  1317. if TVarRec(Args[j]).VInterface = nil then
  1318. Add(nil) else
  1319. if IInterface(TVarRec(Args[j]).VInterface).QueryInterface(ISuperObject, intf) = then
  1320. Add(ISuperObject(intf)) else
  1321. Add(nil);
  1322. vtPointer :
  1323. if TVarRec(Args[j]).VPointer = nil then
  1324. Add(nil) else
  1325. Add(TSuperObject.Create(PtrInt(TVarRec(Args[j]).VPointer)));
  1326. vtVariant:
  1327. Add(SO(TVarRec(Args[j]).VVariant^));
  1328. vtObject:
  1329. if TVarRec(Args[j]).VPointer = nil then
  1330. Add(nil) else
  1331. Add(TSuperObject.Create(PtrInt(TVarRec(Args[j]).VPointer)));
  1332. vtClass:
  1333. if TVarRec(Args[j]).VPointer = nil then
  1334. Add(nil) else
  1335. Add(TSuperObject.Create(PtrInt(TVarRec(Args[j]).VPointer)));
  1336. {$if declared(vtUnicodeString)}
  1337. vtUnicodeString:
  1338. Add(TSuperObject.Create(SOString(string(TVarRec(Args[j]).VUnicodeString))));
  1339. {$ifend}
  1340. else
  1341. assert(false);
  1342. end;
  1343. end;
  1344.  
  1345. function SO(const Args: array of const): ISuperObject; overload;
  1346. var
  1347. j: Integer;
  1348. arr: ISuperObject;
  1349. begin
  1350. Result := TSuperObject.Create(stObject);
  1351. arr := SA(Args);
  1352. with arr.AsArray do
  1353. for j := to (Length div ) - do
  1354. Result.AsObject.PutO(O[j*].AsString, O[(j*) + ]);
  1355. end;
  1356.  
  1357. function SO(const value: Variant): ISuperObject; overload;
  1358. begin
  1359. with TVarData(value) do
  1360. case VType of
  1361. varNull: Result := nil;
  1362. varEmpty: Result := nil;
  1363. varSmallInt: Result := TSuperObject.Create(VSmallInt);
  1364. varInteger: Result := TSuperObject.Create(VInteger);
  1365. varSingle: Result := TSuperObject.Create(VSingle);
  1366. varDouble: Result := TSuperObject.Create(VDouble);
  1367. varCurrency: Result := TSuperObject.CreateCurrency(VCurrency);
  1368. varDate: Result := TSuperObject.Create(DelphiToJavaDateTime(vDate));
  1369. varOleStr: Result := TSuperObject.Create(SOString(VOleStr));
  1370. varBoolean: Result := TSuperObject.Create(VBoolean);
  1371. varShortInt: Result := TSuperObject.Create(VShortInt);
  1372. varByte: Result := TSuperObject.Create(VByte);
  1373. varWord: Result := TSuperObject.Create(VWord);
  1374. varLongWord: Result := TSuperObject.Create(VLongWord);
  1375. varInt64: Result := TSuperObject.Create(VInt64);
  1376. varString: Result := TSuperObject.Create(SOString(AnsiString(VString)));
  1377. {$if declared(varUString)}
  1378. varUString: Result := TSuperObject.Create(SOString(string(VUString)));
  1379. {$ifend}
  1380. else
  1381. raise Exception.CreateFmt('Unsuported variant data type: %d', [VType]);
  1382. end;
  1383. end;
  1384.  
  1385. function ObjectIsError(obj: TSuperObject): boolean;
  1386. begin
  1387. Result := PtrUInt(obj) > PtrUInt(-);
  1388. end;
  1389.  
  1390. function ObjectIsType(const obj: ISuperObject; typ: TSuperType): boolean;
  1391. begin
  1392. if obj <> nil then
  1393. Result := typ = obj.DataType else
  1394. Result := typ = stNull;
  1395. end;
  1396.  
  1397. function ObjectGetType(const obj: ISuperObject): TSuperType;
  1398. begin
  1399. if obj <> nil then
  1400. Result := obj.DataType else
  1401. Result := stNull;
  1402. end;
  1403.  
  1404. function ObjectFindFirst(const obj: ISuperObject; var F: TSuperObjectIter): boolean;
  1405. var
  1406. i: TSuperAvlEntry;
  1407. begin
  1408. if ObjectIsType(obj, stObject) then
  1409. begin
  1410. F.Ite := TSuperAvlIterator.Create(obj.AsObject);
  1411. F.Ite.First;
  1412. i := F.Ite.GetIter;
  1413. if i <> nil then
  1414. begin
  1415. f.key := i.Name;
  1416. f.val := i.Value;
  1417. Result := true;
  1418. end else
  1419. Result := False;
  1420. end else
  1421. Result := False;
  1422. end;
  1423.  
  1424. function ObjectFindNext(var F: TSuperObjectIter): boolean;
  1425. var
  1426. i: TSuperAvlEntry;
  1427. begin
  1428. F.Ite.Next;
  1429. i := F.Ite.GetIter;
  1430. if i <> nil then
  1431. begin
  1432. f.key := i.FName;
  1433. f.val := i.Value;
  1434. Result := true;
  1435. end else
  1436. Result := False;
  1437. end;
  1438.  
  1439. procedure ObjectFindClose(var F: TSuperObjectIter);
  1440. begin
  1441. F.Ite.Free;
  1442. F.val := nil;
  1443. end;
  1444.  
  1445. {$IFDEF VER210}
  1446.  
  1447. function serialtoboolean(ctx: TSuperRttiContext; var value: TValue; const index: ISuperObject): ISuperObject;
  1448. begin
  1449. Result := TSuperObject.Create(TValueData(value).FAsSLong <> );
  1450. end;
  1451.  
  1452. function serialtodatetime(ctx: TSuperRttiContext; var value: TValue; const index: ISuperObject): ISuperObject;
  1453. begin
  1454. Result := TSuperObject.Create(DelphiToJavaDateTime(TValueData(value).FAsDouble));
  1455. end;
  1456.  
  1457. function serialtoguid(ctx: TSuperRttiContext; var value: TValue; const index: ISuperObject): ISuperObject;
  1458. var
  1459. g: TGUID;
  1460. begin
  1461. value.ExtractRawData(@g);
  1462. Result := TSuperObject.Create(
  1463. format('%.8x-%.4x-%.4x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x',
  1464. [g.D1, g.D2, g.D3,
  1465. g.D4[], g.D4[], g.D4[],
  1466. g.D4[], g.D4[], g.D4[],
  1467. g.D4[], g.D4[]])
  1468. );
  1469. end;
  1470.  
  1471. function serialfromboolean(ctx: TSuperRttiContext; const obj: ISuperObject; var Value: TValue): Boolean;
  1472. var
  1473. o: ISuperObject;
  1474. begin
  1475. case ObjectGetType(obj) of
  1476. stBoolean:
  1477. begin
  1478. TValueData(Value).FAsSLong := obj.AsInteger;
  1479. Result := True;
  1480. end;
  1481. stInt:
  1482. begin
  1483. TValueData(Value).FAsSLong := ord(obj.AsInteger <> );
  1484. Result := True;
  1485. end;
  1486. stString:
  1487. begin
  1488. o := SO(obj.AsString);
  1489. if not ObjectIsType(o, stString) then
  1490. Result := serialfromboolean(ctx, SO(obj.AsString), Value) else
  1491. Result := False;
  1492. end;
  1493. else
  1494. Result := False;
  1495. end;
  1496. end;
  1497.  
  1498. function serialfromdatetime(ctx: TSuperRttiContext; const obj: ISuperObject; var Value: TValue): Boolean;
  1499. var
  1500. dt: TDateTime;
  1501. begin
  1502. case ObjectGetType(obj) of
  1503. stInt:
  1504. begin
  1505. TValueData(Value).FAsDouble := JavaToDelphiDateTime(obj.AsInteger);
  1506. Result := True;
  1507. end;
  1508. stString:
  1509. begin
  1510. if TryStrToDateTime(obj.AsString, dt) then
  1511. begin
  1512. TValueData(Value).FAsDouble := dt;
  1513. Result := True;
  1514. end else
  1515. Result := False;
  1516. end;
  1517. else
  1518. Result := False;
  1519. end;
  1520. end;
  1521.  
  1522. function UuidFromString(const s: PSOChar; Uuid: PGUID): Boolean;
  1523. const
  1524. hex2bin: array[#..#] of short = (
  1525. -,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-, (* 0x00 *)
  1526. -,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-, (* 0x10 *)
  1527. -,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-, (* 0x20 *)
  1528. , , , , , , , , , ,-,-,-,-,-,-, (* 0x30 *)
  1529. -,,,,,,,-,-,-,-,-,-,-,-,-, (* 0x40 *)
  1530. -,-,-,-,-,-,-,-,-,-,-,-,-,-,-,-, (* 0x50 *)
  1531. -,,,,,,); (* 0x60 *)
  1532. var
  1533. i: Integer;
  1534. begin
  1535. if (strlen(s) <> ) then Exit(False);
  1536.  
  1537. if ((s[] <> '-') or (s[] <> '-') or (s[] <> '-') or (s[] <> '-')) then
  1538. Exit(False);
  1539.  
  1540. for i := to do
  1541. begin
  1542. if not i in [,,,] then
  1543. if ((s[i] > 'f') or ((hex2bin[s[i]] = -) and (s[i] <> ''))) then
  1544. Exit(False);
  1545. end;
  1546.  
  1547. uuid.D1 := ((hex2bin[s[]] shl ) or (hex2bin[s[]] shl ) or (hex2bin[s[]] shl ) or (hex2bin[s[]] shl ) or
  1548. (hex2bin[s[]] shl ) or (hex2bin[s[]] shl ) or (hex2bin[s[]] shl ) or hex2bin[s[]]);
  1549. uuid.D2 := (hex2bin[s[]] shl ) or (hex2bin[s[]] shl ) or (hex2bin[s[]] shl ) or hex2bin[s[]];
  1550. uuid.D3 := (hex2bin[s[]] shl ) or (hex2bin[s[]] shl ) or (hex2bin[s[]] shl ) or hex2bin[s[]];
  1551.  
  1552. uuid.D4[] := (hex2bin[s[]] shl ) or hex2bin[s[]];
  1553. uuid.D4[] := (hex2bin[s[]] shl ) or hex2bin[s[]];
  1554. uuid.D4[] := (hex2bin[s[]] shl ) or hex2bin[s[]];
  1555. uuid.D4[] := (hex2bin[s[]] shl ) or hex2bin[s[]];
  1556. uuid.D4[] := (hex2bin[s[]] shl ) or hex2bin[s[]];
  1557. uuid.D4[] := (hex2bin[s[]] shl ) or hex2bin[s[]];
  1558. uuid.D4[] := (hex2bin[s[]] shl ) or hex2bin[s[]];
  1559. uuid.D4[] := (hex2bin[s[]] shl ) or hex2bin[s[]];
  1560. Result := True;
  1561. end;
  1562.  
  1563. function serialfromguid(ctx: TSuperRttiContext; const obj: ISuperObject; var Value: TValue): Boolean;
  1564. begin
  1565. case ObjectGetType(obj) of
  1566. stNull:
  1567. begin
  1568. FillChar(Value.GetReferenceToRawData^, SizeOf(TGUID), );
  1569. Result := True;
  1570. end;
  1571. stString: Result := UuidFromString(PSOChar(obj.AsString), Value.GetReferenceToRawData);
  1572. else
  1573. Result := False;
  1574. end;
  1575. end;
  1576.  
  1577. function SOInvoke(const obj: TValue; const method: string; const params: ISuperObject; ctx: TSuperRttiContext): ISuperObject; overload;
  1578. var
  1579. owned: Boolean;
  1580. begin
  1581. if ctx = nil then
  1582. begin
  1583. ctx := TSuperRttiContext.Create;
  1584. owned := True;
  1585. end else
  1586. owned := False;
  1587. try
  1588. if TrySOInvoke(ctx, obj, method, params, Result) <> irSuccess then
  1589. raise Exception.Create('Invalid method call');
  1590. finally
  1591. if owned then
  1592. ctx.Free;
  1593. end;
  1594. end;
  1595.  
  1596. function SOInvoke(const obj: TValue; const method: string; const params: string; ctx: TSuperRttiContext): ISuperObject; overload;
  1597. begin
  1598. Result := SOInvoke(obj, method, so(params), ctx)
  1599. end;
  1600.  
  1601. function TrySOInvoke(var ctx: TSuperRttiContext; const obj: TValue;
  1602. const method: string; const params: ISuperObject;
  1603. var Return: ISuperObject): TSuperInvokeResult;
  1604. var
  1605. t: TRttiInstanceType;
  1606. m: TRttiMethod;
  1607. a: TArray<TValue>;
  1608. ps: TArray<TRttiParameter>;
  1609. v: TValue;
  1610. index: ISuperObject;
  1611.  
  1612. function GetParams: Boolean;
  1613. var
  1614. i: Integer;
  1615. begin
  1616. case ObjectGetType(params) of
  1617. stArray:
  1618. for i := to Length(ps) - do
  1619. if (pfOut in ps[i].Flags) then
  1620. TValue.Make(nil, ps[i].ParamType.Handle, a[i]) else
  1621. if not ctx.FromJson(ps[i].ParamType.Handle, params.AsArray[i], a[i]) then
  1622. Exit(False);
  1623. stObject:
  1624. for i := to Length(ps) - do
  1625. if (pfOut in ps[i].Flags) then
  1626. TValue.Make(nil, ps[i].ParamType.Handle, a[i]) else
  1627. if not ctx.FromJson(ps[i].ParamType.Handle, params.AsObject[ps[i].Name], a[i]) then
  1628. Exit(False);
  1629. stNull: ;
  1630. else
  1631. Exit(False);
  1632. end;
  1633. Result := True;
  1634. end;
  1635.  
  1636. procedure SetParams;
  1637. var
  1638. i: Integer;
  1639. begin
  1640. case ObjectGetType(params) of
  1641. stArray:
  1642. for i := to Length(ps) - do
  1643. if (ps[i].Flags * [pfVar, pfOut]) <> [] then
  1644. params.AsArray[i] := ctx.ToJson(a[i], index);
  1645. stObject:
  1646. for i := to Length(ps) - do
  1647. if (ps[i].Flags * [pfVar, pfOut]) <> [] then
  1648. params.AsObject[ps[i].Name] := ctx.ToJson(a[i], index);
  1649. end;
  1650. end;
  1651.  
  1652. begin
  1653. Result := irSuccess;
  1654. index := SO;
  1655. case obj.Kind of
  1656. tkClass:
  1657. begin
  1658. t := TRttiInstanceType(ctx.Context.GetType(obj.AsObject.ClassType));
  1659. m := t.GetMethod(method);
  1660. if m = nil then Exit(irMethothodError);
  1661. ps := m.GetParameters;
  1662. SetLength(a, Length(ps));
  1663. if not GetParams then Exit(irParamError);
  1664. if m.IsClassMethod then
  1665. begin
  1666. v := m.Invoke(obj.AsObject.ClassType, a);
  1667. Return := ctx.ToJson(v, index);
  1668. SetParams;
  1669. end else
  1670. begin
  1671. v := m.Invoke(obj, a);
  1672. Return := ctx.ToJson(v, index);
  1673. SetParams;
  1674. end;
  1675. end;
  1676. tkClassRef:
  1677. begin
  1678. t := TRttiInstanceType(ctx.Context.GetType(obj.AsClass));
  1679. m := t.GetMethod(method);
  1680. if m = nil then Exit(irMethothodError);
  1681. ps := m.GetParameters;
  1682. SetLength(a, Length(ps));
  1683.  
  1684. if not GetParams then Exit(irParamError);
  1685. if m.IsClassMethod then
  1686. begin
  1687. v := m.Invoke(obj, a);
  1688. Return := ctx.ToJson(v, index);
  1689. SetParams;
  1690. end else
  1691. Exit(irError);
  1692. end;
  1693. else
  1694. Exit(irError);
  1695. end;
  1696. end;
  1697.  
  1698. {$ENDIF}
  1699.  
  1700. { TSuperEnumerator }
  1701.  
  1702. constructor TSuperEnumerator.Create(const obj: ISuperObject);
  1703. begin
  1704. FObj := obj;
  1705. FCount := -;
  1706. if ObjectIsType(FObj, stObject) then
  1707. FObjEnum := FObj.AsObject.GetEnumerator else
  1708. FObjEnum := nil;
  1709. end;
  1710.  
  1711. destructor TSuperEnumerator.Destroy;
  1712. begin
  1713. if FObjEnum <> nil then
  1714. FObjEnum.Free;
  1715. end;
  1716.  
  1717. function TSuperEnumerator.MoveNext: Boolean;
  1718. begin
  1719. case ObjectGetType(FObj) of
  1720. stObject: Result := FObjEnum.MoveNext;
  1721. stArray:
  1722. begin
  1723. inc(FCount);
  1724. if FCount < FObj.AsArray.Length then
  1725. Result := True else
  1726. Result := False;
  1727. end;
  1728. else
  1729. Result := false;
  1730. end;
  1731. end;
  1732.  
  1733. function TSuperEnumerator.GetCurrent: ISuperObject;
  1734. begin
  1735. case ObjectGetType(FObj) of
  1736. stObject: Result := FObjEnum.Current.Value;
  1737. stArray: Result := FObj.AsArray.GetO(FCount);
  1738. else
  1739. Result := FObj;
  1740. end;
  1741. end;
  1742.  
  1743. { TSuperObject }
  1744.  
  1745. constructor TSuperObject.Create(jt: TSuperType);
  1746. begin
  1747. inherited Create;
  1748. {$IFDEF DEBUG}
  1749. InterlockedIncrement(debugcount);
  1750. {$ENDIF}
  1751.  
  1752. FProcessing := false;
  1753. FDataPtr := nil;
  1754. FDataType := jt;
  1755. case FDataType of
  1756. stObject: FO.c_object := TSuperTableString.Create;
  1757. stArray: FO.c_array := TSuperArray.Create;
  1758. stString: FOString := '';
  1759. else
  1760. FO.c_object := nil;
  1761. end;
  1762. end;
  1763.  
  1764. constructor TSuperObject.Create(b: boolean);
  1765. begin
  1766. Create(stBoolean);
  1767. FO.c_boolean := b;
  1768. end;
  1769.  
  1770. constructor TSuperObject.Create(i: SuperInt);
  1771. begin
  1772. Create(stInt);
  1773. FO.c_int := i;
  1774. end;
  1775.  
  1776. constructor TSuperObject.Create(d: double);
  1777. begin
  1778. Create(stDouble);
  1779. FO.c_double := d;
  1780. end;
  1781.  
  1782. constructor TSuperObject.CreateCurrency(c: Currency);
  1783. begin
  1784. Create(stCurrency);
  1785. FO.c_currency := c;
  1786. end;
  1787.  
  1788. destructor TSuperObject.Destroy;
  1789. begin
  1790. {$IFDEF DEBUG}
  1791. InterlockedDecrement(debugcount);
  1792. {$ENDIF}
  1793. case FDataType of
  1794. stObject: FO.c_object.Free;
  1795. stArray: FO.c_array.Free;
  1796. end;
  1797. inherited;
  1798. end;
  1799.  
  1800. function TSuperObject.Write(writer: TSuperWriter; indent: boolean; escape: boolean; level: integer): Integer;
  1801. function DoEscape(str: PSOChar; len: Integer): Integer;
  1802. var
  1803. pos, start_offset: Integer;
  1804. c: SOChar;
  1805. buf: array[..] of SOChar;
  1806. type
  1807. TByteChar = record
  1808. case integer of
  1809. : (a, b: Byte);
  1810. : (c: WideChar);
  1811. end;
  1812. begin
  1813. if str = nil then
  1814. begin
  1815. Result := ;
  1816. exit;
  1817. end;
  1818. pos := ; start_offset := ;
  1819. with writer do
  1820. while pos < len do
  1821. begin
  1822. c := str[pos];
  1823. case c of
  1824. #,#,#,#,#,'"','\','/':
  1825. begin
  1826. if(pos - start_offset > ) then
  1827. Append(str + start_offset, pos - start_offset);
  1828.  
  1829. if(c = #) then Append(ESC_BS, )
  1830. else if (c = #) then Append(ESC_TAB, )
  1831. else if (c = #) then Append(ESC_LF, )
  1832. else if (c = #) then Append(ESC_FF, )
  1833. else if (c = #) then Append(ESC_CR, )
  1834. else if (c = '"') then Append(ESC_QUOT, )
  1835. else if (c = '\') then Append(ESC_SL, )
  1836. else if (c = '/') then Append(ESC_SR, );
  1837. inc(pos);
  1838. start_offset := pos;
  1839. end;
  1840. else
  1841. if (SOIChar(c) > ) then
  1842. begin
  1843. if(pos - start_offset > ) then
  1844. Append(str + start_offset, pos - start_offset);
  1845. buf[] := '\';
  1846. buf[] := 'u';
  1847. buf[] := super_hex_chars[TByteChar(c).b shr ];
  1848. buf[] := super_hex_chars[TByteChar(c).b and $f];
  1849. buf[] := super_hex_chars[TByteChar(c).a shr ];
  1850. buf[] := super_hex_chars[TByteChar(c).a and $f];
  1851. Append(@buf, );
  1852. inc(pos);
  1853. start_offset := pos;
  1854. end else
  1855. if (c < #) or (c > #) then
  1856. begin
  1857. if(pos - start_offset > ) then
  1858. Append(str + start_offset, pos - start_offset);
  1859. buf[] := '\';
  1860. buf[] := 'u';
  1861. buf[] := '';
  1862. buf[] := '';
  1863. buf[] := super_hex_chars[ord(c) shr ];
  1864. buf[] := super_hex_chars[ord(c) and $f];
  1865. Append(buf, );
  1866. inc(pos);
  1867. start_offset := pos;
  1868. end else
  1869. inc(pos);
  1870. end;
  1871. end;
  1872. if(pos - start_offset > ) then
  1873. writer.Append(str + start_offset, pos - start_offset);
  1874. Result := ;
  1875. end;
  1876.  
  1877. function DoMinimalEscape(str: PSOChar; len: Integer): Integer;
  1878. var
  1879. pos, start_offset: Integer;
  1880. c: SOChar;
  1881. type
  1882. TByteChar = record
  1883. case integer of
  1884. : (a, b: Byte);
  1885. : (c: WideChar);
  1886. end;
  1887. begin
  1888. if str = nil then
  1889. begin
  1890. Result := ;
  1891. exit;
  1892. end;
  1893. pos := ; start_offset := ;
  1894. with writer do
  1895. while pos < len do
  1896. begin
  1897. c := str[pos];
  1898. case c of
  1899. #:
  1900. begin
  1901. if(pos - start_offset > ) then
  1902. Append(str + start_offset, pos - start_offset);
  1903. Append(ESC_ZERO, );
  1904. inc(pos);
  1905. start_offset := pos;
  1906. end;
  1907. '"':
  1908. begin
  1909. if(pos - start_offset > ) then
  1910. Append(str + start_offset, pos - start_offset);
  1911. Append(ESC_QUOT, );
  1912. inc(pos);
  1913. start_offset := pos;
  1914. end;
  1915. '\':
  1916. begin
  1917. if(pos - start_offset > ) then
  1918. Append(str + start_offset, pos - start_offset);
  1919. Append(ESC_SL, );
  1920. inc(pos);
  1921. start_offset := pos;
  1922. end;
  1923. '/':
  1924. begin
  1925. if(pos - start_offset > ) then
  1926. Append(str + start_offset, pos - start_offset);
  1927. Append(ESC_SR, );
  1928. inc(pos);
  1929. start_offset := pos;
  1930. end;
  1931. else
  1932. inc(pos);
  1933. end;
  1934. end;
  1935. if(pos - start_offset > ) then
  1936. writer.Append(str + start_offset, pos - start_offset);
  1937. Result := ;
  1938. end;
  1939.  
  1940. procedure _indent(i: shortint; r: boolean);
  1941. begin
  1942. inc(level, i);
  1943. if r then
  1944. with writer do
  1945. begin
  1946. {$IFDEF MSWINDOWS}
  1947. Append(TOK_CRLF, );
  1948. {$ELSE}
  1949. Append(TOK_LF, );
  1950. {$ENDIF}
  1951. for i := to level - do
  1952. Append(TOK_SP, );
  1953. end;
  1954. end;
  1955. var
  1956. k,j: Integer;
  1957. iter: TSuperObjectIter;
  1958. st: AnsiString;
  1959. val: ISuperObject;
  1960. fbuffer: array[..] of AnsiChar;
  1961. const
  1962. ENDSTR_A: PSOChar = '": ';
  1963. ENDSTR_B: PSOChar = '":';
  1964. begin
  1965.  
  1966. if FProcessing then
  1967. begin
  1968. Result := writer.Append(TOK_NULL, );
  1969. Exit;
  1970. end;
  1971.  
  1972. FProcessing := true;
  1973. with writer do
  1974. try
  1975. case FDataType of
  1976. stObject:
  1977. if FO.c_object.FCount > then
  1978. begin
  1979. k := ;
  1980. Append(TOK_CBL, );
  1981. if indent then _indent(, false);
  1982. if ObjectFindFirst(Self, iter) then
  1983. repeat
  1984. {$IFDEF SUPER_METHOD}
  1985. if (iter.val = nil) or not ObjectIsType(iter.val, stMethod) then
  1986. begin
  1987. {$ENDIF}
  1988. if (iter.val = nil) or (not iter.val.Processing) then
  1989. begin
  1990. if(k <> ) then
  1991. Append(TOK_COM, );
  1992. if indent then _indent(, true);
  1993. Append(TOK_DQT, );
  1994. if escape then
  1995. doEscape(PSOChar(iter.key), Length(iter.key)) else
  1996. DoMinimalEscape(PSOChar(iter.key), Length(iter.key));
  1997. if indent then
  1998. Append(ENDSTR_A, ) else
  1999. Append(ENDSTR_B, );
  2000. if(iter.val = nil) then
  2001. Append(TOK_NULL, ) else
  2002. iter.val.write(writer, indent, escape, level);
  2003. inc(k);
  2004. end;
  2005. {$IFDEF SUPER_METHOD}
  2006. end;
  2007. {$ENDIF}
  2008. until not ObjectFindNext(iter);
  2009. ObjectFindClose(iter);
  2010. if indent then _indent(-, true);
  2011. Result := Append(TOK_CBR, );
  2012. end else
  2013. Result := Append(TOK_OBJ, );
  2014. stBoolean:
  2015. begin
  2016. if (FO.c_boolean) then
  2017. Result := Append(TOK_TRUE, ) else
  2018. Result := Append(TOK_FALSE, );
  2019. end;
  2020. stInt:
  2021. begin
  2022. str(FO.c_int, st);
  2023. Result := Append(PSOChar(SOString(st)));
  2024. end;
  2025. stDouble:
  2026. Result := Append(PSOChar(SOString(gcvt(FO.c_double, , fbuffer))));
  2027. stCurrency:
  2028. begin
  2029. Result := Append(PSOChar(CurrToStr(FO.c_currency)));
  2030. end;
  2031. stString:
  2032. begin
  2033. Append(TOK_DQT, );
  2034. if escape then
  2035. doEscape(PSOChar(FOString), Length(FOString)) else
  2036. DoMinimalEscape(PSOChar(FOString), Length(FOString));
  2037. Append(TOK_DQT, );
  2038. Result := ;
  2039. end;
  2040. stArray:
  2041. if FO.c_array.FLength > then
  2042. begin
  2043. Append(TOK_ARL, );
  2044. if indent then _indent(, true);
  2045. k := ;
  2046. j := ;
  2047. while k < FO.c_array.FLength do
  2048. begin
  2049.  
  2050. val := FO.c_array.GetO(k);
  2051. {$IFDEF SUPER_METHOD}
  2052. if not ObjectIsType(val, stMethod) then
  2053. begin
  2054. {$ENDIF}
  2055. if (val = nil) or (not val.Processing) then
  2056. begin
  2057. if (j <> ) then
  2058. Append(TOK_COM, );
  2059. if(val = nil) then
  2060. Append(TOK_NULL, ) else
  2061. val.write(writer, indent, escape, level);
  2062. inc(j);
  2063. end;
  2064. {$IFDEF SUPER_METHOD}
  2065. end;
  2066. {$ENDIF}
  2067. inc(k);
  2068. end;
  2069. if indent then _indent(-, false);
  2070. Result := Append(TOK_ARR, );
  2071. end else
  2072. Result := Append(TOK_ARRAY, );
  2073. stNull:
  2074. Result := Append(TOK_NULL, );
  2075. else
  2076. Result := ;
  2077. end;
  2078. finally
  2079. FProcessing := false;
  2080. end;
  2081. end;
  2082.  
  2083. function TSuperObject.IsType(AType: TSuperType): boolean;
  2084. begin
  2085. Result := AType = FDataType;
  2086. end;
  2087.  
  2088. function TSuperObject.AsBoolean: boolean;
  2089. begin
  2090. case FDataType of
  2091. stBoolean: Result := FO.c_boolean;
  2092. stInt: Result := (FO.c_int <> );
  2093. stDouble: Result := (FO.c_double <> );
  2094. stCurrency: Result := (FO.c_currency <> );
  2095. stString: Result := (Length(FOString) <> );
  2096. stNull: Result := False;
  2097. else
  2098. Result := True;
  2099. end;
  2100. end;
  2101.  
  2102. function TSuperObject.AsInteger: SuperInt;
  2103. var
  2104. code: integer;
  2105. cint: SuperInt;
  2106. begin
  2107. case FDataType of
  2108. stInt: Result := FO.c_int;
  2109. stDouble: Result := round(FO.c_double);
  2110. stCurrency: Result := round(FO.c_currency);
  2111. stBoolean: Result := ord(FO.c_boolean);
  2112. stString:
  2113. begin
  2114. Val(FOString, cint, code);
  2115. if code = then
  2116. Result := cint else
  2117. Result := ;
  2118. end;
  2119. else
  2120. Result := ;
  2121. end;
  2122. end;
  2123.  
  2124. function TSuperObject.AsDouble: Double;
  2125. var
  2126. code: integer;
  2127. cdouble: double;
  2128. begin
  2129. case FDataType of
  2130. stDouble: Result := FO.c_double;
  2131. stCurrency: Result := FO.c_currency;
  2132. stInt: Result := FO.c_int;
  2133. stBoolean: Result := ord(FO.c_boolean);
  2134. stString:
  2135. begin
  2136. Val(FOString, cdouble, code);
  2137. if code = then
  2138. Result := cdouble else
  2139. Result := 0.0;
  2140. end;
  2141. else
  2142. Result := 0.0;
  2143. end;
  2144. end;
  2145.  
  2146. function TSuperObject.AsCurrency: Currency;
  2147. var
  2148. code: integer;
  2149. cdouble: double;
  2150. begin
  2151. case FDataType of
  2152. stDouble: Result := FO.c_double;
  2153. stCurrency: Result := FO.c_currency;
  2154. stInt: Result := FO.c_int;
  2155. stBoolean: Result := ord(FO.c_boolean);
  2156. stString:
  2157. begin
  2158. Val(FOString, cdouble, code);
  2159. if code = then
  2160. Result := cdouble else
  2161. Result := 0.0;
  2162. end;
  2163. else
  2164. Result := 0.0;
  2165. end;
  2166. end;
  2167.  
  2168. function TSuperObject.AsString: SOString;
  2169. begin
  2170. if FDataType = stString then
  2171. Result := FOString else
  2172. Result := AsJSon(false, false);
  2173. end;
  2174.  
  2175. function TSuperObject.GetEnumerator: TSuperEnumerator;
  2176. begin
  2177. Result := TSuperEnumerator.Create(Self);
  2178. end;
  2179.  
  2180. procedure TSuperObject.AfterConstruction;
  2181. begin
  2182. InterlockedDecrement(FRefCount);
  2183. end;
  2184.  
  2185. procedure TSuperObject.BeforeDestruction;
  2186. begin
  2187. if RefCount <> then
  2188. raise Exception.Create('Invalid pointer');
  2189. end;
  2190.  
  2191. function TSuperObject.AsArray: TSuperArray;
  2192. begin
  2193. if FDataType = stArray then
  2194. Result := FO.c_array else
  2195. Result := nil;
  2196. end;
  2197.  
  2198. function TSuperObject.AsObject: TSuperTableString;
  2199. begin
  2200. if FDataType = stObject then
  2201. Result := FO.c_object else
  2202. Result := nil;
  2203. end;
  2204.  
  2205. function TSuperObject.AsJSon(indent, escape: boolean): SOString;
  2206. var
  2207. pb: TSuperWriterString;
  2208. begin
  2209. pb := TSuperWriterString.Create;
  2210. try
  2211. if(Write(pb, indent, escape, ) < ) then
  2212. begin
  2213. Result := '';
  2214. Exit;
  2215. end;
  2216. if pb.FBPos > then
  2217. Result := pb.FBuf else
  2218. Result := '';
  2219. finally
  2220. pb.Free;
  2221. end;
  2222. end;
  2223.  
  2224. class function TSuperObject.ParseString(s: PSOChar; strict: Boolean; partial: boolean; const this: ISuperObject;
  2225. options: TSuperFindOptions; const put: ISuperObject; dt: TSuperType): ISuperObject;
  2226. var
  2227. tok: TSuperTokenizer;
  2228. obj: ISuperObject;
  2229. begin
  2230. tok := TSuperTokenizer.Create;
  2231. obj := ParseEx(tok, s, -, strict, this, options, put, dt);
  2232. if(tok.err <> teSuccess) or (not partial and (s[tok.char_offset] <> #)) then
  2233. Result := nil else
  2234. Result := obj;
  2235. tok.Free;
  2236. end;
  2237.  
  2238. class function TSuperObject.ParseStream(stream: TStream; strict: Boolean;
  2239. partial: boolean; const this: ISuperObject; options: TSuperFindOptions;
  2240. const put: ISuperObject; dt: TSuperType): ISuperObject;
  2241. const
  2242. BUFFER_SIZE = ;
  2243. var
  2244. tok: TSuperTokenizer;
  2245. buffera: array[..BUFFER_SIZE-] of AnsiChar;
  2246. bufferw: array[..BUFFER_SIZE-] of SOChar;
  2247. bom: array[..] of byte;
  2248. unicode: boolean;
  2249. j, size: Integer;
  2250. st: string;
  2251. begin
  2252. st := '';
  2253. tok := TSuperTokenizer.Create;
  2254.  
  2255. if (stream.Read(bom, sizeof(bom)) = ) and (bom[] = $FF) and (bom[] = $FE) then
  2256. begin
  2257. unicode := true;
  2258. size := stream.Read(bufferw, BUFFER_SIZE * SizeOf(SoChar)) div SizeOf(SoChar);
  2259. end else
  2260. begin
  2261. unicode := false;
  2262. stream.Seek(, soFromBeginning);
  2263. size := stream.Read(buffera, BUFFER_SIZE);
  2264. end;
  2265.  
  2266. while size > do
  2267. begin
  2268. if not unicode then
  2269. for j := to size - do
  2270. bufferw[j] := SOChar(buffera[j]);
  2271. ParseEx(tok, bufferw, size, strict, this, options, put, dt);
  2272.  
  2273. if tok.err = teContinue then
  2274. begin
  2275. if not unicode then
  2276. size := stream.Read(buffera, BUFFER_SIZE) else
  2277. size := stream.Read(bufferw, BUFFER_SIZE * SizeOf(SoChar)) div SizeOf(SoChar);
  2278. end else
  2279. Break;
  2280. end;
  2281. if(tok.err <> teSuccess) or (not partial and (st[tok.char_offset] <> #)) then
  2282. Result := nil else
  2283. Result := tok.stack[tok.depth].current;
  2284. tok.Free;
  2285. end;
  2286.  
  2287. class function TSuperObject.ParseFile(const FileName: string; strict: Boolean;
  2288. partial: boolean; const this: ISuperObject; options: TSuperFindOptions;
  2289. const put: ISuperObject; dt: TSuperType): ISuperObject;
  2290. var
  2291. stream: TFileStream;
  2292. begin
  2293. stream := TFileStream.Create(FileName, fmOpenRead, fmShareDenyWrite);
  2294. try
  2295. Result := ParseStream(stream, strict, partial, this, options, put, dt);
  2296. finally
  2297. stream.Free;
  2298. end;
  2299. end;
  2300.  
  2301. class function TSuperObject.ParseEx(tok: TSuperTokenizer; str: PSOChar; len: integer;
  2302. strict: Boolean; const this: ISuperObject; options: TSuperFindOptions; const put: ISuperObject; dt: TSuperType): ISuperObject;
  2303.  
  2304. const
  2305. spaces = [#,#,#,#,#,#];
  2306. delimiters = ['"', '.', '[', ']', '{', '}', '(', ')', ',', ':', #];
  2307. reserved = delimiters + spaces;
  2308. path = ['a'..'z', 'A'..'Z', '.', '_'];
  2309.  
  2310. function hexdigit(x: SOChar): byte;
  2311. begin
  2312. if x <= '' then
  2313. Result := byte(x) - byte('') else
  2314. Result := (byte(x) and ) + ;
  2315. end;
  2316. function min(v1, v2: integer): integer; begin if v1 < v2 then result := v1 else result := v2 end;
  2317.  
  2318. var
  2319. obj: ISuperObject;
  2320. v: SOChar;
  2321. {$IFDEF SUPER_METHOD}
  2322. sm: TSuperMethod;
  2323. {$ENDIF}
  2324. numi: SuperInt;
  2325. numd: Double;
  2326. code: integer;
  2327. TokRec: PSuperTokenerSrec;
  2328. evalstack: integer;
  2329. p: PSOChar;
  2330.  
  2331. function IsEndDelimiter(v: AnsiChar): Boolean;
  2332. begin
  2333. if tok.depth > then
  2334. case tok.stack[tok.depth - ].state of
  2335. tsArrayAdd: Result := v in [',', ']', #];
  2336. tsObjectValueAdd: Result := v in [',', '}', #];
  2337. else
  2338. Result := v = #;
  2339. end else
  2340. Result := v = #;
  2341. end;
  2342.  
  2343. label out, redo_char;
  2344. begin
  2345. evalstack := ;
  2346. obj := nil;
  2347. Result := nil;
  2348. TokRec := @tok.stack[tok.depth];
  2349.  
  2350. tok.char_offset := ;
  2351. tok.err := teSuccess;
  2352.  
  2353. repeat
  2354. if (tok.char_offset = len) then
  2355. begin
  2356. if (tok.depth = ) and (TokRec^.state = tsEatws) and
  2357. (TokRec^.saved_state = tsFinish) then
  2358. tok.err := teSuccess else
  2359. tok.err := teContinue;
  2360. goto out;
  2361. end;
  2362.  
  2363. v := str^;
  2364.  
  2365. case v of
  2366. #:
  2367. begin
  2368. inc(tok.line);
  2369. tok.col := ;
  2370. end;
  2371. #: inc(tok.col, );
  2372. else
  2373. inc(tok.col);
  2374. end;
  2375.  
  2376. redo_char:
  2377. case TokRec^.state of
  2378. tsEatws:
  2379. begin
  2380. if (SOIChar(v) < ) and (AnsiChar(v) in spaces) then {nop} else
  2381. if (v = '/') then
  2382. begin
  2383. tok.pb.Reset;
  2384. tok.pb.Append(@v, );
  2385. TokRec^.state := tsCommentStart;
  2386. end else begin
  2387. TokRec^.state := TokRec^.saved_state;
  2388. goto redo_char;
  2389. end
  2390. end;
  2391.  
  2392. tsStart:
  2393. case v of
  2394. '"',
  2395. '''':
  2396. begin
  2397. TokRec^.state := tsString;
  2398. tok.pb.Reset;
  2399. tok.quote_char := v;
  2400. end;
  2401. '-':
  2402. begin
  2403. TokRec^.state := tsNumber;
  2404. tok.pb.Reset;
  2405. tok.is_double := ;
  2406. tok.floatcount := -;
  2407. goto redo_char;
  2408. end;
  2409.  
  2410. ''..'':
  2411. begin
  2412. if (tok.depth = ) then
  2413. case ObjectGetType(this) of
  2414. stObject:
  2415. begin
  2416. TokRec^.state := tsIdentifier;
  2417. TokRec^.current := this;
  2418. goto redo_char;
  2419. end;
  2420. end;
  2421. TokRec^.state := tsNumber;
  2422. tok.pb.Reset;
  2423. tok.is_double := ;
  2424. tok.floatcount := -;
  2425. goto redo_char;
  2426. end;
  2427. '{':
  2428. begin
  2429. TokRec^.state := tsEatws;
  2430. TokRec^.saved_state := tsObjectFieldStart;
  2431. TokRec^.current := TSuperObject.Create(stObject);
  2432. end;
  2433. '[':
  2434. begin
  2435. TokRec^.state := tsEatws;
  2436. TokRec^.saved_state := tsArray;
  2437. TokRec^.current := TSuperObject.Create(stArray);
  2438. end;
  2439. {$IFDEF SUPER_METHOD}
  2440. '(':
  2441. begin
  2442. if (tok.depth = ) and ObjectIsType(this, stMethod) then
  2443. begin
  2444. TokRec^.current := this;
  2445. TokRec^.state := tsParamValue;
  2446. end;
  2447. end;
  2448. {$ENDIF}
  2449. 'N',
  2450. 'n':
  2451. begin
  2452. TokRec^.state := tsNull;
  2453. tok.pb.Reset;
  2454. tok.st_pos := ;
  2455. goto redo_char;
  2456. end;
  2457. 'T',
  2458. 't',
  2459. 'F',
  2460. 'f':
  2461. begin
  2462. TokRec^.state := tsBoolean;
  2463. tok.pb.Reset;
  2464. tok.st_pos := ;
  2465. goto redo_char;
  2466. end;
  2467. else
  2468. TokRec^.state := tsIdentifier;
  2469. tok.pb.Reset;
  2470. goto redo_char;
  2471. end;
  2472.  
  2473. tsFinish:
  2474. begin
  2475. if(tok.depth = ) then goto out;
  2476. obj := TokRec^.current;
  2477. tok.ResetLevel(tok.depth);
  2478. dec(tok.depth);
  2479. TokRec := @tok.stack[tok.depth];
  2480. goto redo_char;
  2481. end;
  2482.  
  2483. tsNull:
  2484. begin
  2485. tok.pb.Append(@v, );
  2486. if (StrLComp(TOK_NULL, PSOChar(tok.pb.FBuf), min(tok.st_pos + , )) = ) then
  2487. begin
  2488. if (tok.st_pos = ) then
  2489. if (((SOIChar(v) < ) and (AnsiChar(v) in path)) or (SOIChar(v) >= )) then
  2490. TokRec^.state := tsIdentifier else
  2491. begin
  2492. TokRec^.current := TSuperObject.Create(stNull);
  2493. TokRec^.saved_state := tsFinish;
  2494. TokRec^.state := tsEatws;
  2495. goto redo_char;
  2496. end;
  2497. end else
  2498. begin
  2499. TokRec^.state := tsIdentifier;
  2500. tok.pb.FBuf[tok.st_pos] := #;
  2501. dec(tok.pb.FBPos);
  2502. goto redo_char;
  2503. end;
  2504. inc(tok.st_pos);
  2505. end;
  2506.  
  2507. tsCommentStart:
  2508. begin
  2509. if(v = '*') then
  2510. begin
  2511. TokRec^.state := tsComment;
  2512. end else
  2513. if (v = '/') then
  2514. begin
  2515. TokRec^.state := tsCommentEol;
  2516. end else
  2517. begin
  2518. tok.err := teParseComment;
  2519. goto out;
  2520. end;
  2521. tok.pb.Append(@v, );
  2522. end;
  2523.  
  2524. tsComment:
  2525. begin
  2526. if(v = '*') then
  2527. TokRec^.state := tsCommentEnd;
  2528. tok.pb.Append(@v, );
  2529. end;
  2530.  
  2531. tsCommentEol:
  2532. begin
  2533. if (v = #) then
  2534. TokRec^.state := tsEatws else
  2535. tok.pb.Append(@v, );
  2536. end;
  2537.  
  2538. tsCommentEnd:
  2539. begin
  2540. tok.pb.Append(@v, );
  2541. if (v = '/') then
  2542. TokRec^.state := tsEatws else
  2543. TokRec^.state := tsComment;
  2544. end;
  2545.  
  2546. tsString:
  2547. begin
  2548. if (v = tok.quote_char) then
  2549. begin
  2550. TokRec^.current := TSuperObject.Create(SOString(tok.pb.GetString));
  2551. TokRec^.saved_state := tsFinish;
  2552. TokRec^.state := tsEatws;
  2553. end else
  2554. if (v = '\') then
  2555. begin
  2556. TokRec^.saved_state := tsString;
  2557. TokRec^.state := tsStringEscape;
  2558. end else
  2559. begin
  2560. tok.pb.Append(@v, );
  2561. end
  2562. end;
  2563.  
  2564. tsEvalProperty:
  2565. begin
  2566. if (TokRec^.current = nil) and (foCreatePath in options) then
  2567. begin
  2568. TokRec^.current := TSuperObject.Create(stObject);
  2569. TokRec^.parent.AsObject.PutO(tok.pb.Fbuf, TokRec^.current)
  2570. end else
  2571. if not ObjectIsType(TokRec^.current, stObject) then
  2572. begin
  2573. tok.err := teEvalObject;
  2574. goto out;
  2575. end;
  2576. tok.pb.Reset;
  2577. TokRec^.state := tsIdentifier;
  2578. goto redo_char;
  2579. end;
  2580.  
  2581. tsEvalArray:
  2582. begin
  2583. if (TokRec^.current = nil) and (foCreatePath in options) then
  2584. begin
  2585. TokRec^.current := TSuperObject.Create(stArray);
  2586. TokRec^.parent.AsObject.PutO(tok.pb.Fbuf, TokRec^.current)
  2587. end else
  2588. if not ObjectIsType(TokRec^.current, stArray) then
  2589. begin
  2590. tok.err := teEvalArray;
  2591. goto out;
  2592. end;
  2593. tok.pb.Reset;
  2594. TokRec^.state := tsParamValue;
  2595. goto redo_char;
  2596. end;
  2597. {$IFDEF SUPER_METHOD}
  2598. tsEvalMethod:
  2599. begin
  2600. if ObjectIsType(TokRec^.current, stMethod) and assigned(TokRec^.current.AsMethod) then
  2601. begin
  2602. tok.pb.Reset;
  2603. TokRec^.obj := TSuperObject.Create(stArray);
  2604. TokRec^.state := tsMethodValue;
  2605. goto redo_char;
  2606. end else
  2607. begin
  2608. tok.err := teEvalMethod;
  2609. goto out;
  2610. end;
  2611. end;
  2612.  
  2613. tsMethodValue:
  2614. begin
  2615. case v of
  2616. ')':
  2617. TokRec^.state := tsIdentifier;
  2618. else
  2619. if (tok.depth >= SUPER_TOKENER_MAX_DEPTH-) then
  2620. begin
  2621. tok.err := teDepth;
  2622. goto out;
  2623. end;
  2624. inc(evalstack);
  2625. TokRec^.state := tsMethodPut;
  2626. inc(tok.depth);
  2627. tok.ResetLevel(tok.depth);
  2628. TokRec := @tok.stack[tok.depth];
  2629. goto redo_char;
  2630. end;
  2631. end;
  2632.  
  2633. tsMethodPut:
  2634. begin
  2635. TokRec^.obj.AsArray.Add(obj);
  2636. case v of
  2637. ',':
  2638. begin
  2639. tok.pb.Reset;
  2640. TokRec^.saved_state := tsMethodValue;
  2641. TokRec^.state := tsEatws;
  2642. end;
  2643. ')':
  2644. begin
  2645. if TokRec^.obj.AsArray.Length = then
  2646. TokRec^.obj := TokRec^.obj.AsArray.GetO();
  2647. dec(evalstack);
  2648. tok.pb.Reset;
  2649. TokRec^.saved_state := tsIdentifier;
  2650. TokRec^.state := tsEatws;
  2651. end;
  2652. else
  2653. tok.err := teEvalMethod;
  2654. goto out;
  2655. end;
  2656. end;
  2657. {$ENDIF}
  2658. tsParamValue:
  2659. begin
  2660. case v of
  2661. ']':
  2662. TokRec^.state := tsIdentifier;
  2663. else
  2664. if (tok.depth >= SUPER_TOKENER_MAX_DEPTH-) then
  2665. begin
  2666. tok.err := teDepth;
  2667. goto out;
  2668. end;
  2669. inc(evalstack);
  2670. TokRec^.state := tsParamPut;
  2671. inc(tok.depth);
  2672. tok.ResetLevel(tok.depth);
  2673. TokRec := @tok.stack[tok.depth];
  2674. goto redo_char;
  2675. end;
  2676. end;
  2677.  
  2678. tsParamPut:
  2679. begin
  2680. dec(evalstack);
  2681. TokRec^.obj := obj;
  2682. tok.pb.Reset;
  2683. TokRec^.saved_state := tsIdentifier;
  2684. TokRec^.state := tsEatws;
  2685. if v <> ']' then
  2686. begin
  2687. tok.err := teEvalArray;
  2688. goto out;
  2689. end;
  2690. end;
  2691.  
  2692. tsIdentifier:
  2693. begin
  2694. if (this = nil) then
  2695. begin
  2696. if (SOIChar(v) < ) and IsEndDelimiter(AnsiChar(v)) then
  2697. begin
  2698. if not strict then
  2699. begin
  2700. tok.pb.TrimRight;
  2701. TokRec^.current := TSuperObject.Create(tok.pb.Fbuf);
  2702. TokRec^.saved_state := tsFinish;
  2703. TokRec^.state := tsEatws;
  2704. goto redo_char;
  2705. end else
  2706. begin
  2707. tok.err := teParseString;
  2708. goto out;
  2709. end;
  2710. end else
  2711. if (v = '\') then
  2712. begin
  2713. TokRec^.saved_state := tsIdentifier;
  2714. TokRec^.state := tsStringEscape;
  2715. end else
  2716. tok.pb.Append(@v, );
  2717. end else
  2718. begin
  2719. if (SOIChar(v) < ) and (AnsiChar(v) in reserved) then
  2720. begin
  2721. TokRec^.gparent := TokRec^.parent;
  2722. if TokRec^.current = nil then
  2723. TokRec^.parent := this else
  2724. TokRec^.parent := TokRec^.current;
  2725.  
  2726. case ObjectGetType(TokRec^.parent) of
  2727. stObject:
  2728. case v of
  2729. '.':
  2730. begin
  2731. TokRec^.state := tsEvalProperty;
  2732. if tok.pb.FBPos > then
  2733. TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf);
  2734. end;
  2735. '[':
  2736. begin
  2737. TokRec^.state := tsEvalArray;
  2738. if tok.pb.FBPos > then
  2739. TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf);
  2740. end;
  2741. '(':
  2742. begin
  2743. TokRec^.state := tsEvalMethod;
  2744. if tok.pb.FBPos > then
  2745. TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf);
  2746. end;
  2747. else
  2748. if tok.pb.FBPos > then
  2749. TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf);
  2750. if (foPutValue in options) and (evalstack = ) then
  2751. begin
  2752. TokRec^.parent.AsObject.PutO(tok.pb.Fbuf, put);
  2753. TokRec^.current := put
  2754. end else
  2755. if (foDelete in options) and (evalstack = ) then
  2756. begin
  2757. TokRec^.current := TokRec^.parent.AsObject.Delete(tok.pb.Fbuf);
  2758. end else
  2759. if (TokRec^.current = nil) and (foCreatePath in options) then
  2760. begin
  2761. TokRec^.current := TSuperObject.Create(dt);
  2762. TokRec^.parent.AsObject.PutO(tok.pb.Fbuf, TokRec^.current);
  2763. end;
  2764. TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf);
  2765. TokRec^.state := tsFinish;
  2766. goto redo_char;
  2767. end;
  2768. stArray:
  2769. begin
  2770. if TokRec^.obj <> nil then
  2771. begin
  2772. if not ObjectIsType(TokRec^.obj, stInt) or (TokRec^.obj.AsInteger < ) then
  2773. begin
  2774. tok.err := teEvalInt;
  2775. TokRec^.obj := nil;
  2776. goto out;
  2777. end;
  2778. numi := TokRec^.obj.AsInteger;
  2779. TokRec^.obj := nil;
  2780.  
  2781. TokRec^.current := TokRec^.parent.AsArray.GetO(numi);
  2782. case v of
  2783. '.':
  2784. if (TokRec^.current = nil) and (foCreatePath in options) then
  2785. begin
  2786. TokRec^.current := TSuperObject.Create(stObject);
  2787. TokRec^.parent.AsArray.PutO(numi, TokRec^.current);
  2788. end else
  2789. if (TokRec^.current = nil) then
  2790. begin
  2791. tok.err := teEvalObject;
  2792. goto out;
  2793. end;
  2794. '[':
  2795. begin
  2796. if (TokRec^.current = nil) and (foCreatePath in options) then
  2797. begin
  2798. TokRec^.current := TSuperObject.Create(stArray);
  2799. TokRec^.parent.AsArray.Add(TokRec^.current);
  2800. end else
  2801. if (TokRec^.current = nil) then
  2802. begin
  2803. tok.err := teEvalArray;
  2804. goto out;
  2805. end;
  2806. TokRec^.state := tsEvalArray;
  2807. end;
  2808. '(': TokRec^.state := tsEvalMethod;
  2809. else
  2810. if (foPutValue in options) and (evalstack = ) then
  2811. begin
  2812. TokRec^.parent.AsArray.PutO(numi, put);
  2813. TokRec^.current := put;
  2814. end else
  2815. if (foDelete in options) and (evalstack = ) then
  2816. begin
  2817. TokRec^.current := TokRec^.parent.AsArray.Delete(numi);
  2818. end else
  2819. TokRec^.current := TokRec^.parent.AsArray.GetO(numi);
  2820. TokRec^.state := tsFinish;
  2821. goto redo_char
  2822. end;
  2823. end else
  2824. begin
  2825. case v of
  2826. '.':
  2827. begin
  2828. if (foPutValue in options) then
  2829. begin
  2830. TokRec^.current := TSuperObject.Create(stObject);
  2831. TokRec^.parent.AsArray.Add(TokRec^.current);
  2832. end else
  2833. TokRec^.current := TokRec^.parent.AsArray.GetO(TokRec^.parent.AsArray.FLength - );
  2834. end;
  2835. '[':
  2836. begin
  2837. if (foPutValue in options) then
  2838. begin
  2839. TokRec^.current := TSuperObject.Create(stArray);
  2840. TokRec^.parent.AsArray.Add(TokRec^.current);
  2841. end else
  2842. TokRec^.current := TokRec^.parent.AsArray.GetO(TokRec^.parent.AsArray.FLength - );
  2843. TokRec^.state := tsEvalArray;
  2844. end;
  2845. '(':
  2846. begin
  2847. if not (foPutValue in options) then
  2848. TokRec^.current := TokRec^.parent.AsArray.GetO(TokRec^.parent.AsArray.FLength - ) else
  2849. TokRec^.current := nil;
  2850.  
  2851. TokRec^.state := tsEvalMethod;
  2852. end;
  2853. else
  2854. if (foPutValue in options) and (evalstack = ) then
  2855. begin
  2856. TokRec^.parent.AsArray.Add(put);
  2857. TokRec^.current := put;
  2858. end else
  2859. if tok.pb.FBPos = then
  2860. TokRec^.current := TokRec^.parent.AsArray.GetO(TokRec^.parent.AsArray.FLength - );
  2861. TokRec^.state := tsFinish;
  2862. goto redo_char
  2863. end;
  2864. end;
  2865. end;
  2866. {$IFDEF SUPER_METHOD}
  2867. stMethod:
  2868. case v of
  2869. '.':
  2870. begin
  2871. TokRec^.current := nil;
  2872. sm := TokRec^.parent.AsMethod;
  2873. sm(TokRec^.gparent, TokRec^.obj, TokRec^.current);
  2874. TokRec^.obj := nil;
  2875. end;
  2876. '[':
  2877. begin
  2878. TokRec^.current := nil;
  2879. sm := TokRec^.parent.AsMethod;
  2880. sm(TokRec^.gparent, TokRec^.obj, TokRec^.current);
  2881. TokRec^.state := tsEvalArray;
  2882. TokRec^.obj := nil;
  2883. end;
  2884. '(':
  2885. begin
  2886. TokRec^.current := nil;
  2887. sm := TokRec^.parent.AsMethod;
  2888. sm(TokRec^.gparent, TokRec^.obj, TokRec^.current);
  2889. TokRec^.state := tsEvalMethod;
  2890. TokRec^.obj := nil;
  2891. end;
  2892. else
  2893. if not (foPutValue in options) or (evalstack > ) then
  2894. begin
  2895. TokRec^.current := nil;
  2896. sm := TokRec^.parent.AsMethod;
  2897. sm(TokRec^.gparent, TokRec^.obj, TokRec^.current);
  2898. TokRec^.obj := nil;
  2899. TokRec^.state := tsFinish;
  2900. goto redo_char
  2901. end else
  2902. begin
  2903. tok.err := teEvalMethod;
  2904. TokRec^.obj := nil;
  2905. goto out;
  2906. end;
  2907. end;
  2908. {$ENDIF}
  2909. end;
  2910. end else
  2911. tok.pb.Append(@v, );
  2912. end;
  2913. end;
  2914.  
  2915. tsStringEscape:
  2916. case v of
  2917. 'b',
  2918. 'n',
  2919. 'r',
  2920. 't',
  2921. 'f':
  2922. begin
  2923. if(v = 'b') then tok.pb.Append(TOK_BS, )
  2924. else if(v = 'n') then tok.pb.Append(TOK_LF, )
  2925. else if(v = 'r') then tok.pb.Append(TOK_CR, )
  2926. else if(v = 't') then tok.pb.Append(TOK_TAB, )
  2927. else if(v = 'f') then tok.pb.Append(TOK_FF, );
  2928. TokRec^.state := TokRec^.saved_state;
  2929. end;
  2930. 'u':
  2931. begin
  2932. tok.ucs_char := ;
  2933. tok.st_pos := ;
  2934. TokRec^.state := tsEscapeUnicode;
  2935. end;
  2936. 'x':
  2937. begin
  2938. tok.ucs_char := ;
  2939. tok.st_pos := ;
  2940. TokRec^.state := tsEscapeHexadecimal;
  2941. end
  2942. else
  2943. tok.pb.Append(@v, );
  2944. TokRec^.state := TokRec^.saved_state;
  2945. end;
  2946.  
  2947. tsEscapeUnicode:
  2948. begin
  2949. if ((SOIChar(v) < ) and (AnsiChar(v) in super_hex_chars_set)) then
  2950. begin
  2951. inc(tok.ucs_char, (Word(hexdigit(v)) shl ((-tok.st_pos)*)));
  2952. inc(tok.st_pos);
  2953. if (tok.st_pos = ) then
  2954. begin
  2955. tok.pb.Append(@tok.ucs_char, );
  2956. TokRec^.state := TokRec^.saved_state;
  2957. end
  2958. end else
  2959. begin
  2960. tok.err := teParseString;
  2961. goto out;
  2962. end
  2963. end;
  2964. tsEscapeHexadecimal:
  2965. begin
  2966. if ((SOIChar(v) < ) and (AnsiChar(v) in super_hex_chars_set)) then
  2967. begin
  2968. inc(tok.ucs_char, (Word(hexdigit(v)) shl ((-tok.st_pos)*)));
  2969. inc(tok.st_pos);
  2970. if (tok.st_pos = ) then
  2971. begin
  2972. tok.pb.Append(@tok.ucs_char, );
  2973. TokRec^.state := TokRec^.saved_state;
  2974. end
  2975. end else
  2976. begin
  2977. tok.err := teParseString;
  2978. goto out;
  2979. end
  2980. end;
  2981. tsBoolean:
  2982. begin
  2983. tok.pb.Append(@v, );
  2984. if (StrLComp('true', PSOChar(tok.pb.FBuf), min(tok.st_pos + , )) = ) then
  2985. begin
  2986. if (tok.st_pos = ) then
  2987. if (((SOIChar(v) < ) and (AnsiChar(v) in path)) or (SOIChar(v) >= )) then
  2988. TokRec^.state := tsIdentifier else
  2989. begin
  2990. TokRec^.current := TSuperObject.Create(true);
  2991. TokRec^.saved_state := tsFinish;
  2992. TokRec^.state := tsEatws;
  2993. goto redo_char;
  2994. end
  2995. end else
  2996. if (StrLComp('false', PSOChar(tok.pb.FBuf), min(tok.st_pos + , )) = ) then
  2997. begin
  2998. if (tok.st_pos = ) then
  2999. if (((SOIChar(v) < ) and (AnsiChar(v) in path)) or (SOIChar(v) >= )) then
  3000. TokRec^.state := tsIdentifier else
  3001. begin
  3002. TokRec^.current := TSuperObject.Create(false);
  3003. TokRec^.saved_state := tsFinish;
  3004. TokRec^.state := tsEatws;
  3005. goto redo_char;
  3006. end
  3007. end else
  3008. begin
  3009. TokRec^.state := tsIdentifier;
  3010. tok.pb.FBuf[tok.st_pos] := #;
  3011. dec(tok.pb.FBPos);
  3012. goto redo_char;
  3013. end;
  3014. inc(tok.st_pos);
  3015. end;
  3016.  
  3017. tsNumber:
  3018. begin
  3019. if (SOIChar(v) < ) and (AnsiChar(v) in super_number_chars_set) then
  3020. begin
  3021. tok.pb.Append(@v, );
  3022. if (SOIChar(v) < ) then
  3023. case v of
  3024. '.': begin
  3025. tok.is_double := ;
  3026. tok.floatcount := ;
  3027. end;
  3028. 'e','E':
  3029. begin
  3030. tok.is_double := ;
  3031. tok.floatcount := -;
  3032. end;
  3033. ''..'':
  3034. begin
  3035.  
  3036. if (tok.is_double = ) and (tok.floatcount >= ) then
  3037. begin
  3038. inc(tok.floatcount);
  3039. if tok.floatcount > then
  3040. tok.floatcount := -;
  3041. end;
  3042. end;
  3043. end;
  3044. end else
  3045. begin
  3046. if (tok.is_double = ) then
  3047. begin
  3048. val(tok.pb.FBuf, numi, code);
  3049. if ObjectIsType(this, stArray) then
  3050. begin
  3051. if (foPutValue in options) and (evalstack = ) then
  3052. begin
  3053. this.AsArray.PutO(numi, put);
  3054. TokRec^.current := put;
  3055. end else
  3056. if (foDelete in options) and (evalstack = ) then
  3057. TokRec^.current := this.AsArray.Delete(numi) else
  3058. TokRec^.current := this.AsArray.GetO(numi);
  3059. end else
  3060. TokRec^.current := TSuperObject.Create(numi);
  3061.  
  3062. end else
  3063. if (tok.is_double <> ) then
  3064. begin
  3065. if tok.floatcount >= then
  3066. begin
  3067. p := tok.pb.FBuf;
  3068. while p^ <> '.' do inc(p);
  3069. for code := to tok.floatcount - do
  3070. begin
  3071. p^ := p[];
  3072. inc(p);
  3073. end;
  3074. p^ := #;
  3075. val(tok.pb.FBuf, numi, code);
  3076. case tok.floatcount of
  3077. : numi := numi * ;
  3078. : numi := numi * ;
  3079. : numi := numi * ;
  3080. : numi := numi * ;
  3081. end;
  3082. TokRec^.current := TSuperObject.CreateCurrency(PCurrency(@numi)^);
  3083. end else
  3084. begin
  3085. val(tok.pb.FBuf, numd, code);
  3086. TokRec^.current := TSuperObject.Create(numd);
  3087. end;
  3088. end else
  3089. begin
  3090. tok.err := teParseNumber;
  3091. goto out;
  3092. end;
  3093. TokRec^.saved_state := tsFinish;
  3094. TokRec^.state := tsEatws;
  3095. goto redo_char;
  3096. end
  3097. end;
  3098.  
  3099. tsArray:
  3100. begin
  3101. if (v = ']') then
  3102. begin
  3103. TokRec^.saved_state := tsFinish;
  3104. TokRec^.state := tsEatws;
  3105. end else
  3106. begin
  3107. if(tok.depth >= SUPER_TOKENER_MAX_DEPTH-) then
  3108. begin
  3109. tok.err := teDepth;
  3110. goto out;
  3111. end;
  3112. TokRec^.state := tsArrayAdd;
  3113. inc(tok.depth);
  3114. tok.ResetLevel(tok.depth);
  3115. TokRec := @tok.stack[tok.depth];
  3116. goto redo_char;
  3117. end
  3118. end;
  3119.  
  3120. tsArrayAdd:
  3121. begin
  3122. TokRec^.current.AsArray.Add(obj);
  3123. TokRec^.saved_state := tsArraySep;
  3124. TokRec^.state := tsEatws;
  3125. goto redo_char;
  3126. end;
  3127.  
  3128. tsArraySep:
  3129. begin
  3130. if (v = ']') then
  3131. begin
  3132. TokRec^.saved_state := tsFinish;
  3133. TokRec^.state := tsEatws;
  3134. end else
  3135. if (v = ',') then
  3136. begin
  3137. TokRec^.saved_state := tsArray;
  3138. TokRec^.state := tsEatws;
  3139. end else
  3140. begin
  3141. tok.err := teParseArray;
  3142. goto out;
  3143. end
  3144. end;
  3145.  
  3146. tsObjectFieldStart:
  3147. begin
  3148. if (v = '}') then
  3149. begin
  3150. TokRec^.saved_state := tsFinish;
  3151. TokRec^.state := tsEatws;
  3152. end else
  3153. if (SOIChar(v) < ) and (AnsiChar(v) in ['"', '''']) then
  3154. begin
  3155. tok.quote_char := v;
  3156. tok.pb.Reset;
  3157. TokRec^.state := tsObjectField;
  3158. end else
  3159. if not((SOIChar(v) < ) and ((AnsiChar(v) in reserved) or strict)) then
  3160. begin
  3161. TokRec^.state := tsObjectUnquotedField;
  3162. tok.pb.Reset;
  3163. goto redo_char;
  3164. end else
  3165. begin
  3166. tok.err := teParseObjectKeyName;
  3167. goto out;
  3168. end
  3169. end;
  3170.  
  3171. tsObjectField:
  3172. begin
  3173. if (v = tok.quote_char) then
  3174. begin
  3175. TokRec^.field_name := tok.pb.FBuf;
  3176. TokRec^.saved_state := tsObjectFieldEnd;
  3177. TokRec^.state := tsEatws;
  3178. end else
  3179. if (v = '\') then
  3180. begin
  3181. TokRec^.saved_state := tsObjectField;
  3182. TokRec^.state := tsStringEscape;
  3183. end else
  3184. begin
  3185. tok.pb.Append(@v, );
  3186. end
  3187. end;
  3188.  
  3189. tsObjectUnquotedField:
  3190. begin
  3191. if (SOIChar(v) < ) and (AnsiChar(v) in [':', #]) then
  3192. begin
  3193. TokRec^.field_name := tok.pb.FBuf;
  3194. TokRec^.saved_state := tsObjectFieldEnd;
  3195. TokRec^.state := tsEatws;
  3196. goto redo_char;
  3197. end else
  3198. if (v = '\') then
  3199. begin
  3200. TokRec^.saved_state := tsObjectUnquotedField;
  3201. TokRec^.state := tsStringEscape;
  3202. end else
  3203. tok.pb.Append(@v, );
  3204. end;
  3205.  
  3206. tsObjectFieldEnd:
  3207. begin
  3208. if (v = ':') then
  3209. begin
  3210. TokRec^.saved_state := tsObjectValue;
  3211. TokRec^.state := tsEatws;
  3212. end else
  3213. begin
  3214. tok.err := teParseObjectKeySep;
  3215. goto out;
  3216. end
  3217. end;
  3218.  
  3219. tsObjectValue:
  3220. begin
  3221. if (tok.depth >= SUPER_TOKENER_MAX_DEPTH-) then
  3222. begin
  3223. tok.err := teDepth;
  3224. goto out;
  3225. end;
  3226. TokRec^.state := tsObjectValueAdd;
  3227. inc(tok.depth);
  3228. tok.ResetLevel(tok.depth);
  3229. TokRec := @tok.stack[tok.depth];
  3230. goto redo_char;
  3231. end;
  3232.  
  3233. tsObjectValueAdd:
  3234. begin
  3235. TokRec^.current.AsObject.PutO(TokRec^.field_name, obj);
  3236. TokRec^.field_name := '';
  3237. TokRec^.saved_state := tsObjectSep;
  3238. TokRec^.state := tsEatws;
  3239. goto redo_char;
  3240. end;
  3241.  
  3242. tsObjectSep:
  3243. begin
  3244. if (v = '}') then
  3245. begin
  3246. TokRec^.saved_state := tsFinish;
  3247. TokRec^.state := tsEatws;
  3248. end else
  3249. if (v = ',') then
  3250. begin
  3251. TokRec^.saved_state := tsObjectFieldStart;
  3252. TokRec^.state := tsEatws;
  3253. end else
  3254. begin
  3255. tok.err := teParseObjectValueSep;
  3256. goto out;
  3257. end
  3258. end;
  3259. end;
  3260. inc(str);
  3261. inc(tok.char_offset);
  3262. until v = #;
  3263.  
  3264. if(TokRec^.state <> tsFinish) and
  3265. (TokRec^.saved_state <> tsFinish) then
  3266. tok.err := teParseEof;
  3267.  
  3268. out:
  3269. if(tok.err in [teSuccess]) then
  3270. begin
  3271. {$IFDEF SUPER_METHOD}
  3272. if (foCallMethod in options) and ObjectIsType(TokRec^.current, stMethod) and assigned(TokRec^.current.AsMethod) then
  3273. begin
  3274. sm := TokRec^.current.AsMethod;
  3275. sm(TokRec^.parent, put, Result);
  3276. end else
  3277. {$ENDIF}
  3278. Result := TokRec^.current;
  3279. end else
  3280. Result := nil;
  3281. end;
  3282.  
  3283. procedure TSuperObject.PutO(const path: SOString; const Value: ISuperObject);
  3284. begin
  3285. ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], Value);
  3286. end;
  3287.  
  3288. procedure TSuperObject.PutB(const path: SOString; Value: Boolean);
  3289. begin
  3290. ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.Create(Value));
  3291. end;
  3292.  
  3293. procedure TSuperObject.PutD(const path: SOString; Value: Double);
  3294. begin
  3295. ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.Create(Value));
  3296. end;
  3297.  
  3298. procedure TSuperObject.PutC(const path: SOString; Value: Currency);
  3299. begin
  3300. ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.CreateCurrency(Value));
  3301. end;
  3302.  
  3303. procedure TSuperObject.PutI(const path: SOString; Value: SuperInt);
  3304. begin
  3305. ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.Create(Value));
  3306. end;
  3307.  
  3308. procedure TSuperObject.PutS(const path: SOString; const Value: SOString);
  3309. begin
  3310. ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.Create(Value));
  3311. end;
  3312.  
  3313. function TSuperObject.QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
  3314. begin
  3315. if GetInterface(IID, Obj) then
  3316. Result :=
  3317. else
  3318. Result := E_NOINTERFACE;
  3319. end;
  3320.  
  3321. function TSuperObject.SaveTo(stream: TStream; indent, escape: boolean): integer;
  3322. var
  3323. pb: TSuperWriterStream;
  3324. begin
  3325. if escape then
  3326. pb := TSuperAnsiWriterStream.Create(stream) else
  3327. pb := TSuperUnicodeWriterStream.Create(stream);
  3328.  
  3329. if(Write(pb, indent, escape, ) < ) then
  3330. begin
  3331. pb.Reset;
  3332. pb.Free;
  3333. Result := ;
  3334. Exit;
  3335. end;
  3336. Result := stream.Size;
  3337. pb.Free;
  3338. end;
  3339.  
  3340. function TSuperObject.CalcSize(indent, escape: boolean): integer;
  3341. var
  3342. pb: TSuperWriterFake;
  3343. begin
  3344. pb := TSuperWriterFake.Create;
  3345. if(Write(pb, indent, escape, ) < ) then
  3346. begin
  3347. pb.Free;
  3348. Result := ;
  3349. Exit;
  3350. end;
  3351. Result := pb.FSize;
  3352. pb.Free;
  3353. end;
  3354.  
  3355. function TSuperObject.SaveTo(socket: Integer; indent, escape: boolean): integer;
  3356. var
  3357. pb: TSuperWriterSock;
  3358. begin
  3359. pb := TSuperWriterSock.Create(socket);
  3360. if(Write(pb, indent, escape, ) < ) then
  3361. begin
  3362. pb.Free;
  3363. Result := ;
  3364. Exit;
  3365. end;
  3366. Result := pb.FSize;
  3367. pb.Free;
  3368. end;
  3369.  
  3370. constructor TSuperObject.Create(const s: SOString);
  3371. begin
  3372. Create(stString);
  3373. FOString := s;
  3374. end;
  3375.  
  3376. procedure TSuperObject.Clear(all: boolean);
  3377. begin
  3378. if FProcessing then exit;
  3379. FProcessing := true;
  3380. try
  3381. case FDataType of
  3382. stBoolean: FO.c_boolean := false;
  3383. stDouble: FO.c_double := 0.0;
  3384. stCurrency: FO.c_currency := 0.0;
  3385. stInt: FO.c_int := ;
  3386. stObject: FO.c_object.Clear(all);
  3387. stArray: FO.c_array.Clear(all);
  3388. stString: FOString := '';
  3389. {$IFDEF SUPER_METHOD}
  3390. stMethod: FO.c_method := nil;
  3391. {$ENDIF}
  3392. end;
  3393. finally
  3394. FProcessing := false;
  3395. end;
  3396. end;
  3397.  
  3398. procedure TSuperObject.Pack(all: boolean = false);
  3399. begin
  3400. if FProcessing then exit;
  3401. FProcessing := true;
  3402. try
  3403. case FDataType of
  3404. stObject: FO.c_object.Pack(all);
  3405. stArray: FO.c_array.Pack(all);
  3406. end;
  3407. finally
  3408. FProcessing := false;
  3409. end;
  3410. end;
  3411.  
  3412. function TSuperObject.GetN(const path: SOString): ISuperObject;
  3413. begin
  3414. Result := ParseString(PSOChar(path), False, true, self);
  3415. if Result = nil then
  3416. Result := TSuperObject.Create(stNull);
  3417. end;
  3418.  
  3419. procedure TSuperObject.PutN(const path: SOString; const Value: ISuperObject);
  3420. begin
  3421. if Value = nil then
  3422. ParseString(PSOChar(path), False, True, self, [foCreatePath, foPutValue], TSuperObject.Create(stNull)) else
  3423. ParseString(PSOChar(path), False, True, self, [foCreatePath, foPutValue], Value);
  3424. end;
  3425.  
  3426. function TSuperObject.Delete(const path: SOString): ISuperObject;
  3427. begin
  3428. Result := ParseString(PSOChar(path), False, true, self, [foDelete]);
  3429. end;
  3430.  
  3431. function TSuperObject.Clone: ISuperObject;
  3432. var
  3433. ite: TSuperObjectIter;
  3434. arr: TSuperArray;
  3435. j: integer;
  3436. begin
  3437. case FDataType of
  3438. stBoolean: Result := TSuperObject.Create(FO.c_boolean);
  3439. stDouble: Result := TSuperObject.Create(FO.c_double);
  3440. stCurrency: Result := TSuperObject.CreateCurrency(FO.c_currency);
  3441. stInt: Result := TSuperObject.Create(FO.c_int);
  3442. stString: Result := TSuperObject.Create(FOString);
  3443. {$IFDEF SUPER_METHOD}
  3444. stMethod: Result := TSuperObject.Create(FO.c_method);
  3445. {$ENDIF}
  3446. stObject:
  3447. begin
  3448. Result := TSuperObject.Create(stObject);
  3449. if ObjectFindFirst(self, ite) then
  3450. with Result.AsObject do
  3451. repeat
  3452. PutO(ite.key, ite.val.Clone);
  3453. until not ObjectFindNext(ite);
  3454. ObjectFindClose(ite);
  3455. end;
  3456. stArray:
  3457. begin
  3458. Result := TSuperObject.Create(stArray);
  3459. arr := AsArray;
  3460. with Result.AsArray do
  3461. for j := to arr.Length - do
  3462. Add(arr.GetO(j).Clone);
  3463. end;
  3464. else
  3465. Result := nil;
  3466. end;
  3467. end;
  3468.  
  3469. procedure TSuperObject.Merge(const obj: ISuperObject; reference: boolean);
  3470. var
  3471. prop1, prop2: ISuperObject;
  3472. ite: TSuperObjectIter;
  3473. arr: TSuperArray;
  3474. j: integer;
  3475. begin
  3476. if ObjectIsType(obj, FDataType) then
  3477. case FDataType of
  3478. stBoolean: FO.c_boolean := obj.AsBoolean;
  3479. stDouble: FO.c_double := obj.AsDouble;
  3480. stCurrency: FO.c_currency := obj.AsCurrency;
  3481. stInt: FO.c_int := obj.AsInteger;
  3482. stString: FOString := obj.AsString;
  3483. {$IFDEF SUPER_METHOD}
  3484. stMethod: FO.c_method := obj.AsMethod;
  3485. {$ENDIF}
  3486. stObject:
  3487. begin
  3488. if ObjectFindFirst(obj, ite) then
  3489. with FO.c_object do
  3490. repeat
  3491. prop1 := FO.c_object.GetO(ite.key);
  3492. if (prop1 <> nil) and (ite.val <> nil) and (prop1.DataType = ite.val.DataType) then
  3493. prop1.Merge(ite.val) else
  3494. if reference then
  3495. PutO(ite.key, ite.val) else
  3496. PutO(ite.key, ite.val.Clone);
  3497. until not ObjectFindNext(ite);
  3498. ObjectFindClose(ite);
  3499. end;
  3500. stArray:
  3501. begin
  3502. arr := obj.AsArray;
  3503. with FO.c_array do
  3504. for j := to arr.Length - do
  3505. begin
  3506. prop1 := GetO(j);
  3507. prop2 := arr.GetO(j);
  3508. if (prop1 <> nil) and (prop2 <> nil) and (prop1.DataType = prop2.DataType) then
  3509. prop1.Merge(prop2) else
  3510. if reference then
  3511. PutO(j, prop2) else
  3512. PutO(j, prop2.Clone);
  3513. end;
  3514. end;
  3515. end;
  3516. end;
  3517.  
  3518. procedure TSuperObject.Merge(const str: SOString);
  3519. begin
  3520. Merge(TSuperObject.ParseString(PSOChar(str), False), true);
  3521. end;
  3522.  
  3523. class function TSuperObject.NewInstance: TObject;
  3524. begin
  3525. Result := inherited NewInstance;
  3526. TSuperObject(Result).FRefCount := ;
  3527. end;
  3528.  
  3529. function TSuperObject.ForcePath(const path: SOString; dataType: TSuperType = stObject): ISuperObject;
  3530. begin
  3531. Result := ParseString(PSOChar(path), False, True, Self, [foCreatePath], nil, dataType);
  3532. end;
  3533.  
  3534. function TSuperObject.Format(const str: SOString; BeginSep: SOChar; EndSep: SOChar): SOString;
  3535. var
  3536. p1, p2: PSOChar;
  3537. begin
  3538. Result := '';
  3539. p2 := PSOChar(str);
  3540. p1 := p2;
  3541. while true do
  3542. if p2^ = BeginSep then
  3543. begin
  3544. if p2 > p1 then
  3545. Result := Result + Copy(p1, , p2-p1);
  3546. inc(p2);
  3547. p1 := p2;
  3548. while true do
  3549. if p2^ = EndSep then Break else
  3550. if p2^ = # then Exit else
  3551. inc(p2);
  3552. Result := Result + GetS(copy(p1, , p2-p1));
  3553. inc(p2);
  3554. p1 := p2;
  3555. end
  3556. else if p2^ = # then
  3557. begin
  3558. if p2 > p1 then
  3559. Result := Result + Copy(p1, , p2-p1);
  3560. Break;
  3561. end else
  3562. inc(p2);
  3563. end;
  3564.  
  3565. function TSuperObject.GetO(const path: SOString): ISuperObject;
  3566. begin
  3567. Result := ParseString(PSOChar(path), False, True, Self);
  3568. end;
  3569.  
  3570. function TSuperObject.GetA(const path: SOString): TSuperArray;
  3571. var
  3572. obj: ISuperObject;
  3573. begin
  3574. obj := ParseString(PSOChar(path), False, True, Self);
  3575. if obj <> nil then
  3576. Result := obj.AsArray else
  3577. Result := nil;
  3578. end;
  3579.  
  3580. function TSuperObject.GetB(const path: SOString): Boolean;
  3581. var
  3582. obj: ISuperObject;
  3583. begin
  3584. obj := GetO(path);
  3585. if obj <> nil then
  3586. Result := obj.AsBoolean else
  3587. Result := false;
  3588. end;
  3589.  
  3590. function TSuperObject.GetD(const path: SOString): Double;
  3591. var
  3592. obj: ISuperObject;
  3593. begin
  3594. obj := GetO(path);
  3595. if obj <> nil then
  3596. Result := obj.AsDouble else
  3597. Result := 0.0;
  3598. end;
  3599.  
  3600. function TSuperObject.GetC(const path: SOString): Currency;
  3601. var
  3602. obj: ISuperObject;
  3603. begin
  3604. obj := GetO(path);
  3605. if obj <> nil then
  3606. Result := obj.AsCurrency else
  3607. Result := 0.0;
  3608. end;
  3609.  
  3610. function TSuperObject.GetI(const path: SOString): SuperInt;
  3611. var
  3612. obj: ISuperObject;
  3613. begin
  3614. obj := GetO(path);
  3615. if obj <> nil then
  3616. Result := obj.AsInteger else
  3617. Result := ;
  3618. end;
  3619.  
  3620. function TSuperObject.GetDataPtr: Pointer;
  3621. begin
  3622. Result := FDataPtr;
  3623. end;
  3624.  
  3625. function TSuperObject.GetDataType: TSuperType;
  3626. begin
  3627. Result := FDataType
  3628. end;
  3629.  
  3630. function TSuperObject.GetS(const path: SOString): SOString;
  3631. var
  3632. obj: ISuperObject;
  3633. begin
  3634. obj := GetO(path);
  3635. if obj <> nil then
  3636. Result := obj.AsString else
  3637. Result := '';
  3638. end;
  3639.  
  3640. function TSuperObject.SaveTo(const FileName: string; indent, escape: boolean): integer;
  3641. var
  3642. stream: TFileStream;
  3643. begin
  3644. stream := TFileStream.Create(FileName, fmCreate);
  3645. try
  3646. Result := SaveTo(stream, indent, escape);
  3647. finally
  3648. stream.Free;
  3649. end;
  3650. end;
  3651.  
  3652. function TSuperObject.Validate(const rules: SOString; const defs: SOString = ''; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean;
  3653. begin
  3654. Result := Validate(TSuperObject.ParseString(PSOChar(rules), False), TSuperObject.ParseString(PSOChar(defs), False), callback, sender);
  3655. end;
  3656.  
  3657. function TSuperObject.Validate(const rules: ISuperObject; const defs: ISuperObject = nil; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean;
  3658. type
  3659. TDataType = (dtUnknown, dtStr, dtInt, dtFloat, dtNumber, dtText, dtBool,
  3660. dtMap, dtSeq, dtScalar, dtAny);
  3661. var
  3662. datatypes: ISuperObject;
  3663. names: ISuperObject;
  3664.  
  3665. function FindInheritedProperty(const prop: PSOChar; p: ISuperObject): ISuperObject;
  3666. var
  3667. o: ISuperObject;
  3668. e: TSuperAvlEntry;
  3669. begin
  3670. o := p[prop];
  3671. if o <> nil then
  3672. result := o else
  3673. begin
  3674. o := p['inherit'];
  3675. if (o <> nil) and ObjectIsType(o, stString) then
  3676. begin
  3677. e := names.AsObject.Search(o.AsString);
  3678. if (e <> nil) then
  3679. Result := FindInheritedProperty(prop, e.Value) else
  3680. Result := nil;
  3681. end else
  3682. Result := nil;
  3683. end;
  3684. end;
  3685.  
  3686. function FindDataType(o: ISuperObject): TDataType;
  3687. var
  3688. e: TSuperAvlEntry;
  3689. obj: ISuperObject;
  3690. begin
  3691. obj := FindInheritedProperty('type', o);
  3692. if obj <> nil then
  3693. begin
  3694. e := datatypes.AsObject.Search(obj.AsString);
  3695. if e <> nil then
  3696. Result := TDataType(e.Value.AsInteger) else
  3697. Result := dtUnknown;
  3698. end else
  3699. Result := dtUnknown;
  3700. end;
  3701.  
  3702. procedure GetNames(o: ISuperObject);
  3703. var
  3704. obj: ISuperObject;
  3705. f: TSuperObjectIter;
  3706. begin
  3707. obj := o['name'];
  3708. if ObjectIsType(obj, stString) then
  3709. names[obj.AsString] := o;
  3710.  
  3711. case FindDataType(o) of
  3712. dtMap:
  3713. begin
  3714. obj := o['mapping'];
  3715. if ObjectIsType(obj, stObject) then
  3716. begin
  3717. if ObjectFindFirst(obj, f) then
  3718. repeat
  3719. if ObjectIsType(f.val, stObject) then
  3720. GetNames(f.val);
  3721. until not ObjectFindNext(f);
  3722. ObjectFindClose(f);
  3723. end;
  3724. end;
  3725. dtSeq:
  3726. begin
  3727. obj := o['sequence'];
  3728. if ObjectIsType(obj, stObject) then
  3729. GetNames(obj);
  3730. end;
  3731. end;
  3732. end;
  3733.  
  3734. function FindInheritedField(const prop: SOString; p: ISuperObject): ISuperObject;
  3735. var
  3736. o: ISuperObject;
  3737. e: TSuperAvlEntry;
  3738. begin
  3739. o := p['mapping'];
  3740. if ObjectIsType(o, stObject) then
  3741. begin
  3742. o := o.AsObject.GetO(prop);
  3743. if o <> nil then
  3744. begin
  3745. Result := o;
  3746. Exit;
  3747. end;
  3748. end;
  3749.  
  3750. o := p['inherit'];
  3751. if ObjectIsType(o, stString) then
  3752. begin
  3753. e := names.AsObject.Search(o.AsString);
  3754. if (e <> nil) then
  3755. Result := FindInheritedField(prop, e.Value) else
  3756. Result := nil;
  3757. end else
  3758. Result := nil;
  3759. end;
  3760.  
  3761. function InheritedFieldExist(const obj: ISuperObject; p: ISuperObject; const name: SOString = ''): boolean;
  3762. var
  3763. o: ISuperObject;
  3764. e: TSuperAvlEntry;
  3765. j: TSuperAvlIterator;
  3766. begin
  3767. Result := true;
  3768. o := p['mapping'];
  3769. if ObjectIsType(o, stObject) then
  3770. begin
  3771. j := TSuperAvlIterator.Create(o.AsObject);
  3772. try
  3773. j.First;
  3774. e := j.GetIter;
  3775. while e <> nil do
  3776. begin
  3777. if obj.AsObject.Search(e.Name) = nil then
  3778. begin
  3779. Result := False;
  3780. if assigned(callback) then
  3781. callback(sender, veFieldNotFound, name + '.' + e.Name);
  3782. end;
  3783. j.Next;
  3784. e := j.GetIter;
  3785. end;
  3786.  
  3787. finally
  3788. j.Free;
  3789. end;
  3790. end;
  3791.  
  3792. o := p['inherit'];
  3793. if ObjectIsType(o, stString) then
  3794. begin
  3795. e := names.AsObject.Search(o.AsString);
  3796. if (e <> nil) then
  3797. Result := InheritedFieldExist(obj, e.Value, name) and Result;
  3798. end;
  3799. end;
  3800.  
  3801. function getInheritedBool(f: PSOChar; p: ISuperObject; default: boolean = false): boolean;
  3802. var
  3803. o: ISuperObject;
  3804. begin
  3805. o := FindInheritedProperty(f, p);
  3806. case ObjectGetType(o) of
  3807. stBoolean: Result := o.AsBoolean;
  3808. stNull: Result := Default;
  3809. else
  3810. Result := default;
  3811. if assigned(callback) then
  3812. callback(sender, veRuleMalformated, f);
  3813. end;
  3814. end;
  3815.  
  3816. procedure GetInheritedFieldList(list: ISuperObject; p: ISuperObject);
  3817. var
  3818. o: ISuperObject;
  3819. e: TSuperAvlEntry;
  3820. i: TSuperAvlIterator;
  3821. begin
  3822. Result := true;
  3823. o := p['mapping'];
  3824. if ObjectIsType(o, stObject) then
  3825. begin
  3826. i := TSuperAvlIterator.Create(o.AsObject);
  3827. try
  3828. i.First;
  3829. e := i.GetIter;
  3830. while e <> nil do
  3831. begin
  3832. if list.AsObject.Search(e.Name) = nil then
  3833. list[e.Name] := e.Value;
  3834. i.Next;
  3835. e := i.GetIter;
  3836. end;
  3837.  
  3838. finally
  3839. i.Free;
  3840. end;
  3841. end;
  3842.  
  3843. o := p['inherit'];
  3844. if ObjectIsType(o, stString) then
  3845. begin
  3846. e := names.AsObject.Search(o.AsString);
  3847. if (e <> nil) then
  3848. GetInheritedFieldList(list, e.Value);
  3849. end;
  3850. end;
  3851.  
  3852. function CheckEnum(o: ISuperObject; p: ISuperObject; name: SOString = ''): boolean;
  3853. var
  3854. enum: ISuperObject;
  3855. i: integer;
  3856. begin
  3857. Result := false;
  3858. enum := FindInheritedProperty('enum', p);
  3859. case ObjectGetType(enum) of
  3860. stArray:
  3861. for i := to enum.AsArray.Length - do
  3862. if (o.AsString = enum.AsArray[i].AsString) then
  3863. begin
  3864. Result := true;
  3865. exit;
  3866. end;
  3867. stNull: Result := true;
  3868. else
  3869. Result := false;
  3870. if assigned(callback) then
  3871. callback(sender, veRuleMalformated, '');
  3872. Exit;
  3873. end;
  3874.  
  3875. if (not Result) and assigned(callback) then
  3876. callback(sender, veValueNotInEnum, name);
  3877. end;
  3878.  
  3879. function CheckLength(len: integer; p: ISuperObject; const objpath: SOString): boolean;
  3880. var
  3881. length, o: ISuperObject;
  3882. begin
  3883. result := true;
  3884. length := FindInheritedProperty('length', p);
  3885. case ObjectGetType(length) of
  3886. stObject:
  3887. begin
  3888. o := length.AsObject.GetO('min');
  3889. if (o <> nil) and (o.AsInteger > len) then
  3890. begin
  3891. Result := false;
  3892. if assigned(callback) then
  3893. callback(sender, veInvalidLength, objpath);
  3894. end;
  3895. o := length.AsObject.GetO('max');
  3896. if (o <> nil) and (o.AsInteger < len) then
  3897. begin
  3898. Result := false;
  3899. if assigned(callback) then
  3900. callback(sender, veInvalidLength, objpath);
  3901. end;
  3902. o := length.AsObject.GetO('minex');
  3903. if (o <> nil) and (o.AsInteger >= len) then
  3904. begin
  3905. Result := false;
  3906. if assigned(callback) then
  3907. callback(sender, veInvalidLength, objpath);
  3908. end;
  3909. o := length.AsObject.GetO('maxex');
  3910. if (o <> nil) and (o.AsInteger <= len) then
  3911. begin
  3912. Result := false;
  3913. if assigned(callback) then
  3914. callback(sender, veInvalidLength, objpath);
  3915. end;
  3916. end;
  3917. stNull: ;
  3918. else
  3919. Result := false;
  3920. if assigned(callback) then
  3921. callback(sender, veRuleMalformated, '');
  3922. end;
  3923. end;
  3924.  
  3925. function CheckRange(obj: ISuperObject; p: ISuperObject; const objpath: SOString): boolean;
  3926. var
  3927. length, o: ISuperObject;
  3928. begin
  3929. result := true;
  3930. length := FindInheritedProperty('range', p);
  3931. case ObjectGetType(length) of
  3932. stObject:
  3933. begin
  3934. o := length.AsObject.GetO('min');
  3935. if (o <> nil) and (o.Compare(obj) = cpGreat) then
  3936. begin
  3937. Result := false;
  3938. if assigned(callback) then
  3939. callback(sender, veInvalidRange, objpath);
  3940. end;
  3941. o := length.AsObject.GetO('max');
  3942. if (o <> nil) and (o.Compare(obj) = cpLess) then
  3943. begin
  3944. Result := false;
  3945. if assigned(callback) then
  3946. callback(sender, veInvalidRange, objpath);
  3947. end;
  3948. o := length.AsObject.GetO('minex');
  3949. if (o <> nil) and (o.Compare(obj) in [cpGreat, cpEqu]) then
  3950. begin
  3951. Result := false;
  3952. if assigned(callback) then
  3953. callback(sender, veInvalidRange, objpath);
  3954. end;
  3955. o := length.AsObject.GetO('maxex');
  3956. if (o <> nil) and (o.Compare(obj) in [cpLess, cpEqu]) then
  3957. begin
  3958. Result := false;
  3959. if assigned(callback) then
  3960. callback(sender, veInvalidRange, objpath);
  3961. end;
  3962. end;
  3963. stNull: ;
  3964. else
  3965. Result := false;
  3966. if assigned(callback) then
  3967. callback(sender, veRuleMalformated, '');
  3968. end;
  3969. end;
  3970.  
  3971. function process(o: ISuperObject; p: ISuperObject; objpath: SOString = ''): boolean;
  3972. var
  3973. ite: TSuperAvlIterator;
  3974. ent: TSuperAvlEntry;
  3975. p2, o2, sequence: ISuperObject;
  3976. s: SOString;
  3977. i: integer;
  3978. uniquelist, fieldlist: ISuperObject;
  3979. begin
  3980. Result := true;
  3981. if (o = nil) then
  3982. begin
  3983. if getInheritedBool('required', p) then
  3984. begin
  3985. if assigned(callback) then
  3986. callback(sender, veFieldIsRequired, objpath);
  3987. result := false;
  3988. end;
  3989. end else
  3990. case FindDataType(p) of
  3991. dtStr:
  3992. case ObjectGetType(o) of
  3993. stString:
  3994. begin
  3995. Result := Result and CheckLength(Length(o.AsString), p, objpath);
  3996. Result := Result and CheckRange(o, p, objpath);
  3997. end;
  3998. else
  3999. if assigned(callback) then
  4000. callback(sender, veInvalidDataType, objpath);
  4001. result := false;
  4002. end;
  4003. dtBool:
  4004. case ObjectGetType(o) of
  4005. stBoolean:
  4006. begin
  4007. Result := Result and CheckRange(o, p, objpath);
  4008. end;
  4009. else
  4010. if assigned(callback) then
  4011. callback(sender, veInvalidDataType, objpath);
  4012. result := false;
  4013. end;
  4014. dtInt:
  4015. case ObjectGetType(o) of
  4016. stInt:
  4017. begin
  4018. Result := Result and CheckRange(o, p, objpath);
  4019. end;
  4020. else
  4021. if assigned(callback) then
  4022. callback(sender, veInvalidDataType, objpath);
  4023. result := false;
  4024. end;
  4025. dtFloat:
  4026. case ObjectGetType(o) of
  4027. stDouble, stCurrency:
  4028. begin
  4029. Result := Result and CheckRange(o, p, objpath);
  4030. end;
  4031. else
  4032. if assigned(callback) then
  4033. callback(sender, veInvalidDataType, objpath);
  4034. result := false;
  4035. end;
  4036. dtMap:
  4037. case ObjectGetType(o) of
  4038. stObject:
  4039. begin
  4040. // all objects have and match a rule ?
  4041. ite := TSuperAvlIterator.Create(o.AsObject);
  4042. try
  4043. ite.First;
  4044. ent := ite.GetIter;
  4045. while ent <> nil do
  4046. begin
  4047. p2 := FindInheritedField(ent.Name, p);
  4048. if ObjectIsType(p2, stObject) then
  4049. result := process(ent.Value, p2, objpath + '.' + ent.Name) and result else
  4050. begin
  4051. if assigned(callback) then
  4052. callback(sender, veUnexpectedField, objpath + '.' + ent.Name);
  4053. result := false; // field have no rule
  4054. end;
  4055. ite.Next;
  4056. ent := ite.GetIter;
  4057. end;
  4058. finally
  4059. ite.Free;
  4060. end;
  4061.  
  4062. // all expected field exists ?
  4063. Result := InheritedFieldExist(o, p, objpath) and Result;
  4064. end;
  4065. stNull: {nop};
  4066. else
  4067. result := false;
  4068. if assigned(callback) then
  4069. callback(sender, veRuleMalformated, objpath);
  4070. end;
  4071. dtSeq:
  4072. case ObjectGetType(o) of
  4073. stArray:
  4074. begin
  4075. sequence := FindInheritedProperty('sequence', p);
  4076. if sequence <> nil then
  4077. case ObjectGetType(sequence) of
  4078. stObject:
  4079. begin
  4080. for i := to o.AsArray.Length - do
  4081. result := process(o.AsArray.GetO(i), sequence, objpath + '[' + IntToStr(i) + ']') and result;
  4082. if getInheritedBool('unique', sequence) then
  4083. begin
  4084. // type is unique ?
  4085. uniquelist := TSuperObject.Create(stObject);
  4086. try
  4087. for i := to o.AsArray.Length - do
  4088. begin
  4089. s := o.AsArray.GetO(i).AsString;
  4090. if (s <> '') then
  4091. begin
  4092. if uniquelist.AsObject.Search(s) = nil then
  4093. uniquelist[s] := nil else
  4094. begin
  4095. Result := False;
  4096. if Assigned(callback) then
  4097. callback(sender, veDuplicateEntry, objpath + '[' + IntToStr(i) + ']');
  4098. end;
  4099. end;
  4100. end;
  4101. finally
  4102. uniquelist := nil;
  4103. end;
  4104. end;
  4105.  
  4106. // field is unique ?
  4107. if (FindDataType(sequence) = dtMap) then
  4108. begin
  4109. fieldlist := TSuperObject.Create(stObject);
  4110. try
  4111. GetInheritedFieldList(fieldlist, sequence);
  4112. ite := TSuperAvlIterator.Create(fieldlist.AsObject);
  4113. try
  4114. ite.First;
  4115. ent := ite.GetIter;
  4116. while ent <> nil do
  4117. begin
  4118. if getInheritedBool('unique', ent.Value) then
  4119. begin
  4120. uniquelist := TSuperObject.Create(stObject);
  4121. try
  4122. for i := to o.AsArray.Length - do
  4123. begin
  4124. o2 := o.AsArray.GetO(i);
  4125. if o2 <> nil then
  4126. begin
  4127. s := o2.AsObject.GetO(ent.Name).AsString;
  4128. if (s <> '') then
  4129. if uniquelist.AsObject.Search(s) = nil then
  4130. uniquelist[s] := nil else
  4131. begin
  4132. Result := False;
  4133. if Assigned(callback) then
  4134. callback(sender, veDuplicateEntry, objpath + '[' + IntToStr(i) + '].' + ent.name);
  4135. end;
  4136. end;
  4137. end;
  4138. finally
  4139. uniquelist := nil;
  4140. end;
  4141. end;
  4142. ite.Next;
  4143. ent := ite.GetIter;
  4144. end;
  4145. finally
  4146. ite.Free;
  4147. end;
  4148. finally
  4149. fieldlist := nil;
  4150. end;
  4151. end;
  4152.  
  4153. end;
  4154. stNull: {nop};
  4155. else
  4156. result := false;
  4157. if assigned(callback) then
  4158. callback(sender, veRuleMalformated, objpath);
  4159. end;
  4160. Result := Result and CheckLength(o.AsArray.Length, p, objpath);
  4161.  
  4162. end;
  4163. else
  4164. result := false;
  4165. if assigned(callback) then
  4166. callback(sender, veRuleMalformated, objpath);
  4167. end;
  4168. dtNumber:
  4169. case ObjectGetType(o) of
  4170. stInt,
  4171. stDouble, stCurrency:
  4172. begin
  4173. Result := Result and CheckRange(o, p, objpath);
  4174. end;
  4175. else
  4176. if assigned(callback) then
  4177. callback(sender, veInvalidDataType, objpath);
  4178. result := false;
  4179. end;
  4180. dtText:
  4181. case ObjectGetType(o) of
  4182. stInt,
  4183. stDouble,
  4184. stCurrency,
  4185. stString:
  4186. begin
  4187. result := result and CheckLength(Length(o.AsString), p, objpath);
  4188. Result := Result and CheckRange(o, p, objpath);
  4189. end;
  4190. else
  4191. if assigned(callback) then
  4192. callback(sender, veInvalidDataType, objpath);
  4193. result := false;
  4194. end;
  4195. dtScalar:
  4196. case ObjectGetType(o) of
  4197. stBoolean,
  4198. stDouble,
  4199. stCurrency,
  4200. stInt,
  4201. stString:
  4202. begin
  4203. result := result and CheckLength(Length(o.AsString), p, objpath);
  4204. Result := Result and CheckRange(o, p, objpath);
  4205. end;
  4206. else
  4207. if assigned(callback) then
  4208. callback(sender, veInvalidDataType, objpath);
  4209. result := false;
  4210. end;
  4211. dtAny:;
  4212. else
  4213. if assigned(callback) then
  4214. callback(sender, veRuleMalformated, objpath);
  4215. result := false;
  4216. end;
  4217. Result := Result and CheckEnum(o, p, objpath)
  4218.  
  4219. end;
  4220. var
  4221. j: integer;
  4222.  
  4223. begin
  4224. Result := False;
  4225. datatypes := TSuperObject.Create(stObject);
  4226. names := TSuperObject.Create;
  4227. try
  4228. datatypes.I['str'] := ord(dtStr);
  4229. datatypes.I['int'] := ord(dtInt);
  4230. datatypes.I['float'] := ord(dtFloat);
  4231. datatypes.I['number'] := ord(dtNumber);
  4232. datatypes.I['text'] := ord(dtText);
  4233. datatypes.I['bool'] := ord(dtBool);
  4234. datatypes.I['map'] := ord(dtMap);
  4235. datatypes.I['seq'] := ord(dtSeq);
  4236. datatypes.I['scalar'] := ord(dtScalar);
  4237. datatypes.I['any'] := ord(dtAny);
  4238.  
  4239. if ObjectIsType(defs, stArray) then
  4240. for j := to defs.AsArray.Length - do
  4241. if ObjectIsType(defs.AsArray[j], stObject) then
  4242. GetNames(defs.AsArray[j]) else
  4243. begin
  4244. if assigned(callback) then
  4245. callback(sender, veRuleMalformated, '');
  4246. Exit;
  4247. end;
  4248.  
  4249. if ObjectIsType(rules, stObject) then
  4250. GetNames(rules) else
  4251. begin
  4252. if assigned(callback) then
  4253. callback(sender, veRuleMalformated, '');
  4254. Exit;
  4255. end;
  4256.  
  4257. Result := process(self, rules);
  4258.  
  4259. finally
  4260. datatypes := nil;
  4261. names := nil;
  4262. end;
  4263. end;
  4264.  
  4265. function TSuperObject._AddRef: Integer; stdcall;
  4266. begin
  4267. Result := InterlockedIncrement(FRefCount);
  4268. end;
  4269.  
  4270. function TSuperObject._Release: Integer; stdcall;
  4271. begin
  4272. Result := InterlockedDecrement(FRefCount);
  4273. if Result = then
  4274. Destroy;
  4275. end;
  4276.  
  4277. function TSuperObject.Compare(const str: SOString): TSuperCompareResult;
  4278. begin
  4279. Result := Compare(TSuperObject.ParseString(PSOChar(str), False));
  4280. end;
  4281.  
  4282. function TSuperObject.Compare(const obj: ISuperObject): TSuperCompareResult;
  4283. function GetIntCompResult(const i: int64): TSuperCompareResult;
  4284. begin
  4285. if i < then result := cpLess else
  4286. if i = then result := cpEqu else
  4287. Result := cpGreat;
  4288. end;
  4289.  
  4290. function GetDblCompResult(const d: double): TSuperCompareResult;
  4291. begin
  4292. if d < then result := cpLess else
  4293. if d = then result := cpEqu else
  4294. Result := cpGreat;
  4295. end;
  4296.  
  4297. begin
  4298. case DataType of
  4299. stBoolean:
  4300. case ObjectGetType(obj) of
  4301. stBoolean: Result := GetIntCompResult(ord(FO.c_boolean) - ord(obj.AsBoolean));
  4302. stDouble: Result := GetDblCompResult(ord(FO.c_boolean) - obj.AsDouble);
  4303. stCurrency:Result := GetDblCompResult(ord(FO.c_boolean) - obj.AsCurrency);
  4304. stInt: Result := GetIntCompResult(ord(FO.c_boolean) - obj.AsInteger);
  4305. stString: Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString)));
  4306. else
  4307. Result := cpError;
  4308. end;
  4309. stDouble:
  4310. case ObjectGetType(obj) of
  4311. stBoolean: Result := GetDblCompResult(FO.c_double - ord(obj.AsBoolean));
  4312. stDouble: Result := GetDblCompResult(FO.c_double - obj.AsDouble);
  4313. stCurrency:Result := GetDblCompResult(FO.c_double - obj.AsCurrency);
  4314. stInt: Result := GetDblCompResult(FO.c_double - obj.AsInteger);
  4315. stString: Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString)));
  4316. else
  4317. Result := cpError;
  4318. end;
  4319. stCurrency:
  4320. case ObjectGetType(obj) of
  4321. stBoolean: Result := GetDblCompResult(FO.c_currency - ord(obj.AsBoolean));
  4322. stDouble: Result := GetDblCompResult(FO.c_currency - obj.AsDouble);
  4323. stCurrency:Result := GetDblCompResult(FO.c_currency - obj.AsCurrency);
  4324. stInt: Result := GetDblCompResult(FO.c_currency - obj.AsInteger);
  4325. stString: Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString)));
  4326. else
  4327. Result := cpError;
  4328. end;
  4329. stInt:
  4330. case ObjectGetType(obj) of
  4331. stBoolean: Result := GetIntCompResult(FO.c_int - ord(obj.AsBoolean));
  4332. stDouble: Result := GetDblCompResult(FO.c_int - obj.AsDouble);
  4333. stCurrency:Result := GetDblCompResult(FO.c_int - obj.AsCurrency);
  4334. stInt: Result := GetIntCompResult(FO.c_int - obj.AsInteger);
  4335. stString: Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString)));
  4336. else
  4337. Result := cpError;
  4338. end;
  4339. stString:
  4340. case ObjectGetType(obj) of
  4341. stBoolean,
  4342. stDouble,
  4343. stCurrency,
  4344. stInt,
  4345. stString: Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString)));
  4346. else
  4347. Result := cpError;
  4348. end;
  4349. else
  4350. Result := cpError;
  4351. end;
  4352. end;
  4353.  
  4354. {$IFDEF SUPER_METHOD}
  4355. function TSuperObject.AsMethod: TSuperMethod;
  4356. begin
  4357. if FDataType = stMethod then
  4358. Result := FO.c_method else
  4359. Result := nil;
  4360. end;
  4361. {$ENDIF}
  4362.  
  4363. {$IFDEF SUPER_METHOD}
  4364. constructor TSuperObject.Create(m: TSuperMethod);
  4365. begin
  4366. Create(stMethod);
  4367. FO.c_method := m;
  4368. end;
  4369. {$ENDIF}
  4370.  
  4371. {$IFDEF SUPER_METHOD}
  4372. function TSuperObject.GetM(const path: SOString): TSuperMethod;
  4373. var
  4374. v: ISuperObject;
  4375. begin
  4376. v := ParseString(PSOChar(path), False, True, Self);
  4377. if (v <> nil) and (ObjectGetType(v) = stMethod) then
  4378. Result := v.AsMethod else
  4379. Result := nil;
  4380. end;
  4381. {$ENDIF}
  4382.  
  4383. {$IFDEF SUPER_METHOD}
  4384. procedure TSuperObject.PutM(const path: SOString; Value: TSuperMethod);
  4385. begin
  4386. ParseString(PSOChar(path), False, True, Self, [foCreatePath, foPutValue], TSuperObject.Create(Value));
  4387. end;
  4388. {$ENDIF}
  4389.  
  4390. {$IFDEF SUPER_METHOD}
  4391. function TSuperObject.call(const path: SOString; const param: ISuperObject): ISuperObject;
  4392. begin
  4393. Result := ParseString(PSOChar(path), False, True, Self, [foCallMethod], param);
  4394. end;
  4395. {$ENDIF}
  4396.  
  4397. {$IFDEF SUPER_METHOD}
  4398. function TSuperObject.call(const path, param: SOString): ISuperObject;
  4399. begin
  4400. Result := ParseString(PSOChar(path), False, True, Self, [foCallMethod], TSuperObject.ParseString(PSOChar(param), False));
  4401. end;
  4402. {$ENDIF}
  4403.  
  4404. function TSuperObject.GetProcessing: boolean;
  4405. begin
  4406. Result := FProcessing;
  4407. end;
  4408.  
  4409. procedure TSuperObject.SetDataPtr(const Value: Pointer);
  4410. begin
  4411. FDataPtr := Value;
  4412. end;
  4413.  
  4414. procedure TSuperObject.SetProcessing(value: boolean);
  4415. begin
  4416. FProcessing := value;
  4417. end;
  4418.  
  4419. { TSuperArray }
  4420.  
  4421. function TSuperArray.Add(const Data: ISuperObject): Integer;
  4422. begin
  4423. Result := FLength;
  4424. PutO(Result, data);
  4425. end;
  4426.  
  4427. function TSuperArray.Delete(index: Integer): ISuperObject;
  4428. begin
  4429. if (Index >= ) and (Index < FLength) then
  4430. begin
  4431. Result := FArray^[index];
  4432. FArray^[index] := nil;
  4433. Dec(FLength);
  4434. if Index < FLength then
  4435. begin
  4436. Move(FArray^[index + ], FArray^[index],
  4437. (FLength - index) * SizeOf(Pointer));
  4438. Pointer(FArray^[FLength]) := nil;
  4439. end;
  4440. end;
  4441. end;
  4442.  
  4443. procedure TSuperArray.Insert(index: Integer; const value: ISuperObject);
  4444. begin
  4445. if (Index >= ) then
  4446. if (index < FLength) then
  4447. begin
  4448. if FLength = FSize then
  4449. Expand(index);
  4450. if Index < FLength then
  4451. Move(FArray^[index], FArray^[index + ],
  4452. (FLength - index) * SizeOf(Pointer));
  4453. Pointer(FArray^[index]) := nil;
  4454. FArray^[index] := value;
  4455. Inc(FLength);
  4456. end else
  4457. PutO(index, value);
  4458. end;
  4459.  
  4460. procedure TSuperArray.Clear(all: boolean);
  4461. var
  4462. j: Integer;
  4463. begin
  4464. for j := to FLength - do
  4465. if FArray^[j] <> nil then
  4466. begin
  4467. if all then
  4468. FArray^[j].Clear(all);
  4469. FArray^[j] := nil;
  4470. end;
  4471. FLength := ;
  4472. end;
  4473.  
  4474. procedure TSuperArray.Pack(all: boolean);
  4475. var
  4476. PackedCount, StartIndex, EndIndex, j: Integer;
  4477. begin
  4478. if FLength > then
  4479. begin
  4480. PackedCount := ;
  4481. StartIndex := ;
  4482. repeat
  4483. while (StartIndex < FLength) and (FArray^[StartIndex] = nil) do
  4484. Inc(StartIndex);
  4485. if StartIndex < FLength then
  4486. begin
  4487. EndIndex := StartIndex;
  4488. while (EndIndex < FLength) and (FArray^[EndIndex] <> nil) do
  4489. Inc(EndIndex);
  4490.  
  4491. Dec(EndIndex);
  4492.  
  4493. if StartIndex > PackedCount then
  4494. Move(FArray^[StartIndex], FArray^[PackedCount], (EndIndex - StartIndex + ) * SizeOf(Pointer));
  4495.  
  4496. Inc(PackedCount, EndIndex - StartIndex + );
  4497. StartIndex := EndIndex + ;
  4498. end;
  4499. until StartIndex >= FLength;
  4500. FillChar(FArray^[PackedCount], (FLength - PackedCount) * sizeof(Pointer), );
  4501. FLength := PackedCount;
  4502. if all then
  4503. for j := to FLength - do
  4504. FArray^[j].Pack(all);
  4505. end;
  4506. end;
  4507.  
  4508. constructor TSuperArray.Create;
  4509. begin
  4510. inherited Create;
  4511. FSize := SUPER_ARRAY_LIST_DEFAULT_SIZE;
  4512. FLength := ;
  4513. GetMem(FArray, sizeof(Pointer) * FSize);
  4514. FillChar(FArray^, sizeof(Pointer) * FSize, );
  4515. end;
  4516.  
  4517. destructor TSuperArray.Destroy;
  4518. begin
  4519. Clear;
  4520. FreeMem(FArray);
  4521. inherited;
  4522. end;
  4523.  
  4524. procedure TSuperArray.Expand(max: Integer);
  4525. var
  4526. new_size: Integer;
  4527. begin
  4528. if (max < FSize) then
  4529. Exit;
  4530. if max < (FSize shl ) then
  4531. new_size := (FSize shl ) else
  4532. new_size := max + ;
  4533. ReallocMem(FArray, new_size * sizeof(Pointer));
  4534. FillChar(FArray^[FSize], (new_size - FSize) * sizeof(Pointer), );
  4535. FSize := new_size;
  4536. end;
  4537.  
  4538. function TSuperArray.GetO(const index: Integer): ISuperObject;
  4539. begin
  4540. if(index >= FLength) then
  4541. Result := nil else
  4542. Result := FArray^[index];
  4543. end;
  4544.  
  4545. function TSuperArray.GetB(const index: integer): Boolean;
  4546. var
  4547. obj: ISuperObject;
  4548. begin
  4549. obj := GetO(index);
  4550. if obj <> nil then
  4551. Result := obj.AsBoolean else
  4552. Result := false;
  4553. end;
  4554.  
  4555. function TSuperArray.GetD(const index: integer): Double;
  4556. var
  4557. obj: ISuperObject;
  4558. begin
  4559. obj := GetO(index);
  4560. if obj <> nil then
  4561. Result := obj.AsDouble else
  4562. Result := 0.0;
  4563. end;
  4564.  
  4565. function TSuperArray.GetI(const index: integer): SuperInt;
  4566. var
  4567. obj: ISuperObject;
  4568. begin
  4569. obj := GetO(index);
  4570. if obj <> nil then
  4571. Result := obj.AsInteger else
  4572. Result := ;
  4573. end;
  4574.  
  4575. function TSuperArray.GetS(const index: integer): SOString;
  4576. var
  4577. obj: ISuperObject;
  4578. begin
  4579. obj := GetO(index);
  4580. if obj <> nil then
  4581. Result := obj.AsString else
  4582. Result := '';
  4583. end;
  4584.  
  4585. procedure TSuperArray.PutO(const index: Integer; const Value: ISuperObject);
  4586. begin
  4587. Expand(index);
  4588. FArray^[index] := value;
  4589. if(FLength <= index) then FLength := index + ;
  4590. end;
  4591.  
  4592. function TSuperArray.GetN(const index: integer): ISuperObject;
  4593. begin
  4594. Result := GetO(index);
  4595. if Result = nil then
  4596. Result := TSuperObject.Create(stNull);
  4597. end;
  4598.  
  4599. procedure TSuperArray.PutN(const index: integer; const Value: ISuperObject);
  4600. begin
  4601. if Value <> nil then
  4602. PutO(index, Value) else
  4603. PutO(index, TSuperObject.Create(stNull));
  4604. end;
  4605.  
  4606. procedure TSuperArray.PutB(const index: integer; Value: Boolean);
  4607. begin
  4608. PutO(index, TSuperObject.Create(Value));
  4609. end;
  4610.  
  4611. procedure TSuperArray.PutD(const index: integer; Value: Double);
  4612. begin
  4613. PutO(index, TSuperObject.Create(Value));
  4614. end;
  4615.  
  4616. function TSuperArray.GetC(const index: integer): Currency;
  4617. var
  4618. obj: ISuperObject;
  4619. begin
  4620. obj := GetO(index);
  4621. if obj <> nil then
  4622. Result := obj.AsCurrency else
  4623. Result := 0.0;
  4624. end;
  4625.  
  4626. procedure TSuperArray.PutC(const index: integer; Value: Currency);
  4627. begin
  4628. PutO(index, TSuperObject.CreateCurrency(Value));
  4629. end;
  4630.  
  4631. procedure TSuperArray.PutI(const index: integer; Value: SuperInt);
  4632. begin
  4633. PutO(index, TSuperObject.Create(Value));
  4634. end;
  4635.  
  4636. procedure TSuperArray.PutS(const index: integer; const Value: SOString);
  4637. begin
  4638. PutO(index, TSuperObject.Create(Value));
  4639. end;
  4640.  
  4641. {$IFDEF SUPER_METHOD}
  4642. function TSuperArray.GetM(const index: integer): TSuperMethod;
  4643. var
  4644. v: ISuperObject;
  4645. begin
  4646. v := GetO(index);
  4647. if (ObjectGetType(v) = stMethod) then
  4648. Result := v.AsMethod else
  4649. Result := nil;
  4650. end;
  4651. {$ENDIF}
  4652.  
  4653. {$IFDEF SUPER_METHOD}
  4654. procedure TSuperArray.PutM(const index: integer; Value: TSuperMethod);
  4655. begin
  4656. PutO(index, TSuperObject.Create(Value));
  4657. end;
  4658. {$ENDIF}
  4659.  
  4660. { TSuperWriterString }
  4661.  
  4662. function TSuperWriterString.Append(buf: PSOChar; Size: Integer): Integer;
  4663. function max(a, b: Integer): integer; begin if a > b then Result := a else Result := b end;
  4664. begin
  4665. Result := size;
  4666. if Size > then
  4667. begin
  4668. if (FSize - FBPos <= size) then
  4669. begin
  4670. FSize := max(FSize * , FBPos + size + );
  4671. ReallocMem(FBuf, FSize * SizeOf(SOChar));
  4672. end;
  4673. // fast move
  4674. case size of
  4675. : FBuf[FBPos] := buf^;
  4676. : PInteger(@FBuf[FBPos])^ := PInteger(buf)^;
  4677. : PInt64(@FBuf[FBPos])^ := PInt64(buf)^;
  4678. else
  4679. move(buf^, FBuf[FBPos], size * SizeOf(SOChar));
  4680. end;
  4681. inc(FBPos, size);
  4682. FBuf[FBPos] := #;
  4683. end;
  4684. end;
  4685.  
  4686. function TSuperWriterString.Append(buf: PSOChar): Integer;
  4687. begin
  4688. Result := Append(buf, strlen(buf));
  4689. end;
  4690.  
  4691. constructor TSuperWriterString.Create;
  4692. begin
  4693. inherited;
  4694. FSize := ;
  4695. FBPos := ;
  4696. GetMem(FBuf, FSize * SizeOf(SOChar));
  4697. end;
  4698.  
  4699. destructor TSuperWriterString.Destroy;
  4700. begin
  4701. inherited;
  4702. if FBuf <> nil then
  4703. FreeMem(FBuf)
  4704. end;
  4705.  
  4706. function TSuperWriterString.GetString: SOString;
  4707. begin
  4708. SetString(Result, FBuf, FBPos);
  4709. end;
  4710.  
  4711. procedure TSuperWriterString.Reset;
  4712. begin
  4713. FBuf[] := #;
  4714. FBPos := ;
  4715. end;
  4716.  
  4717. procedure TSuperWriterString.TrimRight;
  4718. begin
  4719. while (FBPos > ) and (FBuf[FBPos-] < #) and (AnsiChar(FBuf[FBPos-]) in [#, #, #]) do
  4720. begin
  4721. dec(FBPos);
  4722. FBuf[FBPos] := #;
  4723. end;
  4724. end;
  4725.  
  4726. { TSuperWriterStream }
  4727.  
  4728. function TSuperWriterStream.Append(buf: PSOChar): Integer;
  4729. begin
  4730. Result := Append(buf, StrLen(buf));
  4731. end;
  4732.  
  4733. constructor TSuperWriterStream.Create(AStream: TStream);
  4734. begin
  4735. inherited Create;
  4736. FStream := AStream;
  4737. end;
  4738.  
  4739. procedure TSuperWriterStream.Reset;
  4740. begin
  4741. FStream.Size := ;
  4742. end;
  4743.  
  4744. { TSuperWriterStream }
  4745.  
  4746. function TSuperAnsiWriterStream.Append(buf: PSOChar; Size: Integer): Integer;
  4747. var
  4748. Buffer: array[..] of AnsiChar;
  4749. pBuffer: PAnsiChar;
  4750. i: Integer;
  4751. begin
  4752. if Size = then
  4753. Result := FStream.Write(buf^, Size) else
  4754. begin
  4755. if Size > SizeOf(Buffer) then
  4756. GetMem(pBuffer, Size) else
  4757. pBuffer := @Buffer;
  4758. try
  4759. for i := to Size - do
  4760. pBuffer[i] := AnsiChar(buf[i]);
  4761. Result := FStream.Write(pBuffer^, Size);
  4762. finally
  4763. if pBuffer <> @Buffer then
  4764. FreeMem(pBuffer);
  4765. end;
  4766. end;
  4767. end;
  4768.  
  4769. { TSuperUnicodeWriterStream }
  4770.  
  4771. function TSuperUnicodeWriterStream.Append(buf: PSOChar; Size: Integer): Integer;
  4772. begin
  4773. Result := FStream.Write(buf^, Size * );
  4774. end;
  4775.  
  4776. { TSuperWriterFake }
  4777.  
  4778. function TSuperWriterFake.Append(buf: PSOChar; Size: Integer): Integer;
  4779. begin
  4780. inc(FSize, Size);
  4781. Result := FSize;
  4782. end;
  4783.  
  4784. function TSuperWriterFake.Append(buf: PSOChar): Integer;
  4785. begin
  4786. inc(FSize, Strlen(buf));
  4787. Result := FSize;
  4788. end;
  4789.  
  4790. constructor TSuperWriterFake.Create;
  4791. begin
  4792. inherited Create;
  4793. FSize := ;
  4794. end;
  4795.  
  4796. procedure TSuperWriterFake.Reset;
  4797. begin
  4798. FSize := ;
  4799. end;
  4800.  
  4801. { TSuperWriterSock }
  4802.  
  4803. function TSuperWriterSock.Append(buf: PSOChar; Size: Integer): Integer;
  4804. var
  4805. Buffer: array[..] of AnsiChar;
  4806. pBuffer: PAnsiChar;
  4807. i: Integer;
  4808. begin
  4809. if Size = then
  4810. {$IFDEF FPC}
  4811. Result := fpsend(FSocket, buf, size, ) else
  4812. {$ELSE}
  4813. Result := send(FSocket, buf^, size, ) else
  4814. {$ENDIF}
  4815. begin
  4816. if Size > SizeOf(Buffer) then
  4817. GetMem(pBuffer, Size) else
  4818. pBuffer := @Buffer;
  4819. try
  4820. for i := to Size - do
  4821. pBuffer[i] := AnsiChar(buf[i]);
  4822. {$IFDEF FPC}
  4823. Result := fpsend(FSocket, pBuffer, size, );
  4824. {$ELSE}
  4825. Result := send(FSocket, pBuffer^, size, );
  4826. {$ENDIF}
  4827. finally
  4828. if pBuffer <> @Buffer then
  4829. FreeMem(pBuffer);
  4830. end;
  4831. end;
  4832. inc(FSize, Result);
  4833. end;
  4834.  
  4835. function TSuperWriterSock.Append(buf: PSOChar): Integer;
  4836. begin
  4837. Result := Append(buf, StrLen(buf));
  4838. end;
  4839.  
  4840. constructor TSuperWriterSock.Create(ASocket: Integer);
  4841. begin
  4842. inherited Create;
  4843. FSocket := ASocket;
  4844. FSize := ;
  4845. end;
  4846.  
  4847. procedure TSuperWriterSock.Reset;
  4848. begin
  4849. FSize := ;
  4850. end;
  4851.  
  4852. { TSuperTokenizer }
  4853.  
  4854. constructor TSuperTokenizer.Create;
  4855. begin
  4856. pb := TSuperWriterString.Create;
  4857. line := ;
  4858. col := ;
  4859. Reset;
  4860. end;
  4861.  
  4862. destructor TSuperTokenizer.Destroy;
  4863. begin
  4864. Reset;
  4865. pb.Free;
  4866. inherited;
  4867. end;
  4868.  
  4869. procedure TSuperTokenizer.Reset;
  4870. var
  4871. i: integer;
  4872. begin
  4873. for i := depth downto do
  4874. ResetLevel(i);
  4875. depth := ;
  4876. err := teSuccess;
  4877. end;
  4878.  
  4879. procedure TSuperTokenizer.ResetLevel(adepth: integer);
  4880. begin
  4881. stack[adepth].state := tsEatws;
  4882. stack[adepth].saved_state := tsStart;
  4883. stack[adepth].current := nil;
  4884. stack[adepth].field_name := '';
  4885. stack[adepth].obj := nil;
  4886. stack[adepth].parent := nil;
  4887. stack[adepth].gparent := nil;
  4888. end;
  4889.  
  4890. { TSuperAvlTree }
  4891.  
  4892. constructor TSuperAvlTree.Create;
  4893. begin
  4894. FRoot := nil;
  4895. FCount := ;
  4896. end;
  4897.  
  4898. destructor TSuperAvlTree.Destroy;
  4899. begin
  4900. Clear;
  4901. inherited;
  4902. end;
  4903.  
  4904. function TSuperAvlTree.IsEmpty: boolean;
  4905. begin
  4906. result := FRoot = nil;
  4907. end;
  4908.  
  4909. function TSuperAvlTree.balance(bal: TSuperAvlEntry): TSuperAvlEntry;
  4910. var
  4911. deep, old: TSuperAvlEntry;
  4912. bf: integer;
  4913. begin
  4914. if (bal.FBf > ) then
  4915. begin
  4916. deep := bal.FGt;
  4917. if (deep.FBf < ) then
  4918. begin
  4919. old := bal;
  4920. bal := deep.FLt;
  4921. old.FGt := bal.FLt;
  4922. deep.FLt := bal.FGt;
  4923. bal.FLt := old;
  4924. bal.FGt := deep;
  4925. bf := bal.FBf;
  4926. if (bf <> ) then
  4927. begin
  4928. if (bf > ) then
  4929. begin
  4930. old.FBf := -;
  4931. deep.FBf := ;
  4932. end else
  4933. begin
  4934. deep.FBf := ;
  4935. old.FBf := ;
  4936. end;
  4937. bal.FBf := ;
  4938. end else
  4939. begin
  4940. old.FBf := ;
  4941. deep.FBf := ;
  4942. end;
  4943. end else
  4944. begin
  4945. bal.FGt := deep.FLt;
  4946. deep.FLt := bal;
  4947. if (deep.FBf = ) then
  4948. begin
  4949. deep.FBf := -;
  4950. bal.FBf := ;
  4951. end else
  4952. begin
  4953. deep.FBf := ;
  4954. bal.FBf := ;
  4955. end;
  4956. bal := deep;
  4957. end;
  4958. end else
  4959. begin
  4960. (* "Less than" subtree is deeper. *)
  4961.  
  4962. deep := bal.FLt;
  4963. if (deep.FBf > ) then
  4964. begin
  4965. old := bal;
  4966. bal := deep.FGt;
  4967. old.FLt := bal.FGt;
  4968. deep.FGt := bal.FLt;
  4969. bal.FGt := old;
  4970. bal.FLt := deep;
  4971.  
  4972. bf := bal.FBf;
  4973. if (bf <> ) then
  4974. begin
  4975. if (bf < ) then
  4976. begin
  4977. old.FBf := ;
  4978. deep.FBf := ;
  4979. end else
  4980. begin
  4981. deep.FBf := -;
  4982. old.FBf := ;
  4983. end;
  4984. bal.FBf := ;
  4985. end else
  4986. begin
  4987. old.FBf := ;
  4988. deep.FBf := ;
  4989. end;
  4990. end else
  4991. begin
  4992. bal.FLt := deep.FGt;
  4993. deep.FGt := bal;
  4994. if (deep.FBf = ) then
  4995. begin
  4996. deep.FBf := ;
  4997. bal.FBf := -;
  4998. end else
  4999. begin
  5000. deep.FBf := ;
  5001. bal.FBf := ;
  5002. end;
  5003. bal := deep;
  5004. end;
  5005. end;
  5006. Result := bal;
  5007. end;
  5008.  
  5009. function TSuperAvlTree.Insert(h: TSuperAvlEntry): TSuperAvlEntry;
  5010. var
  5011. unbal, parentunbal, hh, parent: TSuperAvlEntry;
  5012. depth, unbaldepth: longint;
  5013. cmp: integer;
  5014. unbalbf: integer;
  5015. branch: TSuperAvlBitArray;
  5016. p: Pointer;
  5017. begin
  5018. inc(FCount);
  5019. h.FLt := nil;
  5020. h.FGt := nil;
  5021. h.FBf := ;
  5022. branch := [];
  5023.  
  5024. if (FRoot = nil) then
  5025. FRoot := h
  5026. else
  5027. begin
  5028. unbal := nil;
  5029. parentunbal := nil;
  5030. depth := ;
  5031. unbaldepth := ;
  5032. hh := FRoot;
  5033. parent := nil;
  5034. repeat
  5035. if (hh.FBf <> ) then
  5036. begin
  5037. unbal := hh;
  5038. parentunbal := parent;
  5039. unbaldepth := depth;
  5040. end;
  5041. if hh.FHash <> h.FHash then
  5042. begin
  5043. if nowSortMode = sosmDefault then
  5044. begin
  5045. //original code
  5046. if hh.FHash < h.FHash then cmp := - else
  5047. if hh.FHash > h.FHash then cmp := else
  5048. cmp := ;
  5049. end else
  5050. begin
  5051. // modify by mofen
  5052. cmp := CompareForSortModeString(h.Name, hh.Name);
  5053. end;
  5054. end else
  5055. cmp := CompareNodeNode(h, hh);
  5056. if (cmp = ) then
  5057. begin
  5058. Result := hh;
  5059. //exchange data
  5060. p := hh.Ptr;
  5061. hh.FPtr := h.Ptr;
  5062. h.FPtr := p;
  5063. doDeleteEntry(h, false);
  5064. dec(FCount);
  5065. exit;
  5066. end;
  5067. parent := hh;
  5068. if (cmp > ) then
  5069. begin
  5070. hh := hh.FGt;
  5071. include(branch, depth);
  5072. end else
  5073. begin
  5074. hh := hh.FLt;
  5075. exclude(branch, depth);
  5076. end;
  5077. inc(depth);
  5078. until (hh = nil);
  5079.  
  5080. if (cmp < ) then
  5081. parent.FLt := h else
  5082. parent.FGt := h;
  5083.  
  5084. depth := unbaldepth;
  5085.  
  5086. if (unbal = nil) then
  5087. hh := FRoot
  5088. else
  5089. begin
  5090. if depth in branch then
  5091. cmp := else
  5092. cmp := -;
  5093. inc(depth);
  5094. unbalbf := unbal.FBf;
  5095. if (cmp < ) then
  5096. dec(unbalbf) else
  5097. inc(unbalbf);
  5098. if cmp < then
  5099. hh := unbal.FLt else
  5100. hh := unbal.FGt;
  5101. if ((unbalbf <> -) and (unbalbf <> )) then
  5102. begin
  5103. unbal.FBf := unbalbf;
  5104. unbal := nil;
  5105. end;
  5106. end;
  5107.  
  5108. if (hh <> nil) then
  5109. while (h <> hh) do
  5110. begin
  5111. if depth in branch then
  5112. cmp := else
  5113. cmp := -;
  5114. inc(depth);
  5115. if (cmp < ) then
  5116. begin
  5117. hh.FBf := -;
  5118. hh := hh.FLt;
  5119. end else (* cmp > 0 *)
  5120. begin
  5121. hh.FBf := ;
  5122. hh := hh.FGt;
  5123. end;
  5124. end;
  5125.  
  5126. // original code
  5127. // if (unbal <> nil) then
  5128. if (unbal <> nil) and (nowSortMode <> sosmAdd) then //modify by mofen
  5129. begin
  5130. unbal := balance(unbal);
  5131. if (parentunbal = nil) then
  5132. FRoot := unbal
  5133. else
  5134. begin
  5135. depth := unbaldepth - ;
  5136. if depth in branch then
  5137. cmp := else
  5138. cmp := -;
  5139. if (cmp < ) then
  5140. parentunbal.FLt := unbal else
  5141. parentunbal.FGt := unbal;
  5142. end;
  5143. end;
  5144. end;
  5145. result := h;
  5146. end;
  5147.  
  5148. function TSuperAvlTree.Search(const k: SOString; st: TSuperAvlSearchTypes): TSuperAvlEntry;
  5149. var
  5150. cmp, target_cmp: integer;
  5151. match_h, h: TSuperAvlEntry;
  5152. ha: Cardinal;
  5153. begin
  5154. ha := TSuperAvlEntry.Hash(k);
  5155.  
  5156. match_h := nil;
  5157. h := FRoot;
  5158.  
  5159. if (stLess in st) then
  5160. target_cmp := else
  5161. if (stGreater in st) then
  5162. target_cmp := - else
  5163. target_cmp := ;
  5164.  
  5165. while (h <> nil) do
  5166. begin
  5167.  
  5168. // modify by mofen
  5169. if nowSortMode = sosmDefault then
  5170. begin
  5171. //original code
  5172. if h.FHash < ha then cmp := - else
  5173. if h.FHash > ha then cmp := else
  5174. cmp := ;
  5175. end else
  5176. begin
  5177. // modify by mofen
  5178. cmp := CompareForSortModeString(k, h.Name);
  5179. end;
  5180.  
  5181. // if h.FHash < ha then cmp := -1 else
  5182. // if h.FHash > ha then cmp := 1 else
  5183. // cmp := 0;
  5184.  
  5185. if cmp = then
  5186. cmp := CompareKeyNode(PSOChar(k), h);
  5187. if (cmp = ) then
  5188. begin
  5189. if (stEqual in st) then
  5190. begin
  5191. match_h := h;
  5192. break;
  5193. end;
  5194. cmp := -target_cmp;
  5195. end
  5196. else
  5197. if (target_cmp <> ) then
  5198. if ((cmp xor target_cmp) and SUPER_AVL_MASK_HIGH_BIT) = then
  5199. match_h := h;
  5200. if cmp < then
  5201. h := h.FLt else
  5202. h := h.FGt;
  5203. end;
  5204. result := match_h;
  5205. end;
  5206.  
  5207. function TSuperAvlTree.Delete(const k: SOString): ISuperObject;
  5208. var
  5209. depth, rm_depth: longint;
  5210. branch: TSuperAvlBitArray;
  5211. h, parent, child, path, rm, parent_rm: TSuperAvlEntry;
  5212. cmp, cmp_shortened_sub_with_path, reduced_depth, bf: integer;
  5213. ha: Cardinal;
  5214. begin
  5215. ha := TSuperAvlEntry.Hash(k);
  5216. cmp_shortened_sub_with_path := ;
  5217. branch := [];
  5218.  
  5219. depth := ;
  5220. h := FRoot;
  5221. parent := nil;
  5222. while true do
  5223. begin
  5224. if (h = nil) then
  5225. exit;
  5226. // if h.FHash < ha then cmp := -1 else
  5227. // if h.FHash > ha then cmp := 1 else
  5228. // cmp := 0;
  5229.  
  5230. // modify by mofen
  5231. if nowSortMode = sosmDefault then
  5232. begin
  5233. //original code
  5234. if h.FHash < ha then cmp := - else
  5235. if h.FHash > ha then cmp := else
  5236. cmp := ;
  5237. end else
  5238. begin
  5239. // modify by mofen
  5240. cmp := CompareForSortModeString(k, h.Name);
  5241. end;
  5242.  
  5243. if cmp = then
  5244. cmp := CompareKeyNode(k, h);
  5245. if (cmp = ) then
  5246. break;
  5247. parent := h;
  5248. if (cmp > ) then
  5249. begin
  5250. h := h.FGt;
  5251. include(branch, depth)
  5252. end else
  5253. begin
  5254. h := h.FLt;
  5255. exclude(branch, depth)
  5256. end;
  5257. inc(depth);
  5258. cmp_shortened_sub_with_path := cmp;
  5259. end;
  5260. rm := h;
  5261. parent_rm := parent;
  5262. rm_depth := depth;
  5263.  
  5264. if (h.FBf < ) then
  5265. begin
  5266. child := h.FLt;
  5267. exclude(branch, depth);
  5268. cmp := -;
  5269. end else
  5270. begin
  5271. child := h.FGt;
  5272. include(branch, depth);
  5273. cmp := ;
  5274. end;
  5275. inc(depth);
  5276.  
  5277. if (child <> nil) then
  5278. begin
  5279. cmp := -cmp;
  5280. repeat
  5281. parent := h;
  5282. h := child;
  5283. if (cmp < ) then
  5284. begin
  5285. child := h.FLt;
  5286. exclude(branch, depth);
  5287. end else
  5288. begin
  5289. child := h.FGt;
  5290. include(branch, depth);
  5291. end;
  5292. inc(depth);
  5293. until (child = nil);
  5294.  
  5295. if (parent = rm) then
  5296. cmp_shortened_sub_with_path := -cmp else
  5297. cmp_shortened_sub_with_path := cmp;
  5298.  
  5299. if cmp > then
  5300. child := h.FLt else
  5301. child := h.FGt;
  5302. end;
  5303.  
  5304. if (parent = nil) then
  5305. FRoot := child else
  5306. if (cmp_shortened_sub_with_path < ) then
  5307. parent.FLt := child else
  5308. parent.FGt := child;
  5309.  
  5310. if parent = rm then
  5311. path := h else
  5312. path := parent;
  5313.  
  5314. if (h <> rm) then
  5315. begin
  5316. h.FLt := rm.FLt;
  5317. h.FGt := rm.FGt;
  5318. h.FBf := rm.FBf;
  5319. if (parent_rm = nil) then
  5320. FRoot := h
  5321. else
  5322. begin
  5323. depth := rm_depth - ;
  5324. if (depth in branch) then
  5325. parent_rm.FGt := h else
  5326. parent_rm.FLt := h;
  5327. end;
  5328. end;
  5329.  
  5330. if (path <> nil) then
  5331. begin
  5332. h := FRoot;
  5333. parent := nil;
  5334. depth := ;
  5335. while (h <> path) do
  5336. begin
  5337. if (depth in branch) then
  5338. begin
  5339. child := h.FGt;
  5340. h.FGt := parent;
  5341. end else
  5342. begin
  5343. child := h.FLt;
  5344. h.FLt := parent;
  5345. end;
  5346. inc(depth);
  5347. parent := h;
  5348. h := child;
  5349. end;
  5350.  
  5351. reduced_depth := ;
  5352. cmp := cmp_shortened_sub_with_path;
  5353. while true do
  5354. begin
  5355. if (reduced_depth <> ) then
  5356. begin
  5357. bf := h.FBf;
  5358. if (cmp < ) then
  5359. inc(bf) else
  5360. dec(bf);
  5361. if ((bf = -) or (bf = )) then
  5362. begin
  5363. h := balance(h);
  5364. bf := h.FBf;
  5365. end else
  5366. h.FBf := bf;
  5367. reduced_depth := integer(bf = );
  5368. end;
  5369. if (parent = nil) then
  5370. break;
  5371. child := h;
  5372. h := parent;
  5373. dec(depth);
  5374. if depth in branch then
  5375. cmp := else
  5376. cmp := -;
  5377. if (cmp < ) then
  5378. begin
  5379. parent := h.FLt;
  5380. h.FLt := child;
  5381. end else
  5382. begin
  5383. parent := h.FGt;
  5384. h.FGt := child;
  5385. end;
  5386. end;
  5387. FRoot := h;
  5388. end;
  5389. if rm <> nil then
  5390. begin
  5391. Result := rm.GetValue;
  5392. doDeleteEntry(rm, false);
  5393. dec(FCount);
  5394. end;
  5395. end;
  5396.  
  5397. procedure TSuperAvlTree.Pack(all: boolean);
  5398. var
  5399. node1, node2: TSuperAvlEntry;
  5400. list: TList;
  5401. i: Integer;
  5402. begin
  5403. node1 := FRoot;
  5404. list := TList.Create;
  5405. while node1 <> nil do
  5406. begin
  5407. if (node1.FLt = nil) then
  5408. begin
  5409. node2 := node1.FGt;
  5410. if (node1.FPtr = nil) then
  5411. list.Add(node1) else
  5412. if all then
  5413. node1.Value.Pack(all);
  5414. end
  5415. else
  5416. begin
  5417. node2 := node1.FLt;
  5418. node1.FLt := node2.FGt;
  5419. node2.FGt := node1;
  5420. end;
  5421. node1 := node2;
  5422. end;
  5423. for i := to list.Count - do
  5424. Delete(TSuperAvlEntry(list[i]).FName);
  5425. list.Free;
  5426. end;
  5427.  
  5428. procedure TSuperAvlTree.Clear(all: boolean);
  5429. var
  5430. node1, node2: TSuperAvlEntry;
  5431. begin
  5432. node1 := FRoot;
  5433. while node1 <> nil do
  5434. begin
  5435. if (node1.FLt = nil) then
  5436. begin
  5437. node2 := node1.FGt;
  5438. doDeleteEntry(node1, all);
  5439. end
  5440. else
  5441. begin
  5442. node2 := node1.FLt;
  5443. node1.FLt := node2.FGt;
  5444. node2.FGt := node1;
  5445. end;
  5446. node1 := node2;
  5447. end;
  5448. FRoot := nil;
  5449. FCount := ;
  5450. end;
  5451.  
  5452. function TSuperAvlTree.CompareKeyNode(const k: SOString; h: TSuperAvlEntry): integer;
  5453. begin
  5454. Result := StrComp(PSOChar(k), PSOChar(h.FName));
  5455. end;
  5456.  
  5457. function TSuperAvlTree.CompareNodeNode(node1, node2: TSuperAvlEntry): integer;
  5458. begin
  5459. Result := StrComp(PSOChar(node1.FName), PSOChar(node2.FName));
  5460. end;
  5461.  
  5462. { TSuperAvlIterator }
  5463.  
  5464. (* Initialize depth to invalid value, to indicate iterator is
  5465. ** invalid. (Depth is zero-base.) It's not necessary to initialize
  5466. ** iterators prior to passing them to the "start" function.
  5467. *)
  5468.  
  5469. constructor TSuperAvlIterator.Create(tree: TSuperAvlTree);
  5470. begin
  5471. FDepth := not ;
  5472. FTree := tree;
  5473. end;
  5474.  
  5475. procedure TSuperAvlIterator.Search(const k: SOString; st: TSuperAvlSearchTypes);
  5476. var
  5477. h: TSuperAvlEntry;
  5478. d: longint;
  5479. cmp, target_cmp: integer;
  5480. ha: Cardinal;
  5481. begin
  5482. ha := TSuperAvlEntry.Hash(k);
  5483. h := FTree.FRoot;
  5484. d := ;
  5485. FDepth := not ;
  5486. if (h = nil) then
  5487. exit;
  5488.  
  5489. if (stLess in st) then
  5490. target_cmp := else
  5491. if (stGreater in st) then
  5492. target_cmp := - else
  5493. target_cmp := ;
  5494.  
  5495. while true do
  5496. begin
  5497. if h.FHash < ha then cmp := - else
  5498. if h.FHash > ha then cmp := else
  5499. cmp := ;
  5500.  
  5501. if cmp = then
  5502. cmp := FTree.CompareKeyNode(k, h);
  5503. if (cmp = ) then
  5504. begin
  5505. if (stEqual in st) then
  5506. begin
  5507. FDepth := d;
  5508. break;
  5509. end;
  5510. cmp := -target_cmp;
  5511. end
  5512. else
  5513. if (target_cmp <> ) then
  5514. if ((cmp xor target_cmp) and SUPER_AVL_MASK_HIGH_BIT) = then
  5515. FDepth := d;
  5516. if cmp < then
  5517. h := h.FLt else
  5518. h := h.FGt;
  5519. if (h = nil) then
  5520. break;
  5521. if (cmp > ) then
  5522. include(FBranch, d) else
  5523. exclude(FBranch, d);
  5524. FPath[d] := h;
  5525. inc(d);
  5526. end;
  5527. end;
  5528.  
  5529. procedure TSuperAvlIterator.First;
  5530. var
  5531. h: TSuperAvlEntry;
  5532. begin
  5533. h := FTree.FRoot;
  5534. FDepth := not ;
  5535. FBranch := [];
  5536. while (h <> nil) do
  5537. begin
  5538. if (FDepth <> not ) then
  5539. FPath[FDepth] := h;
  5540. inc(FDepth);
  5541. h := h.FLt;
  5542. end;
  5543. end;
  5544.  
  5545. procedure TSuperAvlIterator.Last;
  5546. var
  5547. h: TSuperAvlEntry;
  5548. begin
  5549. h := FTree.FRoot;
  5550. FDepth := not ;
  5551. FBranch := [..SUPER_AVL_MAX_DEPTH - ];
  5552. while (h <> nil) do
  5553. begin
  5554. if (FDepth <> not ) then
  5555. FPath[FDepth] := h;
  5556. inc(FDepth);
  5557. h := h.FGt;
  5558. end;
  5559. end;
  5560.  
  5561. function TSuperAvlIterator.MoveNext: boolean;
  5562. begin
  5563. if FDepth = not then
  5564. First else
  5565. Next;
  5566. Result := GetIter <> nil;
  5567. end;
  5568.  
  5569. function TSuperAvlIterator.GetIter: TSuperAvlEntry;
  5570. begin
  5571. if (FDepth = not ) then
  5572. begin
  5573. result := nil;
  5574. exit;
  5575. end;
  5576. if FDepth = then
  5577. Result := FTree.FRoot else
  5578. Result := FPath[FDepth - ];
  5579. end;
  5580.  
  5581. procedure TSuperAvlIterator.Next;
  5582. var
  5583. h: TSuperAvlEntry;
  5584. begin
  5585. if (FDepth <> not ) then
  5586. begin
  5587. if FDepth = then
  5588. h := FTree.FRoot.FGt else
  5589. h := FPath[FDepth - ].FGt;
  5590.  
  5591. if (h = nil) then
  5592. repeat
  5593. if (FDepth = ) then
  5594. begin
  5595. FDepth := not ;
  5596. break;
  5597. end;
  5598. dec(FDepth);
  5599. until (not (FDepth in FBranch))
  5600. else
  5601. begin
  5602. include(FBranch, FDepth);
  5603. FPath[FDepth] := h;
  5604. inc(FDepth);
  5605. while true do
  5606. begin
  5607. h := h.FLt;
  5608. if (h = nil) then
  5609. break;
  5610. exclude(FBranch, FDepth);
  5611. FPath[FDepth] := h;
  5612. inc(FDepth);
  5613. end;
  5614. end;
  5615. end;
  5616. end;
  5617.  
  5618. procedure TSuperAvlIterator.Prior;
  5619. var
  5620. h: TSuperAvlEntry;
  5621. begin
  5622. if (FDepth <> not ) then
  5623. begin
  5624. if FDepth = then
  5625. h := FTree.FRoot.FLt else
  5626. h := FPath[FDepth - ].FLt;
  5627. if (h = nil) then
  5628. repeat
  5629. if (FDepth = ) then
  5630. begin
  5631. FDepth := not ;
  5632. break;
  5633. end;
  5634. dec(FDepth);
  5635. until (FDepth in FBranch)
  5636. else
  5637. begin
  5638. exclude(FBranch, FDepth);
  5639. FPath[FDepth] := h;
  5640. inc(FDepth);
  5641. while true do
  5642. begin
  5643. h := h.FGt;
  5644. if (h = nil) then
  5645. break;
  5646. include(FBranch, FDepth);
  5647. FPath[FDepth] := h;
  5648. inc(FDepth);
  5649. end;
  5650. end;
  5651. end;
  5652. end;
  5653.  
  5654. procedure TSuperAvlTree.doDeleteEntry(Entry: TSuperAvlEntry; all: boolean);
  5655. begin
  5656. Entry.Free;
  5657. end;
  5658.  
  5659. function TSuperAvlTree.GetEnumerator: TSuperAvlIterator;
  5660. begin
  5661. Result := TSuperAvlIterator.Create(Self);
  5662. end;
  5663.  
  5664. function TSuperAvlTree.CompareForSortModeString(pvKey1, pvKey2: SOString):Integer;
  5665. var
  5666. cmp: integer;
  5667. lvKey1, lvKey2: SOString;
  5668. begin
  5669. lvKey1 := LowerCase(pvKey1);
  5670. lvKey2 := LowerCase(pvKey2);
  5671. if lvKey1 <> lvKey2 then
  5672. begin
  5673. case nowSortMode of
  5674. sosmAdd: cmp := ;
  5675. sosmASC: if lvKey2 < lvKey1 then cmp := else if lvKey2 > lvKey1 then cmp := -;
  5676. sosmDesc: if lvKey2 < lvKey1 then cmp := - else if lvKey2 > lvKey1 then cmp := ;
  5677. else
  5678. raise Exception.Create('默认排序不采用compareForSortModeString');
  5679. end;
  5680. end else
  5681. cmp := ;
  5682. Result := cmp;
  5683. end;
  5684.  
  5685. { TSuperAvlEntry }
  5686.  
  5687. constructor TSuperAvlEntry.Create(const AName: SOString; Obj: Pointer);
  5688. begin
  5689. FName := AName;
  5690. FPtr := Obj;
  5691. FHash := Hash(FName);
  5692. end;
  5693.  
  5694. function TSuperAvlEntry.GetValue: ISuperObject;
  5695. begin
  5696. Result := ISuperObject(FPtr)
  5697. end;
  5698.  
  5699. //class function TSuperAvlEntry.Hash(const k: SOString): Cardinal;
  5700. //var
  5701. // h: cardinal;
  5702. // i: Integer;
  5703. //begin
  5704. // h := 0;
  5705. //{$Q-}
  5706. // for i := 1 to Length(k) do
  5707. // h := h*129 + ord(k[i]) + $9e370001;
  5708. //{$Q+}
  5709. // Result := h;
  5710. //end;
  5711.  
  5712. //修改为:
  5713. {$OVERFLOWCHECKS OFF}
  5714. class function TSuperAvlEntry.Hash(const k: SOString): Cardinal;
  5715. var
  5716. h: cardinal;
  5717. i: Integer;
  5718. begin
  5719. h := ;
  5720. for i := to Length(k) do
  5721. h := h* + ord(k[i]) + $9e370001;
  5722. Result := h;
  5723. end;
  5724. {$OVERFLOWCHECKS ON}
  5725.  
  5726. procedure TSuperAvlEntry.SetValue(const val: ISuperObject);
  5727. begin
  5728. ISuperObject(FPtr) := val;
  5729. end;
  5730.  
  5731. { TSuperTableString }
  5732.  
  5733. function TSuperTableString.GetValues: ISuperObject;
  5734. var
  5735. ite: TSuperAvlIterator;
  5736. obj: TSuperAvlEntry;
  5737. begin
  5738. Result := TSuperObject.Create(stArray);
  5739. ite := TSuperAvlIterator.Create(Self);
  5740. try
  5741. ite.First;
  5742. obj := ite.GetIter;
  5743. while obj <> nil do
  5744. begin
  5745. Result.AsArray.Add(obj.Value);
  5746. ite.Next;
  5747. obj := ite.GetIter;
  5748. end;
  5749. finally
  5750. ite.Free;
  5751. end;
  5752. end;
  5753.  
  5754. function TSuperTableString.GetNames: ISuperObject;
  5755. var
  5756. ite: TSuperAvlIterator;
  5757. obj: TSuperAvlEntry;
  5758. begin
  5759. Result := TSuperObject.Create(stArray);
  5760. ite := TSuperAvlIterator.Create(Self);
  5761. try
  5762. ite.First;
  5763. obj := ite.GetIter;
  5764. while obj <> nil do
  5765. begin
  5766. Result.AsArray.Add(TSuperObject.Create(obj.FName));
  5767. ite.Next;
  5768. obj := ite.GetIter;
  5769. end;
  5770. finally
  5771. ite.Free;
  5772. end;
  5773. end;
  5774.  
  5775. procedure TSuperTableString.doDeleteEntry(Entry: TSuperAvlEntry; all: boolean);
  5776. begin
  5777. if Entry.Ptr <> nil then
  5778. begin
  5779. if all then Entry.Value.Clear(true);
  5780. Entry.Value := nil;
  5781. end;
  5782. inherited;
  5783. end;
  5784.  
  5785. function TSuperTableString.GetO(const k: SOString): ISuperObject;
  5786. var
  5787. e: TSuperAvlEntry;
  5788. begin
  5789. e := Search(k);
  5790. if e <> nil then
  5791. Result := e.Value else
  5792. Result := nil
  5793. end;
  5794.  
  5795. procedure TSuperTableString.PutO(const k: SOString; const value: ISuperObject);
  5796. var
  5797. entry: TSuperAvlEntry;
  5798. begin
  5799. entry := Insert(TSuperAvlEntry.Create(k, Pointer(value)));
  5800. if entry.FPtr <> nil then
  5801. ISuperObject(entry.FPtr)._AddRef;
  5802. end;
  5803.  
  5804. procedure TSuperTableString.PutS(const k: SOString; const value: SOString);
  5805. begin
  5806. PutO(k, TSuperObject.Create(Value));
  5807. end;
  5808.  
  5809. function TSuperTableString.GetS(const k: SOString): SOString;
  5810. var
  5811. obj: ISuperObject;
  5812. begin
  5813. obj := GetO(k);
  5814. if obj <> nil then
  5815. Result := obj.AsString else
  5816. Result := '';
  5817. end;
  5818.  
  5819. procedure TSuperTableString.PutI(const k: SOString; value: SuperInt);
  5820. begin
  5821. PutO(k, TSuperObject.Create(Value));
  5822. end;
  5823.  
  5824. function TSuperTableString.GetI(const k: SOString): SuperInt;
  5825. var
  5826. obj: ISuperObject;
  5827. begin
  5828. obj := GetO(k);
  5829. if obj <> nil then
  5830. Result := obj.AsInteger else
  5831. Result := ;
  5832. end;
  5833.  
  5834. procedure TSuperTableString.PutD(const k: SOString; value: Double);
  5835. begin
  5836. PutO(k, TSuperObject.Create(Value));
  5837. end;
  5838.  
  5839. procedure TSuperTableString.PutC(const k: SOString; value: Currency);
  5840. begin
  5841. PutO(k, TSuperObject.CreateCurrency(Value));
  5842. end;
  5843.  
  5844. function TSuperTableString.GetC(const k: SOString): Currency;
  5845. var
  5846. obj: ISuperObject;
  5847. begin
  5848. obj := GetO(k);
  5849. if obj <> nil then
  5850. Result := obj.AsCurrency else
  5851. Result := 0.0;
  5852. end;
  5853.  
  5854. function TSuperTableString.GetD(const k: SOString): Double;
  5855. var
  5856. obj: ISuperObject;
  5857. begin
  5858. obj := GetO(k);
  5859. if obj <> nil then
  5860. Result := obj.AsDouble else
  5861. Result := 0.0;
  5862. end;
  5863.  
  5864. procedure TSuperTableString.PutB(const k: SOString; value: Boolean);
  5865. begin
  5866. PutO(k, TSuperObject.Create(Value));
  5867. end;
  5868.  
  5869. function TSuperTableString.GetB(const k: SOString): Boolean;
  5870. var
  5871. obj: ISuperObject;
  5872. begin
  5873. obj := GetO(k);
  5874. if obj <> nil then
  5875. Result := obj.AsBoolean else
  5876. Result := False;
  5877. end;
  5878.  
  5879. {$IFDEF SUPER_METHOD}
  5880. procedure TSuperTableString.PutM(const k: SOString; value: TSuperMethod);
  5881. begin
  5882. PutO(k, TSuperObject.Create(Value));
  5883. end;
  5884. {$ENDIF}
  5885.  
  5886. {$IFDEF SUPER_METHOD}
  5887. function TSuperTableString.GetM(const k: SOString): TSuperMethod;
  5888. var
  5889. obj: ISuperObject;
  5890. begin
  5891. obj := GetO(k);
  5892. if obj <> nil then
  5893. Result := obj.AsMethod else
  5894. Result := nil;
  5895. end;
  5896. {$ENDIF}
  5897.  
  5898. procedure TSuperTableString.PutN(const k: SOString; const value: ISuperObject);
  5899. begin
  5900. if value <> nil then
  5901. PutO(k, TSuperObject.Create(stNull)) else
  5902. PutO(k, value);
  5903. end;
  5904.  
  5905. function TSuperTableString.GetN(const k: SOString): ISuperObject;
  5906. var
  5907. obj: ISuperObject;
  5908. begin
  5909. obj := GetO(k);
  5910. if obj <> nil then
  5911. Result := obj else
  5912. Result := TSuperObject.Create(stNull);
  5913. end;
  5914.  
  5915. {$IFDEF VER210}
  5916.  
  5917. { TSuperAttribute }
  5918.  
  5919. constructor TSuperAttribute.Create(const AName: string);
  5920. begin
  5921. FName := AName;
  5922. end;
  5923.  
  5924. { TSuperRttiContext }
  5925.  
  5926. constructor TSuperRttiContext.Create;
  5927. begin
  5928. Context := TRttiContext.Create;
  5929. SerialFromJson := TDictionary<PTypeInfo, TSerialFromJson>.Create;
  5930. SerialToJson := TDictionary<PTypeInfo, TSerialToJson>.Create;
  5931.  
  5932. SerialFromJson.Add(TypeInfo(Boolean), serialfromboolean);
  5933. SerialFromJson.Add(TypeInfo(TDateTime), serialfromdatetime);
  5934. SerialFromJson.Add(TypeInfo(TGUID), serialfromguid);
  5935. SerialToJson.Add(TypeInfo(Boolean), serialtoboolean);
  5936. SerialToJson.Add(TypeInfo(TDateTime), serialtodatetime);
  5937. SerialToJson.Add(TypeInfo(TGUID), serialtoguid);
  5938. end;
  5939.  
  5940. destructor TSuperRttiContext.Destroy;
  5941. begin
  5942. SerialFromJson.Free;
  5943. SerialToJson.Free;
  5944. Context.Free;
  5945. end;
  5946.  
  5947. class function TSuperRttiContext.GetFieldName(r: TRttiField): string;
  5948. var
  5949. o: TCustomAttribute;
  5950. begin
  5951. for o in r.GetAttributes do
  5952. if o is SOName then
  5953. Exit(SOName(o).Name);
  5954. Result := r.Name;
  5955. end;
  5956.  
  5957. class function TSuperRttiContext.GetFieldDefault(r: TRttiField; const obj: ISuperObject): ISuperObject;
  5958. var
  5959. o: TCustomAttribute;
  5960. begin
  5961. if not ObjectIsType(obj, stNull) then Exit(obj);
  5962. for o in r.GetAttributes do
  5963. if o is SODefault then
  5964. Exit(SO(SODefault(o).Name));
  5965. Result := obj;
  5966. end;
  5967.  
  5968. function TSuperRttiContext.AsType<T>(const obj: ISuperObject): T;
  5969. var
  5970. ret: TValue;
  5971. begin
  5972. if FromJson(TypeInfo(T), obj, ret) then
  5973. Result := ret.AsType<T> else
  5974. raise exception.Create('Marshalling error');
  5975. end;
  5976.  
  5977. function TSuperRttiContext.AsJson<T>(const obj: T; const index: ISuperObject = nil): ISuperObject;
  5978. var
  5979. v: TValue;
  5980. begin
  5981. TValue.MakeWithoutCopy(@obj, TypeInfo(T), v);
  5982. if index <> nil then
  5983. Result := ToJson(v, index) else
  5984. Result := ToJson(v, so);
  5985. end;
  5986.  
  5987. function TSuperRttiContext.FromJson(TypeInfo: PTypeInfo; const obj: ISuperObject;
  5988. var Value: TValue): Boolean;
  5989.  
  5990. procedure FromChar;
  5991. begin
  5992. if ObjectIsType(obj, stString) and (Length(obj.AsString) = ) then
  5993. begin
  5994. Value := string(AnsiString(obj.AsString)[]);
  5995. Result := True;
  5996. end else
  5997. Result := False;
  5998. end;
  5999.  
  6000. procedure FromWideChar;
  6001. begin
  6002. if ObjectIsType(obj, stString) and (Length(obj.AsString) = ) then
  6003. begin
  6004. Value := obj.AsString[];
  6005. Result := True;
  6006. end else
  6007. Result := False;
  6008. end;
  6009.  
  6010. procedure FromInt64;
  6011. var
  6012. i: Int64;
  6013. begin
  6014. case ObjectGetType(obj) of
  6015. stInt:
  6016. begin
  6017. TValue.Make(nil, TypeInfo, Value);
  6018. TValueData(Value).FAsSInt64 := obj.AsInteger;
  6019. Result := True;
  6020. end;
  6021. stString:
  6022. begin
  6023. if TryStrToInt64(obj.AsString, i) then
  6024. begin
  6025. TValue.Make(nil, TypeInfo, Value);
  6026. TValueData(Value).FAsSInt64 := i;
  6027. Result := True;
  6028. end else
  6029. Result := False;
  6030. end;
  6031. else
  6032. Result := False;
  6033. end;
  6034. end;
  6035.  
  6036. procedure FromInt(const obj: ISuperObject);
  6037. var
  6038. TypeData: PTypeData;
  6039. i: Integer;
  6040. o: ISuperObject;
  6041. begin
  6042. case ObjectGetType(obj) of
  6043. stInt, stBoolean:
  6044. begin
  6045. i := obj.AsInteger;
  6046. TypeData := GetTypeData(TypeInfo);
  6047. Result := (i >= TypeData.MinValue) and (i <= TypeData.MaxValue);
  6048. if Result then
  6049. TValue.Make(@i, TypeInfo, Value);
  6050. end;
  6051. stString:
  6052. begin
  6053. o := SO(obj.AsString);
  6054. if not ObjectIsType(o, stString) then
  6055. FromInt(o) else
  6056. Result := False;
  6057. end;
  6058. else
  6059. Result := False;
  6060. end;
  6061. end;
  6062.  
  6063. procedure fromSet;
  6064. begin
  6065. if ObjectIsType(obj, stInt) then
  6066. begin
  6067. TValue.Make(nil, TypeInfo, Value);
  6068. TValueData(Value).FAsSLong := obj.AsInteger;
  6069. Result := True;
  6070. end else
  6071. Result := False;
  6072. end;
  6073.  
  6074. procedure FromFloat(const obj: ISuperObject);
  6075. var
  6076. o: ISuperObject;
  6077. begin
  6078. case ObjectGetType(obj) of
  6079. stInt, stDouble, stCurrency:
  6080. begin
  6081. TValue.Make(nil, TypeInfo, Value);
  6082. case GetTypeData(TypeInfo).FloatType of
  6083. ftSingle: TValueData(Value).FAsSingle := obj.AsDouble;
  6084. ftDouble: TValueData(Value).FAsDouble := obj.AsDouble;
  6085. ftExtended: TValueData(Value).FAsExtended := obj.AsDouble;
  6086. ftComp: TValueData(Value).FAsSInt64 := obj.AsInteger;
  6087. ftCurr: TValueData(Value).FAsCurr := obj.AsCurrency;
  6088. end;
  6089. Result := True;
  6090. end;
  6091. stString:
  6092. begin
  6093. o := SO(obj.AsString);
  6094. if not ObjectIsType(o, stString) then
  6095. FromFloat(o) else
  6096. Result := False;
  6097. end
  6098. else
  6099. Result := False;
  6100. end;
  6101. end;
  6102.  
  6103. procedure FromString;
  6104. begin
  6105. case ObjectGetType(obj) of
  6106. stObject, stArray:
  6107. Result := False;
  6108. stnull:
  6109. begin
  6110. Value := '';
  6111. Result := True;
  6112. end;
  6113. else
  6114. Value := obj.AsString;
  6115. Result := True;
  6116. end;
  6117. end;
  6118.  
  6119. procedure FromClass;
  6120. var
  6121. f: TRttiField;
  6122. v: TValue;
  6123. begin
  6124. case ObjectGetType(obj) of
  6125. stObject:
  6126. begin
  6127. Result := True;
  6128. if Value.Kind <> tkClass then
  6129. Value := GetTypeData(TypeInfo).ClassType.Create;
  6130. for f in Context.GetType(Value.AsObject.ClassType).GetFields do
  6131. if f.FieldType <> nil then
  6132. begin
  6133. Result := FromJson(f.FieldType.Handle, GetFieldDefault(f, obj.AsObject[GetFieldName(f)]), v);
  6134. if Result then
  6135. f.SetValue(Value.AsObject, v) else
  6136. Exit;
  6137. end;
  6138. end;
  6139. stNull:
  6140. begin
  6141. Value := nil;
  6142. Result := True;
  6143. end
  6144. else
  6145. // error
  6146. Value := nil;
  6147. Result := False;
  6148. end;
  6149. end;
  6150.  
  6151. procedure FromRecord;
  6152. var
  6153. f: TRttiField;
  6154. p: Pointer;
  6155. v: TValue;
  6156. begin
  6157. Result := True;
  6158. TValue.Make(nil, TypeInfo, Value);
  6159. for f in Context.GetType(TypeInfo).GetFields do
  6160. begin
  6161. if ObjectIsType(obj, stObject) and (f.FieldType <> nil) then
  6162. begin
  6163. p := IValueData(TValueData(Value).FHeapData).GetReferenceToRawData;
  6164. Result := FromJson(f.FieldType.Handle, GetFieldDefault(f, obj.AsObject[GetFieldName(f)]), v);
  6165. if Result then
  6166. f.SetValue(p, v) else
  6167. Exit;
  6168. end else
  6169. begin
  6170. Result := False;
  6171. Exit;
  6172. end;
  6173. end;
  6174. end;
  6175.  
  6176. procedure FromDynArray;
  6177. var
  6178. i: Integer;
  6179. p: Pointer;
  6180. pb: PByte;
  6181. val: TValue;
  6182. typ: PTypeData;
  6183. el: PTypeInfo;
  6184. begin
  6185. case ObjectGetType(obj) of
  6186. stArray:
  6187. begin
  6188. i := obj.AsArray.Length;
  6189. p := nil;
  6190. DynArraySetLength(p, TypeInfo, , @i);
  6191. pb := p;
  6192. typ := GetTypeData(TypeInfo);
  6193. if typ.elType <> nil then
  6194. el := typ.elType^ else
  6195. el := typ.elType2^;
  6196.  
  6197. Result := True;
  6198. for i := to i - do
  6199. begin
  6200. Result := FromJson(el, obj.AsArray[i], val);
  6201. if not Result then
  6202. Break;
  6203. val.ExtractRawData(pb);
  6204. val := TValue.Empty;
  6205. Inc(pb, typ.elSize);
  6206. end;
  6207. if Result then
  6208. TValue.MakeWithoutCopy(@p, TypeInfo, Value) else
  6209. DynArrayClear(p, TypeInfo);
  6210. end;
  6211. stNull:
  6212. begin
  6213. TValue.MakeWithoutCopy(nil, TypeInfo, Value);
  6214. Result := True;
  6215. end;
  6216. else
  6217. i := ;
  6218. p := nil;
  6219. DynArraySetLength(p, TypeInfo, , @i);
  6220. pb := p;
  6221. typ := GetTypeData(TypeInfo);
  6222. if typ.elType <> nil then
  6223. el := typ.elType^ else
  6224. el := typ.elType2^;
  6225.  
  6226. Result := FromJson(el, obj, val);
  6227. val.ExtractRawData(pb);
  6228. val := TValue.Empty;
  6229.  
  6230. if Result then
  6231. TValue.MakeWithoutCopy(@p, TypeInfo, Value) else
  6232. DynArrayClear(p, TypeInfo);
  6233. end;
  6234. end;
  6235.  
  6236. procedure FromArray;
  6237. var
  6238. ArrayData: PArrayTypeData;
  6239. idx: Integer;
  6240. function ProcessDim(dim: Byte; const o: ISuperobject): Boolean;
  6241. var
  6242. i: Integer;
  6243. v: TValue;
  6244. a: PTypeData;
  6245. begin
  6246. if ObjectIsType(o, stArray) and (ArrayData.Dims[dim-] <> nil) then
  6247. begin
  6248. a := @GetTypeData(ArrayData.Dims[dim-]^).ArrayData;
  6249. if (a.MaxValue - a.MinValue + ) <> o.AsArray.Length then
  6250. begin
  6251. Result := False;
  6252. Exit;
  6253. end;
  6254. Result := True;
  6255. if dim = ArrayData.DimCount then
  6256. for i := a.MinValue to a.MaxValue do
  6257. begin
  6258. Result := FromJson(ArrayData.ElType^, o.AsArray[i], v);
  6259. if not Result then
  6260. Exit;
  6261. Value.SetArrayElement(idx, v);
  6262. inc(idx);
  6263. end
  6264. else
  6265. for i := a.MinValue to a.MaxValue do
  6266. begin
  6267. Result := ProcessDim(dim + , o.AsArray[i]);
  6268. if not Result then
  6269. Exit;
  6270. end;
  6271. end else
  6272. Result := False;
  6273. end;
  6274. var
  6275. i: Integer;
  6276. v: TValue;
  6277. begin
  6278. TValue.Make(nil, TypeInfo, Value);
  6279. ArrayData := @GetTypeData(TypeInfo).ArrayData;
  6280. idx := ;
  6281. if ArrayData.DimCount = then
  6282. begin
  6283. if ObjectIsType(obj, stArray) and (obj.AsArray.Length = ArrayData.ElCount) then
  6284. begin
  6285. Result := True;
  6286. for i := to ArrayData.ElCount - do
  6287. begin
  6288. Result := FromJson(ArrayData.ElType^, obj.AsArray[i], v);
  6289. if not Result then
  6290. Exit;
  6291. Value.SetArrayElement(idx, v);
  6292. v := TValue.Empty;
  6293. inc(idx);
  6294. end;
  6295. end else
  6296. Result := False;
  6297. end else
  6298. Result := ProcessDim(, obj);
  6299. end;
  6300.  
  6301. procedure FromClassRef;
  6302. var
  6303. r: TRttiType;
  6304. begin
  6305. if ObjectIsType(obj, stString) then
  6306. begin
  6307. r := Context.FindType(obj.AsString);
  6308. if r <> nil then
  6309. begin
  6310. Value := TRttiInstanceType(r).MetaclassType;
  6311. Result := True;
  6312. end else
  6313. Result := False;
  6314. end else
  6315. Result := False;
  6316. end;
  6317.  
  6318. procedure FromUnknown;
  6319. begin
  6320. case ObjectGetType(obj) of
  6321. stBoolean:
  6322. begin
  6323. Value := obj.AsBoolean;
  6324. Result := True;
  6325. end;
  6326. stDouble:
  6327. begin
  6328. Value := obj.AsDouble;
  6329. Result := True;
  6330. end;
  6331. stCurrency:
  6332. begin
  6333. Value := obj.AsCurrency;
  6334. Result := True;
  6335. end;
  6336. stInt:
  6337. begin
  6338. Value := obj.AsInteger;
  6339. Result := True;
  6340. end;
  6341. stString:
  6342. begin
  6343. Value := obj.AsString;
  6344. Result := True;
  6345. end
  6346. else
  6347. Value := nil;
  6348. Result := False;
  6349. end;
  6350. end;
  6351.  
  6352. procedure FromInterface;
  6353. const soguid: TGuid = '{4B86A9E3-E094-4E5A-954A-69048B7B6327}';
  6354. var
  6355. o: ISuperObject;
  6356. begin
  6357. if CompareMem(@GetTypeData(TypeInfo).Guid, @soguid, SizeOf(TGUID)) then
  6358. begin
  6359. if obj <> nil then
  6360. TValue.Make(@obj, TypeInfo, Value) else
  6361. begin
  6362. o := TSuperObject.Create(stNull);
  6363. TValue.Make(@o, TypeInfo, Value);
  6364. end;
  6365. Result := True;
  6366. end else
  6367. Result := False;
  6368. end;
  6369. var
  6370. Serial: TSerialFromJson;
  6371. begin
  6372. if TypeInfo <> nil then
  6373. begin
  6374. if not SerialFromJson.TryGetValue(TypeInfo, Serial) then
  6375. case TypeInfo.Kind of
  6376. tkChar: FromChar;
  6377. tkInt64: FromInt64;
  6378. tkEnumeration, tkInteger: FromInt(obj);
  6379. tkSet: fromSet;
  6380. tkFloat: FromFloat(obj);
  6381. tkString, tkLString, tkUString, tkWString: FromString;
  6382. tkClass: FromClass;
  6383. tkMethod: ;
  6384. tkWChar: FromWideChar;
  6385. tkRecord: FromRecord;
  6386. tkPointer: ;
  6387. tkInterface: FromInterface;
  6388. tkArray: FromArray;
  6389. tkDynArray: FromDynArray;
  6390. tkClassRef: FromClassRef;
  6391. else
  6392. FromUnknown
  6393. end else
  6394. begin
  6395. TValue.Make(nil, TypeInfo, Value);
  6396. Result := Serial(Self, obj, Value);
  6397. end;
  6398. end else
  6399. Result := False;
  6400. end;
  6401.  
  6402. function TSuperRttiContext.ToJson(var value: TValue; const index: ISuperObject): ISuperObject;
  6403. procedure ToInt64;
  6404. begin
  6405. Result := TSuperObject.Create(SuperInt(Value.AsInt64));
  6406. end;
  6407.  
  6408. procedure ToChar;
  6409. begin
  6410. Result := TSuperObject.Create(string(Value.AsType<AnsiChar>));
  6411. end;
  6412.  
  6413. procedure ToInteger;
  6414. begin
  6415. Result := TSuperObject.Create(TValueData(Value).FAsSLong);
  6416. end;
  6417.  
  6418. procedure ToFloat;
  6419. begin
  6420. case Value.TypeData.FloatType of
  6421. ftSingle: Result := TSuperObject.Create(TValueData(Value).FAsSingle);
  6422. ftDouble: Result := TSuperObject.Create(TValueData(Value).FAsDouble);
  6423. ftExtended: Result := TSuperObject.Create(TValueData(Value).FAsExtended);
  6424. ftComp: Result := TSuperObject.Create(TValueData(Value).FAsSInt64);
  6425. ftCurr: Result := TSuperObject.CreateCurrency(TValueData(Value).FAsCurr);
  6426. end;
  6427. end;
  6428.  
  6429. procedure ToString;
  6430. begin
  6431. Result := TSuperObject.Create(string(Value.AsType<string>));
  6432. end;
  6433.  
  6434. procedure ToClass;
  6435. var
  6436. o: ISuperObject;
  6437. f: TRttiField;
  6438. v: TValue;
  6439. begin
  6440. if TValueData(Value).FAsObject <> nil then
  6441. begin
  6442. o := index[IntToStr(Integer(Value.AsObject))];
  6443. if o = nil then
  6444. begin
  6445. Result := TSuperObject.Create(stObject);
  6446. index[IntToStr(Integer(Value.AsObject))] := Result;
  6447. for f in Context.GetType(Value.AsObject.ClassType).GetFields do
  6448. if f.FieldType <> nil then
  6449. begin
  6450. v := f.GetValue(Value.AsObject);
  6451. Result.AsObject[GetFieldName(f)] := ToJson(v, index);
  6452. end
  6453. end else
  6454. Result := o;
  6455. end else
  6456. Result := nil;
  6457. end;
  6458.  
  6459. procedure ToWChar;
  6460. begin
  6461. Result := TSuperObject.Create(string(Value.AsType<WideChar>));
  6462. end;
  6463.  
  6464. procedure ToVariant;
  6465. begin
  6466. Result := SO(Value.AsVariant);
  6467. end;
  6468.  
  6469. procedure ToRecord;
  6470. var
  6471. f: TRttiField;
  6472. v: TValue;
  6473. begin
  6474. Result := TSuperObject.Create(stObject);
  6475. for f in Context.GetType(Value.TypeInfo).GetFields do
  6476. begin
  6477. v := f.GetValue(IValueData(TValueData(Value).FHeapData).GetReferenceToRawData);
  6478. Result.AsObject[GetFieldName(f)] := ToJson(v, index);
  6479. end;
  6480. end;
  6481.  
  6482. procedure ToArray;
  6483. var
  6484. idx: Integer;
  6485. ArrayData: PArrayTypeData;
  6486.  
  6487. procedure ProcessDim(dim: Byte; const o: ISuperObject);
  6488. var
  6489. dt: PTypeData;
  6490. i: Integer;
  6491. o2: ISuperObject;
  6492. v: TValue;
  6493. begin
  6494. if ArrayData.Dims[dim-] = nil then Exit;
  6495. dt := GetTypeData(ArrayData.Dims[dim-]^);
  6496. if Dim = ArrayData.DimCount then
  6497. for i := dt.MinValue to dt.MaxValue do
  6498. begin
  6499. v := Value.GetArrayElement(idx);
  6500. o.AsArray.Add(toJSon(v, index));
  6501. inc(idx);
  6502. end
  6503. else
  6504. for i := dt.MinValue to dt.MaxValue do
  6505. begin
  6506. o2 := TSuperObject.Create(stArray);
  6507. o.AsArray.Add(o2);
  6508. ProcessDim(dim + , o2);
  6509. end;
  6510. end;
  6511. var
  6512. i: Integer;
  6513. v: TValue;
  6514. begin
  6515. Result := TSuperObject.Create(stArray);
  6516. ArrayData := @Value.TypeData.ArrayData;
  6517. idx := ;
  6518. if ArrayData.DimCount = then
  6519. for i := to ArrayData.ElCount - do
  6520. begin
  6521. v := Value.GetArrayElement(i);
  6522. Result.AsArray.Add(toJSon(v, index))
  6523. end
  6524. else
  6525. ProcessDim(, Result);
  6526. end;
  6527.  
  6528. procedure ToDynArray;
  6529. var
  6530. i: Integer;
  6531. v: TValue;
  6532. begin
  6533. Result := TSuperObject.Create(stArray);
  6534. for i := to Value.GetArrayLength - do
  6535. begin
  6536. v := Value.GetArrayElement(i);
  6537. Result.AsArray.Add(toJSon(v, index));
  6538. end;
  6539. end;
  6540.  
  6541. procedure ToClassRef;
  6542. begin
  6543. if TValueData(Value).FAsClass <> nil then
  6544. Result := TSuperObject.Create(string(
  6545. TValueData(Value).FAsClass.UnitName + '.' +
  6546. TValueData(Value).FAsClass.ClassName)) else
  6547. Result := nil;
  6548. end;
  6549.  
  6550. procedure ToInterface;
  6551. begin
  6552. if TValueData(Value).FHeapData <> nil then
  6553. TValueData(Value).FHeapData.QueryInterface(ISuperObject, Result) else
  6554. Result := nil;
  6555. end;
  6556.  
  6557. var
  6558. Serial: TSerialToJson;
  6559. begin
  6560. if not SerialToJson.TryGetValue(value.TypeInfo, Serial) then
  6561. case Value.Kind of
  6562. tkInt64: ToInt64;
  6563. tkChar: ToChar;
  6564. tkSet, tkInteger, tkEnumeration: ToInteger;
  6565. tkFloat: ToFloat;
  6566. tkString, tkLString, tkUString, tkWString: ToString;
  6567. tkClass: ToClass;
  6568. tkWChar: ToWChar;
  6569. tkVariant: ToVariant;
  6570. tkRecord: ToRecord;
  6571. tkArray: ToArray;
  6572. tkDynArray: ToDynArray;
  6573. tkClassRef: ToClassRef;
  6574. tkInterface: ToInterface;
  6575. else
  6576. result := nil;
  6577. end else
  6578. Result := Serial(Self, value, index);
  6579. end;
  6580.  
  6581. { TSuperObjectHelper }
  6582.  
  6583. constructor TSuperObjectHelper.FromJson(const obj: ISuperObject; ctx: TSuperRttiContext = nil);
  6584. var
  6585. v: TValue;
  6586. ctxowned: Boolean;
  6587. begin
  6588. if ctx = nil then
  6589. begin
  6590. ctx := TSuperRttiContext.Create;
  6591. ctxowned := True;
  6592. end else
  6593. ctxowned := False;
  6594. try
  6595. v := Self;
  6596. if not ctx.FromJson(v.TypeInfo, obj, v) then
  6597. raise Exception.Create('Invalid object');
  6598. finally
  6599. if ctxowned then
  6600. ctx.Free;
  6601. end;
  6602. end;
  6603.  
  6604. constructor TSuperObjectHelper.FromJson(const str: string; ctx: TSuperRttiContext = nil);
  6605. begin
  6606. FromJson(SO(str), ctx);
  6607. end;
  6608.  
  6609. function TSuperObjectHelper.ToJson(ctx: TSuperRttiContext = nil): ISuperObject;
  6610. var
  6611. v: TValue;
  6612. ctxowned: boolean;
  6613. begin
  6614. if ctx = nil then
  6615. begin
  6616. ctx := TSuperRttiContext.Create;
  6617. ctxowned := True;
  6618. end else
  6619. ctxowned := False;
  6620. try
  6621. v := Self;
  6622. Result := ctx.ToJson(v, SO);
  6623. finally
  6624. if ctxowned then
  6625. ctx.Free;
  6626. end;
  6627. end;
  6628.  
  6629. {$ENDIF}
  6630.  
  6631. {$IFDEF DEBUG}
  6632. initialization
  6633.  
  6634. finalization
  6635. Assert(debugcount = , 'Memory leak');
  6636. {$ENDIF}
  6637. end.

排序功能,参考:  http://www.cnblogs.com/DKSoft/category/284941.html  感谢

Super Object Toolkit (支持排序)的更多相关文章

  1. winform datagridview 绑定泛型集合变得不支持排序的解决方案

    原文:winform datagridview 绑定泛型集合变得不支持排序的解决方案 案例: 环境:Winform程序 控件:Datagridview 现象:Datagridview控件绑定到List ...

  2. 给object数组进行排序(排序条件是每个元素对象的属性个数)

    从汤姆大叔的博客里看到了6个基础题目:本篇是第3题 - 给object数组进行排序(排序条件是每个元素对象的属性个数) 解题关键: 1.Array.sort的用法 2.object的属性数量的统计 解 ...

  3. 将map转为Object,支持 Date/Boolean

    import lombok.extern.log4j.Log4j2; import java.lang.reflect.Field; import java.lang.reflect.Method; ...

  4. Mybatis-Plus的Service方法使用 之 泛型方法default <V> List<V> listObjs(Function<? super Object, V> mapper)

    首先 我们先看到的这个方法入参是:Function<? super Object , V> mapper ,这是jdk1.8为了统一简化书写格式引进的函数式接口 . 简单 解释一下我对Fu ...

  5. 修改后的SQL分页存储过程,利用2分法,支持排序

    /****** Object: StoredProcedure [dbo].[sys_Page_v3] Script Date: 08/13/2014 09:32:28 ******/ SET ANS ...

  6. 无限分级Repeater递归实现:读取一次数据库,使用LINQ2SQL技术,支持排序&amp;显示隐藏

    预览效果图: Selenium 数据库结构: id(int)    classname(string)   parentid(int) sort(int用于显示与排序) 1 家居 0 1 2 家电 0 ...

  7. Coding4Fun Toolkit支持本地化解决办法

    在项目中需要使用Coding4Fun Toolkit中的TimePicker控件, 1. 但是在中文系统下显示的却是英文: 2. 最后发现,需要在源代码中添加中文资源,并重新编译出包含中文语言的dll ...

  8. Js比较对Object类型进行排序

    <script> var data=[{name:"121",age:"18",year:"2018"},{name:" ...

  9. superobject 设定排序方式

    (* * Super Object Toolkit * * Usage allowed under the restrictions of the Lesser GNU General Public ...

随机推荐

  1. 通过layer的contents属性来实现uiimageview的淡入切换

    #import "ViewController.h" @interface ViewController () @property(nonatomic,strong)CALayer ...

  2. Java SE ---控制流程:break与continue语句

    在java中,可以使用break和continue语句控制循环.     1. break语句:用于终止循环,就是跳出当前循环,执行循环后面的代码. .     2. continue语句:用于跳出当 ...

  3. IT项目技术建议书核心内容

    第一部分:概述部分 该部分的重点是理解标书,理解项目建设的背景,建设该项目的初衷究竟是什么?需要解决的核心关键问题是什么?基于对项目的理解然后明确项目建设的目标,项目建设的原则,项目本事的定位,项目建 ...

  4. nodejs的mysql模块学习(七)连接池事件

    连接池事件 connection 当建立连接的时候就会触发 pool.on('connection' function(connection){ connection.query('SET SESSI ...

  5. spring事务管理出错。No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy ...

  6. Eclipse中web项目的默认发布路径改为外部Tomcat中webapp路径

    可参考http://www.cnblogs.com/mihu/p/4772509.html 和http://www.cnblogs.com/dyllove98/archive/2013/06/07/3 ...

  7. 自定义UISearchDisplayController中搜索到结果的cell的位置

    #pragma mark - UISearchBarDelegate//当搜索文本被改变的时候调用 - (void)searchBar:(UISearchBar *)searchBar textDid ...

  8. Oracle数据库作业-5 查询

    14.查询所有学生的Sname.Cno和Degree列. select t.sname,c.cno,c.degree from student t inner join score c on t.sn ...

  9. 【转】Oracle 中的 TO_DATE 和 TO_CHAR 函数 日期处理

    Oracle 中的 TO_DATE 和 TO_CHAR 函数oracle 中 TO_DATE 函数的时间格式,以 2008-09-10 23:45:56 为例 格式 说明 显示值 备注 Year(年) ...

  10. CSS - 实现文字显示过长时用省略

    一.添加-文字显示超出范围时隐藏属性 overflow:hidden; 二.添加-超出文字省略号属性 text-overflow:ellipsis; 三.添加-文字不换行属性 white-space: ...