187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk/* 287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk* Copyright 2006 Sony Computer Entertainment Inc. 387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk* 487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk* Licensed under the MIT Open Source License, for details please see license.txt or the website 587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk* http://www.opensource.org/licenses/mit-license.php 687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk* 787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk*/ 887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk// The user can choose whether or not to include libxml support in the DOM. Supporting libxml will 1087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk// require linking against it. By default libxml support is included. 1187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk#if defined(DOM_INCLUDE_LIBXML) 1287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 1387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk// This is a rework of the XML plugin that contains a complete interface to libxml2 "readXML" 1487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk// This is intended to be a seperate plugin but I'm starting out by rewriting it in daeLIBXMLPlugin 1587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk// because I'm not sure if all the plugin handling stuff has been tested. Once I get a working 1687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk// plugin I'll look into renaming it so the old daeLIBXMLPlugin can coexist with it. 1787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk// 1887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk#include <string> 1987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk#include <sstream> 2087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk#include <modules/daeLIBXMLPlugin.h> 2187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk#include <dae.h> 2287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk#include <dom.h> 2387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk#include <dae/daeDatabase.h> 2487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk#include <dae/daeMetaElement.h> 2587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk#include <libxml/xmlreader.h> 2687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk#include <libxml/xmlwriter.h> 2787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk#include <libxml/xmlmemory.h> 2887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk#include <dae/daeErrorHandler.h> 2987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk#include <dae/daeMetaElementAttribute.h> 3087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 3187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchoukusing namespace std; 3287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 3387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 3487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk// Some helper functions for working with libxml 3587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouknamespace { 3687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeInt getCurrentLineNumber(xmlTextReaderPtr reader) { 3787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk#if LIBXML_VERSION >= 20620 3887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return xmlTextReaderGetParserLineNumber(reader); 3987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk#else 4087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return -1; 4187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk#endif 4287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 4387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 4487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // Return value should be freed by caller with delete[]. Passed in value should not 4587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // be null. 4687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlChar* utf8ToLatin1(const xmlChar* utf8) { 4787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk int inLen = xmlStrlen(utf8); 4887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk int outLen = (inLen+1) * 2; 4987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlChar* latin1 = new xmlChar[outLen]; 5087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk int numBytes = UTF8Toisolat1(latin1, &outLen, utf8, &inLen); 5187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (numBytes < 0) 5287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // Failed. Return an empty string instead. 5387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk numBytes = 0; 5487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 5587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk latin1[numBytes] = '\0'; 5687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return latin1; 5787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 5887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 5987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // Return value should be freed by caller with delete[]. 6087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlChar* latin1ToUtf8(const string& latin1) { 6187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk int inLen = (int)latin1.length(); 6287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk int outLen = (inLen+1) * 2; 6387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlChar* utf8 = new xmlChar[outLen]; 6487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk int numBytes = isolat1ToUTF8(utf8, &outLen, (xmlChar*)latin1.c_str(), &inLen); 6587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (numBytes < 0) 6687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // Failed. Return an empty string instead. 6787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk numBytes = 0; 6887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 6987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk utf8[numBytes] = '\0'; 7087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return utf8; 7187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 7287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 7387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk typedef pair<daeString, daeString> stringPair; 7487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 7587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // The attributes vector passed in should be empty. If 'encoding' is anything 7687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // other than utf8 the caller should free the returned attribute value 7787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // strings. The 'freeAttrValues' function is provided for that purpose. 7887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk void packageCurrentAttributes(xmlTextReaderPtr reader, 7987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk DAE::charEncoding encoding, 8087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk /* out */ vector<stringPair>& attributes) { 8187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk int numAttributes = xmlTextReaderAttributeCount(reader); 8287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (numAttributes == -1 || numAttributes == 0) 8387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return; 8487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk attributes.reserve(numAttributes); 8587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 8687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk while (xmlTextReaderMoveToNextAttribute(reader) == 1) { 8787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk const xmlChar* xmlName = xmlTextReaderConstName(reader); 8887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk const xmlChar* xmlValue = xmlTextReaderConstValue(reader); 8987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (encoding == DAE::Latin1) 9087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk attributes.push_back(stringPair((daeString)xmlName, (daeString)utf8ToLatin1(xmlValue))); 9187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk else 9287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk attributes.push_back(stringPair((daeString)xmlName, (daeString)xmlValue)); 9387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 9487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 9587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 9687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk void freeAttrValues(vector<stringPair>& pairs) { 9787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk for(size_t i=0, size=pairs.size(); i<size; ++i) { 9887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk delete[] pairs[i].second; 9987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk pairs[i].second = 0; 10087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 10187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 10287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk} 10387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 10487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex SakhartchoukdaeLIBXMLPlugin::daeLIBXMLPlugin(DAE& dae) : dae(dae), rawRelPath(dae) 10587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk{ 10687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk supportedProtocols.push_back("*"); 10787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlInitParser(); 10887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk rawFile = NULL; 10987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk rawByteCount = 0; 11087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk saveRawFile = false; 11187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk} 11287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 11387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex SakhartchoukdaeLIBXMLPlugin::~daeLIBXMLPlugin() 11487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk{ 11587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlCleanupParser(); 11687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk} 11787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 11887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex SakhartchoukdaeInt daeLIBXMLPlugin::setOption( daeString option, daeString value ) 11987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk{ 12087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ( strcmp( option, "saveRawBinary" ) == 0 ) 12187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 12287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ( strcmp( value, "true" ) == 0 || strcmp( value, "TRUE" ) == 0 ) 12387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 12487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk saveRawFile = true; 12587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 12687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk else 12787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 12887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk saveRawFile = false; 12987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 13087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return DAE_OK; 13187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 13287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return DAE_ERR_INVALID_CALL; 13387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk} 13487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 13587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex SakhartchoukdaeString daeLIBXMLPlugin::getOption( daeString option ) 13687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk{ 13787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ( strcmp( option, "saveRawBinary" ) == 0 ) 13887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 13987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ( saveRawFile ) 14087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 14187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return "true"; 14287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 14387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return "false"; 14487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 14587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return NULL; 14687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk} 14787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 14887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouknamespace { 14987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk void libxmlErrorHandler(void* arg, 15087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk const char* msg, 15187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlParserSeverities severity, 15287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextReaderLocatorPtr locator) { 15387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if(severity == XML_PARSER_SEVERITY_VALIDITY_WARNING || 15487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk severity == XML_PARSER_SEVERITY_WARNING) { 15587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeErrorHandler::get()->handleWarning(msg); 15687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 15787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk else 15887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeErrorHandler::get()->handleError(msg); 15987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 16087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk} 16187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 16287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk// A simple structure to help alloc/free xmlTextReader objects 16387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchoukstruct xmlTextReaderHelper { 16487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextReaderHelper(const daeURI& uri) { 16587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if((reader = xmlReaderForFile(cdom::fixUriForLibxml(uri.str()).c_str(), NULL, 0))) 16687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextReaderSetErrorHandler(reader, libxmlErrorHandler, NULL); 16787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 16887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 16987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextReaderHelper(daeString buffer, const daeURI& baseUri) { 17087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if((reader = xmlReaderForDoc((xmlChar*)buffer, cdom::fixUriForLibxml(baseUri.str()).c_str(), NULL, 0))) 17187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextReaderSetErrorHandler(reader, libxmlErrorHandler, NULL); 17287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk }; 17387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 17487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk ~xmlTextReaderHelper() { 17587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (reader) 17687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlFreeTextReader(reader); 17787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 17887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 17987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextReaderPtr reader; 18087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk}; 18187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 18287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex SakhartchoukdaeElementRef daeLIBXMLPlugin::readFromFile(const daeURI& uri) { 18387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextReaderHelper readerHelper(uri); 18487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (!readerHelper.reader) { 18587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeErrorHandler::get()->handleError((string("Failed to open ") + uri.str() + 18687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk " in daeLIBXMLPlugin::readFromFile\n").c_str()); 18787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return NULL; 18887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 18987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return read(readerHelper.reader); 19087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk} 19187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 19287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex SakhartchoukdaeElementRef daeLIBXMLPlugin::readFromMemory(daeString buffer, const daeURI& baseUri) { 19387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextReaderHelper readerHelper(buffer, baseUri); 19487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (!readerHelper.reader) { 19587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeErrorHandler::get()->handleError("Failed to open XML document from memory buffer in " 19687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk "daeLIBXMLPlugin::readFromMemory\n"); 19787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return NULL; 19887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 19987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return read(readerHelper.reader); 20087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk} 20187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 20287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex SakhartchoukdaeElementRef daeLIBXMLPlugin::read(_xmlTextReader* reader) { 20387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // Drop everything up to the first element. In the future, we should try to store header comments somewhere. 20487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk while(xmlTextReaderNodeType(reader) != XML_READER_TYPE_ELEMENT) 20587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 20687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (xmlTextReaderRead(reader) != 1) { 20787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeErrorHandler::get()->handleError("Error parsing XML in daeLIBXMLPlugin::read\n"); 20887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return NULL; 20987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 21087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 21187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 21287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk int readRetVal = 0; 21387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return readElement(reader, NULL, readRetVal); 21487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk} 21587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 21687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex SakhartchoukdaeElementRef daeLIBXMLPlugin::readElement(_xmlTextReader* reader, 21787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeElement* parentElement, 21887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk /* out */ int& readRetVal) { 21987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk assert(xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT); 22087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeString elementName = (daeString)xmlTextReaderConstName(reader); 22187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk bool empty = xmlTextReaderIsEmptyElement(reader) != 0; 22287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 22387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk vector<attrPair> attributes; 22487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk packageCurrentAttributes(reader, dae.getCharEncoding(), /* out */ attributes); 22587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 22687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeElementRef element = beginReadElement(parentElement, elementName, attributes, getCurrentLineNumber(reader)); 22787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (dae.getCharEncoding() != DAE::Utf8) 22887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk freeAttrValues(attributes); 22987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 23087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (!element) { 23187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // We couldn't create the element. beginReadElement already printed an error message. Just make sure 23287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // to skip ahead past the bad element. 23387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextReaderNext(reader); 23487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return NULL; 23587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 23687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 23787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ((readRetVal = xmlTextReaderRead(reader)) == -1) 23887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return NULL; 23987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (empty) 24087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return element; 24187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 24287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk int nodeType = xmlTextReaderNodeType(reader); 24387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk while (readRetVal == 1 && nodeType != XML_READER_TYPE_END_ELEMENT) { 24487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (nodeType == XML_READER_TYPE_ELEMENT) { 24587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk element->placeElement(readElement(reader, element, readRetVal)); 24687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 24787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk else if (nodeType == XML_READER_TYPE_TEXT) { 24887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk const xmlChar* xmlText = xmlTextReaderConstValue(reader); 24987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (dae.getCharEncoding() == DAE::Latin1) 25087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlText = utf8ToLatin1(xmlText); 25187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk readElementText(element, (daeString)xmlText, getCurrentLineNumber(reader)); 25287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (dae.getCharEncoding() == DAE::Latin1) 25387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk delete[] xmlText; 25487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 25587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk readRetVal = xmlTextReaderRead(reader); 25687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 25787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk else 25887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk readRetVal = xmlTextReaderRead(reader); 25987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 26087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk nodeType = xmlTextReaderNodeType(reader); 26187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 26287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 26387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (nodeType == XML_READER_TYPE_END_ELEMENT) 26487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk readRetVal = xmlTextReaderRead(reader); 26587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 26687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (readRetVal == -1) // Something went wrong (bad xml probably) 26787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return NULL; 26887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 26987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return element; 27087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk} 27187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 27287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex SakhartchoukdaeInt daeLIBXMLPlugin::write(const daeURI& name, daeDocument *document, daeBool replace) 27387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk{ 27487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // Make sure database and document are both set 27587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (!database) 27687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return DAE_ERR_INVALID_CALL; 27787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if(!document) 27887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return DAE_ERR_COLLECTION_DOES_NOT_EXIST; 27987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 28087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // Convert the URI to a file path, to see if we're about to overwrite a file 28187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk string file = cdom::uriToNativePath(name.str()); 28287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (file.empty() && saveRawFile) 28387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 28487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeErrorHandler::get()->handleError( "can't get path in write\n" ); 28587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return DAE_ERR_BACKEND_IO; 28687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 28787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 28887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // If replace=false, don't replace existing files 28987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if(!replace) 29087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 29187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // Using "stat" would be better, but it's not available on all platforms 29287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk FILE *tempfd = fopen(file.c_str(), "r"); 29387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if(tempfd != NULL) 29487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 29587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // File exists, return error 29687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk fclose(tempfd); 29787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return DAE_ERR_BACKEND_FILE_EXISTS; 29887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 29987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk fclose(tempfd); 30087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 30187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ( saveRawFile ) 30287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 30387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk string rawFilePath = file + ".raw"; 30487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ( !replace ) 30587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 30687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk rawFile = fopen(rawFilePath.c_str(), "rb" ); 30787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ( rawFile != NULL ) 30887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 30987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk fclose(rawFile); 31087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return DAE_ERR_BACKEND_FILE_EXISTS; 31187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 31287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk fclose(rawFile); 31387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 31487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk rawFile = fopen(rawFilePath.c_str(), "wb"); 31587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ( rawFile == NULL ) 31687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 31787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return DAE_ERR_BACKEND_IO; 31887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 31987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk rawRelPath.set(cdom::nativePathToUri(rawFilePath)); 32087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk rawRelPath.makeRelativeTo( &name ); 32187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 32287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 32387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // Open the file we will write to 32487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk writer = xmlNewTextWriterFilename(cdom::fixUriForLibxml(name.str()).c_str(), 0); 32587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ( !writer ) { 32687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk ostringstream msg; 32787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk msg << "daeLIBXMLPlugin::write(" << name.str() << ") failed\n"; 32887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeErrorHandler::get()->handleError(msg.str().c_str()); 32987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return DAE_ERR_BACKEND_IO; 33087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 33187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextWriterSetIndentString( writer, (const xmlChar*)"\t" ); // Don't change this to spaces 33287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextWriterSetIndent( writer, 1 ); // Turns indentation on 33387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextWriterStartDocument( writer, "1.0", "UTF-8", NULL ); 33487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 33587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk writeElement( document->getDomRoot() ); 33687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 33787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextWriterEndDocument( writer ); 33887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextWriterFlush( writer ); 33987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlFreeTextWriter( writer ); 34087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 34187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ( saveRawFile && rawFile != NULL ) 34287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 34387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk fclose( rawFile ); 34487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 34587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 34687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return DAE_OK; 34787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk} 34887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 34987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchoukvoid daeLIBXMLPlugin::writeElement( daeElement* element ) 35087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk{ 35187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeMetaElement* _meta = element->getMeta(); 35287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 35387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk //intercept <source> elements for special handling 35487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ( saveRawFile ) 35587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 35687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ( strcmp( element->getTypeName(), "source" ) == 0 ) 35787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 35887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeElementRefArray children; 35987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk element->getChildren( children ); 36087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk bool validArray = false, teqCommon = false; 36187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk for ( unsigned int i = 0; i < children.getCount(); i++ ) 36287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 36387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ( strcmp( children[i]->getTypeName(), "float_array" ) == 0 || 36487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk strcmp( children[i]->getTypeName(), "int_array" ) == 0 ) 36587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 36687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk validArray = true; 36787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 36887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk else if ( strcmp( children[i]->getTypeName(), "technique_common" ) == 0 ) 36987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 37087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk teqCommon = true; 37187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 37287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 37387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ( validArray && teqCommon ) 37487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 37587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk writeRawSource( element ); 37687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return; 37787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 37887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 37987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 38087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 38187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (!_meta->getIsTransparent() ) { 38287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextWriterStartElement(writer, (xmlChar*)element->getElementName()); 38387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeMetaAttributeRefArray& attrs = _meta->getMetaAttributes(); 38487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 38587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk int acnt = (int)attrs.getCount(); 38687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 38787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk for(int i=0;i<acnt;i++) { 38887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk writeAttribute(attrs[i], element); 38987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 39087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 39187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk writeValue(element); 39287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 39387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeElementRefArray children; 39487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk element->getChildren( children ); 39587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk for ( size_t x = 0; x < children.getCount(); x++ ) { 39687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk writeElement( children.get(x) ); 39787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 39887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 39987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk /*if (_meta->getContents() != NULL) { 40087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeElementRefArray* era = (daeElementRefArray*)_meta->getContents()->getWritableMemory(element); 40187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk int elemCnt = (int)era->getCount(); 40287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk for(int i = 0; i < elemCnt; i++) { 40387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeElementRef elem = (daeElementRef)era->get(i); 40487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (elem != NULL) { 40587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk writeElement( elem ); 40687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 40787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 40887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 40987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk else 41087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 41187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeMetaElementAttributeArray& children = _meta->getMetaElements(); 41287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk int cnt = (int)children.getCount(); 41387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk for(int i=0;i<cnt;i++) { 41487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeMetaElement *type = children[i]->getElementType(); 41587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ( !type->getIsAbstract() ) { 41687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk for (int c = 0; c < children[i]->getCount(element); c++ ) { 41787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk writeElement( *(daeElementRef*)children[i]->get(element,c) ); 41887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 41987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 42087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 42187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk }*/ 42287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (!_meta->getIsTransparent() ) { 42387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextWriterEndElement(writer); 42487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 42587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk} 42687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 42787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchoukvoid daeLIBXMLPlugin::writeAttribute( daeMetaAttribute* attr, daeElement* element) 42887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk{ 42987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk ostringstream buffer; 43087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk attr->memoryToString(element, buffer); 43187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk string str = buffer.str(); 43287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 43387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // Don't write the attribute if 43487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // - The attribute isn't required AND 43587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // - The attribute has no default value and the current value is "" 43687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk // - The attribute has a default value and the current value matches the default 43787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (!attr->getIsRequired()) { 43887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if(!attr->getDefaultValue() && str.empty()) 43987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return; 44087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if(attr->getDefaultValue() && attr->compareToDefault(element) == 0) 44187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk return; 44287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 44387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 44487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextWriterStartAttribute(writer, (xmlChar*)(daeString)attr->getName()); 44587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlChar* utf8 = (xmlChar*)str.c_str(); 44687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (dae.getCharEncoding() == DAE::Latin1) 44787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk utf8 = latin1ToUtf8(str); 44887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextWriterWriteString(writer, utf8); 44987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (dae.getCharEncoding() == DAE::Latin1) 45087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk delete[] utf8; 45187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 45287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextWriterEndAttribute(writer); 45387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk} 45487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 45587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchoukvoid daeLIBXMLPlugin::writeValue(daeElement* element) { 45687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (daeMetaAttribute* attr = element->getMeta()->getValueAttribute()) { 45787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk ostringstream buffer; 45887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk attr->memoryToString(element, buffer); 45987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk string s = buffer.str(); 46087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (!s.empty()) { 46187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlChar* str = (xmlChar*)s.c_str(); 46287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (dae.getCharEncoding() == DAE::Latin1) 46387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk str = latin1ToUtf8(s); 46487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk xmlTextWriterWriteString(writer, (xmlChar*)s.c_str()); 46587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if (dae.getCharEncoding() == DAE::Latin1) 46687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk delete[] str; 46787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 46887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 46987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk} 47087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 47187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchoukvoid daeLIBXMLPlugin::writeRawSource( daeElement *src ) 47287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk{ 47387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeElementRef newSrc = src->clone(); 47487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeElementRef array = NULL; 47587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeElement *accessor = NULL; 47687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeElementRefArray children; 47787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk newSrc->getChildren( children ); 47887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk bool isInt = false; 47987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk for ( int i = 0; i < (int)children.getCount(); i++ ) 48087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 48187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ( strcmp( children[i]->getTypeName(), "float_array" ) == 0 ) 48287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 48387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk array = children[i]; 48487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk newSrc->removeChildElement( array ); 48587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 48687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk else if ( strcmp( children[i]->getTypeName(), "int_array" ) == 0 ) 48787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 48887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk array = children[i]; 48987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk isInt = true; 49087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk newSrc->removeChildElement( array ); 49187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 49287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk else if ( strcmp( children[i]->getTypeName(), "technique_common" ) == 0 ) 49387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 49487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk children[i]->getChildren( children ); 49587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 49687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk else if ( strcmp( children[i]->getTypeName(), "accessor" ) == 0 ) 49787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 49887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk accessor = children[i]; 49987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 50087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 50187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 50287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeULong *countPtr = (daeULong*)array->getAttributeValue( "count" ); 50387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeULong count = countPtr != NULL ? *countPtr : 0; 50487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 50587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeULong *stridePtr = (daeULong*)accessor->getAttributeValue( "stride" ); 50687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeULong stride = stridePtr != NULL ? *stridePtr : 1; 50787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 50887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk children.clear(); 50987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk accessor->getChildren( children ); 51087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ( children.getCount() > stride ) { 51187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk *stridePtr = children.getCount(); 51287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 51387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 51487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeFixedName newURI; 51587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk sprintf( newURI, "%s#%ld", rawRelPath.getOriginalURI(), rawByteCount ); 51687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk accessor->setAttribute( "source", newURI ); 51787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 51887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeArray *valArray = (daeArray*)array->getValuePointer(); 51987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 52087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk //TODO: pay attention to precision for the array. 52187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk if ( isInt ) 52287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 52387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk for( size_t i = 0; i < count; i++ ) 52487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 52587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeInt tmp = (daeInt)*(daeLong*)(valArray->getRaw(i)); 52687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk rawByteCount += (unsigned long)(fwrite( &tmp, sizeof(daeInt), 1, rawFile ) * sizeof(daeInt)); 52787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 52887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 52987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk else 53087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 53187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk for( size_t i = 0; i < count; i++ ) 53287ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk { 53387ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk daeFloat tmp = (daeFloat)*(daeDouble*)(valArray->getRaw(i)); 53487ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk rawByteCount += (unsigned long)(fwrite( &tmp, sizeof(daeFloat), 1, rawFile ) * sizeof(daeFloat)); 53587ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 53687ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk } 53787ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 53887ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk writeElement( newSrc ); 53987ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk} 54087ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk 54187ac3e2db6d5ae163131102c066e9d19bdfdc139Alex Sakhartchouk#endif // DOM_INCLUDE_LIBXML 542