2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "WebKitDLL.h"
28 #include "CFDictionaryPropertyBag.h"
30 #include "MarshallingHelpers.h"
33 // CFDictionaryPropertyBag -----------------------------------------------
35 CFDictionaryPropertyBag::CFDictionaryPropertyBag()
39 gClassNameCount.add("CFDictionaryPropertyBag");
42 CFDictionaryPropertyBag::~CFDictionaryPropertyBag()
45 gClassNameCount.remove("CFDictionaryPropertyBag");
48 COMPtr<CFDictionaryPropertyBag> CFDictionaryPropertyBag::createInstance()
50 return new CFDictionaryPropertyBag;
53 void CFDictionaryPropertyBag::setDictionary(CFMutableDictionaryRef dictionary)
55 m_dictionary = dictionary;
58 CFMutableDictionaryRef CFDictionaryPropertyBag::dictionary() const
60 return m_dictionary.get();
63 // IUnknown -------------------------------------------------------------------
65 HRESULT STDMETHODCALLTYPE CFDictionaryPropertyBag::QueryInterface(REFIID riid, void** ppvObject)
68 if (IsEqualGUID(riid, IID_IUnknown))
69 *ppvObject = static_cast<IPropertyBag*>(this);
70 else if (IsEqualGUID(riid, IID_IPropertyBag))
71 *ppvObject = static_cast<IPropertyBag*>(this);
72 else if (IsEqualGUID(riid, __uuidof(this)))
81 ULONG STDMETHODCALLTYPE CFDictionaryPropertyBag::AddRef(void)
86 ULONG STDMETHODCALLTYPE CFDictionaryPropertyBag::Release(void)
88 ULONG newRef = --m_refCount;
95 // IPropertyBag ------------------------------------------------------------
97 static bool ConvertCFTypeToVariant(VARIANT* pVar, void* cfObj)
100 V_VT(pVar) = VT_NULL;
104 // if caller expects a string, retrieve BSTR from CFStringRef
105 if (V_VT(pVar) == VT_BSTR) {
106 V_BSTR(pVar) = MarshallingHelpers::CFStringRefToBSTR((CFStringRef) cfObj);
108 } else if (V_VT(pVar) == VT_I4) {
109 V_I4(pVar) = MarshallingHelpers::CFNumberRefToInt((CFNumberRef) cfObj);
111 } else if (!!(V_VT(pVar)&VT_ARRAY)) {
112 if ((V_VT(pVar)&~VT_ARRAY) == VT_BSTR) {
113 V_ARRAY(pVar) = MarshallingHelpers::stringArrayToSafeArray((CFArrayRef) cfObj);
115 } else if ((V_VT(pVar)&~VT_ARRAY) == VT_I4) {
116 V_ARRAY(pVar) = MarshallingHelpers::intArrayToSafeArray((CFArrayRef) cfObj);
118 } else if ((V_VT(pVar)&~VT_ARRAY) == VT_UNKNOWN) {
119 V_ARRAY(pVar) = MarshallingHelpers::iunknownArrayToSafeArray((CFArrayRef) cfObj);
127 static bool ConvertVariantToCFType(VARIANT* pVar, void** cfObj)
129 if (V_VT(pVar) == VT_NULL) {
134 // if caller expects a string, retrieve BSTR from CFStringRef
135 if (V_VT(pVar) == VT_BSTR) {
136 *cfObj = (void*) MarshallingHelpers::BSTRToCFStringRef(V_BSTR(pVar));
138 } else if (V_VT(pVar) == VT_I4) {
139 *cfObj = (void*) MarshallingHelpers::intToCFNumberRef(V_I4(pVar));
141 } else if (!!(V_VT(pVar)&VT_ARRAY)) {
142 if ((V_VT(pVar)&~VT_ARRAY) == VT_BSTR) {
143 *cfObj = (void*) MarshallingHelpers::safeArrayToStringArray(V_ARRAY(pVar));
145 } else if ((V_VT(pVar)&~VT_ARRAY) == VT_I4) {
146 *cfObj = (void*) MarshallingHelpers::safeArrayToIntArray(V_ARRAY(pVar));
148 } else if ((V_VT(pVar)&~VT_ARRAY) == VT_UNKNOWN) {
149 *cfObj = (void*) MarshallingHelpers::safeArrayToIUnknownArray(V_ARRAY(pVar));
157 HRESULT STDMETHODCALLTYPE CFDictionaryPropertyBag::Read(LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog * /*pErrorLog*/)
163 CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(pszPropName);
165 if (CFDictionaryGetValueIfPresent(m_dictionary.get(), key, (const void**) &value)) {
166 if (ConvertCFTypeToVariant(pVar, value))
176 HRESULT STDMETHODCALLTYPE CFDictionaryPropertyBag::Write(LPCOLESTR pszPropName, VARIANT* pVar)
178 if (!pszPropName || !pVar)
181 m_dictionary.adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
184 if (ConvertVariantToCFType(pVar, &cfObj)) {
185 CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(pszPropName);
186 CFDictionaryAddValue(m_dictionary.get(), key, cfObj);
187 // CFDictionaryAddValue should automatically retain the CF objects passed in, so release them here