mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
1330 lines
30 KiB
C++
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;
|
|
}
|
|
}
|