File indexing completed on 2024-05-12 15:37:27
0001 /* 0002 * Copyright (C) 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> 0003 * Copyright (C) 2008 Apple Inc. All rights reserved. 0004 * 0005 * Redistribution and use in source and binary forms, with or without 0006 * modification, are permitted provided that the following conditions 0007 * are met: 0008 * 1. Redistributions of source code must retain the above copyright 0009 * notice, this list of conditions and the following disclaimer. 0010 * 2. Redistributions in binary form must reproduce the above copyright 0011 * notice, this list of conditions and the following disclaimer in the 0012 * documentation and/or other materials provided with the distribution. 0013 * 0014 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 0015 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0016 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 0017 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 0018 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 0019 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 0020 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 0021 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 0022 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0023 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 0024 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0025 */ 0026 0027 #ifndef JSSVGPODTypeWrapper_h 0028 #define JSSVGPODTypeWrapper_h 0029 0030 #if ENABLE(SVG) 0031 0032 #include "Frame.h" 0033 #include <wtf/RefCounted.h> 0034 #include "SVGElement.h" 0035 0036 #include <wtf/Assertions.h> 0037 #include <wtf/HashMap.h> 0038 0039 namespace WebCore 0040 { 0041 template<typename PODType> 0042 class SVGPODListItem; 0043 } 0044 0045 using namespace WebCore; 0046 0047 namespace khtml 0048 { 0049 0050 template<typename PODType> 0051 class JSSVGPODTypeWrapper : public RefCounted<JSSVGPODTypeWrapper<PODType> > 0052 { 0053 public: 0054 JSSVGPODTypeWrapper() : RefCounted<JSSVGPODTypeWrapper<PODType> >(0) { } 0055 virtual ~JSSVGPODTypeWrapper() { } 0056 0057 // Getter wrapper 0058 virtual operator PODType() = 0; 0059 0060 // Setter wrapper 0061 virtual void commitChange(PODType, SVGElement *) = 0; 0062 }; 0063 0064 template<typename PODType, typename PODTypeCreator> 0065 class JSSVGPODTypeWrapperCreatorReadWrite : public JSSVGPODTypeWrapper<PODType> 0066 { 0067 public: 0068 typedef PODType(PODTypeCreator::*GetterMethod)() const; 0069 typedef void (PODTypeCreator::*SetterMethod)(PODType); 0070 0071 JSSVGPODTypeWrapperCreatorReadWrite(PODTypeCreator *creator, GetterMethod getter, SetterMethod setter) 0072 : m_creator(creator) 0073 , m_getter(getter) 0074 , m_setter(setter) 0075 { 0076 ASSERT(creator); 0077 ASSERT(getter); 0078 ASSERT(setter); 0079 } 0080 0081 virtual ~JSSVGPODTypeWrapperCreatorReadWrite() { } 0082 0083 // Getter wrapper 0084 virtual operator PODType() 0085 { 0086 return (m_creator.get()->*m_getter)(); 0087 } 0088 0089 // Setter wrapper 0090 virtual void commitChange(PODType type, SVGElement *context) 0091 { 0092 if (!m_setter) { 0093 return; 0094 } 0095 0096 (m_creator.get()->*m_setter)(type); 0097 0098 if (context) { 0099 context->svgAttributeChanged(m_creator->associatedAttributeName()); 0100 } 0101 } 0102 0103 private: 0104 // Update callbacks 0105 RefPtr<PODTypeCreator> m_creator; 0106 GetterMethod m_getter; 0107 SetterMethod m_setter; 0108 }; 0109 0110 template<typename PODType> 0111 class JSSVGPODTypeWrapperCreatorReadOnly : public JSSVGPODTypeWrapper<PODType> 0112 { 0113 public: 0114 JSSVGPODTypeWrapperCreatorReadOnly(PODType type) 0115 : m_podType(type) 0116 { } 0117 0118 virtual ~JSSVGPODTypeWrapperCreatorReadOnly() { } 0119 0120 // Getter wrapper 0121 virtual operator PODType() 0122 { 0123 return m_podType; 0124 } 0125 0126 // Setter wrapper 0127 virtual void commitChange(PODType type, SVGElement *) 0128 { 0129 m_podType = type; 0130 } 0131 0132 private: 0133 PODType m_podType; 0134 }; 0135 0136 template<typename PODType> 0137 class JSSVGPODTypeWrapperCreatorForList : public JSSVGPODTypeWrapper<PODType> 0138 { 0139 public: 0140 typedef PODType(SVGPODListItem<PODType>::*GetterMethod)() const; 0141 typedef void (SVGPODListItem<PODType>::*SetterMethod)(PODType); 0142 0143 JSSVGPODTypeWrapperCreatorForList(SVGPODListItem<PODType> *creator, const QualifiedName &attributeName) 0144 : m_creator(creator) 0145 , m_getter(&SVGPODListItem<PODType>::value) 0146 , m_setter(&SVGPODListItem<PODType>::setValue) 0147 , m_associatedAttributeName(attributeName) 0148 { 0149 ASSERT(m_creator); 0150 ASSERT(m_getter); 0151 ASSERT(m_setter); 0152 } 0153 0154 virtual ~JSSVGPODTypeWrapperCreatorForList() { } 0155 0156 // Getter wrapper 0157 virtual operator PODType() 0158 { 0159 return (m_creator.get()->*m_getter)(); 0160 } 0161 0162 // Setter wrapper 0163 virtual void commitChange(PODType type, SVGElement *context) 0164 { 0165 if (!m_setter) { 0166 return; 0167 } 0168 0169 (m_creator.get()->*m_setter)(type); 0170 0171 if (context) { 0172 context->svgAttributeChanged(m_associatedAttributeName); 0173 } 0174 } 0175 0176 private: 0177 // Update callbacks 0178 RefPtr<SVGPODListItem<PODType> > m_creator; 0179 GetterMethod m_getter; 0180 SetterMethod m_setter; 0181 const QualifiedName &m_associatedAttributeName; 0182 }; 0183 0184 // Caching facilities 0185 template<typename PODType, typename PODTypeCreator> 0186 struct PODTypeReadWriteHashInfo { 0187 typedef PODType(PODTypeCreator::*GetterMethod)() const; 0188 typedef void (PODTypeCreator::*SetterMethod)(PODType); 0189 0190 // Empty value 0191 PODTypeReadWriteHashInfo() 0192 : creator(0) 0193 , getter(0) 0194 , setter(0) 0195 { 0196 } 0197 0198 // Deleted value 0199 PODTypeReadWriteHashInfo(WTF::HashTableDeletedValueType) 0200 : creator(reinterpret_cast<PODTypeCreator *>(-1)) 0201 { 0202 } 0203 bool isHashTableDeletedValue() const 0204 { 0205 return creator == reinterpret_cast<PODTypeCreator *>(-1); 0206 } 0207 0208 PODTypeReadWriteHashInfo(PODTypeCreator *_creator, GetterMethod _getter, SetterMethod _setter) 0209 : creator(_creator) 0210 , getter(_getter) 0211 , setter(_setter) 0212 { 0213 ASSERT(creator); 0214 ASSERT(getter); 0215 } 0216 0217 bool operator==(const PODTypeReadWriteHashInfo &other) const 0218 { 0219 return creator == other.creator && getter == other.getter && setter == other.setter; 0220 } 0221 0222 PODTypeCreator *creator; 0223 GetterMethod getter; 0224 SetterMethod setter; 0225 }; 0226 0227 template<typename PODType, typename PODTypeCreator> 0228 struct PODTypeReadWriteHashInfoHash { 0229 static unsigned hash(const PODTypeReadWriteHashInfo<PODType, PODTypeCreator> &info) 0230 { 0231 return StringImpl::computeHash(reinterpret_cast<const WebCore::UChar *>(&info), sizeof(PODTypeReadWriteHashInfo<PODType, PODTypeCreator>) / sizeof(WebCore::UChar)); 0232 } 0233 0234 static bool equal(const PODTypeReadWriteHashInfo<PODType, PODTypeCreator> &a, const PODTypeReadWriteHashInfo<PODType, PODTypeCreator> &b) 0235 { 0236 return a == b; 0237 } 0238 0239 static const bool safeToCompareToEmptyOrDeleted = true; 0240 }; 0241 0242 template<typename PODType, typename PODTypeCreator> 0243 struct PODTypeReadWriteHashInfoTraits : WTF::GenericHashTraits<PODTypeReadWriteHashInfo<PODType, PODTypeCreator> > { 0244 static const bool emptyValueIsZero = true; 0245 static const bool needsDestruction = false; 0246 0247 static const PODTypeReadWriteHashInfo<PODType, PODTypeCreator> &emptyValue() 0248 { 0249 static PODTypeReadWriteHashInfo<PODType, PODTypeCreator> key; 0250 return key; 0251 } 0252 0253 static void constructDeletedValue(PODTypeReadWriteHashInfo<PODType, PODTypeCreator> *slot) 0254 { 0255 new(slot) PODTypeReadWriteHashInfo<PODType, PODTypeCreator>(WTF::HashTableDeletedValue); 0256 } 0257 static bool isDeletedValue(const PODTypeReadWriteHashInfo<PODType, PODTypeCreator> &value) 0258 { 0259 return value.isHashTableDeletedValue(); 0260 } 0261 }; 0262 0263 template<typename PODType, typename PODTypeCreator> 0264 class JSSVGPODTypeWrapperCache 0265 { 0266 public: 0267 typedef PODType(PODTypeCreator::*GetterMethod)() const; 0268 typedef void (PODTypeCreator::*SetterMethod)(PODType); 0269 0270 typedef HashMap<PODTypeReadWriteHashInfo<PODType, PODTypeCreator>, JSSVGPODTypeWrapperCreatorReadWrite<PODType, PODTypeCreator>*, PODTypeReadWriteHashInfoHash<PODType, PODTypeCreator>, PODTypeReadWriteHashInfoTraits<PODType, PODTypeCreator> > ReadWriteHashMap; 0271 typedef typename ReadWriteHashMap::const_iterator ReadWriteHashMapIterator; 0272 0273 static ReadWriteHashMap &readWriteHashMap() 0274 { 0275 static ReadWriteHashMap _readWriteHashMap; 0276 return _readWriteHashMap; 0277 } 0278 0279 // Used for readwrite attributes only 0280 static JSSVGPODTypeWrapper<PODType> *lookupOrCreateWrapper(PODTypeCreator *creator, GetterMethod getter, SetterMethod setter) 0281 { 0282 ReadWriteHashMap &map(readWriteHashMap()); 0283 PODTypeReadWriteHashInfo<PODType, PODTypeCreator> info(creator, getter, setter); 0284 0285 if (map.contains(info)) { 0286 return map.get(info); 0287 } 0288 0289 JSSVGPODTypeWrapperCreatorReadWrite<PODType, PODTypeCreator> *wrapper = new JSSVGPODTypeWrapperCreatorReadWrite<PODType, PODTypeCreator>(creator, getter, setter); 0290 map.set(info, wrapper); 0291 return wrapper; 0292 } 0293 0294 static void forgetWrapper(JSSVGPODTypeWrapper<PODType> *wrapper) 0295 { 0296 ReadWriteHashMap &map(readWriteHashMap()); 0297 0298 ReadWriteHashMapIterator it = map.begin(); 0299 ReadWriteHashMapIterator end = map.end(); 0300 0301 for (; it != end; ++it) { 0302 if (it->second != wrapper) { 0303 continue; 0304 } 0305 0306 // It's guaruanteed that there's just one object we need to take care of. 0307 map.remove(it->first); 0308 break; 0309 } 0310 } 0311 }; 0312 0313 }; 0314 0315 #endif // ENABLE(SVG) 0316 #endif // JSSVGPODTypeWrapper_h