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