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
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
33 #include <wtf/RefCounted.h>
34 #include "SVGElement.h"
36 #include <wtf/Assertions.h>
37 #include <wtf/HashMap.h>
40 template<typename PODType
>
44 using namespace WebCore
;
48 template<typename PODType
>
49 class JSSVGPODTypeWrapper
: public RefCounted
<JSSVGPODTypeWrapper
<PODType
> > {
51 JSSVGPODTypeWrapper() : RefCounted
<JSSVGPODTypeWrapper
<PODType
> >(0) { }
52 virtual ~JSSVGPODTypeWrapper() { }
55 virtual operator PODType() = 0;
58 virtual void commitChange(PODType
, SVGElement
*) = 0;
61 template<typename PODType
, typename PODTypeCreator
>
62 class JSSVGPODTypeWrapperCreatorReadWrite
: public JSSVGPODTypeWrapper
<PODType
>
65 typedef PODType (PODTypeCreator::*GetterMethod
)() const;
66 typedef void (PODTypeCreator::*SetterMethod
)(PODType
);
68 JSSVGPODTypeWrapperCreatorReadWrite(PODTypeCreator
* creator
, GetterMethod getter
, SetterMethod setter
)
78 virtual ~JSSVGPODTypeWrapperCreatorReadWrite() { }
81 virtual operator PODType() { return (m_creator
.get()->*m_getter
)(); }
84 virtual void commitChange(PODType type
, SVGElement
* context
)
89 (m_creator
.get()->*m_setter
)(type
);
92 context
->svgAttributeChanged(m_creator
->associatedAttributeName());
97 RefPtr
<PODTypeCreator
> m_creator
;
98 GetterMethod m_getter
;
99 SetterMethod m_setter
;
102 template<typename PODType
>
103 class JSSVGPODTypeWrapperCreatorReadOnly
: public JSSVGPODTypeWrapper
<PODType
>
106 JSSVGPODTypeWrapperCreatorReadOnly(PODType type
)
110 virtual ~JSSVGPODTypeWrapperCreatorReadOnly() { }
113 virtual operator PODType() { return m_podType
; }
116 virtual void commitChange(PODType type
, SVGElement
*)
125 template<typename PODType
>
126 class JSSVGPODTypeWrapperCreatorForList
: public JSSVGPODTypeWrapper
<PODType
>
129 typedef PODType (SVGPODListItem
<PODType
>::*GetterMethod
)() const;
130 typedef void (SVGPODListItem
<PODType
>::*SetterMethod
)(PODType
);
132 JSSVGPODTypeWrapperCreatorForList(SVGPODListItem
<PODType
>* creator
, const QualifiedName
& attributeName
)
134 , m_getter(&SVGPODListItem
<PODType
>::value
)
135 , m_setter(&SVGPODListItem
<PODType
>::setValue
)
136 , m_associatedAttributeName(attributeName
)
143 virtual ~JSSVGPODTypeWrapperCreatorForList() { }
146 virtual operator PODType() { return (m_creator
.get()->*m_getter
)(); }
149 virtual void commitChange(PODType type
, SVGElement
* context
)
154 (m_creator
.get()->*m_setter
)(type
);
157 context
->svgAttributeChanged(m_associatedAttributeName
);
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
);
175 PODTypeReadWriteHashInfo()
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
)
201 bool operator==(const PODTypeReadWriteHashInfo
& other
) const
203 return creator
== other
.creator
&& getter
== other
.getter
&& setter
== other
.setter
;
206 PODTypeCreator
* creator
;
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
)
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
;
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
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
);
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
)
288 // It's guaruanteed that there's just one object we need to take care of.
289 map
.remove(it
->first
);
297 #endif // ENABLE(SVG)
298 #endif // JSSVGPODTypeWrapper_h