You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by ne...@apache.org on 2003/05/25 01:56:36 UTC
cvs commit: xml-xerces/c/src/xercesc/dom/deprecated AttrImpl.cpp AttrImpl.hpp
neilg 2003/05/24 16:56:35
Modified: c/src/xercesc/dom/deprecated AttrImpl.cpp AttrImpl.hpp
Log:
fix segfault on GCC 2.9x. The depreacted DOM attribute implementation had a cute trick where a void * field could be either a NodeChild pointer or a DOMString; the latter played havoc with the new memory management paradigm. Now a union of a DOMString * and a ChildNode * is used.
Revision Changes Path
1.6 +73 -40 xml-xerces/c/src/xercesc/dom/deprecated/AttrImpl.cpp
Index: AttrImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/deprecated/AttrImpl.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- AttrImpl.cpp 22 May 2003 02:26:49 -0000 1.5
+++ AttrImpl.cpp 24 May 2003 23:56:35 -0000 1.6
@@ -83,8 +83,13 @@
* This is consistently achieved by taking the address of the value field and
* changing it into a DOMString*, and then dereferencing it to get a DOMString.
* The typical piece of code is:
- * DOMString *x = (DOMString *)&value;
+ * DOMString *x = (DomString *)&value;
* ... use of *x which is the DOMString ...
+ * This was amended by neilg after memory management was
+ * introduced. Now a union exists which is either a
+ * DOMString * or a ChildNode *. This will be less efficient
+ * (one more dereference per access) but actually works on all the
+ * compilers we support.
*/
AttrImpl::AttrImpl(DocumentImpl *ownerDoc, const DOMString &aName)
@@ -93,7 +98,7 @@
name = aName.clone();
isSpecified(true);
hasStringValue(true);
- value = null;
+ value.child = null;
};
AttrImpl::AttrImpl(const AttrImpl &other, bool deep)
@@ -109,7 +114,7 @@
* be called on something that is not actually a DOMString... Really bad
* things would then happen!!!
*/
- value = null;
+ value.child = null;
hasStringValue(other.hasStringValue());
if (other.isIdAttr())
@@ -123,13 +128,27 @@
cloneChildren(other);
}
else {
- // get the address of the value field of this as a DOMString*
- DOMString *x = (DOMString*) &value;
- // and the address of the value field of other as a DOMString*
- DOMString *y = (DOMString*) &(other.value);
- // We can now safely do the cloning and assignement, both operands
- // being a DOMString their ref counts will be updated appropriately
- *x = y->clone();
+ if(other.value.str == null)
+ {
+ if(value.str != null)
+ {
+ *(value.str) == null;
+ delete value.str;
+ }
+ }
+ else
+ {
+ // get the address of the value field of this as a DOMString*
+ DOMString *x = (value.str == null
+ ?(value.str = new (getOwnerDocument()->getMemoryManager()) DOMString())
+ :value.str
+ );
+ // and the address of the value field of other as a DOMString*
+ DOMString *y = other.value.str;
+ // We can now safely do the cloning and assignement, both operands
+ // being a DOMString their ref counts will be updated appropriately
+ *x = y->clone();
+ }
}
};
@@ -139,8 +158,11 @@
// if value is a DOMString we must make sure its ref count is updated.
// this is achieved by changing the address of the value field into a
// DOMString* and setting the value field to null
- DOMString *x = (DOMString *) &value;
- *x = null;
+ if(value.str != null)
+ {
+ *(value.str) == null;
+ delete value.str;
+ }
}
}
@@ -148,17 +170,21 @@
// create a real Text node as child if we don't have one yet
void AttrImpl::makeChildNode() {
if (hasStringValue()) {
- if (value != null) {
+ if (value.child != null) {
// change the address of the value field into a DOMString*
- DOMString *x = (DOMString *) &value;
+ DOMString *x = (value.str == null
+ ?(value.str = new (getOwnerDocument()->getMemoryManager()) DOMString())
+ :value.str
+ );
// create a Text node passing the DOMString it points to
TextImpl *text =
(TextImpl *) getOwnerDocument()->createTextNode(*x);
// get the DOMString ref count to be updated by setting the value
// field to null
*x = null;
+ delete x;
// finally reassign the value to the node address
- value = text;
+ value.child = text;
text->isFirstChild(true);
text->previousSibling = text;
text->ownerNode = this;
@@ -206,16 +232,19 @@
DOMString AttrImpl::getValue()
{
- if (value == null) {
+ if (value.child == null) {
return 0; // return "";
}
if (hasStringValue()) {
// change value into a DOMString*
- DOMString *x = (DOMString *) &value;
+ DOMString *x = (value.str == null
+ ?(value.str = new (getOwnerDocument()->getMemoryManager()) DOMString())
+ :value.str
+ );
// return the DOMString it points to
return *x;
}
- ChildNode *firstChild = (ChildNode *) value;
+ ChildNode *firstChild = value.child;
ChildNode *node = firstChild->nextSibling;
if (node == null) {
return firstChild->getNodeValue().clone();
@@ -272,9 +301,9 @@
if (isIdAttr())
this->getOwnerDocument()->getNodeIDMap()->remove(this);
- if (!hasStringValue() && value != null) {
+ if (!hasStringValue() && value.str != null) {
NodeImpl *kid;
- while ((kid = (ChildNode *) value) != null) { // Remove existing kids
+ while ((kid = value.child) != null) { // Remove existing kids
removeChild(kid);
if (kid->nodeRefCount == 0)
NodeImpl::deleteIf(kid);
@@ -283,12 +312,16 @@
// directly store the string as the value by changing the value field
// into a DOMString
- DOMString *x = (DOMString *) &value;
+ DOMString *x = (value.str == null
+ ?(value.str = new (getOwnerDocument()->getMemoryManager()) DOMString())
+ :value.str
+ );
if (newvalue != null) {
*x = newvalue.clone();
}
else {
*x = null;
+ delete x;
}
hasStringValue(true);
isSpecified(true);
@@ -349,7 +382,7 @@
NodeImpl * AttrImpl::getFirstChild() {
makeChildNode();
- return (ChildNode *) value;
+ return value.child;
}
@@ -360,13 +393,13 @@
ChildNode * AttrImpl::lastChild() {
// last child is stored as the previous sibling of first child
makeChildNode();
- return value != null ? ((ChildNode *) value)->previousSibling : null;
+ return value.child != null ? (value.child)->previousSibling : null;
}
void AttrImpl::lastChild(ChildNode *node) {
// store lastChild as previous sibling of first child
- if (value != null) {
- ((ChildNode *) value)->previousSibling = node;
+ if (value.child != null) {
+ (value.child)->previousSibling = node;
}
}
@@ -374,7 +407,7 @@
if (hasStringValue()) {
return 1;
}
- ChildNode *node = (ChildNode *) value;
+ ChildNode *node = value.child;
int length = 0;
while (node != null) {
length++;
@@ -385,7 +418,7 @@
bool AttrImpl::hasChildNodes()
{
- return value != null;
+ return value.child != null;
};
@@ -487,10 +520,10 @@
// Attach before and after
// Note: firstChild.previousSibling == lastChild!!
- ChildNode *firstChild = (ChildNode *) value;
+ ChildNode *firstChild = value.child;
if (firstChild == null) {
// this our first and only child
- value = newInternal; // firstChild = newInternal
+ value.child = newInternal; // firstChild = newInternal
newInternal->isFirstChild(true);
newInternal->previousSibling = newInternal;
}
@@ -510,7 +543,7 @@
newInternal->nextSibling = firstChild;
newInternal->previousSibling = firstChild->previousSibling;
firstChild->previousSibling = newInternal;
- value = newInternal; // firstChild = newInternal;
+ value.child = newInternal; // firstChild = newInternal;
newInternal->isFirstChild(true);
}
else {
@@ -544,15 +577,15 @@
NodeImpl *AttrImpl::item(unsigned int index) {
if (hasStringValue()) {
- if (index != 0 || value == null) {
+ if (index != 0 || value.child == null) {
return null;
}
else {
makeChildNode();
- return (NodeImpl *) value;
+ return (NodeImpl *) (value.child);
}
}
- ChildNode *nodeListNode = (ChildNode *) value;
+ ChildNode *nodeListNode = value.child;
for (unsigned int nodeListIndex = 0;
nodeListIndex < index && nodeListNode != null;
nodeListIndex++) {
@@ -594,11 +627,11 @@
// Patch linked list around oldChild
// Note: lastChild == firstChild->previousSibling
- if (oldInternal == value) {
+ if (oldInternal == value.child) {
// removing first child
oldInternal->isFirstChild(false);
- value = oldInternal->nextSibling; // firstChild = oldInternal->nextSibling
- ChildNode *firstChild = (ChildNode *) value;
+ value.child = oldInternal->nextSibling; // firstChild = oldInternal->nextSibling
+ ChildNode *firstChild = value.child;
if (firstChild != null) {
firstChild->isFirstChild(true);
firstChild->previousSibling = oldInternal->previousSibling;
@@ -609,7 +642,7 @@
prev->nextSibling = next;
if (next == null) {
// removing last child
- ChildNode *firstChild = (ChildNode *) value;
+ ChildNode *firstChild = value.child;
firstChild->previousSibling = prev;
} else {
// removing some other child in the middle
@@ -647,7 +680,7 @@
return;
}
// Recursively set kids
- for (ChildNode *mykid = (ChildNode *) value;
+ for (ChildNode *mykid = value.child;
mykid != null;
mykid = mykid->nextSibling)
if(! (mykid->isEntityReference()))
@@ -664,7 +697,7 @@
return;
}
ChildNode *kid, *next;
- for (kid = (ChildNode *) value; kid != null; kid = next)
+ for (kid = value.child; kid != null; kid = next)
{
next = kid->nextSibling;
1.4 +6 -2 xml-xerces/c/src/xercesc/dom/deprecated/AttrImpl.hpp
Index: AttrImpl.hpp
===================================================================
RCS file: /home/cvs/xml-xerces/c/src/xercesc/dom/deprecated/AttrImpl.hpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- AttrImpl.hpp 4 Nov 2002 15:04:44 -0000 1.3
+++ AttrImpl.hpp 24 May 2003 23:56:35 -0000 1.4
@@ -153,7 +153,10 @@
DOMString name;
/** This can either be a DOMString or the first child node (ChildNode*). */
- void *value;
+ union {
+ ChildNode *child;
+ DOMString *str;
+ } value;
public:
AttrImpl(DocumentImpl *ownerDocument, const DOMString &aName);
@@ -197,6 +200,7 @@
void cloneChildren(const NodeImpl &other);
ChildNode * lastChild();
void lastChild(ChildNode *);
+ inline DOMString* valueToDOMString();
};
---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org