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