fix tricky regression noticed by Vyacheslav Tokarev on Google Reader.
[kdelibs.git] / khtml / bindings / js / JSSVGPODTypeWrapper.h
blob8d223b5710d7de0dbcd5b9ff7d9c64551770ff87
1 /*
2 * Copyright (C) 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2008 Apple Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #ifndef JSSVGPODTypeWrapper_h
28 #define JSSVGPODTypeWrapper_h
30 #if ENABLE(SVG)
32 #include "Frame.h"
33 #include <wtf/RefCounted.h>
34 #include "SVGElement.h"
36 #include <wtf/Assertions.h>
37 #include <wtf/HashMap.h>
39 namespace WebCore {
40 template<typename PODType>
41 class SVGPODListItem;
44 using namespace WebCore;
46 namespace khtml {
48 template<typename PODType>
49 class JSSVGPODTypeWrapper : public RefCounted<JSSVGPODTypeWrapper<PODType> > {
50 public:
51 JSSVGPODTypeWrapper() : RefCounted<JSSVGPODTypeWrapper<PODType> >(0) { }
52 virtual ~JSSVGPODTypeWrapper() { }
54 // Getter wrapper
55 virtual operator PODType() = 0;
57 // Setter wrapper
58 virtual void commitChange(PODType, SVGElement*) = 0;
61 template<typename PODType, typename PODTypeCreator>
62 class JSSVGPODTypeWrapperCreatorReadWrite : public JSSVGPODTypeWrapper<PODType>
64 public:
65 typedef PODType (PODTypeCreator::*GetterMethod)() const;
66 typedef void (PODTypeCreator::*SetterMethod)(PODType);
68 JSSVGPODTypeWrapperCreatorReadWrite(PODTypeCreator* creator, GetterMethod getter, SetterMethod setter)
69 : m_creator(creator)
70 , m_getter(getter)
71 , m_setter(setter)
73 ASSERT(creator);
74 ASSERT(getter);
75 ASSERT(setter);
78 virtual ~JSSVGPODTypeWrapperCreatorReadWrite() { }
80 // Getter wrapper
81 virtual operator PODType() { return (m_creator.get()->*m_getter)(); }
83 // Setter wrapper
84 virtual void commitChange(PODType type, SVGElement* context)
86 if (!m_setter)
87 return;
89 (m_creator.get()->*m_setter)(type);
91 if (context)
92 context->svgAttributeChanged(m_creator->associatedAttributeName());
95 private:
96 // Update callbacks
97 RefPtr<PODTypeCreator> m_creator;
98 GetterMethod m_getter;
99 SetterMethod m_setter;
102 template<typename PODType>
103 class JSSVGPODTypeWrapperCreatorReadOnly : public JSSVGPODTypeWrapper<PODType>
105 public:
106 JSSVGPODTypeWrapperCreatorReadOnly(PODType type)
107 : m_podType(type)
110 virtual ~JSSVGPODTypeWrapperCreatorReadOnly() { }
112 // Getter wrapper
113 virtual operator PODType() { return m_podType; }
115 // Setter wrapper
116 virtual void commitChange(PODType type, SVGElement*)
118 m_podType = type;
121 private:
122 PODType m_podType;
125 template<typename PODType>
126 class JSSVGPODTypeWrapperCreatorForList : public JSSVGPODTypeWrapper<PODType>
128 public:
129 typedef PODType (SVGPODListItem<PODType>::*GetterMethod)() const;
130 typedef void (SVGPODListItem<PODType>::*SetterMethod)(PODType);
132 JSSVGPODTypeWrapperCreatorForList(SVGPODListItem<PODType>* creator, const QualifiedName& attributeName)
133 : m_creator(creator)
134 , m_getter(&SVGPODListItem<PODType>::value)
135 , m_setter(&SVGPODListItem<PODType>::setValue)
136 , m_associatedAttributeName(attributeName)
138 ASSERT(m_creator);
139 ASSERT(m_getter);
140 ASSERT(m_setter);
143 virtual ~JSSVGPODTypeWrapperCreatorForList() { }
145 // Getter wrapper
146 virtual operator PODType() { return (m_creator.get()->*m_getter)(); }
148 // Setter wrapper
149 virtual void commitChange(PODType type, SVGElement* context)
151 if (!m_setter)
152 return;
154 (m_creator.get()->*m_setter)(type);
156 if (context)
157 context->svgAttributeChanged(m_associatedAttributeName);
160 private:
161 // Update callbacks
162 RefPtr<SVGPODListItem<PODType> > m_creator;
163 GetterMethod m_getter;
164 SetterMethod m_setter;
165 const QualifiedName& m_associatedAttributeName;
168 // Caching facilities
169 template<typename PODType, typename PODTypeCreator>
170 struct PODTypeReadWriteHashInfo {
171 typedef PODType (PODTypeCreator::*GetterMethod)() const;
172 typedef void (PODTypeCreator::*SetterMethod)(PODType);
174 // Empty value
175 PODTypeReadWriteHashInfo()
176 : creator(0)
177 , getter(0)
178 , setter(0)
182 // Deleted value
183 PODTypeReadWriteHashInfo(WTF::HashTableDeletedValueType)
184 : creator(reinterpret_cast<PODTypeCreator*>(-1))
187 bool isHashTableDeletedValue() const
189 return creator == reinterpret_cast<PODTypeCreator*>(-1);
192 PODTypeReadWriteHashInfo(PODTypeCreator* _creator, GetterMethod _getter, SetterMethod _setter)
193 : creator(_creator)
194 , getter(_getter)
195 , setter(_setter)
197 ASSERT(creator);
198 ASSERT(getter);
201 bool operator==(const PODTypeReadWriteHashInfo& other) const
203 return creator == other.creator && getter == other.getter && setter == other.setter;
206 PODTypeCreator* creator;
207 GetterMethod getter;
208 SetterMethod setter;
211 template<typename PODType, typename PODTypeCreator>
212 struct PODTypeReadWriteHashInfoHash {
213 static unsigned hash(const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& info)
215 return StringImpl::computeHash(reinterpret_cast<const WebCore::UChar*>(&info), sizeof(PODTypeReadWriteHashInfo<PODType, PODTypeCreator>) / sizeof(WebCore::UChar));
218 static bool equal(const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& a, const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& b)
220 return a == b;
223 static const bool safeToCompareToEmptyOrDeleted = true;
226 template<typename PODType, typename PODTypeCreator>
227 struct PODTypeReadWriteHashInfoTraits : WTF::GenericHashTraits<PODTypeReadWriteHashInfo<PODType, PODTypeCreator> > {
228 static const bool emptyValueIsZero = true;
229 static const bool needsDestruction = false;
231 static const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& emptyValue()
233 static PODTypeReadWriteHashInfo<PODType, PODTypeCreator> key;
234 return key;
237 static void constructDeletedValue(PODTypeReadWriteHashInfo<PODType, PODTypeCreator>* slot)
239 new (slot) PODTypeReadWriteHashInfo<PODType, PODTypeCreator>(WTF::HashTableDeletedValue);
241 static bool isDeletedValue(const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& value)
243 return value.isHashTableDeletedValue();
247 template<typename PODType, typename PODTypeCreator>
248 class JSSVGPODTypeWrapperCache
250 public:
251 typedef PODType (PODTypeCreator::*GetterMethod)() const;
252 typedef void (PODTypeCreator::*SetterMethod)(PODType);
254 typedef HashMap<PODTypeReadWriteHashInfo<PODType, PODTypeCreator>, JSSVGPODTypeWrapperCreatorReadWrite<PODType, PODTypeCreator>*, PODTypeReadWriteHashInfoHash<PODType, PODTypeCreator>, PODTypeReadWriteHashInfoTraits<PODType, PODTypeCreator> > ReadWriteHashMap;
255 typedef typename ReadWriteHashMap::const_iterator ReadWriteHashMapIterator;
257 static ReadWriteHashMap& readWriteHashMap()
259 static ReadWriteHashMap _readWriteHashMap;
260 return _readWriteHashMap;
263 // Used for readwrite attributes only
264 static JSSVGPODTypeWrapper<PODType>* lookupOrCreateWrapper(PODTypeCreator* creator, GetterMethod getter, SetterMethod setter)
266 ReadWriteHashMap& map(readWriteHashMap());
267 PODTypeReadWriteHashInfo<PODType, PODTypeCreator> info(creator, getter, setter);
269 if (map.contains(info))
270 return map.get(info);
272 JSSVGPODTypeWrapperCreatorReadWrite<PODType, PODTypeCreator>* wrapper = new JSSVGPODTypeWrapperCreatorReadWrite<PODType, PODTypeCreator>(creator, getter, setter);
273 map.set(info, wrapper);
274 return wrapper;
277 static void forgetWrapper(JSSVGPODTypeWrapper<PODType>* wrapper)
279 ReadWriteHashMap& map(readWriteHashMap());
281 ReadWriteHashMapIterator it = map.begin();
282 ReadWriteHashMapIterator end = map.end();
284 for (; it != end; ++it) {
285 if (it->second != wrapper)
286 continue;
288 // It's guaruanteed that there's just one object we need to take care of.
289 map.remove(it->first);
290 break;
297 #endif // ENABLE(SVG)
298 #endif // JSSVGPODTypeWrapper_h