MarshallingHelpers.cpp [plain text]
#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)
{
return round((date + windowsEpochAbsoluteTime()) * secondsPerDay);
}
DATE MarshallingHelpers::CFAbsoluteTimeToDATE(CFAbsoluteTime absoluteTime)
{
return (round(absoluteTime)/secondsPerDay - windowsEpochAbsoluteTime());
}
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); count++;
}
return sa;
}
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;
}
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); 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 , const void* value)
{
((IUnknown*) value)->AddRef();
return value;
}
void MarshallingHelpers::IUnknownReleaseCallback(CFAllocatorRef , const void* value)
{
((IUnknown*) value)->Release();
}