18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 1999 Antti Koivisto (koivisto@kde.org)
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 2001 Peter Kelly (pmk@post.com)
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *           (C) 2001 Dirk Mueller (mueller@kde.org)
68f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian * Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Library General Public
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful,
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Library General Public License for more details.
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Library General Public License
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * along with this library; see the file COPYING.LIB.  If not, write to
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Boston, MA 02110-1301, USA.
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef NamedAttrMap_h
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define NamedAttrMap_h
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Attribute.h"
298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef __OBJC__
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#define id id_AVOID_KEYWORD
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore {
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
365f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianclass Node;
375f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
385f1ab04193ad0130ca8204aadaceae083aca9881Feng Qiantypedef int ExceptionCode;
395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianclass NamedNodeMap : public RefCounted<NamedNodeMap> {
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    friend class Element;
425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectprotected:
445f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    NamedNodeMap(Element* element) : m_element(element) { }
455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectpublic:
475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    static PassRefPtr<NamedNodeMap> create(Element* element) { return adoptRef(new NamedNodeMap(element)); }
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
495f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    virtual ~NamedNodeMap();
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
515f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Public DOM interface.
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
535f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    PassRefPtr<Node> getNamedItem(const String& name) const;
545f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    PassRefPtr<Node> removeNamedItem(const String& name, ExceptionCode&);
555f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
565f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    PassRefPtr<Node> getNamedItemNS(const String& namespaceURI, const String& localName) const;
575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    PassRefPtr<Node> removeNamedItemNS(const String& namespaceURI, const String& localName, ExceptionCode&);
585f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
595f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    PassRefPtr<Node> getNamedItem(const QualifiedName& name) const;
605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    PassRefPtr<Node> removeNamedItem(const QualifiedName& name, ExceptionCode&);
615f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    PassRefPtr<Node> setNamedItem(Node*, ExceptionCode&);
625f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    PassRefPtr<Node> setNamedItemNS(Node* node, ExceptionCode& ec) { return setNamedItem(node, ec); }
635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
645f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    PassRefPtr<Node> item(unsigned index) const;
658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    size_t length() const { return m_attributes.size(); }
665f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    bool isEmpty() const { return !length(); }
675f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
685f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Internal interface.
695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
705f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    void setAttributes(const NamedNodeMap&);
715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Attribute* attributeItem(unsigned index) const { return m_attributes[index].get(); }
738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Attribute* getAttributeItem(const QualifiedName&) const;
748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void shrinkToLength() { m_attributes.shrinkCapacity(length()); }
768f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    void reserveInitialCapacity(unsigned capacity) { m_attributes.reserveInitialCapacity(capacity); }
778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
785f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    // Used during parsing: only inserts if not already there. No error checking!
798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void insertAttribute(PassRefPtr<Attribute> newAttribute, bool allowDuplicates)
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    {
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        ASSERT(!m_element);
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        if (allowDuplicates || !getAttributeItem(newAttribute->name()))
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            addAttribute(newAttribute);
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    virtual bool isMappedAttributeMap() const;
875f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
888f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    const AtomicString& id() const { return m_id; }
898f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    void setID(const AtomicString& newId) { m_id = newId; }
908f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
915f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian    bool mapsEquivalent(const NamedNodeMap* otherMap) const;
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
938f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // These functions do no error checking.
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void addAttribute(PassRefPtr<Attribute>);
958f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    void removeAttribute(const QualifiedName&);
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
97231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    Element* element() const { return m_element; }
98231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectprotected:
1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    virtual void clearAttributes();
1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1028f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qianprivate:
1038f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    void detachAttributesFromElement();
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    void detachFromElement();
1058f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    Attribute* getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const;
106d0825bca7fe65beaee391d30da42e937db621564Steve Block    Attribute* getAttributeItemSlowCase(const String& name, bool shouldIgnoreAttributeCase) const;
1078f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Element* m_element;
1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Vector<RefPtr<Attribute> > m_attributes;
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    AtomicString m_id;
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project};
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
113d0825bca7fe65beaee391d30da42e937db621564Steve Blockinline Attribute* NamedNodeMap::getAttributeItem(const QualifiedName& name) const
114d0825bca7fe65beaee391d30da42e937db621564Steve Block{
115d0825bca7fe65beaee391d30da42e937db621564Steve Block    unsigned len = length();
116d0825bca7fe65beaee391d30da42e937db621564Steve Block    for (unsigned i = 0; i < len; ++i) {
117d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (m_attributes[i]->name().matches(name))
118d0825bca7fe65beaee391d30da42e937db621564Steve Block            return m_attributes[i].get();
119d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
120d0825bca7fe65beaee391d30da42e937db621564Steve Block    return 0;
121d0825bca7fe65beaee391d30da42e937db621564Steve Block}
122d0825bca7fe65beaee391d30da42e937db621564Steve Block
123d0825bca7fe65beaee391d30da42e937db621564Steve Block// We use a boolean parameter instead of calling shouldIgnoreAttributeCase so that the caller
124d0825bca7fe65beaee391d30da42e937db621564Steve Block// can tune the behaviour (hasAttribute is case sensitive whereas getAttribute is not).
125d0825bca7fe65beaee391d30da42e937db621564Steve Blockinline Attribute* NamedNodeMap::getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const
126d0825bca7fe65beaee391d30da42e937db621564Steve Block{
127d0825bca7fe65beaee391d30da42e937db621564Steve Block    unsigned len = length();
128d0825bca7fe65beaee391d30da42e937db621564Steve Block    bool doSlowCheck = shouldIgnoreAttributeCase;
129d0825bca7fe65beaee391d30da42e937db621564Steve Block
130d0825bca7fe65beaee391d30da42e937db621564Steve Block    // Optimize for the case where the attribute exists and its name exactly matches.
131d0825bca7fe65beaee391d30da42e937db621564Steve Block    for (unsigned i = 0; i < len; ++i) {
132d0825bca7fe65beaee391d30da42e937db621564Steve Block        const QualifiedName& attrName = m_attributes[i]->name();
133d0825bca7fe65beaee391d30da42e937db621564Steve Block        if (!attrName.hasPrefix()) {
134d0825bca7fe65beaee391d30da42e937db621564Steve Block            if (name == attrName.localName())
135d0825bca7fe65beaee391d30da42e937db621564Steve Block                return m_attributes[i].get();
136d0825bca7fe65beaee391d30da42e937db621564Steve Block        } else
137d0825bca7fe65beaee391d30da42e937db621564Steve Block            doSlowCheck = true;
138d0825bca7fe65beaee391d30da42e937db621564Steve Block    }
139d0825bca7fe65beaee391d30da42e937db621564Steve Block
140d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (doSlowCheck)
141d0825bca7fe65beaee391d30da42e937db621564Steve Block        return getAttributeItemSlowCase(name, shouldIgnoreAttributeCase);
142d0825bca7fe65beaee391d30da42e937db621564Steve Block    return 0;
143d0825bca7fe65beaee391d30da42e937db621564Steve Block}
144d0825bca7fe65beaee391d30da42e937db621564Steve Block
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} //namespace
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#undef id
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
150