array.h revision 48a798f37e7038a0909576f2b1bd67be8747934f
dccbafa70b5a9a6f933c5566e4542caf9f379b97vboxsync/** @file
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync * MS COM / XPCOM Abstraction Layer:
5b281ba489ca18f0380d7efc7a5108b606cce449vboxsync * Safe array helper class declaration
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync */
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync/*
8e3f7f941e446e203bd8f3d0782d761aeb5af6c9vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync *
bd8e360cd1db83dcb2694ea9122ce3bc5bae678avboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
bd8e360cd1db83dcb2694ea9122ce3bc5bae678avboxsync * available from http://www.virtualbox.org. This file is free software;
bd8e360cd1db83dcb2694ea9122ce3bc5bae678avboxsync * you can redistribute it and/or modify it under the terms of the GNU
bd8e360cd1db83dcb2694ea9122ce3bc5bae678avboxsync * General Public License (GPL) as published by the Free Software
bd8e360cd1db83dcb2694ea9122ce3bc5bae678avboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
bd8e360cd1db83dcb2694ea9122ce3bc5bae678avboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
bd8e360cd1db83dcb2694ea9122ce3bc5bae678avboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
bd8e360cd1db83dcb2694ea9122ce3bc5bae678avboxsync *
bd8e360cd1db83dcb2694ea9122ce3bc5bae678avboxsync * The contents of this file may alternatively be used under the terms
bd8e360cd1db83dcb2694ea9122ce3bc5bae678avboxsync * of the Common Development and Distribution License Version 1.0
bd8e360cd1db83dcb2694ea9122ce3bc5bae678avboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
bd8e360cd1db83dcb2694ea9122ce3bc5bae678avboxsync * VirtualBox OSE distribution, in which case the provisions of the
bd8e360cd1db83dcb2694ea9122ce3bc5bae678avboxsync * CDDL are applicable instead of those of the GPL.
bd8e360cd1db83dcb2694ea9122ce3bc5bae678avboxsync *
bd8e360cd1db83dcb2694ea9122ce3bc5bae678avboxsync * You may elect to license modified versions of this file under the
bd8e360cd1db83dcb2694ea9122ce3bc5bae678avboxsync * terms and conditions of either the GPL or the CDDL or both.
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync *
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync * additional information or have any questions.
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync */
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync#ifndef ___VBox_com_array_h
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync#define ___VBox_com_array_h
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync
dccbafa70b5a9a6f933c5566e4542caf9f379b97vboxsync#include <VBox/com/ptr.h>
d618bed3882cd227cf8f5d0d2824f8db42fad415vboxsync
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync/** @defgroup grp_COM_arrays COM/XPCOM Arrays
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync * @{
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync *
5ef92c0006229b3fc7bc7eb4ad80ed65fb0dd98bvboxsync * The COM/XPCOM array support layer provides a cross-platform way to pass
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync * arrays to and from COM interface methods and consists of the com::SafeArray
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync * template and a set of ComSafeArray* macros part of which is defined in
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * VBox/com/defs.h.
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync *
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * This layer works with interface attributes and method parameters that have
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * the 'safearray="yes"' attribute in the XIDL definition:
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * @code
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync <interface name="ISomething" ...>
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync <method name="testArrays">
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync <param name="inArr" type="long" dir="in" safearray="yes"/>
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync <param name="outArr" type="long" dir="out" safearray="yes"/>
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync <param name="retArr" type="long" dir="return" safearray="yes"/>
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync </method>
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync </interface>
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * @endcode
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync *
dccbafa70b5a9a6f933c5566e4542caf9f379b97vboxsync * Methods generated from this and similar definitions are implemented in
ea6c70405e39fa563a55780ef25e0933d8c73a1avboxsync * component classes using the following declarations:
ea6c70405e39fa563a55780ef25e0933d8c73a1avboxsync * @code
ea6c70405e39fa563a55780ef25e0933d8c73a1avboxsync
ea6c70405e39fa563a55780ef25e0933d8c73a1avboxsync STDMETHOD(TestArrays) (ComSafeArrayIn (LONG, aIn),
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync ComSafeArrayOut (LONG, aOut),
ea6c70405e39fa563a55780ef25e0933d8c73a1avboxsync ComSafeArrayOut (LONG, aRet));
81587231c9c584851518872e197f6f02dffe68cavboxsync
81587231c9c584851518872e197f6f02dffe68cavboxsync * @endcode
81587231c9c584851518872e197f6f02dffe68cavboxsync *
81587231c9c584851518872e197f6f02dffe68cavboxsync * And the following function bodies:
81587231c9c584851518872e197f6f02dffe68cavboxsync * @code
81587231c9c584851518872e197f6f02dffe68cavboxsync
7be2140da7230ed5736528554a4dc34b2ac482acvboxsync STDMETHODIMP Component::TestArrays (ComSafeArrayIn (LONG, aIn),
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync ComSafeArrayOut (LONG, aOut),
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync ComSafeArrayOut (LONG, aRet))
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync {
ea6c70405e39fa563a55780ef25e0933d8c73a1avboxsync if (ComSafeArrayInIsNull (aIn))
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync return E_INVALIDARG;
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync if (ComSafeArrayOutIsNull (aOut))
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync return E_POINTER;
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync if (ComSafeArrayOutIsNull (aRet))
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync return E_POINTER;
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync // Use SafeArray to access the input array parameter
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync com::SafeArray <LONG> in (ComSafeArrayInArg (aIn));
ea6c70405e39fa563a55780ef25e0933d8c73a1avboxsync
ea6c70405e39fa563a55780ef25e0933d8c73a1avboxsync for (size_t i = 0; i < in.size(); ++ i)
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync LogFlow (("*** in[%u]=%d\n", i, in [i]));
ea6c70405e39fa563a55780ef25e0933d8c73a1avboxsync
ea6c70405e39fa563a55780ef25e0933d8c73a1avboxsync // Use SafeArray to create the return array (the same technique is used
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync // for output array paramters)
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync SafeArray <LONG> ret (in.size() * 2);
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync for (size_t i = 0; i < in.size(); ++ i)
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync {
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync ret [i] = in [i];
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync ret [i + in.size()] = in [i] * 10;
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync }
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync ret.detachTo (ComSafeArrayOutArg (aRet));
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync return S_OK;
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync }
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync * @endcode
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync *
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync * Such methods can be called from the client code using the following pattern:
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync * @code
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync ComPtr <ISomething> component;
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync // ...
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync com::SafeArray <LONG> in (3);
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync in [0] = -1;
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync in [1] = -2;
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync in [2] = -3;
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync com::SafeArray <LONG> out;
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync com::SafeArray <LONG> ret;
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync HRESULT rc = component->TestArrays (ComSafeArrayAsInParam (in),
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync ComSafeArrayAsOutParam (out),
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync ComSafeArrayAsOutParam (ret));
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync if (SUCCEEDED (rc))
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync for (size_t i = 0; i < ret.size(); ++ i)
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync printf ("*** ret[%u]=%d\n", i, ret [i]);
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync * @endcode
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync *
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync * For interoperability with standard C++ containers, there is a template
c882ddf98a60a4aab1218108b334083f98b7d66avboxsync * constructor that takes such a container as argument and performs a deep copy
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * of its contents. This can be used in method implementations like this:
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * @code
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync STDMETHODIMP Component::COMGETTER(Values) (ComSafeArrayOut (int, aValues))
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync {
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync // ... assume there is a |std::list <int> mValues| data member
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync com::SafeArray <int> values (mValues);
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync values.detachTo (ComSafeArrayOutArg (aValues));
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync return S_OK;
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync }
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * @endcode
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync *
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * The current implementation of the SafeArray layer supports all types normally
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * allowed in XIDL as array element types (including 'wstring' and 'uuid').
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * However, 'pointer-to-...' types (e.g. 'long *', 'wstring *') are not
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * supported and therefore cannot be used as element types.
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync *
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * In order to pass input BSTR array parameters delcared using the
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * ComSafeArrayIn (INPTR BSTR, aParam) macro to the SafeArray<> constructor
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * using the ComSafeArrayInArg() macro, you should use INPTR BSTR as the
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * SafeArray<> template argument, not just BSTR.
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync *
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * Arrays of interface pointers are also supported but they require to use a
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * special SafeArray implementation, com::SafeIfacePointer, which takes the
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * interface class name as a template argument (e.g. com::SafeIfacePointer
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * <IUnknown>). This implementation functions identically to com::SafeArray.
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync */
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync#if defined (VBOX_WITH_XPCOM)
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync#include <nsMemory.h>
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync#endif
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync#include "VBox/com/defs.h"
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync#include "VBox/com/assert.h"
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync#include "iprt/cpputils.h"
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync#if defined (VBOX_WITH_XPCOM)
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync/**
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * Wraps the given com::SafeArray instance to generate an expression that is
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * suitable for passing it to functions that take input safearray parameters
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * declared using the ComSafeArrayIn marco.
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync *
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * @param aArray com::SafeArray instance to pass as an input parameter.
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync */
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync#define ComSafeArrayAsInParam(aArray) \
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync (aArray).size(), (aArray).__asInParam_Arr (aArray.raw())
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync/**
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * Wraps the given com::SafeArray instance to generate an expression that is
b6097213cd07c5383c49168bfb61f915dbd4587avboxsync * suitable for passing it to functions that take output safearray parameters
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync * declared using the ComSafeArrayOut marco.
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync *
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync * @param aArray com::SafeArray instance to pass as an output parameter.
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync */
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync#define ComSafeArrayAsOutParam(aArray) \
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync (aArray).__asOutParam_Size(), (aArray).__asOutParam_Arr()
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync#else /* defined (VBOX_WITH_XPCOM) */
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync#define ComSafeArrayAsInParam(aArray) (aArray).__asInParam()
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync#define ComSafeArrayAsOutParam(aArray) (aArray).__asOutParam()
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync#endif /* defined (VBOX_WITH_XPCOM) */
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync/**
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync *
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync */
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsyncnamespace com
7868f7238f92c22fcfede63182607629da7a8eadvboxsync{
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync
fd546afe09073de92e5422c1334f1c27b4108687vboxsync#if defined (VBOX_WITH_XPCOM)
fd546afe09073de92e5422c1334f1c27b4108687vboxsync
fd546afe09073de92e5422c1334f1c27b4108687vboxsync////////////////////////////////////////////////////////////////////////////////
fd546afe09073de92e5422c1334f1c27b4108687vboxsync
fd546afe09073de92e5422c1334f1c27b4108687vboxsync/**
fd546afe09073de92e5422c1334f1c27b4108687vboxsync * Contains various helper constants for SafeArray.
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync */
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsynctemplate <typename T>
8e3f7f941e446e203bd8f3d0782d761aeb5af6c9vboxsyncstruct SafeArrayTraits
8e3f7f941e446e203bd8f3d0782d761aeb5af6c9vboxsync{
8e3f7f941e446e203bd8f3d0782d761aeb5af6c9vboxsyncprotected:
fd546afe09073de92e5422c1334f1c27b4108687vboxsync
fd546afe09073de92e5422c1334f1c27b4108687vboxsync static void Init (T &aElem) { aElem = 0; }
fd546afe09073de92e5422c1334f1c27b4108687vboxsync static void Uninit (T &aElem) { aElem = 0; }
fd546afe09073de92e5422c1334f1c27b4108687vboxsync static void Copy (const T &aFrom, T &aTo) { aTo = aFrom; }
fd546afe09073de92e5422c1334f1c27b4108687vboxsync
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsyncpublic:
fd546afe09073de92e5422c1334f1c27b4108687vboxsync
fd546afe09073de92e5422c1334f1c27b4108687vboxsync /* Magic to workaround strict rules of par. 4.4.4 of the C++ standard (that
fd546afe09073de92e5422c1334f1c27b4108687vboxsync * in particular forbid casts of 'char **' to 'const char **'). Then initial
fd546afe09073de92e5422c1334f1c27b4108687vboxsync * reason for this magic is that XPIDL declares input strings
fd546afe09073de92e5422c1334f1c27b4108687vboxsync * (char/PRUnichar pointers) as const but doesn't do so for pointers to
fd546afe09073de92e5422c1334f1c27b4108687vboxsync * arrays. */
fd546afe09073de92e5422c1334f1c27b4108687vboxsync static T *__asInParam_Arr (T *aArr) { return aArr; }
fd546afe09073de92e5422c1334f1c27b4108687vboxsync static T *__asInParam_Arr (const T *aArr) { return const_cast <T *> (aArr); }
fd546afe09073de92e5422c1334f1c27b4108687vboxsync};
fd546afe09073de92e5422c1334f1c27b4108687vboxsync
fd546afe09073de92e5422c1334f1c27b4108687vboxsynctemplate <typename T>
8e3f7f941e446e203bd8f3d0782d761aeb5af6c9vboxsyncstruct SafeArrayTraits <T *>
8e3f7f941e446e203bd8f3d0782d761aeb5af6c9vboxsync{
8e3f7f941e446e203bd8f3d0782d761aeb5af6c9vboxsync // Arbitrary pointers are not supported
fd546afe09073de92e5422c1334f1c27b4108687vboxsync};
fd546afe09073de92e5422c1334f1c27b4108687vboxsync
fd546afe09073de92e5422c1334f1c27b4108687vboxsynctemplate<>
fd546afe09073de92e5422c1334f1c27b4108687vboxsyncstruct SafeArrayTraits <PRUnichar *>
fd546afe09073de92e5422c1334f1c27b4108687vboxsync{
fd546afe09073de92e5422c1334f1c27b4108687vboxsyncprotected:
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync
8e3f7f941e446e203bd8f3d0782d761aeb5af6c9vboxsync static void Init (PRUnichar * &aElem) { aElem = NULL; }
8e3f7f941e446e203bd8f3d0782d761aeb5af6c9vboxsync static void Uninit (PRUnichar * &aElem)
8e3f7f941e446e203bd8f3d0782d761aeb5af6c9vboxsync {
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync if (aElem)
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync {
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync ::SysFreeString (aElem);
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync aElem = NULL;
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync }
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync }
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
8e3f7f941e446e203bd8f3d0782d761aeb5af6c9vboxsync static void Copy (const PRUnichar * aFrom, PRUnichar * &aTo)
8e3f7f941e446e203bd8f3d0782d761aeb5af6c9vboxsync {
8e3f7f941e446e203bd8f3d0782d761aeb5af6c9vboxsync AssertCompile (sizeof (PRUnichar) == sizeof (OLECHAR));
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync aTo = aFrom ? ::SysAllocString ((const OLECHAR *) aFrom) : NULL;
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync }
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsyncpublic:
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync /* Magic to workaround strict rules of par. 4.4.4 of the C++ standard */
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync static const PRUnichar **__asInParam_Arr (PRUnichar **aArr)
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync {
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync return const_cast <const PRUnichar **> (aArr);
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync }
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync static const PRUnichar **__asInParam_Arr (const PRUnichar **aArr) { return aArr; }
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync};
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsynctemplate<>
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsyncstruct SafeArrayTraits <const PRUnichar *>
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync{
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsyncprotected:
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync static void Init (const PRUnichar * &aElem) { aElem = NULL; }
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync static void Uninit (const PRUnichar * &aElem)
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync {
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync if (aElem)
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync {
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync ::SysFreeString (const_cast <PRUnichar *> (aElem));
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync aElem = NULL;
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync }
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync }
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync static void Copy (const PRUnichar * aFrom, const PRUnichar * &aTo)
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync {
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync AssertCompile (sizeof (PRUnichar) == sizeof (OLECHAR));
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync aTo = aFrom ? ::SysAllocString ((const OLECHAR *) aFrom) : NULL;
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync }
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsyncpublic:
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync /* Magic to workaround strict rules of par. 4.4.4 of the C++ standard */
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync static const PRUnichar **__asInParam_Arr (const PRUnichar **aArr) { return aArr; }
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync};
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync#else /* defined (VBOX_WITH_XPCOM) */
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync////////////////////////////////////////////////////////////////////////////////
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync/**
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * Contains various helper constants for SafeArray.
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync */
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsynctemplate <typename T>
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsyncstruct SafeArrayTraits
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync{
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync // Arbitrary types are not supported
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync};
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsynctemplate<>
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsyncstruct SafeArrayTraits <LONG>
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync{
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsyncprotected:
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync static VARTYPE VarType() { return VT_I4; }
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync static void Copy (LONG aFrom, LONG &aTo) { aTo = aFrom; }
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync};
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
8f78050183f7368c70cfc93edd1180326edc1208vboxsynctemplate<>
8f78050183f7368c70cfc93edd1180326edc1208vboxsyncstruct SafeArrayTraits <ULONG>
8f78050183f7368c70cfc93edd1180326edc1208vboxsync{
8f78050183f7368c70cfc93edd1180326edc1208vboxsyncprotected:
8f78050183f7368c70cfc93edd1180326edc1208vboxsync
8f78050183f7368c70cfc93edd1180326edc1208vboxsync static VARTYPE VarType() { return VT_UI4; }
8f78050183f7368c70cfc93edd1180326edc1208vboxsync static void Copy (ULONG aFrom, ULONG &aTo) { aTo = aFrom; }
8f78050183f7368c70cfc93edd1180326edc1208vboxsync};
8f78050183f7368c70cfc93edd1180326edc1208vboxsync
8f78050183f7368c70cfc93edd1180326edc1208vboxsynctemplate<>
8f78050183f7368c70cfc93edd1180326edc1208vboxsyncstruct SafeArrayTraits <LONG64>
8f78050183f7368c70cfc93edd1180326edc1208vboxsync{
8f78050183f7368c70cfc93edd1180326edc1208vboxsyncprotected:
8f78050183f7368c70cfc93edd1180326edc1208vboxsync
8f78050183f7368c70cfc93edd1180326edc1208vboxsync static VARTYPE VarType() { return VT_I8; }
8f78050183f7368c70cfc93edd1180326edc1208vboxsync static void Copy (LONG64 aFrom, LONG64 &aTo) { aTo = aFrom; }
8f78050183f7368c70cfc93edd1180326edc1208vboxsync};
8f78050183f7368c70cfc93edd1180326edc1208vboxsync
8f78050183f7368c70cfc93edd1180326edc1208vboxsynctemplate<>
8f78050183f7368c70cfc93edd1180326edc1208vboxsyncstruct SafeArrayTraits <ULONG64>
8f78050183f7368c70cfc93edd1180326edc1208vboxsync{
8f78050183f7368c70cfc93edd1180326edc1208vboxsyncprotected:
8f78050183f7368c70cfc93edd1180326edc1208vboxsync
8f78050183f7368c70cfc93edd1180326edc1208vboxsync static VARTYPE VarType() { return VT_UI8; }
8f78050183f7368c70cfc93edd1180326edc1208vboxsync static void Copy (ULONG64 aFrom, ULONG64 &aTo) { aTo = aFrom; }
8f78050183f7368c70cfc93edd1180326edc1208vboxsync};
8f78050183f7368c70cfc93edd1180326edc1208vboxsync
8f78050183f7368c70cfc93edd1180326edc1208vboxsynctemplate<>
8f78050183f7368c70cfc93edd1180326edc1208vboxsyncstruct SafeArrayTraits <BSTR>
8f78050183f7368c70cfc93edd1180326edc1208vboxsync{
8f78050183f7368c70cfc93edd1180326edc1208vboxsyncprotected:
8f78050183f7368c70cfc93edd1180326edc1208vboxsync
4fa08e9052161e65bfe8d2e3bb38fa227af628c0vboxsync static VARTYPE VarType() { return VT_BSTR; }
4fa08e9052161e65bfe8d2e3bb38fa227af628c0vboxsync
4fa08e9052161e65bfe8d2e3bb38fa227af628c0vboxsync static void Copy (BSTR aFrom, BSTR &aTo)
4fa08e9052161e65bfe8d2e3bb38fa227af628c0vboxsync {
4fa08e9052161e65bfe8d2e3bb38fa227af628c0vboxsync aTo = aFrom ? ::SysAllocString ((const OLECHAR *) aFrom) : NULL;
4fa08e9052161e65bfe8d2e3bb38fa227af628c0vboxsync }
4fa08e9052161e65bfe8d2e3bb38fa227af628c0vboxsync};
4fa08e9052161e65bfe8d2e3bb38fa227af628c0vboxsync
4fa08e9052161e65bfe8d2e3bb38fa227af628c0vboxsync#endif /* defined (VBOX_WITH_XPCOM) */
4fa08e9052161e65bfe8d2e3bb38fa227af628c0vboxsync
4fa08e9052161e65bfe8d2e3bb38fa227af628c0vboxsync////////////////////////////////////////////////////////////////////////////////
4fa08e9052161e65bfe8d2e3bb38fa227af628c0vboxsync
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync/**
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * The SafeArray class represents the safe array type used in COM to pass arrays
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * to/from interface methods.
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync *
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * This helper class hides all MSCOM/XPCOM specific implementation details and,
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * together with ComSafeArrayIn, ComSafeArrayOut and ComSafeArrayRet macros,
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * provides a platform-neutral way to handle safe arrays in the method
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * implementation.
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync *
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * When an instance of this class is destroyed, it automatically frees all
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * resources occupied by individual elements of the array as well as by the
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * array itself. However, when the value of an element is manually changed
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * using #operator[] or by acessing array data through the #raw() pointer, it is
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync * the caller's responsibility to free resources occupied by the previous
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * element's value.
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync *
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * Also, objects of this class do not support copy and assignment operations and
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * therefore cannot be returned from functions by value. In other words, this
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * class is just a temporary storage for handling interface method calls and not
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * intended to be used to store arrays as data members and such -- you should
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * use normal list/vector classes for that.
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync *
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * @note The current implementation supports only one-dimentional arrays.
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync *
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync * @note This class is not thread-safe.
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync */
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsynctemplate <typename T, class Traits = SafeArrayTraits <T> >
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsyncclass SafeArray : public Traits
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync{
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsyncpublic:
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync /**
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync * Creates a null array.
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync */
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync SafeArray() {}
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync /**
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync * Creates a new array of the given size. All elements of the newly created
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync * array initialized with null values.
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync *
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync * @param aSize Initial number of elements in the array. Must be greater
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync * than 0.
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync *
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync * @note If this object remains null after construction it means that there
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync * was not enough memory for creating an array of the requested size.
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync * The constructor will also assert in this case.
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync */
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync SafeArray (size_t aSize) { reset (aSize); }
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync /**
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync * Weakly attaches this instance to the existing array passed in a method
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync * parameter declared using the ComSafeArrayIn macro. When using this call,
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync * always wrap the parameter name in the ComSafeArrayOutArg macro call like
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync * this:
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync * <pre>
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync * SafeArray safeArray (ComSafeArrayInArg (aArg));
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync * </pre>
1a05eb58618c8f646bd1304d10c73792e0034f20vboxsync *
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * Note that this constructor doesn't take the ownership of the array. In
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * particular, it means that operations that operate on the ownership (e.g.
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * #detachTo()) are forbidden and will assert.
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync *
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * @param aArg Input method parameter to attach to.
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync */
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync SafeArray (ComSafeArrayIn (T, aArg))
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync {
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync#if defined (VBOX_WITH_XPCOM)
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync AssertReturnVoid (aArg != NULL);
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync m.size = aArgSize;
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync m.arr = aArg;
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync m.isWeak = true;
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync#else /* defined (VBOX_WITH_XPCOM) */
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync AssertReturnVoid (aArg != NULL);
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync SAFEARRAY *arg = *aArg;
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync if (arg)
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync {
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync AssertReturnVoid (arg->cDims == 1);
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync VARTYPE vt;
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync HRESULT rc = SafeArrayGetVartype (arg, &vt);
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync AssertComRCReturnVoid (rc);
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync AssertMsgReturnVoid (vt == VarType(),
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync ("Expected vartype %d, got %d.\n",
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync VarType(), vt));
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync }
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync m.arr = arg;
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync m.isWeak = true;
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync AssertReturnVoid (accessRaw() != NULL);
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync#endif /* defined (VBOX_WITH_XPCOM) */
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync }
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync /**
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * Creates a deep copy of the goven standard C++ container.
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync *
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * @param aCntr Container object to copy.
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync *
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * @param C Standard C++ container template class (normally deduced from
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * @c aCntr).
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync */
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync template <template <class> class C>
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync SafeArray (const C <T> & aCntr)
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync {
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync reset (aCntr.size());
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync AssertReturnVoid (!isNull());
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync int i = 0;
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync for (typename C <T>::const_iterator it = aCntr.begin();
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync it != aCntr.end(); ++ it, ++ i)
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync#if defined (VBOX_WITH_XPCOM)
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync Copy (*it, m.arr [i]);
ea6c70405e39fa563a55780ef25e0933d8c73a1avboxsync#else
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync Copy (*it, m.raw [i]);
fd546afe09073de92e5422c1334f1c27b4108687vboxsync#endif
fd546afe09073de92e5422c1334f1c27b4108687vboxsync }
fd546afe09073de92e5422c1334f1c27b4108687vboxsync
7be2140da7230ed5736528554a4dc34b2ac482acvboxsync /**
7e0c3d180b978b8f4b5b33f8e924520248ee3ab3vboxsync * Destroys this instance after calling #setNull() to release allocated
fd546afe09073de92e5422c1334f1c27b4108687vboxsync * resources. See #setNull() for more details.
81587231c9c584851518872e197f6f02dffe68cavboxsync */
81587231c9c584851518872e197f6f02dffe68cavboxsync virtual ~SafeArray() { setNull(); }
81587231c9c584851518872e197f6f02dffe68cavboxsync
dc88ff18a0306635c385b14211765e618351b253vboxsync /**
dccbafa70b5a9a6f933c5566e4542caf9f379b97vboxsync * Returns @c true if this instance represents a null array.
dccbafa70b5a9a6f933c5566e4542caf9f379b97vboxsync */
81587231c9c584851518872e197f6f02dffe68cavboxsync bool isNull() const { return m.arr == NULL; }
81587231c9c584851518872e197f6f02dffe68cavboxsync
81587231c9c584851518872e197f6f02dffe68cavboxsync /**
81587231c9c584851518872e197f6f02dffe68cavboxsync * Resets this instance to null and, if this instance is not a weak one,
81587231c9c584851518872e197f6f02dffe68cavboxsync * releases any resources ocuppied by the array data.
81587231c9c584851518872e197f6f02dffe68cavboxsync *
81587231c9c584851518872e197f6f02dffe68cavboxsync * @note This method destroys (cleans up) all elements of the array using
81587231c9c584851518872e197f6f02dffe68cavboxsync * the corresponding cleanup routine for the element type before the
81587231c9c584851518872e197f6f02dffe68cavboxsync * array itself is destroyed.
81587231c9c584851518872e197f6f02dffe68cavboxsync */
81587231c9c584851518872e197f6f02dffe68cavboxsync virtual void setNull() { m.uninit(); }
81587231c9c584851518872e197f6f02dffe68cavboxsync
81587231c9c584851518872e197f6f02dffe68cavboxsync /**
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * Returns @c true if this instance is weak. A weak instance doesn't own the
81587231c9c584851518872e197f6f02dffe68cavboxsync * array data and therefore operations manipulating the ownership (e.g.
81587231c9c584851518872e197f6f02dffe68cavboxsync * #detachTo()) are forbidden and will assert.
81587231c9c584851518872e197f6f02dffe68cavboxsync */
81587231c9c584851518872e197f6f02dffe68cavboxsync bool isWeak() const { return m.isWeak; }
81587231c9c584851518872e197f6f02dffe68cavboxsync
81587231c9c584851518872e197f6f02dffe68cavboxsync /** Number of elements in the array. */
81587231c9c584851518872e197f6f02dffe68cavboxsync size_t size() const
81587231c9c584851518872e197f6f02dffe68cavboxsync {
81587231c9c584851518872e197f6f02dffe68cavboxsync#if defined (VBOX_WITH_XPCOM)
81587231c9c584851518872e197f6f02dffe68cavboxsync if (m.arr)
81587231c9c584851518872e197f6f02dffe68cavboxsync return m.size;
81587231c9c584851518872e197f6f02dffe68cavboxsync return 0;
81587231c9c584851518872e197f6f02dffe68cavboxsync#else
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync if (m.arr)
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync return m.arr->rgsabound [0].cElements;
81587231c9c584851518872e197f6f02dffe68cavboxsync return 0;
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync#endif
81587231c9c584851518872e197f6f02dffe68cavboxsync }
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync /**
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * Resizes the array preserving its contents when possible. If the new size
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * is bigger than the old size, new elements are initialized with null
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * values. If the new size is smaller than the old size, the contents of the
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * array above the new size is lost.
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync *
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * @param aNewSize New number of elements in the array.
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * @return @c true on success and false if there is not enough
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * memory for resizing.
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync */
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync virtual bool resize (size_t aNewSize)
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync {
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync /// @todo Implement me!
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync NOREF (aNewSize);
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync AssertFailedReturn (false);
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync }
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync /**
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * Reinitializes this instance by preallocating space for the given number
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * of elements. The previous array contents is lost.
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync *
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * @param aNewSize New number of elements in the array.
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * @return @c true on success and false if there is not enough
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * memory for resizing.
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync */
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync virtual bool reset (size_t aNewSize)
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync {
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync m.uninit();
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync#if defined (VBOX_WITH_XPCOM)
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync /* Note: for zero-sized arrays, we use the size of 1 because whether
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * malloc(0) returns a null pointer or not (which is used in isNull())
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * is implementation-dependent according to the C standard. */
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync m.arr = (T *) nsMemory::Alloc (RT_MAX (aNewSize, 1) * sizeof (T));
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync AssertReturn (m.arr != NULL, false);
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync m.size = aNewSize;
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync for (size_t i = 0; i < m.size; ++ i)
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync Init (m.arr [i]);
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync#else
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync SAFEARRAYBOUND bound = { (ULONG)aNewSize, 0 };
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync m.arr = SafeArrayCreate (VarType(), 1, &bound);
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync AssertReturn (m.arr != NULL, false);
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync AssertReturn (accessRaw() != NULL, false);
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync#endif
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync return true;
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync }
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync /**
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * Returns a pointer to the raw array data. Use this raw pointer with care
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * as no type or bound checking is done for you in this case.
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync *
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * @note This method returns @c NULL when this instance is null.
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * @see #operator[]
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync */
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync T *raw()
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync {
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync#if defined (VBOX_WITH_XPCOM)
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync return m.arr;
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync#else
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync return accessRaw();
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync#endif
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync }
81587231c9c584851518872e197f6f02dffe68cavboxsync
81587231c9c584851518872e197f6f02dffe68cavboxsync /**
81587231c9c584851518872e197f6f02dffe68cavboxsync * Const version of #raw().
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync */
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync const T *raw() const
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync {
dccbafa70b5a9a6f933c5566e4542caf9f379b97vboxsync#if defined (VBOX_WITH_XPCOM)
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync return m.arr;
da97b7ac000d0f02e86c31a4f2767a00d83c6167vboxsync#else
da97b7ac000d0f02e86c31a4f2767a00d83c6167vboxsync return accessRaw();
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync#endif
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync }
7868f7238f92c22fcfede63182607629da7a8eadvboxsync
14e0667f834cd0e2a8c365084cd2ad0a893109e8vboxsync /**
7868f7238f92c22fcfede63182607629da7a8eadvboxsync * Array access operator that returns an array element by reference. A bit
14e0667f834cd0e2a8c365084cd2ad0a893109e8vboxsync * safer than #raw(): asserts and returns an invalid reference if this
14e0667f834cd0e2a8c365084cd2ad0a893109e8vboxsync * instance is null or if the index is out of bounds.
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync *
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync * @note For weak instances, this call will succeed but the beiavior of
d618bed3882cd227cf8f5d0d2824f8db42fad415vboxsync * changing the contents of an element of the weak array instance is
7868f7238f92c22fcfede63182607629da7a8eadvboxsync * undefined and may lead to a program crash on some platforms.
da97b7ac000d0f02e86c31a4f2767a00d83c6167vboxsync */
ea6c70405e39fa563a55780ef25e0933d8c73a1avboxsync T &operator[] (size_t aIdx)
da97b7ac000d0f02e86c31a4f2767a00d83c6167vboxsync {
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync AssertReturn (m.arr != NULL, *((T *) NULL));
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync AssertReturn (aIdx < size(), *((T *) NULL));
ea6c70405e39fa563a55780ef25e0933d8c73a1avboxsync#if defined (VBOX_WITH_XPCOM)
da97b7ac000d0f02e86c31a4f2767a00d83c6167vboxsync return m.arr [aIdx];
da97b7ac000d0f02e86c31a4f2767a00d83c6167vboxsync#else
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync
81587231c9c584851518872e197f6f02dffe68cavboxsync AssertReturn (accessRaw() != NULL, *((T *) NULL));
81587231c9c584851518872e197f6f02dffe68cavboxsync return m.raw [aIdx];
81587231c9c584851518872e197f6f02dffe68cavboxsync#endif
81587231c9c584851518872e197f6f02dffe68cavboxsync }
81587231c9c584851518872e197f6f02dffe68cavboxsync
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync /**
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync * Const version of #operator[] that returns an array element by value.
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync */
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync const T operator[] (size_t aIdx) const
fd546afe09073de92e5422c1334f1c27b4108687vboxsync {
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync AssertReturn (m.arr != NULL, *((T *) NULL));
fd546afe09073de92e5422c1334f1c27b4108687vboxsync AssertReturn (aIdx < size(), *((T *) NULL));
fd546afe09073de92e5422c1334f1c27b4108687vboxsync#if defined (VBOX_WITH_XPCOM)
fd546afe09073de92e5422c1334f1c27b4108687vboxsync return m.arr [aIdx];
fd546afe09073de92e5422c1334f1c27b4108687vboxsync#else
7e0c3d180b978b8f4b5b33f8e924520248ee3ab3vboxsync AssertReturn (unconst (this)->accessRaw() != NULL, *((T *) NULL));
fd546afe09073de92e5422c1334f1c27b4108687vboxsync return m.raw [aIdx];
7e0c3d180b978b8f4b5b33f8e924520248ee3ab3vboxsync#endif
fd546afe09073de92e5422c1334f1c27b4108687vboxsync }
fd546afe09073de92e5422c1334f1c27b4108687vboxsync
fd546afe09073de92e5422c1334f1c27b4108687vboxsync /**
fd546afe09073de92e5422c1334f1c27b4108687vboxsync * Creates a copy of this array and stores it in a method parameter declared
fd546afe09073de92e5422c1334f1c27b4108687vboxsync * using the ComSafeArrayOut macro. When using this call, always wrap the
fd546afe09073de92e5422c1334f1c27b4108687vboxsync * parameter name in the ComSafeArrayOutArg macro call like this:
fd546afe09073de92e5422c1334f1c27b4108687vboxsync * <pre>
fd546afe09073de92e5422c1334f1c27b4108687vboxsync * safeArray.cloneTo (ComSafeArrayOutArg (aArg));
fd546afe09073de92e5422c1334f1c27b4108687vboxsync * </pre>
fd546afe09073de92e5422c1334f1c27b4108687vboxsync *
fd546afe09073de92e5422c1334f1c27b4108687vboxsync * @note It is assumed that the ownership of the returned copy is
fd546afe09073de92e5422c1334f1c27b4108687vboxsync * transferred to the caller of the method and he is responsible to free the
fd546afe09073de92e5422c1334f1c27b4108687vboxsync * array data when it is no more necessary.
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync *
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync * @param aArg Output method parameter to clone to.
fd546afe09073de92e5422c1334f1c27b4108687vboxsync */
fd546afe09073de92e5422c1334f1c27b4108687vboxsync virtual const SafeArray &cloneTo (ComSafeArrayOut (T, aArg)) const
fd546afe09073de92e5422c1334f1c27b4108687vboxsync {
fd546afe09073de92e5422c1334f1c27b4108687vboxsync /// @todo Implement me!
fd546afe09073de92e5422c1334f1c27b4108687vboxsync#if defined (VBOX_WITH_XPCOM)
fd546afe09073de92e5422c1334f1c27b4108687vboxsync NOREF (aArgSize);
fd546afe09073de92e5422c1334f1c27b4108687vboxsync NOREF (aArg);
7868f7238f92c22fcfede63182607629da7a8eadvboxsync#else
fd546afe09073de92e5422c1334f1c27b4108687vboxsync NOREF (aArg);
fd546afe09073de92e5422c1334f1c27b4108687vboxsync#endif
fd546afe09073de92e5422c1334f1c27b4108687vboxsync AssertFailedReturn (*this);
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync }
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
fd546afe09073de92e5422c1334f1c27b4108687vboxsync /**
fd546afe09073de92e5422c1334f1c27b4108687vboxsync * Transfers the ownership of this array's data to a method parameter
fd546afe09073de92e5422c1334f1c27b4108687vboxsync * declared using the ComSafeArrayOut macro and makes this array a null
fd546afe09073de92e5422c1334f1c27b4108687vboxsync * array. When using this call, always wrap the parameter name in the
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync * ComSafeArrayOutArg macro call like this:
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync * <pre>
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync * safeArray.detachTo (ComSafeArrayOutArg (aArg));
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync * </pre>
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync *
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync * @note Since the ownership of the array data is transferred to the
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * caller of the method, he is responsible to free the array data when it is
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync * no more necessary.
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync *
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync * @param aArg Output method parameter to detach to.
81587231c9c584851518872e197f6f02dffe68cavboxsync */
81587231c9c584851518872e197f6f02dffe68cavboxsync virtual SafeArray &detachTo (ComSafeArrayOut (T, aArg))
81587231c9c584851518872e197f6f02dffe68cavboxsync {
81587231c9c584851518872e197f6f02dffe68cavboxsync AssertReturn (m.isWeak == false, *this);
81587231c9c584851518872e197f6f02dffe68cavboxsync
81587231c9c584851518872e197f6f02dffe68cavboxsync#if defined (VBOX_WITH_XPCOM)
81587231c9c584851518872e197f6f02dffe68cavboxsync
81587231c9c584851518872e197f6f02dffe68cavboxsync AssertReturn (aArgSize != NULL, *this);
81587231c9c584851518872e197f6f02dffe68cavboxsync AssertReturn (aArg != NULL, *this);
81587231c9c584851518872e197f6f02dffe68cavboxsync
81587231c9c584851518872e197f6f02dffe68cavboxsync *aArgSize = m.size;
81587231c9c584851518872e197f6f02dffe68cavboxsync *aArg = m.arr;
81587231c9c584851518872e197f6f02dffe68cavboxsync
81587231c9c584851518872e197f6f02dffe68cavboxsync m.isWeak = false;
81587231c9c584851518872e197f6f02dffe68cavboxsync m.size = 0;
81587231c9c584851518872e197f6f02dffe68cavboxsync m.arr = NULL;
81587231c9c584851518872e197f6f02dffe68cavboxsync
81587231c9c584851518872e197f6f02dffe68cavboxsync#else /* defined (VBOX_WITH_XPCOM) */
81587231c9c584851518872e197f6f02dffe68cavboxsync
81587231c9c584851518872e197f6f02dffe68cavboxsync AssertReturn (aArg != NULL, *this);
81587231c9c584851518872e197f6f02dffe68cavboxsync *aArg = m.arr;
81587231c9c584851518872e197f6f02dffe68cavboxsync
fd546afe09073de92e5422c1334f1c27b4108687vboxsync if (m.raw)
fd546afe09073de92e5422c1334f1c27b4108687vboxsync {
fd546afe09073de92e5422c1334f1c27b4108687vboxsync HRESULT rc = SafeArrayUnaccessData (m.arr);
fd546afe09073de92e5422c1334f1c27b4108687vboxsync AssertComRCReturn (rc, *this);
fd546afe09073de92e5422c1334f1c27b4108687vboxsync m.raw = NULL;
fd546afe09073de92e5422c1334f1c27b4108687vboxsync }
7e0c3d180b978b8f4b5b33f8e924520248ee3ab3vboxsync
7e0c3d180b978b8f4b5b33f8e924520248ee3ab3vboxsync m.isWeak = false;
fd546afe09073de92e5422c1334f1c27b4108687vboxsync m.arr = NULL;
fd546afe09073de92e5422c1334f1c27b4108687vboxsync
fd546afe09073de92e5422c1334f1c27b4108687vboxsync#endif /* defined (VBOX_WITH_XPCOM) */
fd546afe09073de92e5422c1334f1c27b4108687vboxsync
81587231c9c584851518872e197f6f02dffe68cavboxsync return *this;
7be2140da7230ed5736528554a4dc34b2ac482acvboxsync }
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync // public methods for internal purposes only
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync#if defined (VBOX_WITH_XPCOM)
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync /** Internal funciton. Never call it directly. */
45e9c1c72518aeba6673332bdd4d70b59e1c11a4vboxsync PRUint32 *__asOutParam_Size() { setNull(); return &m.size; }
14e0667f834cd0e2a8c365084cd2ad0a893109e8vboxsync
81587231c9c584851518872e197f6f02dffe68cavboxsync /** Internal funciton. Never call it directly. */
81587231c9c584851518872e197f6f02dffe68cavboxsync T **__asOutParam_Arr() { Assert (isNull()); return &m.arr; }
14e0667f834cd0e2a8c365084cd2ad0a893109e8vboxsync
81587231c9c584851518872e197f6f02dffe68cavboxsync#else /* defined (VBOX_WITH_XPCOM) */
14e0667f834cd0e2a8c365084cd2ad0a893109e8vboxsync
ea6c70405e39fa563a55780ef25e0933d8c73a1avboxsync /** Internal funciton. Never call it directly. */
ea6c70405e39fa563a55780ef25e0933d8c73a1avboxsync SAFEARRAY ** __asInParam() { return &m.arr; }
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync
aa4bcf0a4b2db3ac352b56a291d49cb8d4b66d32vboxsync /** Internal funciton. Never call it directly. */
4d6dcfe00aab559241d9ed05b89f803ab5ddf611vboxsync SAFEARRAY ** __asOutParam() { setNull(); return &m.arr; }
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync#endif /* defined (VBOX_WITH_XPCOM) */
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync static const SafeArray Null;
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsyncprotected:
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync DECLARE_CLS_COPY_CTOR_ASSIGN_NOOP(SafeArray)
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync#if defined (VBOX_WITH_XPCOM)
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync#else /* defined (VBOX_WITH_XPCOM) */
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync /** Requests access to the raw data pointer. */
dc88ff18a0306635c385b14211765e618351b253vboxsync T *accessRaw()
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync {
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync if (m.arr && m.raw == NULL)
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync {
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync HRESULT rc = SafeArrayAccessData (m.arr, (void HUGEP **) &m.raw);
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync AssertComRCReturn (rc, NULL);
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync }
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync return m.raw;
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync }
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync#endif /* defined (VBOX_WITH_XPCOM) */
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync struct Data
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync {
b1cf57acefb5d1ce6ae2466f43e225a81083ff34vboxsync Data()
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync : isWeak (false)
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync#if defined (VBOX_WITH_XPCOM)
f6f8bfbbbc6a59ba94b01886ed5a8d6e5813073bvboxsync , size (0), arr (NULL)
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync#else
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync , arr (NULL), raw (NULL)
f181d21bd7f14d7ee3709246500c9353bb33c922vboxsync#endif
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync {}
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync ~Data() { uninit(); }
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync void uninit()
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync {
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync#if defined (VBOX_WITH_XPCOM)
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync if (arr)
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync {
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync if (!isWeak)
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync {
01b2e367e947049139a5d5813ccc1fa162b11f76vboxsync for (size_t i = 0; i < size; ++ i)
01b2e367e947049139a5d5813ccc1fa162b11f76vboxsync Uninit (arr [i]);
01b2e367e947049139a5d5813ccc1fa162b11f76vboxsync
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync nsMemory::Free ((void *) arr);
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync isWeak = false;
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync }
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync arr = NULL;
f181d21bd7f14d7ee3709246500c9353bb33c922vboxsync }
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync#else /* defined (VBOX_WITH_XPCOM) */
03c2683d4e59cc500217b1d5d76fdf9b8cdfefa5vboxsync
if (arr)
{
if (raw)
{
SafeArrayUnaccessData (arr);
raw = NULL;
}
if (!isWeak)
{
HRESULT rc = SafeArrayDestroy (arr);
AssertComRCReturnVoid (rc);
isWeak = false;
}
arr = NULL;
}
#endif /* defined (VBOX_WITH_XPCOM) */
}
bool isWeak : 1;
#if defined (VBOX_WITH_XPCOM)
PRUint32 size;
T *arr;
#else
SAFEARRAY *arr;
T *raw;
#endif
};
Data m;
};
////////////////////////////////////////////////////////////////////////////////
#if defined (VBOX_WITH_XPCOM)
template <class I>
struct SafeIfaceArrayTraits
{
protected:
static void Init (I * &aElem) { aElem = NULL; }
static void Uninit (I * &aElem)
{
if (aElem)
{
aElem->Release();
aElem = NULL;
}
}
static void Copy (I * aFrom, I * &aTo)
{
if (aFrom != NULL)
{
aTo = aFrom;
aTo->AddRef();
}
else
aTo = NULL;
}
public:
/* Magic to workaround strict rules of par. 4.4.4 of the C++ standard. */
static I **__asInParam_Arr (I **aArr) { return aArr; }
static I **__asInParam_Arr (const I **aArr) { return const_cast <I **> (aArr); }
};
#else /* defined (VBOX_WITH_XPCOM) */
template <class I>
struct SafeIfaceArrayTraits
{
protected:
static VARTYPE VarType() { return VT_UNKNOWN; }
static void Copy (I * aFrom, I * &aTo)
{
if (aFrom != NULL)
{
aTo = aFrom;
aTo->AddRef();
}
else
aTo = NULL;
}
};
#endif /* defined (VBOX_WITH_XPCOM) */
////////////////////////////////////////////////////////////////////////////////
/**
* Version of com::SafeArray for arrays of interface pointers.
*
* Except that it manages arrays of interface pointers, the usage of this class
* is identical to com::SafeArray.
*
* @param I Interface class (no asterisk).
*/
template <class I>
class SafeIfaceArray : public SafeArray <I *, SafeIfaceArrayTraits <I> >
{
public:
typedef SafeArray <I *, SafeIfaceArrayTraits <I> > Base;
/**
* Creates a null array.
*/
SafeIfaceArray() {}
/**
* Creates a new array of the given size. All elements of the newly created
* array initialized with null values.
*
* @param aSize Initial number of elements in the array. Must be greater
* than 0.
*
* @note If this object remains null after construction it means that there
* was not enough memory for creating an array of the requested size.
* The constructor will also assert in this case.
*/
SafeIfaceArray (size_t aSize) { reset (aSize); }
/**
* Weakly attaches this instance to the existing array passed in a method
* parameter declared using the ComSafeArrayIn macro. When using this call,
* always wrap the parameter name in the ComSafeArrayOutArg macro call like
* this:
* <pre>
* SafeArray safeArray (ComSafeArrayInArg (aArg));
* </pre>
*
* Note that this constructor doesn't take the ownership of the array. In
* particular, it means that operations that operate on the ownership (e.g.
* #detachTo()) are forbidden and will assert.
*
* @param aArg Input method parameter to attach to.
*/
SafeIfaceArray (ComSafeArrayIn (I *, aArg))
{
#if defined (VBOX_WITH_XPCOM)
AssertReturnVoid (aArg != NULL);
Base::m.size = aArgSize;
Base::m.arr = aArg;
Base::m.isWeak = true;
#else /* defined (VBOX_WITH_XPCOM) */
AssertReturnVoid (aArg != NULL);
SAFEARRAY *arg = *aArg;
if (arg)
{
AssertReturnVoid (arg->cDims == 1);
VARTYPE vt;
HRESULT rc = SafeArrayGetVartype (arg, &vt);
AssertComRCReturnVoid (rc);
AssertMsgReturnVoid (vt == VT_UNKNOWN,
("Expected vartype VT_UNKNOWN, got %d.\n",
VarType(), vt));
GUID guid;
rc = SafeArrayGetIID (arg, &guid);
AssertComRCReturnVoid (rc);
AssertMsgReturnVoid (InlineIsEqualGUID (_ATL_IIDOF (I), guid),
("Expected IID {%Vuuid}, got {%Vuuid}.\n",
&_ATL_IIDOF (I), &guid));
}
m.arr = arg;
m.isWeak = true;
AssertReturnVoid (accessRaw() != NULL);
#endif /* defined (VBOX_WITH_XPCOM) */
}
/**
* Creates a deep copy of the given standard C++ container that stores
* interface pointers as objects of the ComPtr <I> class.
*
* @param aCntr Container object to copy.
*
* @param C Standard C++ container template class (normally deduced from
* @c aCntr).
* @param A Standard C++ allocator class (deduced from @c aCntr).
* @param OI Argument to the ComPtr template (deduced from @c aCntr).
*/
template <template <typename, typename> class C, class A, class OI>
SafeIfaceArray (const C <ComPtr <OI>, A> & aCntr)
{
typedef C <ComPtr <OI>, A> List;
reset (aCntr.size());
AssertReturnVoid (!Base::isNull());
int i = 0;
for (typename List::const_iterator it = aCntr.begin();
it != aCntr.end(); ++ it, ++ i)
#if defined (VBOX_WITH_XPCOM)
Copy (*it, Base::m.arr [i]);
#else
Copy (*it, Base::m.raw [i]);
#endif
}
/**
* Creates a deep copy of the given standard C++ container that stores
* interface pointers as objects of the ComObjPtr <I> class.
*
* @param aCntr Container object to copy.
*
* @param C Standard C++ container template class (normally deduced from
* @c aCntr).
* @param A Standard C++ allocator class (deduced from @c aCntr).
* @param OI Argument to the ComObjPtr template (deduced from @c aCntr).
*/
template <template <typename, typename> class C, class A, class OI>
SafeIfaceArray (const C <ComObjPtr <OI>, A> & aCntr)
{
typedef C <ComObjPtr <OI>, A> List;
reset (aCntr.size());
AssertReturnVoid (!Base::isNull());
int i = 0;
for (typename List::const_iterator it = aCntr.begin();
it != aCntr.end(); ++ it, ++ i)
#if defined (VBOX_WITH_XPCOM)
Copy (*it, Base::m.arr [i]);
#else
Copy (*it, Base::m.raw [i]);
#endif
}
/**
* Reinitializes this instance by preallocating space for the given number
* of elements. The previous array contents is lost.
*
* @param aNewSize New number of elements in the array.
* @return @c true on success and false if there is not enough
* memory for resizing.
*/
virtual bool reset (size_t aNewSize)
{
Base::m.uninit();
#if defined (VBOX_WITH_XPCOM)
/* Note: for zero-sized arrays, we use the size of 1 because whether
* malloc(0) returns a null pointer or not (which is used in isNull())
* is implementation-dependent according to the C standard. */
Base::m.arr = (I **) nsMemory::Alloc (RT_MAX (aNewSize, 1) * sizeof (I *));
AssertReturn (Base::m.arr != NULL, false);
Base::m.size = aNewSize;
for (size_t i = 0; i < Base::m.size; ++ i)
Init (Base::m.arr [i]);
#else
SAFEARRAYBOUND bound = { (ULONG)aNewSize, 0 };
m.arr = SafeArrayCreateEx (VT_UNKNOWN, 1, &bound,
(PVOID) &_ATL_IIDOF (I));
AssertReturn (m.arr != NULL, false);
AssertReturn (accessRaw() != NULL, false);
#endif
return true;
}
};
} /* namespace com */
/** @} */
#endif /* ___VBox_com_array_h */