mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 23:54:35 +00:00
Engine directory for ticket #1
This commit is contained in:
parent
352279af7a
commit
7dbfe6994d
3795 changed files with 1363358 additions and 0 deletions
362
Engine/lib/collada/src/dae/dae.cpp
Normal file
362
Engine/lib/collada/src/dae/dae.cpp
Normal file
|
|
@ -0,0 +1,362 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#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();
|
||||
//----------------------
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
28
Engine/lib/collada/src/dae/daeArray.cpp
Normal file
28
Engine/lib/collada/src/dae/daeArray.cpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <dae/daeArrayTypes.h>
|
||||
#include <dae/daeArray.h>
|
||||
|
||||
daeArray::daeArray():_count(0),_capacity(0),_data(NULL),_elementSize(4),_type(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
daeArray::~daeArray()
|
||||
{
|
||||
}
|
||||
|
||||
void daeArray::setElementSize(size_t elementSize) {
|
||||
clear();
|
||||
_elementSize = elementSize;
|
||||
}
|
||||
943
Engine/lib/collada/src/dae/daeAtomicType.cpp
Normal file
943
Engine/lib/collada/src/dae/daeAtomicType.cpp
Normal file
|
|
@ -0,0 +1,943 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include <dae/daeAtomicType.h>
|
||||
#include <dae/daeElement.h>
|
||||
#include <dae/daeURI.h>
|
||||
#include <dae/daeIDRef.h>
|
||||
#include <dae/daeMetaElement.h>
|
||||
#include <dae/daeDatabase.h>
|
||||
#include <dae/daeErrorHandler.h>
|
||||
#include <dae/daeUtils.h>
|
||||
|
||||
namespace {
|
||||
// Skip leading whitespace
|
||||
daeChar* skipWhitespace(daeChar* s) {
|
||||
if (s) {
|
||||
// !!!GAC NEEDS TO BE CHANGED to use XML standard whitespace parsing
|
||||
while(*s == ' ' || *s == '\r' || *s == '\n' || *s == '\t') s++;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
// Move forward past this token
|
||||
daeChar* skipToken(daeChar* s) {
|
||||
while(*s != ' ' && *s != '\r' && *s != '\n' && *s != '\t' && *s != 0) s++;
|
||||
return s;
|
||||
}
|
||||
|
||||
// Given a string of whitespace-separated tokens, this function returns a null-terminated string
|
||||
// containing the next token. If the next token is already null-terminated, no memory is allocated
|
||||
// and the function returns the pointer that was passed in. Note that this function assumes that
|
||||
// the string passed in starts with the next token and not a whitespace.
|
||||
// If returnValue != s, the client should free the returnValue with delete[].
|
||||
daeChar* extractToken(daeChar* s) {
|
||||
if (!s)
|
||||
return 0;
|
||||
|
||||
daeChar* tmp = skipToken(s);
|
||||
if (*tmp != 0) {
|
||||
daeChar* scopy = new daeChar[tmp-s+1];
|
||||
strncpy(scopy, s, tmp-s);
|
||||
scopy[tmp-s] = 0;
|
||||
return scopy;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
daeAtomicTypeList::daeAtomicTypeList(DAE& dae) {
|
||||
types.append(new daeUIntType(dae));
|
||||
types.append(new daeIntType(dae));
|
||||
types.append(new daeLongType(dae));
|
||||
types.append(new daeShortType(dae));
|
||||
types.append(new daeULongType(dae));
|
||||
types.append(new daeFloatType(dae));
|
||||
types.append(new daeDoubleType(dae));
|
||||
types.append(new daeStringRefType(dae));
|
||||
types.append(new daeElementRefType(dae));
|
||||
types.append(new daeEnumType(dae));
|
||||
types.append(new daeRawRefType(dae));
|
||||
types.append(new daeResolverType(dae));
|
||||
types.append(new daeIDResolverType(dae));
|
||||
types.append(new daeBoolType(dae));
|
||||
types.append(new daeTokenType(dae));
|
||||
}
|
||||
|
||||
daeAtomicTypeList::~daeAtomicTypeList() {
|
||||
for (size_t i = 0; i < types.getCount(); i++)
|
||||
delete types[i];
|
||||
}
|
||||
|
||||
daeInt daeAtomicTypeList::append(daeAtomicType* t) {
|
||||
return (daeInt)types.append(t);
|
||||
}
|
||||
|
||||
const daeAtomicType* daeAtomicTypeList::getByIndex(daeInt index) {
|
||||
return types[index];
|
||||
}
|
||||
|
||||
daeInt daeAtomicTypeList::getCount() {
|
||||
return (daeInt)types.getCount();
|
||||
}
|
||||
|
||||
daeAtomicType* daeAtomicTypeList::get(daeStringRef typeString) {
|
||||
for (size_t i = 0; i < types.getCount(); i++) {
|
||||
daeStringRefArray& nameBindings = types[i]->getNameBindings();
|
||||
for (size_t j = 0; j < nameBindings.getCount(); j++) {
|
||||
if (strcmp(typeString, nameBindings[j]) == 0)
|
||||
return types[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeAtomicType* daeAtomicTypeList::get(daeEnum typeEnum) {
|
||||
for (size_t i = 0; i < types.getCount(); i++)
|
||||
if (typeEnum == types[i]->getTypeEnum())
|
||||
return types[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
daeAtomicType::daeAtomicType(DAE& dae)
|
||||
{
|
||||
_dae = &dae;
|
||||
_size = -1;
|
||||
_alignment = -1;
|
||||
_typeEnum = -1;
|
||||
_typeString = "notype";
|
||||
_printFormat = "badtype";
|
||||
_scanFormat = "";
|
||||
_maxStringLength = -1;
|
||||
}
|
||||
|
||||
daeBool
|
||||
daeAtomicType::stringToMemory(daeChar *src, daeChar* dstMemory)
|
||||
{
|
||||
sscanf(src, _scanFormat, dstMemory);
|
||||
return true;
|
||||
}
|
||||
|
||||
void daeAtomicType::arrayToString(daeArray& array, std::ostringstream& buffer) {
|
||||
if (array.getCount() > 0)
|
||||
memoryToString(array.getRaw(0), buffer);
|
||||
for (size_t i = 1; i < array.getCount(); i++) {
|
||||
buffer << ' ';
|
||||
memoryToString(array.getRaw(i), buffer);
|
||||
}
|
||||
}
|
||||
|
||||
daeBool
|
||||
daeAtomicType::stringToArray(daeChar* src, daeArray& array) {
|
||||
array.clear();
|
||||
array.setElementSize(_size);
|
||||
|
||||
if (src == 0)
|
||||
return false;
|
||||
|
||||
// We're about to insert null terminators into the string so that scanf doesn't take forever
|
||||
// doing strlens. Since the memory might not be writable, I need to duplicate the string and
|
||||
// write into the duplicate, or else I might get access violations.
|
||||
// This sucks... surely we can do better than this.
|
||||
daeChar* srcDup = new daeChar[strlen(src)+1];
|
||||
strcpy(srcDup, src);
|
||||
src = srcDup;
|
||||
|
||||
while (*src != 0)
|
||||
{
|
||||
src = skipWhitespace(src);
|
||||
if(*src != 0)
|
||||
{
|
||||
daeChar* token = src;
|
||||
src = skipToken(src);
|
||||
daeChar temp = *src;
|
||||
*src = 0;
|
||||
|
||||
array.setCount(array.getCount()+1);
|
||||
if (!stringToMemory(token, array.getRaw(array.getCount()-1))) {
|
||||
delete[] srcDup;
|
||||
return false;
|
||||
}
|
||||
|
||||
*src = temp;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] srcDup;
|
||||
return true;
|
||||
}
|
||||
|
||||
daeInt daeAtomicType::compareArray(daeArray& value1, daeArray& value2) {
|
||||
if (value1.getCount() != value2.getCount())
|
||||
return value1.getCount() > value2.getCount() ? 1 : -1;
|
||||
|
||||
for (size_t i = 0; i < value1.getCount(); i++) {
|
||||
daeInt result = compare(value1.getRaw(i), value2.getRaw(i));
|
||||
if (result != 0)
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void daeAtomicType::copyArray(daeArray& src, daeArray& dst) {
|
||||
dst.setCount(src.getCount());
|
||||
for (size_t i = 0; i < src.getCount(); i++)
|
||||
copy(src.getRaw(i), dst.getRaw(i));
|
||||
}
|
||||
|
||||
daeInt
|
||||
daeAtomicType::compare(daeChar* value1, daeChar* value2) {
|
||||
return memcmp(value1, value2, _size);
|
||||
}
|
||||
|
||||
daeEnumType::daeEnumType(DAE& dae) : daeAtomicType(dae)
|
||||
{
|
||||
_size = sizeof(daeEnum);
|
||||
_alignment = sizeof(daeEnum);
|
||||
_typeEnum = EnumType;
|
||||
_nameBindings.append("enum");
|
||||
_printFormat = "%s";//"%%.%ds";
|
||||
_scanFormat = "%s";
|
||||
_strings = NULL;
|
||||
_values = NULL;
|
||||
_typeString = "enum";
|
||||
}
|
||||
|
||||
daeEnumType::~daeEnumType() {
|
||||
if ( _strings ) {
|
||||
delete _strings;
|
||||
_strings = NULL;
|
||||
}
|
||||
if ( _values ) {
|
||||
delete _values;
|
||||
_values = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
daeBoolType::daeBoolType(DAE& dae) : daeAtomicType(dae)
|
||||
{
|
||||
_size = sizeof(daeBool);
|
||||
_alignment = sizeof(daeBool);
|
||||
_typeEnum = BoolType;
|
||||
_printFormat = "%d";
|
||||
_scanFormat = "%d";
|
||||
_typeString = "bool";
|
||||
_maxStringLength = (daeInt)strlen("false")+1;
|
||||
_nameBindings.append("bool");
|
||||
//_nameBindings.append("xsBool");
|
||||
_nameBindings.append("xsBoolean");
|
||||
}
|
||||
|
||||
daeIntType::daeIntType(DAE& dae) : daeAtomicType(dae)
|
||||
{
|
||||
_size = sizeof(daeInt);
|
||||
_alignment = sizeof(daeInt);
|
||||
_typeEnum = IntType;
|
||||
_maxStringLength = 16;
|
||||
_nameBindings.append("int");
|
||||
_nameBindings.append("xsInteger");
|
||||
_nameBindings.append("xsHexBinary");
|
||||
_nameBindings.append("xsIntegerArray");
|
||||
_nameBindings.append("xsHexBinaryArray");
|
||||
_nameBindings.append("xsByte");
|
||||
_nameBindings.append("xsInt");
|
||||
_printFormat = "%d";
|
||||
_scanFormat = "%d";
|
||||
_typeString = "int";
|
||||
}
|
||||
daeLongType::daeLongType(DAE& dae) : daeAtomicType(dae)
|
||||
{
|
||||
_size = sizeof(daeLong);
|
||||
_alignment = sizeof(daeLong);
|
||||
_typeEnum = LongType;
|
||||
_maxStringLength = 32;
|
||||
_nameBindings.append("xsLong");
|
||||
_nameBindings.append("xsLongArray");
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
_printFormat = "%I64d";
|
||||
_scanFormat = "%I64d";
|
||||
#else
|
||||
_printFormat = "%lld";
|
||||
_scanFormat = "%lld";
|
||||
#endif
|
||||
_typeString = "long";
|
||||
}
|
||||
daeShortType::daeShortType(DAE& dae) : daeAtomicType(dae)
|
||||
{
|
||||
_maxStringLength = 8;
|
||||
_size = sizeof(daeShort);
|
||||
_alignment = sizeof(daeShort);
|
||||
_typeEnum = ShortType;
|
||||
_nameBindings.append("short");
|
||||
_nameBindings.append("xsShort");
|
||||
_printFormat = "%hd";
|
||||
_scanFormat = "%hd";
|
||||
_typeString = "short";
|
||||
}
|
||||
daeUIntType::daeUIntType(DAE& dae) : daeAtomicType(dae)
|
||||
{
|
||||
_maxStringLength = 16;
|
||||
_size = sizeof(daeUInt);
|
||||
_alignment = sizeof(daeUInt);
|
||||
_typeEnum = UIntType;
|
||||
_nameBindings.append("uint");
|
||||
_nameBindings.append("xsNonNegativeInteger");
|
||||
_nameBindings.append("xsUnsignedByte");
|
||||
_nameBindings.append("xsUnsignedInt");
|
||||
_nameBindings.append("xsPositiveInteger");
|
||||
_printFormat = "%u";
|
||||
_scanFormat = "%u";
|
||||
_typeString = "uint";
|
||||
}
|
||||
daeULongType::daeULongType(DAE& dae) : daeAtomicType(dae)
|
||||
{
|
||||
_size = sizeof(daeULong);
|
||||
_alignment = sizeof(daeULong);
|
||||
_typeEnum = ULongType;
|
||||
_maxStringLength = 32;
|
||||
_nameBindings.append("ulong");
|
||||
_nameBindings.append("xsUnsignedLong");
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
_printFormat = "%I64u";
|
||||
_scanFormat = "%I64u";
|
||||
#else
|
||||
_printFormat = "%llu";
|
||||
_scanFormat = "%llu";
|
||||
#endif
|
||||
_typeString = "ulong";
|
||||
}
|
||||
daeFloatType::daeFloatType(DAE& dae) : daeAtomicType(dae)
|
||||
{
|
||||
_maxStringLength = 64;
|
||||
_size = sizeof(daeFloat);
|
||||
_alignment = sizeof(daeFloat);
|
||||
_typeEnum = FloatType;
|
||||
_nameBindings.append("float");
|
||||
_nameBindings.append("xsFloat");
|
||||
_printFormat = "%g";
|
||||
_scanFormat = "%g";
|
||||
_typeString = "float";
|
||||
}
|
||||
daeDoubleType::daeDoubleType(DAE& dae) : daeAtomicType(dae)
|
||||
{
|
||||
_size = sizeof(daeDouble);
|
||||
_alignment = sizeof(daeDouble);
|
||||
_typeEnum = DoubleType;
|
||||
_nameBindings.append("double");
|
||||
_nameBindings.append("xsDouble");
|
||||
_nameBindings.append("xsDecimal");
|
||||
_printFormat = "%lg";
|
||||
_scanFormat = "%lg";
|
||||
_typeString = "double";
|
||||
_maxStringLength = 64;
|
||||
}
|
||||
|
||||
daeStringRefType::daeStringRefType(DAE& dae) : daeAtomicType(dae)
|
||||
{
|
||||
_size = sizeof(daeStringRef);
|
||||
_alignment = sizeof(daeStringRef);
|
||||
_typeEnum = StringRefType;
|
||||
_nameBindings.append("string");
|
||||
_nameBindings.append("xsString");
|
||||
_nameBindings.append("xsDateTime");
|
||||
_printFormat = "%s";
|
||||
_scanFormat = "%s";
|
||||
_typeString = "string";
|
||||
}
|
||||
|
||||
daeTokenType::daeTokenType(DAE& dae) : daeStringRefType(dae)
|
||||
{
|
||||
_size = sizeof(daeStringRef);
|
||||
_alignment = sizeof(daeStringRef);
|
||||
_typeEnum = TokenType;
|
||||
_nameBindings.append("token");
|
||||
_nameBindings.append("xsID");
|
||||
_nameBindings.append("xsNCName");
|
||||
_nameBindings.append("xsNMTOKEN");
|
||||
_nameBindings.append("xsName");
|
||||
_nameBindings.append("xsToken");
|
||||
_nameBindings.append("xsNameArray");
|
||||
_nameBindings.append("xsTokenArray");
|
||||
_nameBindings.append("xsNCNameArray");
|
||||
_printFormat = "%s";
|
||||
_scanFormat = "%s";
|
||||
_typeString = "token";
|
||||
}
|
||||
|
||||
daeElementRefType::daeElementRefType(DAE& dae) : daeAtomicType(dae)
|
||||
{
|
||||
_size = sizeof(daeElementRef);
|
||||
_alignment = sizeof(daeElementRef);
|
||||
_typeEnum = ElementRefType;
|
||||
_nameBindings.append("element");
|
||||
_nameBindings.append("Element");
|
||||
_nameBindings.append("TrackedElement");
|
||||
_printFormat = "%p";
|
||||
_scanFormat = "%p";
|
||||
_typeString = "element";
|
||||
_maxStringLength = 64;
|
||||
}
|
||||
|
||||
daeRawRefType::daeRawRefType(DAE& dae) : daeAtomicType(dae)
|
||||
{
|
||||
_size = sizeof(daeRawRef);
|
||||
_alignment = sizeof(daeRawRef);
|
||||
_typeEnum = RawRefType;
|
||||
_nameBindings.append("raw");
|
||||
_printFormat = "%p";
|
||||
_scanFormat = "%p";
|
||||
_typeString = "raw";
|
||||
_maxStringLength = 64;
|
||||
}
|
||||
|
||||
daeResolverType::daeResolverType(DAE& dae) : daeAtomicType(dae)
|
||||
{
|
||||
_size = sizeof(daeURI);
|
||||
_alignment = sizeof(daeURI);
|
||||
_typeEnum = ResolverType;
|
||||
_nameBindings.append("resolver");
|
||||
_nameBindings.append("xsAnyURI");
|
||||
_printFormat = "%s";
|
||||
_scanFormat = "%s";
|
||||
_typeString = "resolver";
|
||||
}
|
||||
daeIDResolverType::daeIDResolverType(DAE& dae) : daeAtomicType(dae)
|
||||
{
|
||||
_size = sizeof(daeIDRef);
|
||||
_alignment = sizeof(daeIDRef);
|
||||
_typeEnum = IDResolverType;
|
||||
_nameBindings.append("xsIDREF");
|
||||
_nameBindings.append("xsIDREFS");
|
||||
_printFormat = "%s";
|
||||
_scanFormat = "%s";
|
||||
_typeString = "idref_resolver";
|
||||
}
|
||||
|
||||
daeBool daeIntType::memoryToString(daeChar* src, std::ostringstream& dst) {
|
||||
dst << *(daeInt*)src;
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool daeLongType::memoryToString(daeChar* src, std::ostringstream& dst) {
|
||||
dst << *(daeLong*)src;
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool daeShortType::memoryToString(daeChar* src, std::ostringstream& dst) {
|
||||
dst << *(daeShort*)src;
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool daeUIntType::memoryToString(daeChar* src, std::ostringstream& dst) {
|
||||
dst << *(daeUInt*)src;
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool daeULongType::memoryToString(daeChar* src, std::ostringstream& dst) {
|
||||
#ifdef _MSC_VER
|
||||
// Microsoft's stringstream implementation has weird performance issues
|
||||
static char buffer[64];
|
||||
_snprintf(buffer, 64, _printFormat, *((daeULong*)src));
|
||||
dst << buffer;
|
||||
#else
|
||||
dst << *(daeULong*)src;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool daeFloatType::memoryToString(daeChar* src, std::ostringstream& dst) {
|
||||
if ( *(daeFloat*)src != *(daeFloat*)src ) // NAN
|
||||
dst << "NaN";
|
||||
else if ( *(daeUInt*)src == 0x7f800000 ) // +INF
|
||||
dst << "INF";
|
||||
else if ( *(daeUInt*)src == 0xff800000 ) // -INF
|
||||
dst << "-INF";
|
||||
else
|
||||
dst << *(daeFloat*)src;
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool
|
||||
daeFloatType::stringToMemory(daeChar *src, daeChar* dstMemory)
|
||||
{
|
||||
src = skipWhitespace(src);
|
||||
|
||||
if ( strncmp(src, "NaN", 3) == 0 ) {
|
||||
daeErrorHandler::get()->handleWarning("NaN encountered while setting an attribute or value\n");
|
||||
*(daeInt*)(dstMemory) = 0x7f800002;
|
||||
}
|
||||
else if ( strncmp(src, "INF", 3) == 0 ) {
|
||||
daeErrorHandler::get()->handleWarning( "INF encountered while setting an attribute or value\n" );
|
||||
*(daeInt*)(dstMemory) = 0x7f800000;
|
||||
}
|
||||
else if ( strncmp(src, "-INF", 4) == 0 ) {
|
||||
daeErrorHandler::get()->handleWarning( "-INF encountered while setting an attribute or value\n" );
|
||||
*(daeInt*)(dstMemory) = 0xff800000;
|
||||
}
|
||||
else
|
||||
{
|
||||
sscanf(src, _scanFormat, dstMemory);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool daeDoubleType::memoryToString(daeChar* src, std::ostringstream& dst) {
|
||||
if ( *(daeDouble*)src != *(daeDouble*)src ) // NAN
|
||||
dst << "NaN";
|
||||
else if ( *(daeULong*)src == 0x7ff0000000000000LL ) // +INF
|
||||
dst << "INF";
|
||||
else if ( *(daeULong*)src == 0xfff0000000000000LL ) // -INF
|
||||
dst << "-INF";
|
||||
else {
|
||||
#ifdef _MSC_VER
|
||||
// Microsoft's stringstream implementation has weird performance issues
|
||||
static char buffer[64];
|
||||
_snprintf(buffer, 64, _printFormat, *((daeDouble*)src));
|
||||
dst << buffer;
|
||||
#else
|
||||
dst << *(daeDouble*)src;
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool
|
||||
daeDoubleType::stringToMemory(daeChar *src, daeChar* dstMemory)
|
||||
{
|
||||
src = skipWhitespace(src);
|
||||
|
||||
if ( strncmp(src, "NaN", 3) == 0 ) {
|
||||
daeErrorHandler::get()->handleWarning( "NaN encountered while setting an attribute or value\n" );
|
||||
*(daeLong*)(dstMemory) = 0x7ff0000000000002LL;
|
||||
}
|
||||
else if ( strncmp(src, "INF", 3) == 0 ) {
|
||||
daeErrorHandler::get()->handleWarning( "INF encountered while setting an attribute or value\n" );
|
||||
*(daeLong*)(dstMemory) = 0x7ff0000000000000LL;
|
||||
}
|
||||
else if ( strncmp(src, "-INF", 4) == 0 ) {
|
||||
daeErrorHandler::get()->handleWarning( "-INF encountered while setting an attribute or value\n" );
|
||||
*(daeLong*)(dstMemory) = 0xfff0000000000000LL;
|
||||
}
|
||||
else
|
||||
{
|
||||
sscanf(src, _scanFormat, dstMemory);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool daeRawRefType::memoryToString(daeChar* src, std::ostringstream& dst) {
|
||||
dst << (void *)(*((daeRawRef*)src));
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool daeStringRefType::memoryToString(daeChar* src, std::ostringstream& dst) {
|
||||
daeString s = *((daeStringRef *)src);
|
||||
if (s)
|
||||
dst << s;
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool daeResolverType::memoryToString(daeChar* src, std::ostringstream& dst) {
|
||||
// Get the URI we are trying to write
|
||||
daeURI *thisURI = ((daeURI *)src);
|
||||
// Encode spaces with %20
|
||||
dst << cdom::replace(thisURI->originalStr(), " ", "%20");
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool daeIDResolverType::memoryToString(daeChar* src, std::ostringstream& dst) {
|
||||
dst << ((daeIDRef *)src)->getID();
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool
|
||||
daeResolverType::stringToMemory(daeChar* src, daeChar* dstMemory)
|
||||
{
|
||||
((daeURI*)dstMemory)->set(cdom::replace(src, " ", "%20"));
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool
|
||||
daeIDResolverType::stringToMemory(daeChar* src, daeChar* dstMemory)
|
||||
{
|
||||
src = skipWhitespace(src);
|
||||
daeChar* id = extractToken(src);
|
||||
((daeIDRef*)dstMemory)->setID(id);
|
||||
if (id != src)
|
||||
delete[] id;
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool
|
||||
daeStringRefType::stringToMemory(daeChar* srcChars, daeChar* dstMemory)
|
||||
{
|
||||
*((daeStringRef*)dstMemory) = srcChars;
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool
|
||||
daeTokenType::stringToMemory(daeChar* src, daeChar* dst)
|
||||
{
|
||||
src = skipWhitespace(src);
|
||||
daeChar* srcTmp = extractToken(src);
|
||||
*((daeStringRef*)dst) = srcTmp;
|
||||
if (srcTmp != src)
|
||||
delete[] srcTmp;
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool
|
||||
daeEnumType::stringToMemory(daeChar* src, daeChar* dst )
|
||||
{
|
||||
src = skipWhitespace(src);
|
||||
daeChar* srcTmp = extractToken(src);
|
||||
|
||||
size_t index(0);
|
||||
bool result = _strings->find(srcTmp, index) != DAE_ERR_QUERY_NO_MATCH;
|
||||
if (result) {
|
||||
daeEnum val = _values->get( index );
|
||||
*((daeEnum*)dst) = val;
|
||||
}
|
||||
|
||||
if (srcTmp != src)
|
||||
delete[] srcTmp;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
daeBool daeEnumType::memoryToString(daeChar* src, std::ostringstream& dst) {
|
||||
daeStringRef s = "unknown";
|
||||
if (_strings != NULL) {
|
||||
size_t index;
|
||||
if (_values->find(*((daeEnum*)src), index) == DAE_OK)
|
||||
s = _strings->get(index);
|
||||
}
|
||||
dst << (const char*)s;
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool
|
||||
daeBoolType::stringToMemory(daeChar* srcChars, daeChar* dstMemory)
|
||||
{
|
||||
if (strncmp(srcChars,"true",4)==0 || strncmp(srcChars,"1",1)==0)
|
||||
*((daeBool*)dstMemory) = true;
|
||||
else
|
||||
*((daeBool*)dstMemory) = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool daeBoolType::memoryToString(daeChar* src, std::ostringstream& dst) {
|
||||
if (*((daeBool*)src))
|
||||
dst << "true";
|
||||
else
|
||||
dst << "false";
|
||||
return true;
|
||||
}
|
||||
//!!!ACL added for 1.4 complex types and groups
|
||||
|
||||
// Unimplemented
|
||||
daeBool daeElementRefType::memoryToString(daeChar* src, std::ostringstream& dst) {
|
||||
(void)src;
|
||||
(void)dst;
|
||||
return false;
|
||||
}
|
||||
|
||||
daeMemoryRef daeBoolType::create() {
|
||||
return (daeMemoryRef)new daeBool;
|
||||
}
|
||||
|
||||
daeMemoryRef daeIntType::create() {
|
||||
return (daeMemoryRef)new daeInt;
|
||||
}
|
||||
|
||||
daeMemoryRef daeLongType::create() {
|
||||
return (daeMemoryRef)new daeLong;
|
||||
}
|
||||
|
||||
daeMemoryRef daeUIntType::create() {
|
||||
return (daeMemoryRef)new daeUInt;
|
||||
}
|
||||
|
||||
daeMemoryRef daeULongType::create() {
|
||||
return (daeMemoryRef)new daeULong;
|
||||
}
|
||||
|
||||
daeMemoryRef daeShortType::create() {
|
||||
return (daeMemoryRef)new daeShort;
|
||||
}
|
||||
|
||||
daeMemoryRef daeFloatType::create() {
|
||||
return (daeMemoryRef)new daeFloat;
|
||||
}
|
||||
|
||||
daeMemoryRef daeDoubleType::create() {
|
||||
return (daeMemoryRef)new daeDouble;
|
||||
}
|
||||
|
||||
daeMemoryRef daeStringRefType::create() {
|
||||
return (daeMemoryRef)new daeStringRef;
|
||||
}
|
||||
|
||||
daeMemoryRef daeTokenType::create() {
|
||||
return (daeMemoryRef)new daeStringRef;
|
||||
}
|
||||
|
||||
daeMemoryRef daeElementRefType::create() {
|
||||
return (daeMemoryRef)new daeElementRef;
|
||||
}
|
||||
|
||||
daeMemoryRef daeEnumType::create() {
|
||||
return (daeMemoryRef)new daeEnum;
|
||||
}
|
||||
|
||||
daeMemoryRef daeRawRefType::create() {
|
||||
return (daeMemoryRef)new daeRawRef;
|
||||
}
|
||||
|
||||
daeMemoryRef daeResolverType::create() {
|
||||
return (daeMemoryRef)new daeURI(*_dae);
|
||||
}
|
||||
|
||||
daeMemoryRef daeIDResolverType::create() {
|
||||
return (daeMemoryRef)new daeIDRef;
|
||||
}
|
||||
|
||||
|
||||
void daeBoolType::destroy(daeMemoryRef obj) {
|
||||
delete (daeBool*)obj;
|
||||
}
|
||||
|
||||
void daeIntType::destroy(daeMemoryRef obj) {
|
||||
delete (daeInt*)obj;
|
||||
}
|
||||
|
||||
void daeLongType::destroy(daeMemoryRef obj) {
|
||||
delete (daeLong*)obj;
|
||||
}
|
||||
|
||||
void daeUIntType::destroy(daeMemoryRef obj) {
|
||||
delete (daeUInt*)obj;
|
||||
}
|
||||
|
||||
void daeULongType::destroy(daeMemoryRef obj) {
|
||||
delete (daeULong*)obj;
|
||||
}
|
||||
|
||||
void daeShortType::destroy(daeMemoryRef obj) {
|
||||
delete (daeShort*)obj;
|
||||
}
|
||||
|
||||
void daeFloatType::destroy(daeMemoryRef obj) {
|
||||
delete (daeFloat*)obj;
|
||||
}
|
||||
|
||||
void daeDoubleType::destroy(daeMemoryRef obj) {
|
||||
delete (daeDouble*)obj;
|
||||
}
|
||||
|
||||
void daeStringRefType::destroy(daeMemoryRef obj) {
|
||||
delete (daeStringRef*)obj;
|
||||
}
|
||||
|
||||
void daeTokenType::destroy(daeMemoryRef obj) {
|
||||
delete (daeStringRef*)obj;
|
||||
}
|
||||
|
||||
void daeElementRefType::destroy(daeMemoryRef obj) {
|
||||
delete (daeElementRef*)obj;
|
||||
}
|
||||
|
||||
void daeEnumType::destroy(daeMemoryRef obj) {
|
||||
delete (daeEnum*)obj;
|
||||
}
|
||||
|
||||
void daeRawRefType::destroy(daeMemoryRef obj) {
|
||||
delete (daeRawRef*)obj;
|
||||
}
|
||||
|
||||
void daeResolverType::destroy(daeMemoryRef obj) {
|
||||
delete (daeURI*)obj;
|
||||
}
|
||||
|
||||
void daeIDResolverType::destroy(daeMemoryRef obj) {
|
||||
delete (daeIDRef*)obj;
|
||||
}
|
||||
|
||||
|
||||
daeInt daeStringRefType::compare(daeChar* value1, daeChar* value2) {
|
||||
daeString s1 = *((daeStringRef *)value1);
|
||||
daeString s2 = *((daeStringRef *)value2);
|
||||
// For string types, the empty string and null are considered equivalent
|
||||
if (!s1)
|
||||
s1 = "";
|
||||
if (!s2)
|
||||
s2 = "";
|
||||
return strcmp(s1, s2);
|
||||
}
|
||||
|
||||
daeInt daeResolverType::compare(daeChar* value1, daeChar* value2) {
|
||||
return strcmp(((daeURI*)value1)->str().c_str(), ((daeURI*)value2)->str().c_str());
|
||||
}
|
||||
|
||||
daeInt daeIDResolverType::compare(daeChar* value1, daeChar* value2) {
|
||||
return (daeIDRef&)*value1 == (daeIDRef&)*value2;
|
||||
}
|
||||
|
||||
|
||||
daeArray* daeBoolType::createArray() {
|
||||
return new daeTArray<daeBool>;
|
||||
}
|
||||
|
||||
daeArray* daeIntType::createArray() {
|
||||
return new daeTArray<daeInt>;
|
||||
}
|
||||
|
||||
daeArray* daeLongType::createArray() {
|
||||
return new daeTArray<daeLong>;
|
||||
}
|
||||
|
||||
daeArray* daeUIntType::createArray() {
|
||||
return new daeTArray<daeUInt>;
|
||||
}
|
||||
|
||||
daeArray* daeULongType::createArray() {
|
||||
return new daeTArray<daeULong>;
|
||||
}
|
||||
|
||||
daeArray* daeShortType::createArray() {
|
||||
return new daeTArray<daeShort>;
|
||||
}
|
||||
|
||||
daeArray* daeFloatType::createArray() {
|
||||
return new daeTArray<daeFloat>;
|
||||
}
|
||||
|
||||
daeArray* daeDoubleType::createArray() {
|
||||
return new daeTArray<daeDouble>;
|
||||
}
|
||||
|
||||
daeArray* daeStringRefType::createArray() {
|
||||
return new daeTArray<daeStringRef>;
|
||||
}
|
||||
|
||||
daeArray* daeTokenType::createArray() {
|
||||
return new daeTArray<daeStringRef>;
|
||||
}
|
||||
|
||||
daeArray* daeElementRefType::createArray() {
|
||||
return new daeTArray<daeElementRef>;
|
||||
}
|
||||
|
||||
daeArray* daeEnumType::createArray() {
|
||||
return new daeTArray<daeEnum>;
|
||||
}
|
||||
|
||||
daeArray* daeRawRefType::createArray() {
|
||||
return new daeTArray<daeRawRef>;
|
||||
}
|
||||
|
||||
daeArray* daeResolverType::createArray() {
|
||||
// !!!steveT
|
||||
// The daeURI object no longer has a constructor that takes no arguments, so
|
||||
// it's not compatible with daeTArray. Therefore this method currently can't be used,
|
||||
// and asserts if you try to use it. The DOM doesn't ever call this code now,
|
||||
// so the situation is sort of alright, but we might need to fix this in the future.
|
||||
assert(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeArray* daeIDResolverType::createArray() {
|
||||
return new daeTArray<daeIDRef>;
|
||||
}
|
||||
|
||||
|
||||
void daeBoolType::copy(daeChar* src, daeChar* dst) {
|
||||
(daeBool&)*dst = (daeBool&)*src;
|
||||
}
|
||||
|
||||
void daeIntType::copy(daeChar* src, daeChar* dst) {
|
||||
(daeInt&)*dst = (daeInt&)*src;
|
||||
}
|
||||
|
||||
void daeLongType::copy(daeChar* src, daeChar* dst) {
|
||||
(daeLong&)*dst = (daeLong&)*src;
|
||||
}
|
||||
|
||||
void daeUIntType::copy(daeChar* src, daeChar* dst) {
|
||||
(daeUInt&)*dst = (daeUInt&)*src;
|
||||
}
|
||||
|
||||
void daeULongType::copy(daeChar* src, daeChar* dst) {
|
||||
(daeULong&)*dst = (daeULong&)*src;
|
||||
}
|
||||
|
||||
void daeShortType::copy(daeChar* src, daeChar* dst) {
|
||||
(daeShort&)*dst = (daeShort&)*src;
|
||||
}
|
||||
|
||||
void daeFloatType::copy(daeChar* src, daeChar* dst) {
|
||||
(daeFloat&)*dst = (daeFloat&)*src;
|
||||
}
|
||||
|
||||
void daeDoubleType::copy(daeChar* src, daeChar* dst) {
|
||||
(daeDouble&)*dst = (daeDouble&)*src;
|
||||
}
|
||||
|
||||
void daeStringRefType::copy(daeChar* src, daeChar* dst) {
|
||||
(daeStringRef&)*dst = (daeStringRef&)*src;
|
||||
}
|
||||
|
||||
void daeTokenType::copy(daeChar* src, daeChar* dst) {
|
||||
(daeStringRef&)*dst = (daeStringRef&)*src;
|
||||
}
|
||||
|
||||
void daeElementRefType::copy(daeChar* src, daeChar* dst) {
|
||||
(daeElementRef&)*dst = (daeElementRef&)*src;
|
||||
}
|
||||
|
||||
void daeEnumType::copy(daeChar* src, daeChar* dst) {
|
||||
(daeEnum&)*dst = (daeEnum&)*src;
|
||||
}
|
||||
|
||||
void daeRawRefType::copy(daeChar* src, daeChar* dst) {
|
||||
(daeRawRef&)*dst = (daeRawRef&)*src;
|
||||
}
|
||||
|
||||
void daeResolverType::copy(daeChar* src, daeChar* dst) {
|
||||
(daeURI&)*dst = (daeURI&)*src;
|
||||
}
|
||||
|
||||
void daeIDResolverType::copy(daeChar* src, daeChar* dst) {
|
||||
(daeIDRef&)*dst = (daeIDRef&)*src;
|
||||
}
|
||||
|
||||
void daeResolverType::setDocument(daeChar* value, daeDocument* doc) {
|
||||
daeURI* uri = (daeURI*)value;
|
||||
uri->setContainer(uri->getContainer());
|
||||
}
|
||||
|
||||
void daeResolverType::setDocument(daeArray& array, daeDocument* doc) {
|
||||
// !!!steveT
|
||||
// The daeURI object no longer has a constructor that takes no arguments, so
|
||||
// it's not compatible with daeTArray. Therefore this method currently can't be used,
|
||||
// and asserts if you try to use it. The DOM doesn't ever call this code now,
|
||||
// so the situation is sort of alright, but we might need to fix this in the future.
|
||||
assert(false);
|
||||
}
|
||||
45
Engine/lib/collada/src/dae/daeDatabase.cpp
Normal file
45
Engine/lib/collada/src/dae/daeDatabase.cpp
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright 2007 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include "dae/daeDatabase.h"
|
||||
using namespace std;
|
||||
|
||||
daeDatabase::daeDatabase(DAE& dae) : dae(dae) { }
|
||||
|
||||
DAE* daeDatabase::getDAE() {
|
||||
return &dae;
|
||||
}
|
||||
|
||||
daeDocument* daeDatabase::getDoc(daeUInt index) {
|
||||
return getDocument(index);
|
||||
}
|
||||
|
||||
daeElement* daeDatabase::idLookup(const string& id, daeDocument* doc) {
|
||||
vector<daeElement*> elts = idLookup(id);
|
||||
for (size_t i = 0; i < elts.size(); i++)
|
||||
if (elts[i]->getDocument() == doc)
|
||||
return elts[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vector<daeElement*> daeDatabase::typeLookup(daeInt typeID, daeDocument* doc) {
|
||||
vector<daeElement*> result;
|
||||
typeLookup(typeID, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<daeElement*> daeDatabase::sidLookup(const string& sid, daeDocument* doc) {
|
||||
vector<daeElement*> result;
|
||||
sidLookup(sid, result, doc);
|
||||
return result;
|
||||
}
|
||||
54
Engine/lib/collada/src/dae/daeDocument.cpp
Normal file
54
Engine/lib/collada/src/dae/daeDocument.cpp
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <dae.h>
|
||||
#include <dae/daeDocument.h>
|
||||
#include <dae/daeDatabase.h>
|
||||
|
||||
|
||||
daeDocument::daeDocument(DAE& dae) : dae(&dae), uri(dae) { }
|
||||
|
||||
daeDocument::~daeDocument() {
|
||||
}
|
||||
|
||||
void daeDocument::insertElement( daeElementRef element ) {
|
||||
dae->getDatabase()->insertElement( this, element.cast() );
|
||||
}
|
||||
|
||||
void daeDocument::removeElement( daeElementRef element ) {
|
||||
dae->getDatabase()->removeElement( this, element.cast() );
|
||||
}
|
||||
|
||||
void daeDocument::changeElementID( daeElementRef element, daeString newID ) {
|
||||
dae->getDatabase()->changeElementID( element.cast(), newID );
|
||||
}
|
||||
|
||||
void daeDocument::changeElementSID( daeElementRef element, daeString newSID ) {
|
||||
dae->getDatabase()->changeElementSID( element.cast(), newSID );
|
||||
}
|
||||
|
||||
void daeDocument::addExternalReference( daeURI &uri ) {
|
||||
if ( uri.getContainer() == NULL || uri.getContainer()->getDocument() != this ) {
|
||||
return;
|
||||
}
|
||||
daeURI tempURI( *dae, uri.getURI(), true ); // Remove fragment
|
||||
referencedDocuments.appendUnique( tempURI.getURI() );
|
||||
}
|
||||
|
||||
DAE* daeDocument::getDAE() {
|
||||
return dae;
|
||||
}
|
||||
|
||||
daeDatabase* daeDocument::getDatabase() {
|
||||
return dae->getDatabase();
|
||||
}
|
||||
22
Engine/lib/collada/src/dae/daeDom.cpp
Normal file
22
Engine/lib/collada/src/dae/daeDom.cpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
#include <dae.h>
|
||||
#include <dae/daeDom.h>
|
||||
#include <dae/daeMetaElement.h>
|
||||
#include <dom.h>
|
||||
|
||||
daeMetaElement* initializeDomMeta(DAE& dae)
|
||||
{
|
||||
registerDomTypes(dae);
|
||||
return registerDomElements(dae);
|
||||
}
|
||||
758
Engine/lib/collada/src/dae/daeElement.cpp
Normal file
758
Engine/lib/collada/src/dae/daeElement.cpp
Normal file
|
|
@ -0,0 +1,758 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <iomanip>
|
||||
#include <dae/daeElement.h>
|
||||
#include <dae/daeArray.h>
|
||||
#include <dae/daeMetaAttribute.h>
|
||||
#include <dae/daeMetaElementAttribute.h>
|
||||
#include <dae/daeMetaElement.h>
|
||||
#include <dae/daeDatabase.h>
|
||||
#include <dae/daeErrorHandler.h>
|
||||
#include <dae/daeURI.h>
|
||||
#include <dae/domAny.h>
|
||||
#include <dae/daeUtils.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
daeElement* daeElement::simpleAdd(daeString name, int index) {
|
||||
if (daeElementRef elt = _meta->create(name))
|
||||
return add(elt, index);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeElement* daeElement::add(daeString names_, int index) {
|
||||
list<string> names;
|
||||
cdom::tokenize(names_, " ", names);
|
||||
cdom::tokenIter iter = names.begin();
|
||||
daeElement* root = simpleAdd(iter->c_str(), index);
|
||||
if (!root)
|
||||
return NULL;
|
||||
|
||||
iter++;
|
||||
daeElement* elt = root;
|
||||
for (; iter != names.end(); iter++) {
|
||||
elt = elt->simpleAdd(iter->c_str());
|
||||
if (!elt) {
|
||||
removeChildElement(root);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return elt;
|
||||
}
|
||||
|
||||
daeElement* daeElement::add(daeElement* elt, int index) {
|
||||
if (!elt)
|
||||
return NULL;
|
||||
if (elt == this)
|
||||
return this;
|
||||
bool result = (index == -1 ? _meta->place(this, elt) : _meta->placeAt(index, this, elt));
|
||||
return result ? elt : NULL;
|
||||
}
|
||||
|
||||
daeElement* daeElement::addBefore(daeElement* elt, daeElement* index) {
|
||||
if (!index || !elt || index->getParent() != this)
|
||||
return NULL;
|
||||
return _meta->placeBefore(index, this, elt) ? elt : NULL;
|
||||
}
|
||||
|
||||
daeElement* daeElement::addAfter(daeElement* elt, daeElement* index) {
|
||||
if (!index || !elt || index->getParent() != this)
|
||||
return NULL;
|
||||
return _meta->placeAfter(index, this, elt) ? elt : NULL;
|
||||
}
|
||||
|
||||
daeElementRef
|
||||
daeElement::createElement(daeString className)
|
||||
{
|
||||
daeElementRef elem = _meta->create(className);
|
||||
// Bug #225 work around
|
||||
// if ( elem != NULL)
|
||||
// elem->ref(); // change premature delete into memory leak.
|
||||
return elem;
|
||||
}
|
||||
|
||||
daeElement* daeElement::createAndPlace(daeString className) {
|
||||
return add(className);
|
||||
}
|
||||
|
||||
daeElement* daeElement::createAndPlaceAt(daeInt index, daeString className) {
|
||||
return add(className, index);
|
||||
}
|
||||
|
||||
daeBool daeElement::placeElement(daeElement* e) {
|
||||
return add(e) != NULL;
|
||||
}
|
||||
|
||||
daeBool daeElement::placeElementAt(daeInt index, daeElement* e) {
|
||||
return add(e, index) != NULL;
|
||||
}
|
||||
|
||||
daeBool daeElement::placeElementBefore( daeElement *marker, daeElement *element ) {
|
||||
return addBefore(element, marker) != NULL;
|
||||
}
|
||||
|
||||
daeBool daeElement::placeElementAfter( daeElement *marker, daeElement *element ) {
|
||||
return addAfter(element, marker) != NULL;
|
||||
}
|
||||
|
||||
daeInt daeElement::findLastIndexOf( daeString elementName ) {
|
||||
if ( _meta->getContents() != NULL ) {
|
||||
daeElementRefArray* contents =
|
||||
(daeElementRefArray*)_meta->getContents()->getWritableMemory(this);
|
||||
for ( int i = (int)contents->getCount()-1; i >= 0; --i ) {
|
||||
if ( strcmp( contents->get(i)->getElementName(), elementName ) == 0 ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
daeBool
|
||||
daeElement::removeChildElement(daeElement* element)
|
||||
{
|
||||
// error traps
|
||||
if(element==NULL)
|
||||
return false;
|
||||
if(element->_parent != this)
|
||||
return false;
|
||||
|
||||
return _meta->remove( this, element );
|
||||
}
|
||||
|
||||
void daeElement::setDocument( daeDocument *c, bool notifyDocument ) {
|
||||
if( _document == c )
|
||||
return;
|
||||
|
||||
// Notify our parent document if necessary.
|
||||
if ( _document != NULL && notifyDocument )
|
||||
_document->removeElement(this);
|
||||
_document = c;
|
||||
if ( _document != NULL && notifyDocument )
|
||||
_document->insertElement(this);
|
||||
|
||||
// Notify our attributes
|
||||
daeMetaAttributeRefArray& metaAttrs = getMeta()->getMetaAttributes();
|
||||
for (size_t i = 0; i < metaAttrs.getCount(); i++)
|
||||
metaAttrs[i]->setDocument(this, c);
|
||||
|
||||
// Notify our char data object
|
||||
if (getCharDataObject())
|
||||
getCharDataObject()->setDocument(this, c);
|
||||
|
||||
// Notify our children
|
||||
daeElementRefArray ea;
|
||||
getChildren( ea );
|
||||
for ( size_t x = 0; x < ea.getCount(); x++ ) {
|
||||
// Since inserting and removing elements works recursively in the database,
|
||||
// we don't need to notify it about inserts/removals as we process the
|
||||
// children of this element.
|
||||
ea[x]->setDocument( c, false );
|
||||
}
|
||||
}
|
||||
|
||||
void daeElement::deleteCMDataArray(daeTArray<daeCharArray*>& cmData) {
|
||||
for (unsigned int i = 0; i < cmData.getCount(); i++)
|
||||
delete cmData.get(i);
|
||||
cmData.clear();
|
||||
}
|
||||
|
||||
size_t daeElement::getAttributeCount() {
|
||||
return getMeta()->getMetaAttributes().getCount();
|
||||
}
|
||||
|
||||
namespace {
|
||||
// A helper function to get the index of an attribute given the attribute name.
|
||||
size_t getAttributeIndex(daeElement& el, daeString name) {
|
||||
if (el.getMeta()) {
|
||||
daeMetaAttributeRefArray& metaAttrs = el.getMeta()->getMetaAttributes();
|
||||
for (size_t i = 0; i < metaAttrs.getCount(); i++)
|
||||
if (metaAttrs[i]->getName() && strcmp(metaAttrs[i]->getName(), name) == 0)
|
||||
return i;
|
||||
}
|
||||
return (size_t)-1;
|
||||
}
|
||||
}
|
||||
|
||||
daeMetaAttribute* daeElement::getAttributeObject(size_t i) {
|
||||
daeMetaAttributeRefArray& attrs = getMeta()->getMetaAttributes();
|
||||
if (i >= attrs.getCount())
|
||||
return NULL;
|
||||
return attrs[i];
|
||||
}
|
||||
|
||||
daeMetaAttribute* daeElement::getAttributeObject(daeString name) {
|
||||
return getAttributeObject(getAttributeIndex(*this, name));
|
||||
}
|
||||
|
||||
std::string daeElement::getAttributeName(size_t i) {
|
||||
if (daeMetaAttribute* attr = getAttributeObject(i))
|
||||
return (daeString)attr->getName();
|
||||
return "";
|
||||
}
|
||||
|
||||
daeBool daeElement::hasAttribute(daeString name) {
|
||||
return getAttributeObject(name) != 0;
|
||||
}
|
||||
|
||||
daeBool daeElement::isAttributeSet(daeString name) {
|
||||
size_t i = getAttributeIndex(*this, name);
|
||||
if (i != (size_t)-1)
|
||||
return _validAttributeArray[i];
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string daeElement::getAttribute(size_t i) {
|
||||
std::string value;
|
||||
getAttribute(i, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
void daeElement::getAttribute(size_t i, std::string& value) {
|
||||
value = "";
|
||||
if (daeMetaAttribute* attr = getAttributeObject(i)) {
|
||||
std::ostringstream buffer;
|
||||
attr->memoryToString(this, buffer);
|
||||
value = buffer.str();
|
||||
}
|
||||
}
|
||||
|
||||
std::string daeElement::getAttribute(daeString name) {
|
||||
std::string value;
|
||||
getAttribute(name, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
void daeElement::getAttribute(daeString name, std::string& value) {
|
||||
getAttribute(getAttributeIndex(*this, name), value);
|
||||
}
|
||||
|
||||
daeElement::attr::attr() { }
|
||||
daeElement::attr::attr(const std::string& name, const std::string& value)
|
||||
: name(name), value(value) { }
|
||||
|
||||
daeTArray<daeElement::attr> daeElement::getAttributes() {
|
||||
daeTArray<daeElement::attr> attrs;
|
||||
getAttributes(attrs);
|
||||
return attrs;
|
||||
}
|
||||
|
||||
void daeElement::getAttributes(daeTArray<attr>& attrs) {
|
||||
attrs.clear();
|
||||
for (size_t i = 0; i < getAttributeCount(); i++) {
|
||||
std::string value;
|
||||
getAttribute(i, value);
|
||||
attrs.append(attr(getAttributeName(i), value));
|
||||
}
|
||||
}
|
||||
|
||||
daeBool daeElement::setAttribute(size_t i, daeString value) {
|
||||
if (daeMetaAttribute* attr = getAttributeObject(i)) {
|
||||
if (attr->getType()) {
|
||||
attr->stringToMemory(this, value);
|
||||
_validAttributeArray.set(i, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
daeBool daeElement::setAttribute(daeString name, daeString value) {
|
||||
return setAttribute(getAttributeIndex(*this, name), value);
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
daeMemoryRef daeElement::getAttributeValue(daeString name) {
|
||||
if (daeMetaAttribute* attr = getAttributeObject(name))
|
||||
return attr->get(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeMetaAttribute* daeElement::getCharDataObject() {
|
||||
if (_meta)
|
||||
return _meta->getValueAttribute();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeBool daeElement::hasCharData() {
|
||||
return getCharDataObject() != NULL;
|
||||
}
|
||||
|
||||
std::string daeElement::getCharData() {
|
||||
std::string result;
|
||||
getCharData(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void daeElement::getCharData(std::string& data) {
|
||||
data = "";
|
||||
if (daeMetaAttribute* charDataAttr = getCharDataObject()) {
|
||||
std::ostringstream buffer;
|
||||
charDataAttr->memoryToString(this, buffer);
|
||||
data = buffer.str();
|
||||
}
|
||||
}
|
||||
|
||||
daeBool daeElement::setCharData(const std::string& data) {
|
||||
if (daeMetaAttribute* charDataAttr = getCharDataObject()) {
|
||||
charDataAttr->stringToMemory(this, data.c_str());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
daeBool daeElement::hasValue() {
|
||||
return hasCharData();
|
||||
}
|
||||
|
||||
daeMemoryRef daeElement::getValuePointer() {
|
||||
if (daeMetaAttribute* charDataAttr = getCharDataObject())
|
||||
return charDataAttr->get(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
daeElement::setup(daeMetaElement* meta)
|
||||
{
|
||||
if (_meta)
|
||||
return;
|
||||
_meta = meta;
|
||||
daeMetaAttributeRefArray& attrs = meta->getMetaAttributes();
|
||||
int macnt = (int)attrs.getCount();
|
||||
|
||||
_validAttributeArray.setCount(macnt, false);
|
||||
|
||||
for (int i = 0; i < macnt; i++) {
|
||||
if (attrs[i]->getDefaultValue() != NULL)
|
||||
attrs[i]->copyDefault(this);
|
||||
}
|
||||
|
||||
//set up the _CMData array if there is one
|
||||
if ( _meta->getMetaCMData() != NULL )
|
||||
{
|
||||
daeTArray< daeCharArray *> *CMData = (daeTArray< daeCharArray *>*)_meta->getMetaCMData()->getWritableMemory(this);
|
||||
CMData->setCount( _meta->getNumChoices() );
|
||||
for ( unsigned int i = 0; i < _meta->getNumChoices(); i++ )
|
||||
{
|
||||
CMData->set( i, new daeCharArray() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void daeElement::init() {
|
||||
_parent = NULL;
|
||||
_document = NULL;
|
||||
_meta = NULL;
|
||||
_elementName = NULL;
|
||||
_userData = NULL;
|
||||
}
|
||||
|
||||
daeElement::daeElement() {
|
||||
init();
|
||||
}
|
||||
|
||||
daeElement::daeElement(DAE& dae) {
|
||||
init();
|
||||
}
|
||||
|
||||
daeElement::~daeElement()
|
||||
{
|
||||
if (_elementName) {
|
||||
delete[] _elementName;
|
||||
_elementName = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//function used until we clarify what's a type and what's a name for an element
|
||||
daeString daeElement::getTypeName() const
|
||||
{
|
||||
return _meta->getName();
|
||||
}
|
||||
daeString daeElement::getElementName() const
|
||||
{
|
||||
return _elementName ? _elementName : (daeString)_meta->getName();
|
||||
}
|
||||
void daeElement::setElementName( daeString nm ) {
|
||||
if ( nm == NULL ) {
|
||||
if ( _elementName ) delete[] _elementName;
|
||||
_elementName = NULL;
|
||||
return;
|
||||
}
|
||||
if ( !_elementName ) _elementName = new daeChar[128];
|
||||
strcpy( (char*)_elementName, nm );
|
||||
}
|
||||
|
||||
daeString daeElement::getID() const {
|
||||
daeElement* this_ = const_cast<daeElement*>(this);
|
||||
if (_meta)
|
||||
if (daeMetaAttribute* idAttr = this_->getAttributeObject("id"))
|
||||
return *(daeStringRef*)idAttr->get(this_);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeElementRefArray daeElement::getChildren() {
|
||||
daeElementRefArray array;
|
||||
getChildren(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
void daeElement::getChildren( daeElementRefArray &array ) {
|
||||
_meta->getChildren( this, array );
|
||||
}
|
||||
|
||||
daeSmartRef<daeElement> daeElement::clone(daeString idSuffix, daeString nameSuffix) {
|
||||
// Use the meta object system to create a new instance of this element. We need to
|
||||
// create a new meta if we're cloning a domAny object because domAnys never share meta objects.
|
||||
// Ideally we'd be able to clone the _meta for domAny objects. Then we wouldn't need
|
||||
// any additional special case code for cloning domAny. Unfortunately, we don't have a
|
||||
// daeMetaElement::clone method.
|
||||
bool any = typeID() == domAny::ID();
|
||||
daeElementRef ret = any ? domAny::registerElement(*getDAE())->create() : _meta->create();
|
||||
ret->setElementName( _elementName );
|
||||
|
||||
// Copy the attributes and character data. Requires special care for domAny.
|
||||
if (any) {
|
||||
domAny* thisAny = (domAny*)this;
|
||||
domAny* retAny = (domAny*)ret.cast();
|
||||
for (daeUInt i = 0; i < (daeUInt)thisAny->getAttributeCount(); i++)
|
||||
retAny->setAttribute(thisAny->getAttributeName(i), thisAny->getAttributeValue(i));
|
||||
retAny->setValue(thisAny->getValue());
|
||||
} else {
|
||||
// Use the meta system to copy attributes
|
||||
daeMetaAttributeRefArray &attrs = _meta->getMetaAttributes();
|
||||
for (unsigned int i = 0; i < attrs.getCount(); i++) {
|
||||
attrs[i]->copy( ret, this );
|
||||
ret->_validAttributeArray[i] = _validAttributeArray[i];
|
||||
}
|
||||
if (daeMetaAttribute* valueAttr = getCharDataObject())
|
||||
valueAttr->copy( ret, this );
|
||||
}
|
||||
|
||||
daeElementRefArray children;
|
||||
_meta->getChildren( this, children );
|
||||
for ( size_t x = 0; x < children.getCount(); x++ ) {
|
||||
ret->placeElement( children.get(x)->clone( idSuffix, nameSuffix ) );
|
||||
}
|
||||
|
||||
// Mangle the id
|
||||
if (idSuffix) {
|
||||
std::string id = ret->getAttribute("id");
|
||||
if (!id.empty())
|
||||
ret->setAttribute("id", (id + idSuffix).c_str());
|
||||
}
|
||||
// Mangle the name
|
||||
if (nameSuffix) {
|
||||
std::string name = ret->getAttribute("name");
|
||||
if (!name.empty())
|
||||
ret->setAttribute("name", (name + nameSuffix).c_str());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// Element comparison
|
||||
|
||||
namespace { // Utility functions
|
||||
int getNecessaryColumnWidth(const vector<string>& tokens) {
|
||||
int result = 0;
|
||||
for (size_t i = 0; i < tokens.size(); i++) {
|
||||
int tokenLength = int(tokens[i].length() > 0 ? tokens[i].length()+2 : 0);
|
||||
result = max(tokenLength, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
string formatToken(const string& token) {
|
||||
if (token.length() <= 50)
|
||||
return token;
|
||||
return token.substr(0, 47) + "...";
|
||||
}
|
||||
} // namespace {
|
||||
|
||||
daeElement::compareResult::compareResult()
|
||||
: compareValue(0),
|
||||
elt1(NULL),
|
||||
elt2(NULL),
|
||||
nameMismatch(false),
|
||||
attrMismatch(""),
|
||||
charDataMismatch(false),
|
||||
childCountMismatch(false) {
|
||||
}
|
||||
|
||||
string daeElement::compareResult::format() {
|
||||
if (!elt1 || !elt2)
|
||||
return "";
|
||||
|
||||
// Gather the data we'll be printing
|
||||
string name1 = formatToken(elt1->getElementName()),
|
||||
name2 = formatToken(elt2->getElementName()),
|
||||
type1 = formatToken(elt1->getTypeName()),
|
||||
type2 = formatToken(elt2->getTypeName()),
|
||||
id1 = formatToken(elt1->getAttribute("id")),
|
||||
id2 = formatToken(elt2->getAttribute("id")),
|
||||
attrName1 = formatToken(attrMismatch),
|
||||
attrName2 = formatToken(attrMismatch),
|
||||
attrValue1 = formatToken(elt1->getAttribute(attrMismatch.c_str())),
|
||||
attrValue2 = formatToken(elt2->getAttribute(attrMismatch.c_str())),
|
||||
charData1 = formatToken(elt1->getCharData()),
|
||||
charData2 = formatToken(elt2->getCharData()),
|
||||
childCount1 = formatToken(cdom::toString(elt1->getChildren().getCount())),
|
||||
childCount2 = formatToken(cdom::toString(elt2->getChildren().getCount()));
|
||||
|
||||
// Compute formatting information
|
||||
vector<string> col1Tokens = cdom::makeStringArray("Name", "Type", "ID",
|
||||
"Attr name", "Attr value", "Char data", "Child count", 0);
|
||||
vector<string> col2Tokens = cdom::makeStringArray("Element 1", name1.c_str(),
|
||||
type1.c_str(), id1.c_str(), attrName1.c_str(), attrValue1.c_str(),
|
||||
charData1.c_str(), childCount1.c_str(), 0);
|
||||
|
||||
int c1w = getNecessaryColumnWidth(col1Tokens),
|
||||
c2w = getNecessaryColumnWidth(col2Tokens);
|
||||
ostringstream msg;
|
||||
msg << setw(c1w) << left << "" << setw(c2w) << left << "Element 1" << "Element 2\n"
|
||||
<< setw(c1w) << left << "" << setw(c2w) << left << "---------" << "---------\n"
|
||||
<< setw(c1w) << left << "Name" << setw(c2w) << left << name1 << name2 << endl
|
||||
<< setw(c1w) << left << "Type" << setw(c2w) << left << type1 << type2 << endl
|
||||
<< setw(c1w) << left << "ID" << setw(c2w) << left << id1 << id2 << endl
|
||||
<< setw(c1w) << left << "Attr name" << setw(c2w) << left << attrName1 << attrName2 << endl
|
||||
<< setw(c1w) << left << "Attr value" << setw(c2w) << left << attrValue1 << attrValue2 << endl
|
||||
<< setw(c1w) << left << "Char data" << setw(c2w) << left << charData1 << charData2 << endl
|
||||
<< setw(c1w) << left << "Child count" << setw(c2w) << left << childCount1 << childCount2;
|
||||
|
||||
return msg.str();
|
||||
}
|
||||
|
||||
namespace {
|
||||
daeElement::compareResult compareMatch() {
|
||||
daeElement::compareResult result;
|
||||
result.compareValue = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
daeElement::compareResult nameMismatch(daeElement& elt1, daeElement& elt2) {
|
||||
daeElement::compareResult result;
|
||||
result.elt1 = &elt1;
|
||||
result.elt2 = &elt2;
|
||||
result.compareValue = strcmp(elt1.getElementName(), elt2.getElementName());
|
||||
result.nameMismatch = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
daeElement::compareResult attrMismatch(daeElement& elt1, daeElement& elt2, const string& attr) {
|
||||
daeElement::compareResult result;
|
||||
result.elt1 = &elt1;
|
||||
result.elt2 = &elt2;
|
||||
result.compareValue = strcmp(elt1.getAttribute(attr.c_str()).c_str(),
|
||||
elt2.getAttribute(attr.c_str()).c_str());
|
||||
result.attrMismatch = attr;
|
||||
return result;
|
||||
}
|
||||
|
||||
daeElement::compareResult charDataMismatch(daeElement& elt1, daeElement& elt2) {
|
||||
daeElement::compareResult result;
|
||||
result.elt1 = &elt1;
|
||||
result.elt2 = &elt2;
|
||||
result.compareValue = strcmp(elt1.getCharData().c_str(),
|
||||
elt2.getCharData().c_str());
|
||||
result.charDataMismatch = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
daeElement::compareResult childCountMismatch(daeElement& elt1, daeElement& elt2) {
|
||||
daeElement::compareResult result;
|
||||
result.elt1 = &elt1;
|
||||
result.elt2 = &elt2;
|
||||
daeElementRefArray children1 = elt1.getChildren(),
|
||||
children2 = elt2.getChildren();
|
||||
result.compareValue = int(children1.getCount()) - int(children2.getCount());
|
||||
result.childCountMismatch = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
daeElement::compareResult compareElementsSameType(daeElement& elt1, daeElement& elt2) {
|
||||
// Compare attributes
|
||||
for (size_t i = 0; i < elt1.getAttributeCount(); i++)
|
||||
if (elt1.getAttributeObject(i)->compare(&elt1, &elt2) != 0)
|
||||
return attrMismatch(elt1, elt2, elt1.getAttributeName(i));
|
||||
|
||||
// Compare character data
|
||||
if (elt1.getCharDataObject())
|
||||
if (elt1.getCharDataObject()->compare(&elt1, &elt2) != 0)
|
||||
return charDataMismatch(elt1, elt2);
|
||||
|
||||
// Compare children
|
||||
daeElementRefArray children1 = elt1.getChildren(),
|
||||
children2 = elt2.getChildren();
|
||||
if (children1.getCount() != children2.getCount())
|
||||
return childCountMismatch(elt1, elt2);
|
||||
for (size_t i = 0; i < children1.getCount(); i++) {
|
||||
daeElement::compareResult result = daeElement::compareWithFullResult(*children1[i], *children2[i]);
|
||||
if (result.compareValue != 0)
|
||||
return result;
|
||||
}
|
||||
|
||||
return compareMatch();
|
||||
}
|
||||
|
||||
daeElement::compareResult compareElementsDifferentTypes(daeElement& elt1, daeElement& elt2) {
|
||||
string value1, value2;
|
||||
|
||||
// Compare attributes. Be careful because each element could have a
|
||||
// different number of attributes.
|
||||
if (elt1.getAttributeCount() > elt2.getAttributeCount())
|
||||
return attrMismatch(elt1, elt2, elt1.getAttributeName(elt2.getAttributeCount()));
|
||||
if (elt2.getAttributeCount() > elt1.getAttributeCount())
|
||||
return attrMismatch(elt1, elt2, elt2.getAttributeName(elt1.getAttributeCount()));
|
||||
for (size_t i = 0; i < elt1.getAttributeCount(); i++) {
|
||||
elt1.getAttribute(i, value1);
|
||||
elt2.getAttribute(elt1.getAttributeName(i).c_str(), value2);
|
||||
if (value1 != value2)
|
||||
return attrMismatch(elt1, elt2, elt1.getAttributeName(i));
|
||||
}
|
||||
|
||||
// Compare character data
|
||||
elt1.getCharData(value1);
|
||||
elt2.getCharData(value2);
|
||||
if (value1 != value2)
|
||||
return charDataMismatch(elt1, elt2);
|
||||
|
||||
// Compare children
|
||||
daeElementRefArray children1 = elt1.getChildren(),
|
||||
children2 = elt2.getChildren();
|
||||
if (children1.getCount() != children2.getCount())
|
||||
return childCountMismatch(elt1, elt2);
|
||||
for (size_t i = 0; i < children1.getCount(); i++) {
|
||||
daeElement::compareResult result = daeElement::compareWithFullResult(*children1[i], *children2[i]);
|
||||
if (result.compareValue != 0)
|
||||
return result;
|
||||
}
|
||||
|
||||
return compareMatch();
|
||||
}
|
||||
} // namespace {
|
||||
|
||||
int daeElement::compare(daeElement& elt1, daeElement& elt2) {
|
||||
return compareWithFullResult(elt1, elt2).compareValue;
|
||||
}
|
||||
|
||||
daeElement::compareResult daeElement::compareWithFullResult(daeElement& elt1, daeElement& elt2) {
|
||||
// Check the element name
|
||||
if (strcmp(elt1.getElementName(), elt2.getElementName()) != 0)
|
||||
return nameMismatch(elt1, elt2);
|
||||
|
||||
// Dispatch to a specific function based on whether or not the types are the same
|
||||
if ((elt1.typeID() != elt2.typeID()) || elt1.typeID() == domAny::ID())
|
||||
return compareElementsDifferentTypes(elt1, elt2);
|
||||
else
|
||||
return compareElementsSameType(elt1, elt2);
|
||||
}
|
||||
|
||||
|
||||
daeURI *daeElement::getDocumentURI() const {
|
||||
if ( _document == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
return _document->getDocumentURI();
|
||||
}
|
||||
|
||||
|
||||
daeElement::matchName::matchName(daeString name) : name(name) { }
|
||||
|
||||
bool daeElement::matchName::operator()(daeElement* elt) const {
|
||||
return strcmp(elt->getElementName(), name.c_str()) == 0;
|
||||
}
|
||||
|
||||
daeElement::matchType::matchType(daeInt typeID) : typeID(typeID) { }
|
||||
|
||||
bool daeElement::matchType::operator()(daeElement* elt) const {
|
||||
return elt->typeID() == typeID;
|
||||
}
|
||||
|
||||
daeElement* daeElement::getChild(const matchElement& matcher) {
|
||||
daeElementRefArray children;
|
||||
getChildren(children);
|
||||
for (size_t i = 0; i < children.getCount(); i++)
|
||||
if (matcher(children[i]))
|
||||
return children[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeElement* daeElement::getDescendant(const matchElement& matcher) {
|
||||
daeElementRefArray elts;
|
||||
getChildren(elts);
|
||||
|
||||
for (size_t i = 0; i < elts.getCount(); i++) {
|
||||
// Check the current element for a match
|
||||
if (matcher(elts[i]))
|
||||
return elts[i];
|
||||
|
||||
// Append the element's children to the queue
|
||||
daeElementRefArray children;
|
||||
elts[i]->getChildren(children);
|
||||
size_t oldCount = elts.getCount();
|
||||
elts.setCount(elts.getCount() + children.getCount());
|
||||
for (size_t j = 0; j < children.getCount(); j++)
|
||||
elts[oldCount + j] = children[j];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeElement* daeElement::getAncestor(const matchElement& matcher) {
|
||||
daeElement* elt = getParent();
|
||||
while (elt) {
|
||||
if (matcher(elt))
|
||||
return elt;
|
||||
elt = elt->getParent();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeElement* daeElement::getParent() {
|
||||
return _parent;
|
||||
}
|
||||
|
||||
daeElement* daeElement::getChild(daeString eltName) {
|
||||
if (!eltName)
|
||||
return NULL;
|
||||
matchName test(eltName);
|
||||
return getChild(matchName(eltName));
|
||||
}
|
||||
|
||||
daeElement* daeElement::getDescendant(daeString eltName) {
|
||||
if (!eltName)
|
||||
return NULL;
|
||||
return getDescendant(matchName(eltName));
|
||||
}
|
||||
|
||||
daeElement* daeElement::getAncestor(daeString eltName) {
|
||||
if (!eltName)
|
||||
return NULL;
|
||||
return getAncestor(matchName(eltName));
|
||||
}
|
||||
|
||||
DAE* daeElement::getDAE() {
|
||||
return _meta->getDAE();
|
||||
}
|
||||
|
||||
void daeElement::setUserData(void* data) {
|
||||
_userData = data;
|
||||
}
|
||||
|
||||
void* daeElement::getUserData() {
|
||||
return _userData;
|
||||
}
|
||||
46
Engine/lib/collada/src/dae/daeError.cpp
Normal file
46
Engine/lib/collada/src/dae/daeError.cpp
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <dae/daeError.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int errCode;
|
||||
const char *errString;
|
||||
} DAEERROR;
|
||||
|
||||
static DAEERROR errorsArray[] =
|
||||
{
|
||||
{ DAE_OK, "Success" },
|
||||
{ DAE_ERROR, "Generic error" },
|
||||
{ DAE_ERR_INVALID_CALL, "Invalid function call" },
|
||||
{ DAE_ERR_FATAL, "Fatal" },
|
||||
{ DAE_ERR_BACKEND_IO, "Backend IO" },
|
||||
{ DAE_ERR_BACKEND_VALIDATION, "Backend validation" },
|
||||
{ DAE_ERR_QUERY_SYNTAX, "Query syntax" },
|
||||
{ DAE_ERR_QUERY_NO_MATCH, "Query no match" },
|
||||
{ DAE_ERR_COLLECTION_ALREADY_EXISTS, "A document with the same name exists already" },
|
||||
{ DAE_ERR_COLLECTION_DOES_NOT_EXIST, "No document is loaded with that name or index" },
|
||||
{ DAE_ERR_NOT_IMPLEMENTED, "This function is not implemented in this reference implementation" },
|
||||
};
|
||||
|
||||
const char *daeErrorString(int errorCode)
|
||||
{
|
||||
int iErrorCount = (int)(sizeof(errorsArray)/sizeof(DAEERROR));
|
||||
for (int i=0;i<iErrorCount;i++)
|
||||
{
|
||||
if (errorsArray[i].errCode == errorCode)
|
||||
return errorsArray[i].errString;
|
||||
}
|
||||
return "Unknown Error code";
|
||||
}
|
||||
35
Engine/lib/collada/src/dae/daeErrorHandler.cpp
Normal file
35
Engine/lib/collada/src/dae/daeErrorHandler.cpp
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <dae/daeErrorHandler.h>
|
||||
#include <modules/stdErrPlugin.h>
|
||||
|
||||
daeErrorHandler *daeErrorHandler::_instance = NULL;
|
||||
std::auto_ptr<daeErrorHandler> daeErrorHandler::_defaultInstance(new stdErrPlugin);
|
||||
|
||||
daeErrorHandler::daeErrorHandler() {
|
||||
}
|
||||
|
||||
daeErrorHandler::~daeErrorHandler() {
|
||||
}
|
||||
|
||||
void daeErrorHandler::setErrorHandler( daeErrorHandler *eh ) {
|
||||
_instance = eh;
|
||||
}
|
||||
|
||||
daeErrorHandler *daeErrorHandler::get() {
|
||||
if ( _instance == NULL ) {
|
||||
return _defaultInstance.get();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
177
Engine/lib/collada/src/dae/daeIDRef.cpp
Normal file
177
Engine/lib/collada/src/dae/daeIDRef.cpp
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include <dae.h>
|
||||
#include <dae/daeIDRef.h>
|
||||
#include <dae/daeDatabase.h>
|
||||
#include <dae/daeErrorHandler.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void
|
||||
daeIDRef::initialize()
|
||||
{
|
||||
id = "";
|
||||
container = NULL;
|
||||
}
|
||||
|
||||
daeIDRef::daeIDRef()
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
daeIDRef::daeIDRef(daeString IDRefString)
|
||||
{
|
||||
initialize();
|
||||
setID(IDRefString);
|
||||
}
|
||||
|
||||
daeIDRef::daeIDRef(const daeIDRef& copyFrom_)
|
||||
{
|
||||
initialize();
|
||||
copyFrom(copyFrom_);
|
||||
}
|
||||
|
||||
daeIDRef::daeIDRef(daeElement& container) {
|
||||
initialize();
|
||||
setContainer(&container);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
daeIDRef::reset()
|
||||
{
|
||||
setID("");
|
||||
}
|
||||
|
||||
bool daeIDRef::operator==(const daeIDRef& other) const {
|
||||
return (!strcmp(other.getID(), getID()));
|
||||
}
|
||||
|
||||
daeIDRef &daeIDRef::operator=( const daeIDRef& other) {
|
||||
if (!container)
|
||||
container = other.container;
|
||||
id = other.getID();
|
||||
return *this;
|
||||
}
|
||||
|
||||
daeString
|
||||
daeIDRef::getID() const
|
||||
{
|
||||
return id.c_str();
|
||||
}
|
||||
|
||||
void
|
||||
daeIDRef::setID(daeString _IDString)
|
||||
{
|
||||
id = _IDString ? _IDString : "";
|
||||
}
|
||||
|
||||
daeElement* daeIDRef::getElement() const {
|
||||
if (container)
|
||||
return container->getDAE()->getIDRefResolvers().resolveElement(id, container->getDocument());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeElement* daeIDRef::getContainer() const {
|
||||
return(container);
|
||||
}
|
||||
|
||||
void daeIDRef::setContainer(daeElement* cont) {
|
||||
container = cont;
|
||||
}
|
||||
|
||||
void
|
||||
daeIDRef::print()
|
||||
{
|
||||
fprintf(stderr,"id = %s\n",id.c_str());
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
// These methods are provided for backward compatibility only.
|
||||
void daeIDRef::validate() { }
|
||||
|
||||
void daeIDRef::resolveElement( daeString ) { }
|
||||
|
||||
void daeIDRef::resolveID() { }
|
||||
|
||||
daeIDRef &daeIDRef::get( daeUInt idx ) {
|
||||
(void)idx;
|
||||
return *this;
|
||||
}
|
||||
|
||||
size_t daeIDRef::getCount() const {
|
||||
return 1;
|
||||
}
|
||||
|
||||
daeIDRef& daeIDRef::operator[](size_t index) {
|
||||
(void)index;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void
|
||||
daeIDRef::copyFrom(const daeIDRef& copyFrom) {
|
||||
*this = copyFrom;
|
||||
}
|
||||
|
||||
daeIDRef::ResolveState daeIDRef::getState() const {
|
||||
if (id.empty())
|
||||
return id_empty;
|
||||
if (getElement())
|
||||
return id_success;
|
||||
return id_failed_id_not_found;
|
||||
}
|
||||
|
||||
|
||||
daeIDRefResolver::daeIDRefResolver(DAE& dae) : dae(&dae) { }
|
||||
|
||||
daeIDRefResolver::~daeIDRefResolver() { }
|
||||
|
||||
|
||||
daeDefaultIDRefResolver::daeDefaultIDRefResolver(DAE& dae) : daeIDRefResolver(dae) { }
|
||||
|
||||
daeDefaultIDRefResolver::~daeDefaultIDRefResolver() { }
|
||||
|
||||
daeString
|
||||
daeDefaultIDRefResolver::getName()
|
||||
{
|
||||
return "DefaultIDRefResolver";
|
||||
}
|
||||
|
||||
daeElement* daeDefaultIDRefResolver::resolveElement(const string& id, daeDocument* doc) {
|
||||
return doc ? dae->getDatabase()->idLookup(id, doc) : NULL;
|
||||
}
|
||||
|
||||
|
||||
daeIDRefResolverList::daeIDRefResolverList() { }
|
||||
|
||||
daeIDRefResolverList::~daeIDRefResolverList() {
|
||||
for (size_t i = 0; i < resolvers.getCount(); i++)
|
||||
delete resolvers[i];
|
||||
}
|
||||
|
||||
void daeIDRefResolverList::addResolver(daeIDRefResolver* resolver) {
|
||||
resolvers.append(resolver);
|
||||
}
|
||||
|
||||
void daeIDRefResolverList::removeResolver(daeIDRefResolver* resolver) {
|
||||
resolvers.remove(resolver);
|
||||
}
|
||||
|
||||
daeElement* daeIDRefResolverList::resolveElement(const string& id, daeDocument* doc) {
|
||||
for(size_t i = 0; i < resolvers.getCount(); i++)
|
||||
if (daeElement* el = resolvers[i]->resolveElement(id, doc))
|
||||
return el;
|
||||
return NULL;
|
||||
}
|
||||
139
Engine/lib/collada/src/dae/daeIOPluginCommon.cpp
Normal file
139
Engine/lib/collada/src/dae/daeIOPluginCommon.cpp
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright 2007 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include <dae.h>
|
||||
#include <dom.h>
|
||||
#include <dae/daeDatabase.h>
|
||||
#include <dae/daeIOPluginCommon.h>
|
||||
#include <dae/daeMetaElement.h>
|
||||
#include <dae/daeErrorHandler.h>
|
||||
#include <dae/daeMetaElementAttribute.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
daeIOPluginCommon::daeIOPluginCommon()
|
||||
: database(NULL),
|
||||
topMeta(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
daeIOPluginCommon::~daeIOPluginCommon()
|
||||
{
|
||||
}
|
||||
|
||||
daeInt daeIOPluginCommon::setMeta(daeMetaElement *_topMeta)
|
||||
{
|
||||
topMeta = _topMeta;
|
||||
return DAE_OK;
|
||||
}
|
||||
|
||||
void daeIOPluginCommon::setDatabase(daeDatabase* _database)
|
||||
{
|
||||
database = _database;
|
||||
}
|
||||
|
||||
// This function needs to be re-entrant, it can be called recursively from inside of resolveAll
|
||||
// to load files that the first file depends on.
|
||||
daeInt daeIOPluginCommon::read(const daeURI& uri, daeString docBuffer)
|
||||
{
|
||||
// Make sure topMeta has been set before proceeding
|
||||
if (topMeta == NULL)
|
||||
{
|
||||
return DAE_ERR_BACKEND_IO;
|
||||
}
|
||||
|
||||
// Generate a version of the URI with the fragment removed
|
||||
daeURI fileURI(*uri.getDAE(), uri.str(), true);
|
||||
|
||||
//check if document already exists
|
||||
if ( database->isDocumentLoaded( fileURI.getURI() ) )
|
||||
{
|
||||
return DAE_ERR_COLLECTION_ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
daeElementRef domObject = docBuffer ?
|
||||
readFromMemory(docBuffer, fileURI) :
|
||||
readFromFile(fileURI); // Load from URI
|
||||
|
||||
if (!domObject) {
|
||||
string msg = docBuffer ?
|
||||
"Failed to load XML document from memory\n" :
|
||||
string("Failed to load ") + fileURI.str() + "\n";
|
||||
daeErrorHandler::get()->handleError(msg.c_str());
|
||||
return DAE_ERR_BACKEND_IO;
|
||||
}
|
||||
|
||||
// Insert the document into the database, the Database will keep a ref on the main dom, so it won't get deleted
|
||||
// until we clear the database
|
||||
|
||||
daeDocument *document = NULL;
|
||||
|
||||
int res = database->insertDocument(fileURI.getURI(),domObject,&document);
|
||||
if (res!= DAE_OK)
|
||||
return res;
|
||||
|
||||
return DAE_OK;
|
||||
}
|
||||
|
||||
daeElementRef daeIOPluginCommon::beginReadElement(daeElement* parentElement,
|
||||
daeString elementName,
|
||||
const vector<attrPair>& attributes,
|
||||
daeInt lineNumber) {
|
||||
daeMetaElement* parentMeta = parentElement ? parentElement->getMeta() : topMeta;
|
||||
daeElementRef element = parentMeta->create(elementName);
|
||||
|
||||
if(!element)
|
||||
{
|
||||
ostringstream msg;
|
||||
msg << "The DOM was unable to create an element named " << elementName << " at line "
|
||||
<< lineNumber << ". Probably a schema violation.\n";
|
||||
daeErrorHandler::get()->handleWarning( msg.str().c_str() );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Process the attributes
|
||||
for (size_t i = 0; i < attributes.size(); i++) {
|
||||
daeString name = attributes[i].first,
|
||||
value = attributes[i].second;
|
||||
if (!element->setAttribute(name, value)) {
|
||||
ostringstream msg;
|
||||
msg << "The DOM was unable to create an attribute " << name << " = " << value
|
||||
<< " at line " << lineNumber << ".\nProbably a schema violation.\n";
|
||||
daeErrorHandler::get()->handleWarning(msg.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (parentElement == NULL) {
|
||||
// This is the root element. Check the COLLADA version.
|
||||
daeURI *xmlns = (daeURI*)(element->getMeta()->getMetaAttribute( "xmlns" )->getWritableMemory( element ));
|
||||
if ( strcmp( xmlns->getURI(), COLLADA_NAMESPACE ) != 0 ) {
|
||||
// Invalid COLLADA version
|
||||
daeErrorHandler::get()->handleError("Trying to load an invalid COLLADA version for this DOM build!");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
bool daeIOPluginCommon::readElementText(daeElement* element, daeString text, daeInt elementLineNumber) {
|
||||
if (element->setCharData(text))
|
||||
return true;
|
||||
|
||||
ostringstream msg;
|
||||
msg << "The DOM was unable to set a value for element of type " << element->getTypeName()
|
||||
<< " at line " << elementLineNumber << ".\nProbably a schema violation.\n";
|
||||
daeErrorHandler::get()->handleWarning(msg.str().c_str());
|
||||
return false;
|
||||
}
|
||||
34
Engine/lib/collada/src/dae/daeMemorySystem.cpp
Normal file
34
Engine/lib/collada/src/dae/daeMemorySystem.cpp
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <dae/daeMemorySystem.h>
|
||||
//#include <malloc.h>
|
||||
|
||||
daeRawRef
|
||||
daeMemorySystem::alloc(daeString pool, size_t n)
|
||||
{
|
||||
(void)pool;
|
||||
void *mem = malloc(n);
|
||||
// memset(mem,0,n);
|
||||
// printf("alloc[%s] - %d = 0x%x\n",pool,n,mem);
|
||||
return (daeRawRef)mem;
|
||||
}
|
||||
|
||||
void
|
||||
daeMemorySystem::dealloc(daeString pool, daeRawRef mem)
|
||||
{
|
||||
(void)pool;
|
||||
// printf("free[%s] - 0x%x\n",pool,mem);
|
||||
free(mem);
|
||||
}
|
||||
|
||||
62
Engine/lib/collada/src/dae/daeMetaAny.cpp
Normal file
62
Engine/lib/collada/src/dae/daeMetaAny.cpp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <dae/daeMetaAny.h>
|
||||
#include <dae/domAny.h>
|
||||
#include <dae/daeMetaElementAttribute.h>
|
||||
#include <dae.h>
|
||||
|
||||
daeMetaAny::daeMetaAny( daeMetaElement *container, daeMetaCMPolicy *parent, daeUInt ordinal,
|
||||
daeInt minO, daeInt maxO) : daeMetaCMPolicy( container, parent, ordinal, minO, maxO )
|
||||
{}
|
||||
|
||||
daeMetaAny::~daeMetaAny()
|
||||
{}
|
||||
|
||||
daeElement *daeMetaAny::placeElement( daeElement *parent, daeElement *child, daeUInt &ordinal, daeInt offset, daeElement* before, daeElement *after ) {
|
||||
//remove element from praent
|
||||
(void)offset;
|
||||
(void)before;
|
||||
(void)after;
|
||||
daeElement::removeFromParent( child );
|
||||
child->setParentElement( parent );
|
||||
//*************************************************************************
|
||||
ordinal = 0;
|
||||
return child;
|
||||
}
|
||||
|
||||
daeBool daeMetaAny::removeElement( daeElement *parent, daeElement *child ) {
|
||||
(void)parent;
|
||||
(void)child;
|
||||
return true;
|
||||
}
|
||||
|
||||
daeMetaElement * daeMetaAny::findChild( daeString elementName ) {
|
||||
if ( elementName != NULL ) {
|
||||
const daeMetaElementRefArray &metas = _container->getDAE()->getAllMetas();
|
||||
size_t cnt = metas.getCount();
|
||||
for ( size_t x = 0; x < cnt; x++ ) {
|
||||
if ( metas[x] && !metas[x]->getIsInnerClass() && strcmp( elementName, metas[x]->getName() ) == 0 ) {
|
||||
return metas[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
return domAny::registerElement(*_container->getDAE());
|
||||
}
|
||||
|
||||
void daeMetaAny::getChildren( daeElement *parent, daeElementRefArray &array ) {
|
||||
(void)parent;
|
||||
(void)array;
|
||||
//this is taken care of by the _contents in metaElement
|
||||
}
|
||||
|
||||
178
Engine/lib/collada/src/dae/daeMetaAttribute.cpp
Normal file
178
Engine/lib/collada/src/dae/daeMetaAttribute.cpp
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include <dae/daeMetaAttribute.h>
|
||||
#include <dae/daeMetaElement.h>
|
||||
#include <dae/daeErrorHandler.h>
|
||||
#include <dae/daeDocument.h>
|
||||
|
||||
void daeMetaAttribute::set(daeElement* e, daeString s) {
|
||||
stringToMemory(e, s);
|
||||
}
|
||||
|
||||
void daeMetaAttribute::copy(daeElement* to, daeElement *from) {
|
||||
_type->copy(get(from), get(to));
|
||||
}
|
||||
|
||||
void daeMetaArrayAttribute::copy(daeElement* to, daeElement *from) {
|
||||
daeArray& fromArray = (daeArray&)*get(from);
|
||||
daeArray& toArray = (daeArray&)*get(to);
|
||||
_type->copyArray(fromArray, toArray);
|
||||
}
|
||||
|
||||
void daeMetaAttribute::copyDefault(daeElement* element) {
|
||||
if (_defaultValue)
|
||||
_type->copy(_defaultValue, get(element));
|
||||
}
|
||||
|
||||
void daeMetaArrayAttribute::copyDefault(daeElement* element) {
|
||||
if (_defaultValue)
|
||||
_type->copyArray((daeArray&)*_defaultValue, (daeArray&)*get(element));
|
||||
}
|
||||
|
||||
daeInt daeMetaAttribute::compare(daeElement* elt1, daeElement* elt2) {
|
||||
return _type->compare(get(elt1), get(elt2));
|
||||
}
|
||||
|
||||
daeInt daeMetaArrayAttribute::compare(daeElement* elt1, daeElement* elt2) {
|
||||
daeArray& value1 = (daeArray&)*get(elt1);
|
||||
daeArray& value2 = (daeArray&)*get(elt2);
|
||||
return _type->compareArray(value1, value2);
|
||||
}
|
||||
|
||||
daeInt daeMetaAttribute::compareToDefault(daeElement* e) {
|
||||
if (!_defaultValue)
|
||||
return 1;
|
||||
return _type->compare(get(e), _defaultValue);
|
||||
}
|
||||
|
||||
daeInt daeMetaArrayAttribute::compareToDefault(daeElement* e) {
|
||||
if (!_defaultValue)
|
||||
return 1;
|
||||
daeArray& value1 = (daeArray&)*get(e);
|
||||
daeArray& value2 = (daeArray&)*_defaultValue;
|
||||
return _type->compareArray(value1, value2);
|
||||
}
|
||||
|
||||
daeMetaAttribute::daeMetaAttribute()
|
||||
{
|
||||
_name = "noname";
|
||||
_offset = -1;
|
||||
_type = NULL;
|
||||
_container = NULL;
|
||||
_defaultString = "";
|
||||
_defaultValue = NULL;
|
||||
_isRequired = false;
|
||||
}
|
||||
|
||||
daeMetaAttribute::~daeMetaAttribute() {
|
||||
if (_defaultValue)
|
||||
_type->destroy(_defaultValue);
|
||||
_defaultValue = NULL;
|
||||
}
|
||||
|
||||
daeMetaArrayAttribute::~daeMetaArrayAttribute() {
|
||||
delete (daeArray*)_defaultValue;
|
||||
_defaultValue = NULL;
|
||||
}
|
||||
|
||||
daeInt
|
||||
daeMetaAttribute::getSize()
|
||||
{
|
||||
return _type->getSize();
|
||||
}
|
||||
daeInt
|
||||
daeMetaAttribute::getAlignment()
|
||||
{
|
||||
return _type->getAlignment();
|
||||
}
|
||||
|
||||
void daeMetaAttribute::memoryToString(daeElement* e, std::ostringstream& buffer) {
|
||||
_type->memoryToString(get(e), buffer);
|
||||
}
|
||||
|
||||
void daeMetaAttribute::stringToMemory(daeElement* e, daeString s) {
|
||||
if (!strcmp(_name, "id") && e->getDocument())
|
||||
e->getDocument()->changeElementID(e, s);
|
||||
else if (!strcmp(_name, "sid") && e->getDocument())
|
||||
e->getDocument()->changeElementSID(e, s);
|
||||
|
||||
_type->stringToMemory((daeChar*)s, get(e));
|
||||
}
|
||||
|
||||
daeChar* daeMetaAttribute::getWritableMemory(daeElement* e) {
|
||||
return (daeChar*)e + _offset;
|
||||
}
|
||||
|
||||
daeMemoryRef daeMetaAttribute::get(daeElement* e) {
|
||||
return getWritableMemory(e);
|
||||
}
|
||||
|
||||
void daeMetaAttribute::setDefaultString(daeString defaultVal) {
|
||||
_defaultString = defaultVal;
|
||||
if (!_defaultValue)
|
||||
_defaultValue = _type->create();
|
||||
_type->stringToMemory((daeChar*)_defaultString.c_str(), _defaultValue);
|
||||
}
|
||||
|
||||
void daeMetaAttribute::setDefaultValue(daeMemoryRef defaultVal) {
|
||||
if (!_defaultValue)
|
||||
_defaultValue = _type->create();
|
||||
_type->copy(defaultVal, _defaultValue);
|
||||
std::ostringstream buffer;
|
||||
_type->memoryToString(_defaultValue, buffer);
|
||||
_defaultString = buffer.str();
|
||||
}
|
||||
|
||||
void daeMetaArrayAttribute::memoryToString(daeElement* e, std::ostringstream& buffer) {
|
||||
if (e)
|
||||
_type->arrayToString(*(daeArray*)get(e), buffer);
|
||||
}
|
||||
|
||||
void daeMetaArrayAttribute::stringToMemory(daeElement* e, daeString s) {
|
||||
if (e)
|
||||
_type->stringToArray((daeChar*)s, *(daeArray*)get(e));
|
||||
}
|
||||
|
||||
void daeMetaArrayAttribute::setDefaultString(daeString defaultVal) {
|
||||
_defaultString = defaultVal;
|
||||
if (!_defaultValue)
|
||||
_defaultValue = (daeMemoryRef)_type->createArray();
|
||||
_type->stringToArray((daeChar*)_defaultString.c_str(), (daeArray&)*_defaultValue);
|
||||
}
|
||||
|
||||
void daeMetaArrayAttribute::setDefaultValue(daeMemoryRef defaultVal) {
|
||||
if (!_defaultValue)
|
||||
_defaultValue = (daeMemoryRef)_type->createArray();
|
||||
_type->copyArray((daeArray&)*defaultVal, (daeArray&)*_defaultValue);
|
||||
std::ostringstream buffer;
|
||||
_type->arrayToString((daeArray&)*_defaultValue, buffer);
|
||||
_defaultString = buffer.str();
|
||||
}
|
||||
|
||||
daeString daeMetaAttribute::getDefaultString() {
|
||||
return _defaultString.c_str();
|
||||
}
|
||||
|
||||
daeMemoryRef daeMetaAttribute::getDefaultValue() {
|
||||
return _defaultValue;
|
||||
}
|
||||
|
||||
void daeMetaAttribute::setDocument(daeElement* e, daeDocument* doc) {
|
||||
_type->setDocument(get(e), doc);
|
||||
}
|
||||
|
||||
void daeMetaArrayAttribute::setDocument(daeElement* e, daeDocument* doc) {
|
||||
_type->setDocument(*(daeArray*)get(e), doc);
|
||||
}
|
||||
22
Engine/lib/collada/src/dae/daeMetaCMPolicy.cpp
Normal file
22
Engine/lib/collada/src/dae/daeMetaCMPolicy.cpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <dae/daeMetaCMPolicy.h>
|
||||
|
||||
daeMetaCMPolicy::~daeMetaCMPolicy()
|
||||
{
|
||||
for( size_t i = 0; i < _children.getCount(); i++ ) {
|
||||
delete _children[i];
|
||||
}
|
||||
}
|
||||
|
||||
153
Engine/lib/collada/src/dae/daeMetaChoice.cpp
Normal file
153
Engine/lib/collada/src/dae/daeMetaChoice.cpp
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <dae/daeMetaChoice.h>
|
||||
#include <dae/daeMetaElement.h>
|
||||
|
||||
daeMetaChoice::daeMetaChoice( daeMetaElement *container, daeMetaCMPolicy *parent, daeUInt choiceNum, daeUInt ordinal,
|
||||
daeInt minO, daeInt maxO) : daeMetaCMPolicy( container, parent, ordinal, minO, maxO ), _choiceNum(choiceNum)
|
||||
{}
|
||||
|
||||
daeMetaChoice::~daeMetaChoice()
|
||||
{}
|
||||
|
||||
daeElement *daeMetaChoice::placeElement( daeElement *parent, daeElement *child, daeUInt &ordinal, daeInt offset, daeElement* before, daeElement *after ) {
|
||||
(void)offset;
|
||||
if ( _maxOccurs == -1 ) {
|
||||
//Needed to prevent infinate loops. If unbounded check to see if you have the child before just trying to place
|
||||
if ( findChild( child->getElementName() ) == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
daeElement *retVal = NULL;
|
||||
size_t cnt = _children.getCount();
|
||||
|
||||
daeTArray< daeCharArray *> *CMData = (daeTArray< daeCharArray *>*)_container->getMetaCMData()->getWritableMemory(parent);
|
||||
daeCharArray *myData = CMData->get( _choiceNum );
|
||||
|
||||
for ( daeInt i = 0; ( i < _maxOccurs || _maxOccurs == -1 ); i++ )
|
||||
{
|
||||
if ( (daeInt)myData->getCount() > i && myData->get(i) != -1 ) //choice has already been made
|
||||
{
|
||||
if ( _children[ myData->get(i) ]->placeElement( parent, child, ordinal, i, before, after ) != NULL )
|
||||
{
|
||||
retVal = child;
|
||||
ordinal = ordinal + _ordinalOffset;
|
||||
break;
|
||||
}
|
||||
//else //try to see if everything can be in a different choice
|
||||
//{
|
||||
// daeElementRefArray childsInChoice;
|
||||
// _children[ myData->get(i) ]->getChildren( parent, childsInChoice );
|
||||
// for ( size_t x = myData->get(i) +1; x < cnt; x++ )
|
||||
// {
|
||||
// daeElementRefArray childsInNext;
|
||||
// _children[ x ]->getChildren( parent, childsInNext ); //If you get children in another choice then
|
||||
// //both choices can have the same type of children.
|
||||
// if ( childsInNext.getCount() == childsInChoice.getCount() )
|
||||
// {
|
||||
// //if there are the same ammount of children then all present children can belong to both
|
||||
// //choices. Try to place the new child in this next choice.
|
||||
// if ( _children[x]->placeElement( parent, child, ordinal, i, before, after ) != NULL )
|
||||
// {
|
||||
// retVal = child;
|
||||
// ordinal = ordinal + _ordinalOffset;
|
||||
|
||||
// myData->set( i, (daeChar)x ); //change the choice to this new one
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// if ( retVal != NULL ) break;
|
||||
//}
|
||||
}
|
||||
else //no choice has been made yet
|
||||
{
|
||||
for ( size_t x = 0; x < cnt; x++ )
|
||||
{
|
||||
if ( _children[x]->placeElement( parent, child, ordinal, i, before, after ) != NULL )
|
||||
{
|
||||
retVal = child;
|
||||
ordinal = ordinal + _ordinalOffset;
|
||||
|
||||
myData->append( (daeChar)x ); //you always place in the next available choice up to maxOccurs
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( retVal != NULL ) break;
|
||||
}
|
||||
}
|
||||
if ( retVal == NULL )
|
||||
{
|
||||
if ( findChild( child->getElementName() ) == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
for ( daeInt i = 0; ( i < _maxOccurs || _maxOccurs == -1 ); i++ )
|
||||
{
|
||||
daeElementRefArray childsInChoice;
|
||||
_children[ myData->get(i) ]->getChildren( parent, childsInChoice );
|
||||
for ( size_t x = myData->get(i) +1; x < cnt; x++ )
|
||||
{
|
||||
daeElementRefArray childsInNext;
|
||||
_children[ x ]->getChildren( parent, childsInNext ); //If you get children in another choice then
|
||||
//both choices can have the same type of children.
|
||||
if ( childsInNext.getCount() == childsInChoice.getCount() )
|
||||
{
|
||||
//if there are the same ammount of children then all present children can belong to both
|
||||
//choices. Try to place the new child in this next choice.
|
||||
if ( _children[x]->placeElement( parent, child, ordinal, i, before, after ) != NULL )
|
||||
{
|
||||
retVal = child;
|
||||
ordinal = ordinal + _ordinalOffset;
|
||||
|
||||
myData->set( i, (daeChar)x ); //change the choice to this new one
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( retVal != NULL ) break;
|
||||
}
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
daeBool daeMetaChoice::removeElement( daeElement *parent, daeElement *child ) {
|
||||
size_t cnt = _children.getCount();
|
||||
for ( size_t x = 0; x < cnt; x++ ) {
|
||||
if ( _children[x]->removeElement( parent, child ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
daeMetaElement * daeMetaChoice::findChild( daeString elementName ) {
|
||||
daeMetaElement *me = NULL;
|
||||
size_t cnt = _children.getCount();
|
||||
for ( size_t x = 0; x < cnt; x++ ) {
|
||||
me = _children[x]->findChild( elementName );
|
||||
if ( me != NULL ) {
|
||||
return me;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void daeMetaChoice::getChildren( daeElement *parent, daeElementRefArray &array ) {
|
||||
size_t cnt = _children.getCount();
|
||||
for ( size_t x = 0; x < cnt; x++ ) {
|
||||
_children[x]->getChildren( parent, array );
|
||||
}
|
||||
}
|
||||
|
||||
477
Engine/lib/collada/src/dae/daeMetaElement.cpp
Normal file
477
Engine/lib/collada/src/dae/daeMetaElement.cpp
Normal file
|
|
@ -0,0 +1,477 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <dae.h>
|
||||
#include <dae/daeMetaElement.h>
|
||||
#include <dae/daeElement.h>
|
||||
#include <dae/daeDocument.h>
|
||||
#include <dae/domAny.h>
|
||||
#include <dae/daeMetaCMPolicy.h>
|
||||
#include <dae/daeMetaElementAttribute.h>
|
||||
|
||||
daeElementRef
|
||||
daeMetaElement::create()
|
||||
{
|
||||
daeElementRef ret = (*_createFunc)(dae);
|
||||
ret->setup(this);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
daeElementRef
|
||||
daeMetaElement::create(daeString s)
|
||||
{
|
||||
daeMetaElement* me = NULL;
|
||||
if ( strcmp( s, _name ) == 0 ) {
|
||||
//looking for this meta
|
||||
me = this;
|
||||
}
|
||||
else if ( _contentModel != NULL ) {
|
||||
me = _contentModel->findChild(s);
|
||||
}
|
||||
if (me != NULL) {
|
||||
daeElementRef ret = me->create();
|
||||
if ( strcmp(s, me->getName() ) != 0 ) {
|
||||
ret->setElementName(s);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
if ( getAllowsAny() ) {
|
||||
daeElementRef ret = domAny::registerElement(dae)->create();
|
||||
ret->setElementName(s);
|
||||
return ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeMetaElement::daeMetaElement(DAE& dae) : dae(dae)
|
||||
{
|
||||
_name = "noname";
|
||||
_createFunc = NULL;
|
||||
_elementSize = sizeof(daeElement);
|
||||
_metaValue = NULL;
|
||||
_metaContents = NULL;
|
||||
_metaContentsOrder = NULL; // sthomas
|
||||
_metaID = NULL;
|
||||
_isTrackableForQueries = true;
|
||||
_usesStringContents = false;
|
||||
_isTransparent = false;
|
||||
_isAbstract = false;
|
||||
_allowsAny = false;
|
||||
_innerClass = false;
|
||||
_contentModel = NULL;
|
||||
_metaCMData = NULL;
|
||||
_numMetaChoices = 0;
|
||||
}
|
||||
|
||||
daeMetaElement::~daeMetaElement()
|
||||
{
|
||||
delete _metaContents;
|
||||
delete _contentModel;
|
||||
delete _metaContentsOrder;
|
||||
delete _metaCMData;
|
||||
}
|
||||
|
||||
DAE* daeMetaElement::getDAE() {
|
||||
return &dae;
|
||||
}
|
||||
|
||||
void daeMetaElement::setCMRoot( daeMetaCMPolicy *cm )
|
||||
{
|
||||
if (_contentModel)
|
||||
delete _contentModel;
|
||||
_contentModel = cm;
|
||||
}
|
||||
|
||||
void
|
||||
daeMetaElement::addContents(daeInt offset)
|
||||
{
|
||||
daeMetaElementArrayAttribute* meaa = new daeMetaElementArrayAttribute( this, NULL, 0, 1, -1 );
|
||||
meaa->setType(dae.getAtomicTypes().get("element"));
|
||||
meaa->setName("contents");
|
||||
meaa->setOffset(offset);
|
||||
meaa->setContainer( this);
|
||||
_metaContents = meaa;
|
||||
}
|
||||
void
|
||||
daeMetaElement::addContentsOrder(daeInt offset)
|
||||
{
|
||||
daeMetaArrayAttribute* meaa = new daeMetaArrayAttribute();
|
||||
meaa->setType(dae.getAtomicTypes().get("uint"));
|
||||
meaa->setName("contentsOrder");
|
||||
meaa->setOffset(offset);
|
||||
meaa->setContainer( this);
|
||||
|
||||
if (_metaContentsOrder)
|
||||
delete _metaContentsOrder;
|
||||
|
||||
_metaContentsOrder = meaa;
|
||||
}
|
||||
|
||||
void daeMetaElement::addCMDataArray(daeInt offset, daeUInt numChoices)
|
||||
{
|
||||
daeMetaArrayAttribute* meaa = new daeMetaArrayAttribute();
|
||||
meaa->setType(dae.getAtomicTypes().get("int"));
|
||||
meaa->setName("CMData");
|
||||
meaa->setOffset(offset);
|
||||
meaa->setContainer( this);
|
||||
|
||||
if (_metaCMData)
|
||||
delete _metaCMData;
|
||||
|
||||
_metaCMData = meaa;
|
||||
|
||||
_numMetaChoices = numChoices;
|
||||
}
|
||||
|
||||
|
||||
/*void
|
||||
daeMetaElement::appendArrayElement(daeMetaElement* element, daeInt offset, daeString name)
|
||||
{
|
||||
daeMetaElementArrayAttribute* meaa = new daeMetaElementArrayAttribute;
|
||||
meaa->setType(daeAtomicType::get("element"));
|
||||
if ( name ) {
|
||||
meaa->setName(name);
|
||||
}
|
||||
else {
|
||||
meaa->setName(element->getName());
|
||||
}
|
||||
meaa->setOffset(offset);
|
||||
meaa->setContainer(this);
|
||||
meaa->setElementType( element);
|
||||
_metaElements.append(meaa);
|
||||
}
|
||||
void
|
||||
daeMetaElement::appendElement(daeMetaElement* element, daeInt offset, daeString name)
|
||||
{
|
||||
daeMetaElementAttribute* meaa = new daeMetaElementAttribute;
|
||||
meaa->setType(daeAtomicType::get("element"));
|
||||
if ( name ) {
|
||||
meaa->setName(name);
|
||||
}
|
||||
else {
|
||||
meaa->setName(element->getName());
|
||||
}
|
||||
meaa->setOffset( offset);
|
||||
meaa->setContainer( this );
|
||||
meaa->setElementType( element );
|
||||
_metaElements.append(meaa);
|
||||
}*/
|
||||
|
||||
void
|
||||
daeMetaElement::appendAttribute(daeMetaAttribute* attr)
|
||||
{
|
||||
if (attr == NULL)
|
||||
return;
|
||||
|
||||
if (strcmp(attr->getName(),"_value") == 0) {
|
||||
_metaValue = attr;
|
||||
}
|
||||
else
|
||||
_metaAttributes.append(attr);
|
||||
|
||||
if ((attr->getName() != NULL) &&
|
||||
(strcmp(attr->getName(),"id") == 0)) {
|
||||
_metaID = attr;
|
||||
_isTrackableForQueries = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
daeMetaElement::validate()
|
||||
{
|
||||
if (_elementSize == 0)
|
||||
{
|
||||
daeInt place=0;
|
||||
unsigned int i;
|
||||
for(i=0;i<_metaAttributes.getCount();i++) {
|
||||
place += _metaAttributes[i]->getSize();
|
||||
int align = _metaAttributes[i]->getAlignment();
|
||||
place += align;
|
||||
place &= (~(align-1));
|
||||
}
|
||||
_elementSize = place;
|
||||
}
|
||||
}
|
||||
|
||||
daeMetaAttribute*
|
||||
daeMetaElement::getMetaAttribute(daeString s)
|
||||
{
|
||||
int cnt = (int)_metaAttributes.getCount();
|
||||
int i;
|
||||
for(i=0;i<cnt;i++)
|
||||
if (strcmp(_metaAttributes[i]->getName(),s) == 0)
|
||||
return _metaAttributes[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// void daeMetaElement::releaseMetas()
|
||||
// {
|
||||
// _metas().clear();
|
||||
// size_t count = _classMetaPointers().getCount();
|
||||
// for ( size_t i = 0; i < count; i++ )
|
||||
// {
|
||||
// *(_classMetaPointers()[i]) = NULL;
|
||||
// }
|
||||
// _classMetaPointers().clear();
|
||||
// if (mera)
|
||||
// {
|
||||
// delete mera;
|
||||
// mera = NULL;
|
||||
// }
|
||||
// if (mes)
|
||||
// {
|
||||
// delete mes;
|
||||
// mes = NULL;
|
||||
// }
|
||||
// }
|
||||
|
||||
daeBool daeMetaElement::place(daeElement *parent, daeElement *child, daeUInt *ordinal )
|
||||
{
|
||||
if (child->getMeta()->getIsAbstract() || parent->getMeta() != this ) {
|
||||
return false;
|
||||
}
|
||||
daeUInt ord;
|
||||
daeElement *retVal = _contentModel->placeElement( parent, child, ord );
|
||||
if ( retVal != NULL ) {
|
||||
//update document pointer
|
||||
child->setDocument( parent->getDocument() );
|
||||
retVal->setDocument( parent->getDocument() );
|
||||
//add to _contents array
|
||||
if (_metaContents != NULL) {
|
||||
daeElementRefArray* contents =
|
||||
(daeElementRefArray*)_metaContents->getWritableMemory(parent);
|
||||
daeUIntArray* contentsOrder =
|
||||
(daeUIntArray*)_metaContentsOrder->getWritableMemory(parent);
|
||||
daeBool needsAppend = true;
|
||||
size_t cnt = contentsOrder->getCount();
|
||||
for ( size_t x = 0; x < cnt; x++ ) {
|
||||
if ( contentsOrder->get(x) > ord ) {
|
||||
contents->insertAt( x, retVal );
|
||||
contentsOrder->insertAt( x, ord );
|
||||
needsAppend = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( needsAppend ) {
|
||||
contents->append(retVal);
|
||||
contentsOrder->append( ord );
|
||||
}
|
||||
}
|
||||
if ( ordinal != NULL ) {
|
||||
*ordinal = ord;
|
||||
}
|
||||
}
|
||||
return retVal!=NULL;
|
||||
}
|
||||
|
||||
daeBool daeMetaElement::placeAt( daeInt index, daeElement *parent, daeElement *child )
|
||||
{
|
||||
if (child->getMeta()->getIsAbstract() || parent->getMeta() != this || index < 0 ) {
|
||||
return false;
|
||||
}
|
||||
daeUInt ord;
|
||||
daeElement *retVal = _contentModel->placeElement( parent, child, ord );
|
||||
if ( retVal != NULL ) {
|
||||
//add to _contents array
|
||||
if (_metaContents != NULL) {
|
||||
daeElementRefArray* contents =
|
||||
(daeElementRefArray*)_metaContents->getWritableMemory(parent);
|
||||
daeUIntArray* contentsOrder =
|
||||
(daeUIntArray*)_metaContentsOrder->getWritableMemory(parent);
|
||||
daeBool validLoc;
|
||||
if ( index > 0 ) {
|
||||
validLoc = contentsOrder->get(index) >= ord && contentsOrder->get(index) <= ord;
|
||||
}
|
||||
else {
|
||||
if ( contentsOrder->getCount() == 0 ) {
|
||||
validLoc = true;
|
||||
}
|
||||
else {
|
||||
validLoc = contentsOrder->get(index) >= ord;
|
||||
}
|
||||
}
|
||||
if ( validLoc ) {
|
||||
contents->insertAt( index, retVal );
|
||||
contentsOrder->insertAt( index, ord );
|
||||
}
|
||||
else {
|
||||
_contentModel->removeElement( parent, retVal );
|
||||
retVal = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( retVal != NULL ) {
|
||||
//update document pointer
|
||||
child->setDocument( parent->getDocument() );
|
||||
retVal->setDocument( parent->getDocument() );
|
||||
}
|
||||
return retVal!=NULL;
|
||||
}
|
||||
|
||||
daeBool daeMetaElement::placeBefore( daeElement *marker, daeElement *parent, daeElement *child, daeUInt *ordinal )
|
||||
{
|
||||
if (child->getMeta()->getIsAbstract() || parent->getMeta() != this ) {
|
||||
return false;
|
||||
}
|
||||
daeUInt ord;
|
||||
daeElement *retVal = _contentModel->placeElement( parent, child, ord, 0, marker, NULL );
|
||||
if ( retVal != NULL ) {
|
||||
//add to _contents array
|
||||
if (_metaContents != NULL) {
|
||||
daeElementRefArray* contents =
|
||||
(daeElementRefArray*)_metaContents->getWritableMemory(parent);
|
||||
daeUIntArray* contentsOrder =
|
||||
(daeUIntArray*)_metaContentsOrder->getWritableMemory(parent);
|
||||
size_t index(0);
|
||||
daeBool validLoc = false;
|
||||
if ( contents->find( marker, index ) == DAE_OK ) {
|
||||
if ( index > 0 ) {
|
||||
daeUInt gt = contentsOrder->get(index-1);
|
||||
daeUInt lt = contentsOrder->get(index);
|
||||
validLoc = gt <= ord && lt >= ord;
|
||||
}
|
||||
else {
|
||||
validLoc = contentsOrder->get(index) >= ord;
|
||||
}
|
||||
}
|
||||
if ( validLoc ) {
|
||||
contents->insertAt( index, retVal );
|
||||
contentsOrder->insertAt( index, ord );
|
||||
if ( ordinal != NULL ) {
|
||||
*ordinal = ord;
|
||||
}
|
||||
}
|
||||
else {
|
||||
_contentModel->removeElement( parent, retVal );
|
||||
retVal = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( retVal != NULL ) {
|
||||
//update document pointer
|
||||
child->setDocument( parent->getDocument() );
|
||||
retVal->setDocument( parent->getDocument() );
|
||||
}
|
||||
return retVal!=NULL;
|
||||
}
|
||||
|
||||
daeBool daeMetaElement::placeAfter( daeElement *marker, daeElement *parent, daeElement *child, daeUInt *ordinal )
|
||||
{
|
||||
if (child->getMeta()->getIsAbstract() || parent->getMeta() != this ) {
|
||||
return false;
|
||||
}
|
||||
daeUInt ord;
|
||||
daeElement *retVal = _contentModel->placeElement( parent, child, ord, 0, NULL, marker );
|
||||
if ( retVal != NULL ) {
|
||||
//add to _contents array
|
||||
if (_metaContents != NULL) {
|
||||
daeElementRefArray* contents =
|
||||
(daeElementRefArray*)_metaContents->getWritableMemory(parent);
|
||||
daeUIntArray* contentsOrder =
|
||||
(daeUIntArray*)_metaContentsOrder->getWritableMemory(parent);
|
||||
size_t index(0);
|
||||
daeBool validLoc = false;
|
||||
if ( contents->find( marker, index ) == DAE_OK ) {
|
||||
if ( index < contentsOrder->getCount()-1 ) {
|
||||
validLoc = contentsOrder->get(index) <= ord && contentsOrder->get(index+1) >= ord;
|
||||
}
|
||||
else {
|
||||
validLoc = contentsOrder->get(index) <= ord;
|
||||
}
|
||||
}
|
||||
if ( validLoc ) {
|
||||
contents->insertAt( index+1, retVal );
|
||||
contentsOrder->insertAt( index+1, ord );
|
||||
if ( ordinal != NULL ) {
|
||||
*ordinal = ord;
|
||||
}
|
||||
}
|
||||
else {
|
||||
_contentModel->removeElement( parent, retVal );
|
||||
retVal = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( retVal != NULL ) {
|
||||
//update document pointer
|
||||
child->setDocument( parent->getDocument() );
|
||||
retVal->setDocument( parent->getDocument() );
|
||||
}
|
||||
return retVal!=NULL;
|
||||
}
|
||||
|
||||
daeBool daeMetaElement::remove(daeElement *parent, daeElement *child)
|
||||
{
|
||||
if ( parent->getMeta() != this ) {
|
||||
return false;
|
||||
}
|
||||
//prevent child from being deleted
|
||||
daeElementRef el( child );
|
||||
if ( _contentModel->removeElement( parent, child ) ) {
|
||||
if ( _metaContents != NULL)
|
||||
{
|
||||
daeElementRefArray* contents = (daeElementRefArray*)_metaContents->getWritableMemory(parent);
|
||||
daeUIntArray* contentsOrder = (daeUIntArray*)_metaContentsOrder->getWritableMemory(parent);
|
||||
size_t idx(0);
|
||||
if ( contents->remove(child, &idx) == DAE_OK ) {
|
||||
contentsOrder->removeIndex( idx );
|
||||
}
|
||||
}
|
||||
if ( child->getDocument() ) {
|
||||
child->getDocument()->removeElement( child );
|
||||
}
|
||||
|
||||
// Clear the child's parent pointer
|
||||
child->setParentElement( NULL );
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void daeMetaElement::getChildren( daeElement* parent, daeElementRefArray &array )
|
||||
{
|
||||
if ( parent->getMeta() != this ) {
|
||||
return;
|
||||
}
|
||||
if ( _metaContents != NULL ) {
|
||||
daeElementRefArray* contents = (daeElementRefArray*)_metaContents->getWritableMemory(parent);
|
||||
for ( size_t x = 0; x < contents->getCount(); x++ ) {
|
||||
array.append( contents->get(x) );
|
||||
}
|
||||
}
|
||||
else if ( _contentModel != NULL ) {
|
||||
_contentModel->getChildren( parent, array );
|
||||
}
|
||||
}
|
||||
|
||||
// daeMetaElementRefArray &daeMetaElement::_metas()
|
||||
// {
|
||||
// if (!mera)
|
||||
// {
|
||||
// mera = new daeMetaElementRefArray();
|
||||
// }
|
||||
// return *mera;
|
||||
// }
|
||||
|
||||
// daeTArray< daeMetaElement** > &daeMetaElement::_classMetaPointers()
|
||||
// {
|
||||
// if (!mes)
|
||||
// {
|
||||
// mes = new daeTArray< daeMetaElement** >();
|
||||
// }
|
||||
// return *mes;
|
||||
// }
|
||||
|
||||
232
Engine/lib/collada/src/dae/daeMetaElementAttribute.cpp
Normal file
232
Engine/lib/collada/src/dae/daeMetaElementAttribute.cpp
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <dae/daeMetaElementAttribute.h>
|
||||
#include <dae/daeMetaElement.h>
|
||||
|
||||
daeMetaElementAttribute::daeMetaElementAttribute( daeMetaElement *container, daeMetaCMPolicy *parent, daeUInt ordinal,
|
||||
daeInt minO, daeInt maxO) : daeMetaCMPolicy( container, parent, ordinal, minO, maxO )
|
||||
{
|
||||
_elementType = NULL;
|
||||
}
|
||||
|
||||
daeMetaElementAttribute::~daeMetaElementAttribute()
|
||||
{}
|
||||
|
||||
daeMetaElementArrayAttribute::daeMetaElementArrayAttribute( daeMetaElement *container, daeMetaCMPolicy *parent, daeUInt ordinal,
|
||||
daeInt minO, daeInt maxO) : daeMetaElementAttribute( container, parent, ordinal, minO, maxO )
|
||||
{
|
||||
}
|
||||
|
||||
daeMetaElementArrayAttribute::~daeMetaElementArrayAttribute()
|
||||
{}
|
||||
|
||||
|
||||
void daeMetaElementAttribute::set(daeElement* e, daeString s)
|
||||
{
|
||||
//_type->stringToMemory((char*)s, getWritableMemory(e));
|
||||
daeElementRef *ref = (daeElementRef*)(getWritableMemory(e));
|
||||
if ((*ref) == NULL) {
|
||||
(*ref) = _elementType->create();
|
||||
}
|
||||
(*ref)->getMeta()->getValueAttribute()->stringToMemory((*ref), s);
|
||||
}
|
||||
|
||||
void daeMetaElementAttribute::copy(daeElement* to, daeElement *from) {
|
||||
daeElement *cpy = (*(daeElementRef*)(getWritableMemory(from)))->clone();
|
||||
(*(daeElementRef*)(getWritableMemory(to))) = cpy;
|
||||
}
|
||||
|
||||
void daeMetaElementArrayAttribute::copy(daeElement* to, daeElement *from) {
|
||||
(void)to;
|
||||
(void)from;
|
||||
}
|
||||
|
||||
void
|
||||
daeMetaElementAttribute::setDocument( daeElement * parent, daeDocument* c )
|
||||
{
|
||||
daeElementRef* er = (daeElementRef*)getWritableMemory( parent );
|
||||
if ( ((daeElement*)(*er)) != NULL ) {
|
||||
(*er)->setDocument( c );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
daeMetaElementArrayAttribute::setDocument( daeElement * parent, daeDocument* c )
|
||||
{
|
||||
daeElementRefArray* era = (daeElementRefArray*)getWritableMemory( parent );
|
||||
for ( unsigned int i = 0; i < era->getCount(); i++ ) {
|
||||
era->get(i)->setDocument( c );
|
||||
}
|
||||
}
|
||||
|
||||
daeInt
|
||||
daeMetaElementAttribute::getCount(daeElement* e)
|
||||
{
|
||||
if (e == NULL)
|
||||
return 0;
|
||||
return ((*((daeElementRef*)getWritableMemory(e))) != NULL);
|
||||
}
|
||||
|
||||
daeMemoryRef
|
||||
daeMetaElementAttribute::get(daeElement *e, daeInt index)
|
||||
{
|
||||
(void)index;
|
||||
return getWritableMemory(e);
|
||||
}
|
||||
|
||||
daeInt
|
||||
daeMetaElementArrayAttribute::getCount(daeElement *e)
|
||||
{
|
||||
if (e == NULL)
|
||||
return 0;
|
||||
daeElementRefArray* era = (daeElementRefArray*)getWritableMemory(e);
|
||||
if (era == NULL)
|
||||
return 0;
|
||||
return (daeInt)era->getCount();
|
||||
}
|
||||
|
||||
daeMemoryRef
|
||||
daeMetaElementArrayAttribute::get(daeElement* e, daeInt index)
|
||||
{
|
||||
if (e == NULL)
|
||||
return NULL;
|
||||
daeElementRefArray* era = (daeElementRefArray*)getWritableMemory(e);
|
||||
if (era == NULL || index >= (daeInt)era->getCount() )
|
||||
return NULL;
|
||||
return (daeMemoryRef)&(era->get(index));
|
||||
}
|
||||
|
||||
daeElement *
|
||||
daeMetaElementAttribute::placeElement(daeElement* parent, daeElement* child, daeUInt &ordinal, daeInt offset, daeElement* before, daeElement *after )
|
||||
{
|
||||
(void)offset;
|
||||
(void)before;
|
||||
(void)after;
|
||||
if ((parent == NULL)||(child == NULL))
|
||||
return NULL;
|
||||
if ( child->getMeta() != _elementType || strcmp( child->getElementName(), _name ) != 0 ) {
|
||||
return NULL;
|
||||
}
|
||||
if (child->getParentElement() == parent) {
|
||||
//I Don't know why this gets called when the child already has this as parent.
|
||||
return child;
|
||||
}
|
||||
daeElementRef* er = (daeElementRef*)getWritableMemory(parent);
|
||||
|
||||
if ( *er != NULL )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeElement::removeFromParent( child );
|
||||
child->setParentElement( parent );
|
||||
|
||||
*er = child;
|
||||
ordinal = _ordinalOffset;
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
daeElement *
|
||||
daeMetaElementArrayAttribute::placeElement(daeElement* parent, daeElement* child, daeUInt &ordinal, daeInt offset, daeElement* before, daeElement *after )
|
||||
{
|
||||
if ((parent == NULL)||(child == NULL))
|
||||
return NULL;
|
||||
if ( child->getMeta() != _elementType || strcmp( child->getElementName(), _name ) != 0 ) {
|
||||
return NULL;
|
||||
}
|
||||
daeElement *p = child->getParentElement();
|
||||
daeElementRefArray* era = (daeElementRefArray*)getWritableMemory(parent);
|
||||
if ( _maxOccurs != -1 && (daeInt)era->getCount()-offset >= _maxOccurs ) {
|
||||
return NULL;
|
||||
}
|
||||
removeElement( p, child );
|
||||
child->setParentElement( parent );
|
||||
|
||||
if ( before != NULL && before->getMeta() == _elementType ) {
|
||||
size_t idx(0);
|
||||
if ( era->find( before, idx ) == DAE_OK ) {
|
||||
era->insertAt( idx, child );
|
||||
}
|
||||
}
|
||||
else if ( after != NULL && after->getMeta() == _elementType ) {
|
||||
size_t idx(0);
|
||||
if ( era->find( after, idx ) == DAE_OK ) {
|
||||
era->insertAt( idx+1, child );
|
||||
}
|
||||
}
|
||||
else {
|
||||
era->append(child);
|
||||
}
|
||||
ordinal = _ordinalOffset;
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
// These are the opposite of the placeElement functions above
|
||||
daeBool
|
||||
daeMetaElementAttribute::removeElement(daeElement* parent, daeElement* child)
|
||||
{
|
||||
(void)child; // silence unused variable warning
|
||||
|
||||
if ((parent == NULL)||(child == NULL ))
|
||||
return false;
|
||||
|
||||
daeElementRef* er = (daeElementRef*)getWritableMemory(parent);
|
||||
if ( *er != child ) {
|
||||
return false;
|
||||
}
|
||||
*er = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
daeBool
|
||||
daeMetaElementArrayAttribute::removeElement(daeElement* parent,
|
||||
daeElement* child)
|
||||
{
|
||||
if ((parent == NULL)||(child == NULL))
|
||||
return false ;
|
||||
|
||||
daeElementRefArray* era = (daeElementRefArray*)getWritableMemory(parent);
|
||||
/* if ( (daeInt)era->getCount() <= _minOccurs ) {
|
||||
return false;
|
||||
}*/
|
||||
daeInt error = era->remove(child);
|
||||
if ( error != DAE_OK ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
daeMetaElement *daeMetaElementAttribute::findChild( daeString elementName ) {
|
||||
if ( strcmp( elementName, _name ) == 0 ) {
|
||||
return _elementType;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void daeMetaElementAttribute::getChildren( daeElement *parent, daeElementRefArray &array ) {
|
||||
daeElementRef* er = (daeElementRef*)getWritableMemory(parent);
|
||||
if ( *er != NULL ) {
|
||||
array.appendUnique( *er );
|
||||
}
|
||||
}
|
||||
|
||||
void daeMetaElementArrayAttribute::getChildren( daeElement *parent, daeElementRefArray &array ) {
|
||||
daeElementRefArray* era = (daeElementRefArray*)getWritableMemory(parent);
|
||||
size_t cnt = era->getCount();
|
||||
for ( size_t x = 0; x < cnt; x++ ) {
|
||||
array.appendUnique( era->get(x) );
|
||||
}
|
||||
}
|
||||
149
Engine/lib/collada/src/dae/daeMetaGroup.cpp
Normal file
149
Engine/lib/collada/src/dae/daeMetaGroup.cpp
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <dae/daeMetaGroup.h>
|
||||
#include <dae/daeMetaElementAttribute.h>
|
||||
#include <dae/daeMetaElement.h>
|
||||
|
||||
daeMetaGroup::daeMetaGroup( daeMetaElementAttribute *econ, daeMetaElement *container,
|
||||
daeMetaCMPolicy *parent, daeUInt ordinal, daeInt minO, daeInt maxO) :
|
||||
daeMetaCMPolicy( container, parent, ordinal, minO, maxO ), _elementContainer( econ )
|
||||
{}
|
||||
|
||||
daeMetaGroup::~daeMetaGroup()
|
||||
{
|
||||
if ( _elementContainer != NULL ) {
|
||||
delete _elementContainer;
|
||||
}
|
||||
}
|
||||
|
||||
daeElement *daeMetaGroup::placeElement( daeElement *parent, daeElement *child, daeUInt &ordinal, daeInt offset, daeElement* before, daeElement *after ) {
|
||||
(void)offset;
|
||||
daeString nm = child->getElementName();
|
||||
if ( findChild( nm ) == NULL ) {
|
||||
return false;
|
||||
}
|
||||
daeElementRef el;
|
||||
|
||||
//check if the element trying to be placed is a group element. If so Just add it don't create a new one.
|
||||
if ( strcmp( nm, _elementContainer->getName() ) == 0 ) {
|
||||
if ( _elementContainer->placeElement(parent, child, ordinal, offset ) != NULL ) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
daeInt elCnt = _elementContainer->getCount(parent);
|
||||
//check existing groups
|
||||
//This doesn't work properly. Because the choice can't check if you make two decisions you cannot fail
|
||||
//here when you are supposed to. Luckily the current schema just has groups with single choices so
|
||||
//every element needs a new group container. Wasteful but thats how the schema is and its how it works.
|
||||
for ( daeInt x = 0; x < elCnt; x++ ) {
|
||||
daeMemoryRef mem = _elementContainer->get(parent, x );
|
||||
if ( mem != NULL ) {
|
||||
el = *(daeElementRef*)mem;
|
||||
}
|
||||
if ( el == NULL ) {
|
||||
continue;
|
||||
}
|
||||
if ( before != NULL ) {
|
||||
if ( _elementContainer->_elementType->placeBefore( before, el, child, &ordinal ) ) {
|
||||
ordinal = ordinal + _ordinalOffset;
|
||||
return el;
|
||||
}
|
||||
}
|
||||
else if ( after != NULL ) {
|
||||
if ( _elementContainer->_elementType->placeAfter( after, el, child, &ordinal ) ) {
|
||||
ordinal = ordinal + _ordinalOffset;
|
||||
return el;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( _elementContainer->_elementType->place( el, child, &ordinal ) ) {
|
||||
ordinal = ordinal + _ordinalOffset;
|
||||
return el;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//if you couldn't place in existing groups make a new one if you can
|
||||
el = _elementContainer->placeElement(parent, _elementContainer->_elementType->create(), ordinal, offset );
|
||||
if ( el != NULL ) {
|
||||
//el = *(daeElementRef*)_elementContainer->get(parent, elCnt );
|
||||
if ( before != NULL ) {
|
||||
if ( _elementContainer->_elementType->placeBefore( before, el, child, &ordinal ) ) {
|
||||
ordinal = ordinal + _ordinalOffset;
|
||||
return el;
|
||||
}
|
||||
}
|
||||
else if ( after != NULL ) {
|
||||
if ( _elementContainer->_elementType->placeAfter( after, el, child, &ordinal ) ) {
|
||||
ordinal = ordinal + _ordinalOffset;
|
||||
return el;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( _elementContainer->_elementType->place( el, child, &ordinal ) ) {
|
||||
ordinal = ordinal + _ordinalOffset;
|
||||
return el;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeBool daeMetaGroup::removeElement( daeElement *parent, daeElement *child ) {
|
||||
daeElementRef el;
|
||||
daeInt elCnt = _elementContainer->getCount(parent);
|
||||
for ( daeInt x = 0; x < elCnt; x++ ) {
|
||||
daeMemoryRef mem = _elementContainer->get(parent, x );
|
||||
if ( mem != NULL ) {
|
||||
el = *(daeElementRef*)mem;
|
||||
}
|
||||
if ( el == NULL ) {
|
||||
continue;
|
||||
}
|
||||
if ( el->removeChildElement( child ) ) {
|
||||
//check if there are any more children in this group. If not remove the group container element too.
|
||||
daeElementRefArray array;
|
||||
getChildren( parent, array );
|
||||
if ( array.getCount() == 0 )
|
||||
{
|
||||
_elementContainer->removeElement( parent, el );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
daeMetaElement * daeMetaGroup::findChild( daeString elementName ) {
|
||||
if ( strcmp( _elementContainer->getName(), elementName ) == 0 ) {
|
||||
return _elementContainer->getElementType();
|
||||
}
|
||||
return _elementContainer->_elementType->getCMRoot()->findChild( elementName );
|
||||
}
|
||||
|
||||
void daeMetaGroup::getChildren( daeElement *parent, daeElementRefArray &array ) {
|
||||
size_t cnt = _elementContainer->getCount( parent );
|
||||
for ( size_t x = 0; x < cnt; x++ ) {
|
||||
(*((daeElementRef*)_elementContainer->get(parent, (daeInt)x )))->getChildren( array );
|
||||
/*daeElementRef el = (*((daeElementRef*)_elementContainer->get(parent, (daeInt)x )));
|
||||
size_t cnt2 = _children.getCount();
|
||||
for ( size_t i = 0; i < cnt2; i++ ) {
|
||||
_children[i]->getChildren( el, array );
|
||||
}*/
|
||||
}
|
||||
//_elementContainer->_elementType->getChildren( parent, array );
|
||||
}
|
||||
|
||||
72
Engine/lib/collada/src/dae/daeMetaSequence.cpp
Normal file
72
Engine/lib/collada/src/dae/daeMetaSequence.cpp
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <dae/daeMetaSequence.h>
|
||||
|
||||
daeMetaSequence::daeMetaSequence( daeMetaElement *container, daeMetaCMPolicy *parent, daeUInt ordinal,
|
||||
daeInt minO, daeInt maxO) :
|
||||
daeMetaCMPolicy( container, parent, ordinal, minO, maxO )
|
||||
{}
|
||||
|
||||
daeMetaSequence::~daeMetaSequence()
|
||||
{}
|
||||
|
||||
daeElement *daeMetaSequence::placeElement( daeElement *parent, daeElement *child, daeUInt &ordinal, daeInt offset, daeElement* before, daeElement *after ) {
|
||||
(void)offset;
|
||||
if ( _maxOccurs == -1 ) {
|
||||
//Needed to prevent infinate loops. If unbounded check to see if you have the child before just trying to place
|
||||
if ( findChild( child->getElementName() ) == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
size_t cnt = _children.getCount();
|
||||
for ( daeInt i = 0; ( i < _maxOccurs || _maxOccurs == -1 ); i++ ) {
|
||||
for ( size_t x = 0; x < cnt; x++ ) {
|
||||
if ( _children[x]->placeElement( parent, child, ordinal, i, before, after ) != NULL ) {
|
||||
ordinal = ordinal + (i * ( _maxOrdinal + 1 )) + _ordinalOffset;
|
||||
return child;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeBool daeMetaSequence::removeElement( daeElement *parent, daeElement *child ) {
|
||||
size_t cnt = _children.getCount();
|
||||
for ( size_t x = 0; x < cnt; x++ ) {
|
||||
if ( _children[x]->removeElement( parent, child ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
daeMetaElement * daeMetaSequence::findChild( daeString elementName ) {
|
||||
daeMetaElement *me = NULL;
|
||||
size_t cnt = _children.getCount();
|
||||
for ( size_t x = 0; x < cnt; x++ ) {
|
||||
me = _children[x]->findChild( elementName );
|
||||
if ( me != NULL ) {
|
||||
return me;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void daeMetaSequence::getChildren( daeElement *parent, daeElementRefArray &array ) {
|
||||
size_t cnt = _children.getCount();
|
||||
for ( size_t x = 0; x < cnt; x++ ) {
|
||||
_children[x]->getChildren( parent, array );
|
||||
}
|
||||
}
|
||||
129
Engine/lib/collada/src/dae/daeRawResolver.cpp
Normal file
129
Engine/lib/collada/src/dae/daeRawResolver.cpp
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <dae/daeRawResolver.h>
|
||||
#include <dae.h>
|
||||
#include <dae/daeURI.h>
|
||||
#include <dae/daeErrorHandler.h>
|
||||
#include <dae/daeUtils.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
daeRawResolver::daeRawResolver(DAE& dae) : daeURIResolver(dae)
|
||||
{
|
||||
}
|
||||
|
||||
daeRawResolver::~daeRawResolver()
|
||||
{
|
||||
}
|
||||
|
||||
daeString
|
||||
daeRawResolver::getName()
|
||||
{
|
||||
return "RawResolver";
|
||||
}
|
||||
|
||||
daeElement* daeRawResolver::resolveElement(const daeURI& uri) {
|
||||
if (cdom::tolower(uri.pathExt()).find(".raw") == string::npos)
|
||||
return NULL;
|
||||
|
||||
daeRawRefCache& cache = dae->getRawRefCache();
|
||||
if (daeElement* elt = cache.lookup(uri))
|
||||
return elt;
|
||||
|
||||
string fileName = cdom::uriToNativePath(uri.str());
|
||||
if (fileName.empty())
|
||||
{
|
||||
daeErrorHandler::get()->handleError( "daeRawResolver::resolveElement() - Can't get path from URI\n" );
|
||||
return NULL;
|
||||
}
|
||||
FILE *rawFile = fopen(fileName.c_str(), "rb");
|
||||
if (rawFile == NULL )
|
||||
return NULL;
|
||||
long byteOffset = atoi( uri.getID() ); //get the fragment
|
||||
|
||||
daeElement *src;
|
||||
daeElement *array;
|
||||
daeElement *accessor;
|
||||
|
||||
accessor = uri.getContainer();
|
||||
if ( accessor == NULL )
|
||||
return NULL;
|
||||
src = accessor->getParentElement()->getParentElement();
|
||||
daeElementRefArray children;
|
||||
accessor->getChildren( children );
|
||||
bool hasInts = children[0]->getAttribute("type") == "int";
|
||||
|
||||
if ( hasInts )
|
||||
{
|
||||
array = src->createAndPlace( "int_array" );
|
||||
}
|
||||
else
|
||||
{
|
||||
array = src->createAndPlace( "float_array" );
|
||||
}
|
||||
|
||||
daeULong *countPtr = (daeULong*)accessor->getAttributeValue( "count" );
|
||||
daeULong count = countPtr != NULL ? *countPtr : 0;
|
||||
|
||||
daeULong *stridePtr = (daeULong*)accessor->getAttributeValue( "stride" );
|
||||
daeULong stride = stridePtr != NULL ? *stridePtr : 1;
|
||||
|
||||
*(daeULong*)(array->getAttributeValue("count")) = count*stride;
|
||||
array->setAttribute( "id", (src->getAttribute("id") + "-array").c_str() );
|
||||
|
||||
daeArray *valArray = (daeArray*)array->getValuePointer();
|
||||
valArray->setCount( (size_t)(count*stride) );
|
||||
|
||||
fseek( rawFile, byteOffset, SEEK_SET );
|
||||
if ( hasInts )
|
||||
{
|
||||
daeInt val;
|
||||
for ( unsigned int i = 0; i < count*stride; i++ )
|
||||
{
|
||||
fread( &val, sizeof(daeInt), 1, rawFile );
|
||||
*(daeLong*)(valArray->getRaw(i)) = (daeLong)val;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
daeFloat val;
|
||||
for ( unsigned int i = 0; i < count*stride; i++ )
|
||||
{
|
||||
fread( &val, sizeof(daeFloat), 1, rawFile );
|
||||
*(daeDouble*)(valArray->getRaw(i)) = (daeDouble)val;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(rawFile);
|
||||
cache.add(uri, array);
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
daeElement* daeRawRefCache::lookup(const daeURI& uri) {
|
||||
map<string, daeElement*>::iterator iter = lookupTable.find(uri.str());
|
||||
return iter == lookupTable.end() ? NULL : iter->second;
|
||||
}
|
||||
|
||||
void daeRawRefCache::add(const daeURI& uri, daeElement* elt) {
|
||||
lookupTable[uri.str()] = elt;
|
||||
}
|
||||
|
||||
void daeRawRefCache::remove(const daeURI& uri) {
|
||||
lookupTable.erase(uri.str());
|
||||
}
|
||||
|
||||
void daeRawRefCache::clear() {
|
||||
lookupTable.clear();
|
||||
}
|
||||
37
Engine/lib/collada/src/dae/daeRefCountedObj.cpp
Normal file
37
Engine/lib/collada/src/dae/daeRefCountedObj.cpp
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <dae/daeRefCountedObj.h>
|
||||
|
||||
daeRefCountedObj::daeRefCountedObj() : _refCount(0) { }
|
||||
|
||||
daeRefCountedObj::~daeRefCountedObj() { }
|
||||
|
||||
void daeRefCountedObj::release() const {
|
||||
if (--_refCount <= 0)
|
||||
delete this;
|
||||
}
|
||||
|
||||
void daeRefCountedObj::ref() const {
|
||||
_refCount++;
|
||||
}
|
||||
|
||||
void checkedRelease(const daeRefCountedObj* obj) {
|
||||
if (obj)
|
||||
obj->release();
|
||||
}
|
||||
|
||||
void checkedRef(const daeRefCountedObj* obj) {
|
||||
if (obj)
|
||||
obj->ref();
|
||||
}
|
||||
511
Engine/lib/collada/src/dae/daeSIDResolver.cpp
Normal file
511
Engine/lib/collada/src/dae/daeSIDResolver.cpp
Normal file
|
|
@ -0,0 +1,511 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <dae/daeSIDResolver.h>
|
||||
#include <dae/daeIDRef.h>
|
||||
#include <dae/daeAtomicType.h>
|
||||
#include <dae/daeMetaAttribute.h>
|
||||
#include <dae/daeMetaElement.h>
|
||||
#include <dae/daeURI.h>
|
||||
#include <dom/domTypes.h>
|
||||
#include <dom/domConstants.h>
|
||||
#include <dae/daeDocument.h>
|
||||
#include <dae/daeDatabase.h>
|
||||
#include <dae/daeUtils.h>
|
||||
#include <dom/domSource.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
namespace {
|
||||
template<typename T>
|
||||
T nextIter(const T& iter) {
|
||||
T next = iter;
|
||||
return ++next;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T moveIter(const T& iter, int n) {
|
||||
T result = iter;
|
||||
advance(result, n);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Implements a breadth-first sid search by starting at the container element and
|
||||
// traversing downward through the element tree.
|
||||
daeElement* findSidTopDown(daeElement* container, const string& sid, const string& profile) {
|
||||
if (!container)
|
||||
return NULL;
|
||||
|
||||
vector<daeElement*> elts, matchingElts;
|
||||
elts.push_back(container);
|
||||
|
||||
for (size_t i = 0; i < elts.size(); i++) {
|
||||
daeElement* elt = elts[i];
|
||||
|
||||
// Bail if we're looking for an element in a different profile
|
||||
if (!profile.empty()) {
|
||||
if (strcmp(elt->getElementName(), COLLADA_ELEMENT_TECHNIQUE_COMMON) == 0)
|
||||
continue;
|
||||
if (strcmp(elt->getElementName(), COLLADA_ELEMENT_TECHNIQUE) == 0 &&
|
||||
profile != elt->getAttribute("profile"))
|
||||
continue;
|
||||
}
|
||||
|
||||
// See if this is a matching element
|
||||
if (elt->getAttribute("sid") == sid)
|
||||
return elt;
|
||||
else {
|
||||
// Add the children to the list of elements to check
|
||||
daeElementRefArray children;
|
||||
elt->getChildren(children);
|
||||
for (size_t j = 0; j < children.getCount(); j++)
|
||||
elts.push_back(children[j]);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Returns the distance between an element and an ancestor of the element. If 'container
|
||||
// isn't an ancestor of 'elt', or if 'elt' is in a profile that doesn't match 'profile'
|
||||
// UINT_MAX is returned.
|
||||
unsigned int computeDistance(daeElement* container, daeElement* elt, const string& profile) {
|
||||
if (!container || !elt)
|
||||
return UINT_MAX;
|
||||
|
||||
unsigned int distance = 0;
|
||||
do {
|
||||
// Bail if we're looking for an element in a different profile
|
||||
if (!profile.empty()) {
|
||||
if (strcmp(elt->getElementName(), COLLADA_ELEMENT_TECHNIQUE_COMMON) == 0)
|
||||
return UINT_MAX;
|
||||
if (strcmp(elt->getElementName(), COLLADA_ELEMENT_TECHNIQUE) == 0 &&
|
||||
profile != elt->getAttribute("profile"))
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
if (elt == container)
|
||||
return distance;
|
||||
distance++;
|
||||
} while ((elt = elt->getParentElement()) != NULL);
|
||||
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
// Implements a breadth-first sid search by using the database to find all elements
|
||||
// matching 'sid', then finding the element closest to 'container'.
|
||||
daeElement* findSidBottomUp(daeElement* container, const string& sid, const string& profile) {
|
||||
if (!container || !container->getDocument())
|
||||
return NULL;
|
||||
|
||||
// Get the elements with a matching sid
|
||||
vector<daeElement*> elts;
|
||||
container->getDocument()->getDAE()->getDatabase()->sidLookup(sid, elts, container->getDocument());
|
||||
|
||||
// Compute the distance from each matching element to the container element
|
||||
unsigned int minDistance = UINT_MAX;
|
||||
daeElement* closestElt = NULL;
|
||||
for (size_t i = 0; i < elts.size(); i++) {
|
||||
unsigned int distance = computeDistance(container, elts[i], profile);
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance;
|
||||
closestElt = elts[i];
|
||||
}
|
||||
}
|
||||
|
||||
return closestElt;
|
||||
}
|
||||
|
||||
daeElement* findID(daeElement* elt, const string& id, const string& profile) {
|
||||
return elt ? elt->getDAE()->getDatabase()->idLookup(id, elt->getDocument()) : NULL;
|
||||
}
|
||||
|
||||
void buildString(const list<string>::iterator& begin,
|
||||
const list<string>::iterator& end,
|
||||
string& result) {
|
||||
ostringstream stream;
|
||||
for (list<string>::iterator iter = begin; iter != end; iter++)
|
||||
stream << *iter;
|
||||
result = stream.str();
|
||||
}
|
||||
|
||||
// Finds an element with a matching ID or sid (depending on the 'finder' function)
|
||||
// passed in. First it tries to resolve the whole ID/sid, then it tries to resolve
|
||||
// successively smaller parts. For example, consider this sid ref: "my.sid.ref".
|
||||
// First this function will try to resolve "my.sid.ref" entirely, then if that
|
||||
// fails it'll try to resolve "my.sid.", "my.sid", "my.", and "my", in that order.
|
||||
// The part that wasn't matched is returned in the 'remainingPart' parameter.
|
||||
daeElement* findWithDots(daeElement* container,
|
||||
const string& s,
|
||||
const string& profile,
|
||||
daeElement* (*finder)(daeElement*, const string&, const string&),
|
||||
list<string>& remainingPart) {
|
||||
remainingPart.clear();
|
||||
|
||||
// First see if the whole thing resolves correctly
|
||||
if (daeElement* result = finder(container, s, profile))
|
||||
return result;
|
||||
|
||||
// It didn't resolve. Let's tokenize it by '.'s and see if we can resolve a
|
||||
// portion of it.
|
||||
cdom::tokenize(s, ".", remainingPart, true);
|
||||
if (remainingPart.size() == 1)
|
||||
return NULL; // There were no '.'s, so the result won't be any different
|
||||
|
||||
list<string>::iterator iter = moveIter(remainingPart.end(), -1);
|
||||
for (int i = int(remainingPart.size())-1; i >= 1; i--, iter--) {
|
||||
string substr;
|
||||
buildString(remainingPart.begin(), iter, substr);
|
||||
if (daeElement* result = finder(container, substr, profile)) {
|
||||
// Remove the part we matched against from the list
|
||||
remainingPart.erase(remainingPart.begin(), iter);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
remainingPart.clear();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeSidRef::resolveData resolveImpl(const daeSidRef& sidRef) {
|
||||
if (sidRef.sidRef.empty() || !sidRef.refElt)
|
||||
return daeSidRef::resolveData();
|
||||
|
||||
daeSidRef::resolveData result;
|
||||
string separators = "/()";
|
||||
list<string> tokens;
|
||||
cdom::tokenize(sidRef.sidRef, separators, /* out */ tokens, true);
|
||||
|
||||
list<string>::iterator tok = tokens.begin();
|
||||
|
||||
// The first token should be either an ID or a '.' to indicate
|
||||
// that we should start the search from the container element.
|
||||
if (tok == tokens.end())
|
||||
return daeSidRef::resolveData();
|
||||
|
||||
list<string> remainingPart;
|
||||
if (*tok == ".") {
|
||||
result.elt = sidRef.refElt;
|
||||
tok++;
|
||||
} else {
|
||||
// Try to resolve it as an ID
|
||||
result.elt = findWithDots(sidRef.refElt, *tok, sidRef.profile, findID, remainingPart);
|
||||
if (result.elt) {
|
||||
if (!remainingPart.empty()) {
|
||||
// Insert the "remaining part" from the ID resolve into our list of tokens
|
||||
tokens.erase(tokens.begin());
|
||||
tokens.splice(tokens.begin(), remainingPart);
|
||||
tok = tokens.begin();
|
||||
} else
|
||||
tok++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result.elt)
|
||||
return daeSidRef::resolveData();
|
||||
|
||||
// Next we have an optional list of SIDs, each one separated by "/". Once we hit one of "()",
|
||||
// we know we're done with the SID section.
|
||||
for (; tok != tokens.end() && *tok == "/"; tok++) {
|
||||
tok++; // Read the '/'
|
||||
if (tok == tokens.end())
|
||||
return daeSidRef::resolveData();
|
||||
|
||||
// Find the element matching the SID
|
||||
result.elt = findWithDots(result.elt, *tok, sidRef.profile, findSidTopDown, remainingPart);
|
||||
if (!result.elt)
|
||||
return daeSidRef::resolveData();
|
||||
|
||||
if (!remainingPart.empty()) {
|
||||
list<string>::iterator tmp = tok;
|
||||
tok--;
|
||||
tokens.splice(tmp, remainingPart);
|
||||
tokens.erase(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
// Now we want to parse the member selection tokens. It can either be
|
||||
// (a) '.' followed by a string representing the member to access
|
||||
// (b) '(x)' where x is a number, optionally followed by another '(x)'
|
||||
// Anything else is an error.
|
||||
string member;
|
||||
bool haveArrayIndex1 = false, haveArrayIndex2 = false;
|
||||
int arrayIndex1 = -1, arrayIndex2 = -1;
|
||||
if (tok != tokens.end()) {
|
||||
if (*tok == ".") {
|
||||
tok++;
|
||||
if (tok == tokens.end())
|
||||
return daeSidRef::resolveData();
|
||||
member = *tok;
|
||||
tok++;
|
||||
}
|
||||
else if (*tok == "(") {
|
||||
tok++;
|
||||
if (tok == tokens.end())
|
||||
return daeSidRef::resolveData();
|
||||
|
||||
istringstream stream(*tok);
|
||||
stream >> arrayIndex1;
|
||||
haveArrayIndex1 = true;
|
||||
if (!stream.good() && !stream.eof())
|
||||
return daeSidRef::resolveData();
|
||||
tok++;
|
||||
if (tok == tokens.end() || *tok != ")")
|
||||
return daeSidRef::resolveData();
|
||||
tok++;
|
||||
|
||||
if (tok != tokens.end() && *tok == "(") {
|
||||
tok++;
|
||||
if (tok == tokens.end())
|
||||
return daeSidRef::resolveData();
|
||||
|
||||
stream.clear();
|
||||
stream.str(*tok);
|
||||
stream >> arrayIndex2;
|
||||
haveArrayIndex2 = true;
|
||||
if (!stream.good() && !stream.eof())
|
||||
return daeSidRef::resolveData();
|
||||
tok++;
|
||||
if (tok == tokens.end() || *tok != ")")
|
||||
return daeSidRef::resolveData();
|
||||
tok++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We shouldn't have any tokens left. If we do it's an error.
|
||||
if (tok != tokens.end())
|
||||
return daeSidRef::resolveData();
|
||||
|
||||
// At this point we've parsed a correctly formatted SID reference. The only thing left is to resolve
|
||||
// the member selection portion of the SID ref. First, see if the resolved element has a float array we
|
||||
// can use.
|
||||
if (result.elt->typeID() == domSource::ID()) {
|
||||
if (domFloat_array* floatArray = ((domSource*)result.elt)->getFloat_array())
|
||||
result.array = (daeDoubleArray*)floatArray->getCharDataObject()->get(floatArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
daeMetaAttribute *ma = result.elt->getCharDataObject();
|
||||
if ( ma != NULL ) {
|
||||
if ( ma->isArrayAttribute() && ma->getType()->getTypeEnum() == daeAtomicType::DoubleType ) {
|
||||
result.array = (daeDoubleArray*)ma->get( result.elt );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( result.array ) {
|
||||
// We have an array to use for indexing. Let's see if the SID ref uses member selection.
|
||||
if (!member.empty()) {
|
||||
// Do member lookup based on the constants defined in the COMMON profile
|
||||
if (member == "ANGLE") {
|
||||
result.scalar = &(result.array->get(3));
|
||||
} else if (member.length() == 1) {
|
||||
switch(member[0]) {
|
||||
case 'X':
|
||||
case 'R':
|
||||
case 'U':
|
||||
case 'S':
|
||||
result.scalar = &(result.array->get(0));
|
||||
break;
|
||||
case 'Y':
|
||||
case 'G':
|
||||
case 'V':
|
||||
case 'T':
|
||||
result.scalar = &(result.array->get(1));
|
||||
break;
|
||||
case 'Z':
|
||||
case 'B':
|
||||
case 'P':
|
||||
result.scalar = &(result.array->get(2));
|
||||
break;
|
||||
case 'W':
|
||||
case 'A':
|
||||
case 'Q':
|
||||
result.scalar = &(result.array->get(3));
|
||||
break;
|
||||
};
|
||||
}
|
||||
} else if (haveArrayIndex1) {
|
||||
// Use the indices to lookup a value in the array
|
||||
if (haveArrayIndex2 && result.array->getCount() == 16) {
|
||||
// We're doing a matrix lookup. Make sure the index is valid.
|
||||
int i = arrayIndex1*4 + arrayIndex2;
|
||||
if (i >= 0 && i < int(result.array->getCount()))
|
||||
result.scalar = &(result.array->get(i));
|
||||
} else {
|
||||
// Vector lookup. Make sure the index is valid.
|
||||
if (arrayIndex1 >= 0 && arrayIndex1 < int(result.array->getCount()))
|
||||
result.scalar = &(result.array->get(arrayIndex1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we tried to do member selection but we couldn't resolve it to a doublePtr, fail.
|
||||
if ((!member.empty() || haveArrayIndex1) && result.scalar == NULL)
|
||||
return daeSidRef::resolveData();
|
||||
|
||||
// SID resolution was successful.
|
||||
return result;
|
||||
}
|
||||
} // namespace {
|
||||
|
||||
|
||||
daeSidRef::resolveData::resolveData() : elt(NULL), array(NULL), scalar(NULL) { }
|
||||
|
||||
daeSidRef::resolveData::resolveData(daeElement* elt, daeDoubleArray* array, daeDouble* scalar)
|
||||
: elt(elt),
|
||||
array(array),
|
||||
scalar(scalar) { }
|
||||
|
||||
|
||||
daeSidRef::daeSidRef() : refElt(NULL) { }
|
||||
|
||||
daeSidRef::daeSidRef(const string& sidRef, daeElement* referenceElt, const string& profile)
|
||||
: sidRef(sidRef),
|
||||
refElt(referenceElt),
|
||||
profile(profile) { }
|
||||
|
||||
bool daeSidRef::operator<(const daeSidRef& other) const {
|
||||
if (refElt != other.refElt)
|
||||
return refElt < other.refElt;
|
||||
if (sidRef != other.sidRef)
|
||||
return sidRef < other.sidRef;
|
||||
return profile < other.profile;
|
||||
}
|
||||
|
||||
daeSidRef::resolveData daeSidRef::resolve() {
|
||||
if (!refElt)
|
||||
return daeSidRef::resolveData();
|
||||
|
||||
// First check the cache
|
||||
daeSidRef::resolveData result = refElt->getDAE()->getSidRefCache().lookup(*this);
|
||||
if (result.elt)
|
||||
return result;
|
||||
|
||||
// Try to resolve as an effect-style sid ref by prepending "./" to the sid ref.
|
||||
// If that fails, try resolving as an animation-style sid ref, where the first part is an ID.
|
||||
result = resolveImpl(daeSidRef(string("./") + sidRef, refElt, profile));
|
||||
if (!result.elt)
|
||||
result = resolveImpl(*this);
|
||||
|
||||
if (result.elt) // Add the result to the cache
|
||||
refElt->getDAE()->getSidRefCache().add(*this, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
daeSIDResolver::daeSIDResolver( daeElement *container, daeString target, daeString profile )
|
||||
: container(NULL)
|
||||
{
|
||||
setContainer(container);
|
||||
setTarget(target);
|
||||
setProfile(profile);
|
||||
}
|
||||
|
||||
daeString daeSIDResolver::getTarget() const {
|
||||
return target.empty() ? NULL : target.c_str();
|
||||
}
|
||||
|
||||
void daeSIDResolver::setTarget( daeString t )
|
||||
{
|
||||
target = t ? t : "";
|
||||
}
|
||||
|
||||
daeString daeSIDResolver::getProfile() const {
|
||||
return profile.empty() ? NULL : profile.c_str();
|
||||
}
|
||||
|
||||
void daeSIDResolver::setProfile( daeString p )
|
||||
{
|
||||
profile = p ? p : "";
|
||||
}
|
||||
|
||||
daeElement* daeSIDResolver::getContainer() const {
|
||||
return container;
|
||||
}
|
||||
|
||||
void daeSIDResolver::setContainer(daeElement* element)
|
||||
{
|
||||
container = element;
|
||||
}
|
||||
|
||||
daeSIDResolver::ResolveState daeSIDResolver::getState() const {
|
||||
if (target.empty())
|
||||
return target_empty;
|
||||
|
||||
daeSidRef::resolveData result = daeSidRef(target, container, profile).resolve();
|
||||
if (!result.elt)
|
||||
return sid_failed_not_found;
|
||||
if (result.scalar)
|
||||
return sid_success_double;
|
||||
if (result.array)
|
||||
return sid_success_array;
|
||||
|
||||
return sid_success_element;
|
||||
}
|
||||
|
||||
daeElement* daeSIDResolver::getElement()
|
||||
{
|
||||
return daeSidRef(target, container, profile).resolve().elt;
|
||||
}
|
||||
|
||||
daeDoubleArray *daeSIDResolver::getDoubleArray()
|
||||
{
|
||||
return daeSidRef(target, container, profile).resolve().array;
|
||||
}
|
||||
|
||||
daeDouble *daeSIDResolver::getDouble()
|
||||
{
|
||||
return daeSidRef(target, container, profile).resolve().scalar;
|
||||
}
|
||||
|
||||
|
||||
daeSidRefCache::daeSidRefCache() : hitCount(0), missCount(0) { }
|
||||
|
||||
daeSidRef::resolveData daeSidRefCache::lookup(const daeSidRef& sidRef) {
|
||||
map<daeSidRef, daeSidRef::resolveData>::iterator iter = lookupTable.find(sidRef);
|
||||
if (iter != lookupTable.end()) {
|
||||
hitCount++;
|
||||
return iter->second;
|
||||
}
|
||||
missCount++;
|
||||
return daeSidRef::resolveData();
|
||||
}
|
||||
|
||||
void daeSidRefCache::add(const daeSidRef& sidRef, const daeSidRef::resolveData& result) {
|
||||
lookupTable[sidRef] = result;
|
||||
}
|
||||
|
||||
void daeSidRefCache::clear() {
|
||||
lookupTable.clear();
|
||||
hitCount = missCount = 0;
|
||||
}
|
||||
|
||||
bool daeSidRefCache::empty() {
|
||||
return lookupTable.empty();
|
||||
}
|
||||
|
||||
int daeSidRefCache::misses() {
|
||||
return missCount;
|
||||
}
|
||||
|
||||
int daeSidRefCache::hits() {
|
||||
return hitCount;
|
||||
}
|
||||
59
Engine/lib/collada/src/dae/daeStandardURIResolver.cpp
Normal file
59
Engine/lib/collada/src/dae/daeStandardURIResolver.cpp
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
#include <dae.h>
|
||||
#include <dae/daeStandardURIResolver.h>
|
||||
#include <dae/daeDatabase.h>
|
||||
#include <dae/daeURI.h>
|
||||
#include <dae/daeIOPlugin.h>
|
||||
#include <dae/daeErrorHandler.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
daeStandardURIResolver::daeStandardURIResolver(DAE& dae)
|
||||
: daeURIResolver(dae) { }
|
||||
|
||||
daeStandardURIResolver::~daeStandardURIResolver() { }
|
||||
|
||||
daeString
|
||||
daeStandardURIResolver::getName()
|
||||
{
|
||||
return "XMLResolver";
|
||||
}
|
||||
|
||||
namespace {
|
||||
void printErrorMsg(const daeURI& uri) {
|
||||
ostringstream msg;
|
||||
msg << "daeStandardURIResolver::resolveElement() - Failed to resolve " << uri.str() << endl;
|
||||
daeErrorHandler::get()->handleError(msg.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
daeElement* daeStandardURIResolver::resolveElement(const daeURI& uri) {
|
||||
daeDocument* doc = uri.getReferencedDocument();
|
||||
if (!doc) {
|
||||
dae->open(uri.str());
|
||||
doc = uri.getReferencedDocument();
|
||||
if (!doc) {
|
||||
printErrorMsg(uri);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
daeElement* elt = dae->getDatabase()->idLookup(uri.id(), doc);
|
||||
if (!elt)
|
||||
printErrorMsg(uri);
|
||||
|
||||
return elt;
|
||||
}
|
||||
58
Engine/lib/collada/src/dae/daeStringRef.cpp
Normal file
58
Engine/lib/collada/src/dae/daeStringRef.cpp
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <dae/daeStringRef.h>
|
||||
|
||||
//Contributed by Nus - Wed, 08 Nov 2006
|
||||
// Nus: Use global pointer instead of local static.
|
||||
static daeStringTable *pST = NULL;
|
||||
//---------------------------
|
||||
|
||||
daeStringTable &daeStringRef::_stringTable()
|
||||
{
|
||||
//Contributed by Nus - Wed, 08 Nov 2006
|
||||
// static daeStringTable *st = new daeStringTable();
|
||||
// return *st;
|
||||
if(!pST)
|
||||
pST = new daeStringTable();
|
||||
return *pST;
|
||||
}
|
||||
|
||||
void daeStringRef::releaseStringTable(void)
|
||||
{
|
||||
if(pST) {
|
||||
delete pST;
|
||||
pST = NULL;
|
||||
}
|
||||
}
|
||||
//--------------------------------
|
||||
|
||||
daeStringRef::daeStringRef(daeString string)
|
||||
{
|
||||
daeStringTable &st = _stringTable();
|
||||
_string = st.allocString(string);
|
||||
}
|
||||
|
||||
const daeStringRef&
|
||||
daeStringRef::set(daeString string)
|
||||
{
|
||||
daeStringTable &st = _stringTable();
|
||||
_string = st.allocString(string);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const daeStringRef&
|
||||
daeStringRef::operator= (daeString string)
|
||||
{
|
||||
return set(string);
|
||||
}
|
||||
69
Engine/lib/collada/src/dae/daeStringTable.cpp
Normal file
69
Engine/lib/collada/src/dae/daeStringTable.cpp
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <dae/daeStringTable.h>
|
||||
|
||||
daeStringTable::daeStringTable(int stringBufferSize):_stringBufferSize(stringBufferSize), _empty( "" )
|
||||
{
|
||||
_stringBufferIndex = _stringBufferSize;
|
||||
//allocate initial buffer
|
||||
//allocateBuffer();
|
||||
}
|
||||
|
||||
daeString daeStringTable::allocateBuffer()
|
||||
{
|
||||
daeString buf = new daeChar[_stringBufferSize];
|
||||
_stringBuffersList.append(buf);
|
||||
_stringBufferIndex = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
daeString daeStringTable::allocString(daeString string)
|
||||
{
|
||||
if ( string == NULL ) return _empty;
|
||||
size_t stringSize = strlen(string) + 1;
|
||||
size_t sizeLeft = _stringBufferSize - _stringBufferIndex;
|
||||
daeString buf;
|
||||
if (sizeLeft < stringSize)
|
||||
{
|
||||
if (stringSize > _stringBufferSize)
|
||||
_stringBufferSize = ((stringSize / _stringBufferSize) + 1) * _stringBufferSize ;
|
||||
buf = allocateBuffer();
|
||||
}
|
||||
else
|
||||
{
|
||||
buf = _stringBuffersList.get((daeInt)_stringBuffersList.getCount()-1);
|
||||
}
|
||||
daeChar *str = (char*)buf + _stringBufferIndex;
|
||||
memcpy(str,string,stringSize);
|
||||
_stringBufferIndex += stringSize;
|
||||
|
||||
int align = sizeof(void*);
|
||||
_stringBufferIndex = (_stringBufferIndex+(align-1)) & (~(align-1));
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
void daeStringTable::clear()
|
||||
{
|
||||
unsigned int i;
|
||||
for (i=0;i<_stringBuffersList.getCount();i++)
|
||||
#if _MSC_VER <= 1200
|
||||
delete [] (char *) _stringBuffersList[i];
|
||||
#else
|
||||
delete [] _stringBuffersList[i];
|
||||
#endif
|
||||
|
||||
_stringBuffersList.clear();
|
||||
_stringBufferIndex = _stringBufferSize;
|
||||
}
|
||||
230
Engine/lib/collada/src/dae/daeTinyXMLPlugin.cpp
Normal file
230
Engine/lib/collada/src/dae/daeTinyXMLPlugin.cpp
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
* Copyright 2007 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
// The user can choose whether or not to include TinyXML support in the DOM. Supporting TinyXML will
|
||||
// require linking against it. By default TinyXML support isn't included.
|
||||
#if defined(DOM_INCLUDE_TINYXML)
|
||||
|
||||
#if defined(DOM_DYNAMIC) && defined(_MSC_VER)
|
||||
#pragma comment(lib, "tinyxml.lib")
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable: 4100) // warning C4100: 'element' : unreferenced formal parameter
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <tinyxml.h>
|
||||
#include <dae.h>
|
||||
#include <dom.h>
|
||||
#include <dae/daeMetaElement.h>
|
||||
#include <dae/daeErrorHandler.h>
|
||||
#include <dae/daeMetaElementAttribute.h>
|
||||
#include <dae/daeTinyXMLPlugin.h>
|
||||
#include <dae/daeDocument.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace {
|
||||
daeInt getCurrentLineNumber(TiXmlElement* element) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
daeTinyXMLPlugin::daeTinyXMLPlugin()
|
||||
{
|
||||
m_doc = NULL;
|
||||
supportedProtocols.push_back("*");
|
||||
}
|
||||
|
||||
daeTinyXMLPlugin::~daeTinyXMLPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
daeInt daeTinyXMLPlugin::setOption( daeString option, daeString value )
|
||||
{
|
||||
return DAE_ERR_INVALID_CALL;
|
||||
}
|
||||
|
||||
daeString daeTinyXMLPlugin::getOption( daeString option )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeElementRef daeTinyXMLPlugin::readFromFile(const daeURI& uri) {
|
||||
string file = cdom::uriToNativePath(uri.str());
|
||||
if (file.empty())
|
||||
return NULL;
|
||||
TiXmlDocument doc;
|
||||
doc.LoadFile(file.c_str());
|
||||
if (!doc.RootElement()) {
|
||||
daeErrorHandler::get()->handleError((std::string("Failed to open ") + uri.str() +
|
||||
" in daeTinyXMLPlugin::readFromFile\n").c_str());
|
||||
return NULL;
|
||||
}
|
||||
return readElement(doc.RootElement(), NULL);
|
||||
}
|
||||
|
||||
daeElementRef daeTinyXMLPlugin::readFromMemory(daeString buffer, const daeURI& baseUri) {
|
||||
TiXmlDocument doc;
|
||||
doc.Parse(buffer);
|
||||
if (!doc.RootElement()) {
|
||||
daeErrorHandler::get()->handleError("Failed to open XML document from memory buffer in "
|
||||
"daeTinyXMLPlugin::readFromMemory\n");
|
||||
return NULL;
|
||||
}
|
||||
return readElement(doc.RootElement(), NULL);
|
||||
}
|
||||
|
||||
daeElementRef daeTinyXMLPlugin::readElement(TiXmlElement* tinyXmlElement, daeElement* parentElement) {
|
||||
std::vector<attrPair> attributes;
|
||||
for (TiXmlAttribute* attrib = tinyXmlElement->FirstAttribute(); attrib != NULL; attrib = attrib->Next())
|
||||
attributes.push_back(attrPair(attrib->Name(), attrib->Value()));
|
||||
|
||||
daeElementRef element = beginReadElement(parentElement, tinyXmlElement->Value(),
|
||||
attributes, getCurrentLineNumber(tinyXmlElement));
|
||||
if (!element) {
|
||||
// We couldn't create the element. beginReadElement already printed an error message.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (tinyXmlElement->GetText() != NULL)
|
||||
readElementText(element, tinyXmlElement->GetText(), getCurrentLineNumber(tinyXmlElement));
|
||||
|
||||
// Recurse children
|
||||
for (TiXmlElement* child = tinyXmlElement->FirstChildElement(); child != NULL; child = child->NextSiblingElement())
|
||||
element->placeElement(readElement(child, element));
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
daeInt daeTinyXMLPlugin::write(const daeURI& name, daeDocument *document, daeBool replace)
|
||||
{
|
||||
// Make sure database and document are both set
|
||||
if (!database)
|
||||
return DAE_ERR_INVALID_CALL;
|
||||
if(!document)
|
||||
return DAE_ERR_COLLECTION_DOES_NOT_EXIST;
|
||||
|
||||
string fileName = cdom::uriToNativePath(name.str());
|
||||
if (fileName.empty())
|
||||
{
|
||||
daeErrorHandler::get()->handleError( "can't get path in write\n" );
|
||||
return DAE_ERR_BACKEND_IO;
|
||||
}
|
||||
// If replace=false, don't replace existing files
|
||||
if(!replace)
|
||||
{
|
||||
// Using "stat" would be better, but it's not available on all platforms
|
||||
FILE *tempfd = fopen(fileName.c_str(), "r");
|
||||
if(tempfd != NULL)
|
||||
{
|
||||
// File exists, return error
|
||||
fclose(tempfd);
|
||||
return DAE_ERR_BACKEND_FILE_EXISTS;
|
||||
}
|
||||
fclose(tempfd);
|
||||
}
|
||||
|
||||
m_doc = new TiXmlDocument(name.getURI());
|
||||
if (m_doc)
|
||||
{
|
||||
m_doc->SetTabSize(4);
|
||||
|
||||
TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "", "" );
|
||||
m_doc->LinkEndChild( decl );
|
||||
|
||||
writeElement(document->getDomRoot());
|
||||
|
||||
m_doc->SaveFile(fileName.c_str());
|
||||
delete m_doc;
|
||||
m_doc = NULL;
|
||||
}
|
||||
return DAE_OK;
|
||||
}
|
||||
|
||||
void daeTinyXMLPlugin::writeElement( daeElement* element )
|
||||
{
|
||||
daeMetaElement* _meta = element->getMeta();
|
||||
if (!_meta->getIsTransparent() )
|
||||
{
|
||||
TiXmlElement* tiElm = new TiXmlElement( element->getElementName() );
|
||||
|
||||
if (m_elements.empty() == true) {
|
||||
m_doc->LinkEndChild(tiElm);
|
||||
} else {
|
||||
TiXmlElement* first = m_elements.front();
|
||||
first->LinkEndChild(tiElm);
|
||||
}
|
||||
m_elements.push_front(tiElm);
|
||||
|
||||
daeMetaAttributeRefArray& attrs = _meta->getMetaAttributes();
|
||||
|
||||
int acnt = (int)attrs.getCount();
|
||||
|
||||
for(int i=0;i<acnt;i++)
|
||||
{
|
||||
writeAttribute( attrs[i], element );
|
||||
}
|
||||
}
|
||||
writeValue(element);
|
||||
|
||||
daeElementRefArray children;
|
||||
element->getChildren( children );
|
||||
for ( size_t x = 0; x < children.getCount(); x++ )
|
||||
{
|
||||
writeElement( children.get(x) );
|
||||
}
|
||||
|
||||
if (!_meta->getIsTransparent() )
|
||||
{
|
||||
m_elements.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void daeTinyXMLPlugin::writeValue( daeElement* element )
|
||||
{
|
||||
if (daeMetaAttribute* attr = element->getMeta()->getValueAttribute()) {
|
||||
std::ostringstream buffer;
|
||||
attr->memoryToString(element, buffer);
|
||||
std::string s = buffer.str();
|
||||
if (!s.empty())
|
||||
m_elements.front()->LinkEndChild( new TiXmlText(buffer.str().c_str()) );
|
||||
}
|
||||
}
|
||||
|
||||
void daeTinyXMLPlugin::writeAttribute( daeMetaAttribute* attr, daeElement* element )
|
||||
{
|
||||
//don't write if !required and is set && is default
|
||||
if ( !attr->getIsRequired() ) {
|
||||
//not required
|
||||
if ( !element->isAttributeSet( attr->getName() ) ) {
|
||||
//early out if !value && !required && !set
|
||||
return;
|
||||
}
|
||||
|
||||
//is set
|
||||
//check for default suppression
|
||||
if (attr->compareToDefault(element) == 0) {
|
||||
// We match the default value, so exit early
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::ostringstream buffer;
|
||||
attr->memoryToString(element, buffer);
|
||||
m_elements.front()->SetAttribute(attr->getName(), buffer.str().c_str());
|
||||
}
|
||||
|
||||
#endif // DOM_INCLUDE_TINYXML
|
||||
825
Engine/lib/collada/src/dae/daeURI.cpp
Normal file
825
Engine/lib/collada/src/dae/daeURI.cpp
Normal file
|
|
@ -0,0 +1,825 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <dae.h>
|
||||
#include <dae/daeURI.h>
|
||||
#include <ctype.h>
|
||||
#include <dae/daeDocument.h>
|
||||
#include <dae/daeErrorHandler.h>
|
||||
#include <dae/daeUtils.h>
|
||||
#include <pcrecpp.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace cdom;
|
||||
|
||||
void daeURI::initialize() {
|
||||
reset();
|
||||
container = NULL;
|
||||
}
|
||||
|
||||
daeURI::~daeURI() { }
|
||||
|
||||
daeURI::daeURI(DAE& dae) : dae(&dae) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
daeURI::daeURI(DAE& dae, const string& uriStr, daeBool nofrag) : dae(&dae) {
|
||||
initialize();
|
||||
|
||||
if (nofrag) {
|
||||
size_t pos = uriStr.find_last_of('#');
|
||||
if (pos != string::npos) {
|
||||
set(uriStr.substr(0, pos));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
set(uriStr);
|
||||
}
|
||||
|
||||
daeURI::daeURI(const daeURI& baseURI, const string& uriStr) : dae(baseURI.getDAE())
|
||||
{
|
||||
initialize();
|
||||
set(uriStr, &baseURI);
|
||||
}
|
||||
|
||||
daeURI::daeURI(const daeURI& copyFrom_) : dae(copyFrom_.getDAE()), container(NULL)
|
||||
{
|
||||
initialize();
|
||||
copyFrom(copyFrom_);
|
||||
}
|
||||
|
||||
daeURI::daeURI(daeElement& container_, const std::string& uriStr)
|
||||
: dae(container_.getDAE())
|
||||
{
|
||||
initialize();
|
||||
container = &container_;
|
||||
set(uriStr);
|
||||
}
|
||||
|
||||
daeURI::daeURI(DAE& dae, daeElement& container_, const string& uriStr)
|
||||
: dae(&dae)
|
||||
{
|
||||
initialize();
|
||||
container = &container_;
|
||||
set(uriStr);
|
||||
}
|
||||
|
||||
void
|
||||
daeURI::copyFrom(const daeURI& copyFrom)
|
||||
{
|
||||
if (!container)
|
||||
container = copyFrom.container;
|
||||
set(copyFrom.originalStr());
|
||||
}
|
||||
|
||||
daeURI& daeURI::operator=(const daeURI& other) {
|
||||
copyFrom(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
daeURI& daeURI::operator=(const string& uriStr) {
|
||||
set(uriStr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void daeURI::reset() {
|
||||
// Clear everything except the container, which doesn't change for the lifetime of the daeURI
|
||||
uriString = "";
|
||||
originalURIString = "";
|
||||
_scheme = "";
|
||||
_authority = "";
|
||||
_path = "";
|
||||
_query = "";
|
||||
_fragment = "";
|
||||
}
|
||||
|
||||
DAE* daeURI::getDAE() const {
|
||||
return dae;
|
||||
}
|
||||
|
||||
|
||||
const string& daeURI::str() const {
|
||||
return uriString;
|
||||
}
|
||||
|
||||
const string& daeURI::originalStr() const {
|
||||
return originalURIString;
|
||||
}
|
||||
|
||||
daeString daeURI::getURI() const {
|
||||
return str().c_str();
|
||||
}
|
||||
|
||||
daeString daeURI::getOriginalURI() const {
|
||||
return originalStr().c_str();
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
void parsePath(const string& path,
|
||||
/* out */ string& dir,
|
||||
/* out */ string& baseName,
|
||||
/* out */ string& extension) {
|
||||
// !!!steveT Currently, if we have a file name that begins with a '.', as in
|
||||
// ".emacs", that will be treated as having no base name with an extension
|
||||
// of ".emacs". We might want to change this behavior, so that the base name
|
||||
// is considered ".emacs" and the extension is empty. I think this is more
|
||||
// in line with what path parsers in other libraries/languages do, and it
|
||||
// more accurately reflects the intended structure of the file name.
|
||||
static pcrecpp::RE re("(.*/)?([^.]*)?(\\..*)?");
|
||||
dir = baseName = extension = "";
|
||||
re.FullMatch(path, &dir, &baseName, &extension);
|
||||
}
|
||||
}
|
||||
|
||||
void daeURI::set(const string& uriStr_, const daeURI* baseURI) {
|
||||
// We make a copy of the uriStr so that set(originalURIString, ...) works properly.
|
||||
string uriStr = uriStr_;
|
||||
reset();
|
||||
originalURIString = uriStr;
|
||||
|
||||
if (!parseUriRef(uriStr, _scheme, _authority, _path, _query, _fragment)) {
|
||||
reset();
|
||||
return;
|
||||
}
|
||||
|
||||
validate(baseURI);
|
||||
}
|
||||
|
||||
void daeURI::set(const string& scheme_,
|
||||
const string& authority_,
|
||||
const string& path_,
|
||||
const string& query_,
|
||||
const string& fragment_,
|
||||
const daeURI* baseURI)
|
||||
{
|
||||
set(assembleUri(scheme_, authority_, path_, query_, fragment_), baseURI);
|
||||
}
|
||||
|
||||
void daeURI::setURI(daeString _URIString, const daeURI* baseURI) {
|
||||
string uriStr = _URIString ? _URIString : "";
|
||||
set(uriStr, baseURI);
|
||||
}
|
||||
|
||||
|
||||
const string& daeURI::scheme() const { return _scheme; }
|
||||
const string& daeURI::authority() const { return _authority; }
|
||||
const string& daeURI::path() const { return _path; }
|
||||
const string& daeURI::query() const { return _query; }
|
||||
const string& daeURI::fragment() const { return _fragment; }
|
||||
const string& daeURI::id() const { return fragment(); }
|
||||
|
||||
|
||||
namespace {
|
||||
string addSlashToEnd(const string& s) {
|
||||
return (!s.empty() && s[s.length()-1] != '/') ? s + '/' : s;
|
||||
}
|
||||
}
|
||||
|
||||
void daeURI::pathComponents(string& dir, string& baseName, string& ext) const {
|
||||
parsePath(_path, dir, baseName, ext);
|
||||
}
|
||||
|
||||
string daeURI::pathDir() const {
|
||||
string dir, base, ext;
|
||||
parsePath(_path, dir, base, ext);
|
||||
return dir;
|
||||
}
|
||||
|
||||
string daeURI::pathFileBase() const {
|
||||
string dir, base, ext;
|
||||
parsePath(_path, dir, base, ext);
|
||||
return base;
|
||||
}
|
||||
|
||||
string daeURI::pathExt() const {
|
||||
string dir, base, ext;
|
||||
parsePath(_path, dir, base, ext);
|
||||
return ext;
|
||||
}
|
||||
|
||||
string daeURI::pathFile() const {
|
||||
string dir, base, ext;
|
||||
parsePath(_path, dir, base, ext);
|
||||
return base + ext;
|
||||
}
|
||||
|
||||
void daeURI::path(const string& dir, const string& baseName, const string& ext) {
|
||||
path(addSlashToEnd(dir) + baseName + ext);
|
||||
}
|
||||
|
||||
void daeURI::pathDir(const string& dir) {
|
||||
string tmp, base, ext;
|
||||
parsePath(_path, tmp, base, ext);
|
||||
path(addSlashToEnd(dir), base, ext);
|
||||
}
|
||||
|
||||
void daeURI::pathFileBase(const string& baseName) {
|
||||
string dir, tmp, ext;
|
||||
parsePath(_path, dir, tmp, ext);
|
||||
path(dir, baseName, ext);
|
||||
}
|
||||
|
||||
void daeURI::pathExt(const string& ext) {
|
||||
string dir, base, tmp;
|
||||
parsePath(_path, dir, base, tmp);
|
||||
path(dir, base, ext);
|
||||
}
|
||||
|
||||
void daeURI::pathFile(const string& file) {
|
||||
string dir, base, ext;
|
||||
parsePath(_path, dir, base, ext);
|
||||
path(dir, file, "");
|
||||
}
|
||||
|
||||
|
||||
daeString daeURI::getScheme() const { return _scheme.c_str(); }
|
||||
daeString daeURI::getProtocol() const { return getScheme(); }
|
||||
daeString daeURI::getAuthority() const { return _authority.c_str(); }
|
||||
daeString daeURI::getPath() const { return _path.c_str(); }
|
||||
daeString daeURI::getQuery() const { return _query.c_str(); }
|
||||
daeString daeURI::getFragment() const { return _fragment.c_str(); }
|
||||
daeString daeURI::getID() const { return getFragment(); }
|
||||
daeBool daeURI::getPath(daeChar *dest, daeInt size) const {
|
||||
if (int(_path.length()) < size) {
|
||||
strcpy(dest, _path.c_str());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void daeURI::scheme(const string& scheme_) { set(scheme_, _authority, _path, _query, _fragment); };
|
||||
void daeURI::authority(const string& authority_) { set(_scheme, authority_, _path, _query, _fragment); }
|
||||
void daeURI::path(const string& path_) { set(_scheme, _authority, path_, _query, _fragment); }
|
||||
void daeURI::query(const string& query_) { set(_scheme, _authority, _path, query_, _fragment); }
|
||||
void daeURI::fragment(const string& fragment_) { set(_scheme, _authority, _path, _query, fragment_); }
|
||||
void daeURI::id(const string& id) { fragment(id); }
|
||||
|
||||
void
|
||||
daeURI::print()
|
||||
{
|
||||
fprintf(stderr,"URI(%s)\n",uriString.c_str());
|
||||
fprintf(stderr,"scheme = %s\n",_scheme.c_str());
|
||||
fprintf(stderr,"authority = %s\n",_authority.c_str());
|
||||
fprintf(stderr,"path = %s\n",_path.c_str());
|
||||
fprintf(stderr,"query = %s\n",_query.c_str());
|
||||
fprintf(stderr,"fragment = %s\n",_fragment.c_str());
|
||||
fprintf(stderr,"URI without base = %s\n",originalURIString.c_str());
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
namespace {
|
||||
void normalize(string& path) {
|
||||
daeURI::normalizeURIPath(const_cast<char*>(path.c_str()));
|
||||
path = path.substr(0, strlen(path.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
daeURI::validate(const daeURI* baseURI)
|
||||
{
|
||||
// If no base URI was supplied, use the container's document URI. If there's
|
||||
// no container or the container doesn't have a doc URI, use the application
|
||||
// base URI.
|
||||
if (!baseURI) {
|
||||
if (!container || !(baseURI = container->getDocumentURI()))
|
||||
baseURI = &dae->getBaseURI();
|
||||
if (this == baseURI)
|
||||
return;
|
||||
}
|
||||
|
||||
// This is rewritten according to the updated rfc 3986
|
||||
if (!_scheme.empty()) // if defined(R.scheme) then
|
||||
{
|
||||
// Everything stays the same except path which we normalize
|
||||
// T.scheme = R.scheme;
|
||||
// T.authority = R.authority;
|
||||
// T.path = remove_dot_segments(R.path);
|
||||
// T.query = R.query;
|
||||
normalize(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_authority.empty()) // if defined(R.authority) then
|
||||
{
|
||||
// Authority and query stay the same, path is normalized
|
||||
// T.authority = R.authority;
|
||||
// T.path = remove_dot_segments(R.path);
|
||||
// T.query = R.query;
|
||||
normalize(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_path.empty()) // if (R.path == "") then
|
||||
{
|
||||
// T.path = Base.path;
|
||||
_path = baseURI->_path;
|
||||
|
||||
//if defined(R.query) then
|
||||
// T.query = R.query;
|
||||
//else
|
||||
// T.query = Base.query;
|
||||
//endif;
|
||||
if (_query.empty())
|
||||
_query = baseURI->_query;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_path[0] == '/') // if (R.path starts-with "/") then
|
||||
{
|
||||
// T.path = remove_dot_segments(R.path);
|
||||
normalize(_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
// T.path = merge(Base.path, R.path);
|
||||
if (!baseURI->_authority.empty() && baseURI->_path.empty()) // authority defined, path empty
|
||||
_path.insert(0, "/");
|
||||
else {
|
||||
string dir, baseName, ext;
|
||||
parsePath(baseURI->_path, dir, baseName, ext);
|
||||
_path = dir + _path;
|
||||
}
|
||||
// T.path = remove_dot_segments(T.path);
|
||||
normalize(_path);
|
||||
}
|
||||
// T.query = R.query;
|
||||
}
|
||||
// T.authority = Base.authority;
|
||||
_authority = baseURI->_authority;
|
||||
}
|
||||
// T.scheme = Base.scheme;
|
||||
_scheme = baseURI->_scheme;
|
||||
}
|
||||
// T.fragment = R.fragment;
|
||||
|
||||
// Reassemble all this into a string version of the URI
|
||||
uriString = assembleUri(_scheme, _authority, _path, _query, _fragment);
|
||||
|
||||
// Collect external references
|
||||
if (isExternalReference())
|
||||
container->getDocument()->addExternalReference( *this );
|
||||
}
|
||||
|
||||
daeElementRef daeURI::getElement() const {
|
||||
return internalResolveElement();
|
||||
}
|
||||
|
||||
daeElement* daeURI::internalResolveElement() const {
|
||||
if (uriString.empty())
|
||||
return NULL;
|
||||
|
||||
return dae->getURIResolvers().resolveElement(*this);
|
||||
}
|
||||
|
||||
void daeURI::resolveElement() { }
|
||||
|
||||
void daeURI::setContainer(daeElement* cont) {
|
||||
container = cont;
|
||||
// Since we have a new container element, the base URI may have changed. Re-resolve.
|
||||
set(originalURIString);
|
||||
}
|
||||
|
||||
daeBool daeURI::isExternalReference() const {
|
||||
if (uriString.empty())
|
||||
return false;
|
||||
|
||||
if (container && container->getDocumentURI()) {
|
||||
daeURI* docURI = container->getDocumentURI();
|
||||
if (_path != docURI->_path ||
|
||||
_scheme != docURI->_scheme ||
|
||||
_authority != docURI->_authority) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
daeDocument* daeURI::getReferencedDocument() const {
|
||||
string doc = assembleUri(_scheme, _authority, _path, "", "");
|
||||
return dae->getDatabase()->getDocument(doc.c_str(), true);
|
||||
}
|
||||
|
||||
daeURI::ResolveState daeURI::getState() const {
|
||||
return uriString.empty() ? uri_empty : uri_loaded;
|
||||
}
|
||||
|
||||
void daeURI::setState(ResolveState newState) { }
|
||||
|
||||
|
||||
// This code is loosely based on the RFC 2396 normalization code from
|
||||
// libXML. Specifically it does the RFC steps 6.c->6.g from section 5.2
|
||||
// The path is modified in place, there is no error return.
|
||||
void daeURI::normalizeURIPath(char* path)
|
||||
{
|
||||
char *cur, // location we are currently processing
|
||||
*out; // Everything from this back we are done with
|
||||
|
||||
// Return if the path pointer is null
|
||||
|
||||
if (path == NULL) return;
|
||||
|
||||
// Skip any initial / characters to get us to the start of the first segment
|
||||
|
||||
for(cur=path; *cur == '/'; cur++);
|
||||
|
||||
// Return if we hit the end of the string
|
||||
|
||||
if (*cur == 0) return;
|
||||
|
||||
// Keep everything we've seen so far.
|
||||
|
||||
out = cur;
|
||||
|
||||
// Analyze each segment in sequence for cases (c) and (d).
|
||||
|
||||
while (*cur != 0)
|
||||
{
|
||||
// (c) All occurrences of "./", where "." is a complete path segment, are removed from the buffer string.
|
||||
|
||||
if ((*cur == '.') && (*(cur+1) == '/'))
|
||||
{
|
||||
cur += 2;
|
||||
// If there were multiple slashes, skip them too
|
||||
while (*cur == '/') cur++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// (d) If the buffer string ends with "." as a complete path segment, that "." is removed.
|
||||
|
||||
if ((*cur == '.') && (*(cur+1) == 0))
|
||||
break;
|
||||
|
||||
// If we passed the above tests copy the segment to the output side
|
||||
|
||||
while (*cur != '/' && *cur != 0)
|
||||
{
|
||||
*(out++) = *(cur++);
|
||||
}
|
||||
|
||||
if(*cur != 0)
|
||||
{
|
||||
// Skip any occurrances of // at the end of the segment
|
||||
|
||||
while ((*cur == '/') && (*(cur+1) == '/')) cur++;
|
||||
|
||||
// Bring the last character in the segment (/ or a null terminator) into the output
|
||||
|
||||
*(out++) = *(cur++);
|
||||
}
|
||||
}
|
||||
|
||||
*out = 0;
|
||||
|
||||
// Restart at the beginning of the first segment for the next part
|
||||
|
||||
for(cur=path; *cur == '/'; cur++);
|
||||
if (*cur == 0) return;
|
||||
|
||||
// Analyze each segment in sequence for cases (e) and (f).
|
||||
//
|
||||
// e) All occurrences of "<segment>/../", where <segment> is a
|
||||
// complete path segment not equal to "..", are removed from the
|
||||
// buffer string. Removal of these path segments is performed
|
||||
// iteratively, removing the leftmost matching pattern on each
|
||||
// iteration, until no matching pattern remains.
|
||||
//
|
||||
// f) If the buffer string ends with "<segment>/..", where <segment>
|
||||
// is a complete path segment not equal to "..", that
|
||||
// "<segment>/.." is removed.
|
||||
//
|
||||
// To satisfy the "iterative" clause in (e), we need to collapse the
|
||||
// string every time we find something that needs to be removed. Thus,
|
||||
// we don't need to keep two pointers into the string: we only need a
|
||||
// "current position" pointer.
|
||||
//
|
||||
while (true)
|
||||
{
|
||||
char *segp, *tmp;
|
||||
|
||||
// At the beginning of each iteration of this loop, "cur" points to
|
||||
// the first character of the segment we want to examine.
|
||||
|
||||
// Find the end of the current segment.
|
||||
|
||||
for(segp = cur;(*segp != '/') && (*segp != 0); ++segp);
|
||||
|
||||
// If this is the last segment, we're done (we need at least two
|
||||
// segments to meet the criteria for the (e) and (f) cases).
|
||||
|
||||
if (*segp == 0)
|
||||
break;
|
||||
|
||||
// If the first segment is "..", or if the next segment _isn't_ "..",
|
||||
// keep this segment and try the next one.
|
||||
|
||||
++segp;
|
||||
if (((*cur == '.') && (cur[1] == '.') && (segp == cur+3))
|
||||
|| ((*segp != '.') || (segp[1] != '.')
|
||||
|| ((segp[2] != '/') && (segp[2] != 0))))
|
||||
{
|
||||
cur = segp;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we get here, remove this segment and the next one and back up
|
||||
// to the previous segment (if there is one), to implement the
|
||||
// "iteratively" clause. It's pretty much impossible to back up
|
||||
// while maintaining two pointers into the buffer, so just compact
|
||||
// the whole buffer now.
|
||||
|
||||
// If this is the end of the buffer, we're done.
|
||||
|
||||
if (segp[2] == 0)
|
||||
{
|
||||
*cur = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// Strings overlap during this copy, but not in a bad way, just avoid using strcpy
|
||||
|
||||
tmp = cur;
|
||||
segp += 3;
|
||||
while ((*(tmp++) = *(segp++)) != 0);
|
||||
|
||||
// If there are no previous segments, then keep going from here.
|
||||
|
||||
segp = cur;
|
||||
while ((segp > path) && (*(--segp) == '/'));
|
||||
|
||||
if (segp == path)
|
||||
continue;
|
||||
|
||||
// "segp" is pointing to the end of a previous segment; find it's
|
||||
// start. We need to back up to the previous segment and start
|
||||
// over with that to handle things like "foo/bar/../..". If we
|
||||
// don't do this, then on the first pass we'll remove the "bar/..",
|
||||
// but be pointing at the second ".." so we won't realize we can also
|
||||
// remove the "foo/..".
|
||||
|
||||
for(cur = segp;(cur > path) && (*(cur-1) != '/'); cur--);
|
||||
}
|
||||
|
||||
*out = 0;
|
||||
|
||||
// g) If the resulting buffer string still begins with one or more
|
||||
// complete path segments of "..", then the reference is
|
||||
// considered to be in error. Implementations may handle this
|
||||
// error by retaining these components in the resolved path (i.e.,
|
||||
// treating them as part of the final URI), by removing them from
|
||||
// the resolved path (i.e., discarding relative levels above the
|
||||
// root), or by avoiding traversal of the reference.
|
||||
//
|
||||
// We discard them from the final path.
|
||||
|
||||
if (*path == '/')
|
||||
{
|
||||
for(cur=path; (*cur == '/') && (cur[1] == '.') && (cur[2] == '.') && ((cur[3] == '/') || (cur[3] == 0)); cur += 3);
|
||||
|
||||
if (cur != path)
|
||||
{
|
||||
for(out=path; *cur != 0; *(out++) = *(cur++));
|
||||
|
||||
*out = 0;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// This function will take a resolved URI and create a version of it that is relative to
|
||||
// another existing URI. The new URI is stored in the "originalURI"
|
||||
int daeURI::makeRelativeTo(const daeURI* relativeToURI)
|
||||
{
|
||||
// Can only do this function if both URIs have the same scheme and authority
|
||||
if (_scheme != relativeToURI->_scheme || _authority != relativeToURI->_authority)
|
||||
return DAE_ERR_INVALID_CALL;
|
||||
|
||||
// advance till we find a segment that doesn't match
|
||||
const char *this_path = getPath();
|
||||
const char *relativeTo_path = relativeToURI->getPath();
|
||||
const char *this_slash = this_path;
|
||||
const char *relativeTo_slash = relativeTo_path;
|
||||
|
||||
while((*this_path == *relativeTo_path) && *this_path)
|
||||
{
|
||||
if(*this_path == '/')
|
||||
{
|
||||
this_slash = this_path;
|
||||
relativeTo_slash = relativeTo_path;
|
||||
}
|
||||
this_path++;
|
||||
relativeTo_path++;
|
||||
}
|
||||
|
||||
// Decide how many ../ segments are needed (Filepath should always end in a /)
|
||||
int segment_count = 0;
|
||||
relativeTo_slash++;
|
||||
while(*relativeTo_slash != 0)
|
||||
{
|
||||
if(*relativeTo_slash == '/')
|
||||
segment_count ++;
|
||||
relativeTo_slash++;
|
||||
}
|
||||
this_slash++;
|
||||
|
||||
string newPath;
|
||||
for (int i = 0; i < segment_count; i++)
|
||||
newPath += "../";
|
||||
newPath += this_slash;
|
||||
|
||||
set("", "", newPath, _query, _fragment, relativeToURI);
|
||||
return(DAE_OK);
|
||||
}
|
||||
|
||||
|
||||
daeBool daeURIResolver::_loadExternalDocuments = true;
|
||||
|
||||
daeURIResolver::daeURIResolver(DAE& dae) : dae(&dae) { }
|
||||
|
||||
daeURIResolver::~daeURIResolver() { }
|
||||
|
||||
void daeURIResolver::setAutoLoadExternalDocuments( daeBool load )
|
||||
{
|
||||
_loadExternalDocuments = load;
|
||||
}
|
||||
|
||||
daeBool daeURIResolver::getAutoLoadExternalDocuments()
|
||||
{
|
||||
return _loadExternalDocuments;
|
||||
}
|
||||
|
||||
|
||||
daeURIResolverList::daeURIResolverList() { }
|
||||
|
||||
daeURIResolverList::~daeURIResolverList() {
|
||||
for (size_t i = 0; i < resolvers.getCount(); i++)
|
||||
delete resolvers[i];
|
||||
}
|
||||
|
||||
daeTArray<daeURIResolver*>& daeURIResolverList::list() {
|
||||
return resolvers;
|
||||
}
|
||||
|
||||
daeElement* daeURIResolverList::resolveElement(const daeURI& uri) {
|
||||
for (size_t i = 0; i < resolvers.getCount(); i++)
|
||||
if (daeElement* elt = resolvers[i]->resolveElement(uri))
|
||||
return elt;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// Returns true if parsing succeeded, false otherwise. Parsing can fail if the uri
|
||||
// reference isn't properly formed.
|
||||
bool cdom::parseUriRef(const string& uriRef,
|
||||
string& scheme,
|
||||
string& authority,
|
||||
string& path,
|
||||
string& query,
|
||||
string& fragment) {
|
||||
// This regular expression for parsing URI references comes from the URI spec:
|
||||
// http://tools.ietf.org/html/rfc3986#appendix-B
|
||||
static pcrecpp::RE re("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?");
|
||||
string s1, s3, s6, s8;
|
||||
if (re.FullMatch(uriRef, &s1, &scheme, &s3, &authority, &path, &s6, &query, &s8, &fragment))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
string safeSubstr(const string& s, size_t offset, size_t length) {
|
||||
string result = s.substr(offset, min(length, s.length() - offset));
|
||||
result.resize(length, '\0');
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
string cdom::assembleUri(const string& scheme,
|
||||
const string& authority,
|
||||
const string& path,
|
||||
const string& query,
|
||||
const string& fragment,
|
||||
bool forceLibxmlCompatible) {
|
||||
string p = safeSubstr(path, 0, 3);
|
||||
bool libxmlHack = forceLibxmlCompatible && scheme == "file";
|
||||
bool uncPath = false;
|
||||
string uri;
|
||||
|
||||
if (!scheme.empty())
|
||||
uri += scheme + ":";
|
||||
|
||||
if (!authority.empty() || libxmlHack || (p[0] == '/' && p[1] == '/'))
|
||||
uri += "//";
|
||||
if (!authority.empty()) {
|
||||
if (libxmlHack) {
|
||||
// We have a UNC path URI of the form file://otherMachine/file.dae.
|
||||
// Convert it to file://///otherMachine/file.dae, which is how libxml
|
||||
// does UNC paths.
|
||||
uri += "///" + authority;
|
||||
uncPath = true;
|
||||
}
|
||||
else {
|
||||
uri += authority;
|
||||
}
|
||||
}
|
||||
|
||||
if (!uncPath && libxmlHack && getSystemType() == Windows) {
|
||||
// We have to be delicate in how we pass absolute path URIs to libxml on Windows.
|
||||
// If the path is an absolute path with no drive letter, add an extra slash to
|
||||
// appease libxml.
|
||||
if (p[0] == '/' && p[1] != '/' && p[2] != ':') {
|
||||
uri += "/";
|
||||
}
|
||||
}
|
||||
uri += path;
|
||||
|
||||
if (!query.empty())
|
||||
uri += "?" + query;
|
||||
if (!fragment.empty())
|
||||
uri += "#" + fragment;
|
||||
|
||||
return uri;
|
||||
}
|
||||
|
||||
string cdom::fixUriForLibxml(const string& uriRef) {
|
||||
string scheme, authority, path, query, fragment;
|
||||
cdom::parseUriRef(uriRef, scheme, authority, path, query, fragment);
|
||||
return assembleUri(scheme, authority, path, query, fragment, true);
|
||||
}
|
||||
|
||||
|
||||
string cdom::nativePathToUri(const string& nativePath, systemType type) {
|
||||
string uri = nativePath;
|
||||
|
||||
if (type == Windows) {
|
||||
// Convert "c:\" to "/c:/"
|
||||
if (uri.length() >= 2 && isalpha(uri[0]) && uri[1] == ':')
|
||||
uri.insert(0, "/");
|
||||
// Convert backslashes to forward slashes
|
||||
uri = replace(uri, "\\", "/");
|
||||
}
|
||||
|
||||
// Convert spaces to %20
|
||||
uri = replace(uri, " ", "%20");
|
||||
|
||||
return uri;
|
||||
}
|
||||
|
||||
string cdom::filePathToUri(const string& filePath) {
|
||||
return nativePathToUri(filePath);
|
||||
}
|
||||
|
||||
string cdom::uriToNativePath(const string& uriRef, systemType type) {
|
||||
string scheme, authority, path, query, fragment;
|
||||
parseUriRef(uriRef, scheme, authority, path, query, fragment);
|
||||
|
||||
// Make sure we have a file scheme URI, or that it doesn't have a scheme
|
||||
if (!scheme.empty() && scheme != "file")
|
||||
return "";
|
||||
|
||||
string filePath;
|
||||
|
||||
if (type == Windows) {
|
||||
if (!authority.empty())
|
||||
filePath += string("\\\\") + authority; // UNC path
|
||||
|
||||
// Replace two leading slashes with one leading slash, so that
|
||||
// ///otherComputer/file.dae becomes //otherComputer/file.dae and
|
||||
// //folder/file.dae becomes /folder/file.dae
|
||||
if (path.length() >= 2 && path[0] == '/' && path[1] == '/')
|
||||
path.erase(0, 1);
|
||||
|
||||
// Convert "/C:/" to "C:/"
|
||||
if (path.length() >= 3 && path[0] == '/' && path[2] == ':')
|
||||
path.erase(0, 1);
|
||||
|
||||
// Convert forward slashes to back slashes
|
||||
path = replace(path, "/", "\\");
|
||||
}
|
||||
|
||||
filePath += path;
|
||||
|
||||
// Replace %20 with space
|
||||
filePath = replace(filePath, "%20", " ");
|
||||
|
||||
return filePath;
|
||||
}
|
||||
|
||||
string cdom::uriToFilePath(const string& uriRef) {
|
||||
return uriToNativePath(uriRef);
|
||||
}
|
||||
126
Engine/lib/collada/src/dae/daeUtils.cpp
Normal file
126
Engine/lib/collada/src/dae/daeUtils.cpp
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
#include <cstdarg>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <dae/daeUtils.h>
|
||||
#include <dae/daeURI.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <direct.h> // for getcwd (windows)
|
||||
#else
|
||||
#include <unistd.h> // for getcwd (linux)
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
cdom::systemType cdom::getSystemType() {
|
||||
#ifdef WIN32
|
||||
return Windows;
|
||||
#else
|
||||
return Posix;
|
||||
#endif
|
||||
}
|
||||
|
||||
string cdom::replace(const string& s, const string& replace, const string& replaceWith) {
|
||||
if (replace.empty())
|
||||
return s;
|
||||
|
||||
string result;
|
||||
size_t pos1 = 0, pos2 = s.find(replace);
|
||||
while (pos2 != string::npos) {
|
||||
result += s.substr(pos1, pos2-pos1);
|
||||
result += replaceWith;
|
||||
pos1 = pos2 + replace.length();
|
||||
pos2 = s.find(replace, pos1);
|
||||
}
|
||||
|
||||
result += s.substr(pos1, s.length()-pos1);
|
||||
return result;
|
||||
}
|
||||
|
||||
void cdom::tokenize(const string& s,
|
||||
const string& separators,
|
||||
/* out */ list<string>& tokens,
|
||||
bool separatorsInResult) {
|
||||
size_t currentIndex = 0, nextTokenIndex = 0;
|
||||
while (currentIndex < s.length() &&
|
||||
(nextTokenIndex = s.find_first_of(separators, currentIndex)) != string::npos) {
|
||||
if ((nextTokenIndex - currentIndex) > 0)
|
||||
tokens.push_back(s.substr(currentIndex, nextTokenIndex-currentIndex));
|
||||
if (separatorsInResult)
|
||||
tokens.push_back(string(1, s[nextTokenIndex]));
|
||||
currentIndex = nextTokenIndex+1;
|
||||
}
|
||||
|
||||
if (currentIndex < s.length())
|
||||
tokens.push_back(s.substr(currentIndex, s.length()-currentIndex));
|
||||
}
|
||||
|
||||
list<string> cdom::tokenize(const string& s,
|
||||
const string& separators,
|
||||
bool separatorsInResult) {
|
||||
list<string> result;
|
||||
tokenize(s, separators, result, separatorsInResult);
|
||||
return result;
|
||||
}
|
||||
|
||||
vector<string> cdom::makeStringArray(const char* s, ...) {
|
||||
va_list args;
|
||||
va_start(args, s);
|
||||
vector<string> result;
|
||||
while (s) {
|
||||
result.push_back(s);
|
||||
s = va_arg(args, const char*);
|
||||
}
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
list<string> cdom::makeStringList(const char* s, ...) {
|
||||
va_list args;
|
||||
va_start(args, s);
|
||||
list<string> result;
|
||||
while (s) {
|
||||
result.push_back(s);
|
||||
s = va_arg(args, const char*);
|
||||
}
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
string cdom::getCurrentDir() {
|
||||
#if defined(__CELLOS_LV2__) || defined(_XBOX_VER)
|
||||
// The PS3 has no getcwd call.
|
||||
// !!!steveT Should we return app_home instead?
|
||||
return "/";
|
||||
#else
|
||||
char buffer[1024];
|
||||
#ifdef _WIN32
|
||||
_getcwd(buffer, 1024);
|
||||
#else
|
||||
getcwd(buffer, 1024);
|
||||
#endif
|
||||
return buffer;
|
||||
#endif
|
||||
}
|
||||
|
||||
string cdom::getCurrentDirAsUri() {
|
||||
string result = string("file://") + cdom::nativePathToUri(getCurrentDir());
|
||||
// Make sure the last char is a /
|
||||
if (!result.empty() && result[result.length()-1] != '/')
|
||||
result += "/";
|
||||
return result;
|
||||
}
|
||||
|
||||
int cdom::strcasecmp(const char* str1, const char* str2) {
|
||||
#ifdef _MSC_VER
|
||||
return _stricmp(str1, str2);
|
||||
#else
|
||||
return ::strcasecmp(str1, str2);
|
||||
#endif
|
||||
}
|
||||
|
||||
string cdom::tolower(const string& s) {
|
||||
string result;
|
||||
transform(s.begin(), s.end(), back_inserter(result), ::tolower);
|
||||
return result;
|
||||
}
|
||||
111
Engine/lib/collada/src/dae/domAny.cpp
Normal file
111
Engine/lib/collada/src/dae/domAny.cpp
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <dae.h>
|
||||
#include <dae/daeDom.h>
|
||||
#include <dae/domAny.h>
|
||||
#include <dae/daeMetaAttribute.h>
|
||||
#include <dae/daeMetaCMPolicy.h>
|
||||
#include <dae/daeMetaSequence.h>
|
||||
#include <dae/daeMetaChoice.h>
|
||||
#include <dae/daeMetaGroup.h>
|
||||
#include <dae/daeMetaAny.h>
|
||||
#include <dae/daeMetaElementAttribute.h>
|
||||
#include <dae/daeErrorHandler.h>
|
||||
|
||||
daeElementRef
|
||||
domAny::create(DAE& dae)
|
||||
{
|
||||
domAnyRef ref = new domAny;
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
||||
daeMetaElement *
|
||||
domAny::registerElement(DAE& dae)
|
||||
{
|
||||
daeMetaElement *_Meta = new daeMetaElement(dae);
|
||||
_Meta->setName( "any" );
|
||||
_Meta->registerClass(domAny::create);
|
||||
_Meta->setIsInnerClass( true );
|
||||
|
||||
daeMetaCMPolicy *cm = NULL;
|
||||
cm = new daeMetaSequence( _Meta, cm, 0, 1, 1 );
|
||||
|
||||
cm = new daeMetaAny( _Meta, cm, 0, 0, -1 );
|
||||
cm->getParent()->appendChild( cm );
|
||||
cm = cm->getParent();
|
||||
|
||||
cm->setMaxOrdinal( 0 );
|
||||
_Meta->setCMRoot( cm );
|
||||
_Meta->setAllowsAny( true );
|
||||
|
||||
_Meta->addContents(daeOffsetOf(domAny,_contents));
|
||||
_Meta->addContentsOrder(daeOffsetOf(domAny,_contentsOrder));
|
||||
|
||||
//VALUE
|
||||
{
|
||||
daeMetaAttribute *ma = new daeMetaAttribute;
|
||||
ma->setName( "_value" );
|
||||
ma->setType( dae.getAtomicTypes().get("xsString"));
|
||||
ma->setOffset( daeOffsetOf( domAny , _value ));
|
||||
ma->setContainer( _Meta );
|
||||
_Meta->appendAttribute(ma);
|
||||
}
|
||||
|
||||
_Meta->setElementSize(sizeof(domAny));
|
||||
_Meta->validate();
|
||||
|
||||
return _Meta;
|
||||
}
|
||||
|
||||
domAny::~domAny() {
|
||||
// domAny objects own their corresponding daeMetaElement
|
||||
delete _meta;
|
||||
}
|
||||
|
||||
// Implementation of daeMetaAttribute that understands how domAny works
|
||||
class domAnyAttribute : public daeMetaAttribute {
|
||||
public:
|
||||
virtual daeChar* getWritableMemory(daeElement* e) {
|
||||
return (daeChar*)&((domAny*)e)->attrs[_offset];
|
||||
}
|
||||
};
|
||||
|
||||
daeBool domAny::setAttribute(daeString attrName, daeString attrValue) {
|
||||
if (_meta == NULL)
|
||||
return false;
|
||||
|
||||
//if the attribute already exists set it.
|
||||
if (daeElement::setAttribute(attrName, attrValue))
|
||||
return true;
|
||||
|
||||
//else register it and then set it.
|
||||
attrs.append("");
|
||||
daeMetaAttribute *ma = new domAnyAttribute;
|
||||
ma->setName( attrName );
|
||||
ma->setType( getDAE()->getAtomicTypes().get("xsString"));
|
||||
ma->setOffset((daeInt)attrs.getCount()-1);
|
||||
ma->setContainer( _meta );
|
||||
if (ma->getType()) {
|
||||
_meta->appendAttribute(ma);
|
||||
_validAttributeArray.append( true );
|
||||
ma->stringToMemory(this, attrValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
delete ma;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue