1/* 2* Copyright 2006 Sony Computer Entertainment Inc. 3* 4* Licensed under the MIT Open Source License, for details please see license.txt or the website 5* http://www.opensource.org/licenses/mit-license.php 6* 7*/ 8 9#include <sstream> 10#include <dae.h> 11#include <dom.h> 12#include <dae/daeDatabase.h> 13#include <dae/daeIOPluginCommon.h> 14#include <dae/daeMetaElement.h> 15#include <dae/daeErrorHandler.h> 16#include <dae/daeMetaElementAttribute.h> 17#ifndef NO_ZAE 18#include <dae/daeZAEUncompressHandler.h> 19#endif 20 21using namespace std; 22 23daeIOPluginCommon::daeIOPluginCommon() 24 : database(NULL), 25 topMeta(NULL) 26{ 27} 28 29daeIOPluginCommon::~daeIOPluginCommon() 30{ 31} 32 33daeInt daeIOPluginCommon::setMeta(daeMetaElement *_topMeta) 34{ 35 topMeta = _topMeta; 36 return DAE_OK; 37} 38 39void daeIOPluginCommon::setDatabase(daeDatabase* _database) 40{ 41 database = _database; 42} 43 44// This function needs to be re-entrant, it can be called recursively from inside of resolveAll 45// to load files that the first file depends on. 46daeInt daeIOPluginCommon::read(const daeURI& uri, daeString docBuffer) 47{ 48 // Make sure topMeta has been set before proceeding 49 if (topMeta == NULL) 50 { 51 return DAE_ERR_BACKEND_IO; 52 } 53 54 // Generate a version of the URI with the fragment removed 55 daeURI fileURI(*uri.getDAE(), uri.str(), true); 56 57 //check if document already exists 58 if ( database->isDocumentLoaded( fileURI.getURI() ) ) 59 { 60 return DAE_ERR_COLLECTION_ALREADY_EXISTS; 61 } 62 63 daeElementRef domObject = docBuffer ? 64 readFromMemory(docBuffer, fileURI) : 65 readFromFile(fileURI); // Load from URI 66 67#ifdef NO_ZAE 68 69 if (!domObject) { 70 string msg = docBuffer ? 71 "Failed to load XML document from memory\n" : 72 string("Failed to load ") + fileURI.str() + "\n"; 73 daeErrorHandler::get()->handleError(msg.c_str()); 74 return DAE_ERR_BACKEND_IO; 75 } 76 77 // Insert the document into the database, the Database will keep a ref on the main dom, so it won't get deleted 78 // until we clear the database 79 80 daeDocument *document = NULL; 81 82 int res = database->insertDocument(fileURI.getURI(),domObject,&document); 83 if (res!= DAE_OK) 84 return res; 85 86#else 87 88 bool zaeRoot = false; 89 string extractedURI = ""; 90 if (!domObject) { 91 daeZAEUncompressHandler zaeHandler(fileURI); 92 if (zaeHandler.isZipFile()) 93 { 94 string rootFilePath = zaeHandler.obtainRootFilePath(); 95 daeURI rootFileURI(*fileURI.getDAE(), rootFilePath); 96 domObject = readFromFile(rootFileURI); 97 if (!domObject) 98 { 99 string msg = string("Failed to load ") + fileURI.str() + "\n"; 100 daeErrorHandler::get()->handleError(msg.c_str()); 101 return DAE_ERR_BACKEND_IO; 102 } 103 zaeRoot = true; 104 extractedURI = rootFileURI.str(); 105 } 106 else 107 { 108 string msg = docBuffer ? 109 "Failed to load XML document from memory\n" : 110 string("Failed to load ") + fileURI.str() + "\n"; 111 daeErrorHandler::get()->handleError(msg.c_str()); 112 return DAE_ERR_BACKEND_IO; 113 } 114 } 115 116 // Insert the document into the database, the Database will keep a ref on the main dom, so it won't get deleted 117 // until we clear the database 118 119 daeDocument *document = NULL; 120 121 int res = database->insertDocument(fileURI.getURI(),domObject,&document, zaeRoot, extractedURI); 122 if (res!= DAE_OK) 123 return res; 124 125#endif 126 127 return DAE_OK; 128} 129 130 131 132 133 134 135 136 137 138 139daeElementRef daeIOPluginCommon::beginReadElement(daeElement* parentElement, 140 daeString elementName, 141 const vector<attrPair>& attributes, 142 daeInt lineNumber) { 143 daeMetaElement* parentMeta = parentElement ? parentElement->getMeta() : topMeta; 144 daeElementRef element = parentMeta->create(elementName); 145 146 if(!element) 147 { 148 ostringstream msg; 149 msg << "The DOM was unable to create an element named " << elementName << " at line " 150 << lineNumber << ". Probably a schema violation.\n"; 151 daeErrorHandler::get()->handleWarning( msg.str().c_str() ); 152 return NULL; 153 } 154 155 // Process the attributes 156 for (size_t i = 0; i < attributes.size(); i++) { 157 daeString name = attributes[i].first, 158 value = attributes[i].second; 159 if (!element->setAttribute(name, value)) { 160 ostringstream msg; 161 msg << "The DOM was unable to create an attribute " << name << " = " << value 162 << " at line " << lineNumber << ".\nProbably a schema violation.\n"; 163 daeErrorHandler::get()->handleWarning(msg.str().c_str()); 164 } 165 } 166 167 if (parentElement == NULL) { 168 // This is the root element. Check the COLLADA version. 169 daeURI *xmlns = (daeURI*)(element->getMeta()->getMetaAttribute( "xmlns" )->getWritableMemory( element )); 170 if ( strcmp( xmlns->getURI(), COLLADA_NAMESPACE ) != 0 ) { 171 // Invalid COLLADA version 172 daeErrorHandler::get()->handleError("Trying to load an invalid COLLADA version for this DOM build!"); 173 return NULL; 174 } 175 } 176 177 return element; 178} 179 180bool daeIOPluginCommon::readElementText(daeElement* element, daeString text, daeInt elementLineNumber) { 181 if (element->setCharData(text)) 182 return true; 183 184 ostringstream msg; 185 msg << "The DOM was unable to set a value for element of type " << element->getTypeName() 186 << " at line " << elementLineNumber << ".\nProbably a schema violation.\n"; 187 daeErrorHandler::get()->handleWarning(msg.str().c_str()); 188 return false; 189} 190