Engine directory for ticket #1

This commit is contained in:
DavidWyand-GG 2012-09-19 11:15:01 -04:00
parent 352279af7a
commit 7dbfe6994d
3795 changed files with 1363358 additions and 0 deletions

View 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));
}

View 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;
}

View 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);
}

View 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;
}

View 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();
}

View 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);
}

View 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;
}

View 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";
}

View 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;
}

View 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;
}

View 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;
}

View 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);
}

View 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
}

View 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);
}

View 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];
}
}

View 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 );
}
}

View 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;
// }

View 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) );
}
}

View 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 );
}

View 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 );
}
}

View 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();
}

View 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();
}

View 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;
}

View 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;
}

View 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);
}

View 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;
}

View 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

View 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);
}

View 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;
}

View 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;
}