Home | History | Annotate | Download | only in svg
      1 /*
      2     Copyright (C) 2004, 2005, 2006, 2008 Nikolas Zimmermann <zimmermann (at) kde.org>
      3                   2004, 2005 Rob Buis <buis (at) kde.org>
      4 
      5     This library is free software; you can redistribute it and/or
      6     modify it under the terms of the GNU Library General Public
      7     License as published by the Free Software Foundation; either
      8     version 2 of the License, or (at your option) any later version.
      9 
     10     This library is distributed in the hope that it will be useful,
     11     but WITHOUT ANY WARRANTY; without even the implied warranty of
     12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13     Library General Public License for more details.
     14 
     15     You should have received a copy of the GNU Library General Public License
     16     along with this library; see the file COPYING.LIB.  If not, write to
     17     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     18     Boston, MA 02110-1301, USA.
     19 */
     20 
     21 #ifndef SVGList_h
     22 #define SVGList_h
     23 
     24 #if ENABLE(SVG)
     25 #include "ExceptionCode.h"
     26 #include "SVGListTraits.h"
     27 
     28 #include <wtf/RefCounted.h>
     29 #include <wtf/PassRefPtr.h>
     30 #include <wtf/Vector.h>
     31 
     32 namespace WebCore {
     33 
     34     class QualifiedName;
     35 
     36     template<typename Item>
     37     struct SVGListTypeOperations {
     38         static Item nullItem()
     39         {
     40             return SVGListTraits<UsesDefaultInitializer<Item>::value, Item>::nullItem();
     41         }
     42         static bool isNull(const Item& it)
     43         {
     44             return SVGListTraits<UsesDefaultInitializer<Item>::value, Item>::isNull(it);
     45         }
     46     };
     47 
     48     template<typename Item>
     49     class SVGList : public RefCounted<SVGList<Item> > {
     50     private:
     51         typedef SVGListTypeOperations<Item> TypeOperations;
     52 
     53     public:
     54         virtual ~SVGList() { }
     55 
     56         const QualifiedName& associatedAttributeName() const { return m_associatedAttributeName; }
     57 
     58         unsigned int numberOfItems() const { return m_vector.size(); }
     59         void clear(ExceptionCode &) { m_vector.clear(); }
     60 
     61         Item initialize(Item newItem, ExceptionCode& ec)
     62         {
     63             if (TypeOperations::isNull(newItem)) {
     64                 ec = TYPE_MISMATCH_ERR;
     65                 return TypeOperations::nullItem();
     66             }
     67             clear(ec);
     68             return appendItem(newItem, ec);
     69         }
     70 
     71         Item getFirst() const
     72         {
     73             ExceptionCode ec = 0;
     74             return getItem(0, ec);
     75         }
     76 
     77         Item getLast() const
     78         {
     79             ExceptionCode ec = 0;
     80             return getItem(m_vector.size() - 1, ec);
     81         }
     82 
     83         Item getItem(unsigned int index, ExceptionCode& ec)
     84         {
     85             if (index >= m_vector.size()) {
     86                 ec = INDEX_SIZE_ERR;
     87                 return TypeOperations::nullItem();
     88             }
     89 
     90             return m_vector.at(index);
     91         }
     92 
     93         const Item getItem(unsigned int index, ExceptionCode& ec) const
     94         {
     95             if (index >= m_vector.size()) {
     96                 ec = INDEX_SIZE_ERR;
     97                 return TypeOperations::nullItem();
     98             }
     99 
    100             return m_vector[index];
    101         }
    102 
    103         Item insertItemBefore(Item newItem, unsigned int index, ExceptionCode& ec)
    104         {
    105             if (TypeOperations::isNull(newItem)) {
    106                 ec = TYPE_MISMATCH_ERR;
    107                 return TypeOperations::nullItem();
    108             }
    109 
    110             if (index < m_vector.size()) {
    111                 m_vector.insert(index, newItem);
    112             } else {
    113                 m_vector.append(newItem);
    114             }
    115             return newItem;
    116         }
    117 
    118         Item replaceItem(Item newItem, unsigned int index, ExceptionCode& ec)
    119         {
    120             if (index >= m_vector.size()) {
    121                 ec = INDEX_SIZE_ERR;
    122                 return TypeOperations::nullItem();
    123             }
    124 
    125             if (TypeOperations::isNull(newItem)) {
    126                 ec = TYPE_MISMATCH_ERR;
    127                 return TypeOperations::nullItem();
    128             }
    129 
    130             m_vector[index] = newItem;
    131             return newItem;
    132         }
    133 
    134         Item removeItem(unsigned int index, ExceptionCode& ec)
    135         {
    136             if (index >= m_vector.size()) {
    137                 ec = INDEX_SIZE_ERR;
    138                 return TypeOperations::nullItem();
    139             }
    140 
    141             Item item = m_vector[index];
    142             m_vector.remove(index);
    143             return item;
    144         }
    145 
    146         Item appendItem(Item newItem, ExceptionCode& ec)
    147         {
    148             if (TypeOperations::isNull(newItem)) {
    149                 ec = TYPE_MISMATCH_ERR;
    150                 return TypeOperations::nullItem();
    151             }
    152 
    153             m_vector.append(newItem);
    154             return newItem;
    155         }
    156 
    157     protected:
    158         SVGList(const QualifiedName& attributeName)
    159             : m_associatedAttributeName(attributeName)
    160         {
    161         }
    162 
    163     private:
    164         Vector<Item> m_vector;
    165         const QualifiedName& m_associatedAttributeName;
    166     };
    167 
    168     template<typename Item>
    169     class SVGPODListItem : public RefCounted<SVGPODListItem<Item> > {
    170     public:
    171         static PassRefPtr<SVGPODListItem> create() { return adoptRef(new SVGPODListItem); }
    172         static PassRefPtr<SVGPODListItem> copy(const Item& item) { return adoptRef(new SVGPODListItem(item)); }
    173 
    174         operator Item&() { return m_item; }
    175         operator const Item&() const { return m_item; }
    176 
    177         // Updating facilities, used by JSSVGPODTypeWrapperCreatorForList
    178         Item value() const { return m_item; }
    179         void setValue(const Item& newItem) { m_item = newItem; }
    180 
    181     private:
    182         SVGPODListItem() : m_item() { }
    183         SVGPODListItem(const Item& item) : RefCounted<SVGPODListItem<Item> >(), m_item(item) { }
    184 
    185         Item m_item;
    186     };
    187 
    188     template<typename Item>
    189     class SVGPODList : public SVGList<RefPtr<SVGPODListItem<Item> > > {
    190     public:
    191         Item initialize(Item newItem, ExceptionCode& ec)
    192         {
    193             SVGPODListItem<Item>* ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::initialize(SVGPODListItem<Item>::copy(newItem), ec).get());
    194             if (!ptr)
    195                 return Item();
    196 
    197             return static_cast<const Item&>(*ptr);
    198         }
    199 
    200         Item getFirst() const
    201         {
    202             SVGPODListItem<Item>* ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::getFirst().get());
    203             if (!ptr)
    204                 return Item();
    205 
    206             return static_cast<const Item&>(*ptr);
    207         }
    208 
    209         Item getLast() const
    210         {
    211             SVGPODListItem<Item>* ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::getLast().get());
    212             if (!ptr)
    213                 return Item();
    214 
    215             return static_cast<const Item&>(*ptr);
    216         }
    217 
    218         Item getItem(unsigned int index, ExceptionCode& ec)
    219         {
    220             SVGPODListItem<Item>* ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::getItem(index, ec).get());
    221             if (!ptr)
    222                 return Item();
    223 
    224             return static_cast<const Item&>(*ptr);
    225         }
    226 
    227         const Item getItem(unsigned int index, ExceptionCode& ec) const
    228         {
    229             SVGPODListItem<Item>* ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::getItem(index, ec).get());
    230              if (!ptr)
    231                 return Item();
    232 
    233             return static_cast<const Item&>(*ptr);
    234         }
    235 
    236         Item insertItemBefore(Item newItem, unsigned int index, ExceptionCode& ec)
    237         {
    238             SVGPODListItem<Item>* ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::insertItemBefore(SVGPODListItem<Item>::copy(newItem), index, ec).get());
    239             if (!ptr)
    240                 return Item();
    241 
    242             return static_cast<const Item&>(*ptr);
    243         }
    244 
    245         Item replaceItem(Item newItem, unsigned int index, ExceptionCode& ec)
    246         {
    247             SVGPODListItem<Item>* ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::replaceItem(SVGPODListItem<Item>::copy(newItem), index, ec).get());
    248             if (!ptr)
    249                 return Item();
    250 
    251             return static_cast<const Item&>(*ptr);
    252         }
    253 
    254         Item removeItem(unsigned int index, ExceptionCode& ec)
    255         {
    256             SVGPODListItem<Item>* ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::removeItem(index, ec).get());
    257             if (!ptr)
    258                 return Item();
    259 
    260             return static_cast<const Item&>(*ptr);
    261         }
    262 
    263         Item appendItem(Item newItem, ExceptionCode& ec)
    264         {
    265             SVGPODListItem<Item>* ptr(SVGList<RefPtr<SVGPODListItem<Item> > >::appendItem(SVGPODListItem<Item>::copy(newItem), ec).get());
    266             if (!ptr)
    267                 return Item();
    268 
    269             return static_cast<const Item&>(*ptr);
    270         }
    271 
    272     protected:
    273         SVGPODList(const QualifiedName& attributeName)
    274             : SVGList<RefPtr<SVGPODListItem<Item> > >(attributeName) { }
    275     };
    276 
    277 } // namespace WebCore
    278 
    279 #endif // ENABLE(SVG)
    280 #endif // SVGList_h
    281