PageRenderTime 26ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/Tools/ColladaConverter/Collada15/FCollada/FUtils/FUXmlWriter.cpp

https://bitbucket.org/ardalanaz/dava.framework
C++ | 259 lines | 208 code | 29 blank | 22 comment | 42 complexity | ab97a19124d2bbb48f3c8e08c4f020a8 MD5 | raw file
  1. /*
  2. Copyright (C) 2005-2007 Feeling Software Inc.
  3. Portions of the code are:
  4. Copyright (C) 2005-2007 Sony Computer Entertainment America
  5. MIT License: http://www.opensource.org/licenses/mit-license.php
  6. */
  7. #include "StdAfx.h"
  8. #include "FUXmlWriter.h"
  9. #include "FUXmlParser.h"
  10. #include "FUStringConversion.h"
  11. #define xcT(text) (const xmlChar*) (text)
  12. // To avoid a nasty 'if' for performance reasons, these are tables of the valid characters
  13. static const bool filenameValidityTable[256] =
  14. {
  15. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 0-15
  16. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 16-31
  17. false, false, false, false, false, false, false, false, false, false, false, false, false, true , true , true , // 32-47 [45-47 is '-./']
  18. true , true , true , true , true , true , true , true , true , true , true , false, false, false, false, false, // 48-63 [48-57 are numerals, 58 is ':']
  19. false, true , true , true , true , true , true , true , true , true , true , true , true , true , true , true , // 64-79 [65-79 is 'A'-'O']
  20. true , true , true , true , true , true , true , true , true , true , true , false, false, false, false, true , // 80-95 [80-90 is 'P'-'Z'], 95 is '_']
  21. false, true , true , true , true , true , true , true , true , true , true , true , true , true , true , true , // 96-111 [97-111 is 'a'-'o']
  22. true , true , true , true , true , true , true , true , true , true , true , false, false, false, false, false, // 112-127 [112-122 is 'p'-'z']
  23. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 128-143
  24. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 144-159
  25. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 160-175
  26. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 176-191
  27. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 192-207
  28. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 208-223
  29. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 224-239
  30. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false // 240-255
  31. };
  32. static const bool xmlValidityTable[256] =
  33. {
  34. false, false, false, false, false, false, false, false, false, false, true , false, false, true , false, false, // 0-15 [10 is \n, 13 is \r]
  35. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 16-31
  36. true , true , false, true , true , true , true , false, true , true , true , true , true , true , true , true , // 32-47 [32-33 is ' !', 35-38 is '#$%&', 40-47 is '()*+,-./']
  37. true , true , true , true , true , true , true , true , true , true , true , true , false, true , false, true , // 48-63 [48-57 are numerals, 58-59 is ':;', 61 is '=', 63 is '?']
  38. false, true , true , true , true , true , true , true , true , true , true , true , true , true , true , true , // 64-79 [65-79 is 'A'-'O']
  39. true , true , true , true , true , true , true , true , true , true , true , true , false, true , false, true , // 80-95 [80-90 is 'P'-'Z', 91 is '[', 93 is ']', 95 is '_']
  40. false, true , true , true , true , true , true , true , true , true , true , true , true , true , true , true , // 96-111 [97-111 is 'a'-'o']
  41. true , true , true , true , true , true , true , true , true , true , true , true , true , true , false, false, // 112-127 [112-122 is 'p'-'z', 123-125 is '{|}']
  42. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 128-143
  43. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 144-159
  44. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 160-175
  45. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 176-191
  46. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 192-207
  47. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 208-223
  48. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 224-239
  49. false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false // 240-255
  50. };
  51. namespace FUXmlWriter
  52. {
  53. // Create a new XML tree node
  54. xmlNode* CreateNode(const char* name)
  55. {
  56. return xmlNewNode(NULL, xcT(name));
  57. }
  58. void RenameNode(xmlNode* node, const char* newName)
  59. {
  60. xmlNodeSetName(node, xcT(newName));
  61. }
  62. // Create a new XML tree child node, parented to the given XML tree node
  63. void AddChild(xmlNode* parent, xmlNode* child)
  64. {
  65. xmlAddChild(parent, child);
  66. }
  67. xmlNode* AddChild(xmlNode* parent, const char* name)
  68. {
  69. return (parent != NULL) ? xmlNewChild(parent, NULL, xcT(name), NULL) : NULL;
  70. }
  71. xmlNode* AddChild(xmlNode* parent, const char* name, const char* content)
  72. {
  73. xmlNode* node = AddChild(parent, name);
  74. if (node != NULL && content != NULL && *content != 0) AddContent(node, content);
  75. return node;
  76. }
  77. #ifdef UNICODE
  78. xmlNode* AddChild(xmlNode* parent, const char* name, const fstring& content)
  79. {
  80. fm::string s = FUStringConversion::ToString(content);
  81. return AddChild(parent, name, !s.empty() ? s.c_str() : NULL);
  82. }
  83. #endif
  84. xmlNode* AddChildOnce(xmlNode* parent, const char* name, const char* content)
  85. {
  86. xmlNode* node = NULL;
  87. if (parent != NULL)
  88. {
  89. node = FUXmlParser::FindChildByType(parent, name);
  90. if (node == NULL) node = AddChild(parent, name, (content == NULL || *content == 0) ? NULL : content);
  91. }
  92. return node;
  93. }
  94. // Create/Append a new XML tree node, as a sibling to a given XML tree node
  95. void AddSibling(xmlNode* sibling, xmlNode* dangling)
  96. {
  97. xmlAddSibling(sibling, dangling);
  98. }
  99. xmlNode* AddSibling(xmlNode* node, const char* name)
  100. {
  101. xmlNode* n = CreateNode(name);
  102. AddSibling(node, n);
  103. return n;
  104. }
  105. xmlNode* InsertChild(xmlNode* parent, xmlNode* sibling, const char* name)
  106. {
  107. xmlNode* n;
  108. if (sibling == NULL || sibling->parent != parent)
  109. {
  110. n = AddChild(parent, name);
  111. }
  112. else
  113. {
  114. n = xmlAddPrevSibling(sibling, CreateNode(name));
  115. }
  116. return n;
  117. }
  118. void AddContent(xmlNode* node, const char* content)
  119. {
  120. if (node != NULL)
  121. {
  122. // Look for non-UTF8 characters that will need to be converted to %XXXX.
  123. FUSStringBuilder xmlSBuilder;
  124. const char* str = content;
  125. char c;
  126. for (; (c = *str) != 0; ++str)
  127. {
  128. // For performance reason, use a look-up table.
  129. if (xmlValidityTable[(uint8) c])
  130. {
  131. // Valid characters
  132. xmlSBuilder.append(c);
  133. }
  134. else
  135. {
  136. // Remove any invalid character(s) in the filename using the %X guideline
  137. xmlSBuilder.append((char) '%');
  138. xmlSBuilder.appendHex((uint8) c);
  139. }
  140. }
  141. xmlNodeAddContent(node, xcT(xmlSBuilder.ToCharPtr()));
  142. }
  143. }
  144. #ifdef UNICODE
  145. void AddContent(xmlNode* node, const fstring& content)
  146. {
  147. fm::string s = FUStringConversion::ToString(content);
  148. AddContent(node, s.c_str());
  149. }
  150. #endif
  151. // Converts all the spaces into %20.
  152. void ConvertFilename(fstring& str)
  153. {
  154. FUStringBuilder xmlBuilder;
  155. const fchar* s = str.c_str();
  156. fchar c;
  157. for (; (c = *s) != 0; ++s)
  158. {
  159. if (filenameValidityTable[(uint8) c]) xmlBuilder.append(c);
  160. else
  161. {
  162. xmlBuilder.append((fchar) '%');
  163. xmlBuilder.appendHex((uint8) c);
  164. }
  165. }
  166. str = xmlBuilder.ToString();
  167. }
  168. void AddContentUnprocessed(xmlNode* node, const char* content)
  169. {
  170. if (node != NULL) xmlNodeAddContent(node, xcT(content));
  171. }
  172. void AddAttribute(xmlNode* node, const char* attributeName, const char* value)
  173. {
  174. if (node != NULL)
  175. {
  176. xmlNewProp(node, xcT(attributeName), xcT(value));
  177. }
  178. }
  179. #ifdef UNICODE
  180. void AddAttribute(xmlNode* node, const char* attributeName, const fstring& attributeValue)
  181. {
  182. fm::string s = FUStringConversion::ToString(attributeValue);
  183. AddAttribute(node, attributeName, s.c_str());
  184. }
  185. #endif
  186. void RemoveAttribute(xmlNode* node, const char* attributeName)
  187. {
  188. xmlAttrPtr ptr = xmlHasProp(node, xcT(attributeName));
  189. xmlRemoveProp(ptr);
  190. }
  191. // Insert a child, respecting lexical ordering
  192. void AddChildSorted(xmlNode* parent, xmlNode* child)
  193. {
  194. // Do an insertion sort in alphabetical order of the element names.
  195. // Walk backward from the last child, to make sure that
  196. // the chronological ordering of elements of the same type is respected.
  197. //
  198. for (xmlNode* p = xmlGetLastChild(parent); p != NULL; p = p->prev)
  199. {
  200. if (p->type != XML_ELEMENT_NODE) continue;
  201. if (strcmp((const char*) p->name, (const char*) child->name) <= 0)
  202. {
  203. xmlAddNextSibling(p, child);
  204. return;
  205. }
  206. }
  207. // Add to the top of the list.
  208. if (parent->children && parent->children->type == XML_ELEMENT_NODE)
  209. {
  210. xmlAddPrevSibling(parent->children, child);
  211. }
  212. else
  213. {
  214. AddChild(parent, child);
  215. }
  216. }
  217. xmlNode* AddChildSorted(xmlNode* parent, const char* name, const char* content)
  218. {
  219. xmlNode* node = CreateNode(name);
  220. if (content != NULL && *content != 0) AddContent(node, content);
  221. AddChildSorted(parent, node);
  222. return node;
  223. }
  224. void ReParentNode(xmlNode* node, xmlNode* newParent)
  225. {
  226. xmlUnlinkNode(node);
  227. AddChild(newParent, node);
  228. }
  229. };