BSTTree.hpp 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001
  1. #pragma once
  2. #include <vector>
  3. #include <list>
  4. #include <string>
  5. #include <functional>
  6. #include <memory>
  7. #include <optional>
  8. #ifndef BSTTree_EXPORTS
  9. #ifdef _WIN64
  10. #ifdef _DEBUG
  11. #pragma comment (lib, "ECOM.Utility.BSTTree64D.lib")
  12. #else
  13. #pragma comment (lib, "ECOM.Utility.BSTTree64.lib")
  14. #endif
  15. #else // X86
  16. #endif
  17. #endif // DSTRING_EXPORTS
  18. #pragma warning (disable:4150)
  19. // 删除指向不完整“boost::property_tree::basic_ptree<std::string, std::string, std::less<Key>>”类型的指针;没有调用析构函数
  20. #pragma warning (disable:4251)
  21. // ECOM::Utility::BSTTree::m_Root: class“XDWHolder<boost::property_tree::ptree>”需要有 dll 接口由 class“ECOM::Utility::BSTTree”的客户端使用
  22. namespace boost
  23. {
  24. namespace property_tree
  25. {
  26. template < class Key, class Data, class KeyCompare>
  27. class basic_ptree;
  28. typedef basic_ptree <std::string, std::string, std::less <std::string>> ptree;
  29. typedef ptree tTree;
  30. // typedef basic_ptree <std::string, eSTR::DString> tTree;
  31. // typedef basic_ptree <eSTR::DString, eSTR::DString> tTree;
  32. };
  33. };
  34. using namespace boost::property_tree;
  35. #include "XDWHolder.tlh"
  36. #include "XDWHolder.tli"
  37. #ifndef BSTTree_EXPORTS
  38. #define _BSTTree_API _declspec(dllimport)
  39. #else
  40. #define _BSTTree_API _declspec(dllexport)
  41. #endif
  42. #ifndef BSTTree_EXPORTS
  43. #ifdef _WIN64
  44. #ifdef _DEBUG
  45. #pragma comment (lib, "ECOM.Utility.BSTTree64D.lib")
  46. #else
  47. #pragma comment (lib, "ECOM.Utility.BSTTree64.lib")
  48. #endif
  49. #else // X86
  50. #ifdef _DEBUG
  51. #pragma comment (lib, "ECOM.Utility.BSTTreeD.lib")
  52. #else
  53. #pragma comment (lib, "ECOM.Utility.BSTTree.lib")
  54. #endif
  55. #endif
  56. #endif // BSTTree_EXPORTS
  57. //-----------------------------------------------------------------------------
  58. // BSTTree
  59. // 对 tTree 的封装
  60. //
  61. // 不能用 std::unique_ptr, 因为 unique_ptr 需要知道 tTree 才能析构
  62. // 因此这里用 XDWHolder
  63. //-----------------------------------------------------------------------------
  64. namespace ECOM::Utility
  65. {
  66. class BSTTreeArray;
  67. class _BSTTree_API BSTTree
  68. {
  69. template <typename> static constexpr bool dependent_false = false;
  70. protected:
  71. tTree * m_Tree;
  72. XDWHolder <tTree> m_Root;
  73. bool m_bAttrib;
  74. friend class BSTXML;
  75. friend class BSTJSON;
  76. friend class BSTINI;
  77. friend class BSTSSV;
  78. friend class BSTTreeArray;
  79. private:
  80. BSTTree (XDWHolder <tTree> && from);
  81. public:
  82. BSTTree ();
  83. BSTTree (BSTTree && from);
  84. BSTTree (const BSTTree & from) = delete;
  85. virtual ~BSTTree ();
  86. BSTTree & operator = (BSTTree && from);
  87. BSTTree & operator = (const BSTTree & from) = delete;
  88. public:
  89. bool IsEmpty () const;
  90. operator bool () const { return ! IsEmpty (); }
  91. // 返回儿子节点的数量
  92. int Size () const;
  93. // 数一数其中有多少个路径
  94. int Count (const std::string & path) const;
  95. int Count (const std::string_view & path) const { return Count (std::string (path)); }
  96. protected:
  97. BSTTree __Into (const std::string & path) const;
  98. BSTTree __Into (const std::string & path, char sep) const;
  99. public:
  100. BSTTree Into (const std::string & path) const;
  101. // BSTTree Into (const eSTR::DString & path) const;
  102. BSTTree Into (const std::string_view & path) const { return Into (std::string (path)); }
  103. public:
  104. BSTTree Into (const std::string & path, char sep) const
  105. {
  106. return __Into (path, sep);
  107. }
  108. public:
  109. BSTTree Attrib () const;
  110. protected:
  111. std::string TryAttribOf (const std::string & path, LPCSTR Def) const;
  112. std::string TryAttribOf (const std::string & path, const std::string & Def) const;
  113. public:
  114. #if 1
  115. template <typename T> T AttribOf (const std::string & path) const
  116. {
  117. return Attrib ().Get <T> (path);
  118. }
  119. template <typename T> T AttribOf (const std::string_view & path) const
  120. {
  121. return Attrib ().Get <T> (path);
  122. }
  123. #endif
  124. // 如果不写类型转换, 默认返回 std::string 类型
  125. std::string AttribOf (const std::string & path) const
  126. {
  127. return (TryAttribOf (path, std::string ()));
  128. }
  129. std::string AttribOf (const std::string_view & _path) const
  130. {
  131. std::string path { _path };
  132. return (TryAttribOf (path, std::string ()));
  133. }
  134. std::string AttribOf (const char * _path) const
  135. {
  136. std::string path { _path };
  137. return (TryAttribOf (path, std::string ()));
  138. }
  139. // 给定路径, 获取 Value
  140. public:
  141. ///
  142. // 类型转换, 默认用的就是 eSTR::DString 的转换函数/模版
  143. template <typename T> T Get (const std::string_view & path) const
  144. {
  145. static_assert (dependent_false<T>);
  146. }
  147. // 偏特化
  148. // template <> std::string Get (const std::string_view & path) const;
  149. template <> std::string Get (const std::string_view & path) const { return TryGet (path, std::string ()); }
  150. template <> int Get (const std::string_view & path) const { return TryGet (path, static_cast <int> (0)); }
  151. template <> unsigned int Get (const std::string_view & path) const { return TryGet (path, static_cast <unsigned int> (0)); }
  152. template <> __int64 Get (const std::string_view & path) const { return TryGet (path, static_cast <__int64> (0)); }
  153. template <> unsigned __int64 Get (const std::string_view & path) const { return TryGet (path, static_cast <unsigned __int64> (0)); }
  154. template <> long Get (const std::string_view & path) const { return TryGet (path, static_cast <long> (0)); }
  155. template <> unsigned long Get (const std::string_view & path) const { return TryGet (path, static_cast <unsigned long> (0)); }
  156. template <> double Get (const std::string_view & path) const { return TryGet (path, static_cast <double> (0.0)); }
  157. template <> float Get (const std::string_view & path) const { return TryGet (path, static_cast <float> (0.0f)); }
  158. template <> bool Get (const std::string_view & path) const { return TryGet (path, false); }
  159. // 如果不写类型转换, 默认返回 std::string 类型
  160. std::string Get (const std::string & path) const { return Get <std::string> (path); }
  161. std::string Get (const std::string_view & path) const { return Get <std::string> (path); }
  162. // std::string Get (const char * path) const { return Get <std::string> (path); }
  163. // 上述函数引起编译器错误: 重载函数定义不明, 因此注释掉
  164. ///
  165. // 给定路径, 获取 Value, 但是返回 optional
  166. public:
  167. std::optional <std::string> GetOpt (const std::string_view & path) const
  168. {
  169. return GetOpt (std::string (path));
  170. }
  171. std::optional <std::string> GetOpt (const std::string & path) const;
  172. public:
  173. int GetArray (const std::string_view & Key, std::vector <std::string> * arStr);
  174. int GetArray (const std::string_view & Key, std::list <std::string> * arStr);
  175. public:
  176. // 带默认值的函数操作符重载
  177. // eSTR::DString operator () (const std::string_view & path, LPCSTR Def) const { return eSTR::DString (TryGet (path, Def)); }
  178. bool operator () (const std::string_view & path, bool Def) const { return TryGet (path, Def); }
  179. int operator () (const std::string_view & path, int Def) const { return TryGet (path, Def); }
  180. unsigned int operator () (const std::string_view & path, unsigned int Def) const { return TryGet (path, Def); }
  181. __int64 operator () (const std::string_view & path, __int64 Def) const { return TryGet (path, Def); }
  182. long operator () (const std::string_view & path, long Def) const { return TryGet (path, Def); }
  183. float operator () (const std::string_view & path, float Def) const { return TryGet (path, Def); }
  184. double operator () (const std::string_view & path, double Def) const { return TryGet (path, Def); }
  185. protected:
  186. /// 如果找不到, 就用 Def 代替
  187. std::string TryGet (const std::string_view & path, const char * Def) const;
  188. std::string TryGet (const std::string_view & path, const std::string_view & Def) const;
  189. std::string TryGet (const std::string_view & path, const std::string & Def) const;
  190. int TryGet (const std::string_view & path, int Def) const;
  191. unsigned int TryGet (const std::string_view & path, unsigned int Def) const;
  192. __int64 TryGet (const std::string_view & path, __int64 Def) const;
  193. unsigned __int64 TryGet (const std::string_view & path, unsigned __int64 Def) const;
  194. long TryGet (const std::string_view & path, long Def) const;
  195. unsigned long TryGet (const std::string_view & path, unsigned long Def) const;
  196. double TryGet (const std::string_view & path, double Def) const;
  197. float TryGet (const std::string_view & path, float Def) const;
  198. bool TryGet (const std::string_view & path, bool Def) const;
  199. template <typename TR, typename T>
  200. TR _TryGet (const std::string_view & path, const T & Def) const;
  201. ///
  202. public:
  203. template <typename T> T GetIf (const std::string_view & path, const T & Def) const
  204. {
  205. auto rc = TryGet (path, Def);
  206. return rc;
  207. }
  208. //< 针对 LPCSTR Def 的特殊处理, 例如 int Port = CH.GetIf ("Port", "22");
  209. template <typename T> T GetIf (const std::string_view & path, LPCSTR Def) const
  210. {
  211. auto rc = TryGet (path, Def);
  212. return rc;
  213. }
  214. // 例如 DString AE = Ch.GetIf ("AE", "DROC");
  215. template <> std::string GetIf (const std::string_view & path, LPCSTR Def) const
  216. {
  217. auto rc = TryGet (path, Def);
  218. return (rc);
  219. }
  220. std::string GetIf (const std::string_view & path, LPCSTR Def) const
  221. {
  222. return GetIf <std::string> (path, Def);
  223. }
  224. //>
  225. std::string GetIf (const std::string_view & path, const std::string & Def) const
  226. {
  227. return GetIf <std::string> (path, Def.c_str ());
  228. }
  229. //< 针对 StringView 的特殊处理, 不能返回 StringView
  230. std::string GetIf (const std::string_view & path, const std::string_view & Def) const
  231. {
  232. auto rc = TryGet (path, Def);
  233. return (rc);
  234. }
  235. //>
  236. public:
  237. template <typename T> T GetData () const
  238. {
  239. static_assert (dependent_false<T>, "Invalid type in BSTTtee.GetData ()");
  240. }
  241. template <> std::string GetData () const;
  242. std::string GetData () const { return GetData <std::string> (); }
  243. protected:
  244. template <typename T> std::optional <T> _GetValue () const;
  245. public:
  246. template <typename T> std::optional <T> GetValue () const
  247. {
  248. static_assert (dependent_false<T>, "Invalid type in BSTTtee.GetValue ()");
  249. }
  250. template <> std::optional <std::string> GetValue () const;
  251. template <> std::optional <int> GetValue () const;
  252. template <> std::optional <unsigned int> GetValue () const;
  253. template <> std::optional <long> GetValue () const;
  254. template <> std::optional <unsigned long> GetValue () const;
  255. template <> std::optional <__int64> GetValue () const;
  256. template <> std::optional <unsigned __int64> GetValue () const;
  257. template <> std::optional <double> GetValue () const;
  258. template <> std::optional <float> GetValue () const;
  259. template <> std::optional <bool> GetValue () const;
  260. std::optional <std::string> GetValue () const { return GetValue <std::string> (); }
  261. public:
  262. // 如果原来没有这一项, 就增加, 如果原来有, 就更新. 返回 this
  263. BSTTree & SetValue (LPCSTR value);
  264. BSTTree & SetValue (const std::string & value);
  265. // BSTTree & SetValue (const eSTR::DString & value);
  266. BSTTree & SetValue (const std::string_view & value);
  267. BSTTree & SetValue (int value);
  268. BSTTree & SetValue (unsigned int value);
  269. BSTTree & SetValue (long value);
  270. BSTTree & SetValue (unsigned long value);
  271. BSTTree & SetValue (__int64 value);
  272. BSTTree & SetValue (unsigned __int64 value);
  273. BSTTree & SetValue (double value);
  274. BSTTree & SetValue (bool value);
  275. BSTTree & SetValue (void * ptr);
  276. public:
  277. // 如果原来没有这一项, 就增加, 如果原来有, 就更新. 返回 this
  278. BSTTree & Put (const std::string_view & path, LPCSTR value);
  279. BSTTree & Put (const std::string_view & path, const std::string & value);
  280. BSTTree & Put (const std::string_view & path, const std::string_view & value);
  281. BSTTree & Put (const std::string_view & path, int value);
  282. BSTTree & Put (const std::string_view & path, unsigned int value);
  283. BSTTree & Put (const std::string_view & path, long value);
  284. BSTTree & Put (const std::string_view & path, unsigned long value);
  285. BSTTree & Put (const std::string_view & path, __int64 value);
  286. BSTTree & Put (const std::string_view & path, unsigned __int64 value);
  287. BSTTree & Put (const std::string_view & path, double value);
  288. BSTTree & Put (const std::string_view & path, bool value);
  289. BSTTree & Put (const std::string_view & path, void * ptr);
  290. public:
  291. // 添加新项, 返回 this
  292. BSTTree & Add (const std::string_view & path, LPCSTR value);
  293. BSTTree & Add (const std::string_view & path, const std::string & value);
  294. BSTTree & Add (const std::string_view & path, const std::string_view & value);
  295. BSTTree & Add (const std::string_view & path, int value);
  296. BSTTree & Add (const std::string_view & path, unsigned int value);
  297. BSTTree & Add (const std::string_view & path, long value);
  298. BSTTree & Add (const std::string_view & path, unsigned long value);
  299. BSTTree & Add (const std::string_view & path, __int64 value);
  300. BSTTree & Add (const std::string_view & path, unsigned __int64 value);
  301. BSTTree & Add (const std::string_view & path, double value);
  302. BSTTree & Add (const std::string_view & path, bool value);
  303. BSTTree & Add (const std::string_view & path, void * ptr);
  304. // 数组/列表
  305. public:
  306. template <typename T>
  307. BSTTree & Add (const std::string_view & path, const std::list <T> & lst);
  308. template <typename T>
  309. BSTTree & Add (const std::string_view & path, const std::vector <T> & lst);
  310. protected:
  311. template <typename T>
  312. BSTTree & __Add (const std::string_view & path, const T & value);
  313. template <typename T>
  314. BSTTree & __Put (const std::string_view & path, const T & value);
  315. public:
  316. // 特殊用途, 把 child 作为子节点
  317. bool Add (const std::string & name, const BSTTree & child);
  318. protected:
  319. class Proxy
  320. {
  321. public:
  322. Proxy (BSTTree * Tree, std::string_view Key)
  323. {
  324. m_Tree = Tree;
  325. m_Key = Key;
  326. }
  327. Proxy (BSTTree * Tree, const std::string & Key)
  328. {
  329. m_Tree = Tree;
  330. m_Key = Key;
  331. }
  332. Proxy (const Proxy & from)
  333. {
  334. m_Tree = from.m_Tree;
  335. m_Key = from.m_Key;
  336. }
  337. Proxy (Proxy && from)
  338. {
  339. m_Tree = from.m_Tree;
  340. m_Key = from.m_Key;
  341. }
  342. ~Proxy () = default;
  343. public:
  344. inline std::string Get () const
  345. {
  346. return m_Tree->Get (m_Key);
  347. }
  348. inline operator std::string () const
  349. {
  350. return m_Tree->Get (m_Key);
  351. }
  352. inline operator void * () const
  353. {
  354. return reinterpret_cast <void *> (m_Tree->Get <UINT_PTR> (m_Key));
  355. }
  356. inline operator DWORD () const
  357. {
  358. return m_Tree->Get <DWORD> (m_Key);
  359. }
  360. inline operator __int64 () const
  361. {
  362. return m_Tree->Get <__int64> (m_Key);
  363. }
  364. inline operator unsigned __int64 () const
  365. {
  366. return m_Tree->Get <unsigned __int64> (m_Key);
  367. }
  368. inline operator int () const
  369. {
  370. return m_Tree->Get <int> (m_Key);
  371. }
  372. inline operator unsigned int () const
  373. {
  374. return m_Tree->Get <unsigned int> (m_Key);
  375. }
  376. inline operator long () const
  377. {
  378. return m_Tree->Get <long> (m_Key);
  379. }
  380. inline operator bool () const
  381. {
  382. return m_Tree->Get <bool> (m_Key);
  383. }
  384. inline operator float () const
  385. {
  386. return m_Tree->Get <float> (m_Key);
  387. }
  388. inline operator double () const
  389. {
  390. return m_Tree->Get <double> (m_Key);
  391. }
  392. public:
  393. inline Proxy & operator = (LPCSTR Value)
  394. {
  395. m_Tree->Put (m_Key, Value);
  396. return (*this);
  397. }
  398. #if 0
  399. inline Proxy & operator = (PCWSTR Value)
  400. {
  401. m_Tree->Put (m_Key, Value);
  402. return (*this);
  403. }
  404. #endif
  405. inline Proxy & operator = (const std::string_view & Value)
  406. {
  407. m_Tree->Put (m_Key, Value);
  408. return (*this);
  409. }
  410. inline Proxy & operator = (const std::string & Value)
  411. {
  412. m_Tree->Put (m_Key, Value);
  413. return (*this);
  414. }
  415. inline Proxy & operator = (__int64 Value)
  416. {
  417. m_Tree->Put (m_Key, Value);
  418. return (*this);
  419. }
  420. inline Proxy & operator = (UINT_PTR Value)
  421. {
  422. m_Tree->Put (m_Key, Value);
  423. return (*this);
  424. }
  425. inline Proxy & operator = (DWORD Value)
  426. {
  427. m_Tree->Put (m_Key, Value);
  428. return (*this);
  429. }
  430. inline Proxy & operator = (int Value)
  431. {
  432. m_Tree->Put (m_Key, Value);
  433. return (*this);
  434. }
  435. inline Proxy & operator = (bool Value)
  436. {
  437. m_Tree->Put (m_Key, Value);
  438. return (*this);
  439. }
  440. inline Proxy & operator = (void * Value)
  441. {
  442. m_Tree->Put (m_Key, Value);
  443. return (*this);
  444. }
  445. inline Proxy & operator = (float Value)
  446. {
  447. m_Tree->Put (m_Key, Value);
  448. return (*this);
  449. }
  450. inline Proxy & operator = (double Value)
  451. {
  452. m_Tree->Put (m_Key, Value);
  453. return (*this);
  454. }
  455. protected:
  456. BSTTree * m_Tree;
  457. std::string_view m_Key;
  458. };
  459. // 函数操作符重载, 下标操作符重载
  460. public:
  461. Proxy operator [] (std::string_view Key)
  462. {
  463. return Proxy (this, Key);
  464. }
  465. Proxy operator () (std::string_view Key)
  466. {
  467. return Proxy (this, Key);
  468. }
  469. public:
  470. // 添加一个子节点, 返回的是这个子节点
  471. BSTTree AddChild (const std::string & path);
  472. BSTTree AddChild (const std::string_view path)
  473. {
  474. return AddChild (std::string (path));
  475. }
  476. public:
  477. // 如果原来没有这一项, 就增加, 如果原来有, 就更新, 返回的是这个子节点
  478. BSTTree PutChild (const std::string & path);
  479. BSTTree PutChild (const std::string_view & path)
  480. {
  481. return PutChild (std::string (path));
  482. }
  483. public:
  484. // 增加子节点, 但是子节点是一个数组
  485. BSTTreeArray AddChildArray (const std::string & path);
  486. BSTTreeArray AddChildArray (const std::string_view & path);
  487. //BSTTreeArray AddChildArray (LPCSTR path); // 易导致编译错误: 重载调用不明确
  488. public:
  489. // 无条件删除指定的项, 当然包括下面的全部子项
  490. bool Delete (const std::string_view & path);
  491. // 当 Pred 返回 true 时, 删除
  492. bool Delete (std::function <bool (const std::string & path, BSTTree & xml)> pred);
  493. public:
  494. // 查找, 判断某个路径是否存在
  495. bool IsExist (const std::string & path);
  496. bool IsExist (const std::string_view & path) { return IsExist (std::string (path)); }
  497. public:
  498. // 如果非空, 就执行指定的函数
  499. template <typename Fun, typename... arg>
  500. inline bool Do (const Fun & fun, arg... e)
  501. {
  502. if (IsEmpty ()) return false;
  503. fun (*this, e...);
  504. return true;
  505. }
  506. public:
  507. // 获取第一个/最后一个, 如果存在, 就调用指定指定的函数
  508. // bool OnFirst (std::function <void (const std::string & path, BSTTree & xml)> fun);
  509. // bool OnLast (std::function <void (const std::string & path, BSTTree & xml)> fun);
  510. // 返回第一个子节点/最后一个子节点. 如果不存在, 或者为空, 返回的 XML 将是空白的
  511. BSTTree First ();
  512. BSTTree Last ();
  513. /// 非模板版本 (2021-11-04)
  514. // 测试表明, 如果用之前版本的模板, 可能导致断言失败.
  515. // 具体原因很难找, 可能是因为 Iter 内部的实例是在本模块内分配的, 但是却由调用者来释放.
  516. ///
  517. // 类似迭代器的调用, 返回调用次数
  518. int ForEach (std::function <void (const std::string & tagname, BSTTree &)>);
  519. // 搜索指定的 tagname, 如果找到, 就执行对应的函数
  520. int ForEachOn (const std::string & tagname, std::function <void (BSTTree &)>);
  521. int ForEachOn (const std::string_view & tagname, std::function <void (BSTTree &)>);
  522. private:
  523. template <typename T>
  524. int _ForEachOn (const T & tagname, std::function <void (BSTTree &)>);
  525. public:
  526. // 寻找满足条件的第一个, 如果找到, 就执行对应的函数
  527. bool First (std::function <bool (const std::string& tagname, BSTTree&)> pred);
  528. public:
  529. // 转换成 容器, 比如 std::list <BSTTree>
  530. template <typename T>
  531. inline T To ()
  532. {
  533. T rc;
  534. if (IsEmpty ())
  535. return rc;
  536. auto Iter = GetIterator ();
  537. for (;;)
  538. {
  539. auto pair = Iter ();
  540. auto & name = pair.first;
  541. auto & ptr = pair.second;
  542. BSTTree * xml = ptr.get ();
  543. if (xml == nullptr) // 迭代结束
  544. break;
  545. rc.push_back (std::move (*xml));
  546. }
  547. return rc;
  548. }
  549. // 转换成 vector <BSTTree>
  550. inline std::vector <BSTTree> ToVector ()
  551. {
  552. return To <std::vector <BSTTree> > ();
  553. }
  554. // 转换成 list <BSTTree>
  555. inline std::list <BSTTree> ToList ()
  556. {
  557. return To <std::list <BSTTree> > ();
  558. }
  559. public:
  560. static bool IsAttrib (const std::string & tagName); // return tagName == XMLATTR
  561. private:
  562. // 迭代函数返回 pair, 参数 2 用指针, 其目的是让上层知道: 何时迭代结束
  563. using IterArgType = std::pair <std::string, std::unique_ptr <BSTTree>>;
  564. using IterFuncType = std::function <IterArgType ()>;
  565. IterFuncType GetIterator ();
  566. static BSTTree _TreeNodeToMe (tTree & node);
  567. static const std::string XMLATTR_DOT; // = "<xmlattr>.";
  568. static const std::string XMLATTR; // = "<xmlattr>";
  569. };
  570. //-----------------------------------------------------------------------------
  571. // BSTTreeArray
  572. //-----------------------------------------------------------------------------
  573. class _BSTTree_API BSTTreeArray : public BSTTree
  574. {
  575. private:
  576. BSTTreeArray (BSTTree & parent, const std::string & path);
  577. public:
  578. BSTTreeArray (BSTTreeArray && with);
  579. private:
  580. BSTTree & m_Parent;
  581. const std::string m_Path;
  582. friend class BSTTree;
  583. public:
  584. ~BSTTreeArray ();
  585. public:
  586. BSTTreeArray & Add (const BSTTree & tree);
  587. template <typename T>
  588. BSTTreeArray & Add (const std::string_view & key, const T & value)
  589. {
  590. BSTTree CH;
  591. CH.Add (key, value);
  592. return Add (std::move (CH));
  593. }
  594. // 最后应该调用 End, 调用 End 之后, 就无法调用 Add 了 (即使调用也无效)
  595. // 析构函数也会调用 End
  596. void End ();
  597. };
  598. }
  599. namespace ECOM::Utility
  600. {
  601. //-----------------------------------------------------------------------------
  602. // BSTXML, BSTJSON, BSTINI
  603. // 全部是 public 的静态函数
  604. // 以下函数被删除, 因为容易引起编译错误: 决策不明 (例如 LoadFile (DString xx));
  605. // static BSTTree LoadFile (const wchar_t * szFileName)
  606. // static BSTTree LoadFile (LPCSTR szFileName)
  607. // static int SaveFile (BSTTree & Tree, const wchar_t * szFileName)
  608. // static int SaveFile (BSTTree & Tree, LPCSTR szFileName)
  609. //-----------------------------------------------------------------------------
  610. //-----------------------------------------------------------------------------
  611. // BSTXML
  612. //-----------------------------------------------------------------------------
  613. class _BSTTree_API BSTXML
  614. {
  615. public:
  616. // 文件和字符串, 默认是 UTF8 编码
  617. static BSTTree LoadFile (const std::wstring & szFileName);
  618. static BSTTree LoadFile (const std::wstring_view & szFileName)
  619. {
  620. return LoadFile (std::wstring (szFileName));
  621. }
  622. static BSTTree LoadFile (const std::string & szFileName);
  623. static BSTTree LoadFile (const std::string_view & szFileName)
  624. {
  625. return LoadFile (std::string (szFileName));
  626. }
  627. static BSTTree FromString (const std::string & doc);
  628. static BSTTree FromString (const std::string_view & doc);
  629. // 返回: 写入的字节数
  630. static int SaveFile (const BSTTree & Tree, const std::wstring_view & szFileName);
  631. static int SaveFile (const BSTTree & Tree, const std::wstring & szFileName)
  632. {
  633. return SaveFile (Tree, std::wstring_view (szFileName));
  634. }
  635. static int SaveFile (const BSTTree & Tree, const std::string_view & szFileName);
  636. static int SaveFile (const BSTTree & Tree, const std::string & szFileName)
  637. {
  638. return SaveFile (Tree, std::string_view (szFileName));
  639. }
  640. public:
  641. // 转换成字符串, 默认是 UTF8 编码
  642. static std::string ToString (const BSTTree & Tree);
  643. };
  644. //-----------------------------------------------------------------------------
  645. // BSTJSON
  646. //-----------------------------------------------------------------------------
  647. class _BSTTree_API BSTJSON
  648. {
  649. public:
  650. // 文件和字符串, 默认是 UTF8 编码
  651. static BSTTree LoadFile (const std::wstring & szFileName);
  652. static BSTTree LoadFile (const std::wstring_view & szFileName)
  653. {
  654. return LoadFile (std::wstring (szFileName));
  655. }
  656. static BSTTree LoadFile (const std::string & szFileName);
  657. static BSTTree LoadFile (const std::string_view & szFileName)
  658. {
  659. return LoadFile (std::string (szFileName));
  660. }
  661. static int SaveFile (const BSTTree & Tree, const std::string_view & szFileName);
  662. static int SaveFile (const BSTTree & Tree, const std::string & szFileName)
  663. {
  664. return SaveFile (Tree, std::string_view (szFileName));
  665. }
  666. static BSTTree FromString (const std::string & doc);
  667. static BSTTree FromString (const std::string_view & doc);
  668. //static BSTTree FromString (LPCSTR doc);
  669. // 返回: 写入的字节数
  670. static int SaveFile (const BSTTree & Tree, const std::wstring & szFileName);
  671. static int SaveFile (const BSTTree & Tree, const std::wstring_view & szFileName)
  672. {
  673. return SaveFile (Tree, std::wstring (szFileName));
  674. }
  675. public:
  676. // 转换成字符串, 默认是 UTF8 编码
  677. static std::string ToString (const BSTTree & Tree);
  678. };
  679. //-----------------------------------------------------------------------------
  680. // BSTINI
  681. //-----------------------------------------------------------------------------
  682. class _BSTTree_API BSTINI
  683. {
  684. public:
  685. // 文件和字符串, 默认是 UTF8 编码
  686. static BSTTree LoadFile (const std::wstring & szFileName);
  687. static BSTTree LoadFile (const std::wstring_view & szFileName)
  688. {
  689. return LoadFile (std::wstring (szFileName));
  690. }
  691. static BSTTree LoadFile (const std::string & szFileName);
  692. static BSTTree LoadFile (const std::string_view & szFileName)
  693. {
  694. return LoadFile (std::string (szFileName));
  695. }
  696. static BSTTree FromString (const std::string & doc);
  697. static BSTTree FromString (const std::string_view & doc);
  698. //static BSTTree FromString (LPCSTR doc);
  699. // 返回: 写入的字节数
  700. static int SaveFile (const BSTTree & Tree, const std::wstring & szFileName);
  701. static int SaveFile (const BSTTree & Tree, const std::wstring_view & szFileName)
  702. {
  703. return SaveFile (Tree, std::wstring (szFileName));
  704. }
  705. static int SaveFile (const BSTTree & Tree, const std::string_view & szFileName);
  706. static int SaveFile (const BSTTree & Tree, const std::string & szFileName)
  707. {
  708. return SaveFile (Tree, std::string_view (szFileName));
  709. }
  710. public:
  711. // 转换成字符串, 默认是 UTF8 编码
  712. static std::string ToString (const BSTTree & Tree);
  713. };
  714. //-----------------------------------------------------------------------------
  715. // BSTSSV
  716. // 以分号分隔, 例如 K1=V1; K2=V2; K3=V3
  717. //-----------------------------------------------------------------------------
  718. class _BSTTree_API BSTSSV
  719. {
  720. public:
  721. // 文件和字符串, 默认是 UTF8 编码
  722. static BSTTree LoadFile (const std::wstring & szFileName);
  723. static BSTTree LoadFile (const std::wstring_view & szFileName)
  724. {
  725. return LoadFile (std::wstring (szFileName));
  726. }
  727. static BSTTree LoadFile (const std::string & szFileName);
  728. static BSTTree LoadFile (const std::string_view & szFileName)
  729. {
  730. return LoadFile (std::string (szFileName));
  731. }
  732. static BSTTree FromString (const std::string & doc);
  733. static BSTTree FromString (const std::string_view & doc);
  734. //static BSTTree FromString (LPCSTR doc);
  735. // 返回: 写入的字节数
  736. static int SaveFile (const BSTTree & Tree, const std::wstring & szFileName);
  737. static int SaveFile (const BSTTree & Tree, const std::wstring_view & szFileName)
  738. {
  739. return SaveFile (Tree, std::wstring (szFileName));
  740. }
  741. static int SaveFile (const BSTTree & Tree, const std::string_view & szFileName);
  742. static int SaveFile (const BSTTree & Tree, const std::string & szFileName)
  743. {
  744. return SaveFile (Tree, std::string_view (szFileName));
  745. }
  746. public:
  747. // 转换成字符串, 默认是 UTF8 编码
  748. static std::string ToString (const BSTTree & Tree);
  749. };
  750. }
  751. namespace ECOM::Utility
  752. {
  753. template <typename T>
  754. inline BSTTree & BSTTree::Add (const std::string_view & path, const std::list <T> & lst)
  755. {
  756. if (! m_Tree) return (*this);
  757. try
  758. {
  759. auto CHArray = this->AddChildArray (path);
  760. std::string emp;
  761. for (const auto & it : lst)
  762. {
  763. ECOM::Utility::BSTTree CH;
  764. CH.Put (emp, it);
  765. CHArray.Add (std::move (CH));
  766. }
  767. CHArray.End ();
  768. }
  769. catch (...)
  770. {
  771. }
  772. return (*this);
  773. }
  774. template <typename T>
  775. inline BSTTree & BSTTree::Add (const std::string_view & path, const std::vector <T> & lst)
  776. {
  777. if (! m_Tree) return (*this);
  778. try
  779. {
  780. auto CHArray = this->AddChildArray (path);
  781. std::string emp;
  782. for (const auto & it : lst)
  783. {
  784. ECOM::Utility::BSTTree CH;
  785. CH.Put (emp, it);
  786. CHArray.Add (std::move (CH));
  787. }
  788. CHArray.End ();
  789. }
  790. catch (...)
  791. {
  792. }
  793. return (*this);
  794. }
  795. }