File indexing completed on 2024-04-28 15:24:35

0001 /*
0002     Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
0003                   2004, 2005 Rob Buis <buis@kde.org>
0004 
0005     This file is part of the KDE project
0006 
0007     This library is free software; you can redistribute it and/or
0008     modify it under the terms of the GNU Library General Public
0009     License as published by the Free Software Foundation; either
0010     version 2 of the License, or (at your option) any later version.
0011 
0012     This library is distributed in the hope that it will be useful,
0013     but WITHOUT ANY WARRANTY; without even the implied warranty of
0014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015     Library General Public License for more details.
0016 
0017     You should have received a copy of the GNU Library General Public License
0018     along with this library; see the file COPYING.LIB.  If not, write to
0019     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020     Boston, MA 02110-1301, USA.
0021 */
0022 
0023 #ifndef SVGList_h
0024 #define SVGList_h
0025 
0026 #if ENABLE(SVG)
0027 #include "ExceptionCode.h"
0028 #include "SVGListTraits.h"
0029 #include "Document.h"
0030 
0031 #include <wtf/RefCounted.h>
0032 #include <wtf/PassRefPtr.h>
0033 #include <wtf/Vector.h>
0034 
0035 namespace WebCore
0036 {
0037 
0038 //class QualifiedName;
0039 
0040 template<typename Item>
0041 struct SVGListTypeOperations {
0042     static Item nullItem()
0043     {
0044         return SVGListTraits<UsesDefaultInitializer<Item>::value, Item>::nullItem();
0045     }
0046 };
0047 
0048 template<typename Item>
0049 class SVGList : public RefCounted<SVGList<Item> >
0050 {
0051 private:
0052     typedef SVGListTypeOperations<Item> TypeOperations;
0053 
0054 public:
0055     virtual ~SVGList() { }
0056 
0057     const QualifiedName &associatedAttributeName() const
0058     {
0059         return m_associatedAttributeName;
0060     }
0061 
0062     unsigned int numberOfItems() const
0063     {
0064         return m_vector.size();
0065     }
0066     void clear(ExceptionCode &)
0067     {
0068         m_vector.clear();
0069     }
0070 
0071     Item initialize(Item newItem, ExceptionCode &ec)
0072     {
0073         clear(ec);
0074         return appendItem(newItem, ec);
0075     }
0076 
0077     Item getFirst() const
0078     {
0079         ExceptionCode ec = 0;
0080         return getItem(0, ec);
0081     }
0082 
0083     Item getLast() const
0084     {
0085         ExceptionCode ec = 0;
0086         return getItem(m_vector.size() - 1, ec);
0087     }
0088 
0089     Item getItem(unsigned int index, ExceptionCode &ec)
0090     {
0091         if (index >= m_vector.size()) {
0092             ec = DOMException::INDEX_SIZE_ERR;
0093             return TypeOperations::nullItem();
0094         }
0095 
0096         return m_vector.at(index);
0097     }
0098 
0099     const Item getItem(unsigned int index, ExceptionCode &ec) const
0100     {
0101         if (index >= m_vector.size()) {
0102             ec = DOMException::INDEX_SIZE_ERR;
0103             return TypeOperations::nullItem();
0104         }
0105 
0106         return m_vector[index];
0107     }
0108 
0109     Item insertItemBefore(Item newItem, unsigned int index, ExceptionCode &)
0110     {
0111         if (index < m_vector.size()) {
0112             m_vector.insert(index, newItem);
0113         } else {
0114             m_vector.append(newItem);
0115         }
0116         return newItem;
0117     }
0118 
0119     Item replaceItem(Item newItem, unsigned int index, ExceptionCode &ec)
0120     {
0121         if (index >= m_vector.size()) {
0122             ec = DOMException::INDEX_SIZE_ERR;
0123             return TypeOperations::nullItem();
0124         }
0125 
0126         m_vector[index] = newItem;
0127         return newItem;
0128     }
0129 
0130     Item removeItem(unsigned int index, ExceptionCode &ec)
0131     {
0132         if (index >= m_vector.size()) {
0133             ec = DOMException::INDEX_SIZE_ERR;
0134             return TypeOperations::nullItem();
0135         }
0136 
0137         Item item = m_vector[index];
0138         m_vector.remove(index);
0139         return item;
0140     }
0141 
0142     Item appendItem(Item newItem, ExceptionCode &)
0143     {
0144         m_vector.append(newItem);
0145         return newItem;
0146     }
0147 
0148 protected:
0149     SVGList(const QualifiedName &attributeName)
0150         : m_associatedAttributeName(attributeName)
0151     {
0152     }
0153 
0154 private:
0155     Vector<Item> m_vector;
0156     const QualifiedName &m_associatedAttributeName;
0157 };
0158 
0159 template<typename Item>
0160 class SVGPODListItem : public RefCounted<SVGPODListItem<Item> >
0161 {
0162 public:
0163     static PassRefPtr<SVGPODListItem> create()
0164     {
0165         return adoptRef(new SVGPODListItem);
0166     }
0167     static PassRefPtr<SVGPODListItem> copy(const Item &item)
0168     {
0169         return adoptRef(new SVGPODListItem(item));
0170     }
0171 
0172     operator Item &()
0173     {
0174         return m_item;
0175     }
0176     operator const Item &() const
0177     {
0178         return m_item;
0179     }
0180 
0181     // Updating facilities, used by JSSVGPODTypeWrapperCreatorForList
0182     Item value() const
0183     {
0184         return m_item;
0185     }
0186     void setValue(Item newItem)
0187     {
0188         m_item = newItem;
0189     }
0190 
0191 private:
0192     SVGPODListItem() : m_item() { }
0193     SVGPODListItem(const Item &item) : RefCounted<SVGPODListItem<Item> >(), m_item(item) { }
0194 
0195     Item m_item;
0196 };
0197 
0198 template<typename Item>
0199 class SVGPODList : public SVGList<RefPtr<SVGPODListItem<Item> > >
0200 {
0201 public:
0202     Item initialize(Item newItem, ExceptionCode &ec)
0203     {
0204         SVGPODListItem<Item> *ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::initialize(SVGPODListItem<Item>::copy(newItem), ec).get());
0205         if (!ptr) {
0206             return Item();
0207         }
0208 
0209         return static_cast<const Item &>(*ptr);
0210     }
0211 
0212     Item getFirst() const
0213     {
0214         SVGPODListItem<Item> *ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::getFirst().get());
0215         if (!ptr) {
0216             return Item();
0217         }
0218 
0219         return static_cast<const Item &>(*ptr);
0220     }
0221 
0222     Item getLast() const
0223     {
0224         SVGPODListItem<Item> *ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::getLast().get());
0225         if (!ptr) {
0226             return Item();
0227         }
0228 
0229         return static_cast<const Item &>(*ptr);
0230     }
0231 
0232     Item getItem(unsigned int index, ExceptionCode &ec)
0233     {
0234         SVGPODListItem<Item> *ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::getItem(index, ec).get());
0235         if (!ptr) {
0236             return Item();
0237         }
0238 
0239         return static_cast<const Item &>(*ptr);
0240     }
0241 
0242     const Item getItem(unsigned int index, ExceptionCode &ec) const
0243     {
0244         SVGPODListItem<Item> *ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::getItem(index, ec).get());
0245         if (!ptr) {
0246             return Item();
0247         }
0248 
0249         return static_cast<const Item &>(*ptr);
0250     }
0251 
0252     Item insertItemBefore(Item newItem, unsigned int index, ExceptionCode &ec)
0253     {
0254         SVGPODListItem<Item> *ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::insertItemBefore(SVGPODListItem<Item>::copy(newItem), index, ec).get());
0255         if (!ptr) {
0256             return Item();
0257         }
0258 
0259         return static_cast<const Item &>(*ptr);
0260     }
0261 
0262     Item replaceItem(Item newItem, unsigned int index, ExceptionCode &ec)
0263     {
0264         SVGPODListItem<Item> *ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::replaceItem(SVGPODListItem<Item>::copy(newItem), index, ec).get());
0265         if (!ptr) {
0266             return Item();
0267         }
0268 
0269         return static_cast<const Item &>(*ptr);
0270     }
0271 
0272     Item removeItem(unsigned int index, ExceptionCode &ec)
0273     {
0274         SVGPODListItem<Item> *ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::removeItem(index, ec).get());
0275         if (!ptr) {
0276             return Item();
0277         }
0278 
0279         return static_cast<const Item &>(*ptr);
0280     }
0281 
0282     Item appendItem(Item newItem, ExceptionCode &ec)
0283     {
0284         SVGPODListItem<Item> *ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::appendItem(SVGPODListItem<Item>::copy(newItem), ec).get());
0285         if (!ptr) {
0286             return Item();
0287         }
0288 
0289         return static_cast<const Item &>(*ptr);
0290     }
0291 
0292 protected:
0293     SVGPODList(const QualifiedName &attributeName)
0294         : SVGList<RefPtr<SVGPODListItem<Item> > >(attributeName) { }
0295 };
0296 
0297 } // namespace WebCore
0298 
0299 #endif // ENABLE(SVG)
0300 #endif // SVGList_h