jptree.hpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #ifndef _PTREE_HPP
  14. #define _PTREE_HPP
  15. #include "jlib.hpp"
  16. #include "jexcept.hpp"
  17. #include "jiter.hpp"
  18. #include "jprop.hpp"
  19. #include <initializer_list>
  20. enum TextMarkupFormat
  21. {
  22. MarkupFmt_Unknown=0,
  23. MarkupFmt_XML,
  24. MarkupFmt_JSON,
  25. MarkupFmt_URL
  26. };
  27. enum PTreeExceptionCodes
  28. {
  29. PTreeExcpt_XPath_Ambiguity,
  30. PTreeExcpt_XPath_ParseError,
  31. PTreeExcpt_XPath_Unsupported,
  32. PTreeExcpt_InvalidTagName,
  33. PTreeExcpt_Unsupported,
  34. PTreeExcpt_InternalError,
  35. };
  36. interface jlib_thrown_decl IPTreeException : extends IException { };
  37. interface IAttributeIterator : extends IInterface
  38. {
  39. virtual bool first()=0;
  40. virtual bool next()=0;
  41. virtual bool isValid()=0;
  42. virtual unsigned count()=0;
  43. virtual const char *queryName() const = 0;
  44. virtual const char *queryValue() const = 0;
  45. virtual StringBuffer &getValue(StringBuffer &out) = 0;
  46. };
  47. interface IPropertyTree;
  48. interface IPropertyTreeIterator : extends IIteratorOf<IPropertyTree> { };
  49. typedef unsigned IPTIteratorCodes;
  50. #define iptiter_null 0x00
  51. #define iptiter_sort 0x01
  52. #define iptiter_remote 0x02
  53. #define iptiter_remoteget 0x06
  54. #define iptiter_remotegetbranch 0x0e
  55. extern jlib_decl unsigned queryNumLocalTrees();
  56. extern jlib_decl unsigned queryNumAtomTrees();
  57. interface jlib_decl IPropertyTree : extends serializable
  58. {
  59. virtual bool hasProp(const char *xpath) const = 0;
  60. virtual bool isBinary(const char *xpath=NULL) const = 0;
  61. virtual bool isCompressed(const char *xpath=NULL) const = 0; // needed for external/internal efficiency e.g. for clone
  62. virtual bool renameProp(const char *xpath, const char *newName) = 0;
  63. virtual bool renameTree(IPropertyTree *tree, const char *newName) = 0;
  64. // string - all types can be converted to string
  65. virtual bool getProp(const char *xpath, StringBuffer &ret) const = 0;
  66. virtual const char *queryProp(const char * xpath) const = 0;
  67. virtual void setProp(const char *xpath, const char *val) = 0;
  68. virtual void addProp(const char *xpath, const char *val) = 0;
  69. virtual void appendProp(const char *xpath, const char *val) = 0;
  70. virtual bool getPropBool(const char *xpath, bool dft=false) const = 0;
  71. virtual void setPropBool(const char *xpath, bool val) = 0;
  72. virtual void addPropBool(const char *xpath, bool val) = 0;
  73. virtual int getPropInt(const char *xpath, int dft=0) const = 0;
  74. virtual void setPropInt(const char *xpath, int val) = 0;
  75. virtual void addPropInt(const char *xpath, int val) = 0;
  76. virtual __int64 getPropInt64(const char *xpath, __int64 dft=0) const = 0;
  77. virtual void setPropInt64(const char *xpath, __int64 val) = 0;
  78. virtual void addPropInt64(const char *xpath, __int64 val) = 0;
  79. virtual double getPropReal(const char *xpath, double dft=0.0) const = 0;
  80. virtual bool getPropBin(const char *xpath, MemoryBuffer &ret) const = 0;
  81. virtual void setPropBin(const char *xpath, size32_t size, const void *data) = 0;
  82. virtual void addPropBin(const char *xpath, size32_t size, const void *data) = 0;
  83. virtual void appendPropBin(const char *xpath, size32_t size, const void *data) = 0;
  84. virtual IPropertyTree *getPropTree(const char *xpath) const = 0;
  85. virtual IPropertyTree *queryPropTree(const char *xpath) const = 0;
  86. virtual IPropertyTree *setPropTree(const char *xpath, IPropertyTree *val) = 0;
  87. virtual IPropertyTree *addPropTree(const char *xpath, IPropertyTree *val) = 0;
  88. virtual IPropertyTree *setPropTree(const char *xpath) = 0;
  89. virtual IPropertyTree *addPropTree(const char *xpath) = 0;
  90. virtual bool removeProp(const char *xpath) = 0;
  91. virtual bool removeTree(IPropertyTree *child) = 0;
  92. virtual aindex_t queryChildIndex(IPropertyTree *child) = 0;
  93. virtual StringBuffer &getName(StringBuffer &) const = 0;
  94. virtual const char *queryName() const = 0;
  95. virtual IPropertyTreeIterator *getElements(const char *xpath, IPTIteratorCodes flags = iptiter_null) const = 0;
  96. virtual IAttributeIterator *getAttributes(bool sorted=false) const = 0;
  97. virtual IPropertyTree *getBranch(const char *xpath) const = 0;
  98. virtual IPropertyTree *queryBranch(const char *xpath) const = 0;
  99. virtual bool hasChildren() const = 0;
  100. virtual unsigned numUniq() = 0;
  101. virtual unsigned numChildren() = 0;
  102. virtual bool isCaseInsensitive() const = 0;
  103. virtual bool IsShared() const = 0;
  104. virtual void localizeElements(const char *xpath, bool allTail=false) = 0;
  105. virtual unsigned getCount(const char *xpath) = 0;
  106. virtual IPropertyTree *addPropTreeArrayItem(const char *xpath, IPropertyTree *val) = 0;
  107. virtual bool isArray(const char *xpath=NULL) const = 0;
  108. virtual unsigned getAttributeCount() const = 0;
  109. private:
  110. void setProp(const char *, int); // dummy to catch accidental use of setProp when setPropInt() intended
  111. void addProp(const char *, int); // likewise
  112. };
  113. jlib_decl bool validateXMLTag(const char *name);
  114. interface IPTreeNotifyEvent : extends IInterface
  115. {
  116. virtual void beginNode(const char *tag, bool sequence, offset_t startOffset) = 0;
  117. virtual void newAttribute(const char *name, const char *value) = 0;
  118. virtual void beginNodeContent(const char *tag) = 0; // attributes parsed
  119. virtual void endNode(const char *tag, unsigned length, const void *value, bool binary, offset_t endOffset) = 0;
  120. };
  121. enum PTreeReadExcptCode { PTreeRead_undefined, PTreeRead_EOS, PTreeRead_syntax };
  122. interface jlib_thrown_decl IPTreeReadException : extends IException
  123. {
  124. virtual const char *queryDescription() = 0;
  125. virtual unsigned queryLine() = 0;
  126. virtual offset_t queryOffset() = 0;
  127. virtual const char *queryContext() = 0;
  128. };
  129. extern jlib_decl IPTreeReadException *createPTreeReadException(int code, const char *msg, const char *context, unsigned line, offset_t offset);
  130. enum PTreeReaderOptions { ptr_none=0x00, ptr_ignoreWhiteSpace=0x01, ptr_noRoot=0x02, ptr_ignoreNameSpaces=0x04 };
  131. interface IPTreeReader : extends IInterface
  132. {
  133. virtual void load() = 0;
  134. virtual offset_t queryOffset() = 0;
  135. };
  136. interface IPullPTreeReader : extends IPTreeReader
  137. {
  138. virtual bool next() = 0;
  139. virtual void reset() = 0;
  140. };
  141. interface IPTreeMaker : extends IPTreeNotifyEvent
  142. {
  143. virtual IPropertyTree *queryRoot() = 0;
  144. virtual IPropertyTree *queryCurrentNode() = 0;
  145. virtual void reset() = 0;
  146. virtual IPropertyTree *create(const char *tag) = 0;
  147. };
  148. interface IPTreeNodeCreator : extends IInterface
  149. {
  150. virtual IPropertyTree *create(const char *tag) = 0;
  151. };
  152. enum ipt_flags
  153. {
  154. ipt_none=0x00,
  155. ipt_caseInsensitive=0x01,
  156. ipt_binary = 0x02,
  157. ipt_ordered = 0x04, // Preserve element ordering
  158. ipt_fast = 0x08, // Prioritize speed over low memory usage
  159. ipt_lowmem = 0x10, // Prioritize low memory usage over speed
  160. ipt_ext3 = 0x20, // Unused
  161. ipt_ext4 = 0x40, // Used internally in Dali
  162. ipt_ext5 = 0x80 // Used internally in Dali
  163. };
  164. jlib_decl IPTreeMaker *createPTreeMaker(byte flags=ipt_none, IPropertyTree *root=NULL, IPTreeNodeCreator *nodeCreator=NULL);
  165. jlib_decl IPTreeMaker *createRootLessPTreeMaker(byte flags=ipt_none, IPropertyTree *root=NULL, IPTreeNodeCreator *nodeCreator=NULL);
  166. jlib_decl IPTreeReader *createXMLStreamReader(ISimpleReadStream &stream, IPTreeNotifyEvent &iEvent, PTreeReaderOptions xmlReaderOptions=ptr_ignoreWhiteSpace, size32_t bufSize=0);
  167. jlib_decl IPTreeReader *createXMLStringReader(const char *xml, IPTreeNotifyEvent &iEvent, PTreeReaderOptions xmlReaderOptions=ptr_ignoreWhiteSpace);
  168. jlib_decl IPTreeReader *createXMLBufferReader(const void *buf, size32_t bufLength, IPTreeNotifyEvent &iEvent, PTreeReaderOptions xmlReaderOptions=ptr_ignoreWhiteSpace);
  169. jlib_decl IPullPTreeReader *createPullXMLStreamReader(ISimpleReadStream &stream, IPTreeNotifyEvent &iEvent, PTreeReaderOptions xmlReaderOptions=ptr_ignoreWhiteSpace, size32_t bufSize=0);
  170. jlib_decl IPullPTreeReader *createPullXMLStringReader(const char *xml, IPTreeNotifyEvent &iEvent, PTreeReaderOptions xmlReaderOptions=ptr_ignoreWhiteSpace);
  171. jlib_decl IPullPTreeReader *createPullXMLBufferReader(const void *buf, size32_t bufLength, IPTreeNotifyEvent &iEvent, PTreeReaderOptions xmlReaderOptions=ptr_ignoreWhiteSpace);
  172. jlib_decl IPTreeReader *createJSONStreamReader(ISimpleReadStream &stream, IPTreeNotifyEvent &iEvent, PTreeReaderOptions readerOptions=ptr_ignoreWhiteSpace, size32_t bufSize=0);
  173. jlib_decl IPTreeReader *createJSONStringReader(const char *json, IPTreeNotifyEvent &iEvent, PTreeReaderOptions readerOptions=ptr_ignoreWhiteSpace);
  174. jlib_decl IPTreeReader *createJSONBufferReader(const void *buf, size32_t bufLength, IPTreeNotifyEvent &iEvent, PTreeReaderOptions jsonReaderOptions=ptr_ignoreWhiteSpace);
  175. jlib_decl IPullPTreeReader *createPullJSONStreamReader(ISimpleReadStream &stream, IPTreeNotifyEvent &iEvent, PTreeReaderOptions readerOptions=ptr_ignoreWhiteSpace, size32_t bufSize=0);
  176. jlib_decl IPullPTreeReader *createPullJSONStringReader(const char *json, IPTreeNotifyEvent &iEvent, PTreeReaderOptions readerOptions=ptr_ignoreWhiteSpace);
  177. jlib_decl IPullPTreeReader *createPullJSONBufferReader(const void *buf, size32_t bufLength, IPTreeNotifyEvent &iEvent, PTreeReaderOptions readerOptions=ptr_ignoreWhiteSpace);
  178. jlib_decl void mergePTree(IPropertyTree *target, IPropertyTree *toMerge);
  179. jlib_decl void synchronizePTree(IPropertyTree *target, IPropertyTree *source, bool removeTargetsNotInSource=true, bool rootsMustMatch=true);
  180. jlib_decl IPropertyTree *ensurePTree(IPropertyTree *root, const char *xpath);
  181. jlib_decl bool areMatchingPTrees(const IPropertyTree * left, const IPropertyTree * right);
  182. jlib_decl IPropertyTree *createPTree(MemoryBuffer &src, byte flags=ipt_none);
  183. jlib_decl IPropertyTree *createPTree(byte flags=ipt_none);
  184. jlib_decl IPropertyTree *createPTree(const char *name, byte flags=ipt_none);
  185. jlib_decl IPropertyTree *createPTree(IFile &ifile, byte flags=ipt_none, PTreeReaderOptions readFlags=ptr_ignoreWhiteSpace, IPTreeMaker *iMaker=NULL);
  186. jlib_decl IPropertyTree *createPTree(IFileIO &ifileio, byte flags=ipt_none, PTreeReaderOptions readFlags=ptr_ignoreWhiteSpace, IPTreeMaker *iMaker=NULL);
  187. jlib_decl IPropertyTree *createPTree(ISimpleReadStream &stream, byte flags=ipt_none, PTreeReaderOptions readFlags=ptr_ignoreWhiteSpace, IPTreeMaker *iMaker=NULL);
  188. jlib_decl IPropertyTree *createPTreeFromXMLString(const char *xml, byte flags=ipt_none, PTreeReaderOptions readFlags=ptr_ignoreWhiteSpace, IPTreeMaker *iMaker=NULL);
  189. jlib_decl IPropertyTree *createPTreeFromXMLString(unsigned len, const char *xml, byte flags=ipt_none, PTreeReaderOptions readFlags=ptr_ignoreWhiteSpace, IPTreeMaker *iMaker=NULL);
  190. jlib_decl IPropertyTree *createPTreeFromXMLFile(const char *filename, byte flags=ipt_none, PTreeReaderOptions readFlags=ptr_ignoreWhiteSpace, IPTreeMaker *iMaker=NULL);
  191. jlib_decl IPropertyTree *createPTreeFromIPT(const IPropertyTree *srcTree, ipt_flags flags=ipt_none);
  192. jlib_decl IPropertyTree *createPTreeFromJSONString(const char *json, byte flags=ipt_none, PTreeReaderOptions readFlags=ptr_ignoreWhiteSpace, IPTreeMaker *iMaker=NULL);
  193. jlib_decl IPropertyTree *createPTreeFromJSONString(unsigned len, const char *json, byte flags=ipt_none, PTreeReaderOptions readFlags=ptr_ignoreWhiteSpace, IPTreeMaker *iMaker=NULL);
  194. //URL node nameWithAttrs is of the form: "TagName/attr1('abc')/attr2/attr3('')"
  195. jlib_decl IPropertyTree *createPTreeFromHttpPath(const char *nameWithAttrs, IPropertyTree *content, bool nestedRoot, ipt_flags flags);
  196. jlib_decl IPropertyTree *createPTreeFromHttpParameters(const char *nameWithAttrs, IProperties *parameters, bool skipLeadingDotParameters, bool nestedRoot, ipt_flags flags=ipt_none);
  197. jlib_decl bool checkParseUrlPathNodeValue(const char *s, StringBuffer &name, StringAttr &value);
  198. typedef int (*TreeCompareFunc)(IInterface * const *ll, IInterface * const *rr);
  199. jlib_decl IPropertyTreeIterator * createSortedIterator(IPropertyTreeIterator & iter, TreeCompareFunc compare);
  200. jlib_decl IPropertyTreeIterator * createSortedIterator(IArrayOf<IPropertyTree> & ownedElems, TreeCompareFunc compare);
  201. #define XML_SortTags 0x01
  202. #define XML_Embed 0x02
  203. #define XML_NoEncode 0x04
  204. #define XML_Sanitize 0x08
  205. #define XML_SanitizeAttributeValues 0x10
  206. #define XML_SingleQuoteAttributeValues 0x20
  207. #define XML_NoBinaryEncode64 0x40
  208. #define XML_LineBreak 0x100
  209. #define XML_LineBreakAttributes 0x80
  210. #define XML_Format (XML_Embed|XML_LineBreakAttributes|XML_LineBreak)
  211. jlib_decl StringBuffer &toXML(const IPropertyTree *tree, StringBuffer &ret, unsigned indent = 0, unsigned flags=XML_Format);
  212. jlib_decl void toXML(const IPropertyTree *tree, IIOStream &out, unsigned indent = 0, unsigned flags=XML_Format);
  213. jlib_decl void saveXML(const char *filename, const IPropertyTree *tree, unsigned indent = 0, unsigned flags=XML_Format);
  214. jlib_decl void saveXML(IFile &ifile, const IPropertyTree *tree, unsigned indent = 0, unsigned=XML_Format);
  215. jlib_decl void saveXML(IFileIO &ifileio, const IPropertyTree *tree, unsigned indent = 0, unsigned flags=XML_Format);
  216. jlib_decl void saveXML(IIOStream &stream, const IPropertyTree *tree, unsigned indent = 0, unsigned flags=XML_Format);
  217. jlib_decl void printXML(const IPropertyTree *tree, unsigned indent = 0, unsigned flags=XML_Format);
  218. jlib_decl void dbglogXML(const IPropertyTree *tree, unsigned indent = 0, unsigned flags=XML_Format);
  219. #define JSON_SortTags XML_SortTags
  220. #define JSON_Format 0x02
  221. #define JSON_HideRootArrayObject 0x04
  222. #define JSON_Sanitize XML_Sanitize
  223. #define JSON_SanitizeAttributeValues XML_SanitizeAttributeValues
  224. jlib_decl StringBuffer &toJSON(const IPropertyTree *tree, StringBuffer &ret, unsigned indent = 0, byte flags=JSON_Format|JSON_HideRootArrayObject);
  225. jlib_decl void toJSON(const IPropertyTree *tree, IIOStream &out, unsigned indent = 0, byte flags=JSON_Format|JSON_HideRootArrayObject);
  226. jlib_decl void printJSON(const IPropertyTree *tree, unsigned indent = 0, byte flags=JSON_Format|JSON_HideRootArrayObject);
  227. jlib_decl void dbglogJSON(const IPropertyTree *tree, unsigned indent = 0, byte flags=JSON_Format|JSON_HideRootArrayObject);
  228. jlib_decl const char *splitXPath(const char *xpath, StringBuffer &head); // returns tail, fills 'head' with leading xpath
  229. jlib_decl bool validateXPathSyntax(const char *xpath, StringBuffer *error=NULL);
  230. jlib_decl bool validateXMLParseXPath(const char *xpath, StringBuffer *error=NULL);
  231. jlib_decl IPropertyTree *getXPathMatchTree(IPropertyTree &parent, const char *xpath);
  232. jlib_decl IPropertyTreeIterator *createNullPTreeIterator();
  233. jlib_decl bool isEmptyPTree(IPropertyTree *t);
  234. jlib_decl void extractJavadoc(IPropertyTree * result, const char * text); // Pass in a javadoc style comment (without head/tail) and extract information into a property tree.
  235. typedef IPropertyTree IPTree;
  236. typedef IPropertyTreeIterator IPTreeIterator;
  237. typedef Owned<IPTree> OwnedPTree;
  238. // http://www.w3.org/TR/REC-xml#xml-names
  239. static const char *validStartChrs = ":_";
  240. inline static bool isValidXPathStartChr(char c)
  241. {
  242. return ('\0' != c && (isalpha(c) || strchr(validStartChrs, c)));
  243. }
  244. static const char *validChrs = ":_.-";
  245. inline static bool isValidXPathChr(char c)
  246. {
  247. return ('\0' != c && (isalnum(c) || strchr(validChrs, c)));
  248. }
  249. //export for unit test
  250. jlib_decl void mergeConfiguration(IPropertyTree & target, IPropertyTree & source, const char *altNameAttribute=nullptr);
  251. jlib_decl IPropertyTree * loadArgsIntoConfiguration(IPropertyTree *config, const char * * argv, std::initializer_list<const char *> ignoreOptions = {});
  252. jlib_decl IPropertyTree * loadConfiguration(IPropertyTree * defaultConfig, const char * * argv, const char * componentTag, const char * envPrefix, const char * legacyFilename, IPropertyTree * (mapper)(IPropertyTree *), const char *altNameAttribute=nullptr);
  253. jlib_decl IPropertyTree * loadConfiguration(const char * defaultYaml, const char * * argv, const char * componentTag, const char * envPrefix, const char * legacyFilename, IPropertyTree * (mapper)(IPropertyTree *), const char *altNameAttribute=nullptr);
  254. jlib_decl IPropertyTree * queryCostsConfiguration();
  255. //The following can only be called after loadConfiguration has been called. All components must call loadConfiguration().
  256. jlib_decl IPropertyTree & queryGlobalConfig();
  257. jlib_decl IPropertyTree & queryComponentConfig();
  258. /*
  259. YAML to PTree support
  260. By default YAML scalars become PTree attributes unless the YAML has an !element or !el YAML tag specifying that the scalar
  261. should be treated as an element. Mixed content can be represented in YAML using a scalar named "^" also using the !el YAML tag
  262. Person:
  263. name: Adam Smith
  264. note: Father of Economics
  265. Becomes:
  266. <Person name="Adam Smith" note="Father of Economics"/>
  267. Person:
  268. name: Adam Smith
  269. note: !el Father of Economics
  270. Becomes:
  271. <Person name="Adam Smith">
  272. <note>Father of Economics</note>
  273. </Person>
  274. Person:
  275. name: Adam Smith
  276. ^: !el Father of Economics
  277. Becomes:
  278. <Person name="Adam Smith">Father of Economics<Person/>
  279. */
  280. jlib_decl IPropertyTree *createPTreeFromYAMLString(const char *yaml, byte flags=ipt_none, PTreeReaderOptions readFlags=ptr_ignoreWhiteSpace, IPTreeMaker *iMaker=NULL);
  281. jlib_decl IPropertyTree *createPTreeFromYAMLString(unsigned len, const char *yaml, byte flags=ipt_none, PTreeReaderOptions readFlags=ptr_ignoreWhiteSpace, IPTreeMaker *iMaker=NULL);
  282. jlib_decl IPropertyTree *createPTreeFromYAMLFile(const char *filename, byte flags=ipt_none, PTreeReaderOptions readFlags=ptr_ignoreWhiteSpace, IPTreeMaker *iMaker=NULL);
  283. #define YAML_HideRootArrayObject 0x04
  284. #define YAML_SortTags XML_SortTags
  285. #define YAML_Sanitize XML_Sanitize
  286. #define YAML_SanitizeAttributeValues XML_SanitizeAttributeValues
  287. jlib_decl StringBuffer &toYAML(const IPropertyTree *tree, StringBuffer &ret, unsigned indent, byte flags);
  288. jlib_decl void toYAML(const IPropertyTree *tree, IIOStream &out, unsigned indent, byte flags);
  289. jlib_decl void saveYAML(const char *filename, const IPropertyTree *tree, unsigned indent = 0, unsigned flags=YAML_HideRootArrayObject);
  290. jlib_decl void saveYAML(IFile &ifile, const IPropertyTree *tree, unsigned indent = 0, unsigned=YAML_HideRootArrayObject);
  291. jlib_decl void saveYAML(IFileIO &ifileio, const IPropertyTree *tree, unsigned indent = 0, unsigned flags=YAML_HideRootArrayObject);
  292. jlib_decl void saveYAML(IIOStream &stream, const IPropertyTree *tree, unsigned indent = 0, unsigned flags=YAML_HideRootArrayObject);
  293. jlib_decl void printYAML(const IPropertyTree *tree, unsigned indent = 0, unsigned flags=YAML_HideRootArrayObject);
  294. jlib_decl void dbglogYAML(const IPropertyTree *tree, unsigned indent = 0, unsigned flags=YAML_HideRootArrayObject);
  295. #endif