helpers.cpp revision 848b6c64616a9dc0d00e7aaad7b82b8eb58e370e
c793af95640863cd29868fc7c419c5d2496b207bsangeeta/** @file
c793af95640863cd29868fc7c419c5d2496b207bsangeeta *
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * COM helper functions for XPCOM
c793af95640863cd29868fc7c419c5d2496b207bsangeeta */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta/*
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * Copyright (C) 2006-2007 innotek GmbH
c793af95640863cd29868fc7c419c5d2496b207bsangeeta *
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * This file is part of VirtualBox Open Source Edition (OSE), as
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * available from http://www.virtualbox.org. This file is free software;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * you can redistribute it and/or modify it under the terms of the GNU
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * General Public License (GPL) as published by the Free Software
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * Foundation, in version 2 as it comes in the "COPYING" file of the
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
c793af95640863cd29868fc7c419c5d2496b207bsangeeta */
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#include "VBox/com/defs.h"
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta#include <nsMemory.h>
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
fff7ec1d8ce71b3d8a998ac4391a99860ce07180Sowmini Varadhan#include <iprt/string.h>
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta//
c793af95640863cd29868fc7c419c5d2496b207bsangeeta// OLE Automation string APIs
c793af95640863cd29868fc7c419c5d2496b207bsangeeta//
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta// Note: on Windows, every BSTR stores its length in the
c793af95640863cd29868fc7c419c5d2496b207bsangeeta// byte just before the pointer you get. If we do it like this,
c793af95640863cd29868fc7c419c5d2496b207bsangeeta// the caller cannot just use nsMemory::Free() on our strings.
c793af95640863cd29868fc7c419c5d2496b207bsangeeta// Therefore we'll try to implement it differently and hope that
c793af95640863cd29868fc7c419c5d2496b207bsangeeta// we don't run into problems.
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta/**
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * Copies a string into a new memory block including the terminating UCS2 NULL
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * @param sz source string to copy
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * @returns BSTR new string buffer
c793af95640863cd29868fc7c419c5d2496b207bsangeeta */
c793af95640863cd29868fc7c419c5d2496b207bsangeetaBSTR SysAllocString(const OLECHAR* sz)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta{
c793af95640863cd29868fc7c419c5d2496b207bsangeeta if (!sz)
edd26dc5eeb3b093945c371e4b6dd8286348d53fdr {
c793af95640863cd29868fc7c419c5d2496b207bsangeeta return NULL;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta }
c793af95640863cd29868fc7c419c5d2496b207bsangeeta return SysAllocStringLen(sz, SysStringLen((BSTR)sz));
c793af95640863cd29868fc7c419c5d2496b207bsangeeta}
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta/**
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * Copies len OLECHARs of a string into a new memory block and
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * adds a terminating UCS2 NULL
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * @param psz source string to copy
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * @param len length of the source string in bytes
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * @returns BSTR new string buffer
c793af95640863cd29868fc7c419c5d2496b207bsangeeta */
edd26dc5eeb3b093945c371e4b6dd8286348d53fdrBSTR SysAllocStringByteLen(char *psz, unsigned int len)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta{
c793af95640863cd29868fc7c419c5d2496b207bsangeeta unsigned int *newBuffer;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta char *newString;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta newBuffer = (unsigned int*)nsMemory::Alloc(len + sizeof(OLECHAR));
c793af95640863cd29868fc7c419c5d2496b207bsangeeta if (!newBuffer)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta {
c793af95640863cd29868fc7c419c5d2496b207bsangeeta return NULL;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta }
c793af95640863cd29868fc7c419c5d2496b207bsangeeta if (psz)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta {
c793af95640863cd29868fc7c419c5d2496b207bsangeeta memcpy(newBuffer, psz, len);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta }
c793af95640863cd29868fc7c419c5d2496b207bsangeeta // make sure there is a trailing UCS2 NULL
c793af95640863cd29868fc7c419c5d2496b207bsangeeta newString = (char*)newBuffer;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta newString[len] = '\0';
c793af95640863cd29868fc7c419c5d2496b207bsangeeta newString[len + 1] = '\0';
c793af95640863cd29868fc7c419c5d2496b207bsangeeta return (BSTR)newString;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta}
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta/**
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * Create a BSTR from the OLECHAR string with a given length in UCS2 characters
44b099c4d944a196d124a02c7403ad891223139eSowmini Varadhan * @param pch pointer to the source string
44b099c4d944a196d124a02c7403ad891223139eSowmini Varadhan * @param cch length of the source string in UCS2 characters
44b099c4d944a196d124a02c7403ad891223139eSowmini Varadhan * @returns BSTR new string buffer
44b099c4d944a196d124a02c7403ad891223139eSowmini Varadhan */
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dhBSTR SysAllocStringLen(const OLECHAR *pch, unsigned int cch)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark{
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark unsigned int bufferSize;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta unsigned int *newBuffer;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta OLECHAR *newString;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta // add the trailing UCS2 NULL
c793af95640863cd29868fc7c419c5d2496b207bsangeeta bufferSize = cch * sizeof(OLECHAR);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta newBuffer = (unsigned int*)nsMemory::Alloc(bufferSize + sizeof(OLECHAR));
c793af95640863cd29868fc7c419c5d2496b207bsangeeta if (!newBuffer)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta {
c793af95640863cd29868fc7c419c5d2496b207bsangeeta return NULL;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark // copy the string, a NULL input string is allowed
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark if (pch)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark memcpy(newBuffer, pch, bufferSize);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta } else
c793af95640863cd29868fc7c419c5d2496b207bsangeeta {
c793af95640863cd29868fc7c419c5d2496b207bsangeeta memset(newBuffer, 0, bufferSize);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark }
c793af95640863cd29868fc7c419c5d2496b207bsangeeta // make sure there is a trailing UCS2 NULL
c793af95640863cd29868fc7c419c5d2496b207bsangeeta newString = (OLECHAR*)newBuffer;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark newString[cch] = L'\0';
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
c793af95640863cd29868fc7c419c5d2496b207bsangeeta return (BSTR)newString;
44b099c4d944a196d124a02c7403ad891223139eSowmini Varadhan}
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
c793af95640863cd29868fc7c419c5d2496b207bsangeeta/**
188e166434dcdde5356d87fb06c169f15dc4dca9Erik Nordmark * Frees the memory associated with the BSTR given
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * @param bstr source string to free
c793af95640863cd29868fc7c419c5d2496b207bsangeeta */
c793af95640863cd29868fc7c419c5d2496b207bsangeetavoid SysFreeString(BSTR bstr)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta{
188e166434dcdde5356d87fb06c169f15dc4dca9Erik Nordmark if (bstr)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta {
c793af95640863cd29868fc7c419c5d2496b207bsangeeta nsMemory::Free(bstr);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta }
c793af95640863cd29868fc7c419c5d2496b207bsangeeta}
188e166434dcdde5356d87fb06c169f15dc4dca9Erik Nordmark
c793af95640863cd29868fc7c419c5d2496b207bsangeeta/**
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * Reallocates a string by freeing the old string and copying
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * a new string into a new buffer.
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * @param pbstr old string to free
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * @param psz source string to copy into the new string
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * @returns success indicator
c793af95640863cd29868fc7c419c5d2496b207bsangeeta */
c793af95640863cd29868fc7c419c5d2496b207bsangeetaint SysReAllocString(BSTR *pbstr, const OLECHAR *psz)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta{
c793af95640863cd29868fc7c419c5d2496b207bsangeeta if (!pbstr)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta {
c793af95640863cd29868fc7c419c5d2496b207bsangeeta return 0;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta }
c793af95640863cd29868fc7c419c5d2496b207bsangeeta SysFreeString(*pbstr);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta *pbstr = SysAllocString(psz);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta return 1;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta}
c793af95640863cd29868fc7c419c5d2496b207bsangeeta
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark/**
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * Changes the length of a previous created BSTR
c793af95640863cd29868fc7c419c5d2496b207bsangeeta * @param pbstr string to change the length of
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dh * @param psz source string to copy into the adjusted pbstr
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dh * @param cch length of the source string in UCS2 characters
f4b3ec61df05330d25f55a36b975b4d7519fdeb1dh * @returns int success indicator
c793af95640863cd29868fc7c419c5d2496b207bsangeeta */
c793af95640863cd29868fc7c419c5d2496b207bsangeetaint SysReAllocStringLen(BSTR *pbstr, const OLECHAR *psz, unsigned int cch)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark{
c793af95640863cd29868fc7c419c5d2496b207bsangeeta if (SysStringLen(*pbstr) > 0)
c793af95640863cd29868fc7c419c5d2496b207bsangeeta {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark unsigned int newByteLen;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta unsigned int *newBuffer;
c793af95640863cd29868fc7c419c5d2496b207bsangeeta newByteLen = cch * sizeof(OLECHAR);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta newBuffer = (unsigned int*)nsMemory::Realloc((void*)*pbstr,
c793af95640863cd29868fc7c419c5d2496b207bsangeeta newByteLen + sizeof(OLECHAR));
c793af95640863cd29868fc7c419c5d2496b207bsangeeta if (psz)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark memcpy(*pbstr, psz, newByteLen);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark *pbstr[cch] = 0;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark }
c793af95640863cd29868fc7c419c5d2496b207bsangeeta } else
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark // allocate a new string
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark *pbstr = SysAllocStringLen(psz, cch);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark }
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark return 1;
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark}
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark/**
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * Returns the string length in bytes without the terminator
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * @returns unsigned int length in bytes
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * @param bstr source string
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark */
c793af95640863cd29868fc7c419c5d2496b207bsangeetaunsigned int SysStringByteLen(BSTR bstr)
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark{
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark return RTUtf16Len(bstr) * sizeof(OLECHAR);
c793af95640863cd29868fc7c419c5d2496b207bsangeeta}
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng/**
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * Returns the string length in OLECHARs without the terminator
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * @returns unsigned int length in OLECHARs
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark * @param bstr source string
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark */
da14cebe459d3275048785f25bd869cb09b5307fEric Chengunsigned int SysStringLen(BSTR bstr)
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng{
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return RTUtf16Len(bstr);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng}
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark