WebKit/win/MarshallingHelpers.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     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 
       
    44 KURL MarshallingHelpers::BSTRToKURL(BSTR urlStr)
       
    45 {
       
    46     return KURL(KURL(), String(urlStr, SysStringLen(urlStr)));
       
    47 }
       
    48 
       
    49 BSTR MarshallingHelpers::KURLToBSTR(const KURL& url)
       
    50 {
       
    51     return SysAllocStringLen(url.string().characters(), url.string().length());
       
    52 }
       
    53 
       
    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 
       
    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 
       
    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 
       
    82 CFStringRef MarshallingHelpers::BSTRToCFStringRef(BSTR str)
       
    83 {
       
    84     return CFStringCreateWithCharacters(0, (const UniChar*)(str ? str : TEXT("")), SysStringLen(str));
       
    85 }
       
    86 
       
    87 CFStringRef MarshallingHelpers::LPCOLESTRToCFStringRef(LPCOLESTR str)
       
    88 {
       
    89     return CFStringCreateWithCharacters(0, (const UniChar*)(str ? str : TEXT("")), (CFIndex)(str ? wcslen(str) : 0));
       
    90 }
       
    91 
       
    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 
       
   110 int MarshallingHelpers::CFNumberRefToInt(CFNumberRef num)
       
   111 {
       
   112     int number;
       
   113     CFNumberGetValue(num, kCFNumberIntType, &number);
       
   114     return number;
       
   115 }
       
   116 
       
   117 CFNumberRef MarshallingHelpers::intToCFNumberRef(int num)
       
   118 {
       
   119     return CFNumberCreate(0, kCFNumberSInt32Type, &num);
       
   120 }
       
   121 
       
   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 
       
   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 
       
   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
       
   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
       
   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 
       
   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
       
   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 
       
   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 
       
   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 
       
   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 
       
   285 const void* MarshallingHelpers::IUnknownRetainCallback(CFAllocatorRef /*allocator*/, const void* value)
       
   286 {
       
   287     ((IUnknown*) value)->AddRef();
       
   288     return value;
       
   289 }
       
   290 
       
   291 void MarshallingHelpers::IUnknownReleaseCallback(CFAllocatorRef /*allocator*/, const void* value)
       
   292 {
       
   293     ((IUnknown*) value)->Release();
       
   294 }