/*
* 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 <dae.h>
#include <dae/daeDatabase.h>
#include <dae/daeDom.h>
#include <dae/daeIDRef.h>
#include <dae/daeMetaElement.h>
#include <modules/daeSTLDatabase.h>
#include <dae/daeErrorHandler.h>
#include <dae/daeRawResolver.h>
#include <dae/daeStandardURIResolver.h>
#include <dom/domTypes.h>
#include <dom/domCOLLADA.h>
#ifdef DOM_INCLUDE_LIBXML
#include <modules/daeLIBXMLPlugin.h>
#endif
#ifdef DOM_INCLUDE_TINYXML
#include <dae/daeTinyXMLPlugin.h>
#endif
using namespace std;
// Don't include domConstants.h because it varies depending on the dom version,
// just extern the one thing we need (COLLADA_VERSION) which all versions of
// domConstants.h/.cpp are required to define.
extern daeString COLLADA_VERSION;
daeInt DAEInstanceCount = 0;
DAE::charEncoding DAE::globalCharEncoding = DAE::Utf8;
void
DAE::cleanup()
{
//Contributed by Nus - Wed, 08 Nov 2006
daeStringRef::releaseStringTable();
//----------------------
#ifndef NO_BOOST
try
{
boost::filesystem::remove_all(cdom::getSafeTmpDir());
}
catch (...)
{
daeErrorHandler::get()->handleWarning("Could not remove temporary directory in DAE::cleanup()\n");
}
#endif
}
void DAE::init(daeDatabase* database_, daeIOPlugin* ioPlugin) {
database = NULL;
plugin = NULL;
defaultDatabase = false;
defaultPlugin = false;
metas.setCount(colladaTypeCount());
initializeDomMeta(*this);
DAEInstanceCount++;
// The order of the URI resolvers is significant, so be careful
uriResolvers.list().append(new daeRawResolver(*this));
uriResolvers.list().append(new daeStandardURIResolver(*this));
idRefResolvers.addResolver(new daeDefaultIDRefResolver(*this));
setDatabase(database_);
setIOPlugin(ioPlugin);
}
DAE::~DAE()
{
if (defaultDatabase)
delete database;
if (defaultPlugin)
delete plugin;
if ( --DAEInstanceCount <= 0 )
cleanup();
}
// Database setup
daeDatabase* DAE::getDatabase()
{
return database;
}
daeInt DAE::setDatabase(daeDatabase* _database)
{
if (defaultDatabase)
delete database;
if (_database)
{
defaultDatabase = false;
database = _database;
}
else
{
//create default database
database = new daeSTLDatabase(*this);
defaultDatabase = true;
}
database->setMeta(getMeta(domCOLLADA::ID()));
return DAE_OK;
}
// IO Plugin setup
daeIOPlugin* DAE::getIOPlugin()
{
return plugin;
}
daeInt DAE::setIOPlugin(daeIOPlugin* _plugin)
{
if (defaultPlugin)
delete plugin;
if (_plugin) {
defaultPlugin = false;
plugin = _plugin;
}
else {
plugin = NULL;
defaultPlugin = true;
//create default plugin
#ifdef DOM_INCLUDE_LIBXML
plugin = new daeLIBXMLPlugin(*this);
#else
#ifdef DOM_INCLUDE_TINYXML
plugin = new daeTinyXMLPlugin;
#endif
#endif
if (!plugin) {
daeErrorHandler::get()->handleWarning("No IOPlugin Set");
plugin = new daeIOEmpty;
return DAE_ERROR;
}
}
int res = plugin->setMeta(getMeta(domCOLLADA::ID()));
if (res != DAE_OK) {
if (defaultPlugin) {
defaultPlugin = false;
delete plugin;
}
plugin = NULL;
}
return res;
}
// Take a path (either a URI ref or a file system path) and return a full URI,
// using the current working directory as the base URI if a relative URI
// reference is given.
string DAE::makeFullUri(const string& path) {
daeURI uri(*this, cdom::nativePathToUri(path));
return uri.str();
}
domCOLLADA* DAE::add(const string& path) {
close(path);
string uri = makeFullUri(path);
database->insertDocument(uri.c_str());
return getRoot(uri);
}
domCOLLADA* DAE::openCommon(const string& path, daeString buffer) {
close(path);
string uri = makeFullUri(path);
plugin->setDatabase(database);
if (plugin->read(daeURI(*this, uri.c_str()), buffer) != DAE_OK)
return NULL;
return getRoot(uri);
}
domCOLLADA* DAE::open(const string& path) {
return openCommon(path, NULL);
}
domCOLLADA* DAE::openFromMemory(const string& path, daeString buffer) {
return openCommon(path, buffer);
}
bool DAE::writeCommon(const string& docPath, const string& pathToWriteTo, bool replace) {
string docUri = makeFullUri(docPath),
uriToWriteTo = makeFullUri(pathToWriteTo);
plugin->setDatabase(database);
if (daeDocument* doc = getDoc(docUri))
return plugin->write(daeURI(*this, uriToWriteTo.c_str()), doc, replace) == DAE_OK;
return false;
}
bool DAE::write(const string& path) {
return writeCommon(path, path, true);
}
bool DAE::writeTo(const string& docPath, const string& pathToWriteTo) {
return writeCommon(docPath, pathToWriteTo, true);
}
bool DAE::writeAll() {
for (int i = 0; i < getDocCount(); i++)
if (save((daeUInt)i, true) != DAE_OK)
return false;
return true;
}
void DAE::close(const string& path) {
database->removeDocument(getDoc(makeFullUri(path).c_str()));
}
daeInt DAE::clear() {
database->clear();
rawRefCache.clear();
sidRefCache.clear();
return DAE_OK;
}
// Deprecated methods
daeInt DAE::load(daeString uri, daeString docBuffer) {
return openCommon(uri, docBuffer) ? DAE_OK : DAE_ERROR;
}
daeInt DAE::save(daeString uri, daeBool replace) {
return writeCommon(uri, uri, replace) ? DAE_OK : DAE_ERROR;
}
daeInt DAE::save(daeUInt documentIndex, daeBool replace) {
if ((int)documentIndex >= getDocCount())
return DAE_ERROR;
// Save it out to the URI it was loaded from
daeString uri = getDoc((int)documentIndex)->getDocumentURI()->getURI();
return writeCommon(uri, uri, replace) ? DAE_OK : DAE_ERROR;
}
daeInt DAE::saveAs(daeString uriToSaveTo, daeString docUri, daeBool replace) {
return writeCommon(docUri, uriToSaveTo, replace) ? DAE_OK : DAE_ERROR;
}
daeInt DAE::saveAs(daeString uriToSaveTo, daeUInt documentIndex, daeBool replace) {
if ((int)documentIndex >= getDocCount())
return DAE_ERROR;
daeString docUri = getDoc((int)documentIndex)->getDocumentURI()->getURI();
return writeCommon(docUri, uriToSaveTo, replace) ? DAE_OK : DAE_ERROR;
}
daeInt DAE::unload(daeString uri) {
close(uri);
return DAE_OK;
}
int DAE::getDocCount() {
return (int)database->getDocumentCount();
}
daeDocument* DAE::getDoc(int i) {
return database->getDocument(i);
}
daeDocument* DAE::getDoc(const string& path) {
return database->getDocument(makeFullUri(path).c_str(), true);
}
domCOLLADA* DAE::getRoot(const string& path) {
if (daeDocument* doc = getDoc(path))
return (domCOLLADA*)doc->getDomRoot();
return NULL;
}
bool DAE::setRoot(const string& path, domCOLLADA* root) {
if (daeDocument* doc = getDoc(path))
doc->setDomRoot(root);
else
database->insertDocument(makeFullUri(path).c_str(), root);
return getRoot(path) != NULL;
}
domCOLLADA* DAE::getDom(daeString uri) {
return getRoot(uri);
}
daeInt DAE::setDom(daeString uri, domCOLLADA* dom) {
return setRoot(uri, dom);
}
daeString DAE::getDomVersion()
{
return(COLLADA_VERSION);
}
daeAtomicTypeList& DAE::getAtomicTypes() {
return atomicTypes;
}
daeMetaElement* DAE::getMeta(daeInt typeID) {
if (typeID < 0 || typeID >= daeInt(metas.getCount()))
return NULL;
return metas[typeID];
}
daeMetaElementRefArray& DAE::getAllMetas() {
return metas;
}
void DAE::setMeta(daeInt typeID, daeMetaElement& meta) {
if (typeID < 0 || typeID >= daeInt(metas.getCount()))
return;
metas[typeID] = &meta;
}
daeURIResolverList& DAE::getURIResolvers() {
return uriResolvers;
}
daeURI& DAE::getBaseURI() {
return baseUri;
}
void DAE::setBaseURI(const daeURI& uri) {
baseUri = uri;
}
void DAE::setBaseURI(const string& uri) {
baseUri = uri.c_str();
}
daeIDRefResolverList& DAE::getIDRefResolvers() {
return idRefResolvers;
}
daeRawRefCache& DAE::getRawRefCache() {
return rawRefCache;
}
daeSidRefCache& DAE::getSidRefCache() {
return sidRefCache;
}
void DAE::dummyFunction1() { }
DAE::charEncoding DAE::getGlobalCharEncoding() {
return globalCharEncoding;
}
void DAE::setGlobalCharEncoding(charEncoding encoding) {
globalCharEncoding = encoding;
}
DAE::charEncoding DAE::getCharEncoding() {
return localCharEncoding.get() ? *localCharEncoding : getGlobalCharEncoding();
}
void DAE::setCharEncoding(charEncoding encoding) {
localCharEncoding.reset(new charEncoding(encoding));
}