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 "MarshallingHelpers.h"
29 #include "MathExtras.h"
31 #include <WebCore/IntRect.h>
32 #include <WebCore/KURL.h>
33 #include <WebCore/PlatformString.h>
35 using namespace WebCore;
37 static const double secondsPerDay = 60 * 60 * 24;
39 CFArrayCallBacks MarshallingHelpers::kIUnknownArrayCallBacks = {0, IUnknownRetainCallback, IUnknownReleaseCallback, 0, 0};
40 CFDictionaryValueCallBacks MarshallingHelpers::kIUnknownDictionaryValueCallBacks = {0, IUnknownRetainCallback, IUnknownReleaseCallback, 0, 0};
42 KURL MarshallingHelpers::BSTRToKURL(BSTR urlStr)
44 return KURL(KURL(), String(urlStr, SysStringLen(urlStr)));
47 BSTR MarshallingHelpers::KURLToBSTR(const KURL& url)
49 return SysAllocStringLen(url.string().characters(), url.string().length());
52 CFURLRef MarshallingHelpers::PathStringToFileCFURLRef(const String& string)
54 CFStringRef cfPath = CFStringCreateWithCharactersNoCopy(0, (const UniChar*)string.characters(), string.length(), kCFAllocatorNull);
55 CFURLRef pathURL = CFURLCreateWithFileSystemPath(0, cfPath, kCFURLWindowsPathStyle, false);
60 String MarshallingHelpers::FileCFURLRefToPathString(CFURLRef fileURL)
62 CFStringRef string = CFURLCopyFileSystemPath(fileURL, kCFURLWindowsPathStyle);
63 String result(string);
68 CFURLRef MarshallingHelpers::BSTRToCFURLRef(BSTR urlStr)
70 CFStringRef urlCFString = BSTRToCFStringRef(urlStr);
74 CFURLRef urlRef = CFURLCreateWithString(0, urlCFString, 0);
75 CFRelease(urlCFString);
80 CFStringRef MarshallingHelpers::BSTRToCFStringRef(BSTR str)
82 return CFStringCreateWithCharacters(0, (const UniChar*)(str ? str : TEXT("")), SysStringLen(str));
85 CFStringRef MarshallingHelpers::LPCOLESTRToCFStringRef(LPCOLESTR str)
87 return CFStringCreateWithCharacters(0, (const UniChar*)(str ? str : TEXT("")), (CFIndex)(str ? wcslen(str) : 0));
90 BSTR MarshallingHelpers::CFStringRefToBSTR(CFStringRef str)
95 const UniChar* uniChars = CFStringGetCharactersPtr(str);
97 return SysAllocStringLen((LPCTSTR)uniChars, CFStringGetLength(str));
99 CFIndex length = CFStringGetLength(str);
100 BSTR bstr = SysAllocStringLen(0, length);
102 CFStringGetCharacters(str, CFRangeMake(0, length), (UniChar*)bstr);
108 int MarshallingHelpers::CFNumberRefToInt(CFNumberRef num)
111 CFNumberGetValue(num, kCFNumberIntType, &number);
115 CFNumberRef MarshallingHelpers::intToCFNumberRef(int num)
117 return CFNumberCreate(0, kCFNumberSInt32Type, &num);
120 CFAbsoluteTime MarshallingHelpers::windowsEpochAbsoluteTime()
122 static CFAbsoluteTime windowsEpochAbsoluteTime = 0;
123 if (!windowsEpochAbsoluteTime) {
124 CFGregorianDate windowsEpochDate = {1899, 12, 30, 0, 0, 0.0};
125 windowsEpochAbsoluteTime = CFGregorianDateGetAbsoluteTime(windowsEpochDate, 0) / secondsPerDay;
127 return windowsEpochAbsoluteTime;
130 CFAbsoluteTime MarshallingHelpers::DATEToCFAbsoluteTime(DATE date)
132 // <http://msdn2.microsoft.com/en-us/library/ms221627.aspx>
133 // DATE: This is the same numbering system used by most spreadsheet programs,
134 // although some specify incorrectly that February 29, 1900 existed, and thus
135 // set January 1, 1900 to 1.0. The date can be converted to and from an MS-DOS
136 // representation using VariantTimeToDosDateTime, which is discussed in
137 // Conversion and Manipulation Functions.
139 // CFAbsoluteTime: Type used to represent a specific point in time relative
140 // to the absolute reference date of 1 Jan 2001 00:00:00 GMT.
141 // Absolute time is measured by the number of seconds between the reference
142 // date and the specified date. Negative values indicate dates/times before
143 // the reference date. Positive values indicate dates/times after the
146 return round((date + windowsEpochAbsoluteTime()) * secondsPerDay);
149 DATE MarshallingHelpers::CFAbsoluteTimeToDATE(CFAbsoluteTime absoluteTime)
151 return (round(absoluteTime)/secondsPerDay - windowsEpochAbsoluteTime());
154 // utility method to store a 1-dim string vector into a newly created SAFEARRAY
155 SAFEARRAY* MarshallingHelpers::stringArrayToSafeArray(CFArrayRef inArray)
157 CFIndex size = CFArrayGetCount(inArray);
158 SAFEARRAY* sa = ::SafeArrayCreateVectorEx(VT_BSTR, 0, (ULONG) size, 0);
160 for (CFIndex i=0; i<size; i++) {
161 CFStringRef item = (CFStringRef) CFArrayGetValueAtIndex(inArray, i);
162 BSTR bstr = CFStringRefToBSTR(item);
163 ::SafeArrayPutElement(sa, &count, bstr);
164 SysFreeString(bstr); // SafeArrayPutElement() should make a copy of the string
170 // utility method to store a 1-dim int vector into a newly created SAFEARRAY
171 SAFEARRAY* MarshallingHelpers::intArrayToSafeArray(CFArrayRef inArray)
173 CFIndex size = CFArrayGetCount(inArray);
174 SAFEARRAY* sa = ::SafeArrayCreateVectorEx(VT_I4, 0, (ULONG) size, 0);
176 for (CFIndex i=0; i<size; i++) {
177 CFNumberRef item = (CFNumberRef) CFArrayGetValueAtIndex(inArray, i);
178 int number = CFNumberRefToInt(item);
179 ::SafeArrayPutElement(sa, &count, &number);
185 SAFEARRAY* MarshallingHelpers::intRectToSafeArray(const WebCore::IntRect& rect)
187 SAFEARRAY* sa = ::SafeArrayCreateVectorEx(VT_I4, 0, 4, 0);
192 ::SafeArrayPutElement(sa, &count, &value);
196 ::SafeArrayPutElement(sa, &count, &value);
199 value = rect.width();
200 ::SafeArrayPutElement(sa, &count, &value);
203 value = rect.height();
204 ::SafeArrayPutElement(sa, &count, &value);
210 // utility method to store a 1-dim IUnknown* vector into a newly created SAFEARRAY
211 SAFEARRAY* MarshallingHelpers::iunknownArrayToSafeArray(CFArrayRef inArray)
213 CFIndex size = CFArrayGetCount(inArray);
214 SAFEARRAY* sa = ::SafeArrayCreateVectorEx(VT_UNKNOWN, 0, (ULONG) size, (LPVOID)&IID_IUnknown);
216 for (CFIndex i=0; i<size; i++) {
217 IUnknown* item = (IUnknown*) CFArrayGetValueAtIndex(inArray, i);
218 ::SafeArrayPutElement(sa, &count, item); // SafeArrayPutElement() adds a reference to the IUnknown added
224 CFArrayRef MarshallingHelpers::safeArrayToStringArray(SAFEARRAY* inArray)
226 long lBound=0, uBound=-1;
227 HRESULT hr = ::SafeArrayGetLBound(inArray, 1, &lBound);
229 hr = ::SafeArrayGetUBound(inArray, 1, &uBound);
230 long len = (SUCCEEDED(hr)) ? (uBound-lBound+1) : 0;
231 CFStringRef* items = 0;
233 items = new CFStringRef[len];
234 for (; lBound <= uBound; lBound++) {
236 hr = ::SafeArrayGetElement(inArray, &lBound, &str);
237 items[lBound] = BSTRToCFStringRef(str);
241 CFArrayRef result = CFArrayCreate(0, (const void**)items, len, &kCFTypeArrayCallBacks);
247 CFArrayRef MarshallingHelpers::safeArrayToIntArray(SAFEARRAY* inArray)
249 long lBound=0, uBound=-1;
250 HRESULT hr = ::SafeArrayGetLBound(inArray, 1, &lBound);
252 hr = ::SafeArrayGetUBound(inArray, 1, &uBound);
253 long len = (SUCCEEDED(hr)) ? (uBound-lBound+1) : 0;
254 CFNumberRef* items = 0;
256 items = new CFNumberRef[len];
257 for (; lBound <= uBound; lBound++) {
259 hr = ::SafeArrayGetElement(inArray, &lBound, &num);
260 items[lBound] = intToCFNumberRef(num);
263 CFArrayRef result = CFArrayCreate(0, (const void**) items, len, &kCFTypeArrayCallBacks);
269 CFArrayRef MarshallingHelpers::safeArrayToIUnknownArray(SAFEARRAY* inArray)
271 long lBound=0, uBound=-1;
272 HRESULT hr = ::SafeArrayGetLBound(inArray, 1, &lBound);
274 hr = ::SafeArrayGetUBound(inArray, 1, &uBound);
275 long len = (SUCCEEDED(hr)) ? (uBound-lBound+1) : 0;
277 hr = ::SafeArrayAccessData(inArray, &items);
278 CFArrayRef result = CFArrayCreate(0, (const void**) items, len, &kIUnknownArrayCallBacks);
279 hr = ::SafeArrayUnaccessData(inArray);
283 const void* MarshallingHelpers::IUnknownRetainCallback(CFAllocatorRef /*allocator*/, const void* value)
285 ((IUnknown*) value)->AddRef();
289 void MarshallingHelpers::IUnknownReleaseCallback(CFAllocatorRef /*allocator*/, const void* value)
291 ((IUnknown*) value)->Release();