BSTTree.hpp 27 KB

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