/***************************************************************************** * * Copyright (c) 2000 - 2007, The Regents of the University of California * Produced at the Lawrence Livermore National Laboratory * All rights reserved. * * This file is part of VisIt. For details, see http://www.llnl.gov/visit/. The * full copyright notice is contained in the file COPYRIGHT located at the root * of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the disclaimer below. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the disclaimer (as noted below) in the * documentation and/or materials provided with the distribution. * - Neither the name of the UC/LLNL nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF * CALIFORNIA, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * *****************************************************************************/ #include #include namespace pointsprite { // Static members. These are returned from the As functions when there // is no data. It ensures that the references that are returned are safe. std::string DataNode::bogusString; charVector DataNode::bogusCharVector; unsignedCharVector DataNode::bogusUnsignedCharVector; intVector DataNode::bogusIntVector; longVector DataNode::bogusLongVector; floatVector DataNode::bogusFloatVector; doubleVector DataNode::bogusDoubleVector; stringVector DataNode::bogusStringVector; // **************************************************************************** // Method: DataNode::DataNode // // Purpose: // These are the constructors for the DataNode class. There is one // constructor for each type of node. // // Programmer: Brad Whitlock // Creation: Thu Sep 28 12:22:58 PDT 2000 // // Modifications: // Jeremy Meredith, Mon Feb 26 16:01:24 PST 2001 // Added unsigned chars. // // **************************************************************************** DataNode::DataNode(const std::string &name) : Key(name) { NodeType = INTERNAL_NODE; Length = 0; Data = 0; } DataNode::DataNode(const std::string &name, char val) : Key(name) { NodeType = CHAR_NODE; Length = 0; Data = (void *)(new char(val)); } DataNode::DataNode(const std::string &name, unsigned char val) : Key(name) { NodeType = UNSIGNED_CHAR_NODE; Length = 0; Data = (void *)(new unsigned char(val)); } DataNode::DataNode(const std::string &name, int val) : Key(name) { NodeType = INT_NODE; Length = 0; Data = (void *)(new int(val)); } DataNode::DataNode(const std::string &name, long val) : Key(name) { NodeType = LONG_NODE; Length = 0; Data = (void *)(new long(val)); } DataNode::DataNode(const std::string &name, float val) : Key(name) { NodeType = FLOAT_NODE; Length = 0; Data = (void *)(new float(val)); } DataNode::DataNode(const std::string &name, double val) : Key(name) { NodeType = DOUBLE_NODE; Length = 0; Data = (void *)(new double(val)); } DataNode::DataNode(const std::string &name, const std::string &val) : Key(name) { NodeType = STRING_NODE; Length = 0; Data = (void *)(new std::string(val)); } DataNode::DataNode(const std::string &name, bool val) : Key(name) { NodeType = BOOL_NODE; Length = 0; Data = (void *)(new bool(val)); } DataNode::DataNode(const std::string &name, const char *vals, int len) : Key(name) { NodeType = CHAR_ARRAY_NODE; Length = len; if(len > 0) { Data = (void *)(new char[len]); memcpy(Data, (void *)vals, len * sizeof(char)); } else Data = 0; } DataNode::DataNode(const std::string &name, const unsigned char *vals, int len) : Key(name) { NodeType = UNSIGNED_CHAR_ARRAY_NODE; Length = len; if(len > 0) { Data = (void *)(new unsigned char[len]); memcpy(Data, (void *)vals, len * sizeof(unsigned char)); } else Data = 0; } DataNode::DataNode(const std::string &name, const int *vals, int len) : Key(name) { NodeType = INT_ARRAY_NODE; Length = len; if(len > 0) { Data = (void *)(new int[len]); memcpy(Data, (void *)vals, len * sizeof(int)); } else Data = 0; } DataNode::DataNode(const std::string &name, const long *vals, int len) : Key(name) { NodeType = LONG_ARRAY_NODE; Length = len; if(len > 0) { Data = (void *)(new long[len]); memcpy(Data, (void *)vals, len * sizeof(long)); } else Data = 0; } DataNode::DataNode(const std::string &name, const float *vals, int len) : Key(name) { NodeType = FLOAT_ARRAY_NODE; Length = len; if(len > 0) { Data = (void *)(new float[len]); memcpy(Data, (void *)vals, len * sizeof(float)); } else Data = 0; } DataNode::DataNode(const std::string &name, const double *vals, int len) : Key(name) { NodeType = DOUBLE_ARRAY_NODE; Length = len; if(len > 0) { Data = (void *)(new double[len]); memcpy(Data, (void *)vals, len * sizeof(double)); } else Data = 0; } DataNode::DataNode(const std::string &name, const std::string *vals, int len) : Key(name) { NodeType = STRING_ARRAY_NODE; Length = len; if(len > 0) { std::string *sptr = new std::string[len]; Data = (void *)sptr; for(int i = 0; i < len; ++i) sptr[i] = vals[i]; } else Data = 0; } DataNode::DataNode(const std::string &name, const bool *vals, int len) : Key(name) { NodeType = BOOL_ARRAY_NODE; Length = len; if(len > 0) { Data = (void *)(new bool[len]); memcpy(Data, (void *)vals, len * sizeof(bool)); } else Data = 0; } DataNode::DataNode(const std::string &name, const charVector &vec) : Key(name) { NodeType = CHAR_VECTOR_NODE; Length = 0; Data = (void *)(new charVector(vec)); } DataNode::DataNode(const std::string &name, const unsignedCharVector &vec) : Key(name) { NodeType = UNSIGNED_CHAR_VECTOR_NODE; Length = 0; Data = (void *)(new unsignedCharVector(vec)); } DataNode::DataNode(const std::string &name, const intVector &vec) : Key(name) { NodeType = INT_VECTOR_NODE; Length = 0; Data = (void *)(new intVector(vec)); } DataNode::DataNode(const std::string &name, const longVector &vec) : Key(name) { NodeType = LONG_VECTOR_NODE; Length = 0; Data = (void *)(new longVector(vec)); } DataNode::DataNode(const std::string &name, const floatVector &vec) : Key(name) { NodeType = FLOAT_VECTOR_NODE; Length = 0; Data = (void *)(new floatVector(vec)); } DataNode::DataNode(const std::string &name, const doubleVector &vec) : Key(name) { NodeType = DOUBLE_VECTOR_NODE; Length = 0; Data = (void *)(new doubleVector(vec)); } DataNode::DataNode(const std::string &name, const stringVector &vec) : Key(name) { NodeType = STRING_VECTOR_NODE; Length = 0; Data = (void *)(new stringVector(vec)); } // **************************************************************************** // Method: DataNode::~DataNode // // Purpose: // Destructor for the DataNode class. It frees any data that the node // has based on the type of the node. // // Programmer: Brad Whitlock // Creation: Thu Sep 28 12:22:11 PDT 2000 // // Modifications: // Jeremy Meredith, Mon Feb 26 16:01:37 PST 2001 // Added unsigned chars. // // Brad Whitlock, Fri Mar 21 10:48:13 PDT 2003 // I moved the implementation into FreeData. // // **************************************************************************** DataNode::~DataNode() { FreeData(); } // **************************************************************************** // Method: DataNode::FreeData // // Purpose: // Frees the data in the DataNode and sets the Data pointer to 0. // // Programmer: Brad Whitlock // Creation: Fri Mar 21 10:47:29 PDT 2003 // // Modifications: // // **************************************************************************** void DataNode::FreeData() { if(Data == 0) return; // Any node types that have dynamically allocated storage must // be freed specially. switch(NodeType) { case INTERNAL_NODE: { // new scope if(Length == 1) { // Delete the child. DataNode *node = (DataNode *)Data; delete node; } else if(Length > 1) { // Delete all the children DataNode **nodeArray = (DataNode **)Data; for(int i = 0; i < Length; ++i) delete nodeArray[i]; // Delete the children's pointer array if(Length > 1) delete [] nodeArray; } } break; case CHAR_NODE: { // new scope char *cptr = (char *)Data; delete cptr; } break; case UNSIGNED_CHAR_NODE: { // new scope unsigned char *uptr = (unsigned char *)Data; delete uptr; } break; case INT_NODE: { // new scope int *iptr = (int *)Data; delete iptr; } break; case LONG_NODE: { // new scope long *lptr = (long *)Data; delete lptr; } break; case FLOAT_NODE: { // new scope float *fptr = (float *)Data; delete fptr; } break; case DOUBLE_NODE: { // new scope double *dptr = (double *)Data; delete dptr; } break; case STRING_NODE: { // new scope std::string *sptr = (std::string *)Data; delete sptr; } break; case BOOL_NODE: { // new scope bool *bptr = (bool *)Data; delete bptr; } break; case CHAR_ARRAY_NODE: { // new scope char *cptr = (char *)Data; delete [] cptr; } break; case UNSIGNED_CHAR_ARRAY_NODE: { // new scope unsigned char *uptr = (unsigned char *)Data; delete [] uptr; } break; case INT_ARRAY_NODE: { // new scope int *iptr = (int *)Data; delete [] iptr; } break; case LONG_ARRAY_NODE: { // new scope long *lptr = (long *)Data; delete [] lptr; } break; case FLOAT_ARRAY_NODE: { // new scope float *fptr = (float *)Data; delete [] fptr; } break; case DOUBLE_ARRAY_NODE: { // new scope double *dptr = (double *)Data; delete [] dptr; } break; case STRING_ARRAY_NODE: { // new scope std::string *sptr = (std::string *)Data; delete [] sptr; } break; case BOOL_ARRAY_NODE: { // new scope bool *bptr = (bool *)Data; delete [] bptr; } break; case CHAR_VECTOR_NODE: { // new scope charVector *cptr = (charVector *)Data; delete cptr; } break; case UNSIGNED_CHAR_VECTOR_NODE: { // new scope unsignedCharVector *uptr = (unsignedCharVector *)Data; delete uptr; } break; case INT_VECTOR_NODE: { // new scope intVector *iptr = (intVector *)Data; delete iptr; } break; case LONG_VECTOR_NODE: { // new scope longVector *lptr = (longVector *)Data; delete lptr; } break; case FLOAT_VECTOR_NODE: { // new scope floatVector *fptr = (floatVector *)Data; delete fptr; } break; case DOUBLE_VECTOR_NODE: { // new scope doubleVector *dptr = (doubleVector *)Data; delete dptr; } break; case STRING_VECTOR_NODE: { // new scope stringVector *sptr = (stringVector *)Data; delete sptr; } break; case BOOL_VECTOR_NODE: // Do nothing since it can't be instantiated. break; } Data = 0; Length = 0; } // // Methods to return the data as a value of a certain type. // char DataNode::AsChar() const { return *((char *)Data); } unsigned char DataNode::AsUnsignedChar() const { return *((unsigned char *)Data); } int DataNode::AsInt() const { return *((int *)Data); } long DataNode::AsLong() const { return *((long *)Data); } float DataNode::AsFloat() const { float rv = 0.f; if (NodeType == FLOAT_NODE) rv = *((float *)Data); else if (NodeType == DOUBLE_NODE) rv = float(*((double *)Data)); return rv; } double DataNode::AsDouble() const { double rv = 0.; if (NodeType == DOUBLE_NODE) rv = *((double *)Data); else if (NodeType == FLOAT_NODE) rv = double(*((float*)Data)); return rv; } const std::string & DataNode::AsString() const { if(NodeType == STRING_NODE && Data != 0) return *((std::string *)Data); else return bogusString; } bool DataNode::AsBool() const { return *((bool *)Data); } const char * DataNode::AsCharArray() const { return (const char *)Data; } const unsigned char * DataNode::AsUnsignedCharArray() const { return (const unsigned char *)Data; } const int * DataNode::AsIntArray() const { return (const int *)Data; } const long * DataNode::AsLongArray() const { return (const long *)Data; } const float * DataNode::AsFloatArray() const { return (const float *)Data; } const double * DataNode::AsDoubleArray() const { return (const double *)Data; } const std::string * DataNode::AsStringArray() const { return (const std::string *)Data; } const bool * DataNode::AsBoolArray() const { return (const bool *)Data; } const charVector & DataNode::AsCharVector() const { if(NodeType == CHAR_VECTOR_NODE && Data != 0) return *((charVector *)Data); else return bogusCharVector; } const unsignedCharVector & DataNode::AsUnsignedCharVector() const { if(NodeType == UNSIGNED_CHAR_VECTOR_NODE && Data != 0) return *((unsignedCharVector *)Data); else return bogusUnsignedCharVector; } const intVector & DataNode::AsIntVector() const { if(NodeType == INT_VECTOR_NODE && Data != 0) return *((intVector *)Data); else return bogusIntVector; } const longVector & DataNode::AsLongVector() const { if(NodeType == LONG_VECTOR_NODE && Data != 0) return *((longVector *)Data); else return bogusLongVector; } const floatVector & DataNode::AsFloatVector() const { if(NodeType == FLOAT_VECTOR_NODE && Data != 0) return *((floatVector *)Data); else return bogusFloatVector; } const doubleVector & DataNode::AsDoubleVector() const { if(NodeType == DOUBLE_VECTOR_NODE && Data != 0) return *((doubleVector *)Data); else return bogusDoubleVector; } const stringVector & DataNode::AsStringVector() const { if(NodeType == STRING_VECTOR_NODE && Data != 0) return *((stringVector *)Data); else return bogusStringVector; } // // Methods to convert the DataNode to a new type with new data. // void DataNode::SetChar(char val) { FreeData(); NodeType = CHAR_NODE; Data = (void *)(new char(val)); } void DataNode::SetUnsignedChar(unsigned char val) { FreeData(); NodeType = UNSIGNED_CHAR_NODE; Data = (void *)(new unsigned char(val)); } void DataNode::SetInt(int val) { FreeData(); NodeType = INT_NODE; Data = (void *)(new int(val)); } void DataNode::SetLong(long val) { FreeData(); NodeType = LONG_NODE; Data = (void *)(new long(val)); } void DataNode::SetFloat(float val) { FreeData(); NodeType = FLOAT_NODE; Data = (void *)(new float(val)); } void DataNode::SetDouble(double val) { FreeData(); NodeType = DOUBLE_NODE; Data = (void *)(new double(val)); } void DataNode::SetString(const std::string &val) { FreeData(); NodeType = STRING_NODE; Data = (void *)(new std::string(val)); } void DataNode::SetBool(bool val) { FreeData(); NodeType = BOOL_NODE; Data = (void *)(new bool(val)); } void DataNode::SetCharArray(const char *vals, int len) { FreeData(); NodeType = CHAR_ARRAY_NODE; Length = len; if(len > 0) { Data = (void *)(new char[len]); memcpy(Data, (void *)vals, len * sizeof(char)); } else Data = 0; } void DataNode::SetUnsignedCharArray(const unsigned char *vals, int len) { FreeData(); NodeType = UNSIGNED_CHAR_ARRAY_NODE; Length = len; if(len > 0) { Data = (void *)(new unsigned char[len]); memcpy(Data, (void *)vals, len * sizeof(unsigned char)); } else Data = 0; } void DataNode::SetIntArray(const int *vals, int len) { FreeData(); NodeType = INT_ARRAY_NODE; Length = len; if(len > 0) { Data = (void *)(new int[len]); memcpy(Data, (void *)vals, len * sizeof(int)); } else Data = 0; } void DataNode::SetLongArray(const long *vals, int len) { FreeData(); NodeType = LONG_ARRAY_NODE; Length = len; if(len > 0) { Data = (void *)(new long[len]); memcpy(Data, (void *)vals, len * sizeof(long)); } else Data = 0; } void DataNode::SetFloatArray(const float *vals, int len) { FreeData(); NodeType = FLOAT_ARRAY_NODE; Length = len; if(len > 0) { Data = (void *)(new float[len]); memcpy(Data, (void *)vals, len * sizeof(float)); } else Data = 0; } void DataNode::SetDoubleArray(const double *vals, int len) { FreeData(); NodeType = DOUBLE_ARRAY_NODE; Length = len; if(len > 0) { Data = (void *)(new double[len]); memcpy(Data, (void *)vals, len * sizeof(double)); } else Data = 0; } void DataNode::SetStringArray(const std::string *vals, int len) { FreeData(); NodeType = STRING_ARRAY_NODE; Length = len; if(len > 0) { std::string *sptr = new std::string[len]; Data = (void *)sptr; for(int i = 0; i < len; ++i) sptr[i] = vals[i]; } else Data = 0; } void DataNode::SetBoolArray(const bool *vals, int len) { FreeData(); NodeType = BOOL_ARRAY_NODE; Length = len; if(len > 0) { Data = (void *)(new bool[len]); memcpy(Data, (void *)vals, len * sizeof(bool)); } else Data = 0; } void DataNode::SetCharVector(const charVector &vec) { FreeData(); NodeType = CHAR_VECTOR_NODE; Data = (void *)(new charVector(vec)); } void DataNode::SetUnsignedCharVector(const unsignedCharVector &vec) { FreeData(); NodeType = UNSIGNED_CHAR_VECTOR_NODE; Data = (void *)(new unsignedCharVector(vec)); } void DataNode::SetIntVector(const intVector &vec) { FreeData(); NodeType = INT_VECTOR_NODE; Data = (void *)(new intVector(vec)); } void DataNode::SetLongVector(const longVector &vec) { FreeData(); NodeType = LONG_VECTOR_NODE; Data = (void *)(new longVector(vec)); } void DataNode::SetFloatVector(const floatVector &vec) { FreeData(); NodeType = FLOAT_VECTOR_NODE; Data = (void *)(new floatVector(vec)); } void DataNode::SetDoubleVector(const doubleVector &vec) { FreeData(); NodeType = DOUBLE_VECTOR_NODE; Data = (void *)(new doubleVector(vec)); } void DataNode::SetStringVector(const stringVector &vec) { FreeData(); NodeType = STRING_VECTOR_NODE; Data = (void *)(new stringVector(vec)); } // **************************************************************************** // Method: DataNode::GetNode // // Purpose: // Returns a pointer to the node having the specified key. If a // parentNode is supplied, then only the children of that node are // searched. // // Arguments: // key : The name of the node to look for. // parentNode : The root of the tree to search. // // Returns: // A pointer to the node having the specified key, or 0 if the node // is not found. // // Programmer: Brad Whitlock // Creation: Thu Sep 28 12:07:56 PDT 2000 // // Modifications: // // **************************************************************************** DataNode * DataNode::GetNode(const std::string &key, DataNode *parentNode) { DataNode *searchNode, *intermediate, *retval = 0; // Determine which node's children to search. if(parentNode == 0) searchNode = this; else searchNode = parentNode; if(key == searchNode->Key) retval = searchNode; else if(searchNode->NodeType == INTERNAL_NODE) { if(searchNode->Length == 1) { DataNode *nodeArray = (DataNode *)(searchNode->Data); intermediate = GetNode(key, nodeArray); if(intermediate != 0) { retval = intermediate; } } else if(searchNode->Length > 1) { DataNode **nodeArray = (DataNode **)(searchNode->Data); for(int i = 0; i < searchNode->Length; ++i) { intermediate = GetNode(key, nodeArray[i]); if(intermediate != 0) { retval = intermediate; break; } } } } return retval; } // **************************************************************************** // Method: DataNode::AddNode // // Purpose: // Adds a child node to the current node if the current node is of // type INTERNAL_NODE. // // Arguments: // node : A pointer to the node that will be added. // // Programmer: Brad Whitlock // Creation: Thu Sep 28 12:12:38 PDT 2000 // // Modifications: // Brad Whitlock, Fri Feb 1 13:27:33 PST 2002 // Fixed a memory leak. // // **************************************************************************** void DataNode::AddNode(DataNode *node) { if(NodeType != INTERNAL_NODE || node == 0) return; int i; if(Length == 0) { Length = 1; Data = (void *)node; } else if(Length == 1) { DataNode **nodeArray = new DataNode*[2]; nodeArray[0] = (DataNode *)Data; nodeArray[1] = node; Data = (void *)nodeArray; Length = 2; } else { DataNode **nodeArray = new DataNode*[Length + 1]; DataNode **dNptr = (DataNode **)Data; for(i = 0; i < Length; ++i) nodeArray[i] = dNptr[i]; nodeArray[i] = node; delete [] dNptr; Data = (void *)nodeArray; ++Length; } } // **************************************************************************** // Method: DataNode::RemoveNode // // Purpose: // Removes the specified node if it exists under the current node. // // Arguments: // node : The node to remove. // // Programmer: Eric Brugger // Creation: Tue Mar 27 15:57:42 PDT 2007 // // Modifications: // // **************************************************************************** void DataNode::RemoveNode(DataNode *node, bool deleteNode) { if(NodeType != INTERNAL_NODE) return; if(Length < 1) return; if(Length == 1) { if((DataNode *)Data == node) { if(deleteNode) delete node; Data = 0; Length = 0; } } else { DataNode **nodeArray = (DataNode **)Data; bool start = false; for(int i = 0; i < Length; ++i) { if(!start && nodeArray[i] == node) { if(deleteNode) delete nodeArray[i]; start = true; } if(start && (i < (Length - 1))) nodeArray[i] = nodeArray[i + 1]; } if(start) { --Length; // If we're down to 1, convert to a single pointer. if(Length == 1) { DataNode *temp = nodeArray[0]; delete [] nodeArray; Data = (void *)temp; } } } } // **************************************************************************** // Method: DataNode::RemoveNode // // Purpose: // Removes the node with the specified key if it exists under the // current node. // // Arguments: // key : The key of the node to remove. // // Programmer: Brad Whitlock // Creation: Thu Sep 28 12:14:24 PDT 2000 // // Modifications: // Brad Whitlock, Mon Feb 2 15:38:05 PST 2004 // I added an optional argument to delete the node. // // **************************************************************************** void DataNode::RemoveNode(const std::string &key, bool deleteNode) { if(NodeType != INTERNAL_NODE) return; if(Length < 1) return; if(Length == 1) { DataNode *node = (DataNode *)Data; if(node->Key == key) { if(deleteNode) delete node; Data = 0; Length = 0; } } else { DataNode **nodeArray = (DataNode **)Data; bool start = false; for(int i = 0; i < Length; ++i) { if(!start && nodeArray[i]->Key == key) { if(deleteNode) delete nodeArray[i]; start = true; } if(start && (i < (Length - 1))) nodeArray[i] = nodeArray[i + 1]; } if(start) { --Length; // If we're down to 1, convert to a single pointer. if(Length == 1) { DataNode *temp = nodeArray[0]; delete [] nodeArray; Data = (void *)temp; } } } } // // Methods to get/set some of the private fields. // const std::string & DataNode::GetKey() const { return Key; } void DataNode::SetKey(const std::string &k) { Key = k; } NodeTypeEnum DataNode::GetNodeType() const { return NodeType; } int DataNode::GetLength() const { return Length; } int DataNode::GetNumChildren() const { return Length; } // **************************************************************************** // Method: DataNode::GetNumChildObjects // // Purpose: // Return the number of children that are of type INTERNAL_NODE // // Programmer: Brad Whitlock // Creation: Fri Sep 29 17:54:21 PST 2000 // // Modifications: // // **************************************************************************** int DataNode::GetNumChildObjects() const { int retval = 0; if(Length == 1) { DataNode *child = (DataNode *)Data; if(child->NodeType == INTERNAL_NODE) retval = 1; } else if(Length > 0) { DataNode **children = (DataNode **)Data; for(int i = 0; i < Length; ++i) { if(children[i]->NodeType == INTERNAL_NODE) ++retval; } } return retval; } // **************************************************************************** // Method: DataNode::GetChildren // // Purpose: // Returns an array of DataNode pointers that point to the node's // children. If there are no children, 0 is returned. // // Programmer: Brad Whitlock // Creation: Thu Sep 28 15:11:24 PST 2000 // // Modifications: // // **************************************************************************** DataNode ** DataNode::GetChildren() { if(NodeType == INTERNAL_NODE) { if(Length == 0) return 0; else if(Length == 1) return ((DataNode **)&Data); else return ((DataNode **)Data); } else return 0; } // // Enum name lookup stuff. // static const char *NodeTypeNameLookup[] = { "", "char", "unsigned char", "int", "long", "float", "double", "string", "bool", "charArray", "unsignedCharArray", "intArray", "longArray", "floatArray", "doubleArray", "stringArray", "boolArray", "charVector", "unsignedCharVector", "intVector", "longVector", "floatVector", "doubleVector", "stringVector" }; const char * NodeTypeName(NodeTypeEnum e) { return NodeTypeNameLookup[(int)e]; } // **************************************************************************** // Function: GetNodeType // // Purpose: // Converts a named type to a NodeTypeEnum. // // Returns: The NodeTypeEnum corresponding to the named type. // // Programmer: Brad Whitlock // Creation: Mon Jun 18 23:30:52 PST 2001 // // Modifications: // // **************************************************************************** NodeTypeEnum GetNodeType(const char *str) { bool found = false; int retval = 0; for(int i = 1; i < 24 && !found; ++i) { found = (strcmp(str, NodeTypeNameLookup[i]) == 0); if(found) retval = i; } return (NodeTypeEnum)retval; } }