| /*
|
| * Copyright 2006 Sony Computer Entertainment Inc.
|
| *
|
| * Licensed under the MIT Open Source License, for details please see license.txt or the website
|
| * http://www.opensource.org/licenses/mit-license.php
|
| *
|
| */ |
| |
| #include <sstream> |
| #include <dae.h> |
| #include <dom.h> |
| #include <dae/daeDatabase.h> |
| #include <dae/daeIOPluginCommon.h> |
| #include <dae/daeMetaElement.h> |
| #include <dae/daeErrorHandler.h> |
| #include <dae/daeMetaElementAttribute.h> |
| #ifndef NO_ZAE |
| #include <dae/daeZAEUncompressHandler.h> |
| #endif |
| |
| using namespace std; |
| |
| daeIOPluginCommon::daeIOPluginCommon() |
| : database(NULL), |
| topMeta(NULL) |
| { |
| } |
| |
| daeIOPluginCommon::~daeIOPluginCommon() |
| { |
| } |
| |
| daeInt daeIOPluginCommon::setMeta(daeMetaElement *_topMeta) |
| { |
| topMeta = _topMeta; |
| return DAE_OK; |
| } |
| |
| void daeIOPluginCommon::setDatabase(daeDatabase* _database) |
| { |
| database = _database; |
| } |
| |
| // This function needs to be re-entrant, it can be called recursively from inside of resolveAll |
| // to load files that the first file depends on. |
| daeInt daeIOPluginCommon::read(const daeURI& uri, daeString docBuffer) |
| { |
| // Make sure topMeta has been set before proceeding |
| if (topMeta == NULL) |
| { |
| return DAE_ERR_BACKEND_IO; |
| } |
| |
| // Generate a version of the URI with the fragment removed |
| daeURI fileURI(*uri.getDAE(), uri.str(), true); |
| |
| //check if document already exists |
| if ( database->isDocumentLoaded( fileURI.getURI() ) ) |
| { |
| return DAE_ERR_COLLECTION_ALREADY_EXISTS; |
| } |
| |
| daeElementRef domObject = docBuffer ? |
| readFromMemory(docBuffer, fileURI) : |
| readFromFile(fileURI); // Load from URI |
| |
| #ifdef NO_ZAE |
| |
| if (!domObject) {
|
| string msg = docBuffer ?
|
| "Failed to load XML document from memory\n" :
|
| string("Failed to load ") + fileURI.str() + "\n";
|
| daeErrorHandler::get()->handleError(msg.c_str());
|
| return DAE_ERR_BACKEND_IO;
|
| }
|
|
|
| // Insert the document into the database, the Database will keep a ref on the main dom, so it won't get deleted
|
| // until we clear the database
|
|
|
| daeDocument *document = NULL;
|
|
|
| int res = database->insertDocument(fileURI.getURI(),domObject,&document);
|
| if (res!= DAE_OK)
|
| return res; |
| |
| #else |
| |
| bool zaeRoot = false; |
| string extractedURI = ""; |
| if (!domObject) { |
| daeZAEUncompressHandler zaeHandler(fileURI); |
| if (zaeHandler.isZipFile()) |
| { |
| string rootFilePath = zaeHandler.obtainRootFilePath(); |
| daeURI rootFileURI(*fileURI.getDAE(), rootFilePath); |
| domObject = readFromFile(rootFileURI); |
| if (!domObject) |
| { |
| string msg = string("Failed to load ") + fileURI.str() + "\n"; |
| daeErrorHandler::get()->handleError(msg.c_str()); |
| return DAE_ERR_BACKEND_IO; |
| } |
| zaeRoot = true; |
| extractedURI = rootFileURI.str(); |
| } |
| else |
| { |
| string msg = docBuffer ? |
| "Failed to load XML document from memory\n" : |
| string("Failed to load ") + fileURI.str() + "\n"; |
| daeErrorHandler::get()->handleError(msg.c_str()); |
| return DAE_ERR_BACKEND_IO; |
| } |
| } |
| |
| // Insert the document into the database, the Database will keep a ref on the main dom, so it won't get deleted |
| // until we clear the database |
| |
| daeDocument *document = NULL; |
| |
| int res = database->insertDocument(fileURI.getURI(),domObject,&document, zaeRoot, extractedURI); |
| if (res!= DAE_OK) |
| return res; |
| |
| #endif
|
|
|
| return DAE_OK;
|
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| daeElementRef daeIOPluginCommon::beginReadElement(daeElement* parentElement, |
| daeString elementName, |
| const vector<attrPair>& attributes, |
| daeInt lineNumber) { |
| daeMetaElement* parentMeta = parentElement ? parentElement->getMeta() : topMeta; |
| daeElementRef element = parentMeta->create(elementName); |
| |
| if(!element) |
| { |
| ostringstream msg; |
| msg << "The DOM was unable to create an element named " << elementName << " at line " |
| << lineNumber << ". Probably a schema violation.\n"; |
| daeErrorHandler::get()->handleWarning( msg.str().c_str() ); |
| return NULL; |
| } |
| |
| // Process the attributes |
| for (size_t i = 0; i < attributes.size(); i++) { |
| daeString name = attributes[i].first, |
| value = attributes[i].second; |
| if (!element->setAttribute(name, value)) { |
| ostringstream msg; |
| msg << "The DOM was unable to create an attribute " << name << " = " << value |
| << " at line " << lineNumber << ".\nProbably a schema violation.\n"; |
| daeErrorHandler::get()->handleWarning(msg.str().c_str()); |
| } |
| } |
| |
| if (parentElement == NULL) { |
| // This is the root element. Check the COLLADA version. |
| daeURI *xmlns = (daeURI*)(element->getMeta()->getMetaAttribute( "xmlns" )->getWritableMemory( element )); |
| if ( strcmp( xmlns->getURI(), COLLADA_NAMESPACE ) != 0 ) { |
| // Invalid COLLADA version |
| daeErrorHandler::get()->handleError("Trying to load an invalid COLLADA version for this DOM build!"); |
| return NULL; |
| } |
| } |
| |
| return element; |
| } |
| |
| bool daeIOPluginCommon::readElementText(daeElement* element, daeString text, daeInt elementLineNumber) { |
| if (element->setCharData(text)) |
| return true; |
| |
| ostringstream msg; |
| msg << "The DOM was unable to set a value for element of type " << element->getTypeName() |
| << " at line " << elementLineNumber << ".\nProbably a schema violation.\n"; |
| daeErrorHandler::get()->handleWarning(msg.str().c_str()); |
| return false; |
| } |