Home | History | Annotate | Download | only in dae
      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 <dae.h>
     10 #include <dae/daeDatabase.h>
     11 #include <dae/daeDom.h>
     12 #include <dae/daeIDRef.h>
     13 #include <dae/daeMetaElement.h>
     14 #include <modules/daeSTLDatabase.h>
     15 #include <dae/daeErrorHandler.h>
     16 #include <dae/daeRawResolver.h>
     17 #include <dae/daeStandardURIResolver.h>
     18 #include <dom/domTypes.h>
     19 #include <dom/domCOLLADA.h>
     20 
     21 #ifdef DOM_INCLUDE_LIBXML
     22 #include <modules/daeLIBXMLPlugin.h>
     23 #endif
     24 
     25 #ifdef DOM_INCLUDE_TINYXML
     26 #include <dae/daeTinyXMLPlugin.h>
     27 #endif
     28 
     29 using namespace std;
     30 
     31 // Don't include domConstants.h because it varies depending on the dom version,
     32 // just extern the one thing we need (COLLADA_VERSION) which all versions of
     33 // domConstants.h/.cpp are required to define.
     34 
     35 extern daeString COLLADA_VERSION;
     36 
     37 daeInt DAEInstanceCount = 0;
     38 DAE::charEncoding DAE::globalCharEncoding = DAE::Utf8;
     39 
     40 void
     41 DAE::cleanup()
     42 {
     43 	//Contributed by Nus - Wed, 08 Nov 2006
     44 	daeStringRef::releaseStringTable();
     45 	//----------------------
     46 
     47 #ifndef NO_BOOST
     48     try
     49     {
     50 		boost::filesystem::remove_all(cdom::getSafeTmpDir());
     51     }
     52     catch (...)
     53     {
     54         daeErrorHandler::get()->handleWarning("Could not remove temporary directory in DAE::cleanup()\n");
     55     }
     56 #endif
     57 }
     58 
     59 void DAE::init(daeDatabase* database_, daeIOPlugin* ioPlugin) {
     60 	database = NULL;
     61 	plugin = NULL;
     62 	defaultDatabase = false;
     63 	defaultPlugin = false;
     64 	metas.setCount(colladaTypeCount());
     65 
     66 	initializeDomMeta(*this);
     67 	DAEInstanceCount++;
     68 
     69 	// The order of the URI resolvers is significant, so be careful
     70 	uriResolvers.list().append(new daeRawResolver(*this));
     71 	uriResolvers.list().append(new daeStandardURIResolver(*this));
     72 
     73 	idRefResolvers.addResolver(new daeDefaultIDRefResolver(*this));
     74 
     75 	setDatabase(database_);
     76 	setIOPlugin(ioPlugin);
     77 }
     78 
     79 DAE::~DAE()
     80 {
     81 	if (defaultDatabase)
     82 		delete database;
     83 	if (defaultPlugin)
     84 		delete plugin;
     85 	if ( --DAEInstanceCount <= 0 )
     86 		cleanup();
     87 }
     88 
     89 // Database setup
     90 daeDatabase* DAE::getDatabase()
     91 {
     92 	return database;
     93 }
     94 
     95 daeInt DAE::setDatabase(daeDatabase* _database)
     96 {
     97 	if (defaultDatabase)
     98 		delete database;
     99 	if (_database)
    100 	{
    101 		defaultDatabase = false;
    102 		database = _database;
    103 	}
    104 	else
    105 	{
    106 		//create default database
    107 		database = new daeSTLDatabase(*this);
    108 		defaultDatabase = true;
    109 	}
    110 	database->setMeta(getMeta(domCOLLADA::ID()));
    111 	return DAE_OK;
    112 }
    113 
    114 // IO Plugin setup
    115 daeIOPlugin* DAE::getIOPlugin()
    116 {
    117 	return plugin;
    118 }
    119 
    120 daeInt DAE::setIOPlugin(daeIOPlugin* _plugin)
    121 {
    122 	if (defaultPlugin)
    123 		delete plugin;
    124 	if (_plugin) {
    125 		defaultPlugin = false;
    126 		plugin = _plugin;
    127 	}
    128 	else {
    129 		plugin = NULL;
    130 		defaultPlugin = true;
    131 
    132 		//create default plugin
    133 #ifdef DOM_INCLUDE_LIBXML
    134 		plugin = new daeLIBXMLPlugin(*this);
    135 #else
    136 #ifdef DOM_INCLUDE_TINYXML
    137 		plugin = new daeTinyXMLPlugin;
    138 #endif
    139 #endif
    140 
    141 		if (!plugin) {
    142 			daeErrorHandler::get()->handleWarning("No IOPlugin Set");
    143 			plugin = new daeIOEmpty;
    144 			return DAE_ERROR;
    145 		}
    146 	}
    147 
    148 	int res = plugin->setMeta(getMeta(domCOLLADA::ID()));
    149 	if (res != DAE_OK) {
    150 		if (defaultPlugin) {
    151 			defaultPlugin = false;
    152 			delete plugin;
    153 		}
    154 		plugin = NULL;
    155 	}
    156 	return res;
    157 }
    158 
    159 
    160 // Take a path (either a URI ref or a file system path) and return a full URI,
    161 // using the current working directory as the base URI if a relative URI
    162 // reference is given.
    163 string DAE::makeFullUri(const string& path) {
    164 	daeURI uri(*this, cdom::nativePathToUri(path));
    165 	return uri.str();
    166 }
    167 
    168 
    169 domCOLLADA* DAE::add(const string& path) {
    170 	close(path);
    171 	string uri = makeFullUri(path);
    172 	database->insertDocument(uri.c_str());
    173 	return getRoot(uri);
    174 }
    175 
    176 domCOLLADA* DAE::openCommon(const string& path, daeString buffer) {
    177 	close(path);
    178 	string uri = makeFullUri(path);
    179 	plugin->setDatabase(database);
    180 	if (plugin->read(daeURI(*this, uri.c_str()), buffer) != DAE_OK)
    181 		return NULL;
    182 	return getRoot(uri);
    183 }
    184 
    185 domCOLLADA* DAE::open(const string& path) {
    186 	return openCommon(path, NULL);
    187 }
    188 
    189 domCOLLADA* DAE::openFromMemory(const string& path, daeString buffer) {
    190 	return openCommon(path, buffer);
    191 }
    192 
    193 bool DAE::writeCommon(const string& docPath, const string& pathToWriteTo, bool replace) {
    194 	string docUri = makeFullUri(docPath),
    195 	       uriToWriteTo = makeFullUri(pathToWriteTo);
    196 	plugin->setDatabase(database);
    197 	if (daeDocument* doc = getDoc(docUri))
    198 		return plugin->write(daeURI(*this, uriToWriteTo.c_str()), doc, replace) == DAE_OK;
    199 	return false;
    200 }
    201 
    202 bool DAE::write(const string& path) {
    203 	return writeCommon(path, path, true);
    204 }
    205 
    206 bool DAE::writeTo(const string& docPath, const string& pathToWriteTo) {
    207 	return writeCommon(docPath, pathToWriteTo, true);
    208 }
    209 
    210 bool DAE::writeAll() {
    211 	for (int i = 0; i < getDocCount(); i++)
    212 		if (save((daeUInt)i, true) != DAE_OK)
    213 			return false;
    214 	return true;
    215 }
    216 
    217 void DAE::close(const string& path) {
    218 	database->removeDocument(getDoc(makeFullUri(path).c_str()));
    219 }
    220 
    221 daeInt DAE::clear() {
    222 	database->clear();
    223 	rawRefCache.clear();
    224 	sidRefCache.clear();
    225 	return DAE_OK;
    226 }
    227 
    228 
    229 // Deprecated methods
    230 daeInt DAE::load(daeString uri, daeString docBuffer) {
    231 	return openCommon(uri, docBuffer) ? DAE_OK : DAE_ERROR;
    232 }
    233 
    234 daeInt DAE::save(daeString uri, daeBool replace) {
    235 	return writeCommon(uri, uri, replace) ? DAE_OK : DAE_ERROR;
    236 }
    237 
    238 daeInt DAE::save(daeUInt documentIndex, daeBool replace) {
    239 	if ((int)documentIndex >= getDocCount())
    240 		return DAE_ERROR;
    241 
    242 	// Save it out to the URI it was loaded from
    243 	daeString uri = getDoc((int)documentIndex)->getDocumentURI()->getURI();
    244 	return writeCommon(uri, uri, replace) ? DAE_OK : DAE_ERROR;
    245 }
    246 
    247 daeInt DAE::saveAs(daeString uriToSaveTo, daeString docUri, daeBool replace) {
    248 	return writeCommon(docUri, uriToSaveTo, replace) ? DAE_OK : DAE_ERROR;
    249 }
    250 
    251 daeInt DAE::saveAs(daeString uriToSaveTo, daeUInt documentIndex, daeBool replace) {
    252 	if ((int)documentIndex >= getDocCount())
    253 		return DAE_ERROR;
    254 
    255 	daeString docUri = getDoc((int)documentIndex)->getDocumentURI()->getURI();
    256 	return writeCommon(docUri, uriToSaveTo, replace) ? DAE_OK : DAE_ERROR;
    257 }
    258 
    259 daeInt DAE::unload(daeString uri) {
    260 	close(uri);
    261 	return DAE_OK;
    262 }
    263 
    264 
    265 int DAE::getDocCount() {
    266 	return (int)database->getDocumentCount();
    267 }
    268 
    269 daeDocument* DAE::getDoc(int i) {
    270 	return database->getDocument(i);
    271 }
    272 
    273 daeDocument* DAE::getDoc(const string& path) {
    274 	return database->getDocument(makeFullUri(path).c_str(), true);
    275 }
    276 
    277 domCOLLADA* DAE::getRoot(const string& path) {
    278 	if (daeDocument* doc = getDoc(path))
    279 		return (domCOLLADA*)doc->getDomRoot();
    280 	return NULL;
    281 }
    282 
    283 bool DAE::setRoot(const string& path, domCOLLADA* root) {
    284 	if (daeDocument* doc = getDoc(path))
    285 		doc->setDomRoot(root);
    286 	else
    287 		database->insertDocument(makeFullUri(path).c_str(), root);
    288 	return getRoot(path) != NULL;
    289 }
    290 
    291 domCOLLADA* DAE::getDom(daeString uri) {
    292 	return getRoot(uri);
    293 }
    294 
    295 daeInt DAE::setDom(daeString uri, domCOLLADA* dom) {
    296 	return setRoot(uri, dom);
    297 }
    298 
    299 daeString DAE::getDomVersion()
    300 {
    301 	return(COLLADA_VERSION);
    302 }
    303 
    304 daeAtomicTypeList& DAE::getAtomicTypes() {
    305 	return atomicTypes;
    306 }
    307 
    308 daeMetaElement* DAE::getMeta(daeInt typeID) {
    309 	if (typeID < 0 || typeID >= daeInt(metas.getCount()))
    310 		return NULL;
    311 	return metas[typeID];
    312 }
    313 
    314 daeMetaElementRefArray& DAE::getAllMetas() {
    315 	return metas;
    316 }
    317 
    318 void DAE::setMeta(daeInt typeID, daeMetaElement& meta) {
    319 	if (typeID < 0 || typeID >= daeInt(metas.getCount()))
    320 		return;
    321 	metas[typeID] = &meta;
    322 }
    323 
    324 daeURIResolverList& DAE::getURIResolvers() {
    325 	return uriResolvers;
    326 }
    327 
    328 daeURI& DAE::getBaseURI() {
    329 	return baseUri;
    330 }
    331 
    332 void DAE::setBaseURI(const daeURI& uri) {
    333 	baseUri = uri;
    334 }
    335 
    336 void DAE::setBaseURI(const string& uri) {
    337 	baseUri = uri.c_str();
    338 }
    339 
    340 daeIDRefResolverList& DAE::getIDRefResolvers() {
    341 	return idRefResolvers;
    342 }
    343 
    344 daeRawRefCache& DAE::getRawRefCache() {
    345 	return rawRefCache;
    346 }
    347 
    348 daeSidRefCache& DAE::getSidRefCache() {
    349 	return sidRefCache;
    350 }
    351 
    352 void DAE::dummyFunction1() { }
    353 
    354 DAE::charEncoding DAE::getGlobalCharEncoding() {
    355 	return globalCharEncoding;
    356 }
    357 
    358 void DAE::setGlobalCharEncoding(charEncoding encoding) {
    359 	globalCharEncoding = encoding;
    360 }
    361 
    362 DAE::charEncoding DAE::getCharEncoding() {
    363 	return localCharEncoding.get() ? *localCharEncoding : getGlobalCharEncoding();
    364 }
    365 
    366 void DAE::setCharEncoding(charEncoding encoding) {
    367 	localCharEncoding.reset(new charEncoding(encoding));
    368 }
    369