| /*
|
| * Copyright 2006 Sony Computer Entertainment Inc.
|
| *
|
| * Licensed under the MIT Open Source License, for details please see license.txt or the website
|
| * http://www.opensource.org/licenses/mit-license.php
|
| *
|
| */ |
| |
| #ifndef __DAE_ELEMENT_H__ |
| #define __DAE_ELEMENT_H__ |
| #include <string> |
| #include <dae/daeTypes.h> |
| #include <dae/daeMemorySystem.h> |
| #include <wchar.h> |
| #include <dae/daeArray.h> |
| #include <dae/daeRefCountedObj.h> |
| #include <dae/daeSmartRef.h> |
| |
| //#ifndef NO_MALLOC_HEADER |
| //#include <malloc.h> |
| //#endif |
| |
| namespace COLLADA_TYPE |
| { |
| typedef int TypeEnum; |
| } |
| |
| class DAE; |
| class daeMetaElement; |
| class daeMetaAttribute; |
| class daeDocument; |
| class daeURI; |
| |
| /** |
| * The @c daeElement class represents an instance of a COLLADA "Element"; |
| * it is the main base class for the COLLADA Dom. |
| * Features of this class include: |
| * - Uses factory concepts defined via daeMetaElement |
| * - Composed of attributes, content elements and content values |
| * - Reference counted via daeSmartRef |
| * - Contains information for XML base URI, and XML containing element |
| */ |
| class DLLSPEC daeElement : public daeRefCountedObj |
| { |
| public: |
| /** |
| * Macro that defines new and delete overrides for this class |
| */ |
| DAE_ALLOC |
| protected: |
| daeElement* _parent; |
| daeDocument* _document; |
| daeMetaElement* _meta; |
| daeString _elementName; |
| daeBoolArray _validAttributeArray; // This is now obsolete and can be removed |
| void* _userData; |
| |
| protected: |
| daeElement( const daeElement &cpy ) : daeRefCountedObj() { (void)cpy; }; |
| virtual daeElement &operator=( const daeElement &cpy ) { (void)cpy; return *this; } |
| |
| void init(); |
| |
| // These functions are called internally. |
| void setDocument( daeDocument* c, bool notifyDocument ); |
| daeElement* simpleAdd(daeString name, int index = -1); |
| |
| public: |
| /** |
| * Element Constructor. |
| * @note This should not be used externally. |
| * Use factories to create elements |
| */ |
| daeElement(); |
| /** |
| * Element Constructor. |
| * @note This should not be used externally. |
| * Use factories to create elements |
| */ |
| daeElement(DAE& dae); |
| |
| /** |
| * Element Destructor. |
| * @note This should not be used externally, |
| * if daeSmartRefs are being used. |
| */ |
| virtual ~daeElement(); |
| |
| /** |
| * Sets up a @c daeElement. Called on all @c daeElements as part of their initialization. |
| * @param meta Meta element to use to configure this element. |
| * @note Should not be called externally. |
| */ |
| void setup(daeMetaElement* meta); |
| |
| // These functions are for adding child elements. They return null if adding |
| // the element failed. |
| daeElement* add(daeString name, int index = -1); |
| daeElement* add(daeElement* elt, int index = -1); |
| daeElement* addBefore(daeElement* elt, daeElement* index); |
| daeElement* addAfter(daeElement* elt, daeElement* index); |
| |
| // These functions are deprecated. Use 'add' instead. |
| daeElement* createAndPlace(daeString elementName); |
| daeElement* createAndPlaceAt(daeInt index, daeString elementName); |
| daeBool placeElement(daeElement* element); |
| daeBool placeElementAt(daeInt index, daeElement* element); |
| daeBool placeElementBefore( daeElement* marker, daeElement *element ); |
| daeBool placeElementAfter( daeElement* marker, daeElement *element ); |
| |
| /** |
| * Finds the last index into the array of children of the name specified. |
| * @param elementName The name to look for. |
| * @return Returns the index into the children array of the last element with name elementName. -1 if |
| * there are no children of name elementName. |
| */ |
| daeInt findLastIndexOf( daeString elementName ); |
| |
| /** |
| * Removes the specified element from it parent, the @c this element. |
| * This function is the opposite of @c placeElement(). It removes the specified |
| * element from the <tt><i> _contents </i></tt> array, and from wherever else it appears |
| * inside of the @c this element. Use this function instead of @c clear(), @c remove() or @c delete() |
| * if you want to keep the <tt><i> _contents </i></tt> field up-to-date. |
| * |
| * @param element Element to be removed in the @c this container. |
| * @return Returns true if the element was successfully removed, false otherwise. |
| */ |
| daeBool removeChildElement(daeElement* element); |
| |
| /** |
| * Removes the specified element from its parent element. |
| * This function is the opposite of @c placeElement(). It removes the specified |
| * element from both the <tt><i> _contents </i></tt> array and from wherever else it appears |
| * inside of its parent. The function itself finds the parent, and is defined as a static method, |
| * since removing the element from its parent may result in the deletion of the element. |
| * If the element has no parent, nothing is done. |
| * |
| * Use this function instead of @c clear(), @c remove() or @c delete() |
| * if you want to keep <tt><i> _contents </i></tt> up-to-date. |
| * |
| * @param element Element to remove from its parent container, the function finds the parent element. |
| * @return Returns true if the element was successfully removed, false otherwise. |
| */ |
| static daeBool removeFromParent(daeElement* element) |
| { |
| if(element != NULL && element->_parent != NULL) |
| return(element->_parent->removeChildElement(element)); |
| return false; |
| }; |
| |
| /** |
| * Returns the number of attributes in this element. |
| * @return The number of attributes this element has. |
| */ |
| size_t getAttributeCount(); |
| |
| /** |
| * Returns the daeMetaAttribute object corresponding to the attribute specified. |
| * @param name The name of the attribute to find. |
| * @return Returns the corresponding daeMetaAttribute object or NULL if this element |
| * doesn't have the specified attribute. |
| */ |
| daeMetaAttribute* getAttributeObject(daeString name); |
| |
| /** |
| * Returns the daeMetaAttribute object corresponding to attribute i. |
| * @param i The index of the attribute to find. |
| * @return Returns the corresponding daeMetaAttribute object |
| */ |
| daeMetaAttribute* getAttributeObject(size_t i); |
| |
| /** |
| * Returns the name of the attribute at the specified index. |
| * @param i The index of the attribute whose name should be retrieved. |
| * @return Returns the name of the attribute, or "" if the index is out of range. |
| */ |
| std::string getAttributeName(size_t i); |
| |
| /** |
| * Checks if this element can have the attribute specified. |
| * @param name The name of the attribute to look for. |
| * @return Returns true is this element can have an attribute with the name specified. False otherwise. |
| */ |
| daeBool hasAttribute(daeString name); |
| |
| /** |
| * Checks if an attribute has been set either by being loaded from the COLLADA document or set |
| * programmatically. |
| * @param name The name of the attribute to check. |
| * @return Returns true if the attribute has been set. False if the attribute hasn't been set |
| * or doesn't exist for this element. |
| */ |
| daeBool isAttributeSet(daeString name); |
| |
| /** |
| * Gets an attribute's value as a string. |
| * @param name The name of the attribute. |
| * @return The value of the attribute. Returns an empty string if this element doesn't |
| * have the specified attribute. |
| */ |
| std::string getAttribute(daeString name); |
| |
| /** |
| * Just like the previous method, this method gets an attribute's value as a string. It |
| * takes the string as a reference parameter instead of returning it, for extra efficiency. |
| * @param name The name of the attribute. |
| * @param A string in which to store the value of the attribute. This will be set to an empty |
| * string if this element doesn't have the specified attribute. |
| */ |
| void getAttribute(daeString name, std::string& value); |
| |
| /** |
| * Gets an attribute's value as a string. |
| * @param i The index of the attribute to retrieve. |
| * @return The value of the attribute. |
| */ |
| std::string getAttribute(size_t i); |
| |
| /** |
| * Just like the previous method, this method gets an attribute's value as a string. It |
| * takes the string as a reference parameter instead of returning it, for extra efficiency. |
| * @param i The index of the attribute to retrieve. |
| * @param A string in which to store the value of the attribute. |
| */ |
| void getAttribute(size_t i, std::string& value); |
| |
| struct DLLSPEC attr { |
| attr(); |
| attr(const std::string& name, const std::string& value); |
| |
| std::string name; |
| std::string value; |
| }; |
| |
| /** |
| * Returns an array containing all the attributes of this element. |
| * @return A daeArray of attr objects. |
| */ |
| daeTArray<attr> getAttributes(); |
| |
| /** |
| * Just like the previous method, this method returns an array containing all the attributes |
| * of this element. It returns the result via a reference parameter for extra efficiency. |
| * @param attrs The array of attr objects to return. |
| */ |
| void getAttributes(daeTArray<attr>& attrs); |
| |
| /** |
| * Sets the attribute to the specified value. |
| * @param name Attribute to set. |
| * @param value Value to apply to the attribute. |
| * @return Returns true if the attribute was found and the value was set, false otherwise. |
| */ |
| virtual daeBool setAttribute(daeString name, daeString value); |
| |
| /** |
| * Sets the attribute at the specified index to the given value. |
| * @param i Index of the attribute to set. |
| * @param value Value to apply to the attribute. |
| * @return Returns true if the attribute was found and the value was set, false otherwise. |
| */ |
| virtual daeBool setAttribute(size_t i, daeString value); |
| |
| /** |
| * Returns the daeMetaAttribute object corresponding to the character data for this element. |
| * @return Returns a daeMetaAttribute object or NULL if this element doesn't have |
| * character data. |
| */ |
| daeMetaAttribute* getCharDataObject(); |
| |
| /** |
| * Checks if this element can have character data. |
| * @return Returns true if this element can have character data, false otherwise. |
| */ |
| daeBool hasCharData(); |
| |
| /** |
| * Returns this element's character data as a string. |
| * @return A string containing this element's character data, or an empty string |
| * if this element can't have character data. |
| */ |
| std::string getCharData(); |
| |
| /** |
| * Similar to the previous method, but fills a string passed in by the user for efficiency. |
| * @param data The string to be filled with this element's character content. The |
| * string is set to an empty string if this element can't have character data. |
| */ |
| void getCharData(std::string& data); |
| |
| /** |
| * Sets this element's character data. |
| * @param data The new character data of this element. |
| * @return Returns true if this element can have character data and the character data |
| * was successfully changed, false otherwise. |
| */ |
| daeBool setCharData(const std::string& data); |
| |
| // These functions are deprecated. |
| daeMemoryRef getAttributeValue(daeString name); // Use getAttribute or getAttributeObject instead. |
| daeBool hasValue(); // Use hasCharData instead. |
| daeMemoryRef getValuePointer(); // Use getCharData or getCharDataObject instead. |
| |
| /** |
| * Finds the database document associated with @c this element. |
| * @return Returns the @c daeDocument representing the containing file or database |
| * group. |
| */ |
| daeDocument* getDocument() const { return _document; } |
| |
| /** |
| * Deprecated. |
| */ |
| daeDocument* getCollection() const { return _document; } |
| |
| /** |
| * Get the associated DAE object. |
| * @return The associated DAE object. |
| */ |
| DAE* getDAE(); |
| |
| /** |
| * Sets the database document associated with this element. |
| * @param c The daeDocument to associate with this element. |
| */ |
| void setDocument(daeDocument* c) { setDocument( c, true ); } |
| /** |
| * Deprecated. |
| */ |
| void setCollection(daeDocument* c ); |
| |
| /** |
| * Gets the URI of the document containing this element, note that this is NOT the URI of the element. |
| * @return Returns a pointer to the daeURI of the document containing this element. |
| */ |
| daeURI* getDocumentURI() const; |
| |
| /** |
| * Creates an element via the element factory system. This creation |
| * is based @em only on potential child elements of this element. |
| * @param elementName Class name of the subelement to create. |
| * @return Returns the created @c daeElement, if it was successfully created. |
| */ |
| daeSmartRef<daeElement> createElement(daeString elementName); |
| |
| /** |
| * Gets the container element for @c this element. |
| * If @c createAndPlace() was used to create the element, its parent is the the caller of @c createAndPlace(). |
| * @return Returns the parent element, if @c this is not the top level element. |
| */ |
| daeElement* getParentElement() { return _parent;} |
| /** |
| * Deprecated. Use getParentElement() |
| * @deprecated |
| */ |
| daeElement* getXMLParentElement() { return _parent;} |
| /** |
| * Sets the parent element for this element. |
| * @param newParent The element which is the new parent element for this element. |
| * @note This function is called internally and not meant to be called form the client application. |
| */ |
| void setParentElement( daeElement *parent ) { _parent = parent; } |
| |
| // These are helper structures to let the xml hierarchy search functions know when we've |
| // found a match. You can implement a custom matcher by inheriting from this structure, |
| // just like matchName and matchType. |
| struct DLLSPEC matchElement { |
| virtual bool operator()(daeElement* elt) const = 0; |
| virtual ~matchElement() { }; |
| }; |
| |
| // Matches an element by name |
| struct DLLSPEC matchName : public matchElement { |
| matchName(daeString name); |
| virtual bool operator()(daeElement* elt) const; |
| std::string name; |
| }; |
| |
| // Matches an element by schema type |
| struct DLLSPEC matchType : public matchElement { |
| matchType(daeInt typeID); |
| virtual bool operator()(daeElement* elt) const; |
| daeInt typeID; |
| }; |
| |
| // Returns a matching child element. By "child", I mean one hierarchy level beneath the |
| // current element. This function is basically the same as getDescendant, except that it |
| // only goes one level deep. |
| daeElement* getChild(const matchElement& matcher); |
| |
| // Performs a breadth-first search and returns a matching descendant element. A "descendant |
| // element" is an element beneath the current element in the xml hierarchy. |
| daeElement* getDescendant(const matchElement& matcher); |
| |
| // Returns the parent element. |
| daeElement* getParent(); |
| |
| // Searches up through the xml hiearchy and returns a matching element. |
| daeElement* getAncestor(const matchElement& matcher); |
| |
| // These functions perform the same as the functions above, except that they take the element |
| // name to match as a string. This makes these functions a little simpler to use if you're |
| // matching based on element name, which is assumed to be the most common case. Instead of |
| // "getChild(matchName(eltName))", you can just write "getChild(eltName)". |
| daeElement* getChild(daeString eltName); |
| daeElement* getDescendant(daeString eltName); |
| daeElement* getAncestor(daeString eltName); |
| |
| /** |
| * Gets the associated Meta information for this element. This |
| * Meta also acts as a factory. See @c daeMetaElement documentation for more |
| * information. |
| * @return Returns the associated meta information. |
| */ |
| inline daeMetaElement* getMeta() { return _meta; } |
| |
| // These functions are deprecated. Use typeID instead. |
| virtual COLLADA_TYPE::TypeEnum getElementType() const { return (COLLADA_TYPE::TypeEnum)0; } |
| daeString getTypeName() const; |
| |
| /** |
| * Returns this element's type ID. Every element is an instance of a type specified in |
| * the Collada schema, and every schema type has a unique ID. |
| * @return The element's type ID. |
| */ |
| virtual daeInt typeID() const = 0; |
| |
| /** |
| * Gets this element's name. |
| * @return Returns the string for the name. |
| * @remarks This function returns NULL if the element's name is identical to it's type's name. |
| */ |
| daeString getElementName() const; |
| /** |
| * Sets this element's name. |
| * @param nm Specifies the string to use as the element's name. |
| * @remarks Use caution when using this function since you can easily create invalid COLLADA documents. |
| */ |
| void setElementName( daeString nm ); |
| |
| /** |
| * Gets the element ID if it exists. |
| * @return Returns the value of the ID attribute, if there is such |
| * an attribute on this element type. |
| * @return the string for the element ID if it exists. |
| */ |
| daeString getID() const; |
| |
| /** |
| * Gets the children/sub-elements of this element. |
| * This is a helper function used to easily access an element's children without the use of the |
| * _meta objects. This function adds the convenience of the _contents array to elements that do |
| * not contain a _contents array. |
| * @return The return value. An elementref array to append this element's children to. |
| */ |
| daeTArray< daeSmartRef<daeElement> > getChildren(); |
| |
| /** |
| * Same as the previous function, but returns the result via a parameter instead |
| * of a return value, for extra efficiency. |
| * @param array The return value. An elementref array to append this element's children to. |
| */ |
| //void getChildren( daeElementRefArray &array ); |
| void getChildren( daeTArray<daeSmartRef<daeElement> > &array ); |
| |
| /** |
| * Gets all the children of a particular type. |
| * @return An array containing the matching child elements. |
| */ |
| template<typename T> |
| daeTArray< daeSmartRef<T> > getChildrenByType() { |
| daeTArray< daeSmartRef<T> > result; |
| getChildrenByType(result); |
| return result; |
| } |
| |
| /** |
| * Same as the previous function, but returns the result via a parameter instead |
| * of a return value, for extra efficiency. |
| * @return An array containing the matching child elements. |
| */ |
| template<typename T> |
| void getChildrenByType(daeTArray< daeSmartRef<T> >& matchingChildren) { |
| matchingChildren.setCount(0); |
| daeTArray< daeSmartRef<daeElement> > children; |
| getChildren(children); |
| for (size_t i = 0; i < children.getCount(); i++) |
| if (children[i]->typeID() == T::ID()) |
| matchingChildren.append((T*)children[i].cast()); |
| } |
| |
| /** |
| * Clones/deep copies this @c daeElement and all of it's subtree. |
| * @param idSuffix A string to append to the copied element's ID, if one exists. |
| * Default is no ID mangling. |
| * @param nameSuffix A string to append to the copied element's name, if one exists. |
| * Default is no name mangling. |
| * @return Returns a @c daeElement smartref of the copy of this element. |
| */ |
| daeSmartRef<daeElement> clone( daeString idSuffix = NULL, daeString nameSuffix = NULL ); |
| |
| // Class for reporting info about element comparisons |
| struct DLLSPEC compareResult { |
| int compareValue; // > 0 if elt1 > elt2, |
| // < 0 if elt1 < elt2, |
| // = 0 if elt1 = elt2 |
| daeElement* elt1; |
| daeElement* elt2; |
| bool nameMismatch; // true if the names didn't match |
| std::string attrMismatch; // The name of the mismatched attribute, or "" if there was no attr mismatch |
| bool charDataMismatch; // true if the char data didn't match |
| bool childCountMismatch; // true if the number of children didn't match |
| |
| compareResult(); |
| std::string format(); // Write to a string |
| }; |
| |
| // Function for doing a generic, recursive comparison of two xml elements. It |
| // also provides a full element ordering, so that you could store elements in |
| // a map or a set. Return val is > 0 if elt1 > elt2, < 0 if elt1 < elt2, and 0 |
| // if elt1 == elt2. |
| static int compare(daeElement& elt1, daeElement& elt2); |
| |
| // Same as the previous function, but returns a full compareResult object. |
| static compareResult compareWithFullResult(daeElement& elt1, daeElement& elt2); |
| |
| /** |
| * Sets the user data pointer attached to this element. |
| * @param data User's custom data to store. |
| */ |
| void setUserData(void* data); |
| |
| /** |
| * Gets the user data pointer attached to this element. |
| * @return User data pointer previously set with setUserData. |
| */ |
| void* getUserData(); |
| |
| public: |
| // This function is called internally |
| static void deleteCMDataArray(daeTArray<daeCharArray*>& cmData); |
| }; |
| |
| #include <dae/daeSmartRef.h> |
| typedef daeSmartRef<daeElement> daeElementRef; |
| typedef daeSmartRef<const daeElement> daeElementConstRef; |
| //#include <dae/daeArray.h> |
| typedef daeTArray<daeElementRef> daeElementRefArray; |
| |
| #endif //__DAE_ELEMENT_H__ |