#include "DOM.h"
#include <string.h>
Node* NamedNodeMap::getNamedItem(String name)
{
for (int i=0; i<getLength(); i++)
if ( strcmp(name, item(i)->getNodeName() ) == 0) return item(i);
return NULL;
}
Node* NamedNodeMap::setNamedItem(Node* arg) throw (DOMException&)
{
// not implemented yet:
// WRONG_DOCUMENT_ERR: Raised if arg was created from a different document
// than the one that created the NamedNodeMap.
// NO_MODIFICATION_ALLOWED_ERR: Raised if this NamedNodeMap is readonly.
// INUSE_ATTRIBUTE_ERR: Raised if arg is an Attr that is already an attribute
// of another Element object. The DOM user must explicitly clone Attr nodes
// to re-use them in other elements.
String arg_name = arg->getNodeName();
for (int i=0; i<getLength(); i++)
if ( strcmp(arg_name, array[i]->getNodeName() ) == 0)
{
Node* oldNode = array[i];
array[i] = arg;
return oldNode;
}
// a node with the same name is not there
if (length==size) enlarge_array();
array[length] = arg;
length++;
return NULL;
}
Node* NamedNodeMap::removeNamedItem(String name) throw (DOMException&)
{
int i;
for (i=0; i<getLength(); i++)
if ( strcmp(name, item(i)->getNodeName() ) == 0) break;
if (i == getLength()) // not found
throw( DOMException(DOMException::NOT_FOUND_ERR, "NamedNodeMap::removeNamedItem") );
// If the found node is an Attr with a default value don't remove it
// not implemented yet
// remove the found node
Node* node = item(i);
for ( ; i < length-1; i++) array[i] = array[i+1];
array[length-1] = NULL;
length--;
return node;
}
Node* NamedNodeMap::item(int index)
{
if ( (index < 0) || (index >= length) ) return NULL;
return array[index];
}
int NamedNodeMap::getLength()
{
return length;
}
void NamedNodeMap::enlarge_array()
{
size += NamedNodeMap::STEP;
Node** newArray = new Node*[size];
for (int i=0; i<size; i++)
newArray[i] = (i<length ? array[i] : NULL);
delete array;
array = newArray;
}
NamedNodeMap* NamedNodeMap::clone()
{
NamedNodeMap* newNNM = new NamedNodeMap;
newNNM->size = size;
newNNM->length = length;
newNNM->array = new Node*[size];
for (int i=0; i<size; i++) newNNM->array[i] = NULL;
for (int i=0; i<length; i++)
if (array[i] != NULL)
{
newNNM->array[i] = array[i]->cloneNode(0);
newNNM->array[i]->setParentNode(array[i]->getParentNode());
}
return newNNM;
}
NamedNodeMap::NamedNodeMap()
{
length = 0;
size = 0;
array = NULL;
}
NamedNodeMap::~NamedNodeMap()
{
length = 0;
size = 0;
delete array;
}
ostream& operator<< (ostream& os, NamedNodeMap& nnm)
{
os << " NamedNodeMap (length = " << nnm.getLength() << ") :" << endl;
for(int i=0; i<nnm.getLength(); i++)
if (nnm.item(i) != NULL)
os << " Name: " << nnm.item(i)->getNodeName()
<< " Value: " << nnm.item(i)->getNodeValue()
<< " Type: " << nnm.item(i)->getNodeType() << endl;
return os;
}
void NamedNodeMap::test()
{
// not implemented yet
NamedNodeMap* nnm = new NamedNodeMap;
cout << "Empty NNM: " << endl << *nnm << "-----------------------" << endl;
Node* n1 = new Node(1, "Element1", "Value");
Node* n2 = new Node(1, "Element2", "Value");
Node* n3 = new Node(1, "Element3", "Value");
Node* n4 = new Node(1, "Element4", "Value");
nnm->setNamedItem(n1);
nnm->setNamedItem(n2);
nnm->setNamedItem(n3);
nnm->setNamedItem(n4);
cout << *nnm << "-----------------------" << endl;
Node* n5 = new Node(2, "Element3", "Valueless");
Node* n6 = nnm->setNamedItem(n5);
cout << *n6 << endl;
cout << *nnm << "-----------------------" << endl;
n6 = nnm->getNamedItem("Element1");
if (n6==NULL) cout << "NULL" << endl;
else cout << *n6 << endl;
n6 = nnm->getNamedItem("XXX");
if (n6==NULL) cout << "NULL" << endl;
else cout << *n6 << endl;
n6 = nnm->removeNamedItem("Element1");
cout << *nnm << "-----------------------" << endl;
if (n6==NULL) cout << "NULL" << endl;
else cout << *n6 << endl;
try { nnm->removeNamedItem("XXX");}
catch (DOMException& e) { cout << e << endl; }
NamedNodeMap* nnm1 = nnm->clone();
nnm1->removeNamedItem("Element2");
cout << *nnm << "-----------------------" << endl;
cout << *nnm1 << "-----------------------" << endl;
}