Files
ThirdParty-6/ParaView-5.0.1/Plugins/PointSprite/Qvis/DataNode.cpp

1330 lines
30 KiB
C++

/*****************************************************************************
*
* 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 <string.h>
#include <DataNode.h>
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;
}
}