WebKit/win/MarshallingHelpers.cpp
changeset 0 4f2f89ce4247
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebKit/win/MarshallingHelpers.cpp	Fri Sep 17 09:02:29 2010 +0300
@@ -0,0 +1,294 @@
+/*
+ * Copyright (C) 2006, 2007 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "WebKitDLL.h"
+#include "MarshallingHelpers.h"
+#include "MathExtras.h"
+
+#pragma warning(push, 0)
+#include <WebCore/IntRect.h>
+#include <WebCore/KURL.h>
+#include <WebCore/PlatformString.h>
+#pragma warning(pop)
+
+using namespace WebCore;
+
+static const double secondsPerDay = 60 * 60 * 24;
+
+CFArrayCallBacks MarshallingHelpers::kIUnknownArrayCallBacks = {0, IUnknownRetainCallback, IUnknownReleaseCallback, 0, 0};
+CFDictionaryValueCallBacks MarshallingHelpers::kIUnknownDictionaryValueCallBacks = {0, IUnknownRetainCallback, IUnknownReleaseCallback, 0, 0};
+
+KURL MarshallingHelpers::BSTRToKURL(BSTR urlStr)
+{
+    return KURL(KURL(), String(urlStr, SysStringLen(urlStr)));
+}
+
+BSTR MarshallingHelpers::KURLToBSTR(const KURL& url)
+{
+    return SysAllocStringLen(url.string().characters(), url.string().length());
+}
+
+CFURLRef MarshallingHelpers::PathStringToFileCFURLRef(const String& string)
+{
+    CFStringRef cfPath = CFStringCreateWithCharactersNoCopy(0, (const UniChar*)string.characters(), string.length(), kCFAllocatorNull);
+    CFURLRef pathURL = CFURLCreateWithFileSystemPath(0, cfPath, kCFURLWindowsPathStyle, false);
+    CFRelease(cfPath);
+    return pathURL;
+}
+
+String MarshallingHelpers::FileCFURLRefToPathString(CFURLRef fileURL)
+{
+    CFStringRef string = CFURLCopyFileSystemPath(fileURL, kCFURLWindowsPathStyle);
+    String result(string);
+    CFRelease(string);
+    return result;
+}
+
+CFURLRef MarshallingHelpers::BSTRToCFURLRef(BSTR urlStr)
+{
+    CFStringRef urlCFString = BSTRToCFStringRef(urlStr);
+    if (!urlCFString)
+        return 0;
+
+    CFURLRef urlRef = CFURLCreateWithString(0, urlCFString, 0);
+    CFRelease(urlCFString);
+
+    return urlRef;
+}
+
+CFStringRef MarshallingHelpers::BSTRToCFStringRef(BSTR str)
+{
+    return CFStringCreateWithCharacters(0, (const UniChar*)(str ? str : TEXT("")), SysStringLen(str));
+}
+
+CFStringRef MarshallingHelpers::LPCOLESTRToCFStringRef(LPCOLESTR str)
+{
+    return CFStringCreateWithCharacters(0, (const UniChar*)(str ? str : TEXT("")), (CFIndex)(str ? wcslen(str) : 0));
+}
+
+BSTR MarshallingHelpers::CFStringRefToBSTR(CFStringRef str)
+{
+    if (!str)
+        return 0;
+
+    const UniChar* uniChars = CFStringGetCharactersPtr(str);
+    if (uniChars)
+        return SysAllocStringLen((LPCTSTR)uniChars, CFStringGetLength(str));
+
+    CFIndex length = CFStringGetLength(str);
+    BSTR bstr = SysAllocStringLen(0, length);
+    if (bstr) {
+        CFStringGetCharacters(str, CFRangeMake(0, length), (UniChar*)bstr);
+        bstr[length] = 0;
+    }
+    return bstr;
+}
+
+int MarshallingHelpers::CFNumberRefToInt(CFNumberRef num)
+{
+    int number;
+    CFNumberGetValue(num, kCFNumberIntType, &number);
+    return number;
+}
+
+CFNumberRef MarshallingHelpers::intToCFNumberRef(int num)
+{
+    return CFNumberCreate(0, kCFNumberSInt32Type, &num);
+}
+
+CFAbsoluteTime MarshallingHelpers::windowsEpochAbsoluteTime()
+{
+    static CFAbsoluteTime windowsEpochAbsoluteTime = 0;
+    if (!windowsEpochAbsoluteTime) {
+        CFGregorianDate windowsEpochDate = {1899, 12, 30, 0, 0, 0.0};
+        windowsEpochAbsoluteTime = CFGregorianDateGetAbsoluteTime(windowsEpochDate, 0) / secondsPerDay;
+    }
+    return windowsEpochAbsoluteTime;
+}
+
+CFAbsoluteTime MarshallingHelpers::DATEToCFAbsoluteTime(DATE date)
+{
+    // <http://msdn2.microsoft.com/en-us/library/ms221627.aspx>
+    // DATE: This is the same numbering system used by most spreadsheet programs,
+    // although some specify incorrectly that February 29, 1900 existed, and thus
+    // set January 1, 1900 to 1.0. The date can be converted to and from an MS-DOS
+    // representation using VariantTimeToDosDateTime, which is discussed in
+    // Conversion and Manipulation Functions.
+
+    // CFAbsoluteTime: Type used to represent a specific point in time relative
+    // to the absolute reference date of 1 Jan 2001 00:00:00 GMT.
+    // Absolute time is measured by the number of seconds between the reference
+    // date and the specified date. Negative values indicate dates/times before
+    // the reference date. Positive values indicate dates/times after the
+    // reference date.
+
+    return round((date + windowsEpochAbsoluteTime()) * secondsPerDay);
+}
+
+DATE MarshallingHelpers::CFAbsoluteTimeToDATE(CFAbsoluteTime absoluteTime)
+{
+    return (round(absoluteTime)/secondsPerDay - windowsEpochAbsoluteTime());
+}
+
+// utility method to store a 1-dim string vector into a newly created SAFEARRAY
+SAFEARRAY* MarshallingHelpers::stringArrayToSafeArray(CFArrayRef inArray)
+{
+    CFIndex size = CFArrayGetCount(inArray);
+    SAFEARRAY* sa = ::SafeArrayCreateVectorEx(VT_BSTR, 0, (ULONG) size, 0);
+    long count = 0;
+    for (CFIndex i=0; i<size; i++) {
+        CFStringRef item = (CFStringRef) CFArrayGetValueAtIndex(inArray, i);
+        BSTR bstr = CFStringRefToBSTR(item);
+        ::SafeArrayPutElement(sa, &count, bstr);
+        SysFreeString(bstr);    // SafeArrayPutElement() should make a copy of the string
+        count++;
+    }
+    return sa;
+}
+
+// utility method to store a 1-dim int vector into a newly created SAFEARRAY
+SAFEARRAY* MarshallingHelpers::intArrayToSafeArray(CFArrayRef inArray)
+{
+    CFIndex size = CFArrayGetCount(inArray);
+    SAFEARRAY* sa = ::SafeArrayCreateVectorEx(VT_I4, 0, (ULONG) size, 0);
+    long count = 0;
+    for (CFIndex i=0; i<size; i++) {
+        CFNumberRef item = (CFNumberRef) CFArrayGetValueAtIndex(inArray, i);
+        int number = CFNumberRefToInt(item);
+        ::SafeArrayPutElement(sa, &count, &number);
+        count++;
+    }
+    return sa;
+}
+
+SAFEARRAY* MarshallingHelpers::intRectToSafeArray(const WebCore::IntRect& rect)
+{
+    SAFEARRAY* sa = ::SafeArrayCreateVectorEx(VT_I4, 0, 4, 0);
+    long count = 0;
+    int value;
+
+    value = rect.x();
+    ::SafeArrayPutElement(sa, &count, &value);
+    count++;
+
+    value = rect.y();
+    ::SafeArrayPutElement(sa, &count, &value);
+    count++;
+
+    value = rect.width();
+    ::SafeArrayPutElement(sa, &count, &value);
+    count++;
+
+    value = rect.height();
+    ::SafeArrayPutElement(sa, &count, &value);
+    count++;
+
+    return sa;
+}
+
+// utility method to store a 1-dim IUnknown* vector into a newly created SAFEARRAY
+SAFEARRAY* MarshallingHelpers::iunknownArrayToSafeArray(CFArrayRef inArray)
+{
+    CFIndex size = CFArrayGetCount(inArray);
+    SAFEARRAY* sa = ::SafeArrayCreateVectorEx(VT_UNKNOWN, 0, (ULONG) size, (LPVOID)&IID_IUnknown);
+    long count = 0;
+    for (CFIndex i=0; i<size; i++) {
+        IUnknown* item = (IUnknown*) CFArrayGetValueAtIndex(inArray, i);
+        ::SafeArrayPutElement(sa, &count, item);    // SafeArrayPutElement() adds a reference to the IUnknown added
+        count++;
+    }
+    return sa;
+}
+
+CFArrayRef MarshallingHelpers::safeArrayToStringArray(SAFEARRAY* inArray)
+{
+    long lBound=0, uBound=-1;
+    HRESULT hr = ::SafeArrayGetLBound(inArray, 1, &lBound);
+    if (SUCCEEDED(hr))
+        hr = ::SafeArrayGetUBound(inArray, 1, &uBound);
+    long len = (SUCCEEDED(hr)) ? (uBound-lBound+1) : 0;
+    CFStringRef* items = 0;
+    if (len > 0) {
+        items = new CFStringRef[len];
+        for (; lBound <= uBound; lBound++) {
+            BSTR str;
+            hr = ::SafeArrayGetElement(inArray, &lBound, &str);
+            items[lBound] = BSTRToCFStringRef(str);
+            SysFreeString(str);
+        }
+    }
+    CFArrayRef result = CFArrayCreate(0, (const void**)items, len, &kCFTypeArrayCallBacks);
+    if (items)
+        delete[] items;
+    return result;
+}
+
+CFArrayRef MarshallingHelpers::safeArrayToIntArray(SAFEARRAY* inArray)
+{
+    long lBound=0, uBound=-1;
+    HRESULT hr = ::SafeArrayGetLBound(inArray, 1, &lBound);
+    if (SUCCEEDED(hr))
+        hr = ::SafeArrayGetUBound(inArray, 1, &uBound);
+    long len = (SUCCEEDED(hr)) ? (uBound-lBound+1) : 0;
+    CFNumberRef* items = 0;
+    if (len > 0) {
+        items = new CFNumberRef[len];
+        for (; lBound <= uBound; lBound++) {
+            int num;
+            hr = ::SafeArrayGetElement(inArray, &lBound, &num);
+            items[lBound] = intToCFNumberRef(num);
+        }
+    }
+    CFArrayRef result = CFArrayCreate(0, (const void**) items, len, &kCFTypeArrayCallBacks);
+    if (items)
+        delete[] items;
+    return result;
+}
+
+CFArrayRef MarshallingHelpers::safeArrayToIUnknownArray(SAFEARRAY* inArray)
+{
+    long lBound=0, uBound=-1;
+    HRESULT hr = ::SafeArrayGetLBound(inArray, 1, &lBound);
+    if (SUCCEEDED(hr))
+        hr = ::SafeArrayGetUBound(inArray, 1, &uBound);
+    long len = (SUCCEEDED(hr)) ? (uBound-lBound+1) : 0;
+    void* items;
+    hr = ::SafeArrayAccessData(inArray, &items);
+    CFArrayRef result = CFArrayCreate(0, (const void**) items, len, &kIUnknownArrayCallBacks);
+    hr = ::SafeArrayUnaccessData(inArray);
+    return result;
+}
+
+const void* MarshallingHelpers::IUnknownRetainCallback(CFAllocatorRef /*allocator*/, const void* value)
+{
+    ((IUnknown*) value)->AddRef();
+    return value;
+}
+
+void MarshallingHelpers::IUnknownReleaseCallback(CFAllocatorRef /*allocator*/, const void* value)
+{
+    ((IUnknown*) value)->Release();
+}