thorxmlwrite.hpp 25 KB

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