CFDictionaryPropertyBag.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*
  2. * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  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.
  12. *
  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.
  24. */
  25. #include "config.h"
  26. #include "WebKitDLL.h"
  27. #include "CFDictionaryPropertyBag.h"
  28. #include "MarshallingHelpers.h"
  29. #include "WebKit.h"
  30. // CFDictionaryPropertyBag -----------------------------------------------
  31. CFDictionaryPropertyBag::CFDictionaryPropertyBag()
  32. : m_refCount(0)
  33. {
  34. gClassCount++;
  35. gClassNameCount.add("CFDictionaryPropertyBag");
  36. }
  37. CFDictionaryPropertyBag::~CFDictionaryPropertyBag()
  38. {
  39. gClassCount--;
  40. gClassNameCount.remove("CFDictionaryPropertyBag");
  41. }
  42. COMPtr<CFDictionaryPropertyBag> CFDictionaryPropertyBag::createInstance()
  43. {
  44. return new CFDictionaryPropertyBag;
  45. }
  46. void CFDictionaryPropertyBag::setDictionary(CFMutableDictionaryRef dictionary)
  47. {
  48. m_dictionary = dictionary;
  49. }
  50. CFMutableDictionaryRef CFDictionaryPropertyBag::dictionary() const
  51. {
  52. return m_dictionary.get();
  53. }
  54. // IUnknown -------------------------------------------------------------------
  55. HRESULT STDMETHODCALLTYPE CFDictionaryPropertyBag::QueryInterface(REFIID riid, void** ppvObject)
  56. {
  57. *ppvObject = 0;
  58. if (IsEqualGUID(riid, IID_IUnknown))
  59. *ppvObject = static_cast<IPropertyBag*>(this);
  60. else if (IsEqualGUID(riid, IID_IPropertyBag))
  61. *ppvObject = static_cast<IPropertyBag*>(this);
  62. else if (IsEqualGUID(riid, __uuidof(this)))
  63. *ppvObject = this;
  64. else
  65. return E_NOINTERFACE;
  66. AddRef();
  67. return S_OK;
  68. }
  69. ULONG STDMETHODCALLTYPE CFDictionaryPropertyBag::AddRef(void)
  70. {
  71. return ++m_refCount;
  72. }
  73. ULONG STDMETHODCALLTYPE CFDictionaryPropertyBag::Release(void)
  74. {
  75. ULONG newRef = --m_refCount;
  76. if (!newRef)
  77. delete(this);
  78. return newRef;
  79. }
  80. // IPropertyBag ------------------------------------------------------------
  81. static bool ConvertCFTypeToVariant(VARIANT* pVar, void* cfObj)
  82. {
  83. if (!cfObj) {
  84. V_VT(pVar) = VT_NULL;
  85. return true;
  86. }
  87. else {
  88. // if caller expects a string, retrieve BSTR from CFStringRef
  89. if (V_VT(pVar) == VT_BSTR) {
  90. V_BSTR(pVar) = MarshallingHelpers::CFStringRefToBSTR((CFStringRef) cfObj);
  91. return true;
  92. } else if (V_VT(pVar) == VT_I4) {
  93. V_I4(pVar) = MarshallingHelpers::CFNumberRefToInt((CFNumberRef) cfObj);
  94. return true;
  95. } else if (!!(V_VT(pVar)&VT_ARRAY)) {
  96. if ((V_VT(pVar)&~VT_ARRAY) == VT_BSTR) {
  97. V_ARRAY(pVar) = MarshallingHelpers::stringArrayToSafeArray((CFArrayRef) cfObj);
  98. return true;
  99. } else if ((V_VT(pVar)&~VT_ARRAY) == VT_I4) {
  100. V_ARRAY(pVar) = MarshallingHelpers::intArrayToSafeArray((CFArrayRef) cfObj);
  101. return true;
  102. } else if ((V_VT(pVar)&~VT_ARRAY) == VT_UNKNOWN) {
  103. V_ARRAY(pVar) = MarshallingHelpers::iunknownArrayToSafeArray((CFArrayRef) cfObj);
  104. return true;
  105. }
  106. }
  107. }
  108. return false;
  109. }
  110. static bool ConvertVariantToCFType(VARIANT* pVar, void** cfObj)
  111. {
  112. if (V_VT(pVar) == VT_NULL) {
  113. *cfObj = 0;
  114. return true;
  115. }
  116. else {
  117. // if caller expects a string, retrieve BSTR from CFStringRef
  118. if (V_VT(pVar) == VT_BSTR) {
  119. *cfObj = (void*) MarshallingHelpers::BSTRToCFStringRef(V_BSTR(pVar));
  120. return true;
  121. } else if (V_VT(pVar) == VT_I4) {
  122. *cfObj = (void*) MarshallingHelpers::intToCFNumberRef(V_I4(pVar));
  123. return true;
  124. } else if (!!(V_VT(pVar)&VT_ARRAY)) {
  125. if ((V_VT(pVar)&~VT_ARRAY) == VT_BSTR) {
  126. *cfObj = (void*) MarshallingHelpers::safeArrayToStringArray(V_ARRAY(pVar));
  127. return true;
  128. } else if ((V_VT(pVar)&~VT_ARRAY) == VT_I4) {
  129. *cfObj = (void*) MarshallingHelpers::safeArrayToIntArray(V_ARRAY(pVar));
  130. return true;
  131. } else if ((V_VT(pVar)&~VT_ARRAY) == VT_UNKNOWN) {
  132. *cfObj = (void*) MarshallingHelpers::safeArrayToIUnknownArray(V_ARRAY(pVar));
  133. return true;
  134. }
  135. }
  136. }
  137. return false;
  138. }
  139. HRESULT STDMETHODCALLTYPE CFDictionaryPropertyBag::Read(LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog * /*pErrorLog*/)
  140. {
  141. if (!pszPropName)
  142. return E_POINTER;
  143. if (m_dictionary) {
  144. void* value;
  145. CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(pszPropName);
  146. HRESULT hr = E_FAIL;
  147. if (CFDictionaryGetValueIfPresent(m_dictionary.get(), key, (const void**) &value)) {
  148. if (ConvertCFTypeToVariant(pVar, value))
  149. hr = S_OK;
  150. } else
  151. hr = E_INVALIDARG;
  152. CFRelease(key);
  153. return hr;
  154. }
  155. return E_FAIL;
  156. }
  157. HRESULT STDMETHODCALLTYPE CFDictionaryPropertyBag::Write(LPCOLESTR pszPropName, VARIANT* pVar)
  158. {
  159. if (!pszPropName || !pVar)
  160. return E_POINTER;
  161. if (!m_dictionary) {
  162. m_dictionary = adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
  163. }
  164. void* cfObj;
  165. if (ConvertVariantToCFType(pVar, &cfObj)) {
  166. CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(pszPropName);
  167. CFDictionaryAddValue(m_dictionary.get(), key, cfObj);
  168. // CFDictionaryAddValue should automatically retain the CF objects passed in, so release them here
  169. CFRelease(key);
  170. CFRelease(cfObj);
  171. return S_OK;
  172. }
  173. return E_FAIL;
  174. }