1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 namespace com
.sun
.star
.bridges
.mono_uno
/* FIXME use some uno.foo namespace ? */
33 using System
.Reflection
;
34 using System
.Runtime
.InteropServices
;
35 using System
.Runtime
.Remoting
;
41 public unsafe class Bridge
43 static IntPtr unoEnvironment
;
44 static cli_uno
.Cli_environment managedEnvironment
;
48 unoEnvironment
= unoEnv
;
49 managedEnvironment
= new cli_uno
.Cli_environment();
52 public unsafe IntPtr
MapManagedToUno(object managedData
, TypeDescription
*td
)
54 IntPtr result
= new IntPtr(null);
56 // get oid from managed environment
57 string oid
= cli_uno
.Cli_environment
.getObjectIdentifier(managedData
);
59 UString
* unoOid
= null;
60 UString
.NewFromString(&unoOid
, oid
);
61 uno
.Binary
.Environment
.GetRegisteredInterface(unoEnvironment
,
64 (InterfaceTypeDescription
*)td
);
65 if (result
== IntPtr
.Zero
)
66 lock (typeof(cli_uno
.Cli_environment
))
68 uno
.Binary
.Environment
.GetRegisteredInterface(unoEnvironment
,
71 (InterfaceTypeDescription
*)td
);
72 if (result
== IntPtr
.Zero
)
73 result
= CreateManagedProxy(managedData
, td
, unoOid
);
76 UString
.Release(unoOid
);
81 public unsafe object MapUnoToManaged(IntPtr unoInterface
, InterfaceTypeDescription
*iTD
)
85 UString
* oidPtr
= null;
86 uno
.Binary
.Environment
.GetObjectIdentifier(unoEnvironment
, &oidPtr
, unoInterface
);
88 // See if the interface was already mapped
89 Type ifaceType
= MapUnoType((TypeDescription
*)iTD
);
90 string oid
= UString
.UStringToString(oidPtr
);
91 // the string is owned by unoEnvironment
94 lock (managedEnvironment
)
96 result
= managedEnvironment
.getRegisteredInterface(oid
, ifaceType
);
99 // There is already an registered object. It can either be a proxy
100 // for the UNO object or a real cli object. In the first case we
101 // tell the proxy that it shall also represent the current UNO
102 // interface. If it already does that, then it does nothing
103 if (RemotingServices
.IsTransparentProxy(result
))
105 UnoInterfaceProxy p
= (UnoInterfaceProxy
)RemotingServices
.GetRealProxy(result
);
106 p
.AddUnoInterface(unoInterface
, iTD
);
111 result
= UnoInterfaceProxy
.Create(this, unoInterface
, iTD
, oid
);
118 // FIXME convert cli types to expected types, e.g a long to a short where the uno type
119 // is a sal_Int16. This could be necessary if a scripting language (typeless) is used
120 // @param assign the uno_data has to be destructed (in/out args)
121 unsafe void MapToUno(void *unoData
, object managedData
,
122 // FIXME it's a TypeDescriptionReference
123 TypeDescription
*type
, bool assign
)
125 // FIXME acquire the TypeDescription?
126 // FIXME assert that all the type equivalences in the comments hold
127 switch (type
->eTypeClass
)
132 *(ushort *)unoData
= (char)managedData
; // sal_Unicode = ushort
134 case TypeClass
.BOOLEAN
:
135 *(byte *)unoData
= (bool)managedData
? (byte)1 : (byte)0; // sal_Bool = byte
138 *(byte *)unoData
= (byte)managedData
; // sal_Int8 = byte
140 case TypeClass
.SHORT
:
141 *(short *)unoData
= (short)managedData
; // sal_Int16 = short
143 case TypeClass
.UNSIGNED_SHORT
:
144 *(ushort *)unoData
= (ushort)managedData
; // sal_uInt16 = ushort
147 *(int *)unoData
= (int)managedData
; // sal_Int32 = int
149 case TypeClass
.UNSIGNED_LONG
:
150 *(uint *)unoData
= (uint)managedData
; // sal_uInt32 = uint
152 case TypeClass
.HYPER
:
153 *(long *)unoData
= (long)managedData
; // sal_Int64 = long
155 case TypeClass
.UNSIGNED_HYPER
:
156 *(ulong *)unoData
= (ulong)managedData
; // sal_uInt64 = ulong
158 case TypeClass
.FLOAT
:
159 *(float *)unoData
= (float)managedData
; // C++ float = C# float
161 case TypeClass
.DOUBLE
:
162 *(double *)unoData
= (double)managedData
; // C++ double = C# double
164 case TypeClass
.STRING
:
166 if (assign
&& *(UString
**)unoData
!= null)
167 UString
.Release(*(UString
**)unoData
);
169 *(UString
**)unoData
= null;
170 if (managedData
== null)
172 UString
.New((UString
**)unoData
);
176 string s
= (string)managedData
;
177 UString
.NewFromString((UString
**)unoData
, s
);
183 TypeDescriptionReference
.Release(*(TypeDescriptionReference
**)unoData
);
185 *(TypeDescriptionReference
**)unoData
= MapManagedType((Type
)managedData
);
189 uno
.Binary
.Any
*binAny
= (uno
.Binary
.Any
*)unoData
;
192 uno
.Binary
.Any
.Destroy(binAny
, null);
194 if (managedData
== null)
196 uno
.Binary
.Any
.Construct(binAny
, null, null, null);
200 uno
.Any any
= (uno
.Any
)managedData
;
201 TypeDescription
*valueTD
= (TypeDescription
*)MapManagedType(any
.Type
);
203 // if there's enough room in void *pReserved, store the value in the pointer
204 binAny
->pData
= &binAny
->pReserved
; // this triggers a bug in mcs < 1.1.4
205 switch (valueTD
->eTypeClass
)
210 *(ushort *)binAny
->pData
= (char)any
.Value
;
212 case TypeClass
.BOOLEAN
:
213 *(byte *)binAny
->pData
= (bool)any
.Value
? (byte)1 : (byte)0;
216 *(byte *)binAny
->pData
= (byte)any
.Value
;
218 case TypeClass
.SHORT
:
219 *(short *)binAny
->pData
= (short)any
.Value
;
221 case TypeClass
.UNSIGNED_SHORT
:
222 *(ushort *)binAny
->pData
= (ushort)any
.Value
;
225 *(int *)binAny
->pData
= (int)any
.Value
;
227 case TypeClass
.UNSIGNED_LONG
:
228 *(uint *)binAny
->pData
= (uint)any
.Value
;
230 case TypeClass
.HYPER
:
231 if (sizeof(long) > sizeof(void *))
232 binAny
->pData
= uno
.rtl
.Mem
.Allocate(sizeof(long));
234 *(long *)binAny
->pData
= (long)any
.Value
;
236 case TypeClass
.UNSIGNED_HYPER
:
237 if (sizeof(ulong) > sizeof(void *))
238 binAny
->pData
= uno
.rtl
.Mem
.Allocate(sizeof(ulong));
240 *(ulong *)binAny
->pData
= (ulong)any
.Value
;
242 case TypeClass
.FLOAT
:
243 if (sizeof(float) > sizeof(void *)) // FIXME can this happen?
244 binAny
->pData
= uno
.rtl
.Mem
.Allocate(sizeof(float));
246 *(float *)binAny
->pData
= (float)any
.Value
;
248 case TypeClass
.DOUBLE
:
249 if (sizeof(double) > sizeof(void *))
250 binAny
->pData
= uno
.rtl
.Mem
.Allocate(sizeof(double));
252 *(double *)binAny
->pData
= (double)any
.Value
;
254 case TypeClass
.STRING
:
255 // string anies are used so often, that we handle them
256 // separately, to be a little faster than with an
257 // extra MapToUno call
259 // the Any was already destroyed, can't contain a
260 // valid string that we could leak here.
261 *(UString
**)binAny
->pData
= null;
263 if (managedData
== null)
265 UString
.New((UString
**)binAny
->pData
);
269 string s
= (string)any
.Value
;
270 UString
.NewFromString((UString
**)binAny
->pData
, s
);
272 // the string is owned by the Any
275 *(int *) binAny
->pData
= System
.Convert
.ToInt32(any
.Value
);
278 case TypeClass
.SEQUENCE
:
279 case TypeClass
.INTERFACE
:
280 binAny
->pReserved
= null;
281 MapToUno(binAny
->pData
, any
.Value
, valueTD
, false /* no assign */);
283 case TypeClass
.STRUCT
:
284 case TypeClass
.EXCEPTION
:
285 binAny
->pData
= uno
.rtl
.Mem
.Allocate(valueTD
->nSize
);
286 MapToUno(binAny
->pData
, any
.Value
, valueTD
, false /* no assign */);
290 throw new Exception();
292 binAny
->pType
= (TypeDescriptionReference
*)valueTD
;
293 TypeDescriptionReference
.Acquire(binAny
->pType
);
297 *(int *)unoData
= System
.Convert
.ToInt32(managedData
);
299 case TypeClass
.STRUCT
:
300 case TypeClass
.EXCEPTION
:
302 TypeDescription
*td
= null; // FIXME leak
303 TypeDescriptionReference
.GetDescription(&td
, (TypeDescriptionReference
*)type
);
304 CompoundTypeDescription
*compTD
= (CompoundTypeDescription
*)td
;
305 StructTypeDescription
*structTD
= null;
307 if (type
->eTypeClass
== TypeClass
.STRUCT
)
308 structTD
= (StructTypeDescription
*)type
;
310 if (((TypeDescription
*)compTD
)->bComplete
== 0)
311 TypeDescription
.Complete((TypeDescription
**)&compTD
);
313 int members
= compTD
->nMembers
;
314 Type managedType
= null;
315 if (managedData
!= null)
316 managedType
= managedData
.GetType();
318 if (compTD
->pBaseTypeDescription
!= null)
319 MapToUno(unoData
, managedData
,
320 (TypeDescription
*)((TypeDescription
*)compTD
->pBaseTypeDescription
)->pWeakRef
,
323 TypeDescriptionReference
*memberType
= null;
324 for (int i
= 0; i
< members
; ++i
)
326 memberType
= compTD
->ppTypeRefs
[i
];
329 if (managedData
!= null)
331 string fieldName
= UString
.UStringToString(compTD
->ppMemberNames
[i
]);
332 FieldInfo fieldInfo
= managedType
.GetField(fieldName
);
333 // special case for Exception.Message property
334 // The com.sun.star.uno.Exception.Message field is mapped to the
335 // System.Exception property. Type.GetField("Message") returns null
336 if (fieldInfo
== null &&
337 UString
.UStringToString(type
->pTypeName
) == "com.sun.star.uno.Exception")
339 // get ExceptionMessage property
340 if (fieldName
== "Message")
342 PropertyInfo propInfo
= managedType
.GetProperty(fieldName
);
343 val
= propInfo
.GetValue(managedData
, null);
344 } // FIXME else throw exception
346 else if (fieldInfo
!= null)
348 val
= fieldInfo
.GetValue(managedData
);
349 } // FIXME else throw exception
352 void *p
= (byte *)unoData
+ compTD
->pMemberOffsets
[i
];
353 // When using polymorphic structs then the parameterized members can be null.
354 // Then we set a default value.
355 bool useDefault
= ((structTD
!= null &&
356 structTD
->pParameterizedTypes
!= null &&
357 structTD
->pParameterizedTypes
[i
] == 1 &&
359 managedData
== null);
360 switch (memberType
->eTypeClass
)
366 *(ushort *)p
= (char)val
;
368 case TypeClass
.BOOLEAN
:
370 *(byte *)p
= (byte)0;
372 *(byte *)p
= (bool)val
? (byte)1 : (byte)0;
376 *(byte *)p
= (byte)0;
378 *(byte *)p
= (byte)val
;
380 case TypeClass
.SHORT
:
382 *(short *)p
= (short)0;
384 *(short *)p
= (short)val
;
386 case TypeClass
.UNSIGNED_SHORT
:
388 *(ushort *)p
= (ushort)0;
390 *(ushort *)p
= (ushort)val
;
396 *(int *)p
= (int)val
;
398 case TypeClass
.UNSIGNED_LONG
:
400 *(uint *)p
= (uint)0;
402 *(uint *)p
= (uint)val
;
404 case TypeClass
.HYPER
:
406 *(long *)p
= (long)0;
408 *(long *)p
= (long)val
;
410 case TypeClass
.UNSIGNED_HYPER
:
412 *(ulong *)p
= (ulong)0;
414 *(ulong *)p
= (ulong)val
;
416 case TypeClass
.FLOAT
:
420 *(float *)p
= (float)val
;
422 case TypeClass
.DOUBLE
:
426 *(double *)p
= (double)val
;
429 // FIXME enum should be converted here
430 MapToUno(p
, val
, (TypeDescription
*)memberType
, assign
);
434 // FIXME exception handling
437 case TypeClass
.SEQUENCE
:
439 TypeDescription
*td
= null; // FIXME
440 TypeDescriptionReference
.GetDescription(&td
, (TypeDescriptionReference
*)type
);
441 TypeDescriptionReference
*elementType
=
442 ((IndirectTypeDescription
*)td
)->pType
;
444 SequencePtr seq
= new SequencePtr();
446 if (managedData
!= null)
448 Array array
= (Array
)managedData
;
449 int length
= array
.GetLength(0);
451 switch (elementType
->eTypeClass
)
454 seq
= SequencePtr
.Allocate(length
, sizeof(ushort));
455 Marshal
.Copy((char [])managedData
, 0, seq
.elementsPtr
, length
);
457 /* case TypeClass.BOOLEAN:
458 // FIXME bool vs. byte ???
459 seq = SequencePtr.Allocate(length, sizeof(byte));
460 Marshal.Copy((byte [])managedData, 0, seq.elementsPtr, length);
463 seq
= SequencePtr
.Allocate(length
, sizeof(byte));
464 Marshal
.Copy((byte [])managedData
, 0, seq
.elementsPtr
, length
);
466 case TypeClass
.SHORT
:
467 seq
= SequencePtr
.Allocate(length
, sizeof(short));
468 Marshal
.Copy((short [])managedData
, 0, seq
.elementsPtr
, length
);
470 /* case TypeClass.UNSIGNED_SHORT:
471 seq = SequencePtr.Allocate(length, sizeof(ushort));
472 Marshal.Copy((short [])managedData, 0, seq.elementsPtr, length);
475 seq
= SequencePtr
.Allocate(length
, sizeof(int));
476 Marshal
.Copy((int [])managedData
, 0, seq
.elementsPtr
, length
);
478 /* case TypeClass.UNSIGNED_LONG:
479 seq = SequencePtr.Allocate(length, sizeof(uint));
480 Marshal.Copy((int [])managedData, 0, seq.elementsPtr, length);
482 case TypeClass
.HYPER
:
483 seq
= SequencePtr
.Allocate(length
, sizeof(long));
484 Marshal
.Copy((long [])managedData
, 0, seq
.elementsPtr
, length
);
486 /* case TypeClass.UNSIGNED_HYPER:
487 seq = SequencePtr.Allocate(length, sizeof(ulong));
488 Marshal.Copy((long [])managedData, 0, seq.elementsPtr, length);
490 case TypeClass
.FLOAT
:
491 seq
= SequencePtr
.Allocate(length
, sizeof(float));
492 Marshal
.Copy((float [])managedData
, 0, seq
.elementsPtr
, length
);
494 case TypeClass
.DOUBLE
:
495 seq
= SequencePtr
.Allocate(length
, sizeof(double));
496 Marshal
.Copy((double [])managedData
, 0, seq
.elementsPtr
, length
);
498 case TypeClass
.STRING
:
500 seq
= SequencePtr
.Allocate(length
, sizeof(void *));
501 string[] stringArray
= (string [])managedData
;
502 for (int i
= 0; i
< length
; ++i
)
504 UString
** pStr
= ((UString
** )seq
.elementsPtr
) + i
;
506 UString
.NewFromString(pStr
, stringArray
[i
]);
507 // string ownership goes to callee
512 seq
= SequencePtr
.Allocate(length
, sizeof(int));
513 for (int i
= 0; i
< length
; ++i
)
514 ((int *)seq
.elementsPtr
)[i
] =
515 Convert
.ToInt32(array
.GetValue(i
));
519 case TypeClass
.STRUCT
:
520 case TypeClass
.EXCEPTION
:
521 case TypeClass
.SEQUENCE
:
522 case TypeClass
.INTERFACE
:
523 // FIXME: surely we can do better for this lot [!] - sign problems ...
524 case TypeClass
.BOOLEAN
:
525 case TypeClass
.UNSIGNED_SHORT
:
526 case TypeClass
.UNSIGNED_LONG
:
527 case TypeClass
.UNSIGNED_HYPER
:
529 seq
= SequencePtr
.Allocate(
530 length
, ((TypeDescription
*)elementType
)->nSize
);
532 for (int i
= 0; i
< length
; ++i
)
535 (byte *)seq
.elementsPtr
+
536 i
* ((TypeDescription
*)elementType
)->nSize
;
537 object elementData
= ((Array
)managedData
).GetValue(i
);
538 MapToUno(p
, elementData
,
539 (TypeDescription
*)((TypeDescription
*)elementType
)->pWeakRef
,
540 false /* no assign */);
542 // FIXME exception handling
546 break; // FIXME throw some exception
551 seq
= SequencePtr
.Allocate(0, sizeof(int));
553 *(SequencePtr
*)unoData
= seq
;
556 case TypeClass
.INTERFACE
:
558 if (assign
&& *(void **)unoData
!= null)
559 uno
.Binary
.Interface
.Release(new IntPtr(*(void **)unoData
));
561 if (managedData
== null)
562 *(void **)unoData
= null;
565 TypeDescription
*td
= null; // FIXME leak
566 TypeDescriptionReference
.GetDescription(&td
, (TypeDescriptionReference
*)type
);
567 *(void **)unoData
= MapManagedToUno(managedData
, td
).ToPointer();
572 // FIXME throw some exception
577 unsafe void MapToManaged(ref object managedData
, void *unoData
,
578 TypeDescriptionReference
*type
, Type info
, bool dontCreateObj
)
580 switch (type
->eTypeClass
)
583 managedData
= (char)*(ushort *)unoData
;
585 case TypeClass
.BOOLEAN
:
586 managedData
= (*(byte *)unoData
!= 0);
589 managedData
= *(byte *)unoData
;
591 case TypeClass
.SHORT
:
592 managedData
= *(short *)unoData
;
594 case TypeClass
.UNSIGNED_SHORT
:
595 managedData
= *(ushort *)unoData
;
598 managedData
= *(int *)unoData
;
600 case TypeClass
.UNSIGNED_LONG
:
601 managedData
= *(uint *)unoData
;
603 case TypeClass
.HYPER
:
604 managedData
= *(long *)unoData
;
606 case TypeClass
.UNSIGNED_HYPER
:
607 managedData
= *(ulong *)unoData
;
609 case TypeClass
.FLOAT
:
610 managedData
= *(float *)unoData
;
612 case TypeClass
.DOUBLE
:
613 managedData
= *(double *)unoData
;
615 case TypeClass
.STRING
:
616 managedData
= UString
.UStringToString(*(UString
**)unoData
);
619 managedData
= MapUnoType(*(TypeDescriptionReference
**)unoData
);
623 uno
.Binary
.Any
*binAny
= (uno
.Binary
.Any
*)unoData
;
624 if (binAny
->pType
->eTypeClass
!= TypeClass
.VOID
)
627 MapToManaged(ref value, binAny
->pData
, binAny
->pType
, null, false);
628 managedData
= new uno
.Any(MapUnoType(binAny
->pType
), value);
632 managedData
= uno
.Any
.VOID
;
638 managedData
= Enum
.ToObject(
639 info
.GetElementType(), *(int *)unoData
);
641 managedData
= Enum
.ToObject(
642 MapUnoType(type
), *(int *)unoData
);
644 case TypeClass
.STRUCT
:
645 case TypeClass
.EXCEPTION
:
647 TypeDescription
*td
= null; // FIXME leak
648 TypeDescriptionReference
.GetDescription(&td
, (TypeDescriptionReference
*)type
);
649 CompoundTypeDescription
*compTD
= (CompoundTypeDescription
*)td
;
651 if (((TypeDescription
*)compTD
)->bComplete
== 0)
652 TypeDescription
.Complete((TypeDescription
**)&compTD
);
655 Type managedType
= LoadCliType(td
->pTypeName
);
657 // detect if we recursivly convert inherited
658 // structures. If this point is reached because of a
659 // recursive call during converting a struct then we must
660 // not create a new object rather we use the one in
661 // cli_data argument.
662 object managedObject
;
664 managedObject
= managedData
;
667 // Special handling for Exception conversion. We must
668 // call constructor System::Exception to pass the
670 if (typeof(unoidl
.com
.sun
.star
.uno
.Exception
).IsAssignableFrom(managedType
))
672 // We need to get the Message field. Therefore we
673 // must obtain the offset from the
674 // typedescription. The base interface of all
675 // exceptions is com::sun::star::uno::Exception
676 // which contains the message
677 CompoundTypeDescription
*pCTD
= compTD
;
678 while (pCTD
->pBaseTypeDescription
!= null)
679 pCTD
= pCTD
->pBaseTypeDescription
;
682 for (int i
= 0; i
< pCTD
->nMembers
; ++i
)
684 if (UString
.UStringToString(pCTD
->ppMemberNames
[i
]) == "Message")
691 int offset
= pCTD
->pMemberOffsets
[pos
];
692 // With the offset within the exception we can get
693 // the message string
694 string message
= UString
.UStringToString(
695 (*(UString
**)((byte *)unoData
+ offset
)));
696 // We need to find a constructor for the exception
697 // that takes the message string. We assume that
698 // the first argument is the message string
699 ConstructorInfo
[] ctorInfos
= managedType
.GetConstructors();
700 ConstructorInfo ctorInfo
= null;
701 // Constructor must at least have 2 params for the base
702 // unoidl.com.sun.star.uno.Exception (String, Object);
704 foreach (ConstructorInfo ci
in ctorInfos
)
706 numArgs
= ci
.GetParameters().Length
;
713 // Prepare parameters for constructor
714 object[] args
= new object[numArgs
];
715 // only initialize the first argument with the
716 // message. All unoidl.<Foo Exception>s are
717 // autogenerated, we know that this is safe.
719 managedObject
= ctorInfo
.Invoke(args
);
722 managedObject
= Activator
.CreateInstance(managedType
);
725 TypeDescriptionReference
**memberTypeRefs
= compTD
->ppTypeRefs
;
726 int *memberOffsets
= compTD
->pMemberOffsets
;
728 if (compTD
->pBaseTypeDescription
!= null)
730 // convert inherited struct
731 // cliObj is passed inout (args in_param, out_param are true), hence the passed
732 // cliObj is used by the callee instead of a newly created struct
733 MapToManaged(ref managedObject
, unoData
,
734 ((TypeDescription
*)compTD
->pBaseTypeDescription
)->pWeakRef
,
738 for (int i
= compTD
->nMembers
- 1; i
>= 0; --i
)
740 TypeDescriptionReference
*memberType
= memberTypeRefs
[i
];
741 string memberName
= UString
.UStringToString(compTD
->ppMemberNames
[i
]);
742 FieldInfo fieldInfo
= managedType
.GetField(memberName
);
743 // special case for Exception.Message. The field has already been
744 // set while constructing cli object
745 if (fieldInfo
== null &&
746 UString
.UStringToString(type
->pTypeName
) == "com.sun.star.uno.Exception")
749 void *p
= (byte *)unoData
+ memberOffsets
[i
];
750 switch (memberType
->eTypeClass
)
753 fieldInfo
.SetValue(managedObject
, (char)*(short *)p
);
755 case TypeClass
.BOOLEAN
:
756 fieldInfo
.SetValue(managedObject
, (*(byte *)p
) != 0);
759 fieldInfo
.SetValue(managedObject
, *(byte *)p
);
761 case TypeClass
.SHORT
:
762 fieldInfo
.SetValue(managedObject
, *(short *)p
);
764 case TypeClass
.UNSIGNED_SHORT
:
765 fieldInfo
.SetValue(managedObject
, *(ushort *)p
);
768 fieldInfo
.SetValue(managedObject
, *(int *)p
);
770 case TypeClass
.UNSIGNED_LONG
:
771 fieldInfo
.SetValue(managedObject
, *(uint *)p
);
773 case TypeClass
.HYPER
:
774 fieldInfo
.SetValue(managedObject
, *(long *)p
);
776 case TypeClass
.UNSIGNED_HYPER
:
777 fieldInfo
.SetValue(managedObject
, *(ulong *)p
);
779 case TypeClass
.FLOAT
:
780 fieldInfo
.SetValue(managedObject
, *(float *)p
);
782 case TypeClass
.DOUBLE
:
783 fieldInfo
.SetValue(managedObject
, *(double *)p
);
787 object managedValue
= null;
788 MapToManaged(ref managedValue
, p
, memberType
, null, false);
789 fieldInfo
.SetValue(managedObject
, managedValue
);
794 managedData
= managedObject
;
797 case TypeClass
.SEQUENCE
:
799 SequencePtr seq
= *(SequencePtr
*)unoData
;
800 int length
= seq
.nElements
;
802 TypeDescription
*td
= null; // FIXME leak
803 TypeDescriptionReference
.GetDescription(&td
, (TypeDescriptionReference
*)type
);
804 TypeDescriptionReference
*elementType
= ((IndirectTypeDescription
*)td
)->pType
;
806 switch (elementType
->eTypeClass
)
810 char[] array
= new char[length
];
811 Marshal
.Copy(seq
.elementsPtr
, array
, 0, length
);
815 case TypeClass
.BOOLEAN
:
817 bool[] array
= new bool[length
];
818 byte *source
= (byte *)seq
.elementsPtr
;
819 if (length
> 0) fixed (bool *arrayPtr
= array
)
821 bool *dest
= arrayPtr
;
822 for (int i
= 0; i
< length
; ++i
)
823 *dest
++ = (*source
++ != 0);
830 byte[] array
= new byte[length
];
831 byte *source
= (byte *)seq
.elementsPtr
;
832 if (length
> 0) fixed (byte *arrayPtr
= array
)
834 byte *dest
= arrayPtr
;
835 for (int i
= 0; i
< length
; ++i
)
841 case TypeClass
.SHORT
:
843 short[] array
= new short[length
];
844 Marshal
.Copy(seq
.elementsPtr
, array
, 0, length
);
848 case TypeClass
.UNSIGNED_SHORT
:
850 ushort[] array
= new ushort[length
];
851 ushort *source
= (ushort *)seq
.elementsPtr
;
852 if (length
> 0) fixed (ushort *arrayPtr
= array
)
854 ushort *dest
= arrayPtr
;
855 for (int i
= 0; i
< length
; ++i
)
863 int[] array
= new int[length
];
864 Marshal
.Copy(seq
.elementsPtr
, array
, 0, length
);
868 case TypeClass
.UNSIGNED_LONG
:
870 uint[] array
= new uint[length
];
871 uint *source
= (uint *)seq
.elementsPtr
;
872 if (length
> 0) fixed (uint *arrayPtr
= array
)
874 uint *dest
= arrayPtr
;
875 for (int i
= 0; i
< length
; ++i
)
881 case TypeClass
.HYPER
:
883 long[] array
= new long[length
];
884 Marshal
.Copy(seq
.elementsPtr
, array
, 0, length
);
888 case TypeClass
.UNSIGNED_HYPER
:
890 ulong[] array
= new ulong[length
];
891 ulong *source
= (ulong *)seq
.elementsPtr
;
892 if (length
> 0) fixed (ulong *arrayPtr
= array
)
894 ulong *dest
= arrayPtr
;
895 for (int i
= 0; i
< length
; ++i
)
901 case TypeClass
.FLOAT
:
903 float[] array
= new float[length
];
904 Marshal
.Copy(seq
.elementsPtr
, array
, 0, length
);
908 case TypeClass
.DOUBLE
:
910 double[] array
= new double[length
];
911 Marshal
.Copy(seq
.elementsPtr
, array
, 0, length
);
915 case TypeClass
.STRING
:
917 string[] array
= new string[length
];
918 for (int i
= 0; i
< length
; ++i
)
920 UString
*us
= ((UString
**)seq
.elementsPtr
)[i
];
921 array
[i
] = UString
.UStringToString(us
);
928 Type
[] array
= new Type
[length
];
929 for (int i
= 0; i
< length
; ++i
)
930 array
[i
] = MapUnoType(((TypeDescriptionReference
**)
931 seq
.elementsPtr
)[i
]);
937 uno
.Any
[] array
= new uno
.Any
[length
];
938 uno
.Binary
.Any
*binAny
= (uno
.Binary
.Any
*)seq
.elementsPtr
;
939 for (int i
= 0; i
< length
; ++i
)
941 object any
= new uno
.Any();
942 MapToManaged(ref any
, (void **)(binAny
+ i
),
943 (TypeDescriptionReference
*)elementType
,
945 array
[i
] = (uno
.Any
)any
;
952 Type enumType
= null;
955 enumType
= info
.GetElementType();
956 // enumType is EnumType[], get EnumType
957 enumType
= enumType
.GetElementType();
960 enumType
= MapUnoType(elementType
);
962 Array array
= Array
.CreateInstance(enumType
, length
);
963 for (int i
= 0; i
< length
; ++i
)
965 array
.SetValue(Enum
.ToObject(enumType
,
966 ((int *)seq
.elementsPtr
)[i
]),
972 case TypeClass
.STRUCT
:
973 case TypeClass
.EXCEPTION
:
975 Array array
= Array
.CreateInstance(MapUnoType(elementType
), length
);
979 byte *p
= (byte *)seq
.elementsPtr
;
980 int size
= ((TypeDescription
*)elementType
)->nSize
;
981 for (int i
= 0; i
< length
; ++i
)
984 MapToManaged(ref val
, p
+ (size
* i
), elementType
, null, false);
985 array
.SetValue(val
, i
);
991 // FIXME verify (says cli_data.cxx)
992 case TypeClass
.SEQUENCE
:
994 Array array
= Array
.CreateInstance(
995 MapUnoType(elementType
), length
);
998 SequencePtr
*elements
= (SequencePtr
*)seq
.elementsPtr
;
999 for (int i
= 0; i
< length
; ++i
)
1002 MapToManaged(ref val
, elements
+ i
, elementType
, null, false);
1003 array
.SetValue(val
, i
);
1006 managedData
= array
;
1009 case TypeClass
.INTERFACE
:
1011 Type ifaceType
= MapUnoType(elementType
);
1012 Array array
= Array
.CreateInstance(ifaceType
, length
);
1014 byte *p
= (byte *)seq
.elementsPtr
;
1015 int size
= ((TypeDescription
*)elementType
)->nSize
;
1016 for (int i
= 0; i
< length
; ++i
)
1019 MapToManaged(ref val
, p
+ (size
* i
), elementType
, null, false);
1020 array
.SetValue(val
, i
);
1022 managedData
= array
;
1027 // FIXME throw some exception
1033 case TypeClass
.INTERFACE
:
1035 IntPtr unoI
= new IntPtr(*(void **)unoData
);
1036 if (unoI
!= IntPtr
.Zero
)
1038 TypeDescription
*td
= null; // FIXME leak
1039 TypeDescriptionReference
.GetDescription(&td
, type
);
1040 managedData
= MapUnoToManaged(unoI
, (InterfaceTypeDescription
*)td
);
1048 // FIXME throw some exception
1054 public static Type
MapUnoType(TypeDescription
*TD
)
1056 return MapUnoType(TD
->pWeakRef
);
1059 public static Type
MapUnoType(TypeDescriptionReference
*TD
)
1063 switch(TD
->eTypeClass
)
1065 case TypeClass
.VOID
:
1066 result
= typeof(void);
1068 case TypeClass
.CHAR
:
1069 result
= typeof(char);
1071 case TypeClass
.BOOLEAN
:
1072 result
= typeof(bool);
1074 case TypeClass
.BYTE
:
1075 result
= typeof(byte);
1077 case TypeClass
.SHORT
:
1078 result
= typeof(short);
1080 case TypeClass
.UNSIGNED_SHORT
:
1081 result
= typeof(ushort);
1083 case TypeClass
.LONG
:
1084 result
= typeof(int);
1086 case TypeClass
.UNSIGNED_LONG
:
1087 result
= typeof(uint);
1089 case TypeClass
.HYPER
:
1090 result
= typeof(long);
1092 case TypeClass
.UNSIGNED_HYPER
:
1093 result
= typeof(ulong);
1095 case TypeClass
.FLOAT
:
1096 result
= typeof(float);
1098 case TypeClass
.DOUBLE
:
1099 result
= typeof(double);
1101 case TypeClass
.STRING
:
1102 result
= typeof(string);
1104 case TypeClass
.TYPE
:
1105 result
= typeof(Type
);
1108 result
= typeof(uno
.Any
);
1110 case TypeClass
.ENUM
:
1111 case TypeClass
.STRUCT
:
1112 case TypeClass
.EXCEPTION
:
1113 result
= LoadCliType(TD
->pTypeName
);
1115 case TypeClass
.INTERFACE
:
1116 // special handling for XInterface, since it does not exist in cli.
1117 if (UString
.UStringToString(TD
->pTypeName
) == "com.sun.star.uno.XInterface")
1118 result
= typeof(object);
1120 result
= LoadCliType(TD
->pTypeName
);
1122 case TypeClass
.SEQUENCE
:
1124 TypeDescription
*seqType
= null; // FIXME leak
1125 TypeDescriptionReference
.GetDescription(&seqType
, TD
);
1127 // FIXME do something with TD here?
1128 TypeDescriptionReference
*elementTDRef
=
1129 ((IndirectTypeDescription
*)seqType
)->pType
;
1131 switch (elementTDRef
->eTypeClass
)
1133 case TypeClass
.CHAR
:
1134 result
= Type
.GetType("System.Char[]");
1136 case TypeClass
.BOOLEAN
:
1137 result
= Type
.GetType("System.Boolean[]");
1139 case TypeClass
.BYTE
:
1140 result
= Type
.GetType("System.Byte[]");
1142 case TypeClass
.SHORT
:
1143 result
= Type
.GetType("System.Int16[]");
1145 case TypeClass
.UNSIGNED_SHORT
:
1146 result
= Type
.GetType("System.UInt16[]");
1148 case TypeClass
.LONG
:
1149 result
= Type
.GetType("System.Int32[]");
1151 case TypeClass
.UNSIGNED_LONG
:
1152 result
= Type
.GetType("System.UInt32[]");
1154 case TypeClass
.HYPER
:
1155 result
= Type
.GetType("System.Int64[]");
1157 case TypeClass
.UNSIGNED_HYPER
:
1158 result
= Type
.GetType("System.UInt64[]");
1160 case TypeClass
.FLOAT
:
1161 result
= Type
.GetType("System.Single[]");
1163 case TypeClass
.DOUBLE
:
1164 result
= Type
.GetType("System.Double[]");
1166 case TypeClass
.STRING
:
1167 result
= Type
.GetType("System.String[]");
1169 case TypeClass
.TYPE
:
1170 result
= Type
.GetType("System.Type[]");
1173 case TypeClass
.ENUM
:
1174 case TypeClass
.EXCEPTION
:
1175 case TypeClass
.STRUCT
:
1176 case TypeClass
.INTERFACE
:
1177 case TypeClass
.SEQUENCE
:
1178 result
= LoadCliType(TD
->pTypeName
);
1181 // FIXME can't happen
1188 // FIXME can't happen
1195 public static Type
LoadCliType(UString
* unoName
)
1197 return LoadCliType(MapUnoTypeName(UString
.UStringToString(unoName
)));
1200 public static Type
LoadCliType(string unoName
)
1203 bool isPolymorphic
= false;
1205 string loadName
= unoName
;
1206 int index
= unoName
.IndexOf('<');
1209 loadName
= unoName
.Substring(0, index
);
1210 isPolymorphic
= true;
1213 result
= Type
.GetType(loadName
+ ",cli_uretypes");
1216 result
= Type
.GetType(loadName
+ ",cli_basetypes");
1219 result
= Type
.GetType(loadName
, false);
1223 foreach (Assembly a
in AppDomain
.CurrentDomain
.GetAssemblies())
1225 result
= a
.GetType(loadName
, false);
1232 // FIXME don't use generic Exception type
1233 throw new Exception("A type could not be loaded: " + loadName
);
1236 result
= uno
.PolymorphicType
.GetType(result
, unoName
);
1241 static TypeDescriptionReference
*MapManagedType(Type managedType
)
1243 TypeDescriptionReference
*result
= null;
1244 if (managedType
== null)
1246 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.VOID
);
1247 TypeDescriptionReference
.Acquire(result
);
1251 // check for Enum first,
1252 // because otherwise case System.TypeCode.Int32 applies
1253 if (managedType
.IsEnum
)
1255 UString
* unoTypeName
= MapManagedTypeName(managedType
.FullName
);
1256 TypeDescriptionReference
.New(&result
, TypeClass
.ENUM
, unoTypeName
);
1257 TypeDescriptionReference
.Acquire(result
);
1261 switch (System
.Type
.GetTypeCode(managedType
))
1263 case System
.TypeCode
.Boolean
:
1264 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.BOOLEAN
);
1265 TypeDescriptionReference
.Acquire(result
);
1267 case System
.TypeCode
.Char
:
1268 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.CHAR
);
1269 TypeDescriptionReference
.Acquire(result
);
1271 case System
.TypeCode
.Byte
:
1272 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.BYTE
);
1273 TypeDescriptionReference
.Acquire(result
);
1275 case System
.TypeCode
.Int16
:
1276 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.SHORT
);
1277 TypeDescriptionReference
.Acquire(result
);
1279 case System
.TypeCode
.Int32
:
1280 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.LONG
);
1281 TypeDescriptionReference
.Acquire(result
);
1283 case System
.TypeCode
.Int64
:
1284 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.HYPER
);
1285 TypeDescriptionReference
.Acquire(result
);
1287 case System
.TypeCode
.UInt16
:
1288 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.UNSIGNED_SHORT
);
1289 TypeDescriptionReference
.Acquire(result
);
1291 case System
.TypeCode
.UInt32
:
1292 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.UNSIGNED_LONG
);
1293 TypeDescriptionReference
.Acquire(result
);
1295 case System
.TypeCode
.UInt64
:
1296 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.UNSIGNED_HYPER
);
1297 TypeDescriptionReference
.Acquire(result
);
1299 case System
.TypeCode
.Single
:
1300 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.FLOAT
);
1301 TypeDescriptionReference
.Acquire(result
);
1303 case System
.TypeCode
.Double
:
1304 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.DOUBLE
);
1305 TypeDescriptionReference
.Acquire(result
);
1307 case System
.TypeCode
.String
:
1308 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.STRING
);
1309 TypeDescriptionReference
.Acquire(result
);
1316 string managedTypeName
= managedType
.FullName
;
1317 if (managedTypeName
== "System.Void")
1319 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.VOID
);
1320 TypeDescriptionReference
.Acquire(result
);
1322 else if (managedTypeName
== "System.Type")
1324 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.TYPE
);
1325 TypeDescriptionReference
.Acquire(result
);
1327 else if (managedTypeName
== "uno.Any")
1329 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.ANY
);
1330 TypeDescriptionReference
.Acquire(result
);
1334 UString
* unoTypeName
;
1336 uno
.PolymorphicType poly
= managedType
as uno
.PolymorphicType
;
1338 unoTypeName
= MapManagedTypeName(poly
.PolymorphicName
);
1340 unoTypeName
= MapManagedTypeName(managedTypeName
);
1342 TypeDescription
*td
= null;
1343 TypeDescription
.GetByName(&td
, unoTypeName
);
1346 result
= td
->pWeakRef
;
1347 TypeDescriptionReference
.Acquire(result
);
1348 TypeDescription
.Release(td
);
1355 // FIXME - quite probably we should throw an exception here instead.
1356 result
= *TypeDescriptionReference
.GetByTypeClass(TypeClass
.VOID
);
1357 TypeDescriptionReference
.Acquire(result
);
1363 static string MapUnoTypeName(string typeName
)
1365 StringBuilder buf
= new StringBuilder();
1367 // determine if the type is a sequence and its dimensions
1369 if (typeName
[0] == '[')
1374 if (typeName
[index
++] == ']')
1376 if (typeName
[index
++] != '[')
1379 typeName
= typeName
.Substring(index
- 1);
1385 buf
.Append("System.Boolean");
1388 buf
.Append("System.Char");
1391 buf
.Append("System.Byte");
1394 buf
.Append("System.Int16");
1396 case "unsigned short":
1397 buf
.Append("System.UInt16");
1400 buf
.Append("System.Int32");
1402 case "unsigned long":
1403 buf
.Append("System.UInt32");
1406 buf
.Append("System.Int64");
1408 case "unsigned hyper":
1409 buf
.Append("System.UInt64");
1412 buf
.Append("System.Single");
1415 buf
.Append("System.Double");
1418 buf
.Append("System.String");
1421 buf
.Append("System.Void");
1424 buf
.Append("System.Type");
1426 case "com.sun.star.uno.XInterface":
1427 buf
.Append("System.Object");
1430 buf
.Append("uno.Any");
1433 // put "unoidl." at the beginning
1434 buf
.Append("unoidl.");
1435 // for polymorphic struct types remove the brackets, e.g. mystruct<bool> -> mystruct
1436 buf
.Append(MapUnoPolymorphicName(typeName
));
1441 for ( ; dims
> 0; --dims
)
1444 return buf
.ToString();
1447 /** For example, there is a uno type
1448 com.sun.star.Foo<char, long>.
1449 The values in the type list
1450 are uno types and are replaced by cli types, such as System.Char,
1453 static string MapUnoPolymorphicName(string unoName
)
1455 int startIndex
= unoName
.LastIndexOf('<');
1456 if (startIndex
== -1)
1459 // get the type list within < and >
1460 int endIndex
= unoName
.LastIndexOf('>');
1461 string list
= unoName
.Substring(startIndex
+ 1, endIndex
- startIndex
- 1);
1463 // parse the type list and replace the types with the corresponding CLI types
1464 char[] delimiters
= new char[] { ',' }
;
1465 string[] unoTypes
= list
.Split(delimiters
);
1467 StringBuilder builder
= new StringBuilder(unoName
.Substring(0, startIndex
+ 1));
1469 int typeCount
= unoTypes
.Length
;
1470 for (int i
= 0; i
< typeCount
; ++i
)
1471 builder
.Append(MapUnoTypeName(unoTypes
[i
]));
1473 builder
.Append('>');
1474 return builder
.ToString();
1477 static UString
* MapManagedTypeName(string typeName
)
1482 if ((index
= typeName
.IndexOf("[]")) > 0)
1486 int curIndex
= index
;
1487 while ((curIndex
+ 2) < typeName
.Length
&&
1488 (curIndex
= typeName
.IndexOf("[]", curIndex
+ 2)) > 0)
1491 // get the element name by removing the brackets
1492 typeName
= typeName
.Substring(0, index
);
1495 StringBuilder buf
= new StringBuilder(256);
1496 for (; dims
> 0; --dims
)
1501 case "System.Boolean":
1502 buf
.Append("boolean");
1510 case "System.Int16":
1511 buf
.Append("short");
1513 case "System.UInt16":
1514 buf
.Append("unsigned short");
1516 case "System.Int32":
1519 case "System.UInt32":
1520 buf
.Append("unsigned long");
1522 case "System.Int64":
1523 buf
.Append("hyper");
1525 case "System.UInt64":
1526 buf
.Append("unsigned hyper");
1528 case "System.Single":
1529 buf
.Append("float");
1531 case "System.Double":
1532 buf
.Append("double");
1534 case "System.String":
1535 buf
.Append("string");
1543 case "System.Object":
1544 buf
.Append("com.sun.star.uno.XInterface");
1551 string name
= MapManagedPolymorphicName(typeName
);
1552 int i
= name
.IndexOf('.');
1553 buf
.Append(name
.Substring(i
+ 1));
1558 UString
*rtl_uString
= null;
1559 UString
.NewFromStringBuilder(&rtl_uString
, buf
);
1563 static string MapManagedPolymorphicName(string unoName
)
1565 int startIndex
= unoName
.LastIndexOf('<');
1566 if (startIndex
== -1)
1569 // get the type list withing < and >
1570 int endIndex
= unoName
.LastIndexOf('>');
1571 string list
= unoName
.Substring(startIndex
+ 1, endIndex
- startIndex
- 1);
1573 // parse the type list and replace the types with the corresponding CLI types
1574 char[] delimiters
= new char[] { ',' }
;
1575 string[] unoTypes
= list
.Split(delimiters
);
1577 StringBuilder builder
= new StringBuilder(unoName
.Substring(0, startIndex
+ 1));
1579 int typeCount
= unoTypes
.Length
;
1580 for (int i
= 0; i
< typeCount
; ++i
)
1581 builder
.Append(UString
.UStringToString(MapManagedTypeName(unoTypes
[i
])));
1582 builder
.Append('>');
1583 return builder
.ToString();
1586 [StructLayout(LayoutKind
.Explicit
)]
1587 private unsafe struct largest
1589 [FieldOffset(0)] long n
;
1590 [FieldOffset(0)] double d
;
1591 [FieldOffset(0)] void *p
;
1592 [FieldOffset(0)] uno
.Binary
.Any a
;
1595 // FIXME args[i] must be of same type as return value
1596 public unsafe uno
.Any
CallUno(IntPtr unoInterface
, TypeDescription
*memberTD
,
1597 TypeDescriptionReference
*returnType
, int nParams
,
1598 MethodParameter
*parameters
, object[] args
,
1599 Type
[] argTypes
, out uno
.Any exception
)
1601 int returnSize
= sizeof(largest
);
1603 if (returnType
!= null &&
1604 (returnType
->eTypeClass
== TypeClass
.STRUCT
||
1605 returnType
->eTypeClass
== TypeClass
.EXCEPTION
))
1608 TypeDescription
*td
= null;
1609 TypeDescriptionReference
.GetDescription(&td
, returnType
);
1611 if (td
->nSize
> returnSize
)
1612 returnSize
= td
->nSize
;
1615 // Prepare memory that contains all converted arguments and
1616 // return values. The memory block contains first pointers to
1617 // the arguments which are in the same block For example, 2
1618 // arguments, 1 ret.
1626 // If an argument is larger then struct largest, such as some
1627 // structures, then the pointer points to an extra block of
1628 // memory. The same goes for a big return value.
1629 // FIXME the last sentence is bullshit. Get it deleted from cli_uno ;)
1630 byte *mem
= stackalloc byte[nParams
* sizeof(void *) +
1632 nParams
* sizeof(largest
)];
1634 // array of pointers to args
1635 void **unoArgPtrs
= (void **)mem
;
1638 void *unoRetPtr
= null;
1639 largest
*unoArgs
= (largest
*)(unoArgPtrs
+ nParams
);
1640 if (memberTD
->eTypeClass
!= TypeClass
.INTERFACE_ATTRIBUTE
|| nParams
!= 1)
1642 // If an attribute is set, then unoRet must be null, e.g. void setAttribute(int)
1643 unoRetPtr
= (void *)unoArgs
;
1644 unoArgs
= (largest
*)((byte *)unoRetPtr
+ returnSize
);
1647 for (int i
= 0; i
< nParams
; ++i
)
1649 TypeDescriptionReference
*typeref
= (TypeDescriptionReference
*)parameters
[i
].pTypeRef
;
1650 TypeDescription
*type
= null;
1651 TypeDescriptionReference
.GetDescription(&type
, typeref
);
1652 unoArgPtrs
[i
] = unoArgs
+ i
;
1653 if ((type
->eTypeClass
== TypeClass
.STRUCT
||
1654 type
->eTypeClass
== TypeClass
.EXCEPTION
) &&
1655 (type
->nSize
> sizeof(largest
)))
1657 // stackalloc is only allowed in initializers
1658 byte *bigArgPtr
= stackalloc byte[type
->nSize
];
1660 unoArgPtrs
[i
] = bigArgPtr
;
1663 if (parameters
[i
].bIn
!= 0)
1665 // FIXME error handling
1666 MapToUno(unoArgPtrs
[i
], args
[i
], (TypeDescription
*)typeref
, false /* no assign */);
1670 uno
.Binary
.Any unoExceptionHolder
;
1671 uno
.Binary
.Any
*unoExc
= &unoExceptionHolder
;
1674 uno
.Binary
.Interface
.Dispatch(
1675 unoInterface
, memberTD
, unoRetPtr
, unoArgPtrs
, &unoExc
);
1679 exception
= uno
.Any
.VOID
;
1681 // convert out args, destroy uno args
1682 for (int i
= 0; i
< nParams
; ++i
)
1684 // FIXME it's a TypeDescriptionReference
1685 TypeDescription
*type
= (TypeDescription
*)parameters
[i
].pTypeRef
;
1687 if (parameters
[i
].bOut
!= 0)
1689 // FIXME error handling
1690 MapToManaged(ref args
[i
], unoArgPtrs
[i
], parameters
[i
].pTypeRef
,
1691 argTypes
!= null ? argTypes
[i
] : null, false);
1695 if (type
->eTypeClass
< TypeClass
.DOUBLE
&&
1696 type
->eTypeClass
!= TypeClass
.ENUM
) // no need to destroy these
1697 uno
.Binary
.Data
.Destroy(unoArgPtrs
[i
], type
, null);
1700 if (returnType
!= null && returnType
->eTypeClass
!= TypeClass
.VOID
)
1702 // convert uno return value
1703 object result
= null;
1704 // FIXME error handling
1705 MapToManaged(ref result
, unoRetPtr
, returnType
, null, false);
1706 uno
.Binary
.Data
.Destroy(unoRetPtr
, (TypeDescription
*)returnType
, null);
1707 return new uno
.Any(MapUnoType(returnType
), result
); // FIXME is this correct?
1710 return uno
.Any
.VOID
;
1712 else // exception occured
1714 for (int i
= 0; i
< nParams
; ++i
)
1715 if (parameters
[i
].bIn
!= 0)
1716 uno
.Binary
.Data
.Destroy(unoArgPtrs
[i
], (TypeDescription
*)parameters
[i
].pTypeRef
, null);
1718 // FIXME needs uno.Any vs System.Object clarification
1720 MapToManaged(ref exc
, unoExceptionHolder
.pData
,
1721 unoExceptionHolder
.pType
, null, false);
1722 exception
= new uno
.Any(MapUnoType(unoExceptionHolder
.pType
), exc
);
1723 return uno
.Any
.VOID
;
1726 // FIXME error handling
1729 // FIXME rename, to say what it does, not how it does this
1730 public void RegisterWithCliEnvironment(object managedI
, string oid
)
1732 managedEnvironment
.registerInterface(managedI
, oid
);
1735 public void RegisterWithCliEnvironment(object managedI
, string oid
, Type type
)
1737 managedEnvironment
.registerInterface(managedI
, oid
, type
);
1740 public void RegisterWithUnoEnvironment(ref IntPtr unoInterface
, string oid
, InterfaceTypeDescription
*TD
)
1742 UString
*unoOid
= null;
1743 UString
.NewFromString(&unoOid
, oid
);
1745 uno
.Binary
.Environment
.RegisterInterface(unoEnvironment
, ref unoInterface
, unoOid
, TD
);
1747 UString
.Release(unoOid
);
1750 public void GetInterfaceFromUnoEnvironment(ref IntPtr unoInterface
, UString
* unoOid
, InterfaceTypeDescription
* TD
)
1752 uno
.Binary
.Environment
.GetRegisteredInterface(unoEnvironment
, ref unoInterface
, unoOid
, TD
);
1755 public void RevokeFromUnoEnvironment(IntPtr unoInterface
)
1757 throw new NotImplementedException();
1760 public unsafe IntPtr
CreateManagedProxy(object managedInterface
,
1761 TypeDescription
* td
,
1764 // register original interface
1765 RegisterWithCliEnvironment(managedInterface
,
1766 UString
.UStringToString(oid
),
1767 Bridge
.MapUnoType(td
));
1769 ManagedProxy proxy
= new ManagedProxy(this, managedInterface
, td
, oid
);
1770 GCHandle gchandle
= GCHandle
.Alloc(proxy
);
1772 // create binary uno uno_Interface and register proxy with target environment
1773 IntPtr unoI
= CreateBinaryProxyAndRegister(unoEnvironment
, (IntPtr
)gchandle
,
1776 proxy
.NativeProxy
= unoI
;
1780 [ DllImport("cli_uno", EntryPoint
="cli_uno_environment_createMonoProxyAndRegister") ]
1781 public static unsafe extern IntPtr
CreateBinaryProxyAndRegister(
1782 IntPtr unoEnvironment
,
1784 /* UString */ void* oid
,
1785 /* InterfaceTypeDescription */ void* td
);
1787 public unsafe void CallManaged(object managedI
, Type ifaceType
, MethodInfo method
,
1788 TypeDescriptionReference
* returnType
,
1789 MethodParameter
* parameters
, int nParams
, void* unoRet
,
1790 void** unoArgs
, uno
.Binary
.Any
** unoExc
)
1792 object[] args
= new object[nParams
];
1793 for (int i
= 0; i
< nParams
; ++i
)
1794 if (parameters
[i
].bIn
!= 0)
1795 MapToManaged(ref args
[i
], unoArgs
[i
], parameters
[i
].pTypeRef
, null, false);
1797 object invocationResult
= null;
1798 Exception exc
= null;
1801 invocationResult
= method
.Invoke(managedI
, args
);
1803 catch (TargetInvocationException e
)
1805 exc
= e
.InnerException
;
1813 if ( !( exc
is unoidl
.com
.sun
.star
.uno
.Exception
) )
1815 // #FIXME put more info in here trace, stack etc. ( when I
1816 // figure out how to do that in mono )
1817 exc
= new unoidl
.com
.sun
.star
.uno
.RuntimeException( exc
.ToString(), null );
1819 TypeDescription
* td
= null;
1821 TypeDescriptionReference
.GetDescription(&td
, MapManagedType(exc
.GetType()));
1822 void* memExc
= uno
.rtl
.Mem
.Allocate(td
->nSize
);
1823 MapToUno(memExc
, exc
, /* FIXME !!!*/ (TypeDescription
*)td
->pWeakRef
, false);
1824 (*unoExc
)->pType
= td
->pWeakRef
;
1825 (*unoExc
)->pData
= memExc
;
1828 // convert out, in/out params
1829 for (int i
= 0; i
< nParams
; ++i
)
1831 if (parameters
[i
].bOut
!= 0)
1834 unoArgs
[i
], args
[i
], /* FIXME !!! */(TypeDescription
*)parameters
[i
].pTypeRef
,
1835 parameters
[i
].bIn
!= 0 /* assign if inout */);
1836 // FIXME error handling
1841 if (returnType
!= null)
1842 MapToUno(unoRet
, invocationResult
, /* FIXME !!! */(TypeDescription
*)returnType
, false /* no assign */);
1844 // no exception occurred