/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
- /*
- Copyright (C) 2005-2007 Feeling Software Inc.
- Portions of the code are:
- Copyright (C) 2005-2007 Sony Computer Entertainment America
-
- MIT License: http://www.opensource.org/licenses/mit-license.php
- */
-
- #include "StdAfx.h"
- #include "FUXmlWriter.h"
- #include "FUXmlParser.h"
- #include "FUStringConversion.h"
-
- #define xcT(text) (const xmlChar*) (text)
-
- // To avoid a nasty 'if' for performance reasons, these are tables of the valid characters
- static const bool filenameValidityTable[256] =
- {
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 0-15
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 16-31
- false, false, false, false, false, false, false, false, false, false, false, false, false, true , true , true , // 32-47 [45-47 is '-./']
- true , true , true , true , true , true , true , true , true , true , true , false, false, false, false, false, // 48-63 [48-57 are numerals, 58 is ':']
- false, true , true , true , true , true , true , true , true , true , true , true , true , true , true , true , // 64-79 [65-79 is 'A'-'O']
- 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 '_']
- false, true , true , true , true , true , true , true , true , true , true , true , true , true , true , true , // 96-111 [97-111 is 'a'-'o']
- true , true , true , true , true , true , true , true , true , true , true , false, false, false, false, false, // 112-127 [112-122 is 'p'-'z']
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 128-143
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 144-159
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 160-175
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 176-191
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 192-207
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 208-223
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 224-239
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false // 240-255
- };
-
- static const bool xmlValidityTable[256] =
- {
- false, false, false, false, false, false, false, false, false, false, true , false, false, true , false, false, // 0-15 [10 is \n, 13 is \r]
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 16-31
- 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 '()*+,-./']
- 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 '?']
- false, true , true , true , true , true , true , true , true , true , true , true , true , true , true , true , // 64-79 [65-79 is 'A'-'O']
- 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 '_']
- false, true , true , true , true , true , true , true , true , true , true , true , true , true , true , true , // 96-111 [97-111 is 'a'-'o']
- 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 '{|}']
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 128-143
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 144-159
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 160-175
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 176-191
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 192-207
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 208-223
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, // 224-239
- false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false // 240-255
- };
-
- namespace FUXmlWriter
- {
-
- // Create a new XML tree node
- xmlNode* CreateNode(const char* name)
- {
- return xmlNewNode(NULL, xcT(name));
- }
-
- void RenameNode(xmlNode* node, const char* newName)
- {
- xmlNodeSetName(node, xcT(newName));
- }
-
- // Create a new XML tree child node, parented to the given XML tree node
- void AddChild(xmlNode* parent, xmlNode* child)
- {
- xmlAddChild(parent, child);
- }
-
- xmlNode* AddChild(xmlNode* parent, const char* name)
- {
- return (parent != NULL) ? xmlNewChild(parent, NULL, xcT(name), NULL) : NULL;
- }
-
- xmlNode* AddChild(xmlNode* parent, const char* name, const char* content)
- {
- xmlNode* node = AddChild(parent, name);
- if (node != NULL && content != NULL && *content != 0) AddContent(node, content);
- return node;
- }
-
- #ifdef UNICODE
- xmlNode* AddChild(xmlNode* parent, const char* name, const fstring& content)
- {
- fm::string s = FUStringConversion::ToString(content);
- return AddChild(parent, name, !s.empty() ? s.c_str() : NULL);
- }
- #endif
-
- xmlNode* AddChildOnce(xmlNode* parent, const char* name, const char* content)
- {
- xmlNode* node = NULL;
- if (parent != NULL)
- {
- node = FUXmlParser::FindChildByType(parent, name);
- if (node == NULL) node = AddChild(parent, name, (content == NULL || *content == 0) ? NULL : content);
- }
- return node;
- }
-
- // Create/Append a new XML tree node, as a sibling to a given XML tree node
- void AddSibling(xmlNode* sibling, xmlNode* dangling)
- {
- xmlAddSibling(sibling, dangling);
- }
-
- xmlNode* AddSibling(xmlNode* node, const char* name)
- {
- xmlNode* n = CreateNode(name);
- AddSibling(node, n);
- return n;
- }
-
- xmlNode* InsertChild(xmlNode* parent, xmlNode* sibling, const char* name)
- {
- xmlNode* n;
- if (sibling == NULL || sibling->parent != parent)
- {
- n = AddChild(parent, name);
- }
- else
- {
- n = xmlAddPrevSibling(sibling, CreateNode(name));
- }
- return n;
- }
-
- void AddContent(xmlNode* node, const char* content)
- {
- if (node != NULL)
- {
- // Look for non-UTF8 characters that will need to be converted to %XXXX.
- FUSStringBuilder xmlSBuilder;
- const char* str = content;
- char c;
- for (; (c = *str) != 0; ++str)
- {
- // For performance reason, use a look-up table.
- if (xmlValidityTable[(uint8) c])
- {
- // Valid characters
- xmlSBuilder.append(c);
- }
- else
- {
- // Remove any invalid character(s) in the filename using the %X guideline
- xmlSBuilder.append((char) '%');
- xmlSBuilder.appendHex((uint8) c);
- }
- }
-
- xmlNodeAddContent(node, xcT(xmlSBuilder.ToCharPtr()));
- }
- }
-
- #ifdef UNICODE
- void AddContent(xmlNode* node, const fstring& content)
- {
- fm::string s = FUStringConversion::ToString(content);
- AddContent(node, s.c_str());
- }
- #endif
-
- // Converts all the spaces into %20.
- void ConvertFilename(fstring& str)
- {
- FUStringBuilder xmlBuilder;
- const fchar* s = str.c_str();
- fchar c;
- for (; (c = *s) != 0; ++s)
- {
- if (filenameValidityTable[(uint8) c]) xmlBuilder.append(c);
- else
- {
- xmlBuilder.append((fchar) '%');
- xmlBuilder.appendHex((uint8) c);
- }
- }
- str = xmlBuilder.ToString();
- }
-
- void AddContentUnprocessed(xmlNode* node, const char* content)
- {
- if (node != NULL) xmlNodeAddContent(node, xcT(content));
- }
-
- void AddAttribute(xmlNode* node, const char* attributeName, const char* value)
- {
- if (node != NULL)
- {
- xmlNewProp(node, xcT(attributeName), xcT(value));
- }
- }
-
- #ifdef UNICODE
- void AddAttribute(xmlNode* node, const char* attributeName, const fstring& attributeValue)
- {
- fm::string s = FUStringConversion::ToString(attributeValue);
- AddAttribute(node, attributeName, s.c_str());
- }
- #endif
-
-
- void RemoveAttribute(xmlNode* node, const char* attributeName)
- {
- xmlAttrPtr ptr = xmlHasProp(node, xcT(attributeName));
- xmlRemoveProp(ptr);
- }
-
-
- // Insert a child, respecting lexical ordering
- void AddChildSorted(xmlNode* parent, xmlNode* child)
- {
- // Do an insertion sort in alphabetical order of the element names.
- // Walk backward from the last child, to make sure that
- // the chronological ordering of elements of the same type is respected.
- //
- for (xmlNode* p = xmlGetLastChild(parent); p != NULL; p = p->prev)
- {
- if (p->type != XML_ELEMENT_NODE) continue;
- if (strcmp((const char*) p->name, (const char*) child->name) <= 0)
- {
- xmlAddNextSibling(p, child);
- return;
- }
- }
-
- // Add to the top of the list.
- if (parent->children && parent->children->type == XML_ELEMENT_NODE)
- {
- xmlAddPrevSibling(parent->children, child);
- }
- else
- {
- AddChild(parent, child);
- }
- }
-
- xmlNode* AddChildSorted(xmlNode* parent, const char* name, const char* content)
- {
- xmlNode* node = CreateNode(name);
- if (content != NULL && *content != 0) AddContent(node, content);
- AddChildSorted(parent, node);
- return node;
- }
-
- void ReParentNode(xmlNode* node, xmlNode* newParent)
- {
- xmlUnlinkNode(node);
- AddChild(newParent, node);
- }
- };