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