diff -r 000000000000 -r dd21522fd290 webengine/osswebengine/WebKit/win/CFDictionaryPropertyBag.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/WebKit/win/CFDictionaryPropertyBag.cpp Mon Mar 30 12:54:55 2009 +0300 @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebKitDLL.h" +#include "CFDictionaryPropertyBag.h" + +#include "MarshallingHelpers.h" + +#include +// {675E712B-8253-4121-A1F0-6A804D095668} +DEFINE_GUID(IID_CFDictionaryPropertyBag, 0x675e712b, 0x8253, 0x4121, 0xa1, 0xf0, 0x6a, 0x80, 0x4d, 0x9, 0x56, 0x68); + +// CFDictionaryPropertyBag ----------------------------------------------- + +CFDictionaryPropertyBag::CFDictionaryPropertyBag() +: m_refCount(1) +{ +} + +CFDictionaryPropertyBag* CFDictionaryPropertyBag::createInstance() +{ + CFDictionaryPropertyBag* instance = new CFDictionaryPropertyBag(); + return instance; +} + +void CFDictionaryPropertyBag::setDictionary(CFMutableDictionaryRef dictionary) +{ + m_dictionary = dictionary; +} + +CFMutableDictionaryRef CFDictionaryPropertyBag::dictionary() const +{ + return m_dictionary.get(); +} + +// IUnknown ------------------------------------------------------------------- + +HRESULT STDMETHODCALLTYPE CFDictionaryPropertyBag::QueryInterface(REFIID riid, void** ppvObject) +{ + *ppvObject = 0; + if (IsEqualGUID(riid, IID_IUnknown)) + *ppvObject = static_cast(this); + else if (IsEqualGUID(riid, IID_IPropertyBag)) + *ppvObject = static_cast(this); + else if (IsEqualGUID(riid, IID_CFDictionaryPropertyBag)) + *ppvObject = this; + else + return E_NOINTERFACE; + + AddRef(); + return S_OK; +} + +ULONG STDMETHODCALLTYPE CFDictionaryPropertyBag::AddRef(void) +{ + return ++m_refCount; +} + +ULONG STDMETHODCALLTYPE CFDictionaryPropertyBag::Release(void) +{ + ULONG newRef = --m_refCount; + if (!newRef) + delete(this); + + return newRef; +} + +// IPropertyBag ------------------------------------------------------------ + +static bool ConvertCFTypeToVariant(VARIANT* pVar, void* cfObj) +{ + if (!cfObj) { + V_VT(pVar) = VT_NULL; + return true; + } + else { + // if caller expects a string, retrieve BSTR from CFStringRef + if (V_VT(pVar) == VT_BSTR) { + V_BSTR(pVar) = MarshallingHelpers::CFStringRefToBSTR((CFStringRef) cfObj); + return true; + } else if (V_VT(pVar) == VT_I4) { + V_I4(pVar) = MarshallingHelpers::CFNumberRefToInt((CFNumberRef) cfObj); + return true; + } else if (!!(V_VT(pVar)&VT_ARRAY)) { + if ((V_VT(pVar)&~VT_ARRAY) == VT_BSTR) { + V_ARRAY(pVar) = MarshallingHelpers::stringArrayToSafeArray((CFArrayRef) cfObj); + return true; + } else if ((V_VT(pVar)&~VT_ARRAY) == VT_I4) { + V_ARRAY(pVar) = MarshallingHelpers::intArrayToSafeArray((CFArrayRef) cfObj); + return true; + } else if ((V_VT(pVar)&~VT_ARRAY) == VT_UNKNOWN) { + V_ARRAY(pVar) = MarshallingHelpers::iunknownArrayToSafeArray((CFArrayRef) cfObj); + return true; + } + } + } + return false; +} + +static bool ConvertVariantToCFType(VARIANT* pVar, void** cfObj) +{ + if (V_VT(pVar) == VT_NULL) { + *cfObj = 0; + return true; + } + else { + // if caller expects a string, retrieve BSTR from CFStringRef + if (V_VT(pVar) == VT_BSTR) { + *cfObj = (void*) MarshallingHelpers::BSTRToCFStringRef(V_BSTR(pVar)); + return true; + } else if (V_VT(pVar) == VT_I4) { + *cfObj = (void*) MarshallingHelpers::intToCFNumberRef(V_I4(pVar)); + return true; + } else if (!!(V_VT(pVar)&VT_ARRAY)) { + if ((V_VT(pVar)&~VT_ARRAY) == VT_BSTR) { + *cfObj = (void*) MarshallingHelpers::safeArrayToStringArray(V_ARRAY(pVar)); + return true; + } else if ((V_VT(pVar)&~VT_ARRAY) == VT_I4) { + *cfObj = (void*) MarshallingHelpers::safeArrayToIntArray(V_ARRAY(pVar)); + return true; + } else if ((V_VT(pVar)&~VT_ARRAY) == VT_UNKNOWN) { + *cfObj = (void*) MarshallingHelpers::safeArrayToIUnknownArray(V_ARRAY(pVar)); + return true; + } + } + } + return false; +} + +HRESULT STDMETHODCALLTYPE CFDictionaryPropertyBag::Read(LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog * /*pErrorLog*/) +{ + if (!pszPropName) + return E_POINTER; + if (m_dictionary) { + void* value; + CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(pszPropName); + HRESULT hr = E_FAIL; + if (CFDictionaryGetValueIfPresent(m_dictionary.get(), key, (const void**) &value)) { + if (ConvertCFTypeToVariant(pVar, value)) + hr = S_OK; + } else + hr = E_INVALIDARG; + CFRelease(key); + return hr; + } + return E_FAIL; +} + +HRESULT STDMETHODCALLTYPE CFDictionaryPropertyBag::Write(LPCOLESTR pszPropName, VARIANT* pVar) +{ + if (!pszPropName || !pVar) + return E_POINTER; + if (!m_dictionary) { + m_dictionary = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + } + void* cfObj; + if (ConvertVariantToCFType(pVar, &cfObj)) { + CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(pszPropName); + CFDictionaryAddValue(m_dictionary.get(), key, cfObj); + // CFDictionaryAddValue should automatically retain the CF objects passed in, so release them here + CFRelease(key); + CFRelease(cfObj); + return S_OK; + } + return E_FAIL; +} \ No newline at end of file