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