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