summaryrefslogtreecommitdiff
path: root/cli_ure
diff options
context:
space:
mode:
authorPetr Mladek <pmladek@suse.cz>2011-08-02 18:20:02 +0200
committerAndras Timar <atimar@suse.com>2012-10-13 12:24:42 +0200
commitc3ab6901890abeacb524608a93e7dd9bde79eb01 (patch)
tree2cb8dd4ea4aeadc52795d7e21fdae217a2ebe5f5 /cli_ure
parent390c81a50c514606857b49f56762db9a2d9c13ae (diff)
[mono] cli_ure-mono-bridge.diff: add mono support
merged with mono-bridge-version.diff: add mono support
Diffstat (limited to 'cli_ure')
-rw-r--r--cli_ure/prj/build.lst1
-rw-r--r--cli_ure/source/mono_bridge/assemblyinfo.cs4
-rw-r--r--cli_ure/source/mono_bridge/binaryuno.cs159
-rw-r--r--cli_ure/source/mono_bridge/bridge.cs1840
-rw-r--r--cli_ure/source/mono_bridge/cli_environment.cs171
-rw-r--r--cli_ure/source/mono_bridge/makefile.mk102
-rw-r--r--cli_ure/source/mono_bridge/managed_proxy.cs444
-rw-r--r--cli_ure/source/mono_bridge/mono_bridge.cxx419
-rw-r--r--cli_ure/source/mono_bridge/mono_bridge.h125
-rw-r--r--cli_ure/source/mono_bridge/mono_proxy.cxx167
-rw-r--r--cli_ure/source/mono_bridge/rtl_ustring.cs105
-rw-r--r--cli_ure/source/mono_bridge/typeclass.cs99
-rw-r--r--cli_ure/source/mono_bridge/typedescription.cs612
-rw-r--r--cli_ure/source/mono_bridge/uik.cs45
-rw-r--r--cli_ure/source/mono_bridge/uno_glue.cxx84
-rw-r--r--cli_ure/source/mono_bridge/uno_proxy.cs565
16 files changed, 4942 insertions, 0 deletions
diff --git a/cli_ure/prj/build.lst b/cli_ure/prj/build.lst
index a46a8297d12d..d72c5250d225 100644
--- a/cli_ure/prj/build.lst
+++ b/cli_ure/prj/build.lst
@@ -8,5 +8,6 @@ ure cli_ure\source\climaker nmake - w,vc7 ure_source_climaker ure_source_basety
ure cli_ure\unotypes nmake - w,vc7 ure_unotypes ure_source_version ure_source_source.w ure_source_climaker.w ure_inc NULL
ure cli_ure\source\ure nmake - w,vc7 ure_source_ure ure_source_version ure_source_source.w ure_source_basetypes.w ure_unotypes.w ure_inc NULL
ure cli_ure\source\uno_bridge nmake - w,vc7 ure_source_uno_bridge ure_source_basetypes.w ure_unotypes.w ure_source_ure.w ure_inc NULL
+ure cli_ure\source\mono_bridge nmake - u ure_source_mono_bridge ure_unotypes ure_source_ure ure_inc NULL
ure cli_ure\source\native nmake - w,vc7 ure_source_native ure_source_version ure_source_source.w ure_source_ure.w ure_unotypes.w ure_source_uno_bridge.w ure_inc NULL
#ure cli_ure\util nmake - w,vc7 ure_util ure_source_ure.w ure_source_native.w NULL
diff --git a/cli_ure/source/mono_bridge/assemblyinfo.cs b/cli_ure/source/mono_bridge/assemblyinfo.cs
new file mode 100644
index 000000000000..bc8fe96e5804
--- /dev/null
+++ b/cli_ure/source/mono_bridge/assemblyinfo.cs
@@ -0,0 +1,4 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyVersion("1.0.0.0")]
diff --git a/cli_ure/source/mono_bridge/binaryuno.cs b/cli_ure/source/mono_bridge/binaryuno.cs
new file mode 100644
index 000000000000..2f3973616c7c
--- /dev/null
+++ b/cli_ure/source/mono_bridge/binaryuno.cs
@@ -0,0 +1,159 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+namespace uno.Binary {
+
+using System;
+using System.Runtime.InteropServices;
+using uno.Typelib;
+using uno.rtl;
+
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct Any
+{
+ /** type of value
+ */
+ public uno.Typelib.TypeDescriptionReference *pType;
+
+ /** pointer to value; this may point to pReserved and thus the uno_Any is not anytime
+ mem-copyable! You may have to correct the pData pointer to pReserved. Otherwise you need
+ not, because the data is stored in heap space.
+ */
+ public void *pData;
+ /** reserved space for storing value
+ */
+ public void *pReserved;
+
+ [ DllImport("uno_cppu", EntryPoint="uno_any_construct") ]
+ public static unsafe extern void Construct(/* Any */ void *dest,
+ void *source,
+ /* uno.Typelib.TypeDescriptionReference */ void *type,
+ void *acquireFunction);
+
+ [ DllImport("uno_cppu", EntryPoint="uno_any_destruct") ]
+ public static unsafe extern void Destroy(/* Any */ void *value, void *releaseFunction);
+}
+
+// FIXME wrap this nicely
+public struct Interface
+{
+ [ DllImport("cli_uno", EntryPoint="cli_uno_interface_acquire") ]
+ public static extern void Acquire(IntPtr unoInterface);
+
+ [ DllImport("cli_uno", EntryPoint="cli_uno_interface_release") ]
+ public static extern void Release(IntPtr unoInterface);
+
+ [ DllImport("cli_uno", EntryPoint="cli_uno_interface_dispatch") ]
+ public static unsafe extern void Dispatch(IntPtr unoInterface,
+ /* uno.Typelib.TypeDescription */ void *memberTD,
+ void *result,
+ void **args,
+ uno.Binary.Any **exception);
+}
+
+// FIXME and this
+public class Environment
+{
+ [ DllImport("cli_uno", EntryPoint="cli_uno_environment_getObjectIdentifier") ]
+ public static unsafe extern void GetObjectIdentifier(IntPtr unoEnvironment,
+ UString** oid,
+ IntPtr unoInterface);
+
+ [ DllImport("cli_uno", EntryPoint="cli_uno_environment_registerInterface") ]
+ public static unsafe extern void RegisterInterface(
+ IntPtr unoEnvironment,
+ ref IntPtr ppInterface,
+ /* UString */ void* oid,
+ /* InterfaceTypeDescription */ void *td);
+
+ [ DllImport("cli_uno", EntryPoint="cli_uno_environment_getRegisteredInterface") ]
+ public static unsafe extern void GetRegisteredInterface(
+ IntPtr unoEnvironment,
+ ref IntPtr ppInterface,
+ /* UString */ void* oid,
+ /* InterfaceTypeDescription */ void *td);
+}
+
+public struct Data
+{
+ [ DllImport("uno_cppu", EntryPoint="uno_type_destructData") ]
+ public static unsafe extern void Destroy(void *data,
+ /* uno.Typelib.TypeDescription */ void *td,
+ // FIXME is this okay? release is a function pointer
+ void *release);
+}
+
+public unsafe struct SequencePtr
+{
+ int *sal_Sequence;
+
+ // sal_Int32 nRefCount;
+ // sal_Int32 nElements;
+ // char elements[1];
+
+ /** element count<br>
+ */
+ /** elements array<br>
+ */
+
+ /** reference count of sequence<br>
+ */
+ private unsafe int nRefCount
+ {
+ get { return *(sal_Sequence); }
+ set { *(sal_Sequence) = value; }
+ }
+
+ public unsafe int nElements
+ {
+ get { return *(sal_Sequence + 1); }
+ set { *(sal_Sequence + 1) = value; }
+ }
+
+ public unsafe IntPtr elementsPtr
+ {
+ get { return new IntPtr((void *)(sal_Sequence + 2)); }
+ }
+
+ private unsafe SequencePtr(void *mem)
+ {
+ sal_Sequence = (int*)mem;
+ }
+
+ private const int HEADER_SIZE = 8; // FIXME alignment
+
+ public static SequencePtr Allocate(int length, int elementSize)
+ {
+ void *rtlPtr = uno.rtl.Mem.Allocate(HEADER_SIZE + (length * elementSize));
+ SequencePtr seqPtr = new SequencePtr(rtlPtr);
+ seqPtr.nRefCount = 1;
+ seqPtr.nElements = length;
+ return seqPtr;
+ }
+}
+}
diff --git a/cli_ure/source/mono_bridge/bridge.cs b/cli_ure/source/mono_bridge/bridge.cs
new file mode 100644
index 000000000000..df2a615f3e98
--- /dev/null
+++ b/cli_ure/source/mono_bridge/bridge.cs
@@ -0,0 +1,1840 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+namespace com.sun.star.bridges.mono_uno /* FIXME use some uno.foo namespace ? */
+{
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Runtime.Remoting;
+using System.Text;
+using uno.Binary;
+using uno.rtl;
+using uno.Typelib;
+
+public unsafe class Bridge
+{
+ static IntPtr unoEnvironment;
+ static cli_uno.Cli_environment managedEnvironment;
+
+ Bridge(IntPtr unoEnv)
+ {
+ unoEnvironment = unoEnv;
+ managedEnvironment = new cli_uno.Cli_environment();
+ }
+
+ public unsafe IntPtr MapManagedToUno(object managedData, TypeDescription *td)
+ {
+ IntPtr result = new IntPtr(null);
+
+ // get oid from managed environment
+ string oid = cli_uno.Cli_environment.getObjectIdentifier(managedData);
+
+ UString* unoOid = null;
+ UString.NewFromString(&unoOid, oid);
+ uno.Binary.Environment.GetRegisteredInterface(unoEnvironment,
+ ref result,
+ unoOid,
+ (InterfaceTypeDescription *)td);
+ if (result == IntPtr.Zero)
+ lock (typeof(cli_uno.Cli_environment))
+ {
+ uno.Binary.Environment.GetRegisteredInterface(unoEnvironment,
+ ref result,
+ unoOid,
+ (InterfaceTypeDescription *)td);
+ if (result == IntPtr.Zero)
+ result = CreateManagedProxy(managedData, td, unoOid);
+ }
+
+ UString.Release(unoOid);
+
+ return result;
+ }
+
+ public unsafe object MapUnoToManaged(IntPtr unoInterface, InterfaceTypeDescription *iTD)
+ {
+ object result = null;
+
+ UString* oidPtr = null;
+ uno.Binary.Environment.GetObjectIdentifier(unoEnvironment, &oidPtr, unoInterface);
+
+ // See if the interface was already mapped
+ Type ifaceType = MapUnoType((TypeDescription *)iTD);
+ string oid = UString.UStringToString(oidPtr);
+ // the string is owned by unoEnvironment
+ oidPtr = null;
+
+ lock (managedEnvironment)
+ {
+ result = managedEnvironment.getRegisteredInterface(oid, ifaceType);
+ if (result != null)
+ {
+ // There is already an registered object. It can either be a proxy
+ // for the UNO object or a real cli object. In the first case we
+ // tell the proxy that it shall also represent the current UNO
+ // interface. If it already does that, then it does nothing
+ if (RemotingServices.IsTransparentProxy(result))
+ {
+ UnoInterfaceProxy p = (UnoInterfaceProxy)RemotingServices.GetRealProxy(result);
+ p.AddUnoInterface(unoInterface, iTD);
+ }
+ }
+ else
+ {
+ result = UnoInterfaceProxy.Create(this, unoInterface, iTD, oid);
+ }
+ }
+
+ return result;
+ }
+
+ // FIXME convert cli types to expected types, e.g a long to a short where the uno type
+ // is a sal_Int16. This could be necessary if a scripting language (typeless) is used
+ // @param assign the uno_data has to be destructed (in/out args)
+ unsafe void MapToUno(void *unoData, object managedData,
+ // FIXME it's a TypeDescriptionReference
+ TypeDescription *type, bool assign)
+ {
+ // FIXME acquire the TypeDescription?
+ // FIXME assert that all the type equivalences in the comments hold
+ switch (type->eTypeClass)
+ {
+ case TypeClass.VOID:
+ break;
+ case TypeClass.CHAR:
+ *(ushort *)unoData = (char)managedData; // sal_Unicode = ushort
+ break;
+ case TypeClass.BOOLEAN:
+ *(byte *)unoData = (bool)managedData ? (byte)1 : (byte)0; // sal_Bool = byte
+ break;
+ case TypeClass.BYTE:
+ *(byte *)unoData = (byte)managedData; // sal_Int8 = byte
+ break;
+ case TypeClass.SHORT:
+ *(short *)unoData = (short)managedData; // sal_Int16 = short
+ break;
+ case TypeClass.UNSIGNED_SHORT:
+ *(ushort *)unoData = (ushort)managedData; // sal_uInt16 = ushort
+ break;
+ case TypeClass.LONG:
+ *(int *)unoData = (int)managedData; // sal_Int32 = int
+ break;
+ case TypeClass.UNSIGNED_LONG:
+ *(uint *)unoData = (uint)managedData; // sal_uInt32 = uint
+ break;
+ case TypeClass.HYPER:
+ *(long *)unoData = (long)managedData; // sal_Int64 = long
+ break;
+ case TypeClass.UNSIGNED_HYPER:
+ *(ulong *)unoData = (ulong)managedData; // sal_uInt64 = ulong
+ break;
+ case TypeClass.FLOAT:
+ *(float *)unoData = (float)managedData; // C++ float = C# float
+ break;
+ case TypeClass.DOUBLE:
+ *(double *)unoData = (double)managedData; // C++ double = C# double
+ break;
+ case TypeClass.STRING:
+ {
+ if (assign && *(UString **)unoData != null)
+ UString.Release(*(UString **)unoData);
+
+ *(UString **)unoData = null;
+ if (managedData == null)
+ {
+ UString.New((UString **)unoData);
+ }
+ else
+ {
+ string s = (string)managedData;
+ UString.NewFromString((UString **)unoData, s);
+ }
+ }
+ break;
+ case TypeClass.TYPE:
+ if (assign)
+ TypeDescriptionReference.Release(*(TypeDescriptionReference **)unoData);
+
+ *(TypeDescriptionReference **)unoData = MapManagedType((Type)managedData);
+ break;
+ case TypeClass.ANY:
+ {
+ uno.Binary.Any *binAny = (uno.Binary.Any *)unoData;
+
+ if (assign)
+ uno.Binary.Any.Destroy(binAny, null);
+
+ if (managedData == null)
+ {
+ uno.Binary.Any.Construct(binAny, null, null, null);
+ break;
+ }
+
+ uno.Any any = (uno.Any)managedData;
+ TypeDescription *valueTD = (TypeDescription *)MapManagedType(any.Type);
+
+ // if there's enough room in void *pReserved, store the value in the pointer
+ binAny->pData = &binAny->pReserved; // this triggers a bug in mcs < 1.1.4
+ switch (valueTD->eTypeClass)
+ {
+ case TypeClass.VOID:
+ break;
+ case TypeClass.CHAR:
+ *(ushort *)binAny->pData = (char)any.Value;
+ break;
+ case TypeClass.BOOLEAN:
+ *(byte *)binAny->pData = (bool)any.Value ? (byte)1 : (byte)0;
+ break;
+ case TypeClass.BYTE:
+ *(byte *)binAny->pData = (byte)any.Value;
+ break;
+ case TypeClass.SHORT:
+ *(short *)binAny->pData = (short)any.Value;
+ break;
+ case TypeClass.UNSIGNED_SHORT:
+ *(ushort *)binAny->pData = (ushort)any.Value;
+ break;
+ case TypeClass.LONG:
+ *(int *)binAny->pData = (int)any.Value;
+ break;
+ case TypeClass.UNSIGNED_LONG:
+ *(uint *)binAny->pData = (uint)any.Value;
+ break;
+ case TypeClass.HYPER:
+ if (sizeof(long) > sizeof(void *))
+ binAny->pData = uno.rtl.Mem.Allocate(sizeof(long));
+
+ *(long *)binAny->pData = (long)any.Value;
+ break;
+ case TypeClass.UNSIGNED_HYPER:
+ if (sizeof(ulong) > sizeof(void *))
+ binAny->pData = uno.rtl.Mem.Allocate(sizeof(ulong));
+
+ *(ulong *)binAny->pData = (ulong)any.Value;
+ break;
+ case TypeClass.FLOAT:
+ if (sizeof(float) > sizeof(void *)) // FIXME can this happen?
+ binAny->pData = uno.rtl.Mem.Allocate(sizeof(float));
+
+ *(float *)binAny->pData = (float)any.Value;
+ break;
+ case TypeClass.DOUBLE:
+ if (sizeof(double) > sizeof(void *))
+ binAny->pData = uno.rtl.Mem.Allocate(sizeof(double));
+
+ *(double *)binAny->pData = (double)any.Value;
+ break;
+ case TypeClass.STRING:
+ // string anies are used so often, that we handle them
+ // separately, to be a little faster than with an
+ // extra MapToUno call
+
+ // the Any was already destroyed, can't contain a
+ // valid string that we could leak here.
+ *(UString **)binAny->pData = null;
+
+ if (managedData == null)
+ {
+ UString.New((UString **)binAny->pData);
+ }
+ else
+ {
+ string s = (string)any.Value;
+ UString.NewFromString((UString **)binAny->pData, s);
+ }
+ // the string is owned by the Any
+ break;
+ case TypeClass.ENUM:
+ *(int *) binAny->pData = System.Convert.ToInt32(any.Value);
+ break;
+ case TypeClass.TYPE:
+ case TypeClass.SEQUENCE:
+ case TypeClass.INTERFACE:
+ binAny->pReserved = null;
+ MapToUno(binAny->pData, any.Value, valueTD, false /* no assign */);
+ break;
+ case TypeClass.STRUCT:
+ case TypeClass.EXCEPTION:
+ binAny->pData = uno.rtl.Mem.Allocate(valueTD->nSize);
+ MapToUno(binAny->pData, any.Value, valueTD, false /* no assign */);
+ break;
+ default:
+ // FIXME
+ throw new Exception();
+ }
+ binAny->pType = (TypeDescriptionReference *)valueTD;
+ TypeDescriptionReference.Acquire(binAny->pType);
+ }
+ break;
+ case TypeClass.ENUM:
+ *(int *)unoData = System.Convert.ToInt32(managedData);
+ break;
+ case TypeClass.STRUCT:
+ case TypeClass.EXCEPTION:
+ {
+ TypeDescription *td = null; // FIXME leak
+ TypeDescriptionReference.GetDescription(&td, (TypeDescriptionReference *)type);
+ CompoundTypeDescription *compTD = (CompoundTypeDescription *)td;
+ StructTypeDescription *structTD = null;
+
+ if (type->eTypeClass == TypeClass.STRUCT)
+ structTD = (StructTypeDescription *)type;
+
+ if (((TypeDescription *)compTD)->bComplete == 0)
+ TypeDescription.Complete((TypeDescription **)&compTD);
+
+ int members = compTD->nMembers;
+ Type managedType = null;
+ if (managedData != null)
+ managedType = managedData.GetType();
+
+ if (compTD->pBaseTypeDescription != null)
+ MapToUno(unoData, managedData,
+ (TypeDescription *)((TypeDescription *)compTD->pBaseTypeDescription)->pWeakRef,
+ assign);
+
+ TypeDescriptionReference *memberType = null;
+ for (int i = 0; i < members; ++i)
+ {
+ memberType = compTD->ppTypeRefs[i];
+
+ object val = null;
+ if (managedData != null)
+ {
+ string fieldName = UString.UStringToString(compTD->ppMemberNames[i]);
+ FieldInfo fieldInfo = managedType.GetField(fieldName);
+ // special case for Exception.Message property
+ // The com.sun.star.uno.Exception.Message field is mapped to the
+ // System.Exception property. Type.GetField("Message") returns null
+ if (fieldInfo == null &&
+ UString.UStringToString(type->pTypeName) == "com.sun.star.uno.Exception")
+ {
+ // get ExceptionMessage property
+ if (fieldName == "Message")
+ {
+ PropertyInfo propInfo = managedType.GetProperty(fieldName);
+ val = propInfo.GetValue(managedData, null);
+ } // FIXME else throw exception
+ }
+ else if (fieldInfo != null)
+ {
+ val = fieldInfo.GetValue(managedData);
+ } // FIXME else throw exception
+ }
+
+ void *p = (byte *)unoData + compTD->pMemberOffsets[i];
+ // When using polymorphic structs then the parameterized members can be null.
+ // Then we set a default value.
+ bool useDefault = ((structTD != null &&
+ structTD->pParameterizedTypes != null &&
+ structTD->pParameterizedTypes[i] == 1 &&
+ val == null) ||
+ managedData == null);
+ switch (memberType->eTypeClass)
+ {
+ case TypeClass.CHAR:
+ if (useDefault)
+ *(ushort *)p = 0;
+ else
+ *(ushort *)p = (char)val;
+ break;
+ case TypeClass.BOOLEAN:
+ if (useDefault)
+ *(byte *)p = (byte)0;
+ else
+ *(byte *)p = (bool)val ? (byte)1 : (byte)0;
+ break;
+ case TypeClass.BYTE:
+ if (useDefault)
+ *(byte *)p = (byte)0;
+ else
+ *(byte *)p = (byte)val;
+ break;
+ case TypeClass.SHORT:
+ if (useDefault)
+ *(short *)p = (short)0;
+ else
+ *(short *)p = (short)val;
+ break;
+ case TypeClass.UNSIGNED_SHORT:
+ if (useDefault)
+ *(ushort *)p = (ushort)0;
+ else
+ *(ushort *)p = (ushort)val;
+ break;
+ case TypeClass.LONG:
+ if (useDefault)
+ *(int *)p = 0;
+ else
+ *(int *)p = (int)val;
+ break;
+ case TypeClass.UNSIGNED_LONG:
+ if (useDefault)
+ *(uint *)p = (uint)0;
+ else
+ *(uint *)p = (uint)val;
+ break;
+ case TypeClass.HYPER:
+ if (useDefault)
+ *(long *)p = (long)0;
+ else
+ *(long *)p = (long)val;
+ break;
+ case TypeClass.UNSIGNED_HYPER:
+ if (useDefault)
+ *(ulong *)p = (ulong)0;
+ else
+ *(ulong *)p = (ulong)val;
+ break;
+ case TypeClass.FLOAT:
+ if (useDefault)
+ *(float *)p = 0.0F;
+ else
+ *(float *)p = (float)val;
+ break;
+ case TypeClass.DOUBLE:
+ if (useDefault)
+ *(double *)p = 0.0;
+ else
+ *(double *)p = (double)val;
+ break;
+ default:
+ // FIXME enum should be converted here
+ MapToUno(p, val, (TypeDescription *)memberType, assign);
+ break;
+ }
+ }
+ // FIXME exception handling
+ }
+ break;
+ case TypeClass.SEQUENCE:
+ {
+ TypeDescription *td = null; // FIXME
+ TypeDescriptionReference.GetDescription(&td, (TypeDescriptionReference *)type);
+ TypeDescriptionReference *elementType =
+ ((IndirectTypeDescription *)td)->pType;
+
+ SequencePtr seq = new SequencePtr();
+
+ if (managedData != null)
+ {
+ Array array = (Array)managedData;
+ int length = array.GetLength(0);
+
+ switch (elementType->eTypeClass)
+ {
+ case TypeClass.CHAR:
+ seq = SequencePtr.Allocate(length, sizeof(ushort));
+ Marshal.Copy((char [])managedData, 0, seq.elementsPtr, length);
+ break;
+/* case TypeClass.BOOLEAN:
+ // FIXME bool vs. byte ???
+ seq = SequencePtr.Allocate(length, sizeof(byte));
+ Marshal.Copy((byte [])managedData, 0, seq.elementsPtr, length);
+ break;*/
+ case TypeClass.BYTE:
+ seq = SequencePtr.Allocate(length, sizeof(byte));
+ Marshal.Copy((byte [])managedData, 0, seq.elementsPtr, length);
+ break;
+ case TypeClass.SHORT:
+ seq = SequencePtr.Allocate(length, sizeof(short));
+ Marshal.Copy((short [])managedData, 0, seq.elementsPtr, length);
+ break;
+/* case TypeClass.UNSIGNED_SHORT:
+ seq = SequencePtr.Allocate(length, sizeof(ushort));
+ Marshal.Copy((short [])managedData, 0, seq.elementsPtr, length);
+ break; */
+ case TypeClass.LONG:
+ seq = SequencePtr.Allocate(length, sizeof(int));
+ Marshal.Copy((int [])managedData, 0, seq.elementsPtr, length);
+ break;
+/* case TypeClass.UNSIGNED_LONG:
+ seq = SequencePtr.Allocate(length, sizeof(uint));
+ Marshal.Copy((int [])managedData, 0, seq.elementsPtr, length);
+ break; */
+ case TypeClass.HYPER:
+ seq = SequencePtr.Allocate(length, sizeof(long));
+ Marshal.Copy((long [])managedData, 0, seq.elementsPtr, length);
+ break;
+/* case TypeClass.UNSIGNED_HYPER:
+ seq = SequencePtr.Allocate(length, sizeof(ulong));
+ Marshal.Copy((long [])managedData, 0, seq.elementsPtr, length);
+ break; */
+ case TypeClass.FLOAT:
+ seq = SequencePtr.Allocate(length, sizeof(float));
+ Marshal.Copy((float [])managedData, 0, seq.elementsPtr, length);
+ break;
+ case TypeClass.DOUBLE:
+ seq = SequencePtr.Allocate(length, sizeof(double));
+ Marshal.Copy((double [])managedData, 0, seq.elementsPtr, length);
+ break;
+ case TypeClass.STRING:
+ {
+ seq = SequencePtr.Allocate(length, sizeof(void *));
+ string[] stringArray = (string [])managedData;
+ for (int i = 0; i < length; ++i)
+ {
+ UString** pStr = ((UString** )seq.elementsPtr) + i;
+ *pStr = null;
+ UString.NewFromString(pStr, stringArray[i]);
+ // string ownership goes to callee
+ }
+ }
+ break;
+ case TypeClass.ENUM:
+ seq = SequencePtr.Allocate(length, sizeof(int));
+ for (int i = 0; i < length; ++i)
+ ((int *)seq.elementsPtr)[i] =
+ Convert.ToInt32(array.GetValue(i));
+ break;
+ case TypeClass.TYPE:
+ case TypeClass.ANY:
+ case TypeClass.STRUCT:
+ case TypeClass.EXCEPTION:
+ case TypeClass.SEQUENCE:
+ case TypeClass.INTERFACE:
+ // FIXME: surely we can do better for this lot [!] - sign problems ...
+ case TypeClass.BOOLEAN:
+ case TypeClass.UNSIGNED_SHORT:
+ case TypeClass.UNSIGNED_LONG:
+ case TypeClass.UNSIGNED_HYPER:
+ {
+ seq = SequencePtr.Allocate(
+ length, ((TypeDescription *)elementType)->nSize);
+
+ for (int i = 0; i < length; ++i)
+ {
+ void *p =
+ (byte *)seq.elementsPtr +
+ i * ((TypeDescription *)elementType)->nSize;
+ object elementData = ((Array)managedData).GetValue(i);
+ MapToUno(p, elementData,
+ (TypeDescription *)((TypeDescription *)elementType)->pWeakRef,
+ false /* no assign */);
+ }
+ // FIXME exception handling
+ }
+ break;
+ default:
+ break; // FIXME throw some exception
+ }
+ }
+ else
+ {
+ seq = SequencePtr.Allocate(0, sizeof(int));
+ }
+ *(SequencePtr *)unoData = seq;
+ }
+ break;
+ case TypeClass.INTERFACE:
+ {
+ if (assign && *(void **)unoData != null)
+ uno.Binary.Interface.Release(new IntPtr(*(void **)unoData));
+
+ if (managedData == null)
+ *(void **)unoData = null;
+ else
+ {
+ TypeDescription *td = null; // FIXME leak
+ TypeDescriptionReference.GetDescription(&td, (TypeDescriptionReference *)type);
+ *(void **)unoData = MapManagedToUno(managedData, td).ToPointer();
+ }
+ break;
+ }
+ default:
+ // FIXME throw some exception
+ break;
+ }
+ }
+
+ unsafe void MapToManaged(ref object managedData, void *unoData,
+ TypeDescriptionReference *type, Type info, bool dontCreateObj)
+ {
+ switch (type->eTypeClass)
+ {
+ case TypeClass.CHAR:
+ managedData = (char)*(ushort *)unoData;
+ break;
+ case TypeClass.BOOLEAN:
+ managedData = (*(byte *)unoData != 0);
+ break;
+ case TypeClass.BYTE:
+ managedData = *(byte *)unoData;
+ break;
+ case TypeClass.SHORT:
+ managedData = *(short *)unoData;
+ break;
+ case TypeClass.UNSIGNED_SHORT:
+ managedData = *(ushort *)unoData;
+ break;
+ case TypeClass.LONG:
+ managedData = *(int *)unoData;
+ break;
+ case TypeClass.UNSIGNED_LONG:
+ managedData = *(uint *)unoData;
+ break;
+ case TypeClass.HYPER:
+ managedData = *(long *)unoData;
+ break;
+ case TypeClass.UNSIGNED_HYPER:
+ managedData = *(ulong *)unoData;
+ break;
+ case TypeClass.FLOAT:
+ managedData = *(float *)unoData;
+ break;
+ case TypeClass.DOUBLE:
+ managedData = *(double *)unoData;
+ break;
+ case TypeClass.STRING:
+ managedData = UString.UStringToString(*(UString **)unoData);
+ break;
+ case TypeClass.TYPE:
+ managedData = MapUnoType(*(TypeDescriptionReference **)unoData);
+ break;
+ case TypeClass.ANY:
+ {
+ uno.Binary.Any *binAny = (uno.Binary.Any *)unoData;
+ if (binAny->pType->eTypeClass != TypeClass.VOID)
+ {
+ object value = null;
+ MapToManaged(ref value, binAny->pData, binAny->pType, null, false);
+ managedData = new uno.Any(MapUnoType(binAny->pType), value);
+ }
+ else
+ {
+ managedData = uno.Any.VOID;
+ }
+ break;
+ }
+ case TypeClass.ENUM:
+ if (info != null)
+ managedData = Enum.ToObject(
+ info.GetElementType(), *(int *)unoData);
+ else
+ managedData = Enum.ToObject(
+ MapUnoType(type), *(int *)unoData);
+ break;
+ case TypeClass.STRUCT:
+ case TypeClass.EXCEPTION:
+ {
+ TypeDescription *td = null; // FIXME leak
+ TypeDescriptionReference.GetDescription(&td, (TypeDescriptionReference *)type);
+ CompoundTypeDescription *compTD = (CompoundTypeDescription *)td;
+
+ if (((TypeDescription *)compTD)->bComplete == 0)
+ TypeDescription.Complete((TypeDescription **)&compTD);
+
+ // create the type
+ Type managedType = LoadCliType(td->pTypeName);
+
+ // detect if we recursivly convert inherited
+ // structures. If this point is reached because of a
+ // recursive call during converting a struct then we must
+ // not create a new object rather we use the one in
+ // cli_data argument.
+ object managedObject;
+ if (dontCreateObj)
+ managedObject = managedData;
+ else
+ {
+ // Special handling for Exception conversion. We must
+ // call constructor System::Exception to pass the
+ // message string
+ if (typeof(unoidl.com.sun.star.uno.Exception).IsAssignableFrom(managedType))
+ {
+ // We need to get the Message field. Therefore we
+ // must obtain the offset from the
+ // typedescription. The base interface of all
+ // exceptions is com::sun::star::uno::Exception
+ // which contains the message
+ CompoundTypeDescription *pCTD = compTD;
+ while (pCTD->pBaseTypeDescription != null)
+ pCTD = pCTD->pBaseTypeDescription;
+
+ int pos = -1;
+ for (int i = 0; i < pCTD->nMembers; ++i)
+ {
+ if (UString.UStringToString(pCTD->ppMemberNames[i]) == "Message")
+ {
+ pos = i;
+ break;
+ }
+ }
+
+ int offset = pCTD->pMemberOffsets[pos];
+ // With the offset within the exception we can get
+ // the message string
+ string message = UString.UStringToString(
+ (*(UString **)((byte *)unoData + offset)));
+ // We need to find a constructor for the exception
+ // that takes the message string. We assume that
+ // the first argument is the message string
+ ConstructorInfo[] ctorInfos = managedType.GetConstructors();
+ ConstructorInfo ctorInfo = null;
+ // Constructor must at least have 2 params for the base
+ // unoidl.com.sun.star.uno.Exception (String, Object);
+ int numArgs = -1;
+ foreach (ConstructorInfo ci in ctorInfos)
+ {
+ numArgs = ci.GetParameters().Length;
+ if (numArgs < 2)
+ continue;
+ ctorInfo = ci;
+ break;
+ }
+
+ // Prepare parameters for constructor
+ object[] args = new object[numArgs];
+ // only initialize the first argument with the
+ // message. All unoidl.<Foo Exception>s are
+ // autogenerated, we know that this is safe.
+ args[0] = message;
+ managedObject = ctorInfo.Invoke(args);
+ }
+ else
+ managedObject = Activator.CreateInstance(managedType);
+ }
+
+ TypeDescriptionReference **memberTypeRefs = compTD->ppTypeRefs;
+ int *memberOffsets = compTD->pMemberOffsets;
+
+ if (compTD->pBaseTypeDescription != null)
+ {
+ // convert inherited struct
+ // cliObj is passed inout (args in_param, out_param are true), hence the passed
+ // cliObj is used by the callee instead of a newly created struct
+ MapToManaged(ref managedObject, unoData,
+ ((TypeDescription *)compTD->pBaseTypeDescription)->pWeakRef,
+ null,
+ true);
+ }
+ for (int i = compTD->nMembers - 1; i >= 0; --i)
+ {
+ TypeDescriptionReference *memberType = memberTypeRefs[i];
+ string memberName = UString.UStringToString(compTD->ppMemberNames[i]);
+ FieldInfo fieldInfo = managedType.GetField(memberName);
+ // special case for Exception.Message. The field has already been
+ // set while constructing cli object
+ if (fieldInfo == null &&
+ UString.UStringToString(type->pTypeName) == "com.sun.star.uno.Exception")
+ continue;
+
+ void *p = (byte *)unoData + memberOffsets[i];
+ switch (memberType->eTypeClass)
+ {
+ case TypeClass.CHAR:
+ fieldInfo.SetValue(managedObject, (char)*(short *)p);
+ break;
+ case TypeClass.BOOLEAN:
+ fieldInfo.SetValue(managedObject, (*(byte *)p) != 0);
+ break;
+ case TypeClass.BYTE:
+ fieldInfo.SetValue(managedObject, *(byte *)p);
+ break;
+ case TypeClass.SHORT:
+ fieldInfo.SetValue(managedObject, *(short *)p);
+ break;
+ case TypeClass.UNSIGNED_SHORT:
+ fieldInfo.SetValue(managedObject, *(ushort *)p);
+ break;
+ case TypeClass.LONG:
+ fieldInfo.SetValue(managedObject, *(int *)p);
+ break;
+ case TypeClass.UNSIGNED_LONG:
+ fieldInfo.SetValue(managedObject, *(uint *)p);
+ break;
+ case TypeClass.HYPER:
+ fieldInfo.SetValue(managedObject, *(long *)p);
+ break;
+ case TypeClass.UNSIGNED_HYPER:
+ fieldInfo.SetValue(managedObject, *(ulong *)p);
+ break;
+ case TypeClass.FLOAT:
+ fieldInfo.SetValue(managedObject, *(float *)p);
+ break;
+ case TypeClass.DOUBLE:
+ fieldInfo.SetValue(managedObject, *(double *)p);
+ break;
+ default:
+ {
+ object managedValue = null;
+ MapToManaged(ref managedValue, p, memberType, null, false);
+ fieldInfo.SetValue(managedObject, managedValue);
+ break;
+ }
+ }
+ }
+ managedData = managedObject;
+ break;
+ }
+ case TypeClass.SEQUENCE:
+ {
+ SequencePtr seq = *(SequencePtr *)unoData;
+ int length = seq.nElements;
+
+ TypeDescription *td = null; // FIXME leak
+ TypeDescriptionReference.GetDescription(&td, (TypeDescriptionReference *)type);
+ TypeDescriptionReference *elementType = ((IndirectTypeDescription *)td)->pType;
+
+ switch (elementType->eTypeClass)
+ {
+ case TypeClass.CHAR:
+ {
+ char[] array = new char[length];
+ Marshal.Copy(seq.elementsPtr, array, 0, length);
+ managedData = array;
+ break;
+ }
+ case TypeClass.BOOLEAN:
+ {
+ bool[] array = new bool[length];
+ byte *source = (byte *)seq.elementsPtr;
+ if (length > 0) fixed (bool *arrayPtr = array)
+ {
+ bool *dest = arrayPtr;
+ for (int i = 0; i < length; ++i)
+ *dest++ = (*source++ != 0);
+ }
+ managedData = array;
+ break;
+ }
+ case TypeClass.BYTE:
+ {
+ byte[] array = new byte[length];
+ byte *source = (byte *)seq.elementsPtr;
+ if (length > 0) fixed (byte *arrayPtr = array)
+ {
+ byte *dest = arrayPtr;
+ for (int i = 0; i < length; ++i)
+ *dest++ = *source++;
+ }
+ managedData = array;
+ break;
+ }
+ case TypeClass.SHORT:
+ {
+ short[] array = new short[length];
+ Marshal.Copy(seq.elementsPtr, array, 0, length);
+ managedData = array;
+ break;
+ }
+ case TypeClass.UNSIGNED_SHORT:
+ {
+ ushort[] array = new ushort[length];
+ ushort *source = (ushort *)seq.elementsPtr;
+ if (length > 0) fixed (ushort *arrayPtr = array)
+ {
+ ushort *dest = arrayPtr;
+ for (int i = 0; i < length; ++i)
+ *dest++ = *source++;
+ }
+ managedData = array;
+ break;
+ }
+ case TypeClass.LONG:
+ {
+ int[] array = new int[length];
+ Marshal.Copy(seq.elementsPtr, array, 0, length);
+ managedData = array;
+ break;
+ }
+ case TypeClass.UNSIGNED_LONG:
+ {
+ uint[] array = new uint[length];
+ uint *source = (uint *)seq.elementsPtr;
+ if (length > 0) fixed (uint *arrayPtr = array)
+ {
+ uint *dest = arrayPtr;
+ for (int i = 0; i < length; ++i)
+ *dest++ = *source++;
+ }
+ managedData = array;
+ break;
+ }
+ case TypeClass.HYPER:
+ {
+ long[] array = new long[length];
+ Marshal.Copy(seq.elementsPtr, array, 0, length);
+ managedData = array;
+ break;
+ }
+ case TypeClass.UNSIGNED_HYPER:
+ {
+ ulong[] array = new ulong[length];
+ ulong *source = (ulong *)seq.elementsPtr;
+ if (length > 0) fixed (ulong *arrayPtr = array)
+ {
+ ulong *dest = arrayPtr;
+ for (int i = 0; i < length; ++i)
+ *dest++ = *source++;
+ }
+ managedData = array;
+ break;
+ }
+ case TypeClass.FLOAT:
+ {
+ float[] array = new float[length];
+ Marshal.Copy(seq.elementsPtr, array, 0, length);
+ managedData = array;
+ break;
+ }
+ case TypeClass.DOUBLE:
+ {
+ double[] array = new double[length];
+ Marshal.Copy(seq.elementsPtr, array, 0, length);
+ managedData = array;
+ break;
+ }
+ case TypeClass.STRING:
+ {
+ string[] array = new string[length];
+ for (int i = 0; i < length; ++i)
+ {
+ UString *us = ((UString **)seq.elementsPtr)[i];
+ array[i] = UString.UStringToString(us);
+ }
+ managedData = array;
+ break;
+ }
+ case TypeClass.TYPE:
+ {
+ Type[] array = new Type[length];
+ for (int i = 0; i < length; ++i)
+ array[i] = MapUnoType(((TypeDescriptionReference **)
+ seq.elementsPtr)[i]);
+ managedData = array;
+ break;
+ }
+ case TypeClass.ANY:
+ {
+ uno.Any[] array = new uno.Any[length];
+ uno.Binary.Any *binAny = (uno.Binary.Any *)seq.elementsPtr;
+ for (int i = 0; i < length; ++i)
+ {
+ object any = new uno.Any();
+ MapToManaged(ref any, (void **)(binAny + i),
+ (TypeDescriptionReference *)elementType,
+ null, false);
+ array[i] = (uno.Any)any;
+ }
+ managedData = array;
+ break;
+ }
+ case TypeClass.ENUM:
+ {
+ Type enumType = null;
+ if (info != null)
+ {
+ enumType = info.GetElementType();
+ // enumType is EnumType[], get EnumType
+ enumType = enumType.GetElementType();
+ }
+ else
+ enumType = MapUnoType(elementType);
+
+ Array array = Array.CreateInstance(enumType, length);
+ for (int i = 0; i < length; ++i)
+ {
+ array.SetValue(Enum.ToObject(enumType,
+ ((int *)seq.elementsPtr)[i]),
+ i);
+ }
+ managedData = array;
+ break;
+ }
+ case TypeClass.STRUCT:
+ case TypeClass.EXCEPTION:
+ {
+ Array array = Array.CreateInstance(MapUnoType(elementType), length);
+ if (length > 0)
+ {
+ // FIXME check this
+ byte *p = (byte *)seq.elementsPtr;
+ int size = ((TypeDescription *)elementType)->nSize;
+ for (int i = 0; i < length; ++i)
+ {
+ object val = null;
+ MapToManaged(ref val, p + (size * i), elementType, null, false);
+ array.SetValue(val, i);
+ }
+ }
+ managedData = array;
+ break;
+ }
+ // FIXME verify (says cli_data.cxx)
+ case TypeClass.SEQUENCE:
+ {
+ Array array = Array.CreateInstance(
+ MapUnoType(elementType), length);
+ if (length > 0)
+ {
+ SequencePtr *elements = (SequencePtr *)seq.elementsPtr;
+ for (int i = 0; i < length; ++i)
+ {
+ object val = null;
+ MapToManaged(ref val, elements + i, elementType, null, false);
+ array.SetValue(val, i);
+ }
+ }
+ managedData = array;
+ break;
+ }
+ case TypeClass.INTERFACE:
+ {
+ Type ifaceType = MapUnoType(elementType);
+ Array array = Array.CreateInstance(ifaceType, length);
+
+ byte *p = (byte *)seq.elementsPtr;
+ int size = ((TypeDescription *)elementType)->nSize;
+ for (int i = 0; i < length; ++i)
+ {
+ object val = null;
+ MapToManaged(ref val, p + (size * i), elementType, null, false);
+ array.SetValue(val, i);
+ }
+ managedData = array;
+ break;
+ }
+ default:
+ {
+ // FIXME throw some exception
+ break;
+ }
+ }
+ break;
+ }
+ case TypeClass.INTERFACE:
+ {
+ IntPtr unoI = new IntPtr(*(void **)unoData);
+ if (unoI != IntPtr.Zero)
+ {
+ TypeDescription *td = null; // FIXME leak
+ TypeDescriptionReference.GetDescription(&td, type);
+ managedData = MapUnoToManaged(unoI, (InterfaceTypeDescription *)td);
+ }
+ else
+ managedData = null;
+ break;
+ }
+ default:
+ {
+ // FIXME throw some exception
+ break;
+ }
+ }
+ }
+
+ public static Type MapUnoType(TypeDescription *TD)
+ {
+ return MapUnoType(TD->pWeakRef);
+ }
+
+ public static Type MapUnoType(TypeDescriptionReference *TD)
+ {
+ Type result;
+
+ switch(TD->eTypeClass)
+ {
+ case TypeClass.VOID:
+ result = typeof(void);
+ break;
+ case TypeClass.CHAR:
+ result = typeof(char);
+ break;
+ case TypeClass.BOOLEAN:
+ result = typeof(bool);
+ break;
+ case TypeClass.BYTE:
+ result = typeof(byte);
+ break;
+ case TypeClass.SHORT:
+ result = typeof(short);
+ break;
+ case TypeClass.UNSIGNED_SHORT:
+ result = typeof(ushort);
+ break;
+ case TypeClass.LONG:
+ result = typeof(int);
+ break;
+ case TypeClass.UNSIGNED_LONG:
+ result = typeof(uint);
+ break;
+ case TypeClass.HYPER:
+ result = typeof(long);
+ break;
+ case TypeClass.UNSIGNED_HYPER:
+ result = typeof(ulong);
+ break;
+ case TypeClass.FLOAT:
+ result = typeof(float);
+ break;
+ case TypeClass.DOUBLE:
+ result = typeof(double);
+ break;
+ case TypeClass.STRING:
+ result = typeof(string);
+ break;
+ case TypeClass.TYPE:
+ result = typeof(Type);
+ break;
+ case TypeClass.ANY:
+ result = typeof(uno.Any);
+ break;
+ case TypeClass.ENUM:
+ case TypeClass.STRUCT:
+ case TypeClass.EXCEPTION:
+ result = LoadCliType(TD->pTypeName);
+ break;
+ case TypeClass.INTERFACE:
+ // special handling for XInterface, since it does not exist in cli.
+ if (UString.UStringToString(TD->pTypeName) == "com.sun.star.uno.XInterface")
+ result = typeof(object);
+ else
+ result = LoadCliType(TD->pTypeName);
+ break;
+ case TypeClass.SEQUENCE:
+ {
+ TypeDescription *seqType = null; // FIXME leak
+ TypeDescriptionReference.GetDescription(&seqType, TD);
+
+ // FIXME do something with TD here?
+ TypeDescriptionReference *elementTDRef =
+ ((IndirectTypeDescription *)seqType)->pType;
+
+ switch (elementTDRef->eTypeClass)
+ {
+ case TypeClass.CHAR:
+ result = Type.GetType("System.Char[]");
+ break;
+ case TypeClass.BOOLEAN:
+ result = Type.GetType("System.Boolean[]");
+ break;
+ case TypeClass.BYTE:
+ result = Type.GetType("System.Byte[]");
+ break;
+ case TypeClass.SHORT:
+ result = Type.GetType("System.Int16[]");
+ break;
+ case TypeClass.UNSIGNED_SHORT:
+ result = Type.GetType("System.UInt16[]");
+ break;
+ case TypeClass.LONG:
+ result = Type.GetType("System.Int32[]");
+ break;
+ case TypeClass.UNSIGNED_LONG:
+ result = Type.GetType("System.UInt32[]");
+ break;
+ case TypeClass.HYPER:
+ result = Type.GetType("System.Int64[]");
+ break;
+ case TypeClass.UNSIGNED_HYPER:
+ result = Type.GetType("System.UInt64[]");
+ break;
+ case TypeClass.FLOAT:
+ result = Type.GetType("System.Single[]");
+ break;
+ case TypeClass.DOUBLE:
+ result = Type.GetType("System.Double[]");
+ break;
+ case TypeClass.STRING:
+ result = Type.GetType("System.String[]");
+ break;
+ case TypeClass.TYPE:
+ result = Type.GetType("System.Type[]");
+ break;
+ case TypeClass.ANY:
+ case TypeClass.ENUM:
+ case TypeClass.EXCEPTION:
+ case TypeClass.STRUCT:
+ case TypeClass.INTERFACE:
+ case TypeClass.SEQUENCE:
+ result = LoadCliType(TD->pTypeName);
+ break;
+ default:
+ // FIXME can't happen
+ result = null;
+ break;
+ }
+ break;
+ }
+ default:
+ // FIXME can't happen
+ result = null;
+ break;
+ }
+ return result;
+ }
+
+ public static Type LoadCliType(UString* unoName)
+ {
+ return LoadCliType(MapUnoTypeName(UString.UStringToString(unoName)));
+ }
+
+ public static Type LoadCliType(string unoName)
+ {
+ Type result = null;
+ bool isPolymorphic = false;
+
+ string loadName = unoName;
+ int index = unoName.IndexOf('<');
+ if (index != -1)
+ {
+ loadName = unoName.Substring(0, index);
+ isPolymorphic = true;
+ }
+
+ result = Type.GetType(loadName + ",cli_uretypes");
+
+ if (result == null)
+ result = Type.GetType(loadName + ",cli_basetypes");
+
+ if (result == null)
+ result = Type.GetType(loadName, false);
+
+ if (result == null)
+ {
+ foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
+ {
+ result = a.GetType(loadName, false);
+ if (result != null)
+ break;
+ }
+ }
+
+ if (result == null)
+ // FIXME don't use generic Exception type
+ throw new Exception("A type could not be loaded: " + loadName);
+
+ if (isPolymorphic)
+ result = uno.PolymorphicType.GetType(result, unoName);
+
+ return result;
+ }
+
+ static TypeDescriptionReference *MapManagedType(Type managedType)
+ {
+ TypeDescriptionReference *result = null;
+ if (managedType == null)
+ {
+ result = *TypeDescriptionReference.GetByTypeClass(TypeClass.VOID);
+ TypeDescriptionReference.Acquire(result);
+ return result;
+ }
+
+ // check for Enum first,
+ // because otherwise case System.TypeCode.Int32 applies
+ if (managedType.IsEnum)
+ {
+ UString* unoTypeName = MapManagedTypeName(managedType.FullName);
+ TypeDescriptionReference.New(&result, TypeClass.ENUM, unoTypeName);
+ TypeDescriptionReference.Acquire(result);
+ }
+ else
+ {
+ switch (System.Type.GetTypeCode(managedType))
+ {
+ case System.TypeCode.Boolean:
+ result = *TypeDescriptionReference.GetByTypeClass(TypeClass.BOOLEAN);
+ TypeDescriptionReference.Acquire(result);
+ break;
+ case System.TypeCode.Char:
+ result = *TypeDescriptionReference.GetByTypeClass(TypeClass.CHAR);
+ TypeDescriptionReference.Acquire(result);
+ break;
+ case System.TypeCode.Byte:
+ result = *TypeDescriptionReference.GetByTypeClass(TypeClass.BYTE);
+ TypeDescriptionReference.Acquire(result);
+ break;
+ case System.TypeCode.Int16:
+ result = *TypeDescriptionReference.GetByTypeClass(TypeClass.SHORT);
+ TypeDescriptionReference.Acquire(result);
+ break;
+ case System.TypeCode.Int32:
+ result = *TypeDescriptionReference.GetByTypeClass(TypeClass.LONG);
+ TypeDescriptionReference.Acquire(result);
+ break;
+ case System.TypeCode.Int64:
+ result = *TypeDescriptionReference.GetByTypeClass(TypeClass.HYPER);
+ TypeDescriptionReference.Acquire(result);
+ break;
+ case System.TypeCode.UInt16:
+ result = *TypeDescriptionReference.GetByTypeClass(TypeClass.UNSIGNED_SHORT);
+ TypeDescriptionReference.Acquire(result);
+ break;
+ case System.TypeCode.UInt32:
+ result = *TypeDescriptionReference.GetByTypeClass(TypeClass.UNSIGNED_LONG);
+ TypeDescriptionReference.Acquire(result);
+ break;
+ case System.TypeCode.UInt64:
+ result = *TypeDescriptionReference.GetByTypeClass(TypeClass.UNSIGNED_HYPER);
+ TypeDescriptionReference.Acquire(result);
+ break;
+ case System.TypeCode.Single:
+ result = *TypeDescriptionReference.GetByTypeClass(TypeClass.FLOAT);
+ TypeDescriptionReference.Acquire(result);
+ break;
+ case System.TypeCode.Double:
+ result = *TypeDescriptionReference.GetByTypeClass(TypeClass.DOUBLE);
+ TypeDescriptionReference.Acquire(result);
+ break;
+ case System.TypeCode.String:
+ result = *TypeDescriptionReference.GetByTypeClass(TypeClass.STRING);
+ TypeDescriptionReference.Acquire(result);
+ break;
+ }
+ }
+
+ if (result == null)
+ {
+ string managedTypeName = managedType.FullName;
+ if (managedTypeName == "System.Void")
+ {
+ result = *TypeDescriptionReference.GetByTypeClass(TypeClass.VOID);
+ TypeDescriptionReference.Acquire(result);
+ }
+ else if (managedTypeName == "System.Type")
+ {
+ result = *TypeDescriptionReference.GetByTypeClass(TypeClass.TYPE);
+ TypeDescriptionReference.Acquire(result);
+ }
+ else if (managedTypeName == "uno.Any")
+ {
+ result = *TypeDescriptionReference.GetByTypeClass(TypeClass.ANY);
+ TypeDescriptionReference.Acquire(result);
+ }
+ else
+ {
+ UString* unoTypeName;
+
+ uno.PolymorphicType poly = managedType as uno.PolymorphicType;
+ if (poly != null)
+ unoTypeName = MapManagedTypeName(poly.PolymorphicName);
+ else
+ unoTypeName = MapManagedTypeName(managedTypeName);
+
+ TypeDescription *td = null;
+ TypeDescription.GetByName(&td, unoTypeName);
+ if (td != null)
+ {
+ result = td->pWeakRef;
+ TypeDescriptionReference.Acquire(result);
+ TypeDescription.Release(td);
+ }
+ }
+ }
+
+ if (result == null)
+ {
+ // FIXME - quite probably we should throw an exception here instead.
+ result = *TypeDescriptionReference.GetByTypeClass(TypeClass.VOID);
+ TypeDescriptionReference.Acquire(result);
+ }
+
+ return result;
+ }
+
+ static string MapUnoTypeName(string typeName)
+ {
+ StringBuilder buf = new StringBuilder();
+
+ // determine if the type is a sequence and its dimensions
+ int dims = 0;
+ if (typeName[0] == '[')
+ {
+ int index = 1;
+ while (true)
+ {
+ if (typeName[index++] == ']')
+ ++dims;
+ if (typeName[index++] != '[')
+ break;
+ }
+ typeName = typeName.Substring(index - 1);
+ }
+
+ switch (typeName)
+ {
+ case "boolean":
+ buf.Append("System.Boolean");
+ break;
+ case "char":
+ buf.Append("System.Char");
+ break;
+ case "byte":
+ buf.Append("System.Byte");
+ break;
+ case "short":
+ buf.Append("System.Int16");
+ break;
+ case "unsigned short":
+ buf.Append("System.UInt16");
+ break;
+ case "long":
+ buf.Append("System.Int32");
+ break;
+ case "unsigned long":
+ buf.Append("System.UInt32");
+ break;
+ case "hyper":
+ buf.Append("System.Int64");
+ break;
+ case "unsigned hyper":
+ buf.Append("System.UInt64");
+ break;
+ case "float":
+ buf.Append("System.Single");
+ break;
+ case "double":
+ buf.Append("System.Double");
+ break;
+ case "string":
+ buf.Append("System.String");
+ break;
+ case "void":
+ buf.Append("System.Void");
+ break;
+ case "type":
+ buf.Append("System.Type");
+ break;
+ case "com.sun.star.uno.XInterface":
+ buf.Append("System.Object");
+ break;
+ case "any":
+ buf.Append("uno.Any");
+ break;
+ default:
+ // put "unoidl." at the beginning
+ buf.Append("unoidl.");
+ // for polymorphic struct types remove the brackets, e.g. mystruct<bool> -> mystruct
+ buf.Append(MapUnoPolymorphicName(typeName));
+ break;
+ }
+
+ // append []
+ for ( ; dims > 0; --dims)
+ buf.Append("[]");
+
+ return buf.ToString();
+ }
+
+ /** For example, there is a uno type
+ com.sun.star.Foo<char, long>.
+ The values in the type list
+ are uno types and are replaced by cli types, such as System.Char,
+ System.Int32, etc.
+ */
+ static string MapUnoPolymorphicName(string unoName)
+ {
+ int startIndex = unoName.LastIndexOf('<');
+ if (startIndex == -1)
+ return unoName;
+
+ // get the type list within < and >
+ int endIndex = unoName.LastIndexOf('>');
+ string list = unoName.Substring(startIndex + 1, endIndex - startIndex - 1);
+
+ // parse the type list and replace the types with the corresponding CLI types
+ char[] delimiters = new char[] { ',' };
+ string[] unoTypes = list.Split(delimiters);
+
+ StringBuilder builder = new StringBuilder(unoName.Substring(0, startIndex + 1));
+
+ int typeCount = unoTypes.Length;
+ for (int i = 0; i < typeCount; ++i)
+ builder.Append(MapUnoTypeName(unoTypes[i]));
+
+ builder.Append('>');
+ return builder.ToString();
+ }
+
+ static UString* MapManagedTypeName(string typeName)
+ {
+ int dims = 0;
+ int index = 0;
+
+ if ((index = typeName.IndexOf("[]")) > 0)
+ {
+ dims = 1;
+
+ int curIndex = index;
+ while ((curIndex + 2) < typeName.Length &&
+ (curIndex = typeName.IndexOf("[]", curIndex + 2)) > 0)
+ ++dims;
+
+ // get the element name by removing the brackets
+ typeName = typeName.Substring(0, index);
+ }
+
+ StringBuilder buf = new StringBuilder(256);
+ for (; dims > 0; --dims)
+ buf.Append("[]");
+
+ switch (typeName)
+ {
+ case "System.Boolean":
+ buf.Append("boolean");
+ break;
+ case "System.Char":
+ buf.Append("char");
+ break;
+ case "System.Byte":
+ buf.Append("byte");
+ break;
+ case "System.Int16":
+ buf.Append("short");
+ break;
+ case "System.UInt16":
+ buf.Append("unsigned short");
+ break;
+ case "System.Int32":
+ buf.Append("long");
+ break;
+ case "System.UInt32":
+ buf.Append("unsigned long");
+ break;
+ case "System.Int64":
+ buf.Append("hyper");
+ break;
+ case "System.UInt64":
+ buf.Append("unsigned hyper");
+ break;
+ case "System.Single":
+ buf.Append("float");
+ break;
+ case "System.Double":
+ buf.Append("double");
+ break;
+ case "System.String":
+ buf.Append("string");
+ break;
+ case "System.Void":
+ buf.Append("void");
+ break;
+ case "System.Type":
+ buf.Append("type");
+ break;
+ case "System.Object":
+ buf.Append("com.sun.star.uno.XInterface");
+ break;
+ case "uno.Any":
+ buf.Append("any");
+ break;
+ default:
+ {
+ string name = MapManagedPolymorphicName(typeName);
+ int i = name.IndexOf('.');
+ buf.Append(name.Substring(i + 1));
+ break;
+ }
+ }
+
+ UString *rtl_uString = null;
+ UString.NewFromStringBuilder(&rtl_uString, buf);
+ return rtl_uString;
+ }
+
+ static string MapManagedPolymorphicName(string unoName)
+ {
+ int startIndex = unoName.LastIndexOf('<');
+ if (startIndex == -1)
+ return unoName;
+
+ // get the type list withing < and >
+ int endIndex = unoName.LastIndexOf('>');
+ string list = unoName.Substring(startIndex + 1, endIndex - startIndex - 1);
+
+ // parse the type list and replace the types with the corresponding CLI types
+ char[] delimiters = new char[] { ',' };
+ string[] unoTypes = list.Split(delimiters);
+
+ StringBuilder builder = new StringBuilder(unoName.Substring(0, startIndex + 1));
+
+ int typeCount = unoTypes.Length;
+ for (int i = 0; i < typeCount; ++i)
+ builder.Append(UString.UStringToString(MapManagedTypeName(unoTypes[i])));
+ builder.Append('>');
+ return builder.ToString();
+ }
+
+ [StructLayout(LayoutKind.Explicit)]
+ private unsafe struct largest
+ {
+ [FieldOffset(0)] long n;
+ [FieldOffset(0)] double d;
+ [FieldOffset(0)] void *p;
+ [FieldOffset(0)] uno.Binary.Any a;
+ }
+
+ // FIXME args[i] must be of same type as return value
+ public unsafe uno.Any CallUno(IntPtr unoInterface, TypeDescription *memberTD,
+ TypeDescriptionReference *returnType, int nParams,
+ MethodParameter *parameters, object[] args,
+ Type[] argTypes, out uno.Any exception)
+ {
+ int returnSize = sizeof(largest);
+
+ if (returnType != null &&
+ (returnType->eTypeClass == TypeClass.STRUCT ||
+ returnType->eTypeClass == TypeClass.EXCEPTION))
+ {
+ // FIXME leak
+ TypeDescription *td = null;
+ TypeDescriptionReference.GetDescription(&td, returnType);
+
+ if (td->nSize > returnSize)
+ returnSize = td->nSize;
+ }
+
+ // Prepare memory that contains all converted arguments and
+ // return values. The memory block contains first pointers to
+ // the arguments which are in the same block For example, 2
+ // arguments, 1 ret.
+ //
+ // | Pointer
+ // | Pointer
+ // | Return value
+ // | Arg 1
+ // | Arg 2
+ //
+ // If an argument is larger then struct largest, such as some
+ // structures, then the pointer points to an extra block of
+ // memory. The same goes for a big return value.
+ // FIXME the last sentence is bullshit. Get it deleted from cli_uno ;)
+ byte *mem = stackalloc byte[nParams * sizeof(void *) +
+ returnSize +
+ nParams * sizeof(largest)];
+
+ // array of pointers to args
+ void **unoArgPtrs = (void **)mem;
+
+ // Return Value
+ void *unoRetPtr = null;
+ largest *unoArgs = (largest *)(unoArgPtrs + nParams);
+ if (memberTD->eTypeClass != TypeClass.INTERFACE_ATTRIBUTE || nParams != 1)
+ {
+ // If an attribute is set, then unoRet must be null, e.g. void setAttribute(int)
+ unoRetPtr = (void *)unoArgs;
+ unoArgs = (largest *)((byte *)unoRetPtr + returnSize);
+ }
+
+ for (int i = 0; i < nParams; ++i)
+ {
+ // FIXME it's a TypeDescriptionReference
+ TypeDescription *type = (TypeDescription *)parameters[i].pTypeRef;
+
+ unoArgPtrs[i] = unoArgs + i;
+ if ((type->eTypeClass == TypeClass.STRUCT ||
+ type->eTypeClass == TypeClass.EXCEPTION) &&
+ (type->nSize > sizeof(largest)))
+ {
+ // stackalloc is only allowed in initializers
+ byte *bigArgPtr = stackalloc byte[type->nSize];
+
+ unoArgPtrs[i] = bigArgPtr;
+ }
+
+ if (parameters[i].bIn != 0)
+ {
+ // FIXME error handling
+ MapToUno(unoArgPtrs[i], args[i], type, false /* no assign */);
+ }
+ }
+
+ uno.Binary.Any unoExceptionHolder;
+ uno.Binary.Any *unoExc = &unoExceptionHolder;
+
+ // call binary uno
+ uno.Binary.Interface.Dispatch(
+ unoInterface, memberTD, unoRetPtr, unoArgPtrs, &unoExc);
+
+ if (unoExc == null)
+ {
+ exception = uno.Any.VOID;
+
+ // convert out args, destroy uno args
+ for (int i = 0; i < nParams; ++i)
+ {
+ // FIXME it's a TypeDescriptionReference
+ TypeDescription *type = (TypeDescription *)parameters[i].pTypeRef;
+
+ if (parameters[i].bOut != 0)
+ {
+ // FIXME error handling
+ MapToManaged(ref args[i], unoArgPtrs[i], parameters[i].pTypeRef,
+ argTypes != null ? argTypes[i] : null, false);
+ }
+
+ // cleanup args
+ if (type->eTypeClass < TypeClass.DOUBLE &&
+ type->eTypeClass != TypeClass.ENUM) // no need to destroy these
+ uno.Binary.Data.Destroy(unoArgPtrs[i], type, null);
+ }
+
+ if (returnType != null && returnType->eTypeClass != TypeClass.VOID)
+ {
+ // convert uno return value
+ object result = null;
+ // FIXME error handling
+ MapToManaged(ref result, unoRetPtr, returnType, null, false);
+ uno.Binary.Data.Destroy(unoRetPtr, (TypeDescription *)returnType, null);
+ return new uno.Any(MapUnoType(returnType), result); // FIXME is this correct?
+ }
+
+ return uno.Any.VOID;
+ }
+ else // exception occured
+ {
+ for (int i = 0; i < nParams; ++i)
+ if (parameters[i].bIn != 0)
+ uno.Binary.Data.Destroy(unoArgPtrs[i], (TypeDescription *)parameters[i].pTypeRef, null);
+
+ // FIXME needs uno.Any vs System.Object clarification
+ object exc = null;
+ MapToManaged(ref exc, unoExceptionHolder.pData,
+ unoExceptionHolder.pType, null, false);
+ exception = new uno.Any(MapUnoType(unoExceptionHolder.pType), exc);
+ return uno.Any.VOID;
+ }
+
+ // FIXME error handling
+ }
+
+ // FIXME rename, to say what it does, not how it does this
+ public void RegisterWithCliEnvironment(object managedI, string oid)
+ {
+ managedEnvironment.registerInterface(managedI, oid);
+ }
+
+ public void RegisterWithCliEnvironment(object managedI, string oid, Type type)
+ {
+ managedEnvironment.registerInterface(managedI, oid, type);
+ }
+
+ public void RegisterWithUnoEnvironment(ref IntPtr unoInterface, string oid, InterfaceTypeDescription *TD)
+ {
+ UString *unoOid = null;
+ UString.NewFromString(&unoOid, oid);
+
+ uno.Binary.Environment.RegisterInterface(unoEnvironment, ref unoInterface, unoOid, TD);
+
+ UString.Release(unoOid);
+ }
+
+ public void GetInterfaceFromUnoEnvironment(ref IntPtr unoInterface, UString* unoOid, InterfaceTypeDescription* TD)
+ {
+ uno.Binary.Environment.GetRegisteredInterface(unoEnvironment, ref unoInterface, unoOid, TD);
+ }
+
+ public void RevokeFromUnoEnvironment(IntPtr unoInterface)
+ {
+ throw new NotImplementedException();
+ }
+
+ public unsafe IntPtr CreateManagedProxy(object managedInterface,
+ TypeDescription* td,
+ UString* oid)
+ {
+ // register original interface
+ RegisterWithCliEnvironment(managedInterface,
+ UString.UStringToString(oid),
+ Bridge.MapUnoType(td));
+
+ ManagedProxy proxy = new ManagedProxy(this, managedInterface, td, oid);
+ GCHandle gchandle = GCHandle.Alloc(proxy);
+
+ // create binary uno uno_Interface and register proxy with target environment
+ IntPtr unoI = CreateBinaryProxyAndRegister(unoEnvironment, (IntPtr)gchandle,
+ oid, td);
+
+ proxy.NativeProxy = unoI;
+ return unoI;
+ }
+
+ [ DllImport("cli_uno", EntryPoint="cli_uno_environment_createMonoProxyAndRegister") ]
+ public static unsafe extern IntPtr CreateBinaryProxyAndRegister(
+ IntPtr unoEnvironment,
+ IntPtr monoProxy,
+ /* UString */ void* oid,
+ /* InterfaceTypeDescription */ void* td);
+
+ public unsafe void CallManaged(object managedI, Type ifaceType, MethodInfo method,
+ TypeDescriptionReference* returnType,
+ MethodParameter* parameters, int nParams, void* unoRet,
+ void** unoArgs, uno.Binary.Any** unoExc)
+ {
+ object[] args = new object[nParams];
+ for (int i = 0; i < nParams; ++i)
+ if (parameters[i].bIn != 0)
+ MapToManaged(ref args[i], unoArgs[i], parameters[i].pTypeRef, null, false);
+
+ object invocationResult = null;
+ try
+ {
+ invocationResult = method.Invoke(managedI, args);
+ }
+ catch (TargetInvocationException e)
+ {
+ Exception exc = e.InnerException;
+ TypeDescription* td = null;
+ // FIXME leak
+ TypeDescriptionReference.GetDescription(&td, MapManagedType(exc.GetType()));
+ void* memExc = uno.rtl.Mem.Allocate(td->nSize);
+ MapToUno(memExc, exc, /* FIXME !!!*/ (TypeDescription*)td->pWeakRef, false);
+ (*unoExc)->pType = td->pWeakRef;
+ (*unoExc)->pData = memExc;
+ return;
+ }
+ catch (Exception e)
+ {
+ // FIXME
+ }
+
+ // convert out, in/out params
+ for (int i = 0; i < nParams; ++i)
+ {
+ if (parameters[i].bOut != 0)
+ {
+ MapToUno(
+ unoArgs[i], args[i], /* FIXME !!! */(TypeDescription*)parameters[i].pTypeRef,
+ parameters[i].bIn != 0 /* assign if inout */);
+ // FIXME error handling
+ }
+ }
+
+ // return value
+ if (returnType != null)
+ MapToUno(unoRet, invocationResult, /* FIXME !!! */(TypeDescription*)returnType, false /* no assign */);
+
+ // no exception occurred
+ *unoExc = null;
+ }
+}
+
+}
diff --git a/cli_ure/source/mono_bridge/cli_environment.cs b/cli_ure/source/mono_bridge/cli_environment.cs
new file mode 100644
index 000000000000..dfacbd96ff61
--- /dev/null
+++ b/cli_ure/source/mono_bridge/cli_environment.cs
@@ -0,0 +1,171 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+namespace cli_uno
+{
+
+using System;
+using System.Collections;
+using System.Runtime.Remoting;
+using System.Runtime.Remoting.Proxies;
+using System.Text;
+
+using com.sun.star.bridges.mono_uno;
+
+public class Cli_environment
+{
+ static string sOidPart = ";cli[0];";
+
+ static Hashtable m_objects = Hashtable.Synchronized(new Hashtable());
+
+ static string createKey(string oid, Type t)
+ {
+ return oid + t.FullName;
+ }
+
+// FIXME setup debugging info here
+// public Cli_environment()
+// {
+// }
+
+// FIXME assert there are no more registered objects
+// public ~Cli_environment()
+// {
+// }
+
+ /**
+ Registers an UNO object as being mapped by this bridge. The resulting
+ cli object is represents all interfaces of the UNO object. Therefore the
+ object can be registered only with its OID; a type is not necessary.
+ */
+ public object registerInterface(object obj, string oid)
+ {
+ // FIXME debugging stuff
+ m_objects.Add(oid, obj); // new WeakReference(obj));
+ return obj;
+ }
+
+ /**
+ Registers a CLI object as being mapped by this bridge. The resulting
+ object represents exactly one UNO interface.
+ */
+ public object registerInterface(object obj, string oid, Type type)
+ {
+ // FIXME debugging stuff
+ string key = createKey(oid, type);
+ m_objects.Add(key, obj); // new WeakReference(obj));
+ return obj;
+ }
+
+ /**
+ By revoking an interface it is declared that the respective interface has
+ not been mapped. The proxy implementations call revoke interface in their
+ destructors.
+ */
+ public void revokeInterface(string oid)
+ {
+ revokeInterface(oid, null);
+ }
+
+ public void revokeInterface(string oid, Type type)
+ {
+ // FIXME debugging stuff
+ string key = type != null ? createKey(oid, type) : oid;
+ m_objects.Remove(key);
+ }
+
+ /**
+ * Retrieves an interface identified by its object id and type from this
+ * environment.
+ *
+ * @param oid object id of interface to be retrieved
+ * @param type the type description of the interface to be retrieved
+ * @see com.sun.star.uno.IEnvironment#getRegisteredInterface
+ */
+ public object getRegisteredInterface(string oid, Type type)
+ {
+ // try if it is a UNO interface
+ object ret = null;
+ ret = m_objects[oid];
+ if (ret == null)
+ {
+ // try if it is a proxy for a cli object
+ oid = createKey(oid, type);
+ ret = m_objects[oid];
+ }
+/* if (ret != null)
+ {
+ WeakReference weakIface = (WeakReference)ret;
+ ret = weakIface.Target;
+ } */
+
+ if (ret == null)
+ m_objects.Remove(oid);
+
+ return ret;
+ }
+
+ /**
+ * Generates a worldwide unique object identifier (oid) for the given object. It is
+ * guaranteed, that subsequent calls to the method with the same object
+ * will give the same id.
+ * <p>
+ * @return the generated oid.
+ * @param object the object for which a Oid should be generated.
+ */
+ public static string getObjectIdentifier(object obj)
+ {
+ string oid = null;
+ RealProxy realProxy = null;
+
+ if (RemotingServices.IsTransparentProxy(obj))
+ realProxy = RemotingServices.GetRealProxy(obj);
+
+ if (realProxy != null)
+ {
+ UnoInterfaceProxy proxyImpl = realProxy as UnoInterfaceProxy;
+ if (proxyImpl != null)
+ oid = proxyImpl.Oid;
+ }
+
+ if (oid == null)
+ {
+ Guid gd = typeof(Cli_environment).GUID; // FIXME apparently not a good idea with mono
+ StringBuilder buf = new StringBuilder(128);
+ buf.Append(obj.GetHashCode());
+ buf.Append(sOidPart);
+ buf.Append(gd);
+ oid = buf.ToString();
+ }
+
+ return oid;
+ }
+
+}
+
+}
diff --git a/cli_ure/source/mono_bridge/makefile.mk b/cli_ure/source/mono_bridge/makefile.mk
new file mode 100644
index 000000000000..262f929b89dc
--- /dev/null
+++ b/cli_ure/source/mono_bridge/makefile.mk
@@ -0,0 +1,102 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=bridges
+TARGET=cli_uno
+USE_DEFFILE=TRUE
+ENABLE_EXCEPTIONS=TRUE
+
+.IF "$(ENABLE_MONO)" != "YES"
+dummy:
+ @echo "Mono binding disabled - skipping ..."
+.ELSE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+CFLAGS+=$(MONO_CFLAGS)
+
+# --- Files --------------------------------------------------------
+
+ALLTAR : \
+ $(SHL1TARGETN) \
+ $(BIN)$/cli_uno_bridge.dll
+
+CSFILES= \
+ assemblyinfo.cs \
+ binaryuno.cs \
+ bridge.cs \
+ cli_environment.cs \
+ managed_proxy.cs \
+ rtl_ustring.cs \
+ typeclass.cs \
+ typedescription.cs \
+ uik.cs \
+ uno_proxy.cs
+
+ASSEMBLIES_DIR=$(SOLARVERSION)$/$(INPATH)$/bin$(EXT_UPDMINOR)
+$(BIN)$/cli_uno_bridge.dll : $(CSFILES)
+ +$(CSC) $(CSCFLAGS) \
+ -target:library \
+ -unsafe \
+ -out:$@ \
+ -keyfile:$(BIN)$/cliuno.snk \
+ -reference:$(BIN)$/cli_basetypes.dll \
+ -reference:$(BIN)$/cli_uretypes.dll \
+ $(CSFILES)
+
+SLOFILES= \
+ $(SLO)$/mono_bridge.obj \
+ $(SLO)$/mono_proxy.obj \
+ $(SLO)$/uno_glue.obj
+
+SHL1TARGET=$(TARGET)
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(SALHELPERLIB)
+
+
+SHL1STDLIBS+=$(MONO_LIBS)
+
+# SHL1VERSIONMAP=..$/bridge_exports.map
+
+SHL1IMPLIB=i$(TARGET)
+SHL1LIBS=$(SLB)$/$(TARGET).lib
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+DEF1NAME=$(SHL1TARGET)
+
+
+
+# --- Targets ------------------------------------------------------
+
+.ENDIF
+
+.INCLUDE : target.mk
diff --git a/cli_ure/source/mono_bridge/managed_proxy.cs b/cli_ure/source/mono_bridge/managed_proxy.cs
new file mode 100644
index 000000000000..40eb2dbe6643
--- /dev/null
+++ b/cli_ure/source/mono_bridge/managed_proxy.cs
@@ -0,0 +1,444 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+namespace com.sun.star.bridges.mono_uno /* FIXME use some uno.foo namespace ? */
+{
+
+using System;
+using System.Reflection;
+using System.Runtime;
+
+using uno.Typelib;
+using uno.rtl;
+
+public unsafe class ManagedProxy
+{
+ Bridge bridge;
+ object managedI;
+ TypeDescription *unoType;
+ UString* unoOid;
+ string oid;
+ Type type;
+ IntPtr nativeProxy;
+
+ enum MethodKind {METHOD = 0, SET, GET};
+
+ /** The array contains MethodInfos of the cli object. Each one reflects an
+ implemented interface method of the interface for which this proxy was
+ created. The MethodInfos are from the object's method and not from the
+ interface type. That is, they can be used to invoke the methods. The
+ order of the MethodInfo objects corresponds to the order of the
+ interface methods (see member m_type). Position 0 contains the
+ MethodInfo of the first method of the interface which represents the
+ root of the inheritance chain. The last MethodInfo represents the last
+ method of the furthest derived interface.
+
+ The array is completely initialized in the constructor of this object.
+
+ When the uno_DispatchMethod is called for this proxy then it receives
+ a typelib_TypeDescription of the member which is either an attribute
+ (setter or getter) or method. After determining the position of the
+ method within the UNO interface one can use the position to obtain the
+ MethodInfo of the corresponding cli method. To obtain the index for the
+ m_arMethodInfos array the function position has to be decreased by 3.
+ This is becaus, the cli interface does not contain the XInterface
+ methods.
+ */
+ MethodInfo[] methodInfos;
+
+ /** This array is similar to m_arMethodInfos but it contains the MethodInfo
+ objects of the interface (not the object). When a call is made from uno
+ to cli then the uno method name is compared to the cli method name. The
+ cli method name can be obtained from the MethodInfo object in this
+ array. The name of the actual implemented method may not be the same as
+ the interface method.
+ */
+ MethodInfo[] interfaceMethodInfos;
+
+ /** Maps the position of the method in the UNO interface to the position of
+ the corresponding MethodInfo in m_arMethodInfos. The Uno position must
+ not include the XInterface methods. For example,
+ pos 0 = XInterface::queryInterface
+ pos 1 = XInterface::acquire
+ pos 2 = XInterface::release
+
+ That is the real Uno position has to be deducted by 3. Then
+ arUnoPosToCliPos[pos] contains the index for m_arMethodInfos.
+
+ */
+ int[] unoPosToCliPos;
+
+ /** Count of inherited interfaces of the cli interface.
+ */
+ int inheritedInterfacesCount = 0;
+ /** Contains the number of methods of each interface.
+ */
+ int[] interfaceMethodCounts;
+
+ public unsafe ManagedProxy(Bridge bridge, object managedI,
+ TypeDescription* TD, UString* oid)
+ {
+ this.bridge = bridge;
+ this.managedI = managedI;
+ this.unoType = TD;
+ TypeDescription.Acquire(this.unoType);
+ this.unoOid = oid;
+ UString.Acquire(this.unoOid);
+ this.oid = UString.UStringToString(oid);
+
+ if (TD != null && TD->bComplete == 0)
+ TypeDescription.Complete(&TD);
+
+ this.type = Bridge.MapUnoType(this.unoType);
+ this.nativeProxy = IntPtr.Zero;
+ makeMethodInfos();
+ }
+
+ ~ManagedProxy()
+ {
+ UString.Release(this.unoOid);
+ TypeDescription.Release(this.unoType);
+ }
+
+ /** Prepares an array (m_arMethoInfos) containing MethodInfo object of the
+ interface and all inherited interfaces. At index null is the first
+ method of the base interface and at the last position is the last method
+ of the furthest derived interface.
+ If a UNO call is received then one can determine the position of the
+ method (or getter or setter for an attribute) from the passed type
+ information. The position minus 3 (there is no XInterface in the cli
+ mapping) corresponds to the index of the cli interface method in the
+ array.
+ */
+ void makeMethodInfos()
+ {
+ if (!type.IsInterface)
+ return;
+
+ MethodInfo[] thisMethods = type.GetMethods();
+ // get the inherited interfaces
+ Type[] inheritedIfaces = type.GetInterfaces();
+ inheritedInterfacesCount = inheritedIfaces.Length;
+
+ // array containing the number of methods for the interface
+ // and its inherited interfaces
+ interfaceMethodCounts = new int[inheritedInterfacesCount + 1];
+
+ // determine the number of all interface methods, including
+ // the inherited interfaces
+ int methodCount = thisMethods.Length;
+ foreach (Type iface in inheritedIfaces)
+ methodCount += iface.GetMethods().Length;
+
+ // array containing MethodInfos of the managed object
+ methodInfos = new MethodInfo[methodCount];
+
+ // array containing MethodInfos of the interface
+ interfaceMethodInfos = new MethodInfo[methodCount];
+
+ // array containing the mapping of UNO interface pos to pos in
+ // methodInfos
+ unoPosToCliPos = new int[methodCount];
+
+ for (int i = 0; i < methodCount; ++i)
+ unoPosToCliPos[i] = -1;
+
+ // fill methodInfos with the mappings
+ // !!! InterfaceMapping.TargetMethods should be MethodInfo*[] according
+ // to documentation
+ // but it is Type*[] instead. Bug in the framework?
+ // FIXME ^ what does mono do?
+ Type objType = managedI.GetType();
+ try
+ {
+ int index = 0;
+ // now get the methods from the inherited interface
+ // inheritedIfaces[0] is the direct base interface
+ // inheritedIfaces[n] is the furthest inherited interface
+ // Start with the base interface
+ for (int i = inheritedIfaces.Length - 1; i >= 0; --i)
+ {
+ InterfaceMapping mapInherited =
+ objType.GetInterfaceMap(inheritedIfaces[i]);
+
+ interfaceMethodCounts[i] = mapInherited.TargetMethods.Length;
+ for (int j = 0; j < interfaceMethodCounts[i]; ++j, ++index)
+ {
+ methodInfos[index] = mapInherited.TargetMethods[j] as MethodInfo;
+ interfaceMethodInfos[index] =
+ mapInherited.InterfaceMethods[j] as MethodInfo;
+ }
+ }
+
+ // At last come the methods of the furthest derived interface
+ InterfaceMapping map = objType.GetInterfaceMap(type);
+ interfaceMethodCounts[inheritedInterfacesCount] =
+ map.TargetMethods.Length;
+ for (int j = 0;
+ j < interfaceMethodCounts[inheritedInterfacesCount]; ++j, ++index)
+ {
+ methodInfos[index] = map.TargetMethods[j] as MethodInfo;
+ interfaceMethodInfos[index] =
+ map.InterfaceMethods[j] as MethodInfo;
+ }
+ }
+ catch (InvalidCastException)
+ {
+ // FIXME do something (can this happen, is "as" not the
+ // proper translation for "__try_cast" ?
+ }
+ }
+
+ /**Obtains a MethodInfo which can be used to invoke the cli object.
+ Internally it maps nUnoFunctionPos to an index that is used to get the
+ corresponding MethodInfo object from m_arMethoInfos. The mapping table
+ is dynamically initialized. If the cli interface has no base interface
+ or exactly one then the mapping table is initialized in one go at the
+ first call. In all ensuing calls the MethodInfo object is immediately
+ retrieved through the mapping table.
+
+ If the interface has more then one interface in its inheritance chain,
+ that is Type.GetInterfaces return more then one Type, then the mapping
+ table is partially initiallized. On the first call the mappings for the
+ methods of the belonging interface are created.
+
+ The implementation assumes that the order of interface methods as
+ provided by InterfaceMapping.InterfaceMethods corresponds to the order
+ of methods in the interface declaration.
+
+ @param nUnoFunctionPos
+ Position of the method in the uno interface.
+ */
+ unsafe MethodInfo getMethodInfo(int unoFunctionPos, UString* unoMethodName, MethodKind methodKind)
+ {
+ MethodInfo result = null;
+
+ // deduct 3 for XInterface methods
+ unoFunctionPos -= 3;
+ lock (unoPosToCliPos)
+ {
+ int cliPos = unoPosToCliPos[unoFunctionPos];
+ if (cliPos != -1)
+ return methodInfos[cliPos];
+
+ // create the method function name
+ string methodName = UString.UStringToString(unoMethodName);
+ switch (methodKind)
+ {
+ case MethodKind.METHOD:
+ break;
+ case MethodKind.SET:
+ methodName = "set_" + methodName;
+ break;
+ case MethodKind.GET:
+ methodName = "get_" + methodName;
+ break;
+ default:
+ // FIXME assert not reached
+ break;
+ }
+
+ // Find the cli interface method that corresponds to the Uno method
+ int indexCliMethod = -1;
+ // If the cli interfaces and their methods are in the same order
+ // as they were declared (inheritance chain and within the interface)
+ // then unoFunctionPos should lead to the correct method. However,
+ // the documentation does not say that this ordering is given.
+ if (methodName == interfaceMethodInfos[unoFunctionPos].Name)
+ indexCliMethod = unoFunctionPos;
+ else
+ {
+ int methodCount = interfaceMethodInfos.Length;
+ for (int i = 0; i < methodCount; ++i)
+ {
+ if (interfaceMethodInfos[i].Name == methodName)
+ {
+ indexCliMethod = i;
+ break;
+ }
+ }
+ }
+
+ if (indexCliMethod == -1 )
+ {
+ // FIXME throw some exception
+ return null;
+ }
+ unoPosToCliPos[unoFunctionPos] = indexCliMethod;
+ result = methodInfos[indexCliMethod];
+ }
+
+ return result;
+ }
+
+ void Acquire()
+ {
+ uno.Binary.Interface.Acquire(nativeProxy);
+ }
+
+ void Release()
+ {
+ uno.Binary.Interface.Release(nativeProxy);
+ }
+
+ unsafe void Dispatch(TypeDescription* memberTD, void* unoRet, void** unoArgs,
+ uno.Binary.Any** unoExc)
+ {
+ switch (memberTD->eTypeClass)
+ {
+ case TypeClass.INTERFACE_ATTRIBUTE:
+ {
+ int memberPos = ((InterfaceMemberTypeDescription*)memberTD)->nPosition;
+ InterfaceTypeDescription* ifaceTD = (InterfaceTypeDescription*)unoType;
+ int functionPos = ifaceTD->pMapMemberIndexToFunctionIndex[memberPos];
+
+ if (unoRet != null) // is getter method
+ {
+ MethodInfo info = getMethodInfo(
+ functionPos,
+ ((InterfaceMemberTypeDescription*)memberTD)->pMemberName,
+ MethodKind.GET);
+ bridge.CallManaged(
+ managedI, type, info,
+ ((InterfaceAttributeTypeDescription*)memberTD)->pAttributeTypeRef,
+ null, 0, // no params
+ unoRet, null, unoExc);
+ }
+ else // is setter method
+ {
+ MethodInfo info = getMethodInfo(
+ // set follows get method
+ functionPos + 1,
+ ((InterfaceMemberTypeDescription*)memberTD)->pMemberName,
+ MethodKind.SET);
+ MethodParameter param;
+ param.pTypeRef = ((InterfaceAttributeTypeDescription*)memberTD)->pAttributeTypeRef;
+ param.bIn = 1;
+ param.bOut = 0;
+
+ bridge.CallManaged(
+ managedI, type, info,
+ null /* indicated void return */, &param, 1,
+ null, unoArgs, unoExc);
+ }
+ break;
+ }
+ case TypeClass.INTERFACE_METHOD:
+ {
+ int memberPos = ((InterfaceMemberTypeDescription*)memberTD)->nPosition;
+ InterfaceTypeDescription* ifaceTD = (InterfaceTypeDescription*)unoType;
+ int functionPos = ifaceTD->pMapMemberIndexToFunctionIndex[memberPos];
+
+ switch (functionPos)
+ {
+ case 0: // queryInterface()
+ {
+ TypeDescription* requestedTD = null;
+ // FIXME leak
+ TypeDescriptionReference * argTD = *(TypeDescriptionReference **) unoArgs[0];
+ if (argTD != null)
+ TypeDescriptionReference.GetDescription(&requestedTD, argTD);
+ if (requestedTD == null || requestedTD->eTypeClass != TypeClass.INTERFACE)
+ {
+ uno.Binary.Any.Construct((uno.Binary.Any*)unoRet, null, null, null);
+ *unoExc = null;
+ break;
+ }
+
+ IntPtr unoInterface = IntPtr.Zero;
+
+ bridge.GetInterfaceFromUnoEnvironment(ref unoInterface, unoOid,
+ (InterfaceTypeDescription*)requestedTD);
+
+ if (unoInterface == IntPtr.Zero)
+ {
+ Type requestedType = Bridge.MapUnoType(requestedTD);
+ if (requestedType.IsInstanceOfType(managedI))
+ {
+ IntPtr unoI = bridge.MapManagedToUno(managedI, requestedTD);
+ uno.Binary.Any.Construct(
+ (uno.Binary.Any*)unoRet, &unoI, requestedTD, null);
+ uno.Binary.Interface.Release(unoI);
+ }
+ else // object does not support requested interface
+ {
+ uno.Binary.Any.Construct((uno.Binary.Any*)unoRet, null, null, null);
+ }
+ // no exception occurred
+ *unoExc = null;
+ }
+ else
+ {
+ uno.Binary.Any.Construct((uno.Binary.Any*)unoRet, &unoInterface,
+ requestedTD, null);
+ *unoExc = null;
+ }
+ break;
+ }
+ case 1: // acquire this proxy()
+ Acquire();
+ *unoExc = null;
+ break;
+ case 2: // release this proxy()
+ Release();
+ *unoExc = null;
+ break;
+ default: // arbitrary method call
+ {
+ InterfaceMethodTypeDescription* methodTD =
+ (InterfaceMethodTypeDescription*)memberTD;
+ UString* methodName = ((InterfaceMemberTypeDescription*)memberTD)->pMemberName;
+
+ MethodInfo info = getMethodInfo(functionPos, methodName, MethodKind.METHOD);
+
+ bridge.CallManaged(
+ managedI, type, info,
+ methodTD->pReturnTypeRef, methodTD->pParams,
+ methodTD->nParams,
+ unoRet, unoArgs, unoExc);
+ break;
+ }
+ }
+
+ break;
+ }
+ default: // Cannot happen
+ {
+ break;// FIXME Throw an error
+ }
+ }
+ }
+
+ public IntPtr NativeProxy
+ {
+ get { return nativeProxy; }
+ set { nativeProxy = value; }
+ }
+}
+
+}
diff --git a/cli_ure/source/mono_bridge/mono_bridge.cxx b/cli_ure/source/mono_bridge/mono_bridge.cxx
new file mode 100644
index 000000000000..039a136fafff
--- /dev/null
+++ b/cli_ure/source/mono_bridge/mono_bridge.cxx
@@ -0,0 +1,419 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <string.h>
+
+#include "uno/dispatcher.h"
+#include "uno/environment.h"
+#include "uno/lbnames.h"
+
+#include "osl/diagnose.h"
+#include "rtl/unload.h"
+#include "rtl/ustring.hxx"
+#include "glib/gtypes.h"
+
+#include "uno/mapping.hxx"
+
+extern "C" {
+#include "mono/metadata/appdomain.h"
+#include "mono/metadata/assembly.h"
+#include "mono/metadata/debug-helpers.h"
+#include "mono/metadata/object.h"
+#include "mono/metadata/threads.h"
+}
+
+#include "mono_bridge.h"
+
+#ifndef MONO_PUBLIC_KEY_TOKEN_LENGTH
+#define MONO_PUBLIC_KEY_TOKEN_LENGTH 17
+struct _MonoAssemblyName {
+ const char *name;
+ const char *culture;
+ const char *hash_value;
+ const guint8* public_key;
+ guchar public_key_token [MONO_PUBLIC_KEY_TOKEN_LENGTH];
+ guint32 hash_alg;
+ guint32 hash_len;
+ guint32 flags;
+ guint16 major, minor, build, revision;
+};
+#endif
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+using namespace ::rtl;
+using namespace ::mono_uno;
+
+extern "C" {
+
+void SAL_CALL Mapping_acquire( uno_Mapping * mapping )
+ SAL_THROW_EXTERN_C()
+{
+ static_cast< Mapping const * >( mapping )->m_bridge->acquire();
+}
+
+void SAL_CALL Mapping_release( uno_Mapping * mapping )
+ SAL_THROW_EXTERN_C()
+{
+ static_cast< Mapping const * >( mapping )->m_bridge->release();
+}
+
+void SAL_CALL Mapping_map_to_uno(
+ uno_Mapping * mapping, void ** ppOut,
+ void * pIn, typelib_InterfaceTypeDescription * td )
+ SAL_THROW_EXTERN_C()
+{
+ uno_Interface ** ppUnoI = (uno_Interface **)ppOut;
+ void * monoI = pIn;
+
+// FIXME do this here? OSL_ASSERT( sizeof (void *) >= sizeof (guint32))
+ OSL_ENSURE( ppUnoI && td, "### null ptr!" );
+
+ if (0 != *ppUnoI)
+ {
+ uno_Interface * pUnoI = *ppUnoI;
+ (*pUnoI->release)( pUnoI );
+ *ppUnoI = 0;
+ }
+
+ try
+ {
+ Bridge const *bridge =
+ static_cast< Mapping const * >( mapping )->m_bridge;
+ // FIXME any wrapper necessary around mono calls? cf. JNI_guarded_context
+ uno_Interface * pUnoI = bridge->map_to_uno(
+ monoI, (typelib_TypeDescription *)td );
+ *ppUnoI = pUnoI;
+ }
+ catch (BridgeRuntimeError & err)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg(
+ OUStringToOString(
+ OUSTR("[mono_uno bridge error] ") + err.m_message,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+#endif
+ }
+}
+
+void SAL_CALL Mapping_map_to_mono(
+ uno_Mapping * mapping, void ** ppOut,
+ void * pIn, typelib_InterfaceTypeDescription * td )
+ SAL_THROW_EXTERN_C()
+{
+ void ** pMonoI = ppOut;
+ uno_Interface * pUnoI = (uno_Interface *)pIn;
+
+ OSL_ENSURE( ppOut && td, "### null ptr!" );
+
+ if (0 != *pMonoI)
+ {
+ // FIXME JNI bridge has guarded_context here
+ // FIXME: do the right thing in the managed bridge
+ // mono_gchandle_free( *pMonoI );
+ }
+
+ try
+ {
+ if (0 != pUnoI)
+ {
+ Bridge const * bridge =
+ static_cast< Mapping const *>( mapping )->m_bridge;
+ // FIXME guarded context
+ *ppOut = (void *)bridge->map_to_mono(
+ pUnoI, (typelib_TypeDescription *)td );
+ OSL_ASSERT( ppOut && *ppOut );
+ }
+ }
+ catch (BridgeRuntimeError & err)
+ {
+#if OSL_DEBUG_LEVEL >= 1
+ rtl::OString cstr_msg(
+ rtl::OUStringToOString(
+ OUSTR("[mono_uno bridge error] ") + err.m_message,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+#endif
+ }
+}
+
+void SAL_CALL Bridge_free( uno_Mapping * mapping )
+ SAL_THROW_EXTERN_C()
+{
+ Mapping * that = static_cast< Mapping * >( mapping );
+ delete that->m_bridge;
+}
+
+} // extern "C"
+
+rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+namespace mono_uno
+{
+
+void Bridge::acquire() const SAL_THROW( () )
+{
+ if (1 == osl_incrementInterlockedCount( &m_ref ))
+ {
+ if (m_registered_mono2uno)
+ {
+ uno_Mapping * mapping = const_cast< Mapping * >( &m_mono2uno );
+ uno_registerMapping(
+ &mapping, Bridge_free,
+ m_mono_env, (uno_Environment *)m_uno_env, 0 );
+ }
+ else
+ {
+ uno_Mapping * mapping = const_cast< Mapping * >( &m_uno2mono );
+ uno_registerMapping(
+ &mapping, Bridge_free,
+ (uno_Environment *)m_uno_env, m_mono_env, 0 );
+ }
+ }
+}
+
+void Bridge::release() const SAL_THROW( () )
+{
+ if (! osl_decrementInterlockedCount( &m_ref ))
+ {
+ uno_revokeMapping(
+ m_registered_mono2uno
+ ? const_cast< Mapping * >( &m_mono2uno )
+ : const_cast< Mapping * >( &m_uno2mono ) );
+ }
+}
+
+MonoAssembly *
+DoLoad (MonoDomain * /* domain */, char * /* fullname */)
+{
+ MonoAssemblyName aname;
+ MonoImageOpenStatus status = MONO_IMAGE_OK;
+ MonoAssembly *ass;
+
+ memset (&aname, 0, sizeof (aname));
+ aname.culture = "";
+ strncpy ((char *)aname.public_key_token, "ce2cb7e279207b9e", MONO_PUBLIC_KEY_TOKEN_LENGTH);
+ aname.name = "cli_uno_bridge";
+ aname.major=1;
+ aname.minor=0;
+ aname.build=0;
+ aname.revision=0;
+
+ ass = mono_assembly_load (&aname, NULL, &status);
+ if (status != MONO_IMAGE_OK)
+ return NULL;
+ return ass;
+}
+
+Bridge::Bridge(
+ uno_Environment * mono_env, uno_ExtEnvironment * uno_env,
+ bool registered_mono2uno )
+ : m_ref( 1 ),
+ m_uno_env( uno_env ),
+ m_mono_env( mono_env ),
+ m_registered_mono2uno( registered_mono2uno )
+{
+ MonoDomain * pDomain = mono_get_root_domain();
+ // FIXME where is this freed?
+ MonoAssembly * pAssembly = DoLoad (pDomain, "cli_uno_bridge, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ce2cb7e279207b9e");
+ // FIXME and this, is this needed later?
+ MonoClass * pClass = mono_class_from_name (
+ (MonoImage *)mono_assembly_get_image( pAssembly ), "com.sun.star.bridges.mono_uno", "Bridge" );
+ OSL_ASSERT( 0 != pClass );
+ /* FIXME add args to method description string */
+ MonoMethodDesc * pMethodDesc = mono_method_desc_new( ":.ctor", FALSE );
+ MonoMethod * pCtor = mono_method_desc_search_in_class( pMethodDesc, pClass );
+ mono_method_desc_free( pMethodDesc );
+ OSL_ASSERT( 0 != pCtor );
+
+ pMethodDesc = mono_method_desc_new( "Bridge:MapManagedToUno", FALSE );
+ m_mapManagedToUnoMethod = mono_method_desc_search_in_class( pMethodDesc, pClass );
+ mono_method_desc_free( pMethodDesc );
+ OSL_ASSERT( 0 != m_mapManagedToUnoMethod );
+
+ pMethodDesc = mono_method_desc_new( "Bridge:MapUnoToManaged", FALSE );
+ m_mapUnoToManagedMethod = mono_method_desc_search_in_class( pMethodDesc, pClass );
+ mono_method_desc_free( pMethodDesc );
+ OSL_ASSERT( 0 != m_mapUnoToManagedMethod );
+
+ gpointer pParams[1];
+ pParams[0] = &uno_env;
+ m_managedBridge = mono_object_new( pDomain, pClass );
+ mono_uno::runtime_invoke( pCtor, m_managedBridge, pParams, NULL,
+ mono_object_get_domain( m_managedBridge ) );
+
+ OSL_ASSERT( 0 != m_mono_env && 0 != m_uno_env );
+ (*((uno_Environment *)m_uno_env)->acquire)( (uno_Environment *)m_uno_env );
+ (*m_mono_env->acquire)( m_mono_env );
+
+ // mono2uno mapping
+ m_mono2uno.acquire = Mapping_acquire;
+ m_mono2uno.release = Mapping_release;
+ m_mono2uno.mapInterface = Mapping_map_to_uno;
+ m_mono2uno.m_bridge = this;
+ // uno2mono mapping
+ m_uno2mono.acquire = Mapping_acquire;
+ m_uno2mono.release = Mapping_release;
+ m_uno2mono.mapInterface = Mapping_map_to_mono;
+ m_uno2mono.m_bridge = this;
+
+ (*g_moduleCount.modCnt.acquire)( &g_moduleCount.modCnt );
+}
+
+Bridge::~Bridge() SAL_THROW( () )
+{
+ (*m_mono_env->release)( m_mono_env );
+ (*((uno_Environment *)m_uno_env)->release)( (uno_Environment *)m_uno_env );
+ // FIXME release managed bridge
+
+ (*g_moduleCount.modCnt.release)( &g_moduleCount.modCnt );
+}
+
+void * Bridge::map_to_mono(
+ uno_Interface *pUnoI, typelib_TypeDescription * pTD ) const
+{
+ gpointer pMonoParams[2];
+
+ pMonoParams[0] = &pUnoI;
+ pMonoParams[1] = pTD;
+
+ return
+ mono_uno::runtime_invoke( m_mapUnoToManagedMethod,
+ m_managedBridge, pMonoParams, NULL,
+ mono_object_get_domain( m_managedBridge ) );
+}
+
+uno_Interface * Bridge::map_to_uno(
+ void * pMonoI, typelib_TypeDescription * pTD ) const
+{
+ gpointer pMonoParams[2];
+ uno_Interface ** ppResult;
+
+ pMonoParams[0] = pMonoI;
+ pMonoParams[1] = pTD;
+
+ ppResult = (uno_Interface **)mono_object_unbox(
+ mono_uno::runtime_invoke( m_mapManagedToUnoMethod,
+ m_managedBridge, pMonoParams, NULL,
+ mono_object_get_domain( m_managedBridge ) ) );
+
+ return *ppResult;
+}
+
+} // namespace mono_uno
+
+extern "C" {
+
+// void SAL_CALL mono_environmentDisposing( uno_Environment * mono_env )
+// SAL_THROW_EXTERN_C()
+// {
+// }
+
+void SAL_CALL uno_initEnvironment( uno_Environment * mono_env )
+ SAL_THROW_EXTERN_C()
+{
+ // mono_env->environmentDisposing = mono_environmentDisposing;
+ mono_env->pExtEnv = 0; /* no extended support */
+}
+
+void SAL_CALL uno_ext_getMapping(
+ uno_Mapping ** ppMapping, uno_Environment *pFrom, uno_Environment *pTo )
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ASSERT( 0 != ppMapping && 0 != pFrom && 0 != pTo );
+ if (0 != *ppMapping)
+ {
+ (*(*ppMapping)->release)( *ppMapping );
+ *ppMapping = 0;
+ }
+
+ /* FIXME check that mono's and sal's types have matching sizes
+ * like jni_bridge does? */
+
+ OUString const & from_env_typename = OUString::unacquired( &pFrom->pTypeName );
+ OUString const & to_env_typename = OUString::unacquired( &pTo->pTypeName );
+
+ uno_Mapping * mapping = 0;
+
+ try
+ {
+ if (from_env_typename.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( UNO_LB_CLI )) &&
+ to_env_typename.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( UNO_LB_UNO)))
+ {
+ Bridge * bridge =
+ new Bridge( pFrom, pTo->pExtEnv, true ); // ref count = 1
+ mapping = &bridge->m_mono2uno;
+ uno_registerMapping(
+ &mapping, Bridge_free, pFrom,
+ (uno_Environment *)pTo->pExtEnv, 0);
+ }
+ else if (from_env_typename.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( UNO_LB_UNO)) &&
+ to_env_typename.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( UNO_LB_CLI)))
+ {
+ Bridge * bridge =
+ new Bridge( pTo, pFrom->pExtEnv, false ); // ref count = 1
+ mapping = &bridge->m_uno2mono;
+ uno_registerMapping(
+ &mapping, Bridge_free,
+ (uno_Environment *)pFrom->pExtEnv, pTo, 0);
+ }
+ }
+ catch (BridgeRuntimeError & err)
+ {
+#if OSL_DEBUG_LEVEL >= 1
+ OString cstr_msg(
+ OUStringToOString(
+ OUSTR("[mono_uno bridge error] ") + err.m_message,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+#endif
+ }
+
+ *ppMapping = mapping;
+}
+
+sal_Bool SAL_CALL component_canUnload( TimeValue * pTime )
+ SAL_THROW_EXTERN_C()
+{
+ return (*g_moduleCount.canUnload)( &g_moduleCount, pTime );
+}
+
+} // extern "C"
+
+MonoObject*
+mono_uno::runtime_invoke (MonoMethod *method, void *obj, void **params,
+ MonoObject **exc, MonoDomain *domain)
+{
+ mono_thread_attach( domain );
+ return mono_runtime_invoke( method, obj, params, exc );
+}
diff --git a/cli_ure/source/mono_bridge/mono_bridge.h b/cli_ure/source/mono_bridge/mono_bridge.h
new file mode 100644
index 000000000000..858ae19b8370
--- /dev/null
+++ b/cli_ure/source/mono_bridge/mono_bridge.h
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if ! defined INCLUDED_MONO_BRIDGE_H
+#define INCLUDED_MONO_BRIDGE_H
+
+#include "glib/gtypes.h"
+#include "osl/interlck.h"
+#include "rtl/ustring.hxx"
+#include "typelib/typedescription.hxx"
+#include "uno/dispatcher.h"
+#include "uno/mapping.h"
+
+extern "C" {
+#include "mono/metadata/appdomain.h"
+#include "mono/metadata/debug-helpers.h"
+#include "mono/metadata/object.h"
+#include "mono/metadata/threads.h"
+}
+
+namespace cssu = com::sun::star::uno;
+
+typedef struct _uno_ExtEnvironment uno_ExtEnvironment;
+typedef struct _uno_Environment uno_Environment;
+typedef struct _typelib_TypeDescription typelib_TypeDescription;
+
+namespace mono_uno
+{
+
+MonoObject* runtime_invoke (MonoMethod *method, void *obj, void **params,
+ MonoObject **exc, MonoDomain *domain);
+
+//==== holds environments and mappings =========================================
+struct Bridge;
+struct Mapping : public uno_Mapping
+{
+ Bridge * m_bridge;
+};
+
+//==============================================================================
+struct Bridge
+{
+ mutable oslInterlockedCount m_ref;
+ MonoObject * m_managedBridge;
+
+ uno_ExtEnvironment * m_uno_env;
+ uno_Environment * m_mono_env;
+
+ Mapping m_mono2uno;
+ Mapping m_uno2mono;
+ bool m_registered_mono2uno;
+
+ MonoMethod * m_mapUnoToManagedMethod;
+ MonoMethod * m_mapManagedToUnoMethod;
+
+ ~Bridge() SAL_THROW( () );
+ explicit Bridge(
+ uno_Environment * mono_env, uno_ExtEnvironment * uno_env,
+ bool registered_mono2uno );
+
+ void acquire() const;
+ void release() const;
+
+ void * map_to_mono(
+ uno_Interface * pUnoI, typelib_TypeDescription * pTD ) const;
+
+ uno_Interface * map_to_uno(
+ void * pMonoI, typelib_TypeDescription * pTD ) const;
+};
+
+struct MonoProxy : public uno_Interface
+{
+ mutable oslInterlockedCount m_ref;
+ guint32 m_managedProxy;
+ uno_ExtEnvironment * m_unoEnv;
+ const cssu::TypeDescription m_unoType;
+ const rtl::OUString m_Oid;
+ MonoMethod * m_managedDispatch;
+
+ void acquire() const;
+ void release() const;
+ void dispatch(typelib_TypeDescription const * member_td, void * uno_ret,
+ void * uno_args [], uno_Any ** uno_exc);
+
+ MonoProxy(uno_ExtEnvironment * pUnoEnv, guint32 managedProxy,
+ rtl_uString * pOid, typelib_TypeDescription * pTD);
+};
+
+struct BridgeRuntimeError
+{
+ ::rtl::OUString m_message;
+
+ inline BridgeRuntimeError( ::rtl::OUString const & message )
+ : m_message( message )
+ {}
+};
+
+}
+
+#endif
diff --git a/cli_ure/source/mono_bridge/mono_proxy.cxx b/cli_ure/source/mono_bridge/mono_proxy.cxx
new file mode 100644
index 000000000000..6304c9ac9537
--- /dev/null
+++ b/cli_ure/source/mono_bridge/mono_proxy.cxx
@@ -0,0 +1,167 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "mono_bridge.h"
+
+#include "rtl/ustring.h"
+#include "uno/dispatcher.h"
+#include "uno/environment.h"
+#include "typelib/typedescription.h"
+
+extern "C" {
+#include "mono/metadata/threads.h"
+}
+
+using namespace mono_uno;
+
+extern "C" {
+
+static void SAL_CALL mono_proxy_free( uno_ExtEnvironment * /* env */, void * proxy)
+{
+ MonoProxy * monoProxy = reinterpret_cast< MonoProxy * >( proxy );
+
+ delete monoProxy;
+}
+
+uno_Interface * SAL_CALL cli_uno_environment_createMonoProxyAndRegister(
+ uno_ExtEnvironment *pUnoEnv, void *pMonoProxy, rtl_uString *pOid,
+ typelib_TypeDescription *pTD )
+ SAL_THROW_EXTERN_C()
+{
+ uno_Interface * proxy = static_cast< uno_Interface * >(
+ new MonoProxy( pUnoEnv,
+ static_cast< guint32 >( reinterpret_cast< sal_IntPtr >( pMonoProxy ) ),
+ pOid, pTD ) );
+
+ pUnoEnv->registerProxyInterface(
+ pUnoEnv,
+ reinterpret_cast< void ** >( &proxy ),
+ mono_proxy_free,
+ pOid,
+ (typelib_InterfaceTypeDescription*) pTD );
+
+ return proxy;
+}
+
+static void SAL_CALL mono_proxy_acquire( uno_Interface * pUnoI )
+{
+ MonoProxy const * that = static_cast< MonoProxy const * >( pUnoI );
+ that->acquire();
+}
+
+static void SAL_CALL mono_proxy_release( uno_Interface * pUnoI )
+{
+ MonoProxy const * that = static_cast< MonoProxy const * >( pUnoI );
+ that->release();
+}
+
+static void SAL_CALL mono_proxy_dispatch(
+ uno_Interface * pUnoI, typelib_TypeDescription const * member_td,
+ void * uno_ret, void * uno_args [], uno_Any ** uno_exc )
+ SAL_THROW_EXTERN_C()
+{
+ MonoProxy * that = static_cast< MonoProxy * >( pUnoI );
+ that->dispatch( member_td, uno_ret, uno_args, uno_exc );
+}
+
+} // extern "C"
+
+namespace mono_uno
+{
+
+MonoProxy::MonoProxy(uno_ExtEnvironment * pUnoEnv, guint32 managedProxy,
+ rtl_uString *pOid, typelib_TypeDescription * pTD):
+ m_ref(1),
+ m_managedProxy(managedProxy), // FIXME free this in the destructor?
+ m_unoEnv(pUnoEnv),
+ m_unoType(pTD),
+ m_Oid(pOid)
+{
+ uno_Interface::acquire = mono_proxy_acquire;
+ uno_Interface::release = mono_proxy_release;
+ uno_Interface::pDispatcher = mono_proxy_dispatch;
+
+ MonoObject * pObj = mono_gchandle_get_target( m_managedProxy );
+ MonoClass * pClass = mono_object_get_class( pObj );
+ MonoMethodDesc * pMethodDesc = mono_method_desc_new( "ManagedProxy:Dispatch", FALSE );
+ m_managedDispatch = mono_method_desc_search_in_class( pMethodDesc, pClass );
+ mono_method_desc_free( pMethodDesc );
+ OSL_ASSERT( 0 != m_managedDispatch );
+}
+
+inline void MonoProxy::acquire() const
+{
+ if (1 == osl_incrementInterlockedCount( &m_ref ))
+ {
+ // rebirth of proxy zombie
+ void * that = const_cast< MonoProxy * >( this );
+ // register at uno env
+ (*m_unoEnv->registerProxyInterface)(
+ m_unoEnv, &that,
+ mono_proxy_free, m_Oid.pData,
+ (typelib_InterfaceTypeDescription *)m_unoType.get() );
+#if OSL_DEBUG_LEVEL >= 2
+ OSL_ASSERT( this == (void const * const)that );
+#endif
+ }
+}
+
+inline void MonoProxy::release() const
+{
+ if (0 == osl_decrementInterlockedCount( &m_ref ))
+ {
+ // revoke from uno env on last release,
+ // The proxy can be resurrected if acquire is called before the uno
+ // environment calls mono_proxy_free. mono_proxy_free will
+ //delete the proxy. The environment does not acquire a registered
+ //proxy.
+ (*m_unoEnv->revokeInterface)(
+ m_unoEnv, const_cast< MonoProxy * >( this ) );
+ }
+}
+
+inline void MonoProxy::dispatch( typelib_TypeDescription const * member_td,
+ void * uno_ret, void * uno_args [], uno_Any ** uno_exc )
+{
+ OSL_ASSERT( m_managedDispatch != 0 );
+
+ gpointer pMonoParams[4];
+
+ pMonoParams[0] = const_cast< typelib_TypeDescription * >(member_td);
+ pMonoParams[1] = uno_ret;
+ pMonoParams[2] = uno_args;
+ pMonoParams[3] = uno_exc;
+
+ MonoObject *obj = mono_gchandle_get_target( m_managedProxy );
+
+ mono_uno::runtime_invoke( m_managedDispatch,
+ obj, pMonoParams, NULL,
+ mono_object_get_domain( obj ) );
+}
+
+}
diff --git a/cli_ure/source/mono_bridge/rtl_ustring.cs b/cli_ure/source/mono_bridge/rtl_ustring.cs
new file mode 100644
index 000000000000..431e9e1dc762
--- /dev/null
+++ b/cli_ure/source/mono_bridge/rtl_ustring.cs
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+namespace uno.rtl {
+
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+public unsafe struct UString
+{
+ public int RefCount;
+ public int Length;
+ public char FirstChar;
+
+ [DllImport("sal")]
+ private static extern void rtl_uString_acquire(void* data);
+
+ [DllImport("sal")]
+ private static unsafe extern void rtl_uString_release(void* data);
+
+ [DllImport("sal")]
+ private static unsafe extern void rtl_uString_new(void* data);
+
+ [DllImport("sal")]
+ private static unsafe extern void rtl_uString_newFromStr_WithLength(
+ void* data,
+ // this should pass a pointer to the original string's char[]
+ [MarshalAs(UnmanagedType.LPWStr)] string value,
+ int len);
+
+ [DllImport("sal")]
+ private static unsafe extern void rtl_uString_newFromStr_WithLength(
+ void* data,
+ // this should pass a pointer to the stringbuilder's internal char[]
+ [MarshalAs(UnmanagedType.LPWStr)] StringBuilder buffer,
+ int len);
+
+ public static unsafe void Acquire(UString* us)
+ {
+ rtl_uString_acquire(us);
+ }
+
+ public static unsafe void Release(UString* us)
+ {
+ rtl_uString_release(us);
+ }
+
+ public static unsafe void New(UString** p)
+ {
+ rtl_uString_new(p);
+ }
+
+ public static unsafe void NewFromString(UString **p, string s)
+ {
+ rtl_uString_newFromStr_WithLength(p, s, s.Length);
+ }
+
+ public static unsafe void NewFromStringBuilder(UString **p, StringBuilder sb)
+ {
+ rtl_uString_newFromStr_WithLength(p, sb, sb.Length);
+ }
+
+ public static unsafe string UStringToString(UString *p)
+ {
+ return new String(&(p->FirstChar), 0, p->Length);
+ }
+}
+
+// FIXME move this to its own file or rename this file to e.g. sal
+public unsafe struct Mem
+{
+ // FIXME parameter is a sal_Size which is unsigned and has the
+ // size of a native long. Thus this is not 64bit safe. Might have
+ // to write a glue function that always takes 32bit.
+ [DllImport("sal", EntryPoint="rtl_allocateMemory")]
+ public static unsafe extern void *Allocate(int bytes);
+}
+
+}
diff --git a/cli_ure/source/mono_bridge/typeclass.cs b/cli_ure/source/mono_bridge/typeclass.cs
new file mode 100644
index 000000000000..5a5383ddb215
--- /dev/null
+++ b/cli_ure/source/mono_bridge/typeclass.cs
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+namespace uno.Typelib {
+
+public class TypeClass
+{
+ /** type class of void */
+ public const int VOID = 0;
+ /** type class of char */
+ public const int CHAR = 1;
+ /** type class of boolean */
+ public const int BOOLEAN = 2;
+ /** type class of byte */
+ public const int BYTE = 3;
+ /** type class of short */
+ public const int SHORT = 4;
+ /** type class of unsigned short */
+ public const int UNSIGNED_SHORT = 5;
+ /** type class of long */
+ public const int LONG = 6;
+ /** type class of unsigned long */
+ public const int UNSIGNED_LONG = 7;
+ /** type class of hyper */
+ public const int HYPER = 8;
+ /** type class of unsigned hyper */
+ public const int UNSIGNED_HYPER = 9;
+ /** type class of float */
+ public const int FLOAT = 10;
+ /** type class of double */
+ public const int DOUBLE = 11;
+ /** type class of string */
+ public const int STRING = 12;
+ /** type class of type */
+ public const int TYPE = 13;
+ /** type class of any */
+ public const int ANY = 14;
+ /** type class of enum */
+ public const int ENUM = 15;
+ /** type class of typedef */
+ public const int TYPEDEF = 16;
+ /** type class of struct */
+ public const int STRUCT = 17;
+ /** type class of union (not implemented) */
+ public const int UNION = 18;
+ /** type class of exception */
+ public const int EXCEPTION = 19;
+ /** type class of sequence */
+ public const int SEQUENCE = 20;
+ /** type class of array (not implemented) */
+ public const int ARRAY = 21;
+ /** type class of interface */
+ public const int INTERFACE = 22;
+ /** type class of service (not implemented) */
+ public const int SERVICE = 23;
+ /** type class of module (not implemented) */
+ public const int MODULE = 24;
+ /** type class of interface method */
+ public const int INTERFACE_METHOD = 25;
+ /** type class of interface attribute */
+ public const int INTERFACE_ATTRIBUTE = 26;
+ /** type class of unknown type */
+ public const int UNKNOWN = 27;
+ /** type class of properties */
+ public const int PROPERTY = 28;
+ /** type class of constants */
+ public const int CONSTANT = 29;
+ /** type class of constants groups */
+ public const int CONSTANTS = 30;
+ /** type class of singletons */
+ public const int SINGLETON = 31;
+}
+
+}
diff --git a/cli_ure/source/mono_bridge/typedescription.cs b/cli_ure/source/mono_bridge/typedescription.cs
new file mode 100644
index 000000000000..fa1076be7481
--- /dev/null
+++ b/cli_ure/source/mono_bridge/typedescription.cs
@@ -0,0 +1,612 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+namespace uno.Typelib {
+
+using System;
+using System.Runtime.InteropServices;
+
+/** Holds a weak reference to a type description.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct TypeDescriptionReference
+{
+ /** reference count of type; don't ever modify this by yourself, use
+ typedescriptionreference_acquire() and typedescriptionreference_release()
+ */
+ public int nRefCount;
+ /** number of static references of type, because of the fact that some types are needed
+ until program termination and are commonly held static.
+ */
+ public int nStaticRefCount;
+ /** type class of type
+ */
+ public int eTypeClass;
+ /** fully qualified name of type.
+ */
+ public uno.rtl.UString * pTypeName;
+ /** pointer to full typedescription; this value is only valid if the type is never swapped out
+ */
+ public TypeDescription * pType;
+ /** pointer to optimize the runtime; not for public use
+ */
+ public void * pUniqueIdentifier;
+ /** reserved for future use; 0 if not used
+ */
+ public void * pReserved;
+
+ [ DllImport("uno_cppu", EntryPoint="typelib_typedescriptionreference_acquire") ]
+ public static extern void Acquire(/* TypeDescriptionReference */ void *td);
+
+ [ DllImport("uno_cppu", EntryPoint="typelib_typedescriptionreference_release") ]
+ public static extern void Release(/* TypeDescriptionReference */ void *td);
+
+ [ DllImport("uno_cppu", EntryPoint="typelib_typedescriptionreference_new") ]
+ public static extern void New(TypeDescriptionReference **ppTDR,
+ int /* enum typelib_TypeClass */ eTypeClass,
+ /* uno.rtl.UString */ void *pTypeName);
+
+ [ DllImport("uno_cppu", EntryPoint="typelib_static_type_getByTypeClass") ]
+ public static extern TypeDescriptionReference **GetByTypeClass(
+ int /* enum typelib_TypeClass */ eTypeClass);
+
+ [ DllImport("uno_cppu", EntryPoint="typelib_typedescriptionreference_getDescription") ]
+ public static extern void GetDescription(
+ TypeDescription ** ppRet, /* TypeDescriptionReference */ void * pRef);
+}
+
+/** Full type description of a type. Memory layout of this struct is identical to the
+ TypeDescriptionReference for the first six members.
+ So a typedescription can be used as type reference.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct TypeDescription
+{
+ /** reference count; don't ever modify this by yourself, use
+ typedescription_acquire() and typedescription_release()
+ */
+ public int nRefCount;
+ /** number of static references of type, because of the fact that some types are needed
+ until program termination and are commonly held static.
+ */
+ public int nStaticRefCount;
+ /** type class of type
+ */
+ public int eTypeClass;
+ /** fully qualified name of type.
+ */
+ public uno.rtl.UString * pTypeName;
+ /** pointer to self to distinguish reference from description; for internal use only
+ */
+ public TypeDescription * pSelf;
+ /** pointer to optimize the runtime; not for public use
+ */
+ public void * pUniqueIdentifier;
+ /** reserved for future use; 0 if not used
+ */
+ public void * pReserved;
+
+ /** flag to determine whether the description is complete:
+ compound and union types lack of member names, enums lack of member types and names,
+ interfaces lack of members and table init.
+ Call typedescription_complete() if false.
+ */
+ public byte bComplete;
+ /** size of type
+ */
+ public int nSize;
+ /** alignment of type
+ */
+ public int nAlignment;
+ /** pointer to weak reference
+ */
+ public TypeDescriptionReference * pWeakRef;
+ /** determines, if type can be unloaded (and it is possible to reloaded it)
+ */
+ public byte bOnDemand;
+
+ /* FIXME move to TypeDescriptionReference */
+ public static TypeDescriptionReference *VoidType
+ {
+ get { return null; /* FIXME, use typelib_static_type_getByTypeClass(VOID) */ }
+ }
+
+ [ DllImport("uno_cppu", EntryPoint="typelib_typedescription_getByName") ]
+ public static extern void GetByName(TypeDescription **pTD,
+ /* uno.rtl.UString */ void *name);
+
+ [ DllImport("uno_cppu", EntryPoint="typelib_typedescription_acquire") ]
+ public static extern void Acquire(/* TypeDescription */ void *td);
+
+ [ DllImport("uno_cppu", EntryPoint="typelib_typedescription_release") ]
+ public static extern void Release(/* TypeDescription */ void *td);
+
+ [ DllImport("uno_cppu", EntryPoint="typelib_typedescription_complete") ]
+ public static extern bool Complete(TypeDescription **pTD);
+}
+
+/** Type description for exception types.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct CompoundTypeDescription
+{
+ /** inherits all members of TypeDescription
+ */
+ public TypeDescription aBase;
+
+ /** pointer to base type description, else 0
+ */
+ public CompoundTypeDescription * pBaseTypeDescription;
+
+ /** number of members
+ */
+ public int nMembers;
+ /** byte offsets of each member including the size the base type
+ */
+ public int * pMemberOffsets;
+ /** members of the struct or exception
+ */
+ public TypeDescriptionReference ** ppTypeRefs;
+ /** member names of the struct or exception.
+ */
+ public uno.rtl.UString ** ppMemberNames;
+}
+
+/**
+ Type description for struct types.
+
+ This is only used to represent plain struct types and instantiated
+ polymorphic struct types; there is no representation of polymorphic struct
+ type templates at this level.
+
+ @since UDK 3.2.0
+ */
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct StructTypeDescription
+{
+ /**
+ Derived from CompoundTypeDescription.
+ */
+ public CompoundTypeDescription aBase;
+
+ /**
+ Flags for direct members, specifying whether they are of parameterized
+ type (true) or explict type (false).
+
+ For a plain struct type, this is a null pointer.
+ */
+ public byte * pParameterizedTypes;
+}
+
+/** Type description of a union. The type class of this description is TypeClass_UNION.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct UnionTypeDescription
+{
+ /** inherits all members of TypeDescription
+ */
+ public TypeDescription aBase;
+
+ /** type of the discriminant
+ */
+ public TypeDescriptionReference * pDiscriminantTypeRef;
+
+ /** union default descriminant
+ */
+ public long nDefaultDiscriminant;
+ /** union default member type (may be 0)
+ */
+ public TypeDescriptionReference * pDefaultTypeRef;
+ /** number of union member types
+ */
+ public int nMembers;
+ /** union member discriminant values (same order as idl declaration)
+ */
+ public long * pDiscriminants;
+ /** union member value types (same order as idl declaration)
+ */
+ public TypeDescriptionReference ** ppTypeRefs;
+ /** union member value names (same order as idl declaration)
+ */
+ public uno.rtl.UString ** ppMemberNames;
+ /** union value offset for data access
+ */
+ public int nValueOffset;
+}
+
+/** Type description of an array or sequence.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct IndirectTypeDescription
+{
+ /** inherits all members of TypeDescription
+ */
+ public TypeDescription aBase;
+
+ /** array, sequence: pointer to element type
+ */
+ public TypeDescriptionReference * pType;
+}
+
+/** Type description of an array.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct ArrayTypeDescription
+{
+ /** inherits all members of IndirectTypeDescription
+ */
+ public IndirectTypeDescription aBase;
+
+ /** number of dimensions
+ */
+ public int nDimensions;
+ /** number of total array elements
+ */
+ public int nTotalElements;
+ /** array of dimensions
+ */
+ public int * pDimensions;
+}
+
+/** Type description of an enum. The type class of this description is TypeClass_ENUM.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct EnumTypeDescription
+{
+ /** inherits all members of TypeDescription
+ */
+ public TypeDescription aBase;
+
+ /** first value of the enum
+ */
+ public int nDefaultEnumValue;
+ /** number of enum values
+ */
+ public int nEnumValues;
+ /** names of enum values
+ */
+ public uno.rtl.UString ** ppEnumNames;
+ /** values of enum (corresponding to names in similar order)
+ */
+ public int * pEnumValues;
+}
+
+/** Description of an interface method parameter.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct MethodParameter
+{
+ /** name of parameter
+ */
+ public uno.rtl.UString * pName;
+ /** type of parameter
+ */
+ public TypeDescriptionReference * pTypeRef;
+ /** true: the call type of this parameter is [in] or [inout]
+ false: the call type of this parameter is [out]
+ */
+ public byte bIn;
+ /** true: the call type of this parameter is [out] or [inout]
+ false: the call type of this parameter is [in]
+ */
+ public byte bOut;
+}
+
+/** Common base type description of InterfaceMethodTypeDescription and
+ InterfaceAttributeTypeDescription.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct InterfaceMemberTypeDescription
+{
+ /** inherits all members of TypeDescription
+ */
+ public TypeDescription aBase;
+
+ /** position of member in the interface including the number of members of
+ any base interfaces
+ */
+ public int nPosition;
+ /** name of member
+ */
+ public uno.rtl.UString * pMemberName;
+}
+
+/** Type description of an interface method. The type class of this description is
+ TypeClass_INTERFACE_METHOD. The size and the alignment are 0.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct InterfaceMethodTypeDescription
+{
+ /** inherits all members of InterfaceMemberTypeDescription
+ */
+ public InterfaceMemberTypeDescription aBase;
+
+ /** type of the return value
+ */
+ public TypeDescriptionReference * pReturnTypeRef;
+ /** number of parameters
+ */
+ public int nParams;
+ /** array of parameters
+ */
+ public MethodParameter * pParams;
+ /** number of exceptions
+ */
+ public int nExceptions;
+ /** array of exception types
+ */
+ public TypeDescriptionReference ** ppExceptions;
+ /** determines whether method is declared oneway
+ */
+ public byte bOneWay;
+
+ /** the interface description this method is a member of
+
+ @since #i21150#
+ */
+ public InterfaceTypeDescription * pInterface;
+ /** the inherited direct base method (null for a method that is not
+ inherited)
+
+ @since UDK 3.2.0
+ */
+ public TypeDescriptionReference * pBaseRef;
+ /** if pBaseRef is null, the member position of this method within
+ pInterface, not counting members inherited from bases; if pBaseRef is
+ not null, the index of the direct base within pInterface from which this
+ method is inherited
+
+ @since UDK 3.2.0
+ */
+ public int nIndex;
+}
+
+/** The description of an interface attribute. The type class of this description is
+ TypeClass_INTERFACE_ATTRIBUTE. The size and the alignment are 0.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct InterfaceAttributeTypeDescription
+{
+ /** inherits all members of InterfaceMemberTypeDescription
+ */
+ public InterfaceMemberTypeDescription aBase;
+
+ /** determines whether attribute is read only
+ */
+ public byte bReadOnly;
+ /** type of the attribute
+ */
+ public TypeDescriptionReference * pAttributeTypeRef;
+
+ /** the interface description this attribute is a member of
+
+ @since #i21150#
+ */
+ public InterfaceTypeDescription * pInterface;
+ /** the inherited direct base attribute (null for an attribute that is not
+ inherited)
+
+ @since UDK 3.2.0
+ */
+ public TypeDescriptionReference * pBaseRef;
+ /** if pBaseRef is null, the member position of this attribute within
+ pInterface, not counting members inherited from bases; if pBaseRef is
+ not null, the index of the direct base within pInterface from which this
+ attribute is inherited
+
+ @since UDK 3.2.0
+ */
+ public int nIndex;
+ /** number of getter exceptions
+
+ @since UDK 3.2.0
+ */
+ public int nGetExceptions;
+ /** array of getter exception types
+
+ @since UDK 3.2.0
+ */
+ public TypeDescriptionReference ** ppGetExceptions;
+ /** number of setter exceptions
+
+ @since UDK 3.2.0
+ */
+ public int nSetExceptions;
+ /** array of setter exception types
+
+ @since UDK 3.2.0
+ */
+ public TypeDescriptionReference ** ppSetExceptions;
+}
+
+/// @HTML
+/** Type description of an interface.
+
+ <p>Not all members are always initialized (not yet initialized members being
+ null); there are three levels:</p>
+ <ul>
+ <li>Minimally, only <code>aBase</code>,
+ <code>pBaseTypeDescription</code>, <code>aUik</code>,
+ <code>nBaseTypes</code>, and <code>ppBaseTypes</code> are initialized;
+ <code>aBase.bComplete</code> is false. This only happens when an
+ interface type description is created with
+ <code>static_mi_interface_type_init</code> or
+ <code>static_interface_type_init</code>.</li>
+
+ <li>At the next level, <code>nMembers</code>, <code>ppMembers</code>,
+ <code>nAllMembers</code>, <code>ppAllMembers</code> are also
+ initialized; <code>aBase.bComplete</code> is still false. This happens
+ when an interface type description is created with
+ <code>typedescription_newMIInterface</cocde> or
+ <code>typedescription_newInterface</code>.</li>
+
+ <li>At the final level, <code>pMapMemberIndexToFunctionIndex</code>,
+ <code>nMapFunctionIndexToMemberIndex</code>, and
+ <code>pMapFunctionIndexToMemberIndex</code> are also initialized;
+ <code>aBase.bComplete</code> is true. This happens after a call to
+ <code>typedescription_complete</code>.</li>
+ </ul>
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct InterfaceTypeDescription
+/// @NOHTML
+{
+ /** inherits all members of TypeDescription
+ */
+ public TypeDescription aBase;
+
+ /** pointer to base type description, else 0
+
+ @deprecated
+ use nBaseTypes and ppBaseTypes instead
+ */
+ public InterfaceTypeDescription * pBaseTypeDescription;
+ /** unique identifier of interface
+ */
+ public Uik aUik;
+ /** number of members
+ */
+ public int nMembers;
+ /** array of members; references attributes or methods
+ */
+ public TypeDescriptionReference ** ppMembers;
+ /** number of members including members of base interface
+ */
+ public int nAllMembers;
+ /** array of members including members of base interface; references attributes or methods
+ */
+ public TypeDescriptionReference ** ppAllMembers;
+ /** array mapping index of the member description to an index doubling for read-write
+ attributes (called function index); size of array is nAllMembers
+ */
+ public int * pMapMemberIndexToFunctionIndex;
+ /** number of members plus number of read-write attributes
+ */
+ public int nMapFunctionIndexToMemberIndex;
+ /** array mapping function index to member index; size of arry is nMapFunctionIndexToMemberIndex
+ */
+ public int * pMapFunctionIndexToMemberIndex;
+ /** number of base types
+
+ @since UDK 3.2.0
+ */
+ public int nBaseTypes;
+ /** array of base type descriptions
+
+ @since UDK 3.2.0
+ */
+ public InterfaceTypeDescription ** ppBaseTypes;
+
+ [ DllImport("uno_cppu", EntryPoint="typelib_typedescription_release") ]
+ public static extern void Release(/* InterfaceTypeDescription */ void *td);
+
+ [ DllImport("uno_cppu", EntryPoint="typelib_typedescription_acquire") ]
+ public static extern void Acquire(/* InterfaceTypeDescription */ void *td);
+
+ [ DllImport("uno_cppu", EntryPoint="typelib_typedescription_equals") ]
+ public static extern bool Equal(/* InterfaceTypeDescription */ void *td1, /* InterfaceTypeDescription */ void *td2);
+}
+
+/** Init struct of compound members for typedescription_new().
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct CompoundMember_Init
+{
+ /** type class of compound member
+ */
+ public int eTypeClass;
+ /** name of type of compound member
+
+ For a member of an instantiated polymorphic struct type that is of
+ parameterized type, this will be a null pointer.
+ */
+ public uno.rtl.UString * pTypeName;
+ /** name of compound member
+ */
+ public uno.rtl.UString * pMemberName;
+}
+
+/**
+ Init struct of members for typedescription_newStruct().
+
+ @since UDK 3.2.0
+ */
+[ StructLayout(LayoutKind.Sequential) ]
+public struct StructMember_Init
+{
+ /**
+ Derived from CompoundMember_Init;
+ */
+ public CompoundMember_Init aBase;
+
+ /**
+ Flag specifying whether the member is of parameterized type (true) or
+ explict type (false).
+ */
+ public byte bParameterizedType;
+}
+
+/** Init struct of interface methods for typedescription_new().
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct Parameter_Init
+{
+ /** type class of parameter
+ */
+ public int eTypeClass;
+ /** name of parameter
+ */
+ public uno.rtl.UString * pTypeName;
+ /** name of parameter
+ */
+ public uno.rtl.UString * pParamName;
+ /** true, if parameter is [in] or [inout]
+ */
+ public byte bIn;
+ /** true, if parameter is [out] or [inout]
+ */
+ public byte bOut;
+}
+
+/** Init struct of union types for typedescription_newUnion().
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public unsafe struct Union_Init
+{
+ /** union member discriminant
+ */
+ public long nDiscriminant;
+ /** union member name
+ */
+ public uno.rtl.UString * pMemberName;
+ /** union member type
+ */
+ public TypeDescriptionReference * pTypeRef;
+}
+
+}
diff --git a/cli_ure/source/mono_bridge/uik.cs b/cli_ure/source/mono_bridge/uik.cs
new file mode 100644
index 000000000000..87c7e85c9d04
--- /dev/null
+++ b/cli_ure/source/mono_bridge/uik.cs
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+namespace uno.Typelib {
+
+using System.Runtime.InteropServices;
+
+/** Binary typelib uik struct. Internally not used anymore.
+*/
+[ StructLayout(LayoutKind.Sequential) ]
+public struct Uik
+{
+ int m_Data1;
+ short m_Data2;
+ short m_Data3;
+ int m_Data4;
+ int m_Data5;
+}
+
+}
diff --git a/cli_ure/source/mono_bridge/uno_glue.cxx b/cli_ure/source/mono_bridge/uno_glue.cxx
new file mode 100644
index 000000000000..de73166e9080
--- /dev/null
+++ b/cli_ure/source/mono_bridge/uno_glue.cxx
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "rtl/ustring.h"
+#include "uno/dispatcher.h"
+#include "uno/environment.h"
+#include <stdio.h>
+
+extern "C" {
+
+/* uno_Interface */
+
+void SAL_CALL cli_uno_interface_acquire( uno_Interface *pInterface )
+ SAL_THROW_EXTERN_C()
+{
+ (*pInterface->acquire)( pInterface );
+}
+
+void SAL_CALL cli_uno_interface_release( uno_Interface *pInterface )
+ SAL_THROW_EXTERN_C()
+{
+ (*pInterface->release)( pInterface );
+}
+
+void SAL_CALL cli_uno_interface_dispatch(
+ uno_Interface *pInterface, const struct _typelib_TypeDescription *pMemberType,
+ void *pReturn, void *pArgs[], uno_Any **ppException )
+ SAL_THROW_EXTERN_C()
+{
+ (*pInterface->pDispatcher)( pInterface, pMemberType, pReturn, pArgs, ppException );
+}
+
+/* uno_ExtEnvironment */
+
+void SAL_CALL cli_uno_environment_getObjectIdentifier(
+ uno_ExtEnvironment *pUnoEnv, rtl_uString **ppOId, uno_Interface *pUnoI )
+ SAL_THROW_EXTERN_C()
+{
+ (*pUnoEnv->getObjectIdentifier)( pUnoEnv, ppOId, pUnoI );
+}
+
+void SAL_CALL cli_uno_environment_registerInterface(
+ uno_ExtEnvironment *pUnoEnv, void **ppInterface, rtl_uString *pOId,
+ struct _typelib_InterfaceTypeDescription *pTypeDescr )
+ SAL_THROW_EXTERN_C()
+{
+ (*pUnoEnv->registerInterface)( pUnoEnv, ppInterface, pOId, pTypeDescr );
+}
+
+void SAL_CALL cli_uno_environment_getRegisteredInterface(
+ uno_ExtEnvironment *pUnoEnv, void **ppInterface, rtl_uString *pOId,
+ struct _typelib_InterfaceTypeDescription *pTypeDescr )
+ SAL_THROW_EXTERN_C()
+{
+ (*pUnoEnv->getRegisteredInterface)( pUnoEnv, ppInterface, pOId, pTypeDescr );
+}
+
+
+}
diff --git a/cli_ure/source/mono_bridge/uno_proxy.cs b/cli_ure/source/mono_bridge/uno_proxy.cs
new file mode 100644
index 000000000000..76f649b70d4c
--- /dev/null
+++ b/cli_ure/source/mono_bridge/uno_proxy.cs
@@ -0,0 +1,565 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+using System;
+using System.Collections;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Runtime.Remoting;
+using System.Runtime.Remoting.Messaging;
+using System.Runtime.Remoting.Proxies;
+
+using uno.Binary;
+using uno.Typelib;
+using uno.rtl;
+
+namespace com.sun.star.bridges.mono_uno /* FIXME use some uno.foo namespace ? */
+{
+
+public unsafe class UnoInterfaceInfo
+{
+ public IntPtr UnoInterface; // wrapped interface
+ public Type Type; // mapped type
+ public com.sun.star.bridges.mono_uno.Bridge Bridge;
+ public InterfaceTypeDescription *TypeDesc;
+
+ public UnoInterfaceInfo(com.sun.star.bridges.mono_uno.Bridge bridge,
+ IntPtr unoInterface,
+ InterfaceTypeDescription *td)
+ {
+ Bridge = bridge;
+ UnoInterface = unoInterface;
+ Type = Bridge.MapUnoType((TypeDescription *)td);
+ uno.Binary.Interface.Acquire(UnoInterface);
+ TypeDesc = td;
+ InterfaceTypeDescription.Acquire(TypeDesc);
+
+ fixed (InterfaceTypeDescription **ppTypeDesc = &TypeDesc)
+ if (((TypeDescription *)TypeDesc)->bComplete == 0 &&
+ TypeDescription.Complete((TypeDescription **)ppTypeDesc))
+ {
+ // FIXME throw a uno runtime exception
+ }
+ }
+
+ ~UnoInterfaceInfo()
+ {
+ Bridge.RevokeFromUnoEnvironment(UnoInterface);
+ uno.Binary.Interface.Release(UnoInterface);
+ InterfaceTypeDescription.Release(TypeDesc);
+ }
+}
+
+public unsafe class UnoInterfaceProxy: RealProxy, IRemotingTypeInfo
+{
+ /** used for IRemotingTypeInfo.TypeName
+ */
+ string typeName = "System.Object";
+
+ /** The list is filled with UnoInterfaceInfo objects. The list can only
+ grow and elements are never changed. If an element was added it
+ must not be changed!
+ */
+ ArrayList interfaces = new ArrayList(10); // of UnoInterfaceInfo
+
+ /** The list is filled with additional UnoInterfaceProxy object due
+ to aggregation via bridges. Though the latter is strongly
+ discouraged, this has to be supported.
+ */
+ ArrayList additionalProxies = new ArrayList();
+
+ Bridge bridge;
+ string oid;
+
+ private unsafe UnoInterfaceProxy(Bridge bridge, IntPtr unoInterface,
+ InterfaceTypeDescription *TD, string oid)
+ : base(typeof(MarshalByRefObject)) // FIXME is there a better type?
+ {
+ this.bridge = bridge;
+ this.oid = oid;
+ AddUnoInterface(unoInterface, TD);
+ }
+
+ ~UnoInterfaceProxy()
+ {
+ // FIXME should revokeInterface from environment, but can't
+ // access managed string oid any longer.
+ }
+
+ public static unsafe object Create(Bridge bridge, IntPtr unoInterface,
+ InterfaceTypeDescription *TD, string oid)
+ {
+ UnoInterfaceProxy realProxy = new UnoInterfaceProxy(bridge, unoInterface,
+ TD, oid);
+ object proxy = realProxy.GetTransparentProxy();
+ bridge.RegisterWithCliEnvironment(proxy, oid);
+ return proxy;
+ }
+
+ // RealProxy members
+ public unsafe override IMessage Invoke(IMessage request)
+ {
+ IMethodCallMessage callmsg = (IMethodCallMessage)request;
+
+ // Find out which UNO interface is being called
+ string typeName = callmsg.TypeName;
+ typeName = typeName.Substring(0, typeName.IndexOf(','));
+
+ // Special Handling for System.Object methods
+ if (typeName.IndexOf("System.Object") != -1)
+ {
+ return InvokeObjectMethod(request);
+ }
+
+ Type typeBeingCalled = Bridge.LoadCliType(typeName);
+ UnoInterfaceInfo info = FindInfo(typeBeingCalled);
+
+ Trace.Assert(info != null);
+
+ string methodName = callmsg.MethodName;
+ TypeDescriptionReference **ppAllMembers =
+ info.TypeDesc->ppAllMembers;
+ int numMembers = info.TypeDesc->nAllMembers;
+ for (int i = numMembers - 1; i >= 0; --i)
+ {
+ TypeDescriptionReference *memberTD = *(ppAllMembers + i);
+
+ // FIXME do without string conversion?
+ string memberTypeName = UString.UStringToString(memberTD->pTypeName);
+ // check methodName against fully qualified memberTypeName
+ // of memberTD; memberTypeName is of the form
+ // <name> "::" <methodName> *(":@" <idx> "," <idx> ":" <name>)
+
+ int offset = memberTypeName.IndexOf(':') + 2;
+ int remainder = memberTypeName.Length - offset;
+ if (memberTD->eTypeClass == TypeClass.INTERFACE_METHOD)
+ {
+ if ((methodName.Length == remainder ||
+ (methodName.Length < remainder &&
+ memberTypeName[offset + methodName.Length] == ':')) &&
+ String.Compare(memberTypeName, offset,
+ methodName, 0, methodName.Length) == 0)
+ {
+ TypeDescription *methodTD = null;
+ // FIXME release it
+ TypeDescriptionReference.GetDescription(&methodTD, memberTD);
+
+ uno.Any exception;
+ uno.Any result =
+ bridge.CallUno(info.UnoInterface,
+ methodTD,
+ ((InterfaceMethodTypeDescription *)methodTD)->pReturnTypeRef,
+ ((InterfaceMethodTypeDescription *)methodTD)->nParams,
+ ((InterfaceMethodTypeDescription *)methodTD)->pParams,
+ callmsg.Args,
+ /* FIXME this is an implementation detail,
+ documented on MSDN, but still an implementation
+ detail. cli_uno does the same */
+ (System.Type[])callmsg.MethodSignature,
+ out exception);
+ return ConstructReturnMessage(result, callmsg.Args,
+ (InterfaceMethodTypeDescription *)methodTD,
+ callmsg, exception);
+ }
+ }
+ else // INTERFACE_ATTRIBUTE
+ {
+ if (methodName.Length > 4 &&
+ (methodName.Length - 4 == remainder ||
+ (methodName.Length - 4 < remainder &&
+ memberTypeName[offset + methodName.Length - 4] == ':')) &&
+ methodName[1] == 'e' && methodName[2] == 't' &&
+ String.Compare(memberTypeName, offset,
+ methodName, 4, methodName.Length - 4) == 0)
+ {
+ InterfaceAttributeTypeDescription *attributeTD = null;
+ // FIXME release it
+ TypeDescriptionReference.GetDescription( (TypeDescription **)&attributeTD,
+ memberTD );
+ uno.Any exception;
+ uno.Any result;
+
+ if (methodName[0] == 'g') // "get"
+ {
+ result = bridge.CallUno(info.UnoInterface,
+ (TypeDescription *)attributeTD,
+ attributeTD->pAttributeTypeRef,
+ 0, null, null, null,
+ out exception);
+ return ConstructReturnMessage(result, null, null,
+ callmsg, exception);
+ }
+ else if (methodName[0] == 's') // "set"
+ {
+ if (attributeTD->bReadOnly != 0)
+ /* FIXME should we generate an exception? */
+ return ConstructReturnMessage(uno.Any.VOID, null, null,
+ callmsg, uno.Any.VOID);
+
+ MethodParameter param;
+ param.pTypeRef = attributeTD->pAttributeTypeRef;
+ param.bIn = 1;
+ param.bOut = 0;
+
+ result =
+ bridge.CallUno(info.UnoInterface,
+ (TypeDescription *)attributeTD,
+ TypeDescription.VoidType,
+ 1, &param,
+ callmsg.Args, null, /* FIXME ??? from cli_uno */
+ out exception);
+ return ConstructReturnMessage(uno.Any.VOID, null, null,
+ callmsg, exception);
+ }
+ break;
+ }
+ }
+ }
+ // FIXME check if the message of the exception is not crippled
+
+ // the thing that should not be... no method info found!
+ // FIXME throw unoidl.com.sun.star.uno.RuntimeException
+
+ return null;
+ }
+
+ // IRemotingTypeInfo members
+ public string TypeName
+ {
+ get { return typeName; }
+ set { typeName = value; }
+ }
+
+ public unsafe bool CanCastTo(Type fromType, object o)
+ {
+ if (fromType == typeof(Object))
+ return true;
+
+ lock (this) {
+ if (FindInfo(fromType) != null)
+ // type is already in our list of Interfaces
+ return true;
+
+ // queryInterface for the required type
+ // there is always a least one interface in our list
+ UnoInterfaceInfo info = (UnoInterfaceInfo)interfaces[0];
+ // ppAllMembers[0] corresponds to queryInterface
+ TypeDescription *queryI = null;
+
+ TypeDescriptionReference.GetDescription( // FIXME release it when you're done
+ &queryI, *(info.TypeDesc->ppAllMembers));
+
+ object[] args = new object[] { fromType };
+ uno.Any exception;
+
+ uno.Any result = bridge.CallUno(info.UnoInterface,
+ queryI,
+ ((InterfaceMethodTypeDescription *)queryI)->pReturnTypeRef,
+ 1, ((InterfaceMethodTypeDescription *)queryI)->pParams, args, null,
+ out exception);
+
+ // queryInterface doesn't throw exceptions.
+
+ if (result.Type != typeof(void)) // result has a value
+ {
+ if (FindInfo(fromType) != null)
+ {
+ // the proxy supports the requested interface now
+ return true;
+ }
+
+ // via aggregation: it is possible that queryInterface() returns
+ // and interface with a different oid.
+ // That way, this type is supported for the CLI
+ // interpreter (CanCastTo() returns true)
+ object obj = result.Value;
+ if (RemotingServices.IsTransparentProxy(obj))
+ {
+ UnoInterfaceProxy proxy =
+ (UnoInterfaceProxy)RemotingServices.GetRealProxy(obj);
+ additionalProxies.Add(proxy);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ // internals
+ public unsafe void AddUnoInterface(IntPtr unoInterface, InterfaceTypeDescription *TD)
+ {
+ lock (this)
+ {
+ foreach (UnoInterfaceInfo info in interfaces)
+ {
+ if (InterfaceTypeDescription.Equal(info.TypeDesc, TD))
+ return;
+ }
+ // This proxy does not contain the unoInterface. Add it.
+ bridge.RegisterWithUnoEnvironment(ref unoInterface,
+ oid, TD);
+ interfaces.Add(new UnoInterfaceInfo(bridge, unoInterface, TD));
+ }
+ }
+
+ UnoInterfaceInfo FindInfo(Type type)
+ {
+ foreach (UnoInterfaceInfo info in interfaces)
+ {
+ if (type.IsAssignableFrom(info.Type))
+ return info;
+ }
+ foreach (UnoInterfaceProxy proxy in additionalProxies)
+ {
+ UnoInterfaceInfo info = proxy.FindInfo(type);
+ if (info != null)
+ return info;
+ }
+ return null;
+ }
+
+ static Type MapUnoType(TypeDescription *TD)
+ {
+ return MapUnoType(TD->pWeakRef);
+ }
+
+ static Type MapUnoType(TypeDescriptionReference *TD)
+ {
+ Type result;
+
+ switch(TD->eTypeClass)
+ {
+ case TypeClass.VOID:
+ result = typeof(void);
+ break;
+ case TypeClass.CHAR:
+ result = typeof(char);
+ break;
+ case TypeClass.BOOLEAN:
+ result = typeof(bool);
+ break;
+ case TypeClass.BYTE:
+ result = typeof(byte);
+ break;
+ case TypeClass.SHORT:
+ result = typeof(short);
+ break;
+ case TypeClass.UNSIGNED_SHORT:
+ result = typeof(ushort);
+ break;
+ case TypeClass.LONG:
+ result = typeof(int);
+ break;
+ case TypeClass.UNSIGNED_LONG:
+ result = typeof(uint);
+ break;
+ case TypeClass.HYPER:
+ result = typeof(long);
+ break;
+ case TypeClass.UNSIGNED_HYPER:
+ result = typeof(ulong);
+ break;
+ case TypeClass.FLOAT:
+ result = typeof(float);
+ break;
+ case TypeClass.DOUBLE:
+ result = typeof(double);
+ break;
+ case TypeClass.STRING:
+ result = typeof(string);
+ break;
+ case TypeClass.TYPE:
+ result = typeof(Type);
+ break;
+ case TypeClass.ANY:
+ result = typeof(uno.Any);
+ break;
+ case TypeClass.ENUM:
+ case TypeClass.STRUCT:
+ case TypeClass.EXCEPTION:
+ result = Bridge.LoadCliType(TD->pTypeName);
+ break;
+ case TypeClass.INTERFACE:
+ // special handling for XInterface, since it does not exist in cli.
+ if (UString.UStringToString(TD->pTypeName) == "com.sun.star.uno.XInterface")
+ result = typeof(object);
+ else
+ result = Bridge.LoadCliType(TD->pTypeName);
+ break;
+ case TypeClass.SEQUENCE:
+ {
+ // FIXME do something with TD here?
+ TypeDescriptionReference *elementTDRef =
+ ((IndirectTypeDescription *)TD)->pType;
+ switch (elementTDRef->eTypeClass)
+ {
+ case TypeClass.CHAR:
+ result = Type.GetType("System.Char[]");
+ break;
+ case TypeClass.BOOLEAN:
+ result = Type.GetType("System.Boolean[]");
+ break;
+ case TypeClass.BYTE:
+ result = Type.GetType("System.Byte[]");
+ break;
+ case TypeClass.SHORT:
+ result = Type.GetType("System.Int16[]");
+ break;
+ case TypeClass.UNSIGNED_SHORT:
+ result = Type.GetType("System.UInt16[]");
+ break;
+ case TypeClass.LONG:
+ result = Type.GetType("System.Int32[]");
+ break;
+ case TypeClass.UNSIGNED_LONG:
+ result = Type.GetType("System.UInt32[]");
+ break;
+ case TypeClass.HYPER:
+ result = Type.GetType("System.Int64[]");
+ break;
+ case TypeClass.UNSIGNED_HYPER:
+ result = Type.GetType("System.UInt64[]");
+ break;
+ case TypeClass.FLOAT:
+ result = Type.GetType("System.Single[]");
+ break;
+ case TypeClass.DOUBLE:
+ result = Type.GetType("System.Double[]");
+ break;
+ case TypeClass.STRING:
+ result = Type.GetType("System.String[]");
+ break;
+ case TypeClass.TYPE:
+ result = Type.GetType("System.Type[]");
+ break;
+ case TypeClass.ANY:
+ case TypeClass.ENUM:
+ case TypeClass.EXCEPTION:
+ case TypeClass.STRUCT:
+ case TypeClass.INTERFACE:
+ case TypeClass.SEQUENCE:
+ result = Bridge.LoadCliType(TD->pTypeName);
+ break;
+ default:
+ // FIXME can't happen
+ result = null;
+ break;
+ }
+ break;
+ }
+ default:
+ // FIXME can't happen
+ result = null;
+ break;
+ }
+ return result;
+ }
+
+ IMessage InvokeObjectMethod(IMessage request)
+ {
+ IMethodMessage methodmsg = (IMethodMessage)request;
+ object ret;
+ switch (methodmsg.MethodName)
+ {
+ case "Equals":
+ ret = false;
+
+ if (RemotingServices.IsTransparentProxy(methodmsg.Args[0]))
+ {
+ UnoInterfaceProxy unoProxy =
+ RemotingServices.GetRealProxy(methodmsg.Args[0]) as UnoInterfaceProxy;
+
+ if (unoProxy != null)
+ {
+ ret = oid.Equals(unoProxy.Oid);
+ break;
+ }
+ }
+ break;
+ case "GetHashCode":
+ ret = oid.GetHashCode();
+ break;
+ case "GetType":
+ ret = typeof(System.Object);
+ break;
+ case "ToString":
+ ret = String.Format("Uno object proxy. OID: {0}", oid);
+ break;
+ default:
+ // Cannot happen
+ ret = null;
+ break;
+ }
+
+ return new ReturnMessage(ret, new object[0], 0,
+ methodmsg.LogicalCallContext,
+ (IMethodCallMessage)methodmsg);
+ }
+
+ public string Oid {
+ get { return oid; }
+ }
+
+ IMessage ConstructReturnMessage(uno.Any result, object[] args,
+ InterfaceMethodTypeDescription *methodTD,
+ IMethodCallMessage callmsg, uno.Any exception)
+ {
+ if (exception.hasValue())
+ {
+ throw (System.Exception)exception.Value;
+ }
+ else
+ {
+ if (args != null)
+ {
+ object[] outArgs = new object[methodTD->nParams];
+ int numOutArgs = 0;
+ for (int i = 0; i < methodTD->nParams; ++i)
+ {
+ if (methodTD->pParams[i].bOut == 1)
+ {
+ outArgs[i] = args[i];
+ ++numOutArgs;
+ }
+ }
+ return new ReturnMessage(result.Value, outArgs, numOutArgs,
+ callmsg.LogicalCallContext,
+ callmsg);
+ }
+ else
+ {
+ return new ReturnMessage(result.Value, null, 0,
+ callmsg.LogicalCallContext,
+ callmsg);
+ }
+ }
+ }
+}
+
+}