attrimpl.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 692 行 · 第 1/2 页

CPP
692
字号
    makeChildNode();    return value.child;}NodeImpl * AttrImpl::getLastChild() {    return lastChild();}ChildNode * AttrImpl::lastChild() {    // last child is stored as the previous sibling of first child    makeChildNode();    return value.child != null ? (value.child)->previousSibling : null;}void AttrImpl::lastChild(ChildNode *node) {    // store lastChild as previous sibling of first child    if (value.child != null) {        (value.child)->previousSibling = node;    }}unsigned int AttrImpl::getLength() {    if (hasStringValue()) {        return 1;    }    ChildNode *node = value.child;    int length = 0;    while (node != null) {        length++;        node = node->nextSibling;    }    return length;}bool AttrImpl::hasChildNodes(){    return value.child != null;};NodeImpl *AttrImpl::insertBefore(NodeImpl *newChild, NodeImpl *refChild) {    DocumentImpl *ownerDocument = getOwnerDocument();    bool errorChecking = ownerDocument->getErrorChecking();    if (newChild->isDocumentFragmentImpl()) {        // SLOW BUT SAFE: We could insert the whole subtree without        // juggling so many next/previous pointers. (Wipe out the        // parent's child-list, patch the parent pointers, set the        // ends of the list.) But we know some subclasses have special-        // case behavior they add to insertBefore(), so we don't risk it.        // This approch also takes fewer bytecodes.        // NOTE: If one of the children is not a legal child of this        // node, throw HIERARCHY_REQUEST_ERR before _any_ of the children        // have been transferred. (Alternative behaviors would be to        // reparent up to the first failure point or reparent all those        // which are acceptable to the target node, neither of which is        // as robust. PR-DOM-0818 isn't entirely clear on which it        // recommends?????        // No need to check kids for right-document; if they weren't,        // they wouldn't be kids of that DocFrag.        if (errorChecking) {            for (NodeImpl *kid = newChild->getFirstChild(); // Prescan                 kid != null; kid = kid->getNextSibling()) {                if (!DocumentImpl::isKidOK(this, kid)) {                    throw DOM_DOMException(                                       DOM_DOMException::HIERARCHY_REQUEST_ERR,                                       null);                }            }        }        while (newChild->hasChildNodes()) {    // Move            insertBefore(newChild->getFirstChild(), refChild);        }        return newChild;    }    // it's a no-op if refChild is the same as newChild    if (refChild == newChild) {        return newChild;    }    if (errorChecking) {        if (isReadOnly()) {            throw DOM_DOMException(                                 DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR,                                 null);        }        if (newChild->getOwnerDocument() != ownerDocument) {            throw DOM_DOMException(DOM_DOMException::WRONG_DOCUMENT_ERR, null);        }        if (!DocumentImpl::isKidOK(this, newChild)) {            throw DOM_DOMException(DOM_DOMException::HIERARCHY_REQUEST_ERR,                                   null);        }        // refChild must be a child of this node (or null)        if (refChild != null && refChild->getParentNode() != this) {            throw DOM_DOMException(DOM_DOMException::NOT_FOUND_ERR, null);        }        // Prevent cycles in the tree        // newChild cannot be ancestor of this Node,        // and actually cannot be this        bool treeSafe = true;        for (NodeImpl *a = this; treeSafe && a != null; a = a->getParentNode())        {            treeSafe = (newChild != a);        }        if (!treeSafe) {            throw DOM_DOMException(DOM_DOMException::HIERARCHY_REQUEST_ERR,                                   null);        }    }    makeChildNode(); // make sure we have a node and not a string    // Convert to internal type, to avoid repeated casting    ChildNode * newInternal = (ChildNode *)newChild;    NodeImpl *oldparent = newInternal->getParentNode();    if (oldparent != null) {        oldparent->removeChild(newInternal);    }    // Convert to internal type, to avoid repeated casting    ChildNode *refInternal = (ChildNode *)refChild;    // Attach up    newInternal->ownerNode = this;    newInternal->isOwned(true);    // Attach before and after    // Note: firstChild.previousSibling == lastChild!!    ChildNode *firstChild = value.child;    if (firstChild == null) {        // this our first and only child        value.child = newInternal; // firstChild = newInternal        newInternal->isFirstChild(true);        newInternal->previousSibling = newInternal;    }    else {        if (refInternal == null) {            // this is an append            ChildNode *lastChild = firstChild->previousSibling;            lastChild->nextSibling = newInternal;            newInternal->previousSibling = lastChild;            firstChild->previousSibling = newInternal;        }        else {            // this is an insert            if (refChild == firstChild) {                // at the head of the list                firstChild->isFirstChild(false);                newInternal->nextSibling = firstChild;                newInternal->previousSibling = firstChild->previousSibling;                firstChild->previousSibling = newInternal;                value.child = newInternal; // firstChild = newInternal;                newInternal->isFirstChild(true);            }            else {                // somewhere in the middle                ChildNode *prev = refInternal->previousSibling;                newInternal->nextSibling = refInternal;                prev->nextSibling = newInternal;                refInternal->previousSibling = newInternal;                newInternal->previousSibling = prev;            }        }    }    changed();    if (this->getOwnerDocument() != null) {        typedef RefVectorOf<RangeImpl> RangeImpls;        RangeImpls* ranges = this->getOwnerDocument()->getRanges();        if ( ranges != null) {            unsigned int sz = ranges->size();            for (unsigned int i =0; i<sz; i++) {                ranges->elementAt(i)->updateRangeForInsertedNode(newInternal);            }        }    }    return newInternal;}NodeImpl *AttrImpl::item(unsigned int index) {    if (hasStringValue()) {        if (index != 0 || value.child == null) {            return null;        }        else {            makeChildNode();            return (NodeImpl *) (value.child);        }    }    ChildNode *nodeListNode = value.child;    for (unsigned int nodeListIndex = 0;         nodeListIndex < index && nodeListNode != null;         nodeListIndex++) {        nodeListNode = nodeListNode->nextSibling;    }    return nodeListNode;}NodeImpl *AttrImpl::removeChild(NodeImpl *oldChild) {    DocumentImpl *ownerDocument = getOwnerDocument();    if (ownerDocument->getErrorChecking()) {        if (isReadOnly()) {            throw DOM_DOMException(                                 DOM_DOMException::NO_MODIFICATION_ALLOWED_ERR,                                 null);        }        if (oldChild == null || oldChild->getParentNode() != this) {            throw DOM_DOMException(DOM_DOMException::NOT_FOUND_ERR, null);        }    }    // fix other ranges for change before deleting the node    if (getOwnerDocument() !=  null) {        typedef RefVectorOf<RangeImpl> RangeImpls;        RangeImpls* ranges = this->getOwnerDocument()->getRanges();        if (ranges != null) {            unsigned int sz = ranges->size();            if (sz != 0) {                for (unsigned int i =0; i<sz; i++) {                    if (ranges->elementAt(i) != null)                        ranges->elementAt(i)->updateRangeForDeletedNode(oldChild);                }            }        }    }    ChildNode * oldInternal = (ChildNode *) oldChild;    // Patch linked list around oldChild    // Note: lastChild == firstChild->previousSibling    if (oldInternal == value.child) {        // removing first child        oldInternal->isFirstChild(false);        value.child = oldInternal->nextSibling; // firstChild = oldInternal->nextSibling        ChildNode *firstChild = value.child;        if (firstChild != null) {            firstChild->isFirstChild(true);            firstChild->previousSibling = oldInternal->previousSibling;        }    } else {        ChildNode *prev = oldInternal->previousSibling;        ChildNode *next = oldInternal->nextSibling;        prev->nextSibling = next;        if (next == null) {            // removing last child            ChildNode *firstChild = value.child;            firstChild->previousSibling = prev;        } else {            // removing some other child in the middle            next->previousSibling = prev;        }    }    // Remove oldInternal's references to tree    oldInternal->ownerNode = getOwnerDocument();    oldInternal->isOwned(false);    oldInternal->nextSibling = null;    oldInternal->previousSibling = null;    changed();    return oldInternal;};NodeImpl *AttrImpl::replaceChild(NodeImpl *newChild, NodeImpl *oldChild) {    insertBefore(newChild, oldChild);    if (newChild != oldChild) {        removeChild(oldChild);    }    // changed() already done.    return oldChild;}void AttrImpl::setReadOnly(bool readOnl, bool deep) {    NodeImpl::setReadOnly(readOnl, deep);    if (deep) {        if (hasStringValue()) {            return;        }        // Recursively set kids        for (ChildNode *mykid = value.child;             mykid != null;             mykid = mykid->nextSibling)            if(! (mykid->isEntityReference()))                mykid->setReadOnly(readOnl,true);    }}//Introduced in DOM Level 2void AttrImpl::normalize(){    if (hasStringValue()) {        return;    }    ChildNode *kid, *next;    for (kid = value.child; kid != null; kid = next)    {        next = kid->nextSibling;        // If kid and next are both Text nodes (but _not_ CDATASection,        // which is a subclass of Text), they can be merged.        if (next != null &&            kid->isTextImpl()   && !(kid->isCDATASectionImpl())  &&            next->isTextImpl()  && !(next->isCDATASectionImpl()) )        {            ((TextImpl *) kid)->appendData(((TextImpl *) next)->getData());            removeChild(next);            if (next->nodeRefCount == 0)                deleteIf(next);            next = kid; // Don't advance; there might be another.        }        // Otherwise it might be an Element, which is handled recursively        else            if (kid->isElementImpl())                kid->normalize();    };    // changed() will have occurred when the removeChild() was done,    // so does not have to be reissued.};XERCES_CPP_NAMESPACE_END

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?