示例#1
0
const XMLCh * DOMAttrImpl::getValue() const
{
    if (fParent.fFirstChild == 0) {
        return XMLUni::fgZeroLenString; // return "";
    }

    // Simple case where attribute value is just a single text node
    DOMNode *node = castToChildImpl(fParent.fFirstChild)->nextSibling;
    if (node == 0 && fParent.fFirstChild->getNodeType() == DOMNode::TEXT_NODE) {
        return fParent.fFirstChild->getNodeValue();
    }

    //
    // Complicated case where attribute value is a DOM tree
    //
    // According to the spec, the child nodes of the Attr node may be either
    // Text or EntityReference nodes.
    //
    // The parser will not create such thing, this is for those created by users.
    //
    // In such case, we have to visit each child to retrieve the text
    //

    DOMDocumentImpl* doc = (DOMDocumentImpl*)fParent.fOwnerDocument;

    XMLBuffer buf(1023, doc->getMemoryManager());
    for (node = fParent.fFirstChild; node != 0; node = castToChildImpl(node)->nextSibling)
        getTextValue(node, buf);

    return doc->getPooledString(buf.getRawBuffer());
}
示例#2
0
void DOMParentNode::normalize()
{
    DOMNode *kid, *next;
    for (kid = fFirstChild; kid != 0; kid = next)
    {
        next = castToChildImpl(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 != 0 &&
            kid->getNodeType() == DOMNode::TEXT_NODE   &&
            next->getNodeType() == DOMNode::TEXT_NODE )
        {
            ((DOMTextImpl *) kid)->appendData(((DOMTextImpl *) next)->getData());
            // revisit:
            //   should I release the removed node?
            //   not released in case user still referencing it externally
            removeChild(next);
            next = kid; // Don't advance; there might be another.
        }

        // Otherwise it might be an Element, which is handled recursively
        else
            if (kid->getNodeType() == DOMNode::ELEMENT_NODE)
                kid->normalize();
    }

    // changed() will have occurred when the removeChild() was done,
    // so does not have to be reissued.
}
示例#3
0
//
//  revisit.  Is this function used anywhere?  I don't see it.
//
void DOMParentNode::lastChild(DOMNode *node) {
    // store lastChild as previous sibling of first child
    if (fFirstChild != 0) {
        DOMChildNode *firstChild = castToChildImpl(fFirstChild);
        firstChild->previousSibling = node;
    }
}
DOMCDATASectionImpl::DOMCDATASectionImpl(const DOMCDATASectionImpl &other, bool /*deep*/)
    : DOMCDATASection(other),
      fNode(*castToNodeImpl(&other)),
      fChild(*castToChildImpl(&other)),
      fCharacterData(other.fCharacterData)
{
    // revisit.  Something nees to make "deep" work.
}
示例#5
0
DOMCDATASectionImpl::DOMCDATASectionImpl(const DOMCDATASectionImpl &other, bool)
    : fNode(*castToNodeImpl(&other)),
    fParent(*castToParentImpl(&other)),
    fChild(*castToChildImpl(&other)),
    fCharacterData(other.fCharacterData)
{
    // revisit.  SOmething nees to make "deep" work.
}
示例#6
0
DOMNode *DOMNodeListImpl::item(XMLSize_t index) const{
    if (fNode) {
        DOMNode *node = castToParentImpl(fNode)->fFirstChild;
        for(XMLSize_t i=0; i<index && node!=0; ++i)
            node = castToChildImpl(node)->nextSibling;
        return node;
    }
    return 0;
}
示例#7
0
DOMNode * DOMParentNode::lastChild() const
{
    // last child is stored as the previous sibling of first child
    if (fFirstChild == 0) {
        return 0;
    }

    DOMChildNode *firstChild = castToChildImpl(fFirstChild);
    DOMNode *ret = firstChild->previousSibling;
    return ret;
}
示例#8
0
XMLSize_t DOMNodeListImpl::getLength() const{
    XMLSize_t count = 0;
    if (fNode) {
        DOMNode *node = castToParentImpl(fNode)->fFirstChild;
        while(node != 0){
            ++count;
            node = castToChildImpl(node)->nextSibling;
        }
    }

    return count;
}
示例#9
0
//Non-standard extension
void DOMParentNode::release()
{
    DOMNode *kid, *next;
    for (kid = fFirstChild; kid != 0; kid = next)
    {
        next = castToChildImpl(kid)->nextSibling;

        // set is Owned false before releasing its child
        castToNodeImpl(kid)->isToBeReleased(true);
        kid->release();
    }
}
示例#10
0
DOMNode * DOMParentNode::appendChildFast(DOMNode *newChild)
{
    // This function makes the following assumptions:
    //
    // - newChild != 0
    // - newChild is not read-only
    // - newChild is not a document fragment
    // - owner documents of this node and newChild are the same
    // - appending newChild to this node cannot result in a cycle
    // - DOMDocumentImpl::isKidOK (this, newChild) return true (that is,
    //   appending newChild to this node results in a valid structure)
    // - newChild->getParentNode() is 0
    // - there are no ranges set for this document
    //

    // Attach up
    castToNodeImpl(newChild)->fOwnerNode = castToNode(this);
    castToNodeImpl(newChild)->isOwned(true);

    // Attach before and after
    // Note: fFirstChild.previousSibling == lastChild!!
    if (fFirstChild != 0)
    {
        DOMNode *lastChild = castToChildImpl(fFirstChild)->previousSibling;
        castToChildImpl(lastChild)->nextSibling = newChild;
        castToChildImpl(newChild)->previousSibling = lastChild;
        castToChildImpl(fFirstChild)->previousSibling = newChild;
    }
    else
    {
        // this our first and only child
        fFirstChild = newChild;
        castToNodeImpl(newChild)->isFirstChild(true);
        // castToChildImpl(newChild)->previousSibling = newChild;
        DOMChildNode *newChild_ci = castToChildImpl(newChild);
        newChild_ci->previousSibling = newChild;
    }

    return newChild;
}
示例#11
0
文件: DOMAttrImpl.cpp 项目: mydw/mydw
void DOMAttrImpl::getTextValue(DOMNode* node, XMLBuffer& buf) const
{
    if (node->getNodeType() == DOMNode::TEXT_NODE)
        buf.append(node->getNodeValue());
    else if (node->getNodeType() == DOMNode::ENTITY_REFERENCE_NODE)
    {
        for (node = node->getFirstChild(); node != 0; node = castToChildImpl(node)->nextSibling)
        {
            getTextValue(node, buf);
        }
    }

    return;
}
示例#12
0
DOMNode *DOMParentNode::removeChild(DOMNode *oldChild)
{
    if (castToNodeImpl(this)->isReadOnly())
        throw DOMException(
        DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMParentNodeMemoryManager);

    if (oldChild == 0 || oldChild->getParentNode() != castToNode(this))
        throw DOMException(DOMException::NOT_FOUND_ERR, 0, GetDOMParentNodeMemoryManager);

    if (this->getOwnerDocument() !=  0  ) {
        //notify iterators
        NodeIterators* nodeIterators = ((DOMDocumentImpl *)this->getOwnerDocument())->getNodeIterators();
        if (nodeIterators != 0) {
            XMLSize_t sz = nodeIterators->size();
            if (sz != 0) {
                for (XMLSize_t i =0; i<sz; i++) {
                    if (nodeIterators->elementAt(i) != 0)
                        nodeIterators->elementAt(i)->removeNode(oldChild);
                }
            }
        }

        //fix other ranges for change before deleting the node
        Ranges* ranges = ((DOMDocumentImpl *)this->getOwnerDocument())->getRanges();
        if (ranges != 0) {
            XMLSize_t sz = ranges->size();
            if (sz != 0) {
                for (XMLSize_t i =0; i<sz; i++) {
                    if (ranges->elementAt(i) != 0)
                        ranges->elementAt(i)->updateRangeForDeletedNode(oldChild);
                }
            }
        }
    }


    // Patch linked list around oldChild
    // Note: lastChild == fFirstChild->previousSibling
    if (oldChild == fFirstChild) {
        // removing first child
        castToNodeImpl(oldChild)->isFirstChild(false);
        fFirstChild = castToChildImpl(oldChild)->nextSibling;
        if (fFirstChild != 0) {
            castToNodeImpl(fFirstChild)->isFirstChild(true);
            castToChildImpl(fFirstChild)->previousSibling = castToChildImpl(oldChild)->previousSibling;
        }
    } else {
        DOMNode *prev = castToChildImpl(oldChild)->previousSibling;
        DOMNode *next = castToChildImpl(oldChild)->nextSibling;
        castToChildImpl(prev)->nextSibling = next;
        if (next == 0) {
            // removing last child
            castToChildImpl(fFirstChild)->previousSibling = prev;
        } else {
            // removing some other child in the middle
            castToChildImpl(next)->previousSibling = prev;
        }
    }

    // Remove oldChild's references to tree
    castToNodeImpl(oldChild)->fOwnerNode = fOwnerDocument;
    castToNodeImpl(oldChild)->isOwned(false);
    castToChildImpl(oldChild)->nextSibling = 0;
    castToChildImpl(oldChild)->previousSibling = 0;

    changed();

    return oldChild;
}
示例#13
0
DOMNode *DOMParentNode::insertBefore(DOMNode *newChild, DOMNode *refChild) {
    //not really in the specs, but better than nothing
    if(newChild==NULL)
        throw DOMException(DOMException::HIERARCHY_REQUEST_ERR,0, GetDOMParentNodeMemoryManager);

    DOMNodeImpl *thisNodeImpl = castToNodeImpl(this);
    if (thisNodeImpl->isReadOnly())
        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, GetDOMParentNodeMemoryManager);

    if (newChild->getOwnerDocument() != fOwnerDocument)
        throw DOMException(DOMException::WRONG_DOCUMENT_ERR, 0, GetDOMParentNodeMemoryManager);

    // Prevent cycles in the tree
    //only need to do this if the node has children
    if(newChild->hasChildNodes()) {
        bool treeSafe=true;
        for(DOMNode *a=castToNode(this)->getParentNode();
            treeSafe && a!=0;
            a=a->getParentNode())
            treeSafe=(newChild!=a);
        if(!treeSafe)
            throw DOMException(DOMException::HIERARCHY_REQUEST_ERR,0, GetDOMParentNodeMemoryManager);
    }

    // refChild must in fact be a child of this node (or 0)
    if (refChild!=0 && refChild->getParentNode() != castToNode(this))
        throw DOMException(DOMException::NOT_FOUND_ERR,0, GetDOMParentNodeMemoryManager);

    // if the new node has to be placed before itself, we don't have to do anything 
    // (even worse, we would crash if we continue, as we assume they are two distinct nodes)
    if (refChild!=0 && newChild->isSameNode(refChild))
        return newChild;

    if (newChild->getNodeType() == DOMNode::DOCUMENT_FRAGMENT_NODE)
    {
        // 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.
        for(DOMNode *kid=newChild->getFirstChild(); // Prescan
              kid!=0;
              kid=kid->getNextSibling())
        {
            if (!DOMDocumentImpl::isKidOK(castToNode(this), kid))
              throw DOMException(DOMException::HIERARCHY_REQUEST_ERR,0, GetDOMParentNodeMemoryManager);
        }
        while(newChild->hasChildNodes())     // Move
            insertBefore(newChild->getFirstChild(),refChild);
    }

    else if (!DOMDocumentImpl::isKidOK(castToNode(this), newChild))
        throw DOMException(DOMException::HIERARCHY_REQUEST_ERR,0, GetDOMParentNodeMemoryManager);

    else
    {
        DOMNode *oldparent=newChild->getParentNode();
        if(oldparent!=0)
            oldparent->removeChild(newChild);

        // Attach up
        castToNodeImpl(newChild)->fOwnerNode = castToNode(this);
        castToNodeImpl(newChild)->isOwned(true);

        // Attach before and after
        // Note: fFirstChild.previousSibling == lastChild!!
        if (fFirstChild == 0) {
            // this our first and only child
            fFirstChild = newChild;
            castToNodeImpl(newChild)->isFirstChild(true);
            // castToChildImpl(newChild)->previousSibling = newChild;
            DOMChildNode *newChild_ci = castToChildImpl(newChild);
            newChild_ci->previousSibling = newChild;
        } else {
            if (refChild == 0) {
                // this is an append
                DOMNode *lastChild = castToChildImpl(fFirstChild)->previousSibling;
                castToChildImpl(lastChild)->nextSibling = newChild;
                castToChildImpl(newChild)->previousSibling = lastChild;
                castToChildImpl(fFirstChild)->previousSibling = newChild;
            } else {
                // this is an insert
                if (refChild == fFirstChild) {
                    // at the head of the list
                    castToNodeImpl(fFirstChild)->isFirstChild(false);
                    castToChildImpl(newChild)->nextSibling = fFirstChild;
                    castToChildImpl(newChild)->previousSibling = castToChildImpl(fFirstChild)->previousSibling;
                    castToChildImpl(fFirstChild)->previousSibling = newChild;
                    fFirstChild = newChild;
                    castToNodeImpl(newChild)->isFirstChild(true);
                } else {
                    // somewhere in the middle
                    DOMNode *prev = castToChildImpl(refChild)->previousSibling;
                    castToChildImpl(newChild)->nextSibling = refChild;
                    castToChildImpl(prev)->nextSibling = newChild;
                    castToChildImpl(refChild)->previousSibling = newChild;
                    castToChildImpl(newChild)->previousSibling = prev;
                }
            }
        }
    }

    changed();

    if (this->getOwnerDocument() != 0) {
        Ranges* ranges = ((DOMDocumentImpl *)this->getOwnerDocument())->getRanges();
        if ( ranges != 0) {
            XMLSize_t sz = ranges->size();
            if (sz != 0) {
                for (XMLSize_t i =0; i<sz; i++) {
                    ranges->elementAt(i)->updateRangeForInsertedNode(newChild);
                }
            }
        }
    }

    return newChild;
}
示例#14
0
DOMNode *XPathDocumentImpl::insertBefore(DOMNode *newChild, DOMNode *refChild)
{
    // if the newChild is a documenttype node created from domimplementation, set the ownerDoc first
    if ((newChild->getNodeType() == DOMNode::DOCUMENT_TYPE_NODE) && !newChild->getOwnerDocument())
        ((DOMDocumentTypeImpl*)newChild)->setOwnerDocument(this);

    if(newChild==NULL)
        throw DOMException(DOMException::HIERARCHY_REQUEST_ERR,0, getMemoryManager());

    DOMNodeImpl *thisNodeImpl = castToNodeImpl(this);
    if (thisNodeImpl->isReadOnly())
        throw DOMException(DOMException::NO_MODIFICATION_ALLOWED_ERR, 0, getMemoryManager());

    DOMNode* thisNode = castToNode(&fParent);
    if (newChild->getOwnerDocument() != thisNode)
        throw DOMException(DOMException::WRONG_DOCUMENT_ERR, 0, getMemoryManager());

    // refChild must in fact be a child of this node (or 0)
    if (refChild!=0 && refChild->getParentNode() != thisNode)
        throw DOMException(DOMException::NOT_FOUND_ERR,0, getMemoryManager());

    // if the new node has to be placed before itself, we don't have to do anything 
    // (even worse, we would crash if we continue, as we assume they are two distinct nodes)
    if (refChild!=0 && newChild->isSameNode(refChild))
        return newChild;

    if (newChild->getNodeType() == DOMNode::DOCUMENT_FRAGMENT_NODE)
    {
        // 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.

        while(newChild->hasChildNodes())     // Move
            insertBefore(newChild->getFirstChild(),refChild);
    }

    else
    {
        DOMNode *oldparent=newChild->getParentNode();
        if(oldparent!=0)
            oldparent->removeChild(newChild);

        // Attach up
        castToNodeImpl(newChild)->fOwnerNode = thisNode;
        castToNodeImpl(newChild)->isOwned(true);

        // Attach before and after
        // Note: fFirstChild.previousSibling == lastChild!!
        if (fParent.fFirstChild == 0) {
            // this our first and only child
            fParent.fFirstChild = newChild;
            castToNodeImpl(newChild)->isFirstChild(true);
            // castToChildImpl(newChild)->previousSibling = newChild;
            DOMChildNode *newChild_ci = castToChildImpl(newChild);
            newChild_ci->previousSibling = newChild;
        } else {
            if (refChild == 0) {
                // this is an append
                DOMNode *lastChild = castToChildImpl(fParent.fFirstChild)->previousSibling;
                castToChildImpl(lastChild)->nextSibling = newChild;
                castToChildImpl(newChild)->previousSibling = lastChild;
                castToChildImpl(fParent.fFirstChild)->previousSibling = newChild;
            } else {
                // this is an insert
                if (refChild == fParent.fFirstChild) {
                    // at the head of the list
                    castToNodeImpl(fParent.fFirstChild)->isFirstChild(false);
                    castToChildImpl(newChild)->nextSibling = fParent.fFirstChild;
                    castToChildImpl(newChild)->previousSibling = castToChildImpl(fParent.fFirstChild)->previousSibling;
                    castToChildImpl(fParent.fFirstChild)->previousSibling = newChild;
                    fParent.fFirstChild = newChild;
                    castToNodeImpl(newChild)->isFirstChild(true);
                } else {
                    // somewhere in the middle
                    DOMNode *prev = castToChildImpl(refChild)->previousSibling;
                    castToChildImpl(newChild)->nextSibling = refChild;
                    castToChildImpl(prev)->nextSibling = newChild;
                    castToChildImpl(refChild)->previousSibling = newChild;
                    castToChildImpl(newChild)->previousSibling = prev;
                }
            }
        }
    }

    changed();

    Ranges* ranges = getRanges();
    if ( ranges != 0) {
        XMLSize_t sz = ranges->size();
        if (sz != 0) {
            for (XMLSize_t i =0; i<sz; i++) {
                ranges->elementAt(i)->updateRangeForInsertedNode(newChild);
            }
        }
    }

    // If insert succeeded, cache the kid appropriately
    if(newChild->getNodeType() == DOMNode::ELEMENT_NODE)
        fMyDocElement=(DOMElement *)newChild;
    else if(newChild->getNodeType() == DOMNode::DOCUMENT_TYPE_NODE)
        fMyDocType=(DOMDocumentType *)newChild;

    return newChild;
}