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