MarshallingHelpers.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  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 "MarshallingHelpers.h"
  28. #include <WebCore/BString.h>
  29. #include <WebCore/IntRect.h>
  30. #include <WebCore/KURL.h>
  31. #include <wtf/MathExtras.h>
  32. #include <wtf/text/WTFString.h>
  33. using namespace WebCore;
  34. static const double secondsPerDay = 60 * 60 * 24;
  35. CFArrayCallBacks MarshallingHelpers::kIUnknownArrayCallBacks = {0, IUnknownRetainCallback, IUnknownReleaseCallback, 0, 0};
  36. CFDictionaryValueCallBacks MarshallingHelpers::kIUnknownDictionaryValueCallBacks = {0, IUnknownRetainCallback, IUnknownReleaseCallback, 0, 0};
  37. KURL MarshallingHelpers::BSTRToKURL(BSTR urlStr)
  38. {
  39. return KURL(KURL(), String(urlStr, SysStringLen(urlStr)));
  40. }
  41. BSTR MarshallingHelpers::KURLToBSTR(const KURL& url)
  42. {
  43. return BString(url.string()).release();
  44. }
  45. CFURLRef MarshallingHelpers::PathStringToFileCFURLRef(const String& string)
  46. {
  47. CFStringRef cfPath = CFStringCreateWithCharactersNoCopy(0, (const UniChar*)string.characters(), string.length(), kCFAllocatorNull);
  48. CFURLRef pathURL = CFURLCreateWithFileSystemPath(0, cfPath, kCFURLWindowsPathStyle, false);
  49. CFRelease(cfPath);
  50. return pathURL;
  51. }
  52. String MarshallingHelpers::FileCFURLRefToPathString(CFURLRef fileURL)
  53. {
  54. CFStringRef string = CFURLCopyFileSystemPath(fileURL, kCFURLWindowsPathStyle);
  55. String result(string);
  56. CFRelease(string);
  57. return result;
  58. }
  59. CFURLRef MarshallingHelpers::BSTRToCFURLRef(BSTR urlStr)
  60. {
  61. CFStringRef urlCFString = BSTRToCFStringRef(urlStr);
  62. if (!urlCFString)
  63. return 0;
  64. CFURLRef urlRef = CFURLCreateWithString(0, urlCFString, 0);
  65. CFRelease(urlCFString);
  66. return urlRef;
  67. }
  68. CFStringRef MarshallingHelpers::BSTRToCFStringRef(BSTR str)
  69. {
  70. return CFStringCreateWithCharacters(0, (const UniChar*)(str ? str : TEXT("")), SysStringLen(str));
  71. }
  72. CFStringRef MarshallingHelpers::LPCOLESTRToCFStringRef(LPCOLESTR str)
  73. {
  74. return CFStringCreateWithCharacters(0, (const UniChar*)(str ? str : TEXT("")), (CFIndex)(str ? wcslen(str) : 0));
  75. }
  76. BSTR MarshallingHelpers::CFStringRefToBSTR(CFStringRef str)
  77. {
  78. return BString(str).release();
  79. }
  80. int MarshallingHelpers::CFNumberRefToInt(CFNumberRef num)
  81. {
  82. int number;
  83. CFNumberGetValue(num, kCFNumberIntType, &number);
  84. return number;
  85. }
  86. CFNumberRef MarshallingHelpers::intToCFNumberRef(int num)
  87. {
  88. return CFNumberCreate(0, kCFNumberSInt32Type, &num);
  89. }
  90. CFAbsoluteTime MarshallingHelpers::windowsEpochAbsoluteTime()
  91. {
  92. static CFAbsoluteTime windowsEpochAbsoluteTime = 0;
  93. if (!windowsEpochAbsoluteTime) {
  94. CFGregorianDate windowsEpochDate = {1899, 12, 30, 0, 0, 0.0};
  95. windowsEpochAbsoluteTime = CFGregorianDateGetAbsoluteTime(windowsEpochDate, 0) / secondsPerDay;
  96. }
  97. return windowsEpochAbsoluteTime;
  98. }
  99. CFAbsoluteTime MarshallingHelpers::DATEToCFAbsoluteTime(DATE date)
  100. {
  101. // <http://msdn2.microsoft.com/en-us/library/ms221627.aspx>
  102. // DATE: This is the same numbering system used by most spreadsheet programs,
  103. // although some specify incorrectly that February 29, 1900 existed, and thus
  104. // set January 1, 1900 to 1.0. The date can be converted to and from an MS-DOS
  105. // representation using VariantTimeToDosDateTime, which is discussed in
  106. // Conversion and Manipulation Functions.
  107. // CFAbsoluteTime: Type used to represent a specific point in time relative
  108. // to the absolute reference date of 1 Jan 2001 00:00:00 GMT.
  109. // Absolute time is measured by the number of seconds between the reference
  110. // date and the specified date. Negative values indicate dates/times before
  111. // the reference date. Positive values indicate dates/times after the
  112. // reference date.
  113. return round((date + windowsEpochAbsoluteTime()) * secondsPerDay);
  114. }
  115. DATE MarshallingHelpers::CFAbsoluteTimeToDATE(CFAbsoluteTime absoluteTime)
  116. {
  117. return (round(absoluteTime)/secondsPerDay - windowsEpochAbsoluteTime());
  118. }
  119. // utility method to store a 1-dim string vector into a newly created SAFEARRAY
  120. SAFEARRAY* MarshallingHelpers::stringArrayToSafeArray(CFArrayRef inArray)
  121. {
  122. CFIndex size = CFArrayGetCount(inArray);
  123. SAFEARRAY* sa = ::SafeArrayCreateVectorEx(VT_BSTR, 0, (ULONG) size, 0);
  124. long count = 0;
  125. for (CFIndex i=0; i<size; i++) {
  126. CFStringRef item = (CFStringRef) CFArrayGetValueAtIndex(inArray, i);
  127. BString bstr(item);
  128. ::SafeArrayPutElement(sa, &count, bstr); // SafeArrayPutElement() copies the string correctly.
  129. count++;
  130. }
  131. return sa;
  132. }
  133. // utility method to store a 1-dim int vector into a newly created SAFEARRAY
  134. SAFEARRAY* MarshallingHelpers::intArrayToSafeArray(CFArrayRef inArray)
  135. {
  136. CFIndex size = CFArrayGetCount(inArray);
  137. SAFEARRAY* sa = ::SafeArrayCreateVectorEx(VT_I4, 0, (ULONG) size, 0);
  138. long count = 0;
  139. for (CFIndex i=0; i<size; i++) {
  140. CFNumberRef item = (CFNumberRef) CFArrayGetValueAtIndex(inArray, i);
  141. int number = CFNumberRefToInt(item);
  142. ::SafeArrayPutElement(sa, &count, &number);
  143. count++;
  144. }
  145. return sa;
  146. }
  147. SAFEARRAY* MarshallingHelpers::intRectToSafeArray(const WebCore::IntRect& rect)
  148. {
  149. SAFEARRAY* sa = ::SafeArrayCreateVectorEx(VT_I4, 0, 4, 0);
  150. long count = 0;
  151. int value;
  152. value = rect.x();
  153. ::SafeArrayPutElement(sa, &count, &value);
  154. count++;
  155. value = rect.y();
  156. ::SafeArrayPutElement(sa, &count, &value);
  157. count++;
  158. value = rect.width();
  159. ::SafeArrayPutElement(sa, &count, &value);
  160. count++;
  161. value = rect.height();
  162. ::SafeArrayPutElement(sa, &count, &value);
  163. count++;
  164. return sa;
  165. }
  166. // utility method to store a 1-dim IUnknown* vector into a newly created SAFEARRAY
  167. SAFEARRAY* MarshallingHelpers::iunknownArrayToSafeArray(CFArrayRef inArray)
  168. {
  169. CFIndex size = CFArrayGetCount(inArray);
  170. SAFEARRAY* sa = ::SafeArrayCreateVectorEx(VT_UNKNOWN, 0, (ULONG) size, (LPVOID)&IID_IUnknown);
  171. long count = 0;
  172. for (CFIndex i=0; i<size; i++) {
  173. IUnknown* item = (IUnknown*) CFArrayGetValueAtIndex(inArray, i);
  174. ::SafeArrayPutElement(sa, &count, item); // SafeArrayPutElement() adds a reference to the IUnknown added
  175. count++;
  176. }
  177. return sa;
  178. }
  179. CFArrayRef MarshallingHelpers::safeArrayToStringArray(SAFEARRAY* inArray)
  180. {
  181. long lBound=0, uBound=-1;
  182. HRESULT hr = ::SafeArrayGetLBound(inArray, 1, &lBound);
  183. if (SUCCEEDED(hr))
  184. hr = ::SafeArrayGetUBound(inArray, 1, &uBound);
  185. long len = (SUCCEEDED(hr)) ? (uBound-lBound+1) : 0;
  186. CFStringRef* items = 0;
  187. if (len > 0) {
  188. items = new CFStringRef[len];
  189. for (; lBound <= uBound; lBound++) {
  190. BString str;
  191. hr = ::SafeArrayGetElement(inArray, &lBound, &str);
  192. items[lBound] = BSTRToCFStringRef(str);
  193. }
  194. }
  195. CFArrayRef result = CFArrayCreate(0, (const void**)items, len, &kCFTypeArrayCallBacks);
  196. if (items)
  197. delete[] items;
  198. return result;
  199. }
  200. CFArrayRef MarshallingHelpers::safeArrayToIntArray(SAFEARRAY* inArray)
  201. {
  202. long lBound=0, uBound=-1;
  203. HRESULT hr = ::SafeArrayGetLBound(inArray, 1, &lBound);
  204. if (SUCCEEDED(hr))
  205. hr = ::SafeArrayGetUBound(inArray, 1, &uBound);
  206. long len = (SUCCEEDED(hr)) ? (uBound-lBound+1) : 0;
  207. CFNumberRef* items = 0;
  208. if (len > 0) {
  209. items = new CFNumberRef[len];
  210. for (; lBound <= uBound; lBound++) {
  211. int num;
  212. hr = ::SafeArrayGetElement(inArray, &lBound, &num);
  213. items[lBound] = intToCFNumberRef(num);
  214. }
  215. }
  216. CFArrayRef result = CFArrayCreate(0, (const void**) items, len, &kCFTypeArrayCallBacks);
  217. if (items)
  218. delete[] items;
  219. return result;
  220. }
  221. CFArrayRef MarshallingHelpers::safeArrayToIUnknownArray(SAFEARRAY* inArray)
  222. {
  223. long lBound=0, uBound=-1;
  224. HRESULT hr = ::SafeArrayGetLBound(inArray, 1, &lBound);
  225. if (SUCCEEDED(hr))
  226. hr = ::SafeArrayGetUBound(inArray, 1, &uBound);
  227. long len = (SUCCEEDED(hr)) ? (uBound-lBound+1) : 0;
  228. void* items;
  229. hr = ::SafeArrayAccessData(inArray, &items);
  230. CFArrayRef result = CFArrayCreate(0, (const void**) items, len, &kIUnknownArrayCallBacks);
  231. hr = ::SafeArrayUnaccessData(inArray);
  232. return result;
  233. }
  234. const void* MarshallingHelpers::IUnknownRetainCallback(CFAllocatorRef /*allocator*/, const void* value)
  235. {
  236. ((IUnknown*) value)->AddRef();
  237. return value;
  238. }
  239. void MarshallingHelpers::IUnknownReleaseCallback(CFAllocatorRef /*allocator*/, const void* value)
  240. {
  241. ((IUnknown*) value)->Release();
  242. }