/* * e4node.cpp -- * * Implementation of the e4_Node class defined in e4graph.h. * * Authors: Jacob Levy and Jean-Claude Wippler. * jyl@best.com jcw@equi4.com * * Copyright (c) 2000-2003, JYL Software Inc. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE, EVEN IF * JYL SOFTWARE INC. IS MADE AWARE OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "e4graphimpl.h" /* * This instance of e4_Node can be used (by assigning it to fields or * variables of type e4_Node) to remove remaining references to instances * that you want to discard. Especially useful for removing remaining * references in malloc'ed memory. */ e4_Node const invalidNode; /* * Default constructor: */ e4_Node::e4_Node() : e4_RefCount() {} /* * Constructor which assigns a value to the the implementation pointer. */ e4_Node::e4_Node(e4_NodeImpl *ip) : e4_RefCount(ip) {} /* * Copying constructor: */ e4_Node::e4_Node(const e4_Node &referrer) : e4_RefCount(referrer) {} /* * Copying constructor that's given an e4_RefCount: */ e4_Node::e4_Node(const e4_RefCount &referrer) : e4_RefCount(referrer) { if ((impl != NULL) && (impl->Kind() != E4_RKNODE)) { (void) e4_RefCount::operator=(invalidNode); } } /* * Assignment operator: */ e4_Node & e4_Node::operator=(const e4_Node &referrer) { return (e4_Node &) e4_RefCount::operator=(referrer); } /* * How many vertices are there in this node? */ int e4_Node::VertexCount() const { if (impl == NULL) { return 0; } return ((e4_NodeImpl *) impl)->VertexCount(); } /* * How many vertices in this node have the given name? */ int e4_Node::VertexCountWithName(const char *name) const { if (impl == NULL) { return 0; } return ((e4_NodeImpl *) impl)->VertexCountWithName(name); } /* * How many vertices in this node have the given type? */ int e4_Node::VertexCountWithType(e4_VertexType type) const { if (impl == NULL) { return 0; } return ((e4_NodeImpl *) impl)->VertexCountWithType(type); } /* * How many vertices in this node have the given value? */ int e4_Node::VertexCountWithValue(const e4_Value &v) const { if (impl == NULL) { return 0; } return ((e4_NodeImpl *) impl)->VertexCountWithValue(v); } /* * Operations to set values into existing vertices in this node. */ bool e4_Node::SetNthVertex(const char *nm, int nth, int i) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->SetNthVertex(nm, nth, i); } bool e4_Node::SetNthVertex(const char *nm, int nth, double f) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->SetNthVertex(nm, nth, f); } bool e4_Node::SetNthVertex(const char *nm, int nth, const char *s) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->SetNthVertex(nm, nth, s); } bool e4_Node::SetNthVertex(const char *nm, int nth, const void *b, int nb) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->SetNthVertex(nm, nth, b, nb); } /* * Set the nth vertex with a given name to a given node. */ bool e4_Node::SetNthVertex(const char *nm, int nth, e4_Node n) const { e4_Storage myStorage, childStorage; if ((impl == NULL) || (!n.IsValid())) { return false; } if ((!GetStorage(myStorage)) || (!n.GetStorage(childStorage))) { return false; } if (myStorage != childStorage) { return false; } return ((e4_NodeImpl *) impl)->SetNthVertexToNode(nm, nth, n.GetRawUniqueID()); } /* * Set the nth vertex with a given name to the value encapsulated in * the given e4_Value. */ bool e4_Node::SetNthVertex(const char *nm, int nth, const e4_Value &v) const { switch (v.vertexType) { case E4_VTNODE: return SetNthVertex(nm, nth, v.n); case E4_VTINT: return SetNthVertex(nm, nth, v.u.i); case E4_VTDOUBLE: return SetNthVertex(nm, nth, v.u.d); case E4_VTSTRING: return SetNthVertex(nm, nth, v.u.s); case E4_VTBINARY: return SetNthVertex(nm, nth, v.u.b.bytes, v.u.b.nbytes); default: return false; } } /* * Set the nth vertex with a given name to a new sub-node and return the * new sub-node. */ bool e4_Node::SetNthNode(const char *nm, int nth, e4_Node &n) const { e4_NodeImpl *nnip; if (impl == NULL) { return false; } nnip = ((e4_NodeImpl *) impl)->SetNthNode(nm, nth); if (nnip == NULL) { return false; } e4_Node nn(nnip); /* * Decrement the refcount to offset the artificially incremented refcount * for protection during callbacks. */ nnip->DecrRefCount(); n = nn; return true; } /* * Operations to set values into existing vertices identified by rank. */ bool e4_Node::SetVertexByRank(int rank, int i) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->SetVertexByRank(rank, i); } bool e4_Node::SetVertexByRank(int rank, double f) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->SetVertexByRank(rank, f); } bool e4_Node::SetVertexByRank(int rank, const char *s) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->SetVertexByRank(rank, s); } bool e4_Node::SetVertexByRank(int rank, const void *b, int nb) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->SetVertexByRank(rank, b, nb); } /* * Set the vertex identified by the given rank to the given node. */ bool e4_Node::SetVertexByRank(int rank, e4_Node n) const { e4_Storage myStorage, childStorage; if ((impl == NULL) || (!n.IsValid())) { return false; } if ((!GetStorage(myStorage)) || (!n.GetStorage(childStorage))) { return false; } if (myStorage != childStorage) { return false; } return ((e4_NodeImpl *) impl)->SetVertexByRankToNode(rank, n.GetRawUniqueID()); } /* * Set the vertex identified by the given rank to the value encapsulated * in the given e4_Value. */ bool e4_Node::SetVertexByRank(int rank, const e4_Value &v) const { switch (v.vertexType) { case E4_VTNODE: return SetVertexByRank(rank, v.n); case E4_VTINT: return SetVertexByRank(rank, v.u.i); case E4_VTDOUBLE: return SetVertexByRank(rank, v.u.d); case E4_VTSTRING: return SetVertexByRank(rank, v.u.s); case E4_VTBINARY: return SetVertexByRank(rank, v.u.b.bytes, v.u.b.nbytes); default: return false; } } /* * Set a vertex identified by rank to a new node and return the new node. */ bool e4_Node::SetNodeByRank(int rank, e4_Node &n) const { e4_NodeImpl *nnip; if (impl == NULL) { return false; } nnip = ((e4_NodeImpl *) impl)->SetNodeByRank(rank); if (nnip == NULL) { return false; } e4_Node nn(nnip); /* * Decrement the refcount to offset the artificially incremented refcount * for protection during callbacks. */ nnip->DecrRefCount(); n = nn; return true; } /* * Operations to add a new vertex to this node according to the rank and * order arguments. */ bool e4_Node::AddVertex(const char *nm, e4_InsertOrder order, int &rank, int i) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->AddVertex(nm, order, rank, i); } bool e4_Node::AddVertex(const char *nm, e4_InsertOrder order, int &rank, double f) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->AddVertex(nm, order, rank, f); } bool e4_Node::AddVertex(const char *nm, e4_InsertOrder order, int &rank, const char *s) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->AddVertex(nm, order, rank, s); } bool e4_Node::AddVertex(const char *nm, e4_InsertOrder order, int &rank, const void *b, int nb) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->AddVertex(nm, order, rank, b, nb); } /* * Add a new vertex and set its value to the given node. */ bool e4_Node::AddVertex(const char *nm, e4_InsertOrder order, int &rank, e4_Node n) const { e4_Storage myStorage, childStorage; if ((impl == NULL) || (!n.IsValid())) { return false; } if ((!GetStorage(myStorage)) || (!n.GetStorage(childStorage))) { return false; } if (myStorage != childStorage) { return false; } return ((e4_NodeImpl *) impl)->AddVertexWithNode(nm, order, rank, n.GetRawUniqueID()); } /* * Add a new vertex and set its value to the value supplied in the given * e4_Value structure. */ bool e4_Node::AddVertex(const char *nm, e4_InsertOrder order, int &rank, const e4_Value &v) const { switch (v.vertexType) { case E4_VTNODE: return AddVertex(nm, order, rank, v.n); case E4_VTINT: return AddVertex(nm, order, rank, v.u.i); case E4_VTDOUBLE: return AddVertex(nm, order, rank, v.u.d); case E4_VTSTRING: return AddVertex(nm, order, rank, v.u.s); case E4_VTBINARY: return AddVertex(nm, order, rank, v.u.b.bytes, v.u.b.nbytes); default: return false; } } /* * Add a new vertex with the given name and set it to a new node. Also return * the new node. */ bool e4_Node::AddNode(const char *nm, e4_InsertOrder order, int &rank, e4_Node &n) const { e4_NodeImpl *nnip; if (impl == NULL) { return false; } nnip = ((e4_NodeImpl *) impl)->AddNode(nm, order, rank); if (nnip == NULL) { return false; } e4_Node nn(nnip); /* * Decrement the refcount to offset the artificially incremented refcount * for protection during callbacks. */ nnip->DecrRefCount(); n = nn; return true; } /* * Add a new vertex and also return an e4_Vertex for the new vertex. */ bool e4_Node::AddVertexRef(const char *nm, e4_InsertOrder order, int &rank, int iv, e4_Vertex &v) const { e4_VertexImpl *vvip; if (impl == NULL) { return false; } vvip = ((e4_NodeImpl *) impl)->AddVertexRef(nm, order, rank, iv); if (vvip == NULL) { return false; } e4_Vertex vv(vvip); /* * Decrement the refcount to offset the artificially incremented * refcount for protection during callbacks. */ vvip->DecrRefCount(); v = vv; return true; } bool e4_Node::AddVertexRef(const char *nm, e4_InsertOrder order, int &rank, double fv, e4_Vertex &v) const { e4_VertexImpl *vvip; if (impl == NULL) { return false; } vvip = ((e4_NodeImpl *) impl)->AddVertexRef(nm, order, rank, fv); if (vvip == NULL) { return false; } e4_Vertex vv(vvip); /* * Decrement the refcount to offset the artificially incremented * refcount for protection during callbacks. */ vvip->DecrRefCount(); v = vv; return true; } bool e4_Node::AddVertexRef(const char *nm, e4_InsertOrder order, int &rank, const char *sv, e4_Vertex &v) const { e4_VertexImpl *vvip; if (impl == NULL) { return false; } vvip = ((e4_NodeImpl *) impl)->AddVertexRef(nm, order, rank, sv); if (vvip == NULL) { return false; } e4_Vertex vv(vvip); /* * Decrement the refcount to offset the artificially incremented * refcount for protection during callbacks. */ vvip->DecrRefCount(); v = vv; return true; } bool e4_Node::AddVertexRef(const char *nm, e4_InsertOrder order, int &rank, const void *bv, int nbv, e4_Vertex &v) const { e4_VertexImpl *vvip; if (impl == NULL) { return false; } vvip = ((e4_NodeImpl *) impl)->AddVertexRef(nm, order, rank, bv, nbv); if (vvip == NULL) { return false; } e4_Vertex vv(vvip); /* * Decrement the refcount to offset the artificially incremented * refcount for protection during callbacks. */ vvip->DecrRefCount(); v = vv; return true; } /* * Add a new vertex whose value is the given node, and return an e4_Vertex for * the new vertex. */ bool e4_Node::AddVertexRef(const char *nm, e4_InsertOrder order, int &rank, e4_Node n, e4_Vertex &v) const { e4_VertexImpl *vvip; e4_Storage myStorage, childStorage; if ((impl == NULL) || (!n.IsValid())) { return false; } if ((!GetStorage(myStorage)) || (!n.GetStorage(childStorage))) { return false; } if (myStorage != childStorage) { return false; } vvip = ((e4_NodeImpl *) impl)->AddVertexRefWithNode(nm, order, rank, n.GetRawUniqueID()); if (vvip == NULL) { return false; } e4_Vertex vv(vvip); /* * Decrement the refcount to offset the artificially incremented * refcount for protection during callbacks. */ vvip->DecrRefCount(); v = vv; return true; } /* * Add a new vertex whose value and type are determined by the given e4_Value, * and return an e4_Vertex for the new vertex. */ bool e4_Node::AddVertexRef(const char *nm, e4_InsertOrder order, int &rank, const e4_Value &v, e4_Vertex &f) const { switch (v.vertexType) { case E4_VTNODE: return AddVertexRef(nm, order, rank, v.n, f); case E4_VTINT: return AddVertexRef(nm, order, rank, v.u.i, f); case E4_VTDOUBLE: return AddVertexRef(nm, order, rank, v.u.d, f); case E4_VTSTRING: return AddVertexRef(nm, order, rank, v.u.s, f); case E4_VTBINARY: return AddVertexRef(nm, order, rank, v.u.b.bytes, v.u.b.nbytes, f); default: return false; } } /* * Add a new vertex whose value is a new node, return an e4_Vertex for the * new vertex and also return an e4_Node for the new node. */ bool e4_Node::AddNodeRef(const char *nm, e4_InsertOrder order, int &rank, e4_Node &n, e4_Vertex &v) const { e4_VertexImpl *vvip; e4_NodeImpl *nnip; if (impl == NULL) { return false; } vvip = ((e4_NodeImpl *) impl)->AddNodeRef(nm, order, rank, nnip); if ((vvip == NULL) || (nnip == NULL)) { return false; } e4_Vertex vv(vvip); /* * Decrement the refcount to offset the artificially incremented * refcount for protection during callbacks. */ vvip->DecrRefCount(); v = vv; e4_Node nn(nnip); /* * Decrement the refcount to offset the artificially incremented * refcount for protection during callbacks. */ nnip->DecrRefCount(); n = nn; return true; } /* * Move a vertex to a specified position within this node. Note that only * moves within the same storage are allowed. */ bool e4_Node::MoveVertex(const e4_Vertex &v, e4_InsertOrder order, int rank) { e4_Storage myStorage, hisStorage; if (!v.IsValid() || (impl == NULL)) { return false; } if ((!GetStorage(myStorage)) || (!v.GetStorage(hisStorage))) { return false; } if (myStorage != hisStorage) { return false; } return ((e4_NodeImpl *) impl)->MoveVertex(v.GetRawUniqueID(), order, rank); } /* * Get the value of a vertex in this node. */ bool e4_Node::GetNthVertex(const char *nm, int nth, e4_Value &v) const { e4_ValueImpl *vipp; if (impl == NULL) { return false; } if (((e4_NodeImpl *) impl)->GetNthVertex(nm, nth, vipp) == false) { return false; } if (vipp == NULL) { return false; } v.vertexType = vipp->vertexType; switch (vipp->vertexType) { case E4_VTNODE: { e4_Node nn(vipp->u.n); v.n = nn; break; } case E4_VTINT: v.u.i = vipp->u.i; break; case E4_VTDOUBLE: v.u.d = vipp->u.d; break; case E4_VTSTRING: v.u.s = vipp->u.s; break; case E4_VTBINARY: v.u.b.bytes = vipp->u.b.bytes; v.u.b.nbytes = vipp->u.b.nbytes; break; default: return false; } delete vipp; return true; } bool e4_Node::GetNthVertex(const char *nm, int nth, e4_Node &n) const { e4_NodeImpl *nnip; if (impl == NULL) { return false; } if (((e4_NodeImpl *) impl)->GetNthVertex(nm, nth, nnip) == false) { return false; } if (nnip == NULL) { return false; } e4_Node nn(nnip); n = nn; return true; } bool e4_Node::GetNthVertex(const char *nm, int nth, int &v) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->GetNthVertex(nm, nth, v); } bool e4_Node::GetNthVertex(const char *nm, int nth, double &v) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->GetNthVertex(nm, nth, v); } bool e4_Node::GetNthVertex(const char *nm, int nth, const char *&v) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->GetNthVertex(nm, nth, v); } bool e4_Node::GetNthVertex(const char *nm, int nth, const void *&v, int &nbv) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->GetNthVertex(nm, nth, v, nbv); } /* * Get the value of a vertex identified by rank. */ bool e4_Node::GetVertexByRank(int rank, e4_Value &v) const { e4_ValueImpl *vipp; if (impl == NULL) { return false; } if (((e4_NodeImpl *) impl)->GetVertexByRank(rank, vipp) == false) { return false; } if (vipp == NULL) { return false; } v.vertexType = vipp->vertexType; switch (vipp->vertexType) { case E4_VTNODE: { e4_Node nn(vipp->u.n); v.n = nn; break; } case E4_VTINT: v.u.i = vipp->u.i; break; case E4_VTDOUBLE: v.u.d = vipp->u.d; break; case E4_VTSTRING: v.u.s = vipp->u.s; break; case E4_VTBINARY: v.u.b.bytes = vipp->u.b.bytes; v.u.b.nbytes = vipp->u.b.nbytes; break; default: return false; } delete vipp; return true; } bool e4_Node::GetVertexByRank(int rank, e4_Node &n) const { e4_NodeImpl *nnip; if (impl == NULL) { return false; } if (((e4_NodeImpl *) impl)->GetVertexByRank(rank, nnip) == false) { return false; } if (nnip == NULL) { return false; } e4_Node nn(nnip); n = nn; return true; } bool e4_Node::GetVertexByRank(int rank, int &v) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->GetVertexByRank(rank, v); } bool e4_Node::GetVertexByRank(int rank, double &v) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->GetVertexByRank(rank, v); } bool e4_Node::GetVertexByRank(int rank, const char *&v) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->GetVertexByRank(rank, v); } bool e4_Node::GetVertexByRank(int rank, const void *&v, int &nbv) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->GetVertexByRank(rank, v, nbv); } /* * Detach a vertex. */ bool e4_Node::DetachVertex(const char *nm, int nth) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->DetachVertex(nm, nth); } bool e4_Node::DetachVertexByRank(int rank) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->DetachVertexByRank(rank); } bool e4_Node::DetachFirstVertexWithNode(e4_Node child) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->DetachFirstVertexWithNode( (e4_NodeImpl *) child.impl); } /* * Get an e4_Vertex for a specific vertex. */ bool e4_Node::GetVertexRef(const char *nm, int nth, e4_Vertex &v) const { e4_VertexImpl *vvip; if (impl == NULL) { return false; } vvip = ((e4_NodeImpl *) impl)->GetVertexRef(nm, nth); if (vvip == NULL) { return false; } e4_Vertex vv(vvip); v = vv; return true; } bool e4_Node::GetVertexRefByRank(int rank, e4_Vertex &v) const { e4_VertexImpl *vvip; if (impl == NULL) { return false; } vvip = ((e4_NodeImpl *) impl)->GetVertexRefByRank(rank); if (vvip == NULL) { return false; } e4_Vertex vv(vvip); v = vv; return true; } /* * Get the type of a value stored in a specified vertex. */ e4_VertexType e4_Node::VertexType(const char *nm, int nth) const { if (impl == NULL) { return E4_VTUNKNOWN; } return ((e4_NodeImpl *) impl)->VertexType(nm, nth); } e4_VertexType e4_Node::VertexTypeByRank(int rank) const { if (impl == NULL) { return E4_VTUNKNOWN; } return ((e4_NodeImpl *) impl)->VertexTypeByRank(rank); } /* * Get the name of a vertex. */ const char * e4_Node::VertexName(int rank) const { if (impl == NULL) { return (const char *) NULL; } return ((e4_NodeImpl *) impl)->VertexName(rank); } /* * Rename a vertex. */ bool e4_Node::RenameVertex(int rank, const char *newName) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->RenameVertex(rank, newName); } /* * Get the rank of a specified vertex. */ int e4_Node::VertexRank(const char *nm, int nth) const { if (impl == NULL) { return E4_VERTEXNOTFOUND; } return ((e4_NodeImpl *) impl)->VertexRank(nm, nth); } /* * Does a specified vertex exist? */ bool e4_Node::Exists(const char *nm, int nth) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->Exists(nm, nth); } /* * Get the parent and root node of this node. */ bool e4_Node::GetParent(int nth, e4_Node &p) const { e4_NodeImpl *ppip; if (impl == NULL) { return false; } ppip = ((e4_NodeImpl *) impl)->GetParent(nth); if (ppip == NULL) { return false; } e4_Node pp(ppip); p = pp; return true; } /* * Retrieve the nth vertex in the parent p of this node whose value is * this node. */ bool e4_Node::GetVertexRefFromParent(e4_Node p, int nth, e4_Vertex &v) const { e4_VertexImpl *vp; e4_NodeImpl *pimpl = (e4_NodeImpl *) p.impl; if ((impl == NULL) || (pimpl == NULL)) { return false; } vp = ((e4_NodeImpl *) impl)->GetVertexRefFromParent(pimpl, nth); if (vp == NULL) { return false; } e4_Vertex vv(vp); v = vv; return true; } /* * Retrieve the nth vertex in the ith parent of this node whose value * is this node. */ bool e4_Node::GetVertexRefFromParent(int i, int nth, e4_Vertex &v) const { e4_VertexImpl *vp; if (impl == NULL) { return false; } vp = ((e4_NodeImpl *) impl)->GetVertexRefFromParent(i, nth); if (vp == NULL) { return false; } e4_Vertex vv(vp); v = vv; return true; } /* * How many parents does this node have? */ int e4_Node::ParentCount() const { if (impl == NULL) { return E4_NODENOTFOUND; } return ((e4_NodeImpl *) impl)->ParentCount(); } /* * In how many different vertices is this node the vertex value? */ int e4_Node::OccurrenceCount() const { if (impl == NULL) { return E4_NODENOTFOUND; } return ((e4_NodeImpl *) impl)->OccurrenceCount(); } /* * How many times does this node occur as a child in the given parent? */ int e4_Node::OccurrenceCount(e4_Node p) const { e4_Storage myStorage, parentStorage; if ((impl == NULL) || (!p.IsValid())) { return E4_NODENOTFOUND; } if ((!GetStorage(myStorage)) || (!p.GetStorage(parentStorage))) { return E4_NODENOTFOUND; } if (myStorage != parentStorage) { return E4_NODENOTFOUND; } return ((e4_NodeImpl *) impl)->OccurrenceCount(p.GetRawUniqueID()); } /* * What is the rank of this parent for this node? */ int e4_Node::ParentRank(e4_Node p) const { e4_Storage myStorage, parentStorage; if ((impl == NULL) || (!p.IsValid())) { return E4_NODENOTFOUND; } if ((!GetStorage(myStorage)) || (!p.GetStorage(parentStorage))) { return E4_NODENOTFOUND; } if (myStorage != parentStorage) { return E4_NODENOTFOUND; } return ((e4_NodeImpl *) impl)->ParentRank(p.GetRawUniqueID()); } /* * Get the rank or name of the vertex containing this node in its parent. */ int e4_Node::GetRankInParent(int nth, int ith) const { if (impl == NULL) { return E4_NODENOTFOUND; } return ((e4_NodeImpl *) impl)->GetRankInParent(nth, ith); } const char * e4_Node::GetNameInParent(int nth, int ith) const { if (impl == NULL) { return NULL; } return ((e4_NodeImpl *) impl)->GetNameInParent(nth, ith); } /* * Get the rank and name of the ith vertex whose value is this node in * the parent node p. */ int e4_Node::GetRankInParent(e4_Node p, int ith) const { e4_NodeImpl *pimpl = (e4_NodeImpl *) p.impl; if ((impl == NULL) || (pimpl == NULL)) { return E4_NODENOTFOUND; } return ((e4_NodeImpl *) impl)->GetRankInParent(pimpl, ith); } const char * e4_Node::GetNameInParent(e4_Node p, int ith) const { e4_NodeImpl *pimpl = (e4_NodeImpl *) p.impl; if ((impl == NULL) || (pimpl == NULL)) { return NULL; } return ((e4_NodeImpl *) impl)->GetNameInParent(pimpl, ith); } /* * Is this node the root? */ bool e4_Node::IsRoot() const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->IsRoot(); } /* * Get the root node of the storage containing this node. */ bool e4_Node::GetRootNode(e4_Node &rn) const { e4_NodeImpl *rnip; e4_StorageImpl *ssip; if (impl == NULL) { return false; } ssip = ((e4_NodeImpl *) impl)->GetStorage(); if (ssip == NULL) { return false; } rnip = ssip->GetRootNode(); if (rnip == NULL) { return false; } e4_Node rrnn(rnip); rn = rrnn; return true; } /* * Get the storage containing this node. */ bool e4_Node::GetStorage(e4_Storage &s) const { e4_StorageImpl *ssip; if (impl == NULL) { return false; } ssip = ((e4_NodeImpl *) impl)->GetStorage(); if (ssip == NULL) { return false; } e4_Storage ss(ssip); s = ss; return true; } /* * Get an ID that uniquely identifies this node within its storage. */ bool e4_Node::GetUniqueID(e4_NodeUniqueID &n) const { int id; e4_StorageImpl *sp; if (impl == NULL) { return false; } id = ((e4_NodeImpl *) impl)->GetUniqueID(); if (id == E4_NODENOTFOUND) { return false; } sp = ((e4_NodeImpl *) impl)->GetStorage(); if (sp == NULL) { return false; } e4_NodeUniqueID nn(id, sp->DRV_HashCode()); n = nn; return true; } /* * Get the ID but return it unwrapped. */ int e4_Node::GetRawUniqueID() const { if (impl == NULL) { return E4_NODENOTFOUND; } return ((e4_NodeImpl *) impl)->GetUniqueID(); } /* * Detach this node from all vertices for which it is the value. */ bool e4_Node::Detach() const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->Detach(); } /* * Is this node detached? */ bool e4_Node::IsDetached() const { if (impl == NULL) { return true; } return ((e4_NodeImpl *) impl)->IsDetached(); } /* * Return the kind identifier for this instance's type. */ e4_RefKind e4_Node::Kind() const { return E4_RKNODE; } /* * Get/Set user data associated with this node. */ bool e4_Node::GetUserData(int &userData) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->GetUserData(userData); } bool e4_Node::SetUserData(int userData) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->SetUserData(userData); } /* * Set/Get user data for contained vertex. */ bool e4_Node::GetVertexUserData(const char *name, int &userData) const { return GetVertexUserData(name, 1, userData); } bool e4_Node::SetVertexUserData(const char *name, int userData) const { return SetVertexUserData(name, 1, userData); } bool e4_Node::GetVertexUserData(const char *name, int nth, int &userData) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->GetVertexUserData(name, nth, userData); } bool e4_Node::SetVertexUserData(const char *name, int nth, int userData) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->SetVertexUserData(name, nth, userData); } bool e4_Node::GetVertexUserDataByRank(int rank, int &userData) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->GetVertexUserDataByRank(rank, userData); } bool e4_Node::SetVertexUserDataByRank(int rank, int userData) const { if (impl == NULL) { return false; } return ((e4_NodeImpl *) impl)->SetVertexUserDataByRank(rank, userData); } /* * Set/Get the advisory caching policy for this node. */ int e4_Node::SetAdvisoryCachingPolicy(bool set, int mask) const { if (impl == NULL) { return E4_CACHEINCREMENTAL; } return ((e4_NodeImpl *) impl)->SetAdvisoryCachingPolicy(set, mask); } int e4_Node::GetAdvisoryCachingPolicy() const { if (impl == NULL) { return E4_CACHEINCREMENTAL; } return ((e4_NodeImpl *) impl)->GetAdvisoryCachingPolicy(); } /* * Pre-cache all vertices in this node. */ void e4_Node::PreCache() const { if (impl == NULL) { return; } ((e4_NodeImpl *) impl)->PreCache(); }