rtlformat.hpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. #ifndef ECLFORMAT_HPP
  2. #define ECLFORMAT_HPP
  3. #include "jiface.hpp"
  4. #include "jfile.hpp"
  5. #include "eclrtl.hpp"
  6. #include "eclhelper.hpp"
  7. interface IXmlWriterExt : extends IXmlWriter
  8. {
  9. virtual IXmlWriterExt & clear() = 0;
  10. virtual size32_t length() const = 0;
  11. virtual const char *str() const = 0;
  12. virtual IInterface *saveLocation() const = 0;
  13. virtual void rewindTo(IInterface *location) = 0;
  14. virtual void cutFrom(IInterface *location, StringBuffer& databuf) = 0;
  15. virtual void outputNumericString(const char *field, const char *fieldname) = 0;
  16. virtual void outputInline(const char* text) = 0;
  17. virtual void finalize() = 0;
  18. };
  19. class ECLRTL_API SimpleOutputWriter : implements IXmlWriterExt, public CInterface
  20. {
  21. void outputFieldSeparator();
  22. bool separatorNeeded;
  23. public:
  24. SimpleOutputWriter();
  25. IMPLEMENT_IINTERFACE;
  26. virtual SimpleOutputWriter & clear() override;
  27. virtual size32_t length() const override { return out.length(); }
  28. virtual const char * str() const override { return out.str(); }
  29. virtual void finalize() override {}
  30. virtual void outputQuoted(const char *text) override;
  31. virtual void outputQString(unsigned len, const char *field, const char *fieldname) override;
  32. virtual void outputString(unsigned len, const char *field, const char *fieldname) override;
  33. virtual void outputBool(bool field, const char *fieldname) override;
  34. virtual void outputData(unsigned len, const void *field, const char *fieldname) override;
  35. virtual void outputReal(double field, const char *fieldname) override;
  36. virtual void outputDecimal(const void *field, unsigned size, unsigned precision, const char *fieldname) override;
  37. virtual void outputUDecimal(const void *field, unsigned size, unsigned precision, const char *fieldname) override;
  38. virtual void outputUnicode(unsigned len, const UChar *field, const char *fieldname) override;
  39. virtual void outputUtf8(unsigned len, const char *field, const char *fieldname) override;
  40. virtual void outputBeginNested(const char *fieldname, bool nestChildren) override;
  41. virtual void outputEndNested(const char *fieldname) override;
  42. virtual void outputBeginDataset(const char *dsname, bool nestChildren) override {}
  43. virtual void outputEndDataset(const char *dsname) override {}
  44. virtual void outputBeginArray(const char *fieldname) override {}
  45. virtual void outputEndArray(const char *fieldname) override {}
  46. virtual void outputSetAll() override;
  47. virtual void outputInlineXml(const char *text) override {} //for appending raw xml content
  48. virtual void outputXmlns(const char *name, const char *uri) override {}
  49. virtual void outputInt(__int64 field, unsigned size, const char *fieldname) override;
  50. virtual void outputUInt(unsigned __int64 field, unsigned size, const char *fieldname) override;
  51. void newline();
  52. virtual IInterface *saveLocation() const override { UNIMPLEMENTED; }
  53. virtual void rewindTo(IInterface *location) override { UNIMPLEMENTED; }
  54. virtual void cutFrom(IInterface *location, StringBuffer& databuf) override { UNIMPLEMENTED; }
  55. virtual void outputNumericString(const char *field, const char *fieldname) override { UNIMPLEMENTED; }
  56. virtual void outputInline(const char* text) override { UNIMPLEMENTED; }
  57. protected:
  58. StringBuffer out;
  59. };
  60. interface IXmlStreamFlusher
  61. {
  62. virtual void flushXML(StringBuffer &current, bool isClose) = 0;
  63. };
  64. class ECLRTL_API CommonXmlPosition : public CInterface, implements IInterface
  65. {
  66. public:
  67. IMPLEMENT_IINTERFACE;
  68. CommonXmlPosition(size32_t _pos, unsigned _indent, unsigned _nestLimit, bool _tagClosed, bool _needDelimiter) :
  69. pos(_pos), indent(_indent), nestLimit(_nestLimit), tagClosed(_tagClosed), needDelimiter(_needDelimiter)
  70. {}
  71. public:
  72. size32_t pos = 0;
  73. unsigned indent = 0;
  74. unsigned nestLimit = 0;
  75. bool tagClosed = false;
  76. bool needDelimiter = false;
  77. };
  78. class ECLRTL_API CommonXmlWriter : implements IXmlWriterExt, public CInterface
  79. {
  80. public:
  81. CommonXmlWriter(unsigned _flags, unsigned initialIndent=0, IXmlStreamFlusher *_flusher=NULL);
  82. ~CommonXmlWriter();
  83. IMPLEMENT_IINTERFACE;
  84. void outputBeginNested(const char *fieldname, bool nestChildren, bool doIndent);
  85. void outputEndNested(const char *fieldname, bool doIndent);
  86. virtual void outputInlineXml(const char *text){closeTag(); out.append(text); flush(false);} //for appending raw xml content
  87. virtual void outputInline(const char* text) { outputInlineXml(text); }
  88. virtual void outputQuoted(const char *text);
  89. virtual void outputQString(unsigned len, const char *field, const char *fieldname);
  90. virtual void outputString(unsigned len, const char *field, const char *fieldname);
  91. virtual void outputBool(bool field, const char *fieldname);
  92. virtual void outputData(unsigned len, const void *field, const char *fieldname);
  93. virtual void outputInt(__int64 field, unsigned size, const char *fieldname);
  94. virtual void outputUInt(unsigned __int64 field, unsigned size, const char *fieldname);
  95. virtual void outputReal(double field, const char *fieldname);
  96. virtual void outputDecimal(const void *field, unsigned size, unsigned precision, const char *fieldname);
  97. virtual void outputUDecimal(const void *field, unsigned size, unsigned precision, const char *fieldname);
  98. virtual void outputUnicode(unsigned len, const UChar *field, const char *fieldname);
  99. virtual void outputUtf8(unsigned len, const char *field, const char *fieldname);
  100. virtual void outputBeginDataset(const char *dsname, bool nestChildren);
  101. virtual void outputEndDataset(const char *dsname);
  102. virtual void outputBeginNested(const char *fieldname, bool nestChildren);
  103. virtual void outputEndNested(const char *fieldname);
  104. virtual void outputBeginArray(const char *fieldname){}; //repeated elements are inline for xml
  105. virtual void outputEndArray(const char *fieldname){};
  106. virtual void outputSetAll();
  107. virtual void outputXmlns(const char *name, const char *uri);
  108. //IXmlWriterExt
  109. virtual IXmlWriterExt & clear();
  110. virtual unsigned length() const { return out.length(); }
  111. virtual const char * str() const { return out.str(); }
  112. virtual void finalize() override {}
  113. virtual IInterface *saveLocation() const
  114. {
  115. if (flusher)
  116. throwUnexpected();
  117. return new CommonXmlPosition(length(), indent, nestLimit, tagClosed, false);
  118. }
  119. virtual void rewindTo(IInterface *saved)
  120. {
  121. if (flusher)
  122. throwUnexpected();
  123. CommonXmlPosition *position = dynamic_cast<CommonXmlPosition *>(saved);
  124. if (!position)
  125. return;
  126. if (position->pos < out.length())
  127. {
  128. out.setLength(position->pos);
  129. tagClosed = position->tagClosed;
  130. indent = position->indent;
  131. nestLimit = position->nestLimit;
  132. }
  133. }
  134. virtual void cutFrom(IInterface *location, StringBuffer& databuf);
  135. virtual void outputNumericString(const char *field, const char *fieldname)
  136. {
  137. outputCString(field, fieldname);
  138. }
  139. protected:
  140. bool checkForAttribute(const char * fieldname);
  141. void closeTag();
  142. inline void flush(bool isClose)
  143. {
  144. if (flusher)
  145. flusher->flushXML(out, isClose);
  146. }
  147. protected:
  148. IXmlStreamFlusher *flusher;
  149. StringBuffer out;
  150. unsigned flags;
  151. unsigned indent;
  152. unsigned nestLimit;
  153. bool tagClosed;
  154. };
  155. class ECLRTL_API CommonJsonWriter : implements IXmlWriterExt, public CInterface
  156. {
  157. public:
  158. CommonJsonWriter(unsigned _flags, unsigned initialIndent=0, IXmlStreamFlusher *_flusher=NULL);
  159. ~CommonJsonWriter();
  160. IMPLEMENT_IINTERFACE;
  161. void checkDelimit(int inc=0);
  162. void checkFormat(bool doDelimit, bool needDelimiter=true, int inc=0);
  163. void prepareBeginArray(const char *fieldname);
  164. virtual void outputInlineXml(const char *text) //for appending raw xml content
  165. {
  166. if (text && *text)
  167. outputUtf8(strlen(text), text, "xml");
  168. }
  169. virtual void outputInline(const char* text) { out.append(text); }
  170. virtual void outputQuoted(const char *text);
  171. virtual void outputQString(unsigned len, const char *field, const char *fieldname);
  172. virtual void outputString(unsigned len, const char *field, const char *fieldname);
  173. virtual void outputBool(bool field, const char *fieldname);
  174. virtual void outputData(unsigned len, const void *field, const char *fieldname);
  175. virtual void outputInt(__int64 field, unsigned size, const char *fieldname);
  176. virtual void outputUInt(unsigned __int64 field, unsigned size, const char *fieldname);
  177. virtual void outputReal(double field, const char *fieldname);
  178. virtual void outputDecimal(const void *field, unsigned size, unsigned precision, const char *fieldname);
  179. virtual void outputUDecimal(const void *field, unsigned size, unsigned precision, const char *fieldname);
  180. virtual void outputUnicode(unsigned len, const UChar *field, const char *fieldname);
  181. virtual void outputUtf8(unsigned len, const char *field, const char *fieldname);
  182. virtual void outputBeginDataset(const char *dsname, bool nestChildren);
  183. virtual void outputEndDataset(const char *dsname);
  184. virtual void outputBeginNested(const char *fieldname, bool nestChildren);
  185. virtual void outputEndNested(const char *fieldname);
  186. virtual void outputBeginArray(const char *fieldname);
  187. virtual void outputEndArray(const char *fieldname);
  188. virtual void outputSetAll();
  189. virtual void outputXmlns(const char *name, const char *uri){}
  190. virtual void outputNumericString(const char *field, const char *fieldname);
  191. //IXmlWriterExt
  192. virtual IXmlWriterExt & clear();
  193. virtual unsigned length() const { return out.length(); }
  194. virtual const char * str() const { return out.str(); }
  195. virtual void finalize() override {}
  196. virtual void rewindTo(unsigned int prevlen) { if (prevlen < out.length()) out.setLength(prevlen); }
  197. virtual IInterface *saveLocation() const
  198. {
  199. if (flusher)
  200. throwUnexpected();
  201. return new CommonXmlPosition(length(), indent, nestLimit, false, needDelimiter);
  202. }
  203. virtual void rewindTo(IInterface *saved)
  204. {
  205. if (flusher)
  206. throwUnexpected();
  207. CommonXmlPosition *position = dynamic_cast<CommonXmlPosition *>(saved);
  208. if (!position)
  209. return;
  210. if (position->pos < out.length())
  211. {
  212. out.setLength(position->pos);
  213. needDelimiter = position->needDelimiter;
  214. indent = position->indent;
  215. nestLimit = position->nestLimit;
  216. }
  217. }
  218. virtual void cutFrom(IInterface *location, StringBuffer& databuf);
  219. void outputBeginRoot(){out.append('{');}
  220. void outputEndRoot(){out.append('}');}
  221. protected:
  222. inline void flush(bool isClose)
  223. {
  224. if (flusher)
  225. flusher->flushXML(out, isClose);
  226. }
  227. class CJsonWriterItem : public CInterface
  228. {
  229. public:
  230. CJsonWriterItem(const char *_name) : name(_name), depth(0){}
  231. StringAttr name;
  232. unsigned depth;
  233. };
  234. const char *checkItemName(CJsonWriterItem *item, const char *name, bool simpleType=true);
  235. const char *checkItemName(const char *name, bool simpleType=true);
  236. const char *checkItemNameBeginNested(const char *name);
  237. const char *checkItemNameEndNested(const char *name);
  238. bool checkUnamedArrayItem(bool begin);
  239. IXmlStreamFlusher *flusher;
  240. CIArrayOf<CJsonWriterItem> arrays;
  241. StringBuffer out;
  242. unsigned flags;
  243. unsigned indent;
  244. unsigned nestLimit;
  245. bool needDelimiter;
  246. };
  247. class ECLRTL_API CommonJsonObjectWriter : public CommonJsonWriter
  248. {
  249. public:
  250. CommonJsonObjectWriter(unsigned _flags, unsigned initialIndent, IXmlStreamFlusher *_flusher) : CommonJsonWriter(_flags, initialIndent, _flusher)
  251. {
  252. outputBeginRoot();
  253. }
  254. ~CommonJsonObjectWriter()
  255. {
  256. if (!final)
  257. outputEndRoot();
  258. }
  259. virtual void finalize() override
  260. {
  261. if (!final)
  262. {
  263. final=true;
  264. outputEndRoot();
  265. }
  266. }
  267. private:
  268. bool final=false;
  269. };
  270. class ECLRTL_API CPropertyTreeWriter : public CSimpleInterfaceOf<IXmlWriter>
  271. {
  272. public:
  273. CPropertyTreeWriter(IPropertyTree *_root=nullptr, unsigned _flags=0);
  274. void setRoot(IPropertyTree &_root);
  275. virtual void outputInlineXml(const char *text) override;
  276. virtual void outputQuoted(const char *text) override;
  277. virtual void outputQString(unsigned len, const char *field, const char *fieldname) override;
  278. virtual void outputString(unsigned len, const char *field, const char *fieldname) override;
  279. virtual void outputBool(bool field, const char *fieldname) override;
  280. virtual void outputData(unsigned len, const void *field, const char *fieldname) override;
  281. virtual void outputInt(__int64 field, unsigned size, const char *fieldname) override;
  282. virtual void outputUInt(unsigned __int64 field, unsigned size, const char *fieldname) override;
  283. virtual void outputReal(double field, const char *fieldname) override;
  284. virtual void outputDecimal(const void *field, unsigned size, unsigned precision, const char *fieldname) override;
  285. virtual void outputUDecimal(const void *field, unsigned size, unsigned precision, const char *fieldname) override;
  286. virtual void outputUnicode(unsigned len, const UChar *field, const char *fieldname) override;
  287. virtual void outputUtf8(unsigned len, const char *field, const char *fieldname) override;
  288. virtual void outputBeginDataset(const char *dsname, bool nestChildren) override;
  289. virtual void outputEndDataset(const char *dsname) override;
  290. virtual void outputBeginNested(const char *fieldname, bool nestChildren) override;
  291. virtual void outputEndNested(const char *fieldname) override;
  292. virtual void outputBeginArray(const char *fieldname) override {}; //repeated elements are inline for xml
  293. virtual void outputEndArray(const char *fieldname) override {};
  294. virtual void outputSetAll();
  295. virtual void outputXmlns(const char *name, const char *uri);
  296. protected:
  297. bool checkForAttribute(const char * fieldname);
  298. protected:
  299. Linked<IPropertyTree> root;
  300. IPropertyTree *target = nullptr;
  301. ICopyArrayOf<IPropertyTree> nestedLevels;
  302. unsigned flags;
  303. };
  304. ECLRTL_API StringBuffer &buildJsonHeader(StringBuffer &header, const char *suppliedHeader, const char *rowTag);
  305. ECLRTL_API StringBuffer &buildJsonFooter(StringBuffer &footer, const char *suppliedFooter, const char *rowTag);
  306. //Writes type encoded XML strings (xsi:type="xsd:string", xsi:type="xsd:boolean" etc)
  307. class ECLRTL_API CommonEncodedXmlWriter : public CommonXmlWriter
  308. {
  309. public:
  310. CommonEncodedXmlWriter(unsigned _flags, unsigned initialIndent=0, IXmlStreamFlusher *_flusher=NULL);
  311. virtual void outputString(unsigned len, const char *field, const char *fieldname);
  312. virtual void outputBool(bool field, const char *fieldname);
  313. virtual void outputData(unsigned len, const void *field, const char *fieldname);
  314. virtual void outputInt(__int64 field, unsigned size, const char *fieldname);
  315. virtual void outputUInt(unsigned __int64 field, unsigned size, const char *fieldname);
  316. virtual void outputReal(double field, const char *fieldname);
  317. virtual void outputDecimal(const void *field, unsigned size, unsigned precision, const char *fieldname);
  318. virtual void outputUDecimal(const void *field, unsigned size, unsigned precision, const char *fieldname);
  319. virtual void outputUnicode(unsigned len, const UChar *field, const char *fieldname);
  320. virtual void outputUtf8(unsigned len, const char *field, const char *fieldname);
  321. };
  322. //Writes all encoded DATA fields as base64Binary
  323. class ECLRTL_API CommonEncoded64XmlWriter : public CommonEncodedXmlWriter
  324. {
  325. public:
  326. CommonEncoded64XmlWriter(unsigned _flags, unsigned initialIndent=0, IXmlStreamFlusher *_flusher=NULL);
  327. virtual void outputData(unsigned len, const void *field, const char *fieldname);
  328. };
  329. enum XMLWriterType{WTStandard, WTEncoding, WTEncodingData64, WTJSONObject, WTJSONRootless} ;
  330. ECLRTL_API CommonXmlWriter * CreateCommonXmlWriter(unsigned _flags, unsigned initialIndent=0, IXmlStreamFlusher *_flusher=NULL, XMLWriterType xmlType=WTStandard);
  331. ECLRTL_API IXmlWriterExt * createIXmlWriterExt(unsigned _flags, unsigned initialIndent=0, IXmlStreamFlusher *_flusher=NULL, XMLWriterType xmlType=WTStandard);
  332. struct CSVOptions
  333. {
  334. StringAttr delimiter, terminator;
  335. bool includeHeader;
  336. };
  337. class CCSVItem : public CInterface, implements IInterface
  338. {
  339. unsigned columnID, nextRowID, rowCount, nestedLayer;
  340. StringAttr name, type, value, parentXPath;
  341. StringArray childNames;
  342. MapStringTo<bool> childNameMap;
  343. bool isNestedItem, simpleNested, currentRowEmpty, outputHeader = false;
  344. public:
  345. CCSVItem() : columnID(0), nestedLayer(0), nextRowID(0), rowCount(0), isNestedItem(false),
  346. simpleNested(false), currentRowEmpty(true) { };
  347. IMPLEMENT_IINTERFACE;
  348. inline const char* getName() const { return name.get(); };
  349. inline void setName(const char* _name) { name.set(_name); };
  350. inline const char* getValue() const { return value.get(); };
  351. inline void setValue(const char* _value) { value.set(_value); };
  352. inline unsigned getColumnID() const { return columnID; };
  353. inline void setColumnID(unsigned _columnID) { columnID = _columnID; };
  354. inline unsigned getNextRowID() const { return nextRowID; };
  355. inline void setNextRowID(unsigned _rowID) { nextRowID = _rowID; };
  356. inline void incrementNextRowID() { nextRowID++; };
  357. inline unsigned getRowCount() const { return rowCount; };
  358. inline void setRowCount(unsigned _rowCount) { rowCount = _rowCount; };
  359. inline void incrementRowCount() { rowCount++; };
  360. inline bool getCurrentRowEmpty() const { return currentRowEmpty; };
  361. inline void setCurrentRowEmpty(bool _currentRowEmpty) { currentRowEmpty = _currentRowEmpty; };
  362. inline unsigned getNestedLayer() const { return nestedLayer; };
  363. inline void setNestedLayer(unsigned _nestedLayer) { nestedLayer = _nestedLayer; };
  364. inline bool checkIsNestedItem() const { return isNestedItem; };
  365. inline void setIsNestedItem(bool _isNestedItem) { isNestedItem = _isNestedItem; };
  366. inline bool checkSimpleNested() const { return simpleNested; };
  367. inline void setSimpleNested(bool _simpleNested) { simpleNested = _simpleNested; };
  368. inline bool checkOutputHeader() const { return outputHeader; };
  369. inline void setOutputHeader(bool _outputHeader) { outputHeader = _outputHeader; };
  370. inline const char* getParentXPath() const { return parentXPath.str(); };
  371. inline void setParentXPath(const char* _parentXPath) { parentXPath.set(_parentXPath); };
  372. inline StringArray& getChildrenNames() { return childNames; };
  373. inline void addChildName(const char* name)
  374. {
  375. if (hasChildName(name))
  376. return;
  377. childNameMap.setValue(name, true);
  378. childNames.append(name);
  379. };
  380. inline bool hasChildName(const char* name)
  381. {
  382. bool* found = childNameMap.getValue(name);
  383. return (found && *found);
  384. };
  385. inline void clearContentVariables()
  386. {
  387. nextRowID = rowCount = 0;
  388. currentRowEmpty = true;
  389. };
  390. };
  391. class CCSVRow : public CInterface, implements IInterface
  392. {
  393. unsigned rowID;
  394. CIArrayOf<CCSVItem> columns;
  395. public:
  396. CCSVRow(unsigned _rowID) : rowID(_rowID) {};
  397. IMPLEMENT_IINTERFACE;
  398. inline unsigned getRowID() const { return rowID; };
  399. inline void setRowID(unsigned _rowID) { rowID = _rowID; };
  400. inline unsigned getColumnCount() const { return columns.length(); };
  401. const char* getColumnValue(unsigned columnID) const;
  402. void setColumn(unsigned columnID, const char* columnName, const char* columnValue);
  403. };
  404. //CommonCSVWriter is used to output a WU result in CSV format.
  405. //Read CSV header information;
  406. //If needed, output CSV headers into the 'out' buffer;
  407. //Read each row (a record) of the WU result and output into the 'out' buffer;
  408. //The 'out' buffer can be accessed through the str() method.
  409. class ECLRTL_API CommonCSVWriter: public CInterface, implements IXmlWriterExt
  410. {
  411. class CXPathItem : public CInterface, implements IInterface
  412. {
  413. bool isArray;
  414. StringAttr path;
  415. public:
  416. CXPathItem(const char* _path, bool _isArray) : path(_path), isArray(_isArray) { };
  417. IMPLEMENT_IINTERFACE;
  418. inline const char* getPath() const { return path.get(); };
  419. inline bool getIsArray() const { return isArray; };
  420. };
  421. CSVOptions options;
  422. bool readingCSVHeader, addingSimpleNestedContent;
  423. unsigned recordCount, headerColumnID, nestedHeaderLayerID;
  424. StringBuffer currentParentXPath, auditOut;
  425. StringArray headerXPathList;
  426. MapStringTo<bool> topHeaderNameMap;
  427. MapStringToMyClass<CCSVItem> csvItems;
  428. CIArrayOf<CCSVRow> contentRowsBuffer;
  429. CIArrayOf<CXPathItem> dataXPath;//xpath in caller
  430. void escapeQuoted(unsigned len, char const* in, StringBuffer& out);
  431. bool checkHeaderName(const char* name);
  432. CCSVItem* getParentCSVItem();
  433. CCSVItem* getCSVItemByFieldName(const char* name);
  434. void addColumnToRow(CIArrayOf<CCSVRow>& rows, unsigned rowID, unsigned colID, const char* columnValue, const char* columnName);
  435. void addCSVHeader(const char* name, const char* type, bool isNested, bool simpleNested, bool outputHeader);
  436. void addContentField(const char* field, const char* fieldName);
  437. void addStringField(unsigned len, const char* field, const char* fieldName);
  438. void setChildrenNextRowID(const char* path, unsigned rowID);
  439. unsigned getChildrenMaxNextRowID(const char* path);
  440. unsigned getChildrenMaxColumnID(CCSVItem* item, unsigned& maxColumnID);
  441. void addChildNameToParentCSVItem(const char* name);
  442. void setParentItemRowEmpty(CCSVItem* item, bool empty);
  443. void addFieldToParentXPath(const char* fieldName);
  444. void removeFieldFromCurrentParentXPath(const char* fieldName);
  445. void appendDataXPathItem(const char* fieldName, bool isArray);
  446. bool isDataRow(const char* fieldName);
  447. void outputCSVRows(CIArrayOf<CCSVRow>& rows, bool isHeader);
  448. void outputHeadersToBuffer();
  449. void finishContentResultRow();
  450. void auditHeaderInfo()
  451. {
  452. ForEachItemIn(i, headerXPathList)
  453. {
  454. const char* path = headerXPathList.item(i);
  455. CCSVItem* item = csvItems.getValue(path);
  456. if (!item)
  457. continue;
  458. if (!item->checkIsNestedItem())
  459. {
  460. auditOut.appendf("dumpHeaderInfo path<%s> next row<%d> col<%d>: name<%s> - value<%s>\n", path, item->getNextRowID(),
  461. item->getColumnID(), item->getName() ? item->getName() : "", item->getValue() ? item->getValue() : "");
  462. }
  463. else
  464. {
  465. auditOut.appendf("dumpHeaderInfo path<%s> next row<%d> col<%d>: name<%s> - value<%s>\n", path, item->getNextRowID(),
  466. item->getColumnID(), item->getName() ? item->getName() : "", item->getValue() ? item->getValue() : "");
  467. }
  468. }
  469. }
  470. public:
  471. CommonCSVWriter(unsigned _flags, CSVOptions& _options, IXmlStreamFlusher* _flusher = NULL);
  472. ~CommonCSVWriter();
  473. IMPLEMENT_IINTERFACE;
  474. inline void flush(bool isClose)
  475. {
  476. if (flusher)
  477. flusher->flushXML(out, isClose);
  478. }
  479. virtual unsigned length() const { return out.length(); }
  480. virtual const char* str() const { return out.str(); }
  481. virtual void finalize() override {}
  482. virtual void rewindTo(IInterface* location) { };
  483. virtual void cutFrom(IInterface *location, StringBuffer& databuf) { };
  484. virtual IInterface* saveLocation() const
  485. {
  486. if (flusher)
  487. throwUnexpected();
  488. return NULL;
  489. };
  490. //IXmlWriter
  491. virtual void outputString(unsigned len, const char* field, const char* fieldName);
  492. virtual void outputBool(bool field, const char* fieldName);
  493. virtual void outputData(unsigned len, const void* field, const char* fieldName);
  494. virtual void outputInt(__int64 field, unsigned size, const char* fieldName);
  495. virtual void outputUInt(unsigned __int64 field, unsigned size, const char* fieldName);
  496. virtual void outputReal(double field, const char *fieldName);
  497. virtual void outputDecimal(const void* field, unsigned size, unsigned precision, const char* fieldName);
  498. virtual void outputUDecimal(const void* field, unsigned size, unsigned precision, const char* fieldName);
  499. virtual void outputUnicode(unsigned len, const UChar* field, const char* fieldName);
  500. virtual void outputQString(unsigned len, const char* field, const char* fieldName);
  501. virtual void outputUtf8(unsigned len, const char* field, const char* fieldName);
  502. virtual void outputBeginNested(const char* fieldName, bool simpleNested);
  503. virtual void outputEndNested(const char* fieldName);
  504. virtual void outputBeginDataset(const char* dsname, bool nestChildren);
  505. virtual void outputEndDataset(const char* dsname);
  506. virtual void outputBeginArray(const char* fieldName);
  507. virtual void outputEndArray(const char* fieldName);
  508. virtual void outputSetAll() { };
  509. virtual void outputXmlns(const char* name, const char* uri) { };
  510. virtual void outputQuoted(const char* text)
  511. {
  512. //No fieldName. Is it valid for CSV?
  513. };
  514. virtual void outputInlineXml(const char* text)//for appending raw xml content
  515. {
  516. //Dynamically add a new header 'xml' and insert the header.
  517. //But, not sure we want to do that for a big WU result.
  518. //if (text && *text)
  519. //outputUtf8(strlen(text), text, "xml");
  520. };
  521. virtual void outputInline(const char* text) { out.append(text); }
  522. //IXmlWriterExt
  523. virtual void outputNumericString(const char* field, const char* fieldName);
  524. virtual IXmlWriterExt& clear();
  525. void outputBeginNested(const char* fieldName, bool simpleNested, bool outputHeader);
  526. void outputEndNested(const char* fieldName, bool outputHeader);
  527. void outputCSVHeader(const char* name, const char* type);
  528. void finishCSVHeaders();
  529. const char* auditStr() const { return auditOut.str(); }
  530. protected:
  531. IXmlStreamFlusher* flusher;
  532. StringBuffer out;
  533. unsigned flags;
  534. };
  535. #endif