mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-03-13 01:10:45 +00:00
Engine directory for ticket #1
This commit is contained in:
parent
352279af7a
commit
7dbfe6994d
3795 changed files with 1363358 additions and 0 deletions
758
Engine/lib/collada/src/dae/daeElement.cpp
Normal file
758
Engine/lib/collada/src/dae/daeElement.cpp
Normal file
|
|
@ -0,0 +1,758 @@
|
|||
/*
|
||||
* Copyright 2006 Sony Computer Entertainment Inc.
|
||||
*
|
||||
* Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this
|
||||
* file except in compliance with the License. You may obtain a copy of the License at:
|
||||
* http://research.scea.com/scea_shared_source_license.html
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing permissions and limitations under the
|
||||
* License.
|
||||
*/
|
||||
|
||||
#include <iomanip>
|
||||
#include <dae/daeElement.h>
|
||||
#include <dae/daeArray.h>
|
||||
#include <dae/daeMetaAttribute.h>
|
||||
#include <dae/daeMetaElementAttribute.h>
|
||||
#include <dae/daeMetaElement.h>
|
||||
#include <dae/daeDatabase.h>
|
||||
#include <dae/daeErrorHandler.h>
|
||||
#include <dae/daeURI.h>
|
||||
#include <dae/domAny.h>
|
||||
#include <dae/daeUtils.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
daeElement* daeElement::simpleAdd(daeString name, int index) {
|
||||
if (daeElementRef elt = _meta->create(name))
|
||||
return add(elt, index);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeElement* daeElement::add(daeString names_, int index) {
|
||||
list<string> names;
|
||||
cdom::tokenize(names_, " ", names);
|
||||
cdom::tokenIter iter = names.begin();
|
||||
daeElement* root = simpleAdd(iter->c_str(), index);
|
||||
if (!root)
|
||||
return NULL;
|
||||
|
||||
iter++;
|
||||
daeElement* elt = root;
|
||||
for (; iter != names.end(); iter++) {
|
||||
elt = elt->simpleAdd(iter->c_str());
|
||||
if (!elt) {
|
||||
removeChildElement(root);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return elt;
|
||||
}
|
||||
|
||||
daeElement* daeElement::add(daeElement* elt, int index) {
|
||||
if (!elt)
|
||||
return NULL;
|
||||
if (elt == this)
|
||||
return this;
|
||||
bool result = (index == -1 ? _meta->place(this, elt) : _meta->placeAt(index, this, elt));
|
||||
return result ? elt : NULL;
|
||||
}
|
||||
|
||||
daeElement* daeElement::addBefore(daeElement* elt, daeElement* index) {
|
||||
if (!index || !elt || index->getParent() != this)
|
||||
return NULL;
|
||||
return _meta->placeBefore(index, this, elt) ? elt : NULL;
|
||||
}
|
||||
|
||||
daeElement* daeElement::addAfter(daeElement* elt, daeElement* index) {
|
||||
if (!index || !elt || index->getParent() != this)
|
||||
return NULL;
|
||||
return _meta->placeAfter(index, this, elt) ? elt : NULL;
|
||||
}
|
||||
|
||||
daeElementRef
|
||||
daeElement::createElement(daeString className)
|
||||
{
|
||||
daeElementRef elem = _meta->create(className);
|
||||
// Bug #225 work around
|
||||
// if ( elem != NULL)
|
||||
// elem->ref(); // change premature delete into memory leak.
|
||||
return elem;
|
||||
}
|
||||
|
||||
daeElement* daeElement::createAndPlace(daeString className) {
|
||||
return add(className);
|
||||
}
|
||||
|
||||
daeElement* daeElement::createAndPlaceAt(daeInt index, daeString className) {
|
||||
return add(className, index);
|
||||
}
|
||||
|
||||
daeBool daeElement::placeElement(daeElement* e) {
|
||||
return add(e) != NULL;
|
||||
}
|
||||
|
||||
daeBool daeElement::placeElementAt(daeInt index, daeElement* e) {
|
||||
return add(e, index) != NULL;
|
||||
}
|
||||
|
||||
daeBool daeElement::placeElementBefore( daeElement *marker, daeElement *element ) {
|
||||
return addBefore(element, marker) != NULL;
|
||||
}
|
||||
|
||||
daeBool daeElement::placeElementAfter( daeElement *marker, daeElement *element ) {
|
||||
return addAfter(element, marker) != NULL;
|
||||
}
|
||||
|
||||
daeInt daeElement::findLastIndexOf( daeString elementName ) {
|
||||
if ( _meta->getContents() != NULL ) {
|
||||
daeElementRefArray* contents =
|
||||
(daeElementRefArray*)_meta->getContents()->getWritableMemory(this);
|
||||
for ( int i = (int)contents->getCount()-1; i >= 0; --i ) {
|
||||
if ( strcmp( contents->get(i)->getElementName(), elementName ) == 0 ) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
daeBool
|
||||
daeElement::removeChildElement(daeElement* element)
|
||||
{
|
||||
// error traps
|
||||
if(element==NULL)
|
||||
return false;
|
||||
if(element->_parent != this)
|
||||
return false;
|
||||
|
||||
return _meta->remove( this, element );
|
||||
}
|
||||
|
||||
void daeElement::setDocument( daeDocument *c, bool notifyDocument ) {
|
||||
if( _document == c )
|
||||
return;
|
||||
|
||||
// Notify our parent document if necessary.
|
||||
if ( _document != NULL && notifyDocument )
|
||||
_document->removeElement(this);
|
||||
_document = c;
|
||||
if ( _document != NULL && notifyDocument )
|
||||
_document->insertElement(this);
|
||||
|
||||
// Notify our attributes
|
||||
daeMetaAttributeRefArray& metaAttrs = getMeta()->getMetaAttributes();
|
||||
for (size_t i = 0; i < metaAttrs.getCount(); i++)
|
||||
metaAttrs[i]->setDocument(this, c);
|
||||
|
||||
// Notify our char data object
|
||||
if (getCharDataObject())
|
||||
getCharDataObject()->setDocument(this, c);
|
||||
|
||||
// Notify our children
|
||||
daeElementRefArray ea;
|
||||
getChildren( ea );
|
||||
for ( size_t x = 0; x < ea.getCount(); x++ ) {
|
||||
// Since inserting and removing elements works recursively in the database,
|
||||
// we don't need to notify it about inserts/removals as we process the
|
||||
// children of this element.
|
||||
ea[x]->setDocument( c, false );
|
||||
}
|
||||
}
|
||||
|
||||
void daeElement::deleteCMDataArray(daeTArray<daeCharArray*>& cmData) {
|
||||
for (unsigned int i = 0; i < cmData.getCount(); i++)
|
||||
delete cmData.get(i);
|
||||
cmData.clear();
|
||||
}
|
||||
|
||||
size_t daeElement::getAttributeCount() {
|
||||
return getMeta()->getMetaAttributes().getCount();
|
||||
}
|
||||
|
||||
namespace {
|
||||
// A helper function to get the index of an attribute given the attribute name.
|
||||
size_t getAttributeIndex(daeElement& el, daeString name) {
|
||||
if (el.getMeta()) {
|
||||
daeMetaAttributeRefArray& metaAttrs = el.getMeta()->getMetaAttributes();
|
||||
for (size_t i = 0; i < metaAttrs.getCount(); i++)
|
||||
if (metaAttrs[i]->getName() && strcmp(metaAttrs[i]->getName(), name) == 0)
|
||||
return i;
|
||||
}
|
||||
return (size_t)-1;
|
||||
}
|
||||
}
|
||||
|
||||
daeMetaAttribute* daeElement::getAttributeObject(size_t i) {
|
||||
daeMetaAttributeRefArray& attrs = getMeta()->getMetaAttributes();
|
||||
if (i >= attrs.getCount())
|
||||
return NULL;
|
||||
return attrs[i];
|
||||
}
|
||||
|
||||
daeMetaAttribute* daeElement::getAttributeObject(daeString name) {
|
||||
return getAttributeObject(getAttributeIndex(*this, name));
|
||||
}
|
||||
|
||||
std::string daeElement::getAttributeName(size_t i) {
|
||||
if (daeMetaAttribute* attr = getAttributeObject(i))
|
||||
return (daeString)attr->getName();
|
||||
return "";
|
||||
}
|
||||
|
||||
daeBool daeElement::hasAttribute(daeString name) {
|
||||
return getAttributeObject(name) != 0;
|
||||
}
|
||||
|
||||
daeBool daeElement::isAttributeSet(daeString name) {
|
||||
size_t i = getAttributeIndex(*this, name);
|
||||
if (i != (size_t)-1)
|
||||
return _validAttributeArray[i];
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string daeElement::getAttribute(size_t i) {
|
||||
std::string value;
|
||||
getAttribute(i, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
void daeElement::getAttribute(size_t i, std::string& value) {
|
||||
value = "";
|
||||
if (daeMetaAttribute* attr = getAttributeObject(i)) {
|
||||
std::ostringstream buffer;
|
||||
attr->memoryToString(this, buffer);
|
||||
value = buffer.str();
|
||||
}
|
||||
}
|
||||
|
||||
std::string daeElement::getAttribute(daeString name) {
|
||||
std::string value;
|
||||
getAttribute(name, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
void daeElement::getAttribute(daeString name, std::string& value) {
|
||||
getAttribute(getAttributeIndex(*this, name), value);
|
||||
}
|
||||
|
||||
daeElement::attr::attr() { }
|
||||
daeElement::attr::attr(const std::string& name, const std::string& value)
|
||||
: name(name), value(value) { }
|
||||
|
||||
daeTArray<daeElement::attr> daeElement::getAttributes() {
|
||||
daeTArray<daeElement::attr> attrs;
|
||||
getAttributes(attrs);
|
||||
return attrs;
|
||||
}
|
||||
|
||||
void daeElement::getAttributes(daeTArray<attr>& attrs) {
|
||||
attrs.clear();
|
||||
for (size_t i = 0; i < getAttributeCount(); i++) {
|
||||
std::string value;
|
||||
getAttribute(i, value);
|
||||
attrs.append(attr(getAttributeName(i), value));
|
||||
}
|
||||
}
|
||||
|
||||
daeBool daeElement::setAttribute(size_t i, daeString value) {
|
||||
if (daeMetaAttribute* attr = getAttributeObject(i)) {
|
||||
if (attr->getType()) {
|
||||
attr->stringToMemory(this, value);
|
||||
_validAttributeArray.set(i, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
daeBool daeElement::setAttribute(daeString name, daeString value) {
|
||||
return setAttribute(getAttributeIndex(*this, name), value);
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
daeMemoryRef daeElement::getAttributeValue(daeString name) {
|
||||
if (daeMetaAttribute* attr = getAttributeObject(name))
|
||||
return attr->get(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeMetaAttribute* daeElement::getCharDataObject() {
|
||||
if (_meta)
|
||||
return _meta->getValueAttribute();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeBool daeElement::hasCharData() {
|
||||
return getCharDataObject() != NULL;
|
||||
}
|
||||
|
||||
std::string daeElement::getCharData() {
|
||||
std::string result;
|
||||
getCharData(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void daeElement::getCharData(std::string& data) {
|
||||
data = "";
|
||||
if (daeMetaAttribute* charDataAttr = getCharDataObject()) {
|
||||
std::ostringstream buffer;
|
||||
charDataAttr->memoryToString(this, buffer);
|
||||
data = buffer.str();
|
||||
}
|
||||
}
|
||||
|
||||
daeBool daeElement::setCharData(const std::string& data) {
|
||||
if (daeMetaAttribute* charDataAttr = getCharDataObject()) {
|
||||
charDataAttr->stringToMemory(this, data.c_str());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
daeBool daeElement::hasValue() {
|
||||
return hasCharData();
|
||||
}
|
||||
|
||||
daeMemoryRef daeElement::getValuePointer() {
|
||||
if (daeMetaAttribute* charDataAttr = getCharDataObject())
|
||||
return charDataAttr->get(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
daeElement::setup(daeMetaElement* meta)
|
||||
{
|
||||
if (_meta)
|
||||
return;
|
||||
_meta = meta;
|
||||
daeMetaAttributeRefArray& attrs = meta->getMetaAttributes();
|
||||
int macnt = (int)attrs.getCount();
|
||||
|
||||
_validAttributeArray.setCount(macnt, false);
|
||||
|
||||
for (int i = 0; i < macnt; i++) {
|
||||
if (attrs[i]->getDefaultValue() != NULL)
|
||||
attrs[i]->copyDefault(this);
|
||||
}
|
||||
|
||||
//set up the _CMData array if there is one
|
||||
if ( _meta->getMetaCMData() != NULL )
|
||||
{
|
||||
daeTArray< daeCharArray *> *CMData = (daeTArray< daeCharArray *>*)_meta->getMetaCMData()->getWritableMemory(this);
|
||||
CMData->setCount( _meta->getNumChoices() );
|
||||
for ( unsigned int i = 0; i < _meta->getNumChoices(); i++ )
|
||||
{
|
||||
CMData->set( i, new daeCharArray() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void daeElement::init() {
|
||||
_parent = NULL;
|
||||
_document = NULL;
|
||||
_meta = NULL;
|
||||
_elementName = NULL;
|
||||
_userData = NULL;
|
||||
}
|
||||
|
||||
daeElement::daeElement() {
|
||||
init();
|
||||
}
|
||||
|
||||
daeElement::daeElement(DAE& dae) {
|
||||
init();
|
||||
}
|
||||
|
||||
daeElement::~daeElement()
|
||||
{
|
||||
if (_elementName) {
|
||||
delete[] _elementName;
|
||||
_elementName = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//function used until we clarify what's a type and what's a name for an element
|
||||
daeString daeElement::getTypeName() const
|
||||
{
|
||||
return _meta->getName();
|
||||
}
|
||||
daeString daeElement::getElementName() const
|
||||
{
|
||||
return _elementName ? _elementName : (daeString)_meta->getName();
|
||||
}
|
||||
void daeElement::setElementName( daeString nm ) {
|
||||
if ( nm == NULL ) {
|
||||
if ( _elementName ) delete[] _elementName;
|
||||
_elementName = NULL;
|
||||
return;
|
||||
}
|
||||
if ( !_elementName ) _elementName = new daeChar[128];
|
||||
strcpy( (char*)_elementName, nm );
|
||||
}
|
||||
|
||||
daeString daeElement::getID() const {
|
||||
daeElement* this_ = const_cast<daeElement*>(this);
|
||||
if (_meta)
|
||||
if (daeMetaAttribute* idAttr = this_->getAttributeObject("id"))
|
||||
return *(daeStringRef*)idAttr->get(this_);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeElementRefArray daeElement::getChildren() {
|
||||
daeElementRefArray array;
|
||||
getChildren(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
void daeElement::getChildren( daeElementRefArray &array ) {
|
||||
_meta->getChildren( this, array );
|
||||
}
|
||||
|
||||
daeSmartRef<daeElement> daeElement::clone(daeString idSuffix, daeString nameSuffix) {
|
||||
// Use the meta object system to create a new instance of this element. We need to
|
||||
// create a new meta if we're cloning a domAny object because domAnys never share meta objects.
|
||||
// Ideally we'd be able to clone the _meta for domAny objects. Then we wouldn't need
|
||||
// any additional special case code for cloning domAny. Unfortunately, we don't have a
|
||||
// daeMetaElement::clone method.
|
||||
bool any = typeID() == domAny::ID();
|
||||
daeElementRef ret = any ? domAny::registerElement(*getDAE())->create() : _meta->create();
|
||||
ret->setElementName( _elementName );
|
||||
|
||||
// Copy the attributes and character data. Requires special care for domAny.
|
||||
if (any) {
|
||||
domAny* thisAny = (domAny*)this;
|
||||
domAny* retAny = (domAny*)ret.cast();
|
||||
for (daeUInt i = 0; i < (daeUInt)thisAny->getAttributeCount(); i++)
|
||||
retAny->setAttribute(thisAny->getAttributeName(i), thisAny->getAttributeValue(i));
|
||||
retAny->setValue(thisAny->getValue());
|
||||
} else {
|
||||
// Use the meta system to copy attributes
|
||||
daeMetaAttributeRefArray &attrs = _meta->getMetaAttributes();
|
||||
for (unsigned int i = 0; i < attrs.getCount(); i++) {
|
||||
attrs[i]->copy( ret, this );
|
||||
ret->_validAttributeArray[i] = _validAttributeArray[i];
|
||||
}
|
||||
if (daeMetaAttribute* valueAttr = getCharDataObject())
|
||||
valueAttr->copy( ret, this );
|
||||
}
|
||||
|
||||
daeElementRefArray children;
|
||||
_meta->getChildren( this, children );
|
||||
for ( size_t x = 0; x < children.getCount(); x++ ) {
|
||||
ret->placeElement( children.get(x)->clone( idSuffix, nameSuffix ) );
|
||||
}
|
||||
|
||||
// Mangle the id
|
||||
if (idSuffix) {
|
||||
std::string id = ret->getAttribute("id");
|
||||
if (!id.empty())
|
||||
ret->setAttribute("id", (id + idSuffix).c_str());
|
||||
}
|
||||
// Mangle the name
|
||||
if (nameSuffix) {
|
||||
std::string name = ret->getAttribute("name");
|
||||
if (!name.empty())
|
||||
ret->setAttribute("name", (name + nameSuffix).c_str());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// Element comparison
|
||||
|
||||
namespace { // Utility functions
|
||||
int getNecessaryColumnWidth(const vector<string>& tokens) {
|
||||
int result = 0;
|
||||
for (size_t i = 0; i < tokens.size(); i++) {
|
||||
int tokenLength = int(tokens[i].length() > 0 ? tokens[i].length()+2 : 0);
|
||||
result = max(tokenLength, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
string formatToken(const string& token) {
|
||||
if (token.length() <= 50)
|
||||
return token;
|
||||
return token.substr(0, 47) + "...";
|
||||
}
|
||||
} // namespace {
|
||||
|
||||
daeElement::compareResult::compareResult()
|
||||
: compareValue(0),
|
||||
elt1(NULL),
|
||||
elt2(NULL),
|
||||
nameMismatch(false),
|
||||
attrMismatch(""),
|
||||
charDataMismatch(false),
|
||||
childCountMismatch(false) {
|
||||
}
|
||||
|
||||
string daeElement::compareResult::format() {
|
||||
if (!elt1 || !elt2)
|
||||
return "";
|
||||
|
||||
// Gather the data we'll be printing
|
||||
string name1 = formatToken(elt1->getElementName()),
|
||||
name2 = formatToken(elt2->getElementName()),
|
||||
type1 = formatToken(elt1->getTypeName()),
|
||||
type2 = formatToken(elt2->getTypeName()),
|
||||
id1 = formatToken(elt1->getAttribute("id")),
|
||||
id2 = formatToken(elt2->getAttribute("id")),
|
||||
attrName1 = formatToken(attrMismatch),
|
||||
attrName2 = formatToken(attrMismatch),
|
||||
attrValue1 = formatToken(elt1->getAttribute(attrMismatch.c_str())),
|
||||
attrValue2 = formatToken(elt2->getAttribute(attrMismatch.c_str())),
|
||||
charData1 = formatToken(elt1->getCharData()),
|
||||
charData2 = formatToken(elt2->getCharData()),
|
||||
childCount1 = formatToken(cdom::toString(elt1->getChildren().getCount())),
|
||||
childCount2 = formatToken(cdom::toString(elt2->getChildren().getCount()));
|
||||
|
||||
// Compute formatting information
|
||||
vector<string> col1Tokens = cdom::makeStringArray("Name", "Type", "ID",
|
||||
"Attr name", "Attr value", "Char data", "Child count", 0);
|
||||
vector<string> col2Tokens = cdom::makeStringArray("Element 1", name1.c_str(),
|
||||
type1.c_str(), id1.c_str(), attrName1.c_str(), attrValue1.c_str(),
|
||||
charData1.c_str(), childCount1.c_str(), 0);
|
||||
|
||||
int c1w = getNecessaryColumnWidth(col1Tokens),
|
||||
c2w = getNecessaryColumnWidth(col2Tokens);
|
||||
ostringstream msg;
|
||||
msg << setw(c1w) << left << "" << setw(c2w) << left << "Element 1" << "Element 2\n"
|
||||
<< setw(c1w) << left << "" << setw(c2w) << left << "---------" << "---------\n"
|
||||
<< setw(c1w) << left << "Name" << setw(c2w) << left << name1 << name2 << endl
|
||||
<< setw(c1w) << left << "Type" << setw(c2w) << left << type1 << type2 << endl
|
||||
<< setw(c1w) << left << "ID" << setw(c2w) << left << id1 << id2 << endl
|
||||
<< setw(c1w) << left << "Attr name" << setw(c2w) << left << attrName1 << attrName2 << endl
|
||||
<< setw(c1w) << left << "Attr value" << setw(c2w) << left << attrValue1 << attrValue2 << endl
|
||||
<< setw(c1w) << left << "Char data" << setw(c2w) << left << charData1 << charData2 << endl
|
||||
<< setw(c1w) << left << "Child count" << setw(c2w) << left << childCount1 << childCount2;
|
||||
|
||||
return msg.str();
|
||||
}
|
||||
|
||||
namespace {
|
||||
daeElement::compareResult compareMatch() {
|
||||
daeElement::compareResult result;
|
||||
result.compareValue = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
daeElement::compareResult nameMismatch(daeElement& elt1, daeElement& elt2) {
|
||||
daeElement::compareResult result;
|
||||
result.elt1 = &elt1;
|
||||
result.elt2 = &elt2;
|
||||
result.compareValue = strcmp(elt1.getElementName(), elt2.getElementName());
|
||||
result.nameMismatch = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
daeElement::compareResult attrMismatch(daeElement& elt1, daeElement& elt2, const string& attr) {
|
||||
daeElement::compareResult result;
|
||||
result.elt1 = &elt1;
|
||||
result.elt2 = &elt2;
|
||||
result.compareValue = strcmp(elt1.getAttribute(attr.c_str()).c_str(),
|
||||
elt2.getAttribute(attr.c_str()).c_str());
|
||||
result.attrMismatch = attr;
|
||||
return result;
|
||||
}
|
||||
|
||||
daeElement::compareResult charDataMismatch(daeElement& elt1, daeElement& elt2) {
|
||||
daeElement::compareResult result;
|
||||
result.elt1 = &elt1;
|
||||
result.elt2 = &elt2;
|
||||
result.compareValue = strcmp(elt1.getCharData().c_str(),
|
||||
elt2.getCharData().c_str());
|
||||
result.charDataMismatch = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
daeElement::compareResult childCountMismatch(daeElement& elt1, daeElement& elt2) {
|
||||
daeElement::compareResult result;
|
||||
result.elt1 = &elt1;
|
||||
result.elt2 = &elt2;
|
||||
daeElementRefArray children1 = elt1.getChildren(),
|
||||
children2 = elt2.getChildren();
|
||||
result.compareValue = int(children1.getCount()) - int(children2.getCount());
|
||||
result.childCountMismatch = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
daeElement::compareResult compareElementsSameType(daeElement& elt1, daeElement& elt2) {
|
||||
// Compare attributes
|
||||
for (size_t i = 0; i < elt1.getAttributeCount(); i++)
|
||||
if (elt1.getAttributeObject(i)->compare(&elt1, &elt2) != 0)
|
||||
return attrMismatch(elt1, elt2, elt1.getAttributeName(i));
|
||||
|
||||
// Compare character data
|
||||
if (elt1.getCharDataObject())
|
||||
if (elt1.getCharDataObject()->compare(&elt1, &elt2) != 0)
|
||||
return charDataMismatch(elt1, elt2);
|
||||
|
||||
// Compare children
|
||||
daeElementRefArray children1 = elt1.getChildren(),
|
||||
children2 = elt2.getChildren();
|
||||
if (children1.getCount() != children2.getCount())
|
||||
return childCountMismatch(elt1, elt2);
|
||||
for (size_t i = 0; i < children1.getCount(); i++) {
|
||||
daeElement::compareResult result = daeElement::compareWithFullResult(*children1[i], *children2[i]);
|
||||
if (result.compareValue != 0)
|
||||
return result;
|
||||
}
|
||||
|
||||
return compareMatch();
|
||||
}
|
||||
|
||||
daeElement::compareResult compareElementsDifferentTypes(daeElement& elt1, daeElement& elt2) {
|
||||
string value1, value2;
|
||||
|
||||
// Compare attributes. Be careful because each element could have a
|
||||
// different number of attributes.
|
||||
if (elt1.getAttributeCount() > elt2.getAttributeCount())
|
||||
return attrMismatch(elt1, elt2, elt1.getAttributeName(elt2.getAttributeCount()));
|
||||
if (elt2.getAttributeCount() > elt1.getAttributeCount())
|
||||
return attrMismatch(elt1, elt2, elt2.getAttributeName(elt1.getAttributeCount()));
|
||||
for (size_t i = 0; i < elt1.getAttributeCount(); i++) {
|
||||
elt1.getAttribute(i, value1);
|
||||
elt2.getAttribute(elt1.getAttributeName(i).c_str(), value2);
|
||||
if (value1 != value2)
|
||||
return attrMismatch(elt1, elt2, elt1.getAttributeName(i));
|
||||
}
|
||||
|
||||
// Compare character data
|
||||
elt1.getCharData(value1);
|
||||
elt2.getCharData(value2);
|
||||
if (value1 != value2)
|
||||
return charDataMismatch(elt1, elt2);
|
||||
|
||||
// Compare children
|
||||
daeElementRefArray children1 = elt1.getChildren(),
|
||||
children2 = elt2.getChildren();
|
||||
if (children1.getCount() != children2.getCount())
|
||||
return childCountMismatch(elt1, elt2);
|
||||
for (size_t i = 0; i < children1.getCount(); i++) {
|
||||
daeElement::compareResult result = daeElement::compareWithFullResult(*children1[i], *children2[i]);
|
||||
if (result.compareValue != 0)
|
||||
return result;
|
||||
}
|
||||
|
||||
return compareMatch();
|
||||
}
|
||||
} // namespace {
|
||||
|
||||
int daeElement::compare(daeElement& elt1, daeElement& elt2) {
|
||||
return compareWithFullResult(elt1, elt2).compareValue;
|
||||
}
|
||||
|
||||
daeElement::compareResult daeElement::compareWithFullResult(daeElement& elt1, daeElement& elt2) {
|
||||
// Check the element name
|
||||
if (strcmp(elt1.getElementName(), elt2.getElementName()) != 0)
|
||||
return nameMismatch(elt1, elt2);
|
||||
|
||||
// Dispatch to a specific function based on whether or not the types are the same
|
||||
if ((elt1.typeID() != elt2.typeID()) || elt1.typeID() == domAny::ID())
|
||||
return compareElementsDifferentTypes(elt1, elt2);
|
||||
else
|
||||
return compareElementsSameType(elt1, elt2);
|
||||
}
|
||||
|
||||
|
||||
daeURI *daeElement::getDocumentURI() const {
|
||||
if ( _document == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
return _document->getDocumentURI();
|
||||
}
|
||||
|
||||
|
||||
daeElement::matchName::matchName(daeString name) : name(name) { }
|
||||
|
||||
bool daeElement::matchName::operator()(daeElement* elt) const {
|
||||
return strcmp(elt->getElementName(), name.c_str()) == 0;
|
||||
}
|
||||
|
||||
daeElement::matchType::matchType(daeInt typeID) : typeID(typeID) { }
|
||||
|
||||
bool daeElement::matchType::operator()(daeElement* elt) const {
|
||||
return elt->typeID() == typeID;
|
||||
}
|
||||
|
||||
daeElement* daeElement::getChild(const matchElement& matcher) {
|
||||
daeElementRefArray children;
|
||||
getChildren(children);
|
||||
for (size_t i = 0; i < children.getCount(); i++)
|
||||
if (matcher(children[i]))
|
||||
return children[i];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeElement* daeElement::getDescendant(const matchElement& matcher) {
|
||||
daeElementRefArray elts;
|
||||
getChildren(elts);
|
||||
|
||||
for (size_t i = 0; i < elts.getCount(); i++) {
|
||||
// Check the current element for a match
|
||||
if (matcher(elts[i]))
|
||||
return elts[i];
|
||||
|
||||
// Append the element's children to the queue
|
||||
daeElementRefArray children;
|
||||
elts[i]->getChildren(children);
|
||||
size_t oldCount = elts.getCount();
|
||||
elts.setCount(elts.getCount() + children.getCount());
|
||||
for (size_t j = 0; j < children.getCount(); j++)
|
||||
elts[oldCount + j] = children[j];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeElement* daeElement::getAncestor(const matchElement& matcher) {
|
||||
daeElement* elt = getParent();
|
||||
while (elt) {
|
||||
if (matcher(elt))
|
||||
return elt;
|
||||
elt = elt->getParent();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
daeElement* daeElement::getParent() {
|
||||
return _parent;
|
||||
}
|
||||
|
||||
daeElement* daeElement::getChild(daeString eltName) {
|
||||
if (!eltName)
|
||||
return NULL;
|
||||
matchName test(eltName);
|
||||
return getChild(matchName(eltName));
|
||||
}
|
||||
|
||||
daeElement* daeElement::getDescendant(daeString eltName) {
|
||||
if (!eltName)
|
||||
return NULL;
|
||||
return getDescendant(matchName(eltName));
|
||||
}
|
||||
|
||||
daeElement* daeElement::getAncestor(daeString eltName) {
|
||||
if (!eltName)
|
||||
return NULL;
|
||||
return getAncestor(matchName(eltName));
|
||||
}
|
||||
|
||||
DAE* daeElement::getDAE() {
|
||||
return _meta->getDAE();
|
||||
}
|
||||
|
||||
void daeElement::setUserData(void* data) {
|
||||
_userData = data;
|
||||
}
|
||||
|
||||
void* daeElement::getUserData() {
|
||||
return _userData;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue