/* xbexpnode.cpp
XBase64 Software Library
Copyright (c) 1997,2003,2014,2017,2022,2023 Gary A Kunkel
The xb64 software library is covered under
the terms of the GPL Version 3, 2007 license.
Email Contact:
XDB-devel@lists.sourceforge.net
XDB-users@lists.sourceforge.net
*/
#include "xbase.h"
#ifdef XB_EXPRESSION_SUPPORT
namespace xb{
/************************************************************************/
//! @brief Constructor
xbExpNode::xbExpNode(){
sNodeText = "";
cReturnType = 0;
cNodeType = 0;
dResult = 0;
iFieldNo = 0;
ulResultLen = 0;
iWeight = 0;
nParent = NULL;
dbf = NULL;
}
/************************************************************************/
//! @brief Constructor
/*!
\param sNodeText Node text.
\param cReturnType Return type.
\param cNodeType Node type.
*/
xbExpNode::xbExpNode( xbString &sNodeText, char cReturnType, char cNodeType ){
this->sNodeText = sNodeText;
this->cReturnType = cReturnType;
this->cNodeType = cNodeType;
dResult = 0;
iFieldNo = 0;
ulResultLen = 0;
iWeight = 0;
nParent = NULL;
dbf = NULL;
}
/************************************************************************/
//! @brief Constructor
/*!
\param sNodeText Node text.
\param cNodeType Node type.
*/
xbExpNode::xbExpNode( xbString &sNodeText, char cNodeType ){
this->sNodeText = sNodeText;
this->cReturnType = 0x00;
this->cNodeType = cNodeType;
dResult = 0;
iFieldNo = 0;
ulResultLen = 0;
iWeight = 0;
nParent = NULL;
dbf = NULL;
}
/************************************************************************/
//! @brief Constructor
/*!
\param cNodeType Node type.
*/
xbExpNode::xbExpNode( char cNodeType ){
this->cReturnType = 0x00;
this->cNodeType = cNodeType;
dResult = 0;
iFieldNo = 0;
ulResultLen = 0;
iWeight = 0;
nParent = NULL;
dbf = NULL;
}
/************************************************************************/
//! @brief Deconstructor
xbExpNode::~xbExpNode(){
xbExpNode * n;
while( llChildren.GetNodeCnt() > 0 ){
llChildren.RemoveFromFront( n );
delete n;
}
}
/************************************************************************/
//! @brief Add child node to linked list.
/*!
\param n Pointer to node to add to linked list.
\returns Return Codes
*/
xbInt16 xbExpNode::AddChild( xbExpNode *n ){
n->SetParent( this );
return llChildren.InsertAtEnd( n );
}
/************************************************************************/
#ifdef XB_DEBUG_SUPPORT
//! @brief Dump Node.
/*!
\param iOption xbTrue - Print child info if they exist.
xbFalse - Don't print child info.
\returns void.
*/
void xbExpNode::DumpNode( xbInt16 iOption ) const {
xbString sMsg;
std::cout << "Me=[" << this << "] ";
if( nParent )
std::cout << "Par=[" << nParent << "] ";
std::cout << "nTyp=[" << cNodeType << "] ";
std::cout << "dTyp=[" << cReturnType << "] ";
if( iWeight != 0 )
std::cout << "W=[" << iWeight << "] ";
if( cNodeType == XB_EXP_FIELD )
std::cout << "FieldNo=[" << iFieldNo << "] ";
std::cout << "Txt=[" << sNodeText << "] ";
if( sResult != "" )
std::cout << "sVal=[" << sResult << "] ";
if( ulResultLen > 0 )
std::cout << "Len=[" << ulResultLen << "] ";
if( cReturnType == XB_EXP_DATE ){
xbDate d( (xbInt32) dResult );
std::cout << "dtVal=[" << d.Str() << "] ";
}
if( cReturnType == XB_EXP_DATE || cReturnType == XB_EXP_NUMERIC ){
sMsg.Sprintf( "dVal=[%f]\n", dResult );
std::cout << sMsg.Str();
}
if( cReturnType == XB_EXP_LOGICAL ){
sMsg.Sprintf( "lVal=[%d]\n", (xbInt32) dResult );
std::cout << sMsg.Str();
}
if( iOption ){
xbLinkListNode *lln = llChildren.GetHeadNode();
xbExpNode *n;
if( lln ){
std::cout << " Children: ";
while( lln ){
n = lln->GetKey();
std::cout << " [" << n << "]";
lln = lln->GetNextNode();
}
std::cout << std::endl;
lln = llChildren.GetHeadNode();
while( lln ){
n = lln->GetKey();
n->DumpNode( iOption );
lln = lln->GetNextNode();
}
}
}
std::cout << std::endl;
}
#endif
/************************************************************************/
//! @brief Get boolean result.
/*!
\returns Boolean result.
*/
xbBool xbExpNode::GetBoolResult() const {
return (xbBool) dResult;
}
/************************************************************************/
//! @brief Get pointer to child.
/*!
\param ulChildNo - Which child? 1,2 or3
\returns Pointer to child node or null if none exists.
*/
xbExpNode *xbExpNode::GetChild( xbUInt32 ulChildNo ) const {
xbLinkListNode *lln = llChildren.GetNodeForNo( ulChildNo );
if( lln )
return lln->GetKey();
else
return 0x00;
}
/************************************************************************/
//! @brief Get child count.
/*!
\returns Child count.
*/
xbUInt32 xbExpNode::GetChildCnt() const{
return llChildren.GetNodeCnt();
}
/************************************************************************/
//! @brief Get the current child number for this node.
/*!
\returns Child number: 1, 2 or 3.
*/
xbUInt32 xbExpNode::GetChildNo() const {
if( !nParent )
return 0;
for( xbUInt32 i = 0; i < nParent->GetChildCnt(); i++ ){
if( this == nParent->GetChild( i )){
// std::cout << "get child no [" << this << "][" << nParent->GetChild(i) << "]\n";
return i;
}
}
return 0;
}
/************************************************************************/
//! @brief Get the dbf pointer.
/*!
\returns Pointer to dbf.
*/
xbDbf *xbExpNode::GetDbf() const {
return dbf;
}
/************************************************************************/
//! @brief Get the field number.
/*!
\returns Field number for field node.
*/
xbInt16 xbExpNode::GetFieldNo() const {
return iFieldNo;
}
/*************************************************************************/
//! @brief Get the first node.
/*!
\returns Pointer to left most child node or *this if childless.
*/
xbExpNode *xbExpNode::GetFirstNode() {
xbExpNode *n = this;
while( n && n->GetChildCnt() > 0 )
n = n->GetChild(0);
return n;
}
/*************************************************************************/
//! @brief Get the next node.
/*!
\returns Pointer to right node or parent if right node does not exist.
*/
xbExpNode *xbExpNode::GetNextNode() const {
if( HasRightSibling())
return GetRightSibling()->GetFirstNode();
else
return nParent;
}
/************************************************************************/
//! @brief Get the node text.
/*!
\param sOutText Output string containing node text.
\returns void
*/
void xbExpNode::GetNodeText( xbString &sOutText ) const{
sOutText = sNodeText;
}
/************************************************************************/
//! @brief Get the node type.
/*!
\returns Node type.
*/
char xbExpNode::GetNodeType() const{
return cNodeType;
}
/************************************************************************/
//! @brief Get numeric result.
/*!
\returns Numeric result.
*/
xbDouble xbExpNode::GetNumericResult() const {
return dResult;
}
/************************************************************************/
//! @brief Get parent.
/*!
\returns Pointer to parent node.
*/
xbExpNode *xbExpNode::GetParent() const{
return nParent;
}
/************************************************************************/
//! @brief Get result length.
/*!
\returns Result length.
*/
xbUInt32 xbExpNode::GetResultLen() const{
return ulResultLen;
}
/************************************************************************/
//! @brief Get result type.
/*!
\returns Result type.
*/
char xbExpNode::GetReturnType() const{
return cReturnType;
}
/*************************************************************************/
//! @brief Get right sibling.
/*!
\returns Pointer to right sibling.
*/
xbExpNode *xbExpNode::GetRightSibling() const {
xbExpNode * nParent;
if(( nParent = GetParent()) == NULL )
return NULL;
if( nParent->GetChildCnt() <= 0 )
return NULL;
xbUInt32 ulChildNo = GetChildNo();
if( ulChildNo < (nParent->GetChildCnt() - 1))
return nParent->GetChild( ulChildNo + 1 );
else
return NULL;
}
/************************************************************************/
//! @brief Get string result.
/*!
\returns String result.
*/
xbString &xbExpNode::GetStringResult(){
return sResult;
}
/************************************************************************/
//! @brief Get node weight.
/*!
Each node is assigned a weight used internally to detmerine processing sequence.
\returns Node weight.
*/
xbInt16 xbExpNode::GetWeight() const {
return iWeight;
}
/*************************************************************************/
//! @brief Determine if node has a right sibling.
/*!
\returns xbTrue - Node has right sibling.
xbFalse - Node has no right sibling.
*/
xbBool xbExpNode::HasRightSibling() const {
// std::cout << "in HasRightSibling [" << sNodeText << "]\n";
if( nParent == NULL )
return xbFalse;
xbUInt32 ulChildNo = GetChildNo();
if( ulChildNo < (nParent->GetChildCnt() - 1)){
// std::cout << "Has Right Sibling = " << iChildNo << "] of [" << nParent->GetChildCnt() << "]\n";
return xbTrue;
}
else
return xbFalse;
}
/*************************************************************************/
//! @brief Determine if node is an operator.
/*!
\returns xbTrue - Node is an operator.
xbFalse - Node is not an operator.
*/
xbBool xbExpNode::IsOperator() const {
if( cNodeType == XB_EXP_OPERATOR )
return xbTrue;
else
return xbFalse;
}
/*************************************************************************/
//! @brief Determine if node is a unary operator.
/*!
\returns xbTrue - Node is a unary operator.
xbFalse - Node is not a unary operator.
*/
xbBool xbExpNode::IsUnaryOperator() const {
if( cNodeType == XB_EXP_PRE_OPERATOR || cNodeType == XB_EXP_POST_OPERATOR )
return xbTrue;
else if( cNodeType == XB_EXP_OPERATOR && (sNodeText == ".NOT." || sNodeText == "NOT" ))
return xbTrue;
else
return xbFalse;
}
/************************************************************************/
//! @brief Remove last child from node.
/*!
\returns void.
*/
void xbExpNode::RemoveLastChild(){
xbExpNode *n;
llChildren.RemoveFromEnd( n );
}
/************************************************************************/
//! @brief Set dbf info on node.
/*!
\param dbf Pointer to dbf.
\param iFieldNo Field number of field.
\returns void.
*/
void xbExpNode::SetDbfInfo( xbDbf *dbf, xbInt16 iFieldNo ){
this->dbf = dbf;
this->iFieldNo = iFieldNo;
}
/************************************************************************/
//! @brief Set dbf info on node.
/*!
\param dbf Pointer to dbf.
\returns void.
*/
void xbExpNode::SetDbfInfo( xbDbf *dbf ){
this->dbf = dbf;
}
/************************************************************************/
//! @brief Set node type.
/*!
\param cNodeType Node type.
\returns void.
*/
void xbExpNode::SetNodeType( char cNodeType ){
this->cNodeType = cNodeType;
}
/************************************************************************/
//! @brief Set node text.
/*!
\param sNodeText Node text.
\returns void.
*/
void xbExpNode::SetNodeText( xbString & sNodeText ){
this->sNodeText = sNodeText;
}
/************************************************************************/
//! @brief Set parent.
/*!
\param n Pointer to parent.
\returns void.
*/
void xbExpNode::SetParent( xbExpNode *n ){
this->nParent = n;
}
/************************************************************************/
//! @brief Set date result.
/*!
\param dtResult Date result.
\returns void.
*/
void xbExpNode::SetResult( xbDate &dtResult ){
this->dResult = dtResult.JulianDays();
}
/************************************************************************/
//! @brief Set boolean result.
/*!
\param bResult Boolean result.
\returns void.
*/
void xbExpNode::SetResult( xbBool bResult ){
this->dResult = bResult;
}
/************************************************************************/
//! @brief Set numeric result.
/*!
\param dResult Double numeric result.
\returns void.
*/
void xbExpNode::SetResult( xbDouble dResult ){
this->dResult = dResult;
}
/************************************************************************/
//! @brief Set string result.
/*!
\param sResult String result.
\returns void.
*/
void xbExpNode::SetResult( xbString &sResult ){
this->sResult = sResult;
}
/************************************************************************/
//! @brief Set result length.
/*!
\param ulResultLen Set result length.
\returns void.
*/
void xbExpNode::SetResultLen( xbUInt32 ulResultLen ){
this->ulResultLen = ulResultLen;
}
/************************************************************************/
//! @brief Set return type.
/*!
\param cReturnType Return Type.
\returns void.
*/
void xbExpNode::SetReturnType( char cReturnType ){
this->cReturnType = cReturnType;
}
/************************************************************************/
//! @brief Set weight.
/*!
\param iWeight Weight to set this node at.
\returns void.
*/
void xbExpNode::SetWeight( xbInt16 iWeight ){
this->iWeight = iWeight;
}
/*************************************************************************/
}; // namespace
#endif // XB_EXPRESSION_SUPPORT
/*************************************************************************/