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
cleanup()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
init(daeDatabase * database_,daeIOPlugin * ioPlugin)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
~DAE()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
getDatabase()90 daeDatabase* DAE::getDatabase()
91 {
92 return database;
93 }
94
setDatabase(daeDatabase * _database)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
getIOPlugin()115 daeIOPlugin* DAE::getIOPlugin()
116 {
117 return plugin;
118 }
119
setIOPlugin(daeIOPlugin * _plugin)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.
makeFullUri(const string & path)163 string DAE::makeFullUri(const string& path) {
164 daeURI uri(*this, cdom::nativePathToUri(path));
165 return uri.str();
166 }
167
168
add(const string & path)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
openCommon(const string & path,daeString buffer)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
open(const string & path)185 domCOLLADA* DAE::open(const string& path) {
186 return openCommon(path, NULL);
187 }
188
openFromMemory(const string & path,daeString buffer)189 domCOLLADA* DAE::openFromMemory(const string& path, daeString buffer) {
190 return openCommon(path, buffer);
191 }
192
writeCommon(const string & docPath,const string & pathToWriteTo,bool replace)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
write(const string & path)202 bool DAE::write(const string& path) {
203 return writeCommon(path, path, true);
204 }
205
writeTo(const string & docPath,const string & pathToWriteTo)206 bool DAE::writeTo(const string& docPath, const string& pathToWriteTo) {
207 return writeCommon(docPath, pathToWriteTo, true);
208 }
209
writeAll()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
close(const string & path)217 void DAE::close(const string& path) {
218 database->removeDocument(getDoc(makeFullUri(path).c_str()));
219 }
220
clear()221 daeInt DAE::clear() {
222 database->clear();
223 rawRefCache.clear();
224 sidRefCache.clear();
225 return DAE_OK;
226 }
227
228
229 // Deprecated methods
load(daeString uri,daeString docBuffer)230 daeInt DAE::load(daeString uri, daeString docBuffer) {
231 return openCommon(uri, docBuffer) ? DAE_OK : DAE_ERROR;
232 }
233
save(daeString uri,daeBool replace)234 daeInt DAE::save(daeString uri, daeBool replace) {
235 return writeCommon(uri, uri, replace) ? DAE_OK : DAE_ERROR;
236 }
237
save(daeUInt documentIndex,daeBool replace)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
saveAs(daeString uriToSaveTo,daeString docUri,daeBool replace)247 daeInt DAE::saveAs(daeString uriToSaveTo, daeString docUri, daeBool replace) {
248 return writeCommon(docUri, uriToSaveTo, replace) ? DAE_OK : DAE_ERROR;
249 }
250
saveAs(daeString uriToSaveTo,daeUInt documentIndex,daeBool replace)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
unload(daeString uri)259 daeInt DAE::unload(daeString uri) {
260 close(uri);
261 return DAE_OK;
262 }
263
264
getDocCount()265 int DAE::getDocCount() {
266 return (int)database->getDocumentCount();
267 }
268
getDoc(int i)269 daeDocument* DAE::getDoc(int i) {
270 return database->getDocument(i);
271 }
272
getDoc(const string & path)273 daeDocument* DAE::getDoc(const string& path) {
274 return database->getDocument(makeFullUri(path).c_str(), true);
275 }
276
getRoot(const string & path)277 domCOLLADA* DAE::getRoot(const string& path) {
278 if (daeDocument* doc = getDoc(path))
279 return (domCOLLADA*)doc->getDomRoot();
280 return NULL;
281 }
282
setRoot(const string & path,domCOLLADA * root)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
getDom(daeString uri)291 domCOLLADA* DAE::getDom(daeString uri) {
292 return getRoot(uri);
293 }
294
setDom(daeString uri,domCOLLADA * dom)295 daeInt DAE::setDom(daeString uri, domCOLLADA* dom) {
296 return setRoot(uri, dom);
297 }
298
getDomVersion()299 daeString DAE::getDomVersion()
300 {
301 return(COLLADA_VERSION);
302 }
303
getAtomicTypes()304 daeAtomicTypeList& DAE::getAtomicTypes() {
305 return atomicTypes;
306 }
307
getMeta(daeInt typeID)308 daeMetaElement* DAE::getMeta(daeInt typeID) {
309 if (typeID < 0 || typeID >= daeInt(metas.getCount()))
310 return NULL;
311 return metas[typeID];
312 }
313
getAllMetas()314 daeMetaElementRefArray& DAE::getAllMetas() {
315 return metas;
316 }
317
setMeta(daeInt typeID,daeMetaElement & meta)318 void DAE::setMeta(daeInt typeID, daeMetaElement& meta) {
319 if (typeID < 0 || typeID >= daeInt(metas.getCount()))
320 return;
321 metas[typeID] = &meta;
322 }
323
getURIResolvers()324 daeURIResolverList& DAE::getURIResolvers() {
325 return uriResolvers;
326 }
327
getBaseURI()328 daeURI& DAE::getBaseURI() {
329 return baseUri;
330 }
331
setBaseURI(const daeURI & uri)332 void DAE::setBaseURI(const daeURI& uri) {
333 baseUri = uri;
334 }
335
setBaseURI(const string & uri)336 void DAE::setBaseURI(const string& uri) {
337 baseUri = uri.c_str();
338 }
339
getIDRefResolvers()340 daeIDRefResolverList& DAE::getIDRefResolvers() {
341 return idRefResolvers;
342 }
343
getRawRefCache()344 daeRawRefCache& DAE::getRawRefCache() {
345 return rawRefCache;
346 }
347
getSidRefCache()348 daeSidRefCache& DAE::getSidRefCache() {
349 return sidRefCache;
350 }
351
dummyFunction1()352 void DAE::dummyFunction1() { }
353
getGlobalCharEncoding()354 DAE::charEncoding DAE::getGlobalCharEncoding() {
355 return globalCharEncoding;
356 }
357
setGlobalCharEncoding(charEncoding encoding)358 void DAE::setGlobalCharEncoding(charEncoding encoding) {
359 globalCharEncoding = encoding;
360 }
361
getCharEncoding()362 DAE::charEncoding DAE::getCharEncoding() {
363 return localCharEncoding.get() ? *localCharEncoding : getGlobalCharEncoding();
364 }
365
setCharEncoding(charEncoding encoding)366 void DAE::setCharEncoding(charEncoding encoding) {
367 localCharEncoding.reset(new charEncoding(encoding));
368 }
369