SimpleMsgPack.pas 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976
  1. (*
  2. unit Owner: D10.Mofen, qdac.swish
  3. welcome to report bug: 185511468(qq), 185511468@qq.com
  4. Web site : https://github.com/ymofen/msgpack-delphi
  5. * Delphi 2007 (tested)
  6. * XE5, XE7 (tested)
  7. + first release
  8. 2014-08-15 13:05:13
  9. + add array support
  10. 2014-08-19 12:18:47
  11. + add andriod support
  12. 2014-09-08 00:45:27
  13. samples:
  14. lvMsgPack:=TSimpleMsgPack.Create;
  15. lvMsgPack.S['root.child01'] := 'abc';
  16. //save to stream
  17. lvMsgPack.EncodeToStream(pvStream);
  18. Copyright (c) 2014, ymofen, swish
  19. All rights reserved.
  20. Redistribution and use in source and binary forms, with or without
  21. modification, are permitted provided that the following conditions are met:
  22. * Redistributions of source code must retain the above copyright notice, this
  23. list of conditions and the following disclaimer.
  24. * Redistributions in binary form must reproduce the above copyright notice,
  25. this list of conditions and the following disclaimer in the documentation
  26. and/or other materials provided with the distribution.
  27. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  28. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  29. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  30. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  31. FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  32. DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  33. SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  34. CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  35. OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  36. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37. *)
  38. unit SimpleMsgPack;
  39. interface
  40. uses
  41. classes, SysUtils
  42. {$IFDEF UNICODE}, Generics.Collections{$ELSE}, Contnrs{$ENDIF}
  43. {$IFDEF MSWINDOWS}, Windows{$ENDIF}
  44. ,Variants;
  45. type
  46. {$IF RTLVersion<25}
  47. IntPtr=Integer;
  48. {$IFEND IntPtr}
  49. {$if CompilerVersion < 18} //before delphi 2007
  50. TBytes = array of Byte;
  51. {$ifend}
  52. TMsgPackType = (mptUnknown, mptNull, mptMap, mptArray, mptString, mptInteger,
  53. mptBoolean, mptFloat, mptSingle, mptDateTime, mptBinary);
  54. // reserved
  55. IMsgPack = interface
  56. ['{37D3E479-7A46-435A-914D-08FBDA75B50E}']
  57. end;
  58. // copy from qmsgPack
  59. TMsgPackValue= packed record
  60. ValueType:Byte;
  61. case Integer of
  62. 0:(U8Val:Byte);
  63. 1:(I8Val:Shortint);
  64. 2:(U16Val:Word);
  65. 3:(I16Val:Smallint);
  66. 4:(U32Val:Cardinal);
  67. 5:(I32Val:Integer);
  68. 6:(U64Val:UInt64);
  69. 7:(I64Val:Int64);
  70. 8:(F32Val:Single);
  71. 9:(F64Val:Double);
  72. 10:(BArray:array[0..16] of Byte);
  73. end;
  74. TMsgPackSetting = class(TObject)
  75. private
  76. FCaseSensitive: Boolean;
  77. public
  78. property CaseSensitive: Boolean read FCaseSensitive write FCaseSensitive;
  79. end;
  80. TSimpleMsgPack = class(TObject)
  81. private
  82. FParent:TSimpleMsgPack;
  83. FLowerName:String;
  84. FName:String;
  85. FValue:TBytes;
  86. FDataType:TMsgPackType;
  87. {$IFDEF UNICODE}
  88. FChildren: TObjectList<TSimpleMsgPack>;
  89. {$ELSE}
  90. FChildren: TObjectList;
  91. {$ENDIF}
  92. procedure InnerAddToChildren(obj:TSimpleMsgPack);
  93. function InnerAdd: TSimpleMsgPack;
  94. function GetCount: Integer;
  95. procedure InnerEncodeToStream(pvStream:TStream);
  96. procedure InnerParseFromStream(pvStream: TStream);
  97. procedure setName(pvName:string);
  98. private
  99. function getAsString: String;
  100. procedure setAsString(pvValue:string);
  101. function getAsInteger: Int64;
  102. procedure setAsInteger(pvValue:Int64);
  103. function GetAsBoolean: Boolean;
  104. procedure SetAsBoolean(const Value: Boolean);
  105. procedure SetAsFloat(const Value: Double);
  106. function GetAsFloat: Double;
  107. procedure SetAsDateTime(const Value: TDateTime);
  108. function GetAsDateTime: TDateTime;
  109. function GetAsVariant: Variant;
  110. procedure SetAsVariant(const Value: Variant);
  111. procedure SetAsSingle(const Value: Single);
  112. function GetAsSingle: Single;
  113. procedure SetAsBytes(const Value: TBytes);
  114. function GetAsBytes: TBytes;
  115. procedure checkObjectDataType(ANewType: TMsgPackType = mptMap);
  116. function findObj(pvName:string): TSimpleMsgPack;
  117. function indexOf(pvName:string): Integer;
  118. function indexOfCaseSensitive(pvName:string): Integer;
  119. function indexOfIgnoreSensitive(pvLowerCaseName: string): Integer;
  120. private
  121. /// <summary>
  122. /// find object index by a path
  123. /// </summary>
  124. function InnerFindPathObject(pvPath: string; var vParent: TSimpleMsgPack; var
  125. vIndex: Integer): TSimpleMsgPack;
  126. function GetO(pvPath: String): TSimpleMsgPack;
  127. procedure SetO(pvPath: String; const Value: TSimpleMsgPack);
  128. function GetS(pvPath: String): string;
  129. procedure SetS(pvPath: String; const Value: string);
  130. function GetI(pvPath: String): Int64;
  131. procedure SetI(pvPath: String; const Value: Int64);
  132. function GetB(pvPath: String): Boolean;
  133. procedure SetB(pvPath: String; const Value: Boolean);
  134. function GetD(pvPath: String): Double;
  135. procedure SetD(pvPath: String; const Value: Double);
  136. function GetItems(AIndex: Integer): TSimpleMsgPack;
  137. /// <summary>
  138. /// delete a children
  139. /// </summary>
  140. procedure NotifyForDeleteChildren;
  141. public
  142. constructor Create;
  143. destructor Destroy; override;
  144. procedure clear;
  145. property Count: Integer read GetCount;
  146. procedure LoadBinaryFromStream(pvStream: TStream; pvLen: cardinal = 0);
  147. procedure SaveBinaryToStream(pvStream:TStream);
  148. procedure LoadBinaryFromFile(pvFileName:String);
  149. procedure SaveBinaryToFile(pvFileName:String);
  150. procedure EncodeToStream(pvStream:TStream);
  151. procedure DecodeFromStream(pvStream:TStream);
  152. function EncodeToBytes: TBytes;
  153. procedure DecodeFromBytes(pvBytes:TBytes);
  154. function Add(pvNameKey, pvValue: string): TSimpleMsgPack; overload;
  155. function Add(pvNameKey: string; pvValue: Int64): TSimpleMsgPack; overload;
  156. function Add(pvNameKey: string; pvValue: TBytes): TSimpleMsgPack; overload;
  157. function Add(pvNameKey: String): TSimpleMsgPack; overload;
  158. function Add():TSimpleMsgPack; overload;
  159. function ForcePathObject(pvPath:string): TSimpleMsgPack;
  160. /// <summary>
  161. /// remove and free object
  162. /// false : object is not found!
  163. /// </summary>
  164. function DeleteObject(pvPath:String):Boolean;
  165. property AsInteger:Int64 read getAsInteger write setAsInteger;
  166. property AsString:string read getAsString write setAsString;
  167. property AsBoolean: Boolean read GetAsBoolean write SetAsBoolean;
  168. property AsFloat: Double read GetAsFloat write SetAsFloat;
  169. property AsSingle: Single read GetAsSingle write SetAsSingle;
  170. property AsDateTime: TDateTime read GetAsDateTime write SetAsDateTime;
  171. property AsVariant: Variant read GetAsVariant write SetAsVariant;
  172. property AsBytes: TBytes read GetAsBytes write SetAsBytes;
  173. property O[pvPath: String]: TSimpleMsgPack read GetO write SetO;
  174. property S[pvPath: String]: string read GetS write SetS;
  175. property I[pvPath: String]: Int64 read GetI write SetI;
  176. property B[pvPath: String]: Boolean read GetB write SetB;
  177. property D[pvPath: String]: Double read GetD write SetD;
  178. property Items[AIndex: Integer]: TSimpleMsgPack read GetItems; default;
  179. end;
  180. implementation
  181. resourcestring
  182. SVariantConvertNotSupport = 'type to convert not support!。';
  183. function swap16(const v): Word;
  184. begin
  185. // FF, EE : EE->1, FF->2
  186. PByte(@result)^ := PByte(IntPtr(@v) + 1)^;
  187. PByte(IntPtr(@result) + 1)^ := PByte(@v)^;
  188. end;
  189. function swap32(const v): Cardinal;
  190. begin
  191. // FF, EE, DD, CC : CC->1, DD->2, EE->3, FF->4
  192. PByte(@result)^ := PByte(IntPtr(@v) + 3)^;
  193. PByte(IntPtr(@result) + 1)^ := PByte(IntPtr(@v) + 2)^;
  194. PByte(IntPtr(@result) + 2)^ := PByte(IntPtr(@v) + 1)^;
  195. PByte(IntPtr(@result) + 3)^ := PByte(@v)^;
  196. end;
  197. function swap64(const v): Int64;
  198. begin
  199. // FF, EE, DD, CC, BB, AA, 99, 88 : 88->1 ,99->2 ....
  200. PByte(@result)^ := PByte(IntPtr(@v) + 7)^;
  201. PByte(IntPtr(@result) + 1)^ := PByte(IntPtr(@v) + 6)^;
  202. PByte(IntPtr(@result) + 2)^ := PByte(IntPtr(@v) + 5)^;
  203. PByte(IntPtr(@result) + 3)^ := PByte(IntPtr(@v) + 4)^;
  204. PByte(IntPtr(@result) + 4)^ := PByte(IntPtr(@v) + 3)^;
  205. PByte(IntPtr(@result) + 5)^ := PByte(IntPtr(@v) + 2)^;
  206. PByte(IntPtr(@result) + 6)^ := PByte(IntPtr(@v) + 1)^;
  207. PByte(IntPtr(@result) + 7)^ := PByte(@v)^;
  208. end;
  209. // v and outVal is can't the same value
  210. procedure swap64Ex(const v; out outVal);
  211. begin
  212. // FF, EE, DD, CC, BB, AA, 99, 88 : 88->1 ,99->2 ....
  213. PByte(@outVal)^ := PByte(IntPtr(@v) + 7)^;
  214. PByte(IntPtr(@outVal) + 1)^ := PByte(IntPtr(@v) + 6)^;
  215. PByte(IntPtr(@outVal) + 2)^ := PByte(IntPtr(@v) + 5)^;
  216. PByte(IntPtr(@outVal) + 3)^ := PByte(IntPtr(@v) + 4)^;
  217. PByte(IntPtr(@outVal) + 4)^ := PByte(IntPtr(@v) + 3)^;
  218. PByte(IntPtr(@outVal) + 5)^ := PByte(IntPtr(@v) + 2)^;
  219. PByte(IntPtr(@outVal) + 6)^ := PByte(IntPtr(@v) + 1)^;
  220. PByte(IntPtr(@outVal) + 7)^ := PByte(@v)^;
  221. end;
  222. // v and outVal is can't the same value
  223. procedure swap32Ex(const v; out outVal);
  224. begin
  225. // FF, EE, DD, CC : CC->1, DD->2, EE->3, FF->4
  226. PByte(@outVal)^ := PByte(IntPtr(@v) + 3)^;
  227. PByte(IntPtr(@outVal) + 1)^ := PByte(IntPtr(@v) + 2)^;
  228. PByte(IntPtr(@outVal) + 2)^ := PByte(IntPtr(@v) + 1)^;
  229. PByte(IntPtr(@outVal) + 3)^ := PByte(@v)^;
  230. end;
  231. // v and outVal is can't the same value
  232. procedure swap16Ex(const v; out outVal);
  233. begin
  234. // FF, EE : EE->1, FF->2
  235. PByte(@outVal)^ := PByte(IntPtr(@v) + 1)^;
  236. PByte(IntPtr(@outVal) + 1)^ := PByte(@v)^;
  237. end;
  238. // overload swap
  239. function swap(v:Single):Single; overload;
  240. begin
  241. swap16Ex(v, Result);
  242. end;
  243. // overload swap
  244. function swap(v:word):Word; overload;
  245. begin
  246. swap16Ex(v, Result);
  247. end;
  248. // overload swap
  249. function swap(v:Cardinal):Cardinal; overload;
  250. begin
  251. swap32Ex(v, Result);
  252. end;
  253. function swap(v:Double):Double; overload;
  254. begin
  255. swap64Ex(v, Result);
  256. end;
  257. // copy from qstring
  258. function BinToHex(p: Pointer; l: Integer; ALowerCase: Boolean): string;
  259. const
  260. B2HConvert: array [0 .. 15] of Char = ('0', '1', '2', '3', '4', '5', '6',
  261. '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
  262. B2HConvertL: array [0 .. 15] of Char = ('0', '1', '2', '3', '4', '5', '6',
  263. '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
  264. var
  265. pd: PChar;
  266. pb: PByte;
  267. begin
  268. if SizeOf(Char) = 2 then
  269. begin
  270. SetLength(Result, l shl 1);
  271. end else
  272. begin
  273. SetLength(Result, l);
  274. end;
  275. pd := PChar(Result);
  276. pb := p;
  277. if ALowerCase then
  278. begin
  279. while l > 0 do
  280. begin
  281. pd^ := B2HConvertL[pb^ shr 4];
  282. Inc(pd);
  283. pd^ := B2HConvertL[pb^ and $0F];
  284. Inc(pd);
  285. Inc(pb);
  286. Dec(l);
  287. end;
  288. end
  289. else
  290. begin
  291. while l > 0 do
  292. begin
  293. pd^ := B2HConvert[pb^ shr 4];
  294. Inc(pd);
  295. pd^ := B2HConvert[pb^ and $0F];
  296. Inc(pd);
  297. Inc(pb);
  298. Dec(l);
  299. end;
  300. end;
  301. end;
  302. function getFirst(var strPtr: PChar; splitChars: TSysCharSet): string;
  303. var
  304. oPtr:PChar;
  305. l:Cardinal;
  306. begin
  307. oPtr := strPtr;
  308. Result := '';
  309. while True do
  310. begin
  311. if (strPtr^ in splitChars) then
  312. begin
  313. l := strPtr - oPtr;
  314. if l > 0 then
  315. begin
  316. {$IFDEF UNICODE}
  317. SetLength(Result, l);
  318. Move(oPtr^, PChar(Result)^, l shl 1);
  319. {$ELSE}
  320. SetLength(Result, l);
  321. Move(oPtr^, PChar(Result)^, l);
  322. {$ENDIF}
  323. break;
  324. end;
  325. end else if (strPtr^ = #0) then
  326. begin
  327. l := strPtr - oPtr;
  328. if l > 0 then
  329. begin
  330. {$IFDEF UNICODE}
  331. SetLength(Result, l);
  332. Move(oPtr^, PChar(Result)^, l shl 1);
  333. {$ELSE}
  334. SetLength(Result, l);
  335. Move(oPtr^, PChar(Result)^, l);
  336. {$ENDIF}
  337. end;
  338. break;
  339. end;
  340. Inc(strPtr);
  341. end;
  342. end;
  343. function Utf8DecodeEx(pvValue:{$IFDEF UNICODE}TBytes{$ELSE}AnsiString{$ENDIF}; len:Cardinal):string;
  344. {$IFDEF UNICODE}
  345. var
  346. lvBytes:TBytes;
  347. {$ENDIF}
  348. begin
  349. {$IFDEF UNICODE}
  350. lvBytes := TEncoding.Convert(TEncoding.UTF8, TEncoding.Unicode, pvValue);
  351. SetLength(Result, Length(lvBytes) shr 1);
  352. Move(lvBytes[0], PChar(Result)^, Length(lvBytes));
  353. {$ELSE}
  354. result:= UTF8Decode(pvValue);
  355. {$ENDIF}
  356. end;
  357. function Utf8EncodeEx(pvValue:string):{$IFDEF UNICODE}TBytes{$ELSE}AnsiString{$ENDIF};
  358. {$IFDEF UNICODE}
  359. var
  360. lvBytes:TBytes;
  361. len:Cardinal;
  362. {$ENDIF}
  363. begin
  364. {$IFDEF UNICODE}
  365. len := length(pvValue) shl 1;
  366. SetLength(lvBytes, len);
  367. Move(PChar(pvValue)^, lvBytes[0], len);
  368. Result := TEncoding.Convert(TEncoding.Unicode, TEncoding.UTF8, lvBytes);
  369. {$ELSE}
  370. result:= UTF8Encode(pvValue);
  371. {$ENDIF}
  372. end;
  373. // copy from qmsgPack
  374. procedure writeString(pvValue: string; pvStream: TStream);
  375. var
  376. lvRawData:{$IFDEF UNICODE}TBytes{$ELSE}AnsiString{$ENDIF};
  377. l:Integer;
  378. lvValue:TMsgPackValue;
  379. begin
  380. lvRawData := Utf8EncodeEx(pvValue);
  381. l:=Length(lvRawData);
  382. //
  383. //fixstr stores a byte array whose length is upto 31 bytes:
  384. //+--------+========+
  385. //|101XXXXX| data |
  386. //+--------+========+
  387. //
  388. //str 8 stores a byte array whose length is upto (2^8)-1 bytes:
  389. //+--------+--------+========+
  390. //| 0xd9 |YYYYYYYY| data |
  391. //+--------+--------+========+
  392. //
  393. //str 16 stores a byte array whose length is upto (2^16)-1 bytes:
  394. //+--------+--------+--------+========+
  395. //| 0xda |ZZZZZZZZ|ZZZZZZZZ| data |
  396. //+--------+--------+--------+========+
  397. //
  398. //str 32 stores a byte array whose length is upto (2^32)-1 bytes:
  399. //+--------+--------+--------+--------+--------+========+
  400. //| 0xdb |AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA| data |
  401. //+--------+--------+--------+--------+--------+========+
  402. //
  403. //where
  404. //* XXXXX is a 5-bit unsigned integer which represents N
  405. //* YYYYYYYY is a 8-bit unsigned integer which represents N
  406. //* ZZZZZZZZ_ZZZZZZZZ is a 16-bit big-endian unsigned integer which represents N
  407. //* AAAAAAAA_AAAAAAAA_AAAAAAAA_AAAAAAAA is a 32-bit big-endian unsigned integer which represents N
  408. //* N is the length of data
  409. if L<=31 then
  410. begin
  411. lvValue.ValueType:=$A0+Byte(L);
  412. pvStream.WriteBuffer(lvValue.ValueType,1);
  413. end
  414. else if L<=255 then
  415. begin
  416. lvValue.ValueType:=$d9;
  417. lvValue.U8Val:=Byte(L);
  418. pvStream.WriteBuffer(lvValue,2);
  419. end
  420. else if L<=65535 then
  421. begin
  422. lvValue.ValueType:=$da;
  423. lvValue.U16Val:=((L shr 8) and $FF) or ((L shl 8) and $FF00);
  424. pvStream.Write(lvValue,3);
  425. end else
  426. begin
  427. lvValue.ValueType:=$db;
  428. lvValue.BArray[0]:=(L shr 24) and $FF;
  429. lvValue.BArray[1]:=(L shr 16) and $FF;
  430. lvValue.BArray[2]:=(L shr 8) and $FF;
  431. lvValue.BArray[3]:=L and $FF;
  432. pvStream.WriteBuffer(lvValue,5);
  433. end;
  434. pvStream.Write(PByte(lvRawData)^, l);
  435. end;
  436. procedure WriteBinary(p: PByte; l: Integer; pvStream: TStream);
  437. var
  438. lvValue:TMsgPackValue;
  439. begin
  440. if l <= 255 then
  441. begin
  442. lvValue.ValueType := $C4;
  443. lvValue.U8Val := Byte(l);
  444. pvStream.WriteBuffer(lvValue, 2);
  445. end
  446. else if l <= 65535 then
  447. begin
  448. lvValue.ValueType := $C5;
  449. lvValue.BArray[0] := (l shr 8) and $FF;
  450. lvValue.BArray[1] := l and $FF;
  451. pvStream.WriteBuffer(lvValue, 3);
  452. end
  453. else
  454. begin
  455. lvValue.ValueType := $C6;
  456. lvValue.BArray[0] := (l shr 24) and $FF;
  457. lvValue.BArray[1] := (l shr 16) and $FF;
  458. lvValue.BArray[2] := (l shr 8) and $FF;
  459. lvValue.BArray[3] := l and $FF;
  460. pvStream.WriteBuffer(lvValue, 5);
  461. end;
  462. pvStream.WriteBuffer(p^, l);
  463. end;
  464. // copy from qmsgPack
  465. procedure WriteInt(const iVal: Int64; AStream: TStream);
  466. var
  467. lvValue:TMsgPackValue;
  468. begin
  469. if iVal>=0 then
  470. begin
  471. if iVal<=127 then
  472. begin
  473. lvValue.U8Val:=Byte(iVal);
  474. AStream.WriteBuffer(lvValue.U8Val,1);
  475. end
  476. else if iVal<=255 then//UInt8
  477. begin
  478. lvValue.ValueType:=$cc;
  479. lvValue.U8Val:=Byte(iVal);
  480. AStream.WriteBuffer(lvValue,2);
  481. end
  482. else if iVal<=65535 then
  483. begin
  484. lvValue.ValueType:=$cd;
  485. lvValue.BArray[0]:=(iVal shr 8);
  486. lvValue.BArray[1]:=(iVal and $FF);
  487. AStream.WriteBuffer(lvValue,3);
  488. end
  489. else if iVal<=Cardinal($FFFFFFFF) then
  490. begin
  491. lvValue.ValueType:=$ce;
  492. lvValue.BArray[0]:=(iVal shr 24) and $FF;
  493. lvValue.BArray[1]:=(iVal shr 16) and $FF;
  494. lvValue.BArray[2]:=(iVal shr 8) and $FF;
  495. lvValue.BArray[3]:=iVal and $FF;
  496. AStream.WriteBuffer(lvValue,5);
  497. end
  498. else
  499. begin
  500. lvValue.ValueType:=$cf;
  501. lvValue.BArray[0]:=(iVal shr 56) and $FF;
  502. lvValue.BArray[1]:=(iVal shr 48) and $FF;
  503. lvValue.BArray[2]:=(iVal shr 40) and $FF;
  504. lvValue.BArray[3]:=(iVal shr 32) and $FF;
  505. lvValue.BArray[4]:=(iVal shr 24) and $FF;
  506. lvValue.BArray[5]:=(iVal shr 16) and $FF;
  507. lvValue.BArray[6]:=(iVal shr 8) and $FF;
  508. lvValue.BArray[7]:=iVal and $FF;
  509. AStream.WriteBuffer(lvValue,9);
  510. end;
  511. end
  512. else//<0
  513. begin
  514. if iVal<=Low(Integer) then //-2147483648 // 64 bit
  515. begin
  516. lvValue.ValueType:=$d3;
  517. lvValue.BArray[0]:=(iVal shr 56) and $FF;
  518. lvValue.BArray[1]:=(iVal shr 48) and $FF;
  519. lvValue.BArray[2]:=(iVal shr 40) and $FF;
  520. lvValue.BArray[3]:=(iVal shr 32) and $FF;
  521. lvValue.BArray[4]:=(iVal shr 24) and $FF;
  522. lvValue.BArray[5]:=(iVal shr 16) and $FF;
  523. lvValue.BArray[6]:=(iVal shr 8) and $FF;
  524. lvValue.BArray[7]:=iVal and $FF;
  525. AStream.WriteBuffer(lvValue,9);
  526. end
  527. else if iVal<=Low(SmallInt) then // -32768 // 32 bit
  528. begin
  529. lvValue.ValueType:=$d2;
  530. lvValue.BArray[0]:=(iVal shr 24) and $FF;
  531. lvValue.BArray[1]:=(iVal shr 16) and $FF;
  532. lvValue.BArray[2]:=(iVal shr 8) and $FF;
  533. lvValue.BArray[3]:=iVal and $FF;
  534. AStream.WriteBuffer(lvValue,5);
  535. end
  536. else if iVal<=-128 then
  537. begin
  538. lvValue.ValueType:=$d1;
  539. lvValue.BArray[0]:=(iVal shr 8);
  540. lvValue.BArray[1]:=(iVal and $FF);
  541. AStream.WriteBuffer(lvValue,3);
  542. end
  543. else if iVal<-32 then
  544. begin
  545. lvValue.ValueType:=$d0;
  546. lvValue.I8Val:=iVal;
  547. AStream.WriteBuffer(lvValue,2);
  548. end
  549. else
  550. begin
  551. lvValue.I8Val:=iVal;
  552. AStream.Write(lvValue.I8Val,1);
  553. end;
  554. end;//End <0
  555. end;
  556. procedure WriteFloat(pvVal: Double; AStream: TStream);
  557. var
  558. lvValue:TMsgPackValue;
  559. begin
  560. lvValue.F64Val := swap(pvVal);
  561. lvValue.ValueType := $CB;
  562. AStream.WriteBuffer(lvValue, 9);
  563. end;
  564. procedure WriteSingle(pvVal: Single; AStream: TStream);
  565. var
  566. lvValue:TMsgPackValue;
  567. begin
  568. lvValue.F64Val := swap(pvVal);
  569. lvValue.ValueType := $CB;
  570. AStream.WriteBuffer(lvValue, 5);
  571. end;
  572. procedure WriteNull(pvStream:TStream);
  573. var
  574. lvByte:Byte;
  575. begin
  576. lvByte := $C0;
  577. pvStream.Write(lvByte, 1);
  578. end;
  579. procedure WriteBoolean(pvValue:Boolean; pvStream:TStream);
  580. var
  581. lvByte:Byte;
  582. begin
  583. if pvValue then lvByte := $C3 else lvByte := $C2;
  584. pvStream.Write(lvByte, 1);
  585. end;
  586. /// <summary>
  587. /// copy from qmsgpack
  588. /// </summary>
  589. procedure writeArray(obj:TSimpleMsgPack; pvStream:TStream);
  590. var
  591. c, i:Integer;
  592. lvValue:TMsgPackValue;
  593. lvNode:TSimpleMsgPack;
  594. begin
  595. C:=obj.Count;
  596. if C <= 15 then
  597. begin
  598. lvValue.ValueType := $90 + C;
  599. pvStream.WriteBuffer(lvValue.ValueType, 1);
  600. end
  601. else if C <= 65535 then
  602. begin
  603. lvValue.ValueType := $DC;
  604. lvValue.BArray[0] := (C shr 8) and $FF;
  605. lvValue.BArray[1] := C and $FF;
  606. pvStream.WriteBuffer(lvValue, 3);
  607. end
  608. else
  609. begin
  610. lvValue.ValueType := $DD;
  611. lvValue.BArray[0] := (C shr 24) and $FF;
  612. lvValue.BArray[1] := (C shr 16) and $FF;
  613. lvValue.BArray[2] := (C shr 8) and $FF;
  614. lvValue.BArray[3] := C and $FF;
  615. pvStream.WriteBuffer(lvValue, 5);
  616. end;
  617. for I := 0 to C-1 do
  618. begin
  619. lvNode:=TSimpleMsgPack(obj.FChildren[I]);
  620. lvNode.InnerEncodeToStream(pvStream);
  621. end;
  622. end;
  623. procedure writeMap(obj:TSimpleMsgPack; pvStream:TStream);
  624. var
  625. c, i:Integer;
  626. lvValue:TMsgPackValue;
  627. lvNode:TSimpleMsgPack;
  628. begin
  629. C:=obj.Count;
  630. if C<=15 then
  631. begin
  632. lvValue.ValueType:=$80+C;
  633. pvStream.WriteBuffer(lvValue.ValueType,1);
  634. end
  635. else if C<=65535 then
  636. begin
  637. lvValue.ValueType:=$de;
  638. lvValue.BArray[0]:=(C shr 8) and $FF;
  639. lvValue.BArray[1]:=C and $FF;
  640. pvStream.WriteBuffer(lvValue,3);
  641. end
  642. else
  643. begin
  644. lvValue.ValueType:=$df;
  645. lvValue.BArray[0]:=(C shr 24) and $FF;
  646. lvValue.BArray[1]:=(C shr 16) and $FF;
  647. lvValue.BArray[2]:=(C shr 8) and $FF;
  648. lvValue.BArray[3]:=C and $FF;
  649. pvStream.WriteBuffer(lvValue,5);
  650. end;
  651. for I := 0 to C-1 do
  652. begin
  653. lvNode:=TSimpleMsgPack(obj.FChildren[I]);
  654. writeString(lvNode.FName, pvStream);
  655. lvNode.InnerEncodeToStream(pvStream);
  656. end;
  657. end;
  658. function EncodeDateTime(pvVal: TDateTime): string;
  659. var
  660. AValue: TDateTime;
  661. begin
  662. AValue := pvVal;
  663. if AValue - Trunc(AValue) = 0 then // Date
  664. Result := FormatDateTime('yyyy-MM-dd', AValue)
  665. else
  666. begin
  667. if Trunc(AValue) = 0 then
  668. Result := FormatDateTime('hh:nn:ss.zzz', AValue)
  669. else
  670. Result := FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', AValue);
  671. end;
  672. end;
  673. constructor TSimpleMsgPack.Create;
  674. begin
  675. inherited Create;
  676. {$IFDEF UNICODE}
  677. FChildren := TObjectList<TSimpleMsgPack>.Create(true);
  678. {$ELSE}
  679. FChildren := TObjectList.Create(true);
  680. {$ENDIF}
  681. end;
  682. procedure TSimpleMsgPack.DecodeFromBytes(pvBytes: TBytes);
  683. var
  684. lvStream:TStream;
  685. begin
  686. lvStream := TMemoryStream.Create;
  687. try
  688. lvStream.Write(pvBytes[0], Length(pvBytes));
  689. lvStream.Position := 0;
  690. DecodeFromStream(lvStream);
  691. finally
  692. lvStream.Free;
  693. end;
  694. end;
  695. procedure TSimpleMsgPack.DecodeFromStream(pvStream: TStream);
  696. begin
  697. InnerParseFromStream(pvStream);
  698. end;
  699. function TSimpleMsgPack.DeleteObject(pvPath: String): Boolean;
  700. var
  701. lvParent, lvObj:TSimpleMsgPack;
  702. j:Integer;
  703. begin
  704. lvObj := InnerFindPathObject(pvPath, lvParent, j);
  705. Result := lvObj <> nil;
  706. if Result then
  707. begin
  708. lvParent.FChildren.Delete(j);
  709. end;
  710. end;
  711. destructor TSimpleMsgPack.Destroy;
  712. begin
  713. FChildren.Clear;
  714. FChildren.Free;
  715. FChildren := nil;
  716. inherited Destroy;
  717. end;
  718. function TSimpleMsgPack.Add(pvNameKey, pvValue: string): TSimpleMsgPack;
  719. begin
  720. Result := InnerAdd;
  721. Result.setName(pvNameKey);
  722. Result.AsString := pvValue;
  723. end;
  724. function TSimpleMsgPack.Add(pvNameKey: string; pvValue: Int64): TSimpleMsgPack;
  725. begin
  726. Result := InnerAdd;
  727. Result.setName(pvNameKey);
  728. Result.AsInteger := pvValue;
  729. end;
  730. function TSimpleMsgPack.Add: TSimpleMsgPack;
  731. begin
  732. Result := InnerAdd;
  733. end;
  734. function TSimpleMsgPack.Add(pvNameKey: string; pvValue: TBytes): TSimpleMsgPack;
  735. begin
  736. Result := InnerAdd;
  737. Result.setName(pvNameKey);
  738. Result.FDataType := mptBinary;
  739. Result.FValue := pvValue;
  740. end;
  741. function TSimpleMsgPack.Add(pvNameKey:String): TSimpleMsgPack;
  742. begin
  743. Result := InnerAdd;
  744. Result.setName(pvNameKey);
  745. end;
  746. procedure TSimpleMsgPack.checkObjectDataType(ANewType: TMsgPackType = mptMap);
  747. begin
  748. if not (FDataType in [mptMap]) then
  749. begin
  750. FDataType := ANewType;
  751. end;
  752. end;
  753. procedure TSimpleMsgPack.clear;
  754. begin
  755. FChildren.Clear;
  756. FDataType := mptNull;
  757. SetLength(FValue, 0);
  758. end;
  759. function TSimpleMsgPack.EncodeToBytes: TBytes;
  760. var
  761. lvStream:TStream;
  762. begin
  763. lvStream := TMemoryStream.Create;
  764. try
  765. EncodeToStream(lvStream);
  766. lvStream.Position := 0;
  767. SetLength(Result, lvStream.size);
  768. lvStream.Read(Result[0], lvStream.Size);
  769. finally
  770. lvStream.Free;
  771. end;
  772. end;
  773. procedure TSimpleMsgPack.EncodeToStream(pvStream: TStream);
  774. begin
  775. InnerEncodeToStream(pvStream);
  776. end;
  777. function TSimpleMsgPack.findObj(pvName:string): TSimpleMsgPack;
  778. var
  779. i:Integer;
  780. begin
  781. i := indexOfCaseSensitive(pvName);
  782. if i <> -1 then
  783. begin
  784. Result := TSimpleMsgPack(FChildren[i]);
  785. end else
  786. begin
  787. Result := nil;
  788. end;
  789. end;
  790. function TSimpleMsgPack.ForcePathObject(pvPath:string): TSimpleMsgPack;
  791. var
  792. lvName:string;
  793. s:string;
  794. sPtr:PChar;
  795. lvTempObj, lvParent:TSimpleMsgPack;
  796. j:Integer;
  797. begin
  798. s := pvPath;
  799. lvParent := Self;
  800. sPtr := PChar(s);
  801. while sPtr^ <> #0 do
  802. begin
  803. lvName := getFirst(sPtr, ['.', '/','\']);
  804. if lvName = '' then
  805. begin
  806. Break;
  807. end else
  808. begin
  809. if sPtr^ = #0 then
  810. begin // end
  811. j := lvParent.indexOf(lvName);
  812. if j <> -1 then
  813. begin
  814. Result := TSimpleMsgPack(lvParent.FChildren[j]);
  815. end else
  816. begin
  817. Result := lvParent.Add(lvName);
  818. end;
  819. end else
  820. begin
  821. // find childrean
  822. lvTempObj := lvParent.findObj(lvName);
  823. if lvTempObj = nil then
  824. begin
  825. lvParent := lvParent.Add(lvName);
  826. end else
  827. begin
  828. lvParent := lvTempObj;
  829. end;
  830. end;
  831. end;
  832. if sPtr^ = #0 then Break;
  833. Inc(sPtr);
  834. end;
  835. end;
  836. function TSimpleMsgPack.GetAsBoolean: Boolean;
  837. begin
  838. if FDataType = mptBoolean then
  839. Result := PBoolean(FValue)^
  840. else if FDataType = mptString then
  841. Result := StrToBoolDef(AsString, False)
  842. else if FDataType = mptInteger then
  843. Result := (AsInteger <> 0)
  844. else if FDataType in [mptNull, mptUnknown] then
  845. Result := False
  846. else
  847. Result := False;
  848. end;
  849. function TSimpleMsgPack.GetAsBytes: TBytes;
  850. begin
  851. Result := FValue;
  852. end;
  853. function TSimpleMsgPack.GetAsDateTime: TDateTime;
  854. begin
  855. if FDataType in [mptDateTime, mptFloat] then
  856. Result := PDouble(FValue)^
  857. else if FDataType = mptSingle then
  858. Result := PSingle(FValue)^
  859. else if FDataType = mptString then
  860. begin
  861. Result := StrToDateTimeDef(GetAsString, 0);
  862. end
  863. else if FDataType in [mptInteger] then
  864. Result := AsInteger
  865. else
  866. Result := 0;
  867. end;
  868. function TSimpleMsgPack.GetAsFloat: Double;
  869. begin
  870. if FDataType in [mptFloat, mptDateTime] then
  871. Result := PDouble(FValue)^
  872. else if FDataType = mptSingle then
  873. Result := PSingle(FValue)^
  874. else if FDataType = mptBoolean then
  875. Result := Integer(AsBoolean)
  876. else if FDataType = mptString then
  877. Result := StrToFloatDef(AsString, 0)
  878. else if FDataType = mptInteger then
  879. Result := AsInteger
  880. else
  881. Result := 0;
  882. end;
  883. function TSimpleMsgPack.getAsInteger: Int64;
  884. begin
  885. case FDataType of
  886. mptInteger: Result:=PInt64(FValue)^;
  887. else
  888. Result := 0;
  889. end;
  890. end;
  891. function TSimpleMsgPack.GetAsSingle: Single;
  892. begin
  893. if FDataType in [mptFloat, mptDateTime] then
  894. Result := PDouble(FValue)^
  895. else if FDataType = mptSingle then
  896. Result := PSingle(FValue)^
  897. else if FDataType = mptBoolean then
  898. Result := Integer(AsBoolean)
  899. else if FDataType = mptString then
  900. Result := StrToFloatDef(AsString, 0)
  901. else if FDataType = mptInteger then
  902. Result := AsInteger
  903. else
  904. Result := 0;
  905. end;
  906. function TSimpleMsgPack.getAsString: String;
  907. var
  908. l:Cardinal;
  909. begin
  910. Result := '';
  911. if FDataType = mptString then
  912. begin
  913. l := Length(FValue);
  914. if l = 0 then
  915. begin
  916. Result := '';
  917. end else if SizeOf(Char) = 2 then
  918. begin
  919. SetLength(Result, l shr 1);
  920. Move(FValue[0],PChar(Result)^, l);
  921. end else
  922. begin
  923. SetLength(Result, l);
  924. Move(FValue[0],PChar(Result)^, l);
  925. end;
  926. end else
  927. begin
  928. case FDataType of
  929. mptUnknown, mptNull:
  930. Result := '';
  931. mptInteger:
  932. Result := IntToStr(AsInteger);
  933. mptBoolean:
  934. Result := BoolToStr(AsBoolean, True);
  935. mptFloat:
  936. Result := FloatToStrF(AsFloat, ffGeneral, 15, 0);
  937. mptSingle:
  938. Result := FloatToStrF(AsSingle, ffGeneral, 7, 0);
  939. mptBinary:
  940. Result := BinToHex(@FValue[0], Length(FValue), False);
  941. mptDateTime:
  942. Result := EncodeDateTime(AsDateTime);
  943. // mptArray:
  944. // Result := EncodeArray;
  945. // mptMap:
  946. // Result := EncodeMap;
  947. // mptExtended:
  948. // Result := EncodeExtended;
  949. else
  950. Result := '';
  951. end;
  952. end;
  953. //showMessage(Result);
  954. end;
  955. /// <summary>
  956. /// copy from qdac3
  957. /// </summary>
  958. function TSimpleMsgPack.GetAsVariant: Variant;
  959. var
  960. I: Integer;
  961. procedure BytesAsVariant;
  962. var
  963. L: Integer;
  964. p:PByte;
  965. begin
  966. L := Length(FValue);
  967. Result := VarArrayCreate([0, L - 1], varByte);
  968. p:=VarArrayLock(Result);
  969. Move(FValue[0],p^,L);
  970. VarArrayUnlock(Result);
  971. end;
  972. begin
  973. case FDataType of
  974. mptString:
  975. Result := AsString;
  976. mptInteger:
  977. Result := AsInteger;
  978. mptFloat:
  979. Result := AsFloat;
  980. mptSingle:
  981. Result := AsSingle;
  982. mptDateTime:
  983. Result := AsDateTime;
  984. mptBoolean:
  985. Result := AsBoolean;
  986. mptArray, mptMap:
  987. begin
  988. Result := VarArrayCreate([0, Count - 1], varVariant);
  989. for I := 0 to Count - 1 do
  990. Result[I] := TSimpleMsgPack(FChildren[I]).AsVariant;
  991. end;
  992. mptBinary:
  993. BytesAsVariant;
  994. else
  995. raise Exception.Create(SVariantConvertNotSupport);
  996. end;
  997. end;
  998. function TSimpleMsgPack.GetB(pvPath: String): Boolean;
  999. var
  1000. lvObj:TSimpleMsgPack;
  1001. begin
  1002. lvObj := GetO(pvPath);
  1003. if lvObj = nil then
  1004. begin
  1005. Result := False;
  1006. end else
  1007. begin
  1008. Result := lvObj.AsBoolean;
  1009. end;
  1010. end;
  1011. function TSimpleMsgPack.GetCount: Integer;
  1012. begin
  1013. Result := FChildren.Count;
  1014. end;
  1015. function TSimpleMsgPack.GetD(pvPath: String): Double;
  1016. var
  1017. lvObj:TSimpleMsgPack;
  1018. begin
  1019. lvObj := GetO(pvPath);
  1020. if lvObj = nil then
  1021. begin
  1022. Result := 0;
  1023. end else
  1024. begin
  1025. Result := lvObj.AsFloat;
  1026. end;
  1027. end;
  1028. function TSimpleMsgPack.GetI(pvPath: String): Int64;
  1029. var
  1030. lvObj:TSimpleMsgPack;
  1031. begin
  1032. lvObj := GetO(pvPath);
  1033. if lvObj = nil then
  1034. begin
  1035. Result := 0;
  1036. end else
  1037. begin
  1038. Result := lvObj.AsInteger;
  1039. end;
  1040. end;
  1041. function TSimpleMsgPack.GetItems(AIndex: Integer): TSimpleMsgPack;
  1042. begin
  1043. Result := TSimpleMsgPack(FChildren[AIndex]);
  1044. end;
  1045. function TSimpleMsgPack.GetO(pvPath: String): TSimpleMsgPack;
  1046. var
  1047. lvParent:TSimpleMsgPack;
  1048. j:Integer;
  1049. begin
  1050. Result := InnerFindPathObject(pvPath, lvParent, j);
  1051. end;
  1052. function TSimpleMsgPack.GetS(pvPath: String): string;
  1053. var
  1054. lvObj:TSimpleMsgPack;
  1055. begin
  1056. lvObj := GetO(pvPath);
  1057. if lvObj = nil then
  1058. begin
  1059. Result := '';
  1060. end else
  1061. begin
  1062. Result := lvObj.AsString;
  1063. end;
  1064. end;
  1065. function TSimpleMsgPack.indexOf(pvName:string): Integer;
  1066. begin
  1067. Result := indexOfIgnoreSensitive(LowerCase(pvName));
  1068. end;
  1069. function TSimpleMsgPack.indexOfCaseSensitive(pvName:string): Integer;
  1070. var
  1071. i, l: Integer;
  1072. lvObj:TSimpleMsgPack;
  1073. begin
  1074. Result := -1;
  1075. l := Length(pvName);
  1076. if l = 0 then exit;
  1077. for i := 0 to FChildren.Count-1 do
  1078. begin
  1079. lvObj := TSimpleMsgPack(FChildren[i]);
  1080. if Length(lvObj.FName) = l then
  1081. begin
  1082. if lvObj.FName = pvName then
  1083. begin
  1084. Result := i;
  1085. break;
  1086. end;
  1087. end;
  1088. end;
  1089. end;
  1090. function TSimpleMsgPack.indexOfIgnoreSensitive(pvLowerCaseName: string):
  1091. Integer;
  1092. var
  1093. i, l: Integer;
  1094. lvObj:TSimpleMsgPack;
  1095. begin
  1096. Result := -1;
  1097. l := Length(pvLowerCaseName);
  1098. if l = 0 then exit;
  1099. for i := 0 to FChildren.Count-1 do
  1100. begin
  1101. lvObj := TSimpleMsgPack(FChildren[i]);
  1102. if Length(lvObj.FLowerName) = l then
  1103. begin
  1104. if lvObj.FLowerName = pvLowerCaseName then
  1105. begin
  1106. Result := i;
  1107. break;
  1108. end;
  1109. end;
  1110. end;
  1111. end;
  1112. function TSimpleMsgPack.InnerAdd: TSimpleMsgPack;
  1113. begin
  1114. Result := TSimpleMsgPack.Create;
  1115. Result.FDataType := mptUnknown;
  1116. InnerAddToChildren(Result);
  1117. end;
  1118. procedure TSimpleMsgPack.InnerAddToChildren(obj: TSimpleMsgPack);
  1119. begin
  1120. checkObjectDataType(mptMap);
  1121. obj.FParent := self;
  1122. FChildren.Add(obj);
  1123. end;
  1124. procedure TSimpleMsgPack.InnerEncodeToStream(pvStream:TStream);
  1125. begin
  1126. case FDataType of
  1127. mptUnknown, mptNull: WriteNull(pvStream);
  1128. mptMap: writeMap(Self, pvStream);
  1129. mptArray: writeArray(Self, pvStream);
  1130. mptString: writeString(Self.getAsString, pvStream);
  1131. mptInteger: WriteInt(self.getAsInteger, pvStream);
  1132. mptBoolean: WriteBoolean(self.GetAsBoolean, pvStream);
  1133. mptFloat: WriteFloat(GetAsFloat, pvStream);
  1134. mptSingle: WriteSingle(GetAsSingle, pvStream);
  1135. mptBinary: WriteBinary(PByte(@FValue[0]), Length(FValue), pvStream);
  1136. end;
  1137. end;
  1138. function TSimpleMsgPack.InnerFindPathObject(pvPath: string; var vParent:
  1139. TSimpleMsgPack; var vIndex: Integer): TSimpleMsgPack;
  1140. var
  1141. lvName:string;
  1142. s:string;
  1143. sPtr:PChar;
  1144. lvTempObj, lvParent:TSimpleMsgPack;
  1145. j:Integer;
  1146. begin
  1147. s := pvPath;
  1148. Result := nil;
  1149. lvParent := Self;
  1150. sPtr := PChar(s);
  1151. while sPtr^ <> #0 do
  1152. begin
  1153. lvName := getFirst(sPtr, ['.', '/','\']);
  1154. if lvName = '' then
  1155. begin
  1156. Break;
  1157. end else
  1158. begin
  1159. if sPtr^ = #0 then
  1160. begin // end
  1161. j := lvParent.indexOf(lvName);
  1162. if j <> -1 then
  1163. begin
  1164. Result := TSimpleMsgPack(lvParent.FChildren[j]);
  1165. vIndex := j;
  1166. vParent := lvParent;
  1167. end else
  1168. begin
  1169. Break;
  1170. end;
  1171. end else
  1172. begin
  1173. // find childrean
  1174. lvTempObj := lvParent.findObj(lvName);
  1175. if lvTempObj = nil then
  1176. begin
  1177. Break;
  1178. end else
  1179. begin
  1180. lvParent := lvTempObj;
  1181. end;
  1182. end;
  1183. end;
  1184. if sPtr^ = #0 then Break;
  1185. Inc(sPtr);
  1186. end;
  1187. end;
  1188. procedure TSimpleMsgPack.InnerParseFromStream(pvStream: TStream);
  1189. var
  1190. lvByte:Byte;
  1191. lvBData: array[0..15] of Byte;
  1192. lvAnsiStr:{$IFDEF UNICODE}TBytes{$ELSE}AnsiString{$ENDIF};
  1193. lvBytes:TBytes;
  1194. l, i:Cardinal;
  1195. i64:Int64;
  1196. lvObj:TSimpleMsgPack;
  1197. begin
  1198. pvStream.Read(lvByte, 1);
  1199. if lvByte <=$7F then //positive fixint 0xxxxxxx 0x00 - 0x7f
  1200. begin
  1201. setAsInteger(lvByte);
  1202. end else if lvByte <= $8f then //fixmap 1000xxxx 0x80 - 0x8f
  1203. begin
  1204. FDataType := mptMap;
  1205. SetLength(FValue, 0);
  1206. FChildren.Clear;
  1207. l := lvByte - $80;
  1208. if l > 0 then // check is empty ele
  1209. begin
  1210. for I := 0 to l - 1 do
  1211. begin
  1212. lvObj := InnerAdd;
  1213. // map key
  1214. lvObj.InnerParseFromStream(pvStream);
  1215. lvObj.setName(lvObj.getAsString);
  1216. // value
  1217. lvObj.InnerParseFromStream(pvStream);
  1218. end;
  1219. end;
  1220. end else if lvByte <= $9f then //fixarray 1001xxxx 0x90 - 0x9f
  1221. begin
  1222. FDataType := mptArray;
  1223. SetLength(FValue, 0);
  1224. FChildren.Clear;
  1225. l := lvByte - $90;
  1226. if l > 0 then // check is empty ele
  1227. begin
  1228. for I := 0 to l - 1 do
  1229. begin
  1230. lvObj := InnerAdd;
  1231. // value
  1232. lvObj.InnerParseFromStream(pvStream);
  1233. end;
  1234. end;
  1235. end else if lvByte <= $bf then //fixstr 101xxxxx 0xa0 - 0xbf
  1236. begin
  1237. l := lvByte - $A0; // str len
  1238. if l > 0 then
  1239. begin
  1240. SetLength(lvAnsiStr, l);
  1241. pvStream.Read(PByte(lvAnsiStr)^, l);
  1242. setAsString(UTF8DecodeEx(lvAnsiStr, l));
  1243. // SetLength(lvBytes, l + 1);
  1244. // lvBytes[l] := 0;
  1245. // pvStream.Read(lvBytes[0], l);
  1246. // setAsString(UTF8Decode(PAnsiChar(@lvBytes[0])));
  1247. end else
  1248. begin
  1249. setAsString('');
  1250. end;
  1251. end else
  1252. begin
  1253. case lvByte of
  1254. $C0: // null
  1255. begin
  1256. FDataType := mptNull;
  1257. SetLength(FValue, 0);
  1258. end;
  1259. $C2: // False
  1260. begin
  1261. SetAsBoolean(False);
  1262. end;
  1263. $C3: // True
  1264. begin
  1265. SetAsBoolean(True);
  1266. end;
  1267. $C4: // 短二进制,最长255字节
  1268. begin
  1269. FDataType := mptBinary;
  1270. l := 0; // fill zero
  1271. pvStream.Read(l, 1);
  1272. SetLength(FValue, l);
  1273. pvStream.Read(FValue[0], l);
  1274. end;
  1275. $C5: // 二进制,16位,最长65535B
  1276. begin
  1277. FDataType := mptBinary;
  1278. l := 0; // fill zero
  1279. pvStream.Read(l, 2);
  1280. l := swap16(l);
  1281. SetLength(FValue, l);
  1282. pvStream.Read(FValue[0], l);
  1283. end;
  1284. $C6: // 二进制,32位,最长2^32-1
  1285. begin
  1286. FDataType := mptBinary;
  1287. l := 0; // fill zero
  1288. pvStream.Read(l, 4);
  1289. l := swap32(l);
  1290. SetLength(FValue, l);
  1291. pvStream.Read(FValue[0], l);
  1292. end;
  1293. $ca: // float 32
  1294. begin
  1295. pvStream.Read(lvBData[0], 4);
  1296. AsSingle := swap(PSingle(@lvBData[0])^);
  1297. end;
  1298. $cb: // Float 64
  1299. begin
  1300. pvStream.Read(lvBData[0], 8);
  1301. AsSingle := swap(PDouble(@lvBData[0])^);
  1302. end;
  1303. $dc: // array 16
  1304. begin
  1305. // +--------+--------+--------+~~~~~~~~~~~~~~~~~+
  1306. // | 0xdc |YYYYYYYY|YYYYYYYY| N objects |
  1307. // +--------+--------+--------+~~~~~~~~~~~~~~~~~+
  1308. FDataType := mptArray;
  1309. SetLength(FValue, 0);
  1310. FChildren.Clear;
  1311. l := 0; // fill zero
  1312. pvStream.Read(l, 2);
  1313. l := swap16(l);
  1314. if l > 0 then // check is empty ele
  1315. begin
  1316. for I := 0 to l - 1 do
  1317. begin
  1318. lvObj := InnerAdd;
  1319. // value
  1320. lvObj.InnerParseFromStream(pvStream);
  1321. end;
  1322. end;
  1323. end;
  1324. $dd: // Array 32
  1325. begin
  1326. // +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
  1327. // | 0xdd |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ| N objects |
  1328. // +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
  1329. FDataType := mptArray;
  1330. SetLength(FValue, 0);
  1331. FChildren.Clear;
  1332. l := 0; // fill zero
  1333. pvStream.Read(l, 4);
  1334. l := swap32(l);
  1335. if l > 0 then // check is empty ele
  1336. begin
  1337. for I := 0 to l - 1 do
  1338. begin
  1339. lvObj := InnerAdd;
  1340. // value
  1341. lvObj.InnerParseFromStream(pvStream);
  1342. end;
  1343. end;
  1344. end;
  1345. $d9: //str 8 , 255
  1346. begin
  1347. // str 8 stores a byte array whose length is upto (2^8)-1 bytes:
  1348. // +--------+--------+========+
  1349. // | 0xd9 |YYYYYYYY| data |
  1350. // +--------+--------+========+
  1351. l := 0;
  1352. pvStream.Read(l, 1);
  1353. if l > 0 then // check is empty ele
  1354. begin
  1355. SetLength(lvAnsiStr, l);
  1356. pvStream.Read(PByte(lvAnsiStr)^, l);
  1357. setAsString(UTF8DecodeEx(lvAnsiStr, l));
  1358. end else
  1359. begin
  1360. setAsString('');
  1361. end;
  1362. // SetLength(lvBytes, l + 1);
  1363. // lvBytes[l] := 0;
  1364. // pvStream.Read(lvBytes[0], l);
  1365. // setAsString(UTF8Decode(PAnsiChar(@lvBytes[0])));
  1366. end;
  1367. $DE: // Object map 16
  1368. begin
  1369. // +--------+--------+--------+~~~~~~~~~~~~~~~~~+
  1370. // | 0xde |YYYYYYYY|YYYYYYYY| N*2 objects |
  1371. // +--------+--------+--------+~~~~~~~~~~~~~~~~~+
  1372. FDataType := mptMap;
  1373. SetLength(FValue, 0);
  1374. FChildren.Clear;
  1375. l := 0; // fill zero
  1376. pvStream.Read(l, 2);
  1377. l := swap16(l);
  1378. if l > 0 then // check is empty ele
  1379. begin
  1380. for I := 0 to l - 1 do
  1381. begin
  1382. lvObj := InnerAdd;
  1383. // map key
  1384. lvObj.InnerParseFromStream(pvStream);
  1385. lvObj.setName(lvObj.getAsString);
  1386. // value
  1387. lvObj.InnerParseFromStream(pvStream);
  1388. end;
  1389. end;
  1390. end;
  1391. $DF: //Object map 32
  1392. begin
  1393. // +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
  1394. // | 0xdf |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ| N*2 objects |
  1395. // +--------+--------+--------+--------+--------+~~~~~~~~~~~~~~~~~+
  1396. FDataType := mptMap;
  1397. SetLength(FValue, 0);
  1398. FChildren.Clear;
  1399. l := 0; // fill zero
  1400. pvStream.Read(l, 4);
  1401. l := swap32(l);
  1402. if l > 0 then // check is empty ele
  1403. begin
  1404. for I := 0 to l - 1 do
  1405. begin
  1406. lvObj := InnerAdd;
  1407. // map key
  1408. lvObj.InnerParseFromStream(pvStream);
  1409. lvObj.setName(lvObj.getAsString);
  1410. // value
  1411. lvObj.InnerParseFromStream(pvStream);
  1412. end;
  1413. end;
  1414. end;
  1415. $da: // str 16
  1416. begin
  1417. // str 16 stores a byte array whose length is upto (2^16)-1 bytes:
  1418. // +--------+--------+--------+========+
  1419. // | 0xda |ZZZZZZZZ|ZZZZZZZZ| data |
  1420. // +--------+--------+--------+========+
  1421. l := 0; // fill zero
  1422. pvStream.Read(l, 2);
  1423. l := swap16(l);
  1424. if l > 0 then // check is empty ele
  1425. begin
  1426. SetLength(lvAnsiStr, l);
  1427. pvStream.Read(PByte(lvAnsiStr)^, l);
  1428. setAsString(UTF8DecodeEx(lvAnsiStr, l));
  1429. end else
  1430. begin
  1431. setAsString('');
  1432. end;
  1433. // SetLength(lvBytes, l + 1);
  1434. // lvBytes[l] := 0;
  1435. // pvStream.Read(lvBytes[0], l);
  1436. // setAsString(UTF8Decode(PAnsiChar(@lvBytes[0])));
  1437. end;
  1438. $db: // str 16
  1439. begin
  1440. // str 32 stores a byte array whose length is upto (2^32)-1 bytes:
  1441. // +--------+--------+--------+--------+--------+========+
  1442. // | 0xdb |AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA| data |
  1443. // +--------+--------+--------+--------+--------+========+
  1444. l := 0; // fill zero
  1445. pvStream.Read(l, 4);
  1446. l := swap32(l);
  1447. if l > 0 then // check is empty ele
  1448. begin
  1449. SetLength(lvAnsiStr, l);
  1450. pvStream.Read(PByte(lvAnsiStr)^, l);
  1451. setAsString(UTF8DecodeEx(lvAnsiStr, l));
  1452. end else
  1453. begin
  1454. setAsString('');
  1455. end;
  1456. // SetLength(lvBytes, l + 1);
  1457. // lvBytes[l] := 0;
  1458. // pvStream.Read(lvBytes[0], l);
  1459. // setAsString(UTF8Decode(PAnsiChar(@lvBytes[0])));
  1460. end;
  1461. $cc, $d0: //uint 8, int 8
  1462. begin
  1463. // uint 8 stores a 8-bit unsigned integer
  1464. // +--------+--------+
  1465. // | 0xcc |ZZZZZZZZ|
  1466. // +--------+--------+
  1467. // int 8 stores a 8-bit signed integer
  1468. // +--------+--------+
  1469. // | 0xd0 |ZZZZZZZZ|
  1470. // +--------+--------+
  1471. l := 0;
  1472. pvStream.Read(l, 1);
  1473. setAsInteger(l);
  1474. end;
  1475. $cd, $d1:
  1476. begin
  1477. // uint 16 stores a 16-bit big-endian unsigned integer
  1478. // +--------+--------+--------+
  1479. // | 0xcd |ZZZZZZZZ|ZZZZZZZZ|
  1480. // +--------+--------+--------+
  1481. //
  1482. // int 16 stores a 16-bit big-endian signed integer
  1483. // +--------+--------+--------+
  1484. // | 0xd1 |ZZZZZZZZ|ZZZZZZZZ|
  1485. // +--------+--------+--------+
  1486. l := 0;
  1487. pvStream.Read(l, 2);
  1488. l := swap16(l);
  1489. setAsInteger(l);
  1490. end;
  1491. $ce, $d2:
  1492. begin
  1493. // uint 32 stores a 32-bit big-endian unsigned integer
  1494. // +--------+--------+--------+--------+--------+
  1495. // | 0xce |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ
  1496. // +--------+--------+--------+--------+--------+
  1497. // int 32 stores a 32-bit big-endian signed integer
  1498. // +--------+--------+--------+--------+--------+
  1499. // | 0xd2 |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
  1500. // +--------+--------+--------+--------+--------+
  1501. l := 0;
  1502. pvStream.Read(l, 4);
  1503. l := swap32(l);
  1504. setAsInteger(l);
  1505. end;
  1506. $cf, $d3:
  1507. begin
  1508. // uint 64 stores a 64-bit big-endian unsigned integer
  1509. // +--------+--------+--------+--------+--------+--------+--------+--------+--------+
  1510. // | 0xcf |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
  1511. // +--------+--------+--------+--------+--------+--------+--------+--------+--------+
  1512. // int 64 stores a 64-bit big-endian signed integer
  1513. // +--------+--------+--------+--------+--------+--------+--------+--------+--------+
  1514. // | 0xd3 |ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|ZZZZZZZZ|
  1515. // +--------+--------+--------+--------+--------+--------+--------+--------+--------+
  1516. i64 := 0;
  1517. pvStream.Read(i64, 8);
  1518. i64 := swap64(i64);
  1519. setAsInteger(i64);
  1520. end;
  1521. end;
  1522. end;
  1523. end;
  1524. procedure TSimpleMsgPack.LoadBinaryFromFile(pvFileName:String);
  1525. var
  1526. lvFileStream:TFileStream;
  1527. begin
  1528. if FileExists(pvFileName) then
  1529. begin
  1530. lvFileStream := TFileStream.Create(pvFileName, fmOpenRead);
  1531. try
  1532. LoadBinaryFromStream(lvFileStream);
  1533. finally
  1534. lvFileStream.Free;
  1535. end;
  1536. end;
  1537. end;
  1538. procedure TSimpleMsgPack.LoadBinaryFromStream(pvStream: TStream; pvLen:
  1539. cardinal = 0);
  1540. begin
  1541. FDataType := mptBinary;
  1542. if pvLen = 0 then
  1543. begin
  1544. pvStream.Position := 0;
  1545. SetLength(FValue, pvStream.Size);
  1546. pvStream.Read(FValue[0], pvStream.Size);
  1547. end else
  1548. begin
  1549. SetLength(FValue, pvLen);
  1550. pvStream.ReadBuffer(FValue[0], pvLen);
  1551. end;
  1552. end;
  1553. procedure TSimpleMsgPack.NotifyForDeleteChildren;
  1554. begin
  1555. //Result := ;
  1556. end;
  1557. procedure TSimpleMsgPack.SaveBinaryToFile(pvFileName: String);
  1558. var
  1559. lvFileStream:TFileStream;
  1560. begin
  1561. if FileExists(pvFileName) then
  1562. begin
  1563. if not DeleteFile(PChar(pvFileName)) then
  1564. RaiseLastOSError;
  1565. end;
  1566. lvFileStream := TFileStream.Create(pvFileName, fmCreate);
  1567. try
  1568. lvFileStream.WriteBuffer(FValue[0], Length(FValue));
  1569. finally
  1570. lvFileStream.Free;
  1571. end;
  1572. end;
  1573. procedure TSimpleMsgPack.SaveBinaryToStream(pvStream: TStream);
  1574. begin
  1575. pvStream.WriteBuffer(FValue[0], Length(FValue));
  1576. end;
  1577. procedure TSimpleMsgPack.SetAsBoolean(const Value: Boolean);
  1578. begin
  1579. FDataType := mptBoolean;
  1580. SetLength(FValue, 1);
  1581. PBoolean(@FValue[0])^ := Value;
  1582. end;
  1583. procedure TSimpleMsgPack.SetAsBytes(const Value: TBytes);
  1584. begin
  1585. FDataType := mptBinary;
  1586. FValue := Value;
  1587. end;
  1588. procedure TSimpleMsgPack.SetAsDateTime(const Value: TDateTime);
  1589. begin
  1590. FDataType := mptDateTime;
  1591. SetLength(FValue, SizeOf(TDateTime));
  1592. PDouble(@FValue[0])^ := Value;
  1593. end;
  1594. procedure TSimpleMsgPack.SetAsFloat(const Value: Double);
  1595. begin
  1596. FDataType := mptFloat;
  1597. SetLength(FValue, SizeOf(Double));
  1598. PDouble(@FValue[0])^ := Value;
  1599. end;
  1600. procedure TSimpleMsgPack.setAsInteger(pvValue: Int64);
  1601. begin
  1602. FDataType := mptInteger;
  1603. SetLength(FValue, SizeOf(Int64));
  1604. PInt64(@FValue[0])^ := pvValue;
  1605. end;
  1606. procedure TSimpleMsgPack.SetAsSingle(const Value: Single);
  1607. begin
  1608. FDataType := mptSingle;
  1609. PSingle(FValue)^ := Value;
  1610. end;
  1611. procedure TSimpleMsgPack.setAsString(pvValue: string);
  1612. begin
  1613. FDataType := mptString;
  1614. if SizeOf(Char) = 2 then
  1615. begin
  1616. SetLength(FValue, length(pvValue) shl 1);
  1617. Move(PChar(pvValue)^, FValue[0], Length(FValue));
  1618. end else
  1619. begin
  1620. SetLength(FValue, length(pvValue));
  1621. Move(PChar(pvValue)^, FValue[0], Length(FValue));
  1622. end;
  1623. end;
  1624. /// <summary>
  1625. /// copy from qdac3
  1626. /// </summary>
  1627. procedure TSimpleMsgPack.SetAsVariant(const Value: Variant);
  1628. var
  1629. I: Integer;
  1630. AType: TVarType;
  1631. procedure VarAsBytes;
  1632. var
  1633. L: Integer;
  1634. p: PByte;
  1635. begin
  1636. FDataType := mptBinary;
  1637. L := VarArrayHighBound(Value, 1) + 1;
  1638. SetLength(FValue, L);
  1639. p := VarArrayLock(Value);
  1640. Move(p^, FValue[0], L);
  1641. VarArrayUnlock(Value);
  1642. end;
  1643. begin
  1644. if VarIsArray(Value) then
  1645. begin
  1646. AType := VarType(Value);
  1647. if (AType and varTypeMask) = varByte then
  1648. VarAsBytes
  1649. else
  1650. begin
  1651. checkObjectDataType(mptArray);
  1652. FChildren.Clear;
  1653. for I := VarArrayLowBound(Value, VarArrayDimCount(Value))
  1654. to VarArrayHighBound(Value, VarArrayDimCount(Value)) do
  1655. Add.AsVariant := Value[I];
  1656. end;
  1657. end
  1658. else
  1659. begin
  1660. case VarType(Value) of
  1661. varSmallInt, varInteger, varByte, varShortInt, varWord,
  1662. varLongWord, varInt64:
  1663. AsInteger := Value;
  1664. varSingle, varDouble, varCurrency:
  1665. AsFloat := Value;
  1666. varDate:
  1667. AsDateTime := Value;
  1668. varOleStr, varString{$IFDEF UNICODE}, varUString{$ENDIF}:
  1669. AsString := Value;
  1670. varBoolean:
  1671. AsBoolean := Value;
  1672. {$IF RtlVersion>=26}
  1673. varUInt64:
  1674. AsInteger := Value;
  1675. {$IFEND}
  1676. else
  1677. raise Exception.Create(SVariantConvertNotSupport);
  1678. end;
  1679. end;
  1680. end;
  1681. procedure TSimpleMsgPack.SetB(pvPath: String; const Value: Boolean);
  1682. var
  1683. lvObj:TSimpleMsgPack;
  1684. begin
  1685. lvObj := ForcePathObject(pvPath);
  1686. lvObj.AsBoolean := Value;
  1687. end;
  1688. procedure TSimpleMsgPack.SetD(pvPath: String; const Value: Double);
  1689. var
  1690. lvObj:TSimpleMsgPack;
  1691. begin
  1692. lvObj := ForcePathObject(pvPath);
  1693. lvObj.AsFloat := Value;
  1694. end;
  1695. procedure TSimpleMsgPack.SetI(pvPath: String; const Value: Int64);
  1696. var
  1697. lvObj:TSimpleMsgPack;
  1698. begin
  1699. lvObj := ForcePathObject(pvPath);
  1700. lvObj.AsInteger := Value;
  1701. end;
  1702. procedure TSimpleMsgPack.setName(pvName: string);
  1703. begin
  1704. FName := pvName;
  1705. FLowerName := LowerCase(FName);
  1706. end;
  1707. procedure TSimpleMsgPack.SetO(pvPath: String; const Value: TSimpleMsgPack);
  1708. var
  1709. lvName:String;
  1710. s:String;
  1711. sPtr:PChar;
  1712. lvTempObj, lvParent:TSimpleMsgPack;
  1713. j:Integer;
  1714. begin
  1715. s := pvPath;
  1716. lvParent := Self;
  1717. sPtr := PChar(s);
  1718. while sPtr^ <> #0 do
  1719. begin
  1720. lvName := getFirst(sPtr, ['.', '/','\']);
  1721. if lvName = '' then
  1722. begin
  1723. Break;
  1724. end else
  1725. begin
  1726. if sPtr^ = #0 then
  1727. begin // end
  1728. j := lvParent.indexOf(lvName);
  1729. if j <> -1 then
  1730. begin
  1731. lvTempObj := TSimpleMsgPack(lvParent.FChildren[j]);
  1732. lvParent.FChildren[j] := Value;
  1733. lvTempObj.Free; // free old
  1734. end else
  1735. begin
  1736. Value.setName(lvName);
  1737. lvParent.InnerAddToChildren(Value);
  1738. end;
  1739. end else
  1740. begin
  1741. // find childrean
  1742. lvTempObj := lvParent.findObj(lvName);
  1743. if lvTempObj = nil then
  1744. begin
  1745. lvParent := lvParent.Add(lvName);
  1746. end else
  1747. begin
  1748. lvParent := lvTempObj;
  1749. end;
  1750. end;
  1751. end;
  1752. if sPtr^ = #0 then Break;
  1753. Inc(sPtr);
  1754. end;
  1755. end;
  1756. procedure TSimpleMsgPack.SetS(pvPath: String; const Value: string);
  1757. var
  1758. lvObj:TSimpleMsgPack;
  1759. begin
  1760. lvObj := ForcePathObject(pvPath);
  1761. lvObj.AsString := Value;
  1762. end;
  1763. end.