summaryrefslogtreecommitdiff
path: root/bridges
diff options
context:
space:
mode:
Diffstat (limited to 'bridges')
-rw-r--r--bridges/inc/bridges/cpp_uno/bridge.hxx504
-rw-r--r--bridges/inc/bridges/cpp_uno/shared/arraypointer.hxx58
-rw-r--r--bridges/inc/bridges/cpp_uno/shared/bridge.hxx131
-rw-r--r--bridges/inc/bridges/cpp_uno/shared/cppinterfaceproxy.hxx109
-rw-r--r--bridges/inc/bridges/cpp_uno/shared/types.hxx80
-rw-r--r--bridges/inc/bridges/cpp_uno/shared/unointerfaceproxy.hxx119
-rw-r--r--bridges/inc/bridges/cpp_uno/shared/vtablefactory.hxx218
-rw-r--r--bridges/inc/bridges/cpp_uno/shared/vtables.hxx111
-rw-r--r--bridges/inc/bridges/cpp_uno/type_misc.hxx132
-rw-r--r--bridges/inc/bridges/remote/bridgeimpl.hxx97
-rw-r--r--bridges/inc/bridges/remote/connection.h70
-rw-r--r--bridges/inc/bridges/remote/context.h262
-rw-r--r--bridges/inc/bridges/remote/counter.hxx60
-rw-r--r--bridges/inc/bridges/remote/helper.hxx71
-rw-r--r--bridges/inc/bridges/remote/mapping.hxx72
-rw-r--r--bridges/inc/bridges/remote/proxy.hxx94
-rw-r--r--bridges/inc/bridges/remote/remote.h96
-rw-r--r--bridges/inc/bridges/remote/remote.hxx76
-rw-r--r--bridges/inc/bridges/remote/stub.hxx67
-rw-r--r--bridges/inc/makefile.mk47
-rw-r--r--bridges/inc/pch/precompiled_bridges.cxx31
-rw-r--r--bridges/inc/pch/precompiled_bridges.hxx155
-rw-r--r--bridges/prj/build.lst34
-rw-r--r--bridges/prj/d.lst28
-rw-r--r--bridges/source/bridge_exports.map8
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_intel/call.s248
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_intel/cc50_solaris_intel.hxx75
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_intel/cpp2uno.cxx530
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_intel/except.cxx451
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_intel/hash.cxx264
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_intel/makefile.mk75
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_intel/uno2cpp.cxx421
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_sparc/call.s199
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_sparc/cc50_solaris_sparc.hxx89
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_sparc/cpp2uno.cxx533
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx447
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_sparc/flushcode.hxx51
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_sparc/hash.cxx265
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_sparc/makefile.mk80
-rw-r--r--bridges/source/cpp_uno/cc50_solaris_sparc/uno2cpp.cxx399
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/callvirtualmethod.hxx39
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/callvirtualmethod.s59
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/cpp2uno.cxx614
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.cxx462
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.hxx75
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/flushcode.hxx51
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/fp.hxx116
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/fp.s602
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/isdirectreturntype.cxx84
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/isdirectreturntype.hxx44
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/makefile.mk61
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/uno2cpp.cxx512
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/vtableslotcall.hxx38
-rw-r--r--bridges/source/cpp_uno/cc5_solaris_sparc64/vtableslotcall.s51
-rw-r--r--bridges/source/cpp_uno/gcc3_aix_powerpc/cpp2uno.cxx663
-rw-r--r--bridges/source/cpp_uno/gcc3_aix_powerpc/except.cxx291
-rw-r--r--bridges/source/cpp_uno/gcc3_aix_powerpc/makefile.mk81
-rw-r--r--bridges/source/cpp_uno/gcc3_aix_powerpc/share.hxx102
-rw-r--r--bridges/source/cpp_uno/gcc3_aix_powerpc/uno2cpp.cxx502
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_alpha/cpp2uno.cxx677
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_alpha/except.cxx289
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_alpha/makefile.mk77
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_alpha/share.hxx99
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_alpha/uno2cpp.cxx534
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_arm/armhelper.S38
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_arm/cpp2uno.cxx551
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_arm/except.cxx342
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_arm/makefile.mk84
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_arm/share.hxx102
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_arm/uno2cpp.cxx670
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_hppa/call.cxx143
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_hppa/cpp2uno.cxx726
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_hppa/except.cxx335
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_hppa/makefile.mk82
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_hppa/share.hxx102
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_hppa/uno2cpp.cxx522
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_ia64/call.s20
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_ia64/cpp2uno.cxx685
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_ia64/except.cxx289
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_ia64/makefile.mk83
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_ia64/share.hxx132
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_ia64/uno2cpp.cxx692
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_intel/call.s274
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx527
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_intel/except.cxx340
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_intel/makefile.mk84
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_intel/share.hxx99
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx507
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_m68k/cpp2uno.cxx537
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_m68k/except.cxx335
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_m68k/makefile.mk80
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_m68k/share.hxx94
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_m68k/uno2cpp.cxx494
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_mips/cpp2uno.cxx805
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_mips/except.cxx327
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_mips/makefile.mk81
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_mips/share.hxx94
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_mips/uno2cpp.cxx599
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc/cpp2uno.cxx795
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc/except.cxx289
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc/makefile.mk80
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc/share.hxx94
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc/uno2cpp.cxx675
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx723
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc64/except.cxx289
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc64/makefile.mk79
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx99
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx603
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390/cpp2uno.cxx696
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390/except.cxx289
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390/makefile.mk77
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390/share.hxx94
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390/uno2cpp.cxx637
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390x/cpp2uno.cxx658
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390x/except.cxx289
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390x/makefile.mk77
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390x/share.hxx99
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_s390x/uno2cpp.cxx539
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_sparc/call.s10
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_sparc/cpp2uno.cxx578
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_sparc/except.cxx330
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_sparc/makefile.mk85
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_sparc/share.hxx100
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_sparc/uno2cpp.cxx603
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx350
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx70
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/call.s96
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx523
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx340
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/makefile.mk83
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx93
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx574
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_intel/call.s327
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_intel/cpp2uno.cxx522
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_intel/except.cxx331
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_intel/makefile.mk76
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_intel/share.hxx95
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_intel/uno2cpp.cxx496
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_powerpc/cpp2uno.cxx732
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_powerpc/except.cxx288
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_powerpc/makefile.mk78
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_powerpc/share.hxx94
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_powerpc/uno2cpp.cxx637
-rw-r--r--bridges/source/cpp_uno/gcc3_os2_intel/cpp2uno.cxx528
-rw-r--r--bridges/source/cpp_uno/gcc3_os2_intel/defs/gcc3_uno.def915
-rw-r--r--bridges/source/cpp_uno/gcc3_os2_intel/except.cxx351
-rw-r--r--bridges/source/cpp_uno/gcc3_os2_intel/makefile.mk73
-rw-r--r--bridges/source/cpp_uno/gcc3_os2_intel/share.hxx93
-rw-r--r--bridges/source/cpp_uno/gcc3_os2_intel/uno2cpp.cxx454
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_intel/cpp2uno.cxx526
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_intel/except.cxx331
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_intel/makefile.mk73
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_intel/share.hxx93
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_intel/uno2cpp.cxx430
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_sparc/cpp2uno.cxx567
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_sparc/except.cxx329
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_sparc/makefile.mk77
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_sparc/share.hxx100
-rw-r--r--bridges/source/cpp_uno/gcc3_solaris_sparc/uno2cpp.cxx598
-rw-r--r--bridges/source/cpp_uno/mingw_intel/call.s261
-rw-r--r--bridges/source/cpp_uno/mingw_intel/cpp2uno.cxx521
-rw-r--r--bridges/source/cpp_uno/mingw_intel/dllinit.cxx59
-rw-r--r--bridges/source/cpp_uno/mingw_intel/except.cxx316
-rw-r--r--bridges/source/cpp_uno/mingw_intel/makefile.mk91
-rw-r--r--bridges/source/cpp_uno/mingw_intel/share.hxx93
-rw-r--r--bridges/source/cpp_uno/mingw_intel/smallstruct.cxx82
-rw-r--r--bridges/source/cpp_uno/mingw_intel/smallstruct.hxx38
-rw-r--r--bridges/source/cpp_uno/mingw_intel/uno2cpp.cxx503
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx491
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/dllinit.cxx61
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/except.cxx634
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/makefile.mk83
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/msci.hxx59
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx468
-rw-r--r--bridges/source/cpp_uno/shared/bridge.cxx229
-rw-r--r--bridges/source/cpp_uno/shared/component.cxx275
-rw-r--r--bridges/source/cpp_uno/shared/component.hxx42
-rw-r--r--bridges/source/cpp_uno/shared/cppinterfaceproxy.cxx208
-rw-r--r--bridges/source/cpp_uno/shared/guardedarray.hxx55
-rw-r--r--bridges/source/cpp_uno/shared/makefile.mk53
-rw-r--r--bridges/source/cpp_uno/shared/types.cxx129
-rw-r--r--bridges/source/cpp_uno/shared/unointerfaceproxy.cxx145
-rw-r--r--bridges/source/cpp_uno/shared/vtablefactory.cxx385
-rw-r--r--bridges/source/cpp_uno/shared/vtables.cxx157
-rw-r--r--bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_info_holder.java52
-rw-r--r--bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_proxy.java218
-rw-r--r--bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/makefile.mk53
-rw-r--r--bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/manifest1
-rw-r--r--bridges/source/jni_uno/java_uno.map27
-rw-r--r--bridges/source/jni_uno/jni_base.h295
-rw-r--r--bridges/source/jni_uno/jni_bridge.cxx572
-rw-r--r--bridges/source/jni_uno/jni_bridge.h127
-rw-r--r--bridges/source/jni_uno/jni_data.cxx2579
-rw-r--r--bridges/source/jni_uno/jni_helper.h165
-rw-r--r--bridges/source/jni_uno/jni_info.cxx999
-rw-r--r--bridges/source/jni_uno/jni_info.h378
-rw-r--r--bridges/source/jni_uno/jni_java2uno.cxx706
-rw-r--r--bridges/source/jni_uno/jni_uno2java.cxx876
-rw-r--r--bridges/source/jni_uno/makefile.mk85
-rw-r--r--bridges/source/jni_uno/nativethreadpool.cxx233
-rw-r--r--bridges/source/remote/context/context.cxx487
-rw-r--r--bridges/source/remote/context/exports.dxp5
-rw-r--r--bridges/source/remote/context/makefile.mk65
-rwxr-xr-xbridges/source/remote/context/rmcxt.map10
-rw-r--r--bridges/source/remote/idl/corba.idl88
-rw-r--r--bridges/source/remote/static/helper.cxx212
-rw-r--r--bridges/source/remote/static/makefile.mk61
-rw-r--r--bridges/source/remote/static/mapping.cxx221
-rw-r--r--bridges/source/remote/static/proxy.cxx341
-rw-r--r--bridges/source/remote/static/remote.cxx164
-rw-r--r--bridges/source/remote/static/remote_types.cxx99
-rw-r--r--bridges/source/remote/static/remote_types.hxx92
-rw-r--r--bridges/source/remote/static/stub.cxx339
-rw-r--r--bridges/source/remote/urp/makefile.mk78
-rw-r--r--bridges/source/remote/urp/urp_bridgeimpl.cxx253
-rw-r--r--bridges/source/remote/urp/urp_bridgeimpl.hxx130
-rw-r--r--bridges/source/remote/urp/urp_cache.h60
-rw-r--r--bridges/source/remote/urp/urp_cache.hxx163
-rw-r--r--bridges/source/remote/urp/urp_dispatch.cxx118
-rw-r--r--bridges/source/remote/urp/urp_dispatch.hxx80
-rw-r--r--bridges/source/remote/urp/urp_environment.cxx554
-rw-r--r--bridges/source/remote/urp/urp_job.cxx941
-rw-r--r--bridges/source/remote/urp/urp_job.hxx381
-rw-r--r--bridges/source/remote/urp/urp_log.cxx150
-rw-r--r--bridges/source/remote/urp/urp_log.hxx53
-rw-r--r--bridges/source/remote/urp/urp_marshal.cxx238
-rw-r--r--bridges/source/remote/urp/urp_marshal.hxx345
-rw-r--r--bridges/source/remote/urp/urp_marshal_decl.hxx109
-rw-r--r--bridges/source/remote/urp/urp_property.hxx94
-rw-r--r--bridges/source/remote/urp/urp_propertyobject.cxx796
-rw-r--r--bridges/source/remote/urp/urp_propertyobject.hxx107
-rw-r--r--bridges/source/remote/urp/urp_reader.cxx835
-rw-r--r--bridges/source/remote/urp/urp_reader.hxx81
-rw-r--r--bridges/source/remote/urp/urp_replycontainer.hxx78
-rw-r--r--bridges/source/remote/urp/urp_threadid.cxx51
-rw-r--r--bridges/source/remote/urp/urp_threadid.hxx62
-rw-r--r--bridges/source/remote/urp/urp_unmarshal.cxx709
-rw-r--r--bridges/source/remote/urp/urp_unmarshal.hxx281
-rw-r--r--bridges/source/remote/urp/urp_writer.cxx271
-rw-r--r--bridges/source/remote/urp/urp_writer.hxx85
-rw-r--r--bridges/test/com/sun/star/lib/TestBed.java232
-rw-r--r--bridges/test/com/sun/star/lib/makefile.mk36
-rw-r--r--bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug107753_Test.java394
-rw-r--r--bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug108825_Test.java163
-rw-r--r--bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug110892_Test.java124
-rw-r--r--bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug111153_Test.java103
-rw-r--r--bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug114133_Test.java76
-rw-r--r--bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug51323_Test.java84
-rw-r--r--bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug92174_Test.java99
-rw-r--r--bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug97697_Test.java105
-rw-r--r--bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug98508_Test.idl37
-rw-r--r--bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug98508_Test.java104
-rwxr-xr-xbridges/test/com/sun/star/lib/uno/bridges/java_remote/MethodIdTest.java473
-rw-r--r--bridges/test/com/sun/star/lib/uno/bridges/java_remote/PolyStructTest.idl52
-rw-r--r--bridges/test/com/sun/star/lib/uno/bridges/java_remote/PolyStructTest.java260
-rw-r--r--bridges/test/com/sun/star/lib/uno/bridges/java_remote/StopMessageDispatcherTest.java108
-rw-r--r--bridges/test/com/sun/star/lib/uno/bridges/java_remote/makefile.mk51
-rw-r--r--bridges/test/inter_libs_exc/inter.cxx69
-rw-r--r--bridges/test/inter_libs_exc/makefile.mk80
-rw-r--r--bridges/test/inter_libs_exc/share.h10
-rw-r--r--bridges/test/inter_libs_exc/starter.cxx68
-rw-r--r--bridges/test/inter_libs_exc/starter.map7
-rw-r--r--bridges/test/inter_libs_exc/thrower.cxx51
-rw-r--r--bridges/test/inter_libs_exc/thrower.map7
-rw-r--r--bridges/test/java_uno/acquire/TestAcquire.java304
-rw-r--r--bridges/test/java_uno/acquire/makefile.mk117
-rw-r--r--bridges/test/java_uno/acquire/readme.txt21
-rw-r--r--bridges/test/java_uno/acquire/testacquire.cxx577
-rw-r--r--bridges/test/java_uno/acquire/types.idl68
-rw-r--r--bridges/test/java_uno/any/TestAny.java2267
-rw-r--r--bridges/test/java_uno/any/TestJni.java48
-rw-r--r--bridges/test/java_uno/any/TestRemote.java64
-rw-r--r--bridges/test/java_uno/any/makefile.mk127
-rw-r--r--bridges/test/java_uno/any/test_javauno_any.map6
-rw-r--r--bridges/test/java_uno/any/transport.cxx111
-rw-r--r--bridges/test/java_uno/any/types.idl42
-rw-r--r--bridges/test/java_uno/equals/TestEquals.java1304
-rw-r--r--bridges/test/java_uno/equals/makefile.mk96
-rw-r--r--bridges/test/java_uno/equals/testequals.cxx235
-rw-r--r--bridges/test/java_uno/equals/types.idl47
-rw-r--r--bridges/test/java_uno/nativethreadpool/Relay.java125
-rw-r--r--bridges/test/java_uno/nativethreadpool/makefile.mk121
-rw-r--r--bridges/test/java_uno/nativethreadpool/readme39
-rw-r--r--bridges/test/java_uno/nativethreadpool/relay.manifest2
-rw-r--r--bridges/test/java_uno/nativethreadpool/testnativethreadpoolclient.cxx187
-rw-r--r--bridges/test/java_uno/nativethreadpool/testnativethreadpoolserver.cxx149
-rw-r--r--bridges/test/java_uno/nativethreadpool/types.idl40
-rw-r--r--bridges/test/java_uno/nativethreadpool/version.map35
-rw-r--r--bridges/test/makefile.mk175
-rw-r--r--bridges/test/performance/makefile.mk61
-rw-r--r--bridges/test/performance/testperformance.cxx193
-rw-r--r--bridges/test/test_bridge.idl82
-rw-r--r--bridges/test/testclient.cxx249
-rw-r--r--bridges/test/testclient.java156
-rw-r--r--bridges/test/testcomp.cxx801
-rw-r--r--bridges/test/testcomp.h157
-rw-r--r--bridges/test/testoffice.cxx282
-rw-r--r--bridges/test/testsameprocess.cxx218
-rw-r--r--bridges/test/testserver.cxx256
-rw-r--r--bridges/unotypes/makefile.mk63
-rw-r--r--bridges/version.mk40
301 files changed, 77834 insertions, 0 deletions
diff --git a/bridges/inc/bridges/cpp_uno/bridge.hxx b/bridges/inc/bridges/cpp_uno/bridge.hxx
new file mode 100644
index 000000000000..b5dfd5d28168
--- /dev/null
+++ b/bridges/inc/bridges/cpp_uno/bridge.hxx
@@ -0,0 +1,504 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+#ifndef _BRIDGES_CPP_UNO_BRIDGE_HXX_
+#define _BRIDGES_CPP_UNO_BRIDGE_HXX_
+
+#include <bridges/cpp_uno/bridge.h>
+#include <osl/mutex.hxx>
+#include <rtl/process.h>
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/uno/genfunc.hxx>
+#include <com/sun/star/uno/XInterface.hpp>
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+//--------------------------------------------------------------------------------------------------
+inline void SAL_CALL cppu_cppInterfaceProxy_free( uno_ExtEnvironment * pEnv, void * pProxy ) SAL_THROW( () )
+{
+ cppu_cppInterfaceProxy * pThis =
+ static_cast< cppu_cppInterfaceProxy * >(
+ reinterpret_cast< ::com::sun::star::uno::XInterface * >( pProxy ) );
+ OSL_ASSERT( pEnv == pThis->pBridge->pCppEnv );
+
+ (*pThis->pBridge->pUnoEnv->revokeInterface)( pThis->pBridge->pUnoEnv, pThis->pUnoI );
+ (*pThis->pUnoI->release)( pThis->pUnoI );
+ ::typelib_typedescription_release( (typelib_TypeDescription *)pThis->pTypeDescr );
+ pThis->pBridge->release();
+
+#if OSL_DEBUG_LEVEL > 1
+ *(int *)pProxy = 0xdeadbabe;
+#endif
+ delete pThis;
+}
+//--------------------------------------------------------------------------------------------------
+inline void SAL_CALL cppu_Mapping_uno2cpp(
+ uno_Mapping * pMapping, void ** ppCppI,
+ void * pUnoI, typelib_InterfaceTypeDescription * pTypeDescr ) SAL_THROW( () )
+{
+ OSL_ASSERT( ppCppI && pTypeDescr );
+ if (*ppCppI)
+ {
+ reinterpret_cast< ::com::sun::star::uno::XInterface * >( *ppCppI )->release();
+ *ppCppI = 0;
+ }
+ if (pUnoI)
+ {
+ cppu_Bridge * pBridge = static_cast< cppu_Mapping * >( pMapping )->pBridge;
+
+ // get object id of uno interface to be wrapped
+ rtl_uString * pOId = 0;
+ (*pBridge->pUnoEnv->getObjectIdentifier)( pBridge->pUnoEnv, &pOId, pUnoI );
+ OSL_ASSERT( pOId );
+
+ // try to get any known interface from target environment
+ (*pBridge->pCppEnv->getRegisteredInterface)(
+ pBridge->pCppEnv, ppCppI, pOId, pTypeDescr );
+
+ if (! *ppCppI) // no existing interface, register new proxy interface
+ {
+ // try to publish a new proxy (ref count initially 1)
+ cppu_cppInterfaceProxy * pProxy = new cppu_cppInterfaceProxy(
+ pBridge, reinterpret_cast< uno_Interface * >( pUnoI ), pTypeDescr, pOId );
+ ::com::sun::star::uno::XInterface * pSurrogate = pProxy;
+ cppu_cppInterfaceProxy_patchVtable( pSurrogate, pProxy->pTypeDescr );
+
+ // proxy may be exchanged during registration
+ (*pBridge->pCppEnv->registerProxyInterface)(
+ pBridge->pCppEnv, reinterpret_cast< void ** >( &pSurrogate ),
+ (uno_freeProxyFunc)cppu_cppInterfaceProxy_free, pOId, pTypeDescr );
+
+ *ppCppI = pSurrogate;
+ }
+ ::rtl_uString_release( pOId );
+ }
+}
+//__________________________________________________________________________________________________
+inline void cppu_cppInterfaceProxy::acquireProxy() SAL_THROW( () )
+{
+ if (1 == osl_incrementInterlockedCount( &nRef ))
+ {
+ // rebirth of proxy zombie
+ // register at cpp env
+ void * pThis = static_cast< ::com::sun::star::uno::XInterface * >( this );
+ (*pBridge->pCppEnv->registerProxyInterface)(
+ pBridge->pCppEnv, &pThis, (uno_freeProxyFunc)cppu_cppInterfaceProxy_free,
+ oid.pData, pTypeDescr );
+ OSL_ASSERT( pThis == static_cast< ::com::sun::star::uno::XInterface * >( this ) );
+ }
+}
+//__________________________________________________________________________________________________
+inline void cppu_cppInterfaceProxy::releaseProxy() SAL_THROW( () )
+{
+ if (! osl_decrementInterlockedCount( &nRef )) // last release
+ {
+ // revoke from cpp env
+ (*pBridge->pCppEnv->revokeInterface)(
+ pBridge->pCppEnv, static_cast< ::com::sun::star::uno::XInterface * >( this ) );
+ }
+}
+//__________________________________________________________________________________________________
+inline cppu_cppInterfaceProxy::cppu_cppInterfaceProxy(
+ cppu_Bridge * pBridge_, uno_Interface * pUnoI_,
+ typelib_InterfaceTypeDescription * pTypeDescr_, const ::rtl::OUString & rOId_ ) SAL_THROW( () )
+ : nRef( 1 )
+ , pBridge( pBridge_ )
+ , pUnoI( pUnoI_ )
+ , pTypeDescr( pTypeDescr_ )
+ , oid( rOId_ )
+{
+ pBridge->acquire();
+ ::typelib_typedescription_acquire( (typelib_TypeDescription *)pTypeDescr );
+ if (! ((typelib_TypeDescription *)pTypeDescr)->bComplete)
+ ::typelib_typedescription_complete( (typelib_TypeDescription **)&pTypeDescr );
+ OSL_ENSURE( ((typelib_TypeDescription *)pTypeDescr)->bComplete, "### type is incomplete!" );
+ (*pUnoI->acquire)( pUnoI );
+ (*pBridge->pUnoEnv->registerInterface)(
+ pBridge->pUnoEnv, reinterpret_cast< void ** >( &pUnoI ), oid.pData, pTypeDescr );
+}
+
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+
+//--------------------------------------------------------------------------------------------------
+inline void SAL_CALL cppu_unoInterfaceProxy_free( uno_ExtEnvironment * pEnv, void * pProxy ) SAL_THROW( () )
+{
+ cppu_unoInterfaceProxy * pThis =
+ static_cast< cppu_unoInterfaceProxy * >(
+ reinterpret_cast< uno_Interface * >( pProxy ) );
+ OSL_ASSERT( pEnv == pThis->pBridge->pUnoEnv );
+
+ (*pThis->pBridge->pCppEnv->revokeInterface)( pThis->pBridge->pCppEnv, pThis->pCppI );
+ pThis->pCppI->release();
+ ::typelib_typedescription_release( (typelib_TypeDescription *)pThis->pTypeDescr );
+ pThis->pBridge->release();
+
+#if OSL_DEBUG_LEVEL > 1
+ *(int *)pProxy = 0xdeadbabe;
+#endif
+ delete pThis;
+}
+//--------------------------------------------------------------------------------------------------
+inline void SAL_CALL cppu_unoInterfaceProxy_acquire( uno_Interface * pUnoI ) SAL_THROW( () )
+{
+ if (1 == osl_incrementInterlockedCount( & static_cast< cppu_unoInterfaceProxy * >( pUnoI )->nRef ))
+ {
+ // rebirth of proxy zombie
+ // register at uno env
+#if OSL_DEBUG_LEVEL > 1
+ void * pThis = pUnoI;
+#endif
+ (*static_cast< cppu_unoInterfaceProxy * >( pUnoI )->pBridge->pUnoEnv->registerProxyInterface)(
+ static_cast< cppu_unoInterfaceProxy * >( pUnoI )->pBridge->pUnoEnv,
+ reinterpret_cast< void ** >( &pUnoI ),
+ (uno_freeProxyFunc)cppu_unoInterfaceProxy_free,
+ static_cast< cppu_unoInterfaceProxy * >( pUnoI )->oid.pData,
+ static_cast< cppu_unoInterfaceProxy * >( pUnoI )->pTypeDescr );
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ASSERT( pThis == pUnoI );
+#endif
+ }
+}
+//--------------------------------------------------------------------------------------------------
+inline void SAL_CALL cppu_unoInterfaceProxy_release( uno_Interface * pUnoI ) SAL_THROW( () )
+{
+ if (! osl_decrementInterlockedCount( & static_cast< cppu_unoInterfaceProxy * >( pUnoI )->nRef ))
+ {
+ // revoke from uno env on last release
+ (*static_cast< cppu_unoInterfaceProxy * >( pUnoI )->pBridge->pUnoEnv->revokeInterface)(
+ static_cast< cppu_unoInterfaceProxy * >( pUnoI )->pBridge->pUnoEnv, pUnoI );
+ }
+}
+//--------------------------------------------------------------------------------------------------
+inline void SAL_CALL cppu_Mapping_cpp2uno(
+ uno_Mapping * pMapping, void ** ppUnoI,
+ void * pCppI, typelib_InterfaceTypeDescription * pTypeDescr ) SAL_THROW( () )
+{
+ OSL_ENSURE( ppUnoI && pTypeDescr, "### null ptr!" );
+ if (*ppUnoI)
+ {
+ (*reinterpret_cast< uno_Interface * >( *ppUnoI )->release)(
+ reinterpret_cast< uno_Interface * >( *ppUnoI ) );
+ *ppUnoI = 0;
+ }
+ if (pCppI)
+ {
+ cppu_Bridge * pBridge = static_cast< cppu_Mapping * >( pMapping )->pBridge;
+
+ // get object id of interface to be wrapped
+ rtl_uString * pOId = 0;
+ (*pBridge->pCppEnv->getObjectIdentifier)( pBridge->pCppEnv, &pOId, pCppI );
+ OSL_ASSERT( pOId );
+
+ // try to get any known interface from target environment
+ (*pBridge->pUnoEnv->getRegisteredInterface)(
+ pBridge->pUnoEnv, ppUnoI, pOId, pTypeDescr );
+
+ if (! *ppUnoI) // no existing interface, register new proxy interface
+ {
+ // try to publish a new proxy (refcount initially 1)
+ uno_Interface * pSurrogate = new cppu_unoInterfaceProxy(
+ pBridge, reinterpret_cast< ::com::sun::star::uno::XInterface * >( pCppI ),
+ pTypeDescr, pOId );
+
+ // proxy may be exchanged during registration
+ (*pBridge->pUnoEnv->registerProxyInterface)(
+ pBridge->pUnoEnv, reinterpret_cast< void ** >( &pSurrogate ),
+ (uno_freeProxyFunc)cppu_unoInterfaceProxy_free, pOId, pTypeDescr );
+
+ *ppUnoI = pSurrogate;
+ }
+ ::rtl_uString_release( pOId );
+ }
+}
+//__________________________________________________________________________________________________
+inline cppu_unoInterfaceProxy::cppu_unoInterfaceProxy(
+ cppu_Bridge * pBridge_, ::com::sun::star::uno::XInterface * pCppI_,
+ typelib_InterfaceTypeDescription * pTypeDescr_, const ::rtl::OUString & rOId_ ) SAL_THROW( () )
+ : nRef( 1 )
+ , pBridge( pBridge_ )
+ , pCppI( pCppI_ )
+ , pTypeDescr( pTypeDescr_ )
+ , oid( rOId_ )
+{
+ pBridge->acquire();
+ ::typelib_typedescription_acquire( (typelib_TypeDescription *)pTypeDescr );
+ if (! ((typelib_TypeDescription *)pTypeDescr)->bComplete)
+ ::typelib_typedescription_complete( (typelib_TypeDescription **)&pTypeDescr );
+ OSL_ENSURE( ((typelib_TypeDescription *)pTypeDescr)->bComplete, "### type is incomplete!" );
+ pCppI->acquire();
+ (*pBridge->pCppEnv->registerInterface)(
+ pBridge->pCppEnv, reinterpret_cast< void ** >( &pCppI ), oid.pData, pTypeDescr );
+
+ // uno_Interface
+ uno_Interface::acquire = cppu_unoInterfaceProxy_acquire;
+ uno_Interface::release = cppu_unoInterfaceProxy_release;
+ uno_Interface::pDispatcher = (uno_DispatchMethod)cppu_unoInterfaceProxy_dispatch;
+}
+
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+
+//--------------------------------------------------------------------------------------------------
+inline void SAL_CALL cppu_Mapping_acquire( uno_Mapping * pMapping ) SAL_THROW( () )
+{
+ static_cast< cppu_Mapping * >( pMapping )->pBridge->acquire();
+}
+//--------------------------------------------------------------------------------------------------
+inline void SAL_CALL cppu_Mapping_release( uno_Mapping * pMapping ) SAL_THROW( () )
+{
+ static_cast< cppu_Mapping * >( pMapping )->pBridge->release();
+}
+//__________________________________________________________________________________________________
+inline cppu_Bridge::cppu_Bridge(
+ uno_ExtEnvironment * pCppEnv_, uno_ExtEnvironment * pUnoEnv_,
+ sal_Bool bExportCpp2Uno_ ) SAL_THROW( () )
+ : nRef( 1 )
+ , pCppEnv( pCppEnv_ )
+ , pUnoEnv( pUnoEnv_ )
+ , bExportCpp2Uno( bExportCpp2Uno_ )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+
+ aCpp2Uno.pBridge = this;
+ aCpp2Uno.acquire = cppu_Mapping_acquire;
+ aCpp2Uno.release = cppu_Mapping_release;
+ aCpp2Uno.mapInterface = cppu_Mapping_cpp2uno;
+
+ aUno2Cpp.pBridge = this;
+ aUno2Cpp.acquire = cppu_Mapping_acquire;
+ aUno2Cpp.release = cppu_Mapping_release;
+ aUno2Cpp.mapInterface = cppu_Mapping_uno2cpp;
+
+ (*((uno_Environment *)pCppEnv)->acquire)( (uno_Environment *)pCppEnv );
+ (*((uno_Environment *)pUnoEnv)->acquire)( (uno_Environment *)pUnoEnv );
+}
+//__________________________________________________________________________________________________
+inline cppu_Bridge::~cppu_Bridge() SAL_THROW( () )
+{
+ (*((uno_Environment *)pUnoEnv)->release)( (uno_Environment *)pUnoEnv );
+ (*((uno_Environment *)pCppEnv)->release)( (uno_Environment *)pCppEnv );
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+//__________________________________________________________________________________________________
+inline void SAL_CALL cppu_Bridge_free( uno_Mapping * pMapping ) SAL_THROW( () )
+{
+ delete static_cast< cppu_Mapping * >( pMapping )->pBridge;
+}
+//__________________________________________________________________________________________________
+inline void cppu_Bridge::acquire() SAL_THROW( () )
+{
+ if (1 == osl_incrementInterlockedCount( &nRef ))
+ {
+ if (bExportCpp2Uno)
+ {
+ uno_Mapping * pMapping = &aCpp2Uno;
+ ::uno_registerMapping(
+ &pMapping, cppu_Bridge_free,
+ (uno_Environment *)pCppEnv, (uno_Environment *)pUnoEnv, 0 );
+ }
+ else
+ {
+ uno_Mapping * pMapping = &aUno2Cpp;
+ ::uno_registerMapping(
+ &pMapping, cppu_Bridge_free,
+ (uno_Environment *)pUnoEnv, (uno_Environment *)pCppEnv, 0 );
+ }
+ }
+}
+//__________________________________________________________________________________________________
+inline void cppu_Bridge::release() SAL_THROW( () )
+{
+ if (! osl_decrementInterlockedCount( &nRef ))
+ {
+ ::uno_revokeMapping( bExportCpp2Uno ? &aCpp2Uno : &aUno2Cpp );
+ }
+}
+
+//##################################################################################################
+inline void SAL_CALL cppu_ext_getMapping(
+ uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo ) SAL_THROW( () )
+{
+ OSL_ASSERT( ppMapping && pFrom && pTo );
+ if (ppMapping && pFrom && pTo && pFrom->pExtEnv && pTo->pExtEnv)
+ {
+ uno_Mapping * pMapping = 0;
+
+ if (0 == rtl_ustr_ascii_compare( pFrom->pTypeName->buffer, CPPU_CURRENT_LANGUAGE_BINDING_NAME ) &&
+ 0 == rtl_ustr_ascii_compare( pTo->pTypeName->buffer, UNO_LB_UNO ))
+ {
+ // ref count initially 1
+ pMapping = &(new cppu_Bridge( pFrom->pExtEnv, pTo->pExtEnv, sal_True ))->aCpp2Uno;
+ ::uno_registerMapping(
+ &pMapping, cppu_Bridge_free,
+ (uno_Environment *)pFrom->pExtEnv,
+ (uno_Environment *)pTo->pExtEnv, 0 );
+ }
+ else if (0 == rtl_ustr_ascii_compare( pTo->pTypeName->buffer, CPPU_CURRENT_LANGUAGE_BINDING_NAME ) &&
+ 0 == rtl_ustr_ascii_compare( pFrom->pTypeName->buffer, UNO_LB_UNO ))
+ {
+ // ref count initially 1
+ pMapping = &(new cppu_Bridge( pTo->pExtEnv, pFrom->pExtEnv, sal_False ))->aUno2Cpp;
+ ::uno_registerMapping(
+ &pMapping, cppu_Bridge_free,
+ (uno_Environment *)pFrom->pExtEnv,
+ (uno_Environment *)pTo->pExtEnv, 0 );
+ }
+
+ if (*ppMapping)
+ {
+ (*(*ppMapping)->release)( *ppMapping );
+ }
+ if (pMapping)
+ *ppMapping = pMapping;
+ }
+}
+
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))
+static ::rtl::OUString * s_pStaticOidPart = 0;
+#endif
+
+// environment init stuff
+//--------------------------------------------------------------------------------------------------
+inline const ::rtl::OUString & SAL_CALL cppu_cppenv_getStaticOIdPart() SAL_THROW( () )
+{
+#if ! (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))
+ static ::rtl::OUString * s_pStaticOidPart = 0;
+#endif
+ if (! s_pStaticOidPart)
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if (! s_pStaticOidPart)
+ {
+ ::rtl::OUStringBuffer aRet( 64 );
+ aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") );
+ // good guid
+ sal_uInt8 ar[16];
+ ::rtl_getGlobalProcessId( ar );
+ for ( sal_Int32 i = 0; i < 16; ++i )
+ {
+ aRet.append( (sal_Int32)ar[i], 16 );
+ }
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))
+ s_pStaticOidPart = new ::rtl::OUString( aRet.makeStringAndClear() );
+#else
+ static ::rtl::OUString s_aStaticOidPart( aRet.makeStringAndClear() );
+ s_pStaticOidPart = &s_aStaticOidPart;
+#endif
+ }
+ }
+ return *s_pStaticOidPart;
+}
+// functions set at environment init
+//--------------------------------------------------------------------------------------------------
+inline void SAL_CALL cppu_cppenv_computeObjectIdentifier(
+ uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface ) SAL_THROW( () )
+{
+ OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" );
+ if (pEnv && ppOId && pInterface)
+ {
+ if (*ppOId)
+ {
+ rtl_uString_release( *ppOId );
+ *ppOId = 0;
+ }
+
+ try
+ {
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xHome(
+ reinterpret_cast< ::com::sun::star::uno::XInterface * >( pInterface ),
+ ::com::sun::star::uno::UNO_QUERY );
+ OSL_ENSURE( xHome.is(), "### query to XInterface failed!" );
+ if (xHome.is())
+ {
+ // interface
+ ::rtl::OUStringBuffer oid( 64 );
+ oid.append( (sal_Int64)xHome.get(), 16 );
+ oid.append( (sal_Unicode)';' );
+ // ;environment[context]
+ oid.append(
+ *reinterpret_cast< ::rtl::OUString const * >(
+ &((uno_Environment *) pEnv)->pTypeName ) );
+ oid.append( (sal_Unicode)'[' );
+ oid.append( (sal_Int64)((uno_Environment *)pEnv)->pContext, 16 );
+ // ];good guid
+ oid.append( cppu_cppenv_getStaticOIdPart() );
+ ::rtl::OUString aRet( oid.makeStringAndClear() );
+ ::rtl_uString_acquire( *ppOId = aRet.pData );
+ }
+ }
+ catch (::com::sun::star::uno::RuntimeException &)
+ {
+ OSL_ENSURE( 0, "### RuntimeException occured udring queryInterface()!" );
+ }
+ }
+}
+//--------------------------------------------------------------------------------------------------
+inline void SAL_CALL cppu_cppenv_acquireInterface( uno_ExtEnvironment *, void * pCppI ) SAL_THROW( () )
+{
+ reinterpret_cast< ::com::sun::star::uno::XInterface * >( pCppI )->acquire();
+}
+//--------------------------------------------------------------------------------------------------
+inline void SAL_CALL cppu_cppenv_releaseInterface( uno_ExtEnvironment *, void * pCppI ) SAL_THROW( () )
+{
+ reinterpret_cast< ::com::sun::star::uno::XInterface * >( pCppI )->release();
+}
+//--------------------------------------------------------------------------------------------------
+inline void SAL_CALL cppu_cppenv_environmentDisposing( uno_Environment * ) SAL_THROW( () )
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+//--------------------------------------------------------------------------------------------------
+inline void SAL_CALL cppu_cppenv_initEnvironment( uno_Environment * pCppEnv ) SAL_THROW( () )
+{
+ OSL_ENSURE( pCppEnv->pExtEnv, "### expected extended environment!" );
+ OSL_ENSURE( ::rtl_ustr_ascii_compare( pCppEnv->pTypeName->buffer, CPPU_CURRENT_LANGUAGE_BINDING_NAME ) == 0, "### wrong environment type!" );
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ ((uno_ExtEnvironment *)pCppEnv)->computeObjectIdentifier = cppu_cppenv_computeObjectIdentifier;
+ ((uno_ExtEnvironment *)pCppEnv)->acquireInterface = cppu_cppenv_acquireInterface;
+ ((uno_ExtEnvironment *)pCppEnv)->releaseInterface = cppu_cppenv_releaseInterface;
+ pCppEnv->environmentDisposing = cppu_cppenv_environmentDisposing;
+}
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/bridges/cpp_uno/shared/arraypointer.hxx b/bridges/inc/bridges/cpp_uno/shared/arraypointer.hxx
new file mode 100644
index 000000000000..542be6e0f3d6
--- /dev/null
+++ b/bridges/inc/bridges/cpp_uno/shared/arraypointer.hxx
@@ -0,0 +1,58 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_CPP_UNO_SHARED_ARRAYPOINTER_HXX
+#define INCLUDED_BRIDGES_CPP_UNO_SHARED_ARRAYPOINTER_HXX
+
+#include "sal/config.h"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+/**
+ * A simple smart pointer that holds an array until it is being released.
+ */
+template< typename T > class ArrayPointer {
+public:
+ ArrayPointer(T * p): p_(p) {}
+
+ ~ArrayPointer() { delete[] p_; }
+
+ T * release() { T * t = p_; p_ = 0; return t; }
+
+private:
+ ArrayPointer(ArrayPointer &); // not defined
+ void operator =(ArrayPointer &); // not defined
+
+ T * p_;
+};
+
+} } }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/bridges/cpp_uno/shared/bridge.hxx b/bridges/inc/bridges/cpp_uno/shared/bridge.hxx
new file mode 100644
index 000000000000..4ee69e37b416
--- /dev/null
+++ b/bridges/inc/bridges/cpp_uno/shared/bridge.hxx
@@ -0,0 +1,131 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_CPP_UNO_SHARED_BRIDGE_HXX
+#define INCLUDED_BRIDGES_CPP_UNO_SHARED_BRIDGE_HXX
+
+#include "osl/interlck.h"
+#include "sal/types.h"
+#include "typelib/typedescription.h"
+#include "uno/environment.h"
+#include "uno/mapping.h"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+// private:
+extern "C" typedef void SAL_CALL FreeMapping(uno_Mapping *);
+FreeMapping freeMapping;
+
+// private:
+extern "C"
+typedef void SAL_CALL AcquireMapping(uno_Mapping *);
+AcquireMapping acquireMapping;
+
+// private:
+extern "C"
+typedef void SAL_CALL ReleaseMapping(uno_Mapping *);
+ReleaseMapping releaseMapping;
+
+// private:
+extern "C" typedef void SAL_CALL Cpp2unoMapping(
+ uno_Mapping *, void **, void *, typelib_InterfaceTypeDescription *);
+Cpp2unoMapping cpp2unoMapping;
+
+// private:
+extern "C" typedef void SAL_CALL Uno2cppMapping(
+ uno_Mapping *, void **, void *, typelib_InterfaceTypeDescription *);
+Uno2cppMapping uno2cppMapping;
+
+/**
+ * Holding environments and mappings.
+ */
+class Bridge {
+public:
+ // Interface for generic/component.cxx:
+
+ static uno_Mapping * createMapping(
+ uno_ExtEnvironment * pCppEnv, uno_ExtEnvironment * pUnoEnv,
+ bool bExportCpp2Uno) SAL_THROW(());
+
+ // Interface for Cpp/UnoInterfaceProxy:
+
+ void acquire() SAL_THROW(());
+ void release() SAL_THROW(());
+
+ // Interface for individual CPP--UNO bridges:
+
+ uno_ExtEnvironment * getCppEnv() { return pCppEnv; }
+ uno_ExtEnvironment * getUnoEnv() { return pUnoEnv; }
+
+ uno_Mapping * getCpp2Uno() { return &aCpp2Uno; }
+ uno_Mapping * getUno2Cpp() { return &aUno2Cpp; }
+
+private:
+ Bridge(Bridge &); // not implemented
+ void operator =(Bridge); // not implemented
+
+ Bridge(
+ uno_ExtEnvironment * pCppEnv_, uno_ExtEnvironment * pUnoEnv_,
+ bool bExportCpp2Uno_) SAL_THROW(());
+
+ ~Bridge() SAL_THROW(());
+
+ struct Mapping: public uno_Mapping {
+ Bridge * pBridge;
+ };
+
+ oslInterlockedCount nRef;
+
+ uno_ExtEnvironment * pCppEnv;
+ uno_ExtEnvironment * pUnoEnv;
+
+ Mapping aCpp2Uno;
+ Mapping aUno2Cpp;
+
+ bool bExportCpp2Uno;
+
+ friend void SAL_CALL freeMapping(uno_Mapping * pMapping);
+
+ friend void SAL_CALL acquireMapping(uno_Mapping * pMapping);
+
+ friend void SAL_CALL releaseMapping(uno_Mapping * pMapping);
+
+ friend void SAL_CALL cpp2unoMapping(
+ uno_Mapping * pMapping, void ** ppUnoI, void * pCppI,
+ typelib_InterfaceTypeDescription * pTypeDescr);
+
+ friend void SAL_CALL uno2cppMapping(
+ uno_Mapping * pMapping, void ** ppCppI, void * pUnoI,
+ typelib_InterfaceTypeDescription * pTypeDescr);
+};
+
+} } }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/bridges/cpp_uno/shared/cppinterfaceproxy.hxx b/bridges/inc/bridges/cpp_uno/shared/cppinterfaceproxy.hxx
new file mode 100644
index 000000000000..31e19cc94d00
--- /dev/null
+++ b/bridges/inc/bridges/cpp_uno/shared/cppinterfaceproxy.hxx
@@ -0,0 +1,109 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_CPP_UNO_SHARED_CPPINTERFACEPROXY_HXX
+#define INCLUDED_BRIDGES_CPP_UNO_SHARED_CPPINTERFACEPROXY_HXX
+
+#include "osl/interlck.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "typelib/typedescription.h"
+#include "uno/dispatcher.h"
+#include "uno/environment.h"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+namespace com { namespace sun { namespace star { namespace uno {
+ class XInterface;
+} } } }
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+class Bridge;
+
+extern "C" typedef void SAL_CALL FreeCppInterfaceProxy(
+ uno_ExtEnvironment * pEnv, void * pInterface);
+FreeCppInterfaceProxy freeCppInterfaceProxy;
+
+/**
+ * A cpp proxy wrapping a uno interface.
+ */
+class CppInterfaceProxy {
+public:
+ // Interface for Bridge:
+
+ static com::sun::star::uno::XInterface * create(
+ Bridge * pBridge, uno_Interface * pUnoI,
+ typelib_InterfaceTypeDescription * pTypeDescr,
+ rtl::OUString const & rOId) SAL_THROW(());
+
+ // Interface for individual CPP--UNO bridges:
+
+ Bridge * getBridge() { return pBridge; }
+ uno_Interface * getUnoI() { return pUnoI; }
+ typelib_InterfaceTypeDescription * getTypeDescr() { return pTypeDescr; }
+ rtl::OUString getOid() { return oid; }
+
+ // non virtual methods called on incoming vtable calls #1, #2
+ void acquireProxy() SAL_THROW(());
+ void releaseProxy() SAL_THROW(());
+
+ static CppInterfaceProxy * castInterfaceToProxy(void * pInterface);
+
+private:
+ CppInterfaceProxy(CppInterfaceProxy &); // not implemented
+ void operator =(CppInterfaceProxy); // not implemented
+
+ CppInterfaceProxy(
+ Bridge * pBridge_, uno_Interface * pUnoI_,
+ typelib_InterfaceTypeDescription * pTypeDescr_,
+ rtl::OUString const & rOId_) SAL_THROW(());
+
+ ~CppInterfaceProxy();
+
+ static com::sun::star::uno::XInterface * castProxyToInterface(
+ CppInterfaceProxy * pProxy);
+
+ oslInterlockedCount nRef;
+ Bridge * pBridge;
+
+ // mapping information
+ uno_Interface * pUnoI; // wrapped interface
+ typelib_InterfaceTypeDescription * pTypeDescr;
+ rtl::OUString oid;
+
+ VtableFactory::Slot * vtables[1];
+
+ friend void SAL_CALL freeCppInterfaceProxy(
+ uno_ExtEnvironment * pEnv, void * pInterface);
+};
+
+} } }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/bridges/cpp_uno/shared/types.hxx b/bridges/inc/bridges/cpp_uno/shared/types.hxx
new file mode 100644
index 000000000000..0cc87864af0e
--- /dev/null
+++ b/bridges/inc/bridges/cpp_uno/shared/types.hxx
@@ -0,0 +1,80 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_CPP_UNO_SHARED_TYPES_HXX
+#define INCLUDED_BRIDGES_CPP_UNO_SHARED_TYPES_HXX
+
+#include "typelib/typeclass.h"
+#include "typelib/typedescription.h"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+/**
+ * Determines whether a type is a "simple" type (VOID, BOOLEAN, BYTE, SHORT,
+ * UNSIGNED SHORT, LONG, UNSIGNED LONG, HYPER, UNSIGNED HYPER, FLOAT, DOUBLE,
+ * CHAR, or an enum type).
+ *
+ * @param typeClass a type class
+ * @return true if the given type is "simple"
+ */
+bool isSimpleType(typelib_TypeClass typeClass);
+
+/**
+ * Determines whether a type is a "simple" type (VOID, BOOLEAN, BYTE, SHORT,
+ * UNSIGNED SHORT, LONG, UNSIGNED LONG, HYPER, UNSIGNED HYPER, FLOAT, DOUBLE,
+ * CHAR, or an enum type).
+ *
+ * @param type a non-null pointer to a type description reference
+ * @return true if the given type is "simple"
+ */
+bool isSimpleType(typelib_TypeDescriptionReference const * type);
+
+/**
+ * Determines whether a type is a "simple" type (VOID, BOOLEAN, BYTE, SHORT,
+ * UNSIGNED SHORT, LONG, UNSIGNED LONG, HYPER, UNSIGNED HYPER, FLOAT, DOUBLE,
+ * CHAR, or an enum type).
+ *
+ * @param type a non-null pointer to a type description
+ * @return true if the given type is "simple"
+ */
+bool isSimpleType(typelib_TypeDescription const * type);
+
+/**
+ * Determines whether a type relates to an interface type (is itself an
+ * interface type, or might contain entities of interface type).
+ *
+ * @param type a non-null pointer to a type description
+ * @return true if the given type relates to an interface type
+ */
+bool relatesToInterfaceType(typelib_TypeDescription const * type);
+
+} } }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/bridges/cpp_uno/shared/unointerfaceproxy.hxx b/bridges/inc/bridges/cpp_uno/shared/unointerfaceproxy.hxx
new file mode 100644
index 000000000000..87c96ec36689
--- /dev/null
+++ b/bridges/inc/bridges/cpp_uno/shared/unointerfaceproxy.hxx
@@ -0,0 +1,119 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_CPP_UNO_SHARED_UNOINTERFACEPROXY_HXX
+#define INCLUDED_BRIDGES_CPP_UNO_SHARED_UNOINTERFACEPROXY_HXX
+
+#include "osl/interlck.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "typelib/typedescription.h"
+#include "uno/dispatcher.h"
+#include "uno/environment.h"
+
+namespace com { namespace sun { namespace star { namespace uno {
+ class XInterface;
+} } } }
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+class Bridge;
+
+extern "C" typedef void SAL_CALL FreeUnoInterfaceProxy(
+ uno_ExtEnvironment * pEnv, void * pProxy);
+FreeUnoInterfaceProxy freeUnoInterfaceProxy;
+
+// private:
+extern "C" typedef void SAL_CALL UnoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, typelib_TypeDescription const * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException);
+UnoInterfaceProxyDispatch unoInterfaceProxyDispatch;
+ // this function is not defined in the generic part, but instead has to be
+ // defined individually for each CPP--UNO bridge
+
+// private:
+extern "C" typedef void SAL_CALL AcquireProxy(uno_Interface *);
+AcquireProxy acquireProxy;
+
+// private:
+extern "C" typedef void SAL_CALL ReleaseProxy(uno_Interface *);
+ReleaseProxy releaseProxy;
+
+/**
+ * A uno proxy wrapping a cpp interface.
+ */
+class UnoInterfaceProxy: public uno_Interface {
+public:
+ // Interface for Bridge:
+
+ static UnoInterfaceProxy * create(
+ Bridge * pBridge, com::sun::star::uno::XInterface * pCppI,
+ typelib_InterfaceTypeDescription * pTypeDescr,
+ rtl::OUString const & rOId) SAL_THROW(());
+
+ // Interface for individual CPP--UNO bridges:
+
+ Bridge * getBridge() { return pBridge; }
+ com::sun::star::uno::XInterface * getCppI() { return pCppI; }
+
+private:
+ UnoInterfaceProxy(UnoInterfaceProxy &); // not implemented
+ void operator =(UnoInterfaceProxy); // not implemented
+
+ UnoInterfaceProxy(
+ Bridge * pBridge_, com::sun::star::uno::XInterface * pCppI_,
+ typelib_InterfaceTypeDescription * pTypeDescr_,
+ rtl::OUString const & rOId_) SAL_THROW(());
+
+ ~UnoInterfaceProxy();
+
+ oslInterlockedCount nRef;
+ Bridge * pBridge;
+
+ // mapping information
+ com::sun::star::uno::XInterface * pCppI; // wrapped interface
+ typelib_InterfaceTypeDescription * pTypeDescr;
+ rtl::OUString oid;
+
+ friend void SAL_CALL freeUnoInterfaceProxy(
+ uno_ExtEnvironment * pEnv, void * pProxy);
+
+ friend void SAL_CALL unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, typelib_TypeDescription const * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException);
+
+ friend void SAL_CALL acquireProxy(uno_Interface * pUnoI);
+
+ friend void SAL_CALL releaseProxy(uno_Interface * pUnoI);
+};
+
+} } }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/bridges/cpp_uno/shared/vtablefactory.hxx b/bridges/inc/bridges/cpp_uno/shared/vtablefactory.hxx
new file mode 100644
index 000000000000..247b12aafb25
--- /dev/null
+++ b/bridges/inc/bridges/cpp_uno/shared/vtablefactory.hxx
@@ -0,0 +1,218 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_CPP_UNO_SHARED_VTABLEFACTORY_HXX
+#define INCLUDED_BRIDGES_CPP_UNO_SHARED_VTABLEFACTORY_HXX
+
+#include "osl/mutex.hxx"
+#include "rtl/alloc.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "typelib/typedescription.hxx"
+
+#include <hash_map>
+
+/*See: http://people.redhat.com/drepper/selinux-mem.html*/
+#if defined(LINUX) || defined(OPENBSD) || defined(FREEBSD) \
+ || defined(NETBSD)
+#define USE_DOUBLE_MMAP
+#endif
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+/** Hand out vtable structures for interface type descriptions.
+ */
+class VtableFactory {
+public:
+ // This structure is not defined in the generic part, but instead has to be
+ // defined individually for each CPP--UNO bridge:
+ /** A vtable slot.
+ */
+ struct Slot;
+
+ /** A raw vtable block.
+ */
+ struct Block {
+ /** The start of the raw vtable block.
+
+ It points to the start of the allocated memory block, whereas the
+ vtable pointer typically points some bytes into the block (e.g.,
+ skipping an RTTI pointer, see mapBlockToVtable). Also, the block
+ contains any generated code snippets, after the vtable itself.
+ */
+ void * start;
+
+#ifdef USE_DOUBLE_MMAP
+ /** When seperately mmapping the block for writing and executing
+ exec points to the same memory as start, except start is used
+ exclusively for writing and exec for executing
+ */
+ void * exec;
+
+ /** File handle for the underlying anonymous file
+ */
+ int fd;
+#endif
+
+ /** The size of the raw vtable block, in bytes.
+ */
+ sal_Size size;
+ };
+
+ /** The vtable structure corresponding to an interface type.
+ */
+ struct Vtables {
+ /** The number of blocks/vtables.
+ */
+ sal_Int32 count;
+
+ /** An array of blocks, representing the multiple vtables of a
+ (multiple-inheritance) type.
+
+ <p>A block is a raw vtable. It points to the start of the allocated
+ memory block, whereas the vtable pointer typically points some bytes
+ into the block (e.g., skipping an RTTI pointer, see
+ mapBlockToVtable). Also, the block contains any generated code
+ snippets, after the vtable itself.</p>
+ */
+ Block * blocks;
+ };
+
+ VtableFactory();
+
+ ~VtableFactory();
+
+ /** Given an interface type description, return its corresponding vtable
+ structure.
+ */
+ Vtables getVtables(typelib_InterfaceTypeDescription * type);
+
+ // This function is not defined in the generic part, but instead has to be
+ // defined individually for each CPP--UNO bridge:
+ /** Given a pointer to a block, turn it into a vtable pointer.
+ */
+ static Slot * mapBlockToVtable(void * block);
+
+private:
+ class GuardedBlocks;
+ friend class GuardedBlocks;
+
+ class BaseOffset;
+
+ VtableFactory(VtableFactory &); // not implemented
+ void operator =(VtableFactory); // not implemented
+
+ bool createBlock(Block &block, sal_Int32 slotCount) const;
+
+ void freeBlock(Block const & block) const;
+
+ void createVtables(
+ GuardedBlocks & blocks, BaseOffset const & baseOffset,
+ typelib_InterfaceTypeDescription * type, bool includePrimary) const;
+
+ // This function is not defined in the generic part, but instead has to be
+ // defined individually for each CPP--UNO bridge:
+ /** Calculate the size of a raw vtable block.
+
+ @param slotCount the number of virtual function slots the returned
+ vtable block shall support (if there are any platform-specific slots,
+ like an RTTI pointer, or a pointer to a destructor, they are not covered
+ by slotCount)
+ @return the size of the raw vtable block, in bytes
+ */
+ static sal_Size getBlockSize(sal_Int32 slotCount);
+
+ // This function is not defined in the generic part, but instead has to be
+ // defined individually for each CPP--UNO bridge:
+ /** Initialize a raw vtable block.
+
+ @param block the start address of the raw vtable block
+ @param slotCount the number of slots
+ @return a pointer past the last vtable slot
+ */
+ static Slot * initializeBlock(void * block, sal_Int32 slotCount);
+
+ // This function is not defined in the generic part, but instead has to be
+ // defined individually for each CPP--UNO bridge:
+ /** Fill the vtable slots corresponding to all local (i.e., not inherited)
+ functions of a given interface type (and generate any necessary code
+ snippets for them).
+
+ @param slots on input, points past the vtable slot to be filled with
+ the last virtual function local to the given type; on output, points to
+ the vtable slot filled with the first virtual function local to the
+ given type
+ @param code points to the start of the area where code snippets can be
+ generated
+ @param writetoexecdiff when the same code area is mmaped twice, once for
+ writing for code-generation, and once for code-execution, then this
+ records the offset from a writable address to its executable address
+ @param type the interface type description for which to generate vtable
+ slots
+ @param functionOffset the function offset of the first vtable slot
+ (typically coded into the code snippet for that vtable slot)
+ @param functionCount the number of vtable slots to fill (the number of
+ local functions of the given type, passed in so that it need not be
+ recomputed)
+ @param vtableOffset the offset of this vtable (needed to adjust the
+ this pointer, typically coded into the code snippets for all the filled
+ vtable slots)
+ @return a pointer to the remaining code snippet area
+ */
+ static unsigned char * addLocalFunctions(
+ Slot ** slots, unsigned char * code,
+#ifdef USE_DOUBLE_MMAP
+ sal_PtrDiff writetoexecdiff,
+#endif
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset);
+
+ // This function is not defined in the generic part, but instead has to be
+ // defined individually for each CPP--UNO bridge:
+ /** Flush all the generated code snippets of a vtable, on platforms that
+ require it.
+
+ @param begin points to the start of the code snippet area
+ @param end points behind the end of the code snippet area
+ */
+ static void flushCode(
+ unsigned char const * begin, unsigned char const * end);
+
+ typedef std::hash_map< rtl::OUString, Vtables, rtl::OUStringHash > Map;
+
+ osl::Mutex m_mutex;
+ Map m_map;
+
+ rtl_arena_type * m_arena;
+};
+
+} } }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/bridges/cpp_uno/shared/vtables.hxx b/bridges/inc/bridges/cpp_uno/shared/vtables.hxx
new file mode 100644
index 000000000000..2ea5c7c83121
--- /dev/null
+++ b/bridges/inc/bridges/cpp_uno/shared/vtables.hxx
@@ -0,0 +1,111 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_CPP_UNO_SHARED_VTABLES_HXX
+#define INCLUDED_BRIDGES_CPP_UNO_SHARED_VTABLES_HXX
+
+#include "sal/types.h"
+#include "typelib/typedescription.h"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+/**
+ * Calculate the number of local functions of an interface type.
+ *
+ * <p><em>Local</em> functions are those not inherited from any base types. The
+ * number of <em>functions</em> is potentially larger than the number of
+ * <em>members</em>, as each read&ndash;write attribute member counts as two
+ * functions.</p>
+ *
+ * @param type a non-null pointer to an interface type description, for which
+ * <code>typelib_typedescription_complete</code> must already have been
+ * executed
+ * @return the number of local functions of the given interface type
+ */
+sal_Int32 getLocalFunctions(typelib_InterfaceTypeDescription const * type);
+
+/**
+ * Calculate the number of primary functions of an interface type.
+ *
+ * <p>The number of primary functions of an interface is the number of local
+ * functions of that interface (see <code>getLocalFunctions</code>), plus the
+ * number of primary functions of that interface's first base type (if it has at
+ * least one base type).</p>
+ *
+ * @param type a pointer to an interface type description; may be null
+ * @return the number of primary functions of the given interface type, or zero
+ * if the given interface type is null
+ */
+sal_Int32 getPrimaryFunctions(typelib_InterfaceTypeDescription * type);
+
+/**
+ * Represents a vtable slot of a C++ class.
+ */
+struct VtableSlot {
+ /**
+ * The offset of the vtable.
+ *
+ * <p>Multiple-inheritance C++ classes have more than one vtable. The
+ * offset is logical (<em>not</em> a byte offset), and must be
+ * non-negative.</p>
+ */
+ sal_Int32 offset;
+
+ /**
+ * The index within the vtable.
+ *
+ * <p>The index is logical (<em>not</em> a byte offset), and must be
+ * non-negative.</p>
+ */
+ sal_Int32 index;
+};
+
+/**
+ * Calculates the vtable slot associated with an interface attribute member.
+ *
+ * @param ifcMember a non-null pointer to an interface attribute member
+ * description
+ * @return the vtable slot associated with the given interface member
+ */
+VtableSlot getVtableSlot(
+ typelib_InterfaceAttributeTypeDescription const * ifcMember);
+
+/**
+ * Calculates the vtable slot associated with an interface method member.
+ *
+ * @param ifcMember a non-null pointer to an interface method member description
+ * @return the vtable slot associated with the given interface member
+ */
+VtableSlot getVtableSlot(
+ typelib_InterfaceMethodTypeDescription const * ifcMember);
+
+} } }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/bridges/cpp_uno/type_misc.hxx b/bridges/inc/bridges/cpp_uno/type_misc.hxx
new file mode 100644
index 000000000000..5fbd0da45cac
--- /dev/null
+++ b/bridges/inc/bridges/cpp_uno/type_misc.hxx
@@ -0,0 +1,132 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+#ifndef _BRIDGES_CPP_UNO_TYPE_MISC_HXX_
+#define _BRIDGES_CPP_UNO_TYPE_MISC_HXX_
+
+#include <sal/types.h>
+#include <typelib/typedescription.h>
+
+
+/** Determines whether given type might relate or relates to an interface,
+ i.e. values of this type are interface or may contain interface(s).<br>
+ @param pTypeDescr type description of type
+ @return true if type might relate to an interface, false otherwise
+*/
+inline bool cppu_relatesToInterface( typelib_TypeDescription * pTypeDescr ) SAL_THROW( () )
+{
+ switch (pTypeDescr->eTypeClass)
+ {
+// case typelib_TypeClass_TYPEDEF:
+ case typelib_TypeClass_SEQUENCE:
+ {
+ switch (((typelib_IndirectTypeDescription *)pTypeDescr)->pType->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE:
+ case typelib_TypeClass_UNION: // might relate to interface
+ case typelib_TypeClass_ANY: // might relate to interface
+ return true;
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType );
+ bool bRel = cppu_relatesToInterface( pTD );
+ TYPELIB_DANGER_RELEASE( pTD );
+ return bRel;
+ }
+ default:
+ return false;
+ }
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ // ...optimized... to avoid getDescription() calls!
+ typelib_CompoundTypeDescription * pComp = (typelib_CompoundTypeDescription *)pTypeDescr;
+ typelib_TypeDescriptionReference ** pTypes = pComp->ppTypeRefs;
+ for ( sal_Int32 nPos = pComp->nMembers; nPos--; )
+ {
+ switch (pTypes[nPos]->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE:
+ case typelib_TypeClass_UNION: // might relate to interface
+ case typelib_TypeClass_ANY: // might relate to interface
+ return true;
+// case typelib_TypeClass_TYPEDEF:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, pTypes[nPos] );
+ bool bRel = cppu_relatesToInterface( pTD );
+ TYPELIB_DANGER_RELEASE( pTD );
+ if (bRel)
+ return true;
+ }
+ default:
+ break;
+ }
+ }
+ if (pComp->pBaseTypeDescription)
+ return cppu_relatesToInterface( (typelib_TypeDescription *)pComp->pBaseTypeDescription );
+ return false;
+ }
+ case typelib_TypeClass_UNION: // might relate to interface
+ case typelib_TypeClass_ANY: // might relate to interface
+ case typelib_TypeClass_INTERFACE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/** Determines whether given type is a cpp simple type, e.g. int, enum.<br>
+ @param eTypeClass type class of type
+ @return true if type is a cpp simple type, false otherwise
+*/
+inline bool cppu_isSimpleType( typelib_TypeClass eTypeClass ) SAL_THROW( () )
+{
+ return (eTypeClass <= typelib_TypeClass_ENUM &&
+ eTypeClass != typelib_TypeClass_STRING &&
+ eTypeClass != typelib_TypeClass_ANY &&
+ eTypeClass != typelib_TypeClass_TYPE);
+}
+/** Determines whether given type is a cpp simple type, e.g. int, enum.<br>
+ @param pTypeDescr type description of type
+ @return true if type is a cpp simple type, false otherwise
+*/
+inline bool cppu_isSimpleType( typelib_TypeDescription * pTypeDescr ) SAL_THROW( () )
+{
+ return cppu_isSimpleType( pTypeDescr->eTypeClass );
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/bridges/remote/bridgeimpl.hxx b/bridges/inc/bridges/remote/bridgeimpl.hxx
new file mode 100644
index 000000000000..bb166d50a153
--- /dev/null
+++ b/bridges/inc/bridges/remote/bridgeimpl.hxx
@@ -0,0 +1,97 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+#ifndef _BRIDGES_REMOTE_BRIDGEIMPL_HXX_
+#define _BRIDGES_REMOTE_BRIDGEIMPL_HXX_
+#include <osl/interlck.h>
+
+#include <uno/environment.h>
+
+#include <bridges/remote/context.h>
+#include <bridges/remote/remote.h>
+
+
+struct remote_BridgeImpl
+{
+ void (SAL_CALL * m_allThreadsAreGone ) ( uno_Environment * );
+ requestClientSideDispatcher m_sendRequest;
+ oslInterlockedCount m_nRemoteThreads;
+ sal_Bool m_bDisposed;
+ sal_Bool m_bReleaseStubsCalled;
+};
+
+namespace bridges_remote {
+
+ enum RemoteThreadCounter_HoldEnvWeak
+ {
+ RTC_HOLDENVWEAK = 0x1
+ };
+
+ class RemoteThreadCounter
+ {
+ public:
+ // performance optimization. In some cases, it is not necessary to acquire the
+ // environment.
+ RemoteThreadCounter( uno_Environment *pEnvRemote, RemoteThreadCounter_HoldEnvWeak )
+ : m_bReleaseEnvironment( sal_False )
+ , m_pEnvRemote( pEnvRemote )
+ {
+ remote_Context *pContext = ((remote_Context *) m_pEnvRemote->pContext );
+ osl_incrementInterlockedCount( &( pContext->m_pBridgeImpl->m_nRemoteThreads ) );
+ }
+
+ RemoteThreadCounter( uno_Environment *pEnvRemote )
+ : m_bReleaseEnvironment( sal_True )
+ , m_pEnvRemote( pEnvRemote )
+ {
+ m_pEnvRemote->acquire( m_pEnvRemote );
+
+ remote_Context *pContext = ((remote_Context *) m_pEnvRemote->pContext );
+ osl_incrementInterlockedCount( &( pContext->m_pBridgeImpl->m_nRemoteThreads ) );
+ }
+
+ ~RemoteThreadCounter( )
+ {
+ remote_Context *pContext = ((remote_Context *) m_pEnvRemote->pContext );
+ if( 0 == osl_decrementInterlockedCount( &( pContext->m_pBridgeImpl->m_nRemoteThreads)) &&
+ pContext->m_pBridgeImpl->m_bDisposed &&
+ ! pContext->m_pBridgeImpl->m_bReleaseStubsCalled )
+ {
+ pContext->m_pBridgeImpl->m_allThreadsAreGone( m_pEnvRemote );
+ }
+ if( m_bReleaseEnvironment )
+ m_pEnvRemote->release( m_pEnvRemote );
+ }
+
+ sal_Bool m_bReleaseEnvironment;
+ uno_Environment *m_pEnvRemote;
+ };
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/bridges/remote/connection.h b/bridges/inc/bridges/remote/connection.h
new file mode 100644
index 000000000000..9ed8fad10d02
--- /dev/null
+++ b/bridges/inc/bridges/remote/connection.h
@@ -0,0 +1,70 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+#ifndef _BRIDGES_REMOTE_CONNECTION_H_
+#define _BRIDGES_REMOTE_CONNECTION_H_
+#include <sal/types.h>
+
+/** Specfies a C-interface for a bidirectional bytestream,
+ which is used by a UNO remote environment.
+ */
+struct remote_Connection
+{
+ void ( SAL_CALL * acquire ) ( remote_Connection *);
+
+ void ( SAL_CALL * release ) ( remote_Connection *);
+
+ /**
+ reads nSize bytes from the connection. This method blocks, until
+ all bytes are available or an error occurs.
+ @return Number of bytes read.
+ If the return value is less than nSize, an unrecoverable
+ i/o error has occured or the connection was closed.
+
+ */
+ sal_Int32 (SAL_CALL * read)(remote_Connection *, sal_Int8 *pDest, sal_Int32 nSize );
+
+ /**
+ @return Number of bytes written.
+ if the return value is less than nSize an unrecoverable
+ i/o error has occured or the connection was closed.
+ */
+ sal_Int32 (SAL_CALL * write)(remote_Connection *, const sal_Int8 *pSource, sal_Int32 nSize );
+
+ void ( SAL_CALL * flush ) ( remote_Connection * );
+
+ /** closes the connection.
+ Any read or write operation after this call shall not be served
+ anymore. Any ongoing read or write operation must return immeadiatly after this call.
+ The implementation should cope with multiple calls to this method.
+ */
+ void (SAL_CALL * close) ( remote_Connection * );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/bridges/remote/context.h b/bridges/inc/bridges/remote/context.h
new file mode 100644
index 000000000000..8ff83adfb128
--- /dev/null
+++ b/bridges/inc/bridges/remote/context.h
@@ -0,0 +1,262 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef _BRIDGES_REMOTE_CONTEXT_H_
+#define _BRIDGES_REMOTE_CONTEXT_H_
+#include <osl/interlck.h>
+#include <osl/conditn.h>
+
+#include <typelib/typedescription.h>
+
+#include <uno/environment.h>
+#include <uno/any2.h>
+
+
+/** Interface for refcounted contexts of uno-environments.
+
+ Not all uno_Contexts need to be refcounted, in case they are,
+ they should be 'derived' from this struct.
+ This is used as a base class for the remote_Context.
+ @see uno_Environment
+ @see uno_getEnvironment()
+ @see remote_Context
+ */
+struct uno_Context
+{
+ /** increase the refcount of the context
+ */
+ void (SAL_CALL * acquire)( uno_Context *pContext );
+
+ /** decrements the recount of the context. In case the recount drops to zero,
+ the context gets destroye.
+ */
+ void (SAL_CALL * release)( uno_Context *pContext);
+
+ /** Allows to query for a different interface of the uno_Context.
+ The result of the void pointer is unspecified and depends on the concrete context.
+ */
+ void * (SAL_CALL *query ) ( uno_Context *pContext , rtl_uString *pId);
+};
+
+struct remote_Connection;
+struct remote_Context;
+struct remote_Interface;
+
+
+
+/** performs a query-interface for a certain interface via the remote connection !
+
+ @param pEnvRemote The environment, that shall perform the call.
+ @param ppRemoteI in/out parameter contains the interface returned by queryInterface
+ @param pOid the oid of the 'ghost' object on which the call must be done.
+ ***/
+typedef void ( SAL_CALL * remote_getInstanceFunc ) (
+ uno_Environment *pEnvRemote,
+ remote_Interface **ppRemoteI,
+ rtl_uString *pOid,
+ typelib_TypeDescriptionReference *pInterfaceTypeRef,
+ uno_Any **ppException );
+
+
+/** refcounted C-interface, which provides object by name.
+ */
+struct remote_InstanceProvider
+{
+ void (SAL_CALL * acquire ) ( remote_InstanceProvider * pProvider );
+ void (SAL_CALL * release ) ( remote_InstanceProvider * pProvider );
+ void (SAL_CALL * getInstance ) ( remote_InstanceProvider * pProvider ,
+ uno_Environment *pEnvRemote,
+ remote_Interface **ppRemoteI,
+ rtl_uString *pInstanceName,
+ typelib_InterfaceTypeDescription *pType,
+ uno_Any **ppException );
+};
+
+/** refcounted C-interface, which allows to register a listener to an
+ remote bridge to be informed when the bridge gets disposed.
+
+ @see remote_Context
+ */
+struct remote_DisposingListener
+{
+ void (SAL_CALL * acquire ) ( remote_DisposingListener * pProvider );
+ void (SAL_CALL * release ) ( remote_DisposingListener * pProvider );
+ void (SAL_CALL * disposing ) ( remote_DisposingListener * pProvider,
+ rtl_uString *pBridgeName );
+};
+
+
+/**
+ Try to get an existing context characterized by the pIdString. Each ID-String must
+ uniquely charcterize a certain connection. The context can't be retrieved via this
+ function anymore, after it got disposed.
+
+ @return 0 when such a context does not exist, otherwise
+ a pointer to an acquired remote_Context.
+ **/
+extern "C" remote_Context * SAL_CALL
+remote_getContext( rtl_uString *pIdString );
+
+/**
+ Create an acquired remote context. The Context is weakly held by the context administration
+ and can be accessed later through remote_getContext() (using the same id-string).
+
+ @param pIdString A string, that uniquely describes the connection. For e.g. a socket connection,
+ host and port of the local and remote host should be in the string.
+
+ @param pDescription
+ Description of the connection, that may brought up to the user.
+
+ @param pProtocol
+ The protocol, that the environment uses for
+ communicating with the remote process.
+ The format of the protocol string is : "protocolname,para1=para1value,..."
+ @return 0, when a context with this name already exists.
+
+ @see remote_getContext()
+ @see remote_Context
+ */
+extern "C" remote_Context * SAL_CALL
+remote_createContext( remote_Connection *pConnection,
+ rtl_uString *pIdStr,
+ rtl_uString *pDescription,
+ rtl_uString *pProtocol,
+ remote_InstanceProvider *);
+
+const sal_Int32 REMOTE_CONTEXT_CREATE = 1;
+const sal_Int32 REMOTE_CONTEXT_DESTROY = 2;
+
+typedef void ( SAL_CALL * remote_contextListenerFunc ) (
+ void *pThis,
+ sal_Int32 nRemoteContextMode,
+ rtl_uString *sName,
+ rtl_uString *sDescription
+ );
+
+/** Registers a listener at the context administration, which allows to keep
+ track of existing remote connections.
+ @param pObject object which is handed to the listener function, when called.
+ */
+extern "C" void SAL_CALL
+remote_addContextListener( remote_contextListenerFunc listener, void *pObject );
+
+
+/** Removes a listener from the context administration.
+ */
+extern "C" void SAL_CALL
+remote_removeContextListener( remote_contextListenerFunc listener , void *pObject );
+
+/** Allows to retrieve all existing context strings.
+
+ @param pnStringCount out parameter. Contains the number of rtl_uStrings in the array
+ @param memAlloc a memory allocation function for the array of pointers to rtl_uStrings
+
+ @return array of rtl strings. The caller must call release on all rtl_uString s and must free
+ the pointer array.
+ */
+extern "C" rtl_uString ** SAL_CALL
+remote_getContextList(
+ sal_Int32 *pnStringCount,
+ void * ( SAL_CALL * memAlloc ) ( sal_Size nBytesToAlloc ) );
+
+
+struct remote_BridgeImpl;
+
+/** The context structure for a remote bridge.
+
+ @see uno_getEnvironment()
+ */
+struct remote_Context
+{
+ struct uno_Context aBase;
+
+ /**
+ These methods are implemented by context administration
+ */
+ void ( SAL_CALL * addDisposingListener ) ( remote_Context *,
+ remote_DisposingListener * );
+ void ( SAL_CALL * removeDisposingListener ) ( remote_Context *,
+ remote_DisposingListener * );
+ /**
+ will be called by the environment when it gets disposed
+ */
+ void ( SAL_CALL * dispose ) ( remote_Context * );
+
+ /** The method is set by the remote-environment during environment initialization.
+ @see remote_getInstanceFunc
+ */
+ remote_getInstanceFunc getRemoteInstance;
+
+ /**
+ The protocol, that the environment uses for communicating with the remote process.
+ The format of the protocol string is : "protocolname,para1=para1value,..."
+ The parameters are protocol dependend
+ */
+ rtl_uString *m_pProtocol;
+
+ /**
+ It may be the same as m_pName.
+ Livetime is handled by the context administration.
+ */
+ rtl_uString *m_pDescription;
+
+ /**
+ The name of this context at context administration.
+ A string, that uniquely describes this environment.
+ Livetime is handled by the context administration.
+ */
+ rtl_uString *m_pName;
+
+ /** The instance-provider, which is used to look up unknown object identifiers.
+ Is usually called on server side, when the first client request comes in.
+ Maybe 0. Livetime is handled by the context administration.
+ */
+ remote_InstanceProvider *m_pInstanceProvider;
+
+ /**
+ The connection of this context.
+ Livetime is handled by the context administration.
+ */
+ remote_Connection *m_pConnection;
+
+ /**
+ Here arbitrary data may be stored. It may be used by a connection
+ service to store environment specific data. The bridge does not
+ use it.
+ */
+ void *m_pAdditionalInformation;
+
+ /**
+ here the bridge stores its private per environment data.
+ */
+ struct remote_BridgeImpl *m_pBridgeImpl;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/bridges/remote/counter.hxx b/bridges/inc/bridges/remote/counter.hxx
new file mode 100644
index 000000000000..8bcb547008af
--- /dev/null
+++ b/bridges/inc/bridges/remote/counter.hxx
@@ -0,0 +1,60 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+#ifndef _BRIDGES_REMOTE_COUNTER_H_
+#define _BRIDGES_REMOTE_COUNTER_H_
+#include <stdio.h>
+#if OSL_DEBUG_LEVEL > 1
+struct MyCounter
+{
+ MyCounter( sal_Char const *pName ) :
+ m_nCounter( 0 ),
+ m_pName ( pName )
+ {
+ }
+ ~MyCounter()
+ {
+ if( m_nCounter ) {
+ printf(
+ "%s : %ld left\n", m_pName,
+ sal::static_int_cast< long >(m_nCounter) );
+ }
+ }
+ void acquire()
+ { m_nCounter ++; }
+ void release()
+ { m_nCounter --; }
+
+
+ sal_Int32 m_nCounter;
+ sal_Char const *m_pName;
+};
+#endif
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/bridges/remote/helper.hxx b/bridges/inc/bridges/remote/helper.hxx
new file mode 100644
index 000000000000..56de06b7d8c8
--- /dev/null
+++ b/bridges/inc/bridges/remote/helper.hxx
@@ -0,0 +1,71 @@
+/* -*- 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 <bridges/remote/bridgeimpl.hxx>
+
+typedef void ( SAL_CALL * ReleaseRemoteCallbackFunc ) (
+ remote_Interface *ppRemoteI,
+ rtl_uString *pOid,
+ typelib_TypeDescriptionReference *pTypeRef,
+ uno_Environment *pEnvRemote
+ );
+
+typedef void ( SAL_CALL * remote_createStubFunc ) (
+ remote_Interface **ppRemoteI,
+ rtl_uString *pOid ,
+ typelib_TypeDescriptionReference *pTypeRef,
+ uno_Environment *pEnvRemote,
+ ReleaseRemoteCallbackFunc callback
+ );
+namespace bridges_remote
+{
+
+ /** @param callback If the bridge implementation wants to handle the remote release call,
+ it can do it giving this callback. If callback == 0, the releaseRemote
+ method of the stub is called.
+ */
+ void SAL_CALL remote_createStub (
+ remote_Interface **ppRemoteI,
+ rtl_uString *pOid ,
+ typelib_TypeDescriptionReference *pType,
+ uno_Environment *pEnvRemote,
+ ReleaseRemoteCallbackFunc callback );
+
+ void SAL_CALL remote_retrieveOidFromProxy(
+ remote_Interface *pRemtoeI,
+ rtl_uString **ppOid );
+
+ void SAL_CALL remote_sendQueryInterface(
+ uno_Environment *pEnvRemote,
+ remote_Interface **ppRemoteI,
+ rtl_uString *pOid ,
+ typelib_TypeDescriptionReference *pType,
+ uno_Any **ppException
+ );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/bridges/remote/mapping.hxx b/bridges/inc/bridges/remote/mapping.hxx
new file mode 100644
index 000000000000..28903eff8ac2
--- /dev/null
+++ b/bridges/inc/bridges/remote/mapping.hxx
@@ -0,0 +1,72 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+#ifndef _BRIDGES_REMOTE_MAPPING_HXX_
+#define _BRIDGES_REMOTE_MAPPING_HXX_
+
+#include <osl/interlck.h>
+#include <rtl/ustring.hxx>
+
+#include <typelib/typedescription.h>
+
+#include <bridges/remote/remote.h>
+
+typedef struct _uno_Environment uno_Environment;
+
+namespace bridges_remote
+{
+ extern "C" typedef void SAL_CALL RemoteToUno(
+ uno_Mapping *pMapping, void **ppOut, void *pInterface,
+ typelib_InterfaceTypeDescription *pInterfaceTypeDescr );
+ RemoteToUno remoteToUno;
+
+ extern "C" typedef void SAL_CALL UnoToRemote(
+ uno_Mapping *pMapping, void **ppOut, void *pInterface,
+ typelib_InterfaceTypeDescription *pInterfaceTypeDescr );
+ UnoToRemote unoToRemote;
+
+ extern "C" typedef void SAL_CALL FreeRemoteMapping(uno_Mapping * mapping);
+ FreeRemoteMapping freeRemoteMapping;
+
+ class RemoteMapping :
+ public remote_Mapping
+ {
+ public:
+ RemoteMapping( uno_Environment *pEnvUno ,
+ uno_Environment *pEnvRemote,
+ uno_MapInterfaceFunc func ,
+ const ::rtl::OUString sPurpose);
+ ~RemoteMapping();
+
+ oslInterlockedCount m_nRef;
+ ::rtl::OUString m_sPurpose;
+ };
+
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/bridges/remote/proxy.hxx b/bridges/inc/bridges/remote/proxy.hxx
new file mode 100644
index 000000000000..25afecca6c13
--- /dev/null
+++ b/bridges/inc/bridges/remote/proxy.hxx
@@ -0,0 +1,94 @@
+/* -*- 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 <osl/interlck.h>
+
+#include <uno/environment.h>
+#include <uno/dispatcher.h>
+#include <uno/mapping.hxx>
+
+#include <bridges/remote/remote.h>
+
+namespace bridges_remote {
+
+extern "C" typedef void SAL_CALL FreeRemote2UnoProxy(
+ uno_ExtEnvironment * environment, void * proxy);
+FreeRemote2UnoProxy freeRemote2UnoProxy;
+
+// private:
+extern "C" typedef void SAL_CALL AcquireRemote2UnoProxy(uno_Interface *);
+AcquireRemote2UnoProxy acquireRemote2UnoProxy;
+
+// private:
+extern "C" typedef void SAL_CALL ReleaseRemote2UnoProxy(uno_Interface *);
+ReleaseRemote2UnoProxy releaseRemote2UnoProxy;
+
+// private:
+extern "C" typedef void SAL_CALL DispatchRemote2UnoProxy(
+ uno_Interface *, typelib_TypeDescription const *, void *, void **,
+ uno_Any **);
+DispatchRemote2UnoProxy dispatchRemote2UnoProxy;
+
+extern "C" void SAL_CALL remote_release( void * );
+
+class Remote2UnoProxy :
+ public uno_Interface
+{
+public:
+ Remote2UnoProxy(
+ remote_Interface *pRemoteI,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pType ,
+ uno_Environment *pEnvUno,
+ uno_Environment *pEnvRemote
+ );
+
+ ~Remote2UnoProxy();
+
+private:
+ ::rtl::OUString m_sOid;
+ typelib_InterfaceTypeDescription *m_pType;
+ remote_Interface *m_pRemoteI;
+ uno_Environment *m_pEnvUno;
+ uno_Environment *m_pEnvRemote;
+ ::com::sun::star::uno::Mapping m_mapRemote2Uno;
+ ::com::sun::star::uno::Mapping m_mapUno2Remote;
+
+ oslInterlockedCount m_nRef;
+
+ friend void SAL_CALL acquireRemote2UnoProxy(uno_Interface *);
+
+ friend void SAL_CALL releaseRemote2UnoProxy(uno_Interface *);
+
+ friend void SAL_CALL dispatchRemote2UnoProxy(
+ uno_Interface *, typelib_TypeDescription const *, void *, void **,
+ uno_Any **);
+};
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/bridges/remote/remote.h b/bridges/inc/bridges/remote/remote.h
new file mode 100644
index 000000000000..1e8ebabf2b93
--- /dev/null
+++ b/bridges/inc/bridges/remote/remote.h
@@ -0,0 +1,96 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+#ifndef _BRIDGES_REMOTE_REMOTE_H
+#define _BRIDGES_REMOTE_REMOTE_H
+#include <uno/mapping.h>
+#include <uno/any2.h>
+
+#include <typelib/typedescription.h>
+#include <uno/environment.h>
+
+#define CORBA_STRING8_NAME "com.sun.star.corba.CorbaString8"
+#define CORBA_STRING8_NAME_LENGTH (sizeof(CORBA_STRING8_NAME)-1)
+
+#define CORBA_UNION_NAME "com.sun.star.corba.CorbaUnion"
+#define CORBA_UNION_NAME_LENGTH (sizeof(CORBA_UNION_NAME)-1)
+
+#define REMOTE_MARSHALED_MSGHDR_SIZE 12
+#define REMOTE_RELEASE_METHOD_INDEX 2
+#define REMOTE_RELEASE_METHOD_NAME "release"
+
+#define CURRENT_IIOP_PROTOCOL_MAJOR 1
+#define CURRENT_IIOP_PROTOCOL_MINOR 2
+
+extern "C" {
+
+struct remote_Interface;
+
+/** @internal
+ */
+typedef void (SAL_CALL * remote_DispatchMethod)(
+ remote_Interface * pRemoteI, typelib_TypeDescription const * pMemberType,
+ void * pReturn, void * pArgs[], uno_Any ** ppException );
+
+/**
+ @internal
+ */
+typedef void ( SAL_CALL * requestClientSideDispatcher ) (
+ uno_Environment *pEnvRemote,
+ typelib_TypeDescription const * pMemberType,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pInterfaceType,
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException );
+
+/** The base class of an UNO interface in a remote environment.
+ */
+struct remote_Interface
+{
+ void (SAL_CALL * acquire)( remote_Interface * pInterface );
+
+ void (SAL_CALL * release)( remote_Interface * pInterface );
+
+ remote_DispatchMethod pDispatcher;
+};
+
+/** The mapping between an binary-c-uno and a remote environment.
+ @internal
+ */
+struct remote_Mapping
+{
+ uno_Mapping aBase;
+ uno_Environment *pEnvRemote;
+ uno_Environment *pEnvUno;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/bridges/remote/remote.hxx b/bridges/inc/bridges/remote/remote.hxx
new file mode 100644
index 000000000000..a4fcac21f1c8
--- /dev/null
+++ b/bridges/inc/bridges/remote/remote.hxx
@@ -0,0 +1,76 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+#ifndef _BRIDGES_REMOTE_REMOTE_HXX_
+#define _BRIDGES_REMOTE_REMOTE_HXX_
+#include <list>
+
+#include <osl/mutex.hxx>
+#include <osl/conditn.h>
+#include <osl/interlck.h>
+
+#include <uno/environment.h>
+
+#include <bridges/remote/remote.h>
+#include <bridges/remote/connection.h>
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+namespace bridges_remote {
+
+extern "C" typedef void SAL_CALL AcquireRemote2RemoteStub(
+ remote_Interface * pThis);
+AcquireRemote2RemoteStub acquireRemote2RemoteStub;
+
+extern "C" typedef void SAL_CALL FreeRemote2RemoteStub(
+ uno_ExtEnvironment * environment, void * stub);
+FreeRemote2RemoteStub freeRemote2RemoteStub;
+
+class Remote2RemoteStub :
+ public remote_Interface
+{
+public:
+ Remote2RemoteStub(rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pType,
+ uno_Environment *pEnvRemote,
+ requestClientSideDispatcher dispatch );
+ ~Remote2RemoteStub();
+
+ void releaseRemote();
+public:
+ ::rtl::OUString m_sOid;
+ typelib_InterfaceTypeDescription *m_pType;
+ oslInterlockedCount m_nRef;
+ uno_Environment *m_pEnvRemote;
+ requestClientSideDispatcher m_dispatch;
+ oslInterlockedCount m_nReleaseRemote;
+};
+
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/bridges/remote/stub.hxx b/bridges/inc/bridges/remote/stub.hxx
new file mode 100644
index 000000000000..b89389ec50fe
--- /dev/null
+++ b/bridges/inc/bridges/remote/stub.hxx
@@ -0,0 +1,67 @@
+/* -*- 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 <bridges/remote/remote.hxx>
+
+#include <uno/dispatcher.h>
+#include <uno/mapping.hxx>
+
+namespace bridges_remote {
+
+extern "C" typedef void SAL_CALL AcquireUno2RemoteStub( remote_Interface *pThis );
+AcquireUno2RemoteStub acquireUno2RemoteStub;
+
+extern "C" typedef void SAL_CALL FreeUno2RemoteStub(
+ uno_ExtEnvironment * environment, void * stub);
+FreeUno2RemoteStub freeUno2RemoteStub;
+
+class Uno2RemoteStub :
+ public remote_Interface
+{
+public:
+ Uno2RemoteStub( uno_Interface *pUnoI,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pType,
+ uno_Environment *pEnvUno,
+ uno_Environment *pEnvRemote );
+ ~Uno2RemoteStub();
+
+public:
+ ::rtl::OUString m_sOid;
+ typelib_InterfaceTypeDescription *m_pType;
+ uno_Interface *m_pUnoI;
+ oslInterlockedCount m_nRef;
+
+ uno_Environment *m_pEnvUno;
+ uno_Environment *m_pEnvRemote;
+ ::com::sun::star::uno::Mapping m_mapRemote2Uno;
+ ::com::sun::star::uno::Mapping m_mapUno2Remote;
+};
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/makefile.mk b/bridges/inc/makefile.mk
new file mode 100644
index 000000000000..de828a78479f
--- /dev/null
+++ b/bridges/inc/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# 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=inc
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.IF "$(ENABLE_PCH)"!=""
+ALLTAR : \
+ $(SLO)$/precompiled.pch \
+ $(SLO)$/precompiled_ex.pch
+
+.ENDIF # "$(ENABLE_PCH)"!=""
+
diff --git a/bridges/inc/pch/precompiled_bridges.cxx b/bridges/inc/pch/precompiled_bridges.cxx
new file mode 100644
index 000000000000..05fd24f32377
--- /dev/null
+++ b/bridges/inc/pch/precompiled_bridges.cxx
@@ -0,0 +1,31 @@
+/* -*- 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 "precompiled_bridges.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/inc/pch/precompiled_bridges.hxx b/bridges/inc/pch/precompiled_bridges.hxx
new file mode 100644
index 000000000000..3116a130f7ed
--- /dev/null
+++ b/bridges/inc/pch/precompiled_bridges.hxx
@@ -0,0 +1,155 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): Generated on 2006-09-01 17:49:31.967936
+
+#ifdef PRECOMPILED_HEADERS
+//---MARKER---
+#include "boost/static_assert.hpp"
+
+#include "com/sun/star/bridge/InvalidProtocolChangeException.hdl"
+#include "com/sun/star/bridge/InvalidProtocolChangeException.hpp"
+#include "com/sun/star/bridge/ProtocolProperty.hdl"
+#include "com/sun/star/bridge/ProtocolProperty.hpp"
+#include "com/sun/star/bridge/XBridge.hpp"
+#include "com/sun/star/bridge/XBridgeFactory.hpp"
+#include "com/sun/star/bridge/XInstanceProvider.hpp"
+#include "com/sun/star/bridge/XProtocolProperties.hdl"
+#include "com/sun/star/bridge/XProtocolProperties.hpp"
+#include "com/sun/star/bridge/XUnoUrlResolver.hpp"
+#include "com/sun/star/connection/ConnectionSetupException.hpp"
+#include "com/sun/star/connection/NoConnectException.hpp"
+#include "com/sun/star/connection/XAcceptor.hpp"
+#include "com/sun/star/connection/XConnection.hpp"
+#include "com/sun/star/connection/XConnector.hpp"
+#include "com/sun/star/frame/XComponentLoader.hpp"
+#include "com/sun/star/io/XInputStream.hpp"
+#include "com/sun/star/io/XOutputStream.hpp"
+#include "com/sun/star/lang/DisposedException.hdl"
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "com/sun/star/lang/IllegalArgumentException.hpp"
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/lang/XComponent.hpp"
+#include "com/sun/star/lang/XInitialization.hpp"
+#include "com/sun/star/lang/XMain.hpp"
+#include "com/sun/star/lang/XMultiComponentFactory.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XSingleComponentFactory.hpp"
+#include "com/sun/star/registry/InvalidRegistryException.hpp"
+#include "com/sun/star/registry/XImplementationRegistration.hpp"
+#include "com/sun/star/registry/XRegistryKey.hpp"
+#include "com/sun/star/text/XTextDocument.hpp"
+#include "com/sun/star/uno/Any.h"
+#include "com/sun/star/uno/Any.hxx"
+#include "com/sun/star/uno/DeploymentException.hpp"
+#include "com/sun/star/uno/Exception.hdl"
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/Reference.h"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hdl"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.h"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/Type.h"
+#include "com/sun/star/uno/Type.hxx"
+#include "com/sun/star/uno/TypeClass.hdl"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/uno/XInterface.hdl"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/uno/XNamingService.hpp"
+#include "com/sun/star/uno/genfunc.hxx"
+
+#include "cppu/macros.hxx"
+#include "cppu/unotype.hxx"
+
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/implbase3.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "cppuhelper/servicefactory.hxx"
+#include "cppuhelper/weak.hxx"
+
+
+#include "osl/conditn.h"
+#include "osl/conditn.hxx"
+#include "osl/diagnose.h"
+#include "osl/doublecheckedlocking.h"
+#include "osl/getglobalmutex.hxx"
+#include "osl/interlck.h"
+#include "osl/module.h"
+#include "osl/module.hxx"
+#include "osl/mutex.h"
+#include "osl/mutex.hxx"
+#include "osl/process.h"
+#include "osl/semaphor.h"
+#include "osl/thread.h"
+#include "osl/thread.hxx"
+#include "osl/time.h"
+
+#include "rtl/alloc.h"
+#include "rtl/byteseq.h"
+#include "rtl/byteseq.hxx"
+#include "rtl/instance.hxx"
+#include "rtl/memory.h"
+#include "rtl/process.h"
+#include "rtl/random.h"
+#include "rtl/strbuf.hxx"
+#include "rtl/string.h"
+#include "rtl/string.hxx"
+#include "rtl/unload.h"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "rtl/uuid.h"
+
+#include "sal/alloca.h"
+#include "sal/config.h"
+#include "sal/types.h"
+
+#include "sys/types.h"
+
+
+#include "typelib/typeclass.h"
+#include "typelib/typedescription.h"
+#include "typelib/typedescription.hxx"
+
+#include "uno/any2.h"
+#include "uno/data.h"
+#include "uno/dispatcher.h"
+#include "uno/environment.h"
+#include "uno/environment.hxx"
+#include "uno/lbnames.h"
+#include "uno/mapping.h"
+#include "uno/mapping.hxx"
+#include "uno/sequence2.h"
+#include "uno/threadpool.h"
+//---MARKER---
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/prj/build.lst b/bridges/prj/build.lst
new file mode 100644
index 000000000000..34eda8ae63c2
--- /dev/null
+++ b/bridges/prj/build.lst
@@ -0,0 +1,34 @@
+br bridges : cppuhelper jurt jvmaccess salhelper NULL
+br bridges usr1 - all br_mkout NULL
+br bridges\inc nmake - all br_inc NULL
+br bridges\unotypes nmake - all br_unotypes NULL
+br bridges\source\remote\static nmake - all br_rem_static br_unotypes br_inc NULL
+br bridges\source\remote\urp nmake - all br_rem_urp br_rem_static br_inc NULL
+br bridges\source\remote\context nmake - all br_rcon br_unotypes br_inc NULL
+br bridges\source\cpp_uno\mingw_intel nmake - w br_gcc3i br_cppuno_shared br_unotypes br_inc NULL
+br bridges\source\cpp_uno\msvc_win32_intel nmake - w br_msci br_cppuno_shared br_unotypes br_inc NULL
+br bridges\source\cpp_uno\gcc3_linux_intel nmake - u br_gcc3li br_cppuno_shared br_unotypes br_inc NULL
+br bridges\source\cpp_uno\gcc3_os2_intel nmake - p br_gcc3os br_cppuno_shared br_unotypes br_inc NULL
+br bridges\source\cpp_uno\gcc3_linux_x86-64 nmake - u br_gcc3lx br_cppuno_shared br_unotypes br_inc NULL
+br bridges\source\cpp_uno\gcc3_linux_powerpc nmake - u br_gcc3lp br_cppuno_shared br_unotypes br_inc NULL
+br bridges\source\cpp_uno\gcc3_aix_powerpc nmake - u br_gcc3ap br_cppuno_shared br_unotypes br_inc NULL
+br bridges\source\cpp_uno\gcc3_linux_powerpc64 nmake - u br_gcc3lp_64 br_cppuno_shared br_unotypes br_inc NULL
+br bridges\source\cpp_uno\gcc3_linux_mips nmake - u br_gcc3lmips br_cppuno_shared br_unotypes br_inc NULL
+br bridges\source\cpp_uno\gcc3_linux_m68k nmake - u br_gcc3lm68k br_cppuno_shared br_unotypes br_inc NULL
+br bridges\source\cpp_uno\gcc3_linux_s390 nmake - u br_gcc3l3 br_unotypes br_inc NULL
+br bridges\source\cpp_uno\gcc3_linux_s390x nmake - u br_gcc3l3_64 br_unotypes br_inc NULL
+br bridges\source\cpp_uno\gcc3_linux_sparc nmake - u br_gcc3ls br_unotypes br_cppuno_shared br_inc NULL
+br bridges\source\cpp_uno\gcc3_linux_arm nmake - u br_gcc3lr br_unotypes NULL
+br bridges\source\cpp_uno\gcc3_linux_ia64 nmake - u br_gcc3la br_unotypes NULL
+br bridges\source\cpp_uno\gcc3_linux_hppa nmake - u br_gcc3lh br_unotypes NULL
+br bridges\source\cpp_uno\gcc3_linux_alpha nmake - u br_gcc3ll br_unotypes NULL
+br bridges\source\cpp_uno\gcc3_macosx_intel nmake - u br_gcc3macoxi br_cppuno_shared br_unotypes br_inc NULL
+br bridges\source\cpp_uno\gcc3_macosx_powerpc nmake - u br_gcc3macoxp br_cppuno_shared br_unotypes br_inc NULL
+br bridges\source\cpp_uno\cc50_solaris_sparc nmake - u br_cc50sols br_unotypes br_cppuno_shared br_inc NULL
+br bridges\source\cpp_uno\cc5_solaris_sparc64 nmake - u br_cc5sols64 br_unotypes br_cppuno_shared br_inc NULL
+br bridges\source\cpp_uno\cc50_solaris_intel nmake - u br_cc50soli br_unotypes br_cppuno_shared br_inc NULL
+br bridges\source\cpp_uno\gcc3_solaris_sparc nmake - u br_gcc3sogs br_cppuno_shared br_unotypes br_inc NULL
+br bridges\source\cpp_uno\gcc3_solaris_intel nmake - u br_gcc3sogi br_cppuno_shared br_unotypes br_inc NULL
+br bridges\source\cpp_uno\shared nmake - all br_cppuno_shared br_unotypes br_inc NULL
+br bridges\source\jni_uno nmake - all br_jni_uno br_unotypes br_inc NULL
+br bridges\source\jni_uno\java\com\sun\star\bridges\jni_uno nmake - all br_jni_uno_java br_unotypes br_inc NULL
diff --git a/bridges/prj/d.lst b/bridges/prj/d.lst
new file mode 100644
index 000000000000..0b3dd93370d4
--- /dev/null
+++ b/bridges/prj/d.lst
@@ -0,0 +1,28 @@
+mkdir: %_DEST%\inc%_EXT%\bridges
+mkdir: %_DEST%\inc%_EXT%\bridges\remote
+
+..\inc\bridges\remote\connection.h %_DEST%\inc%_EXT%\bridges\remote\connection.h
+..\inc\bridges\remote\context.h %_DEST%\inc%_EXT%\bridges\remote\context.h
+..\inc\bridges\remote\remote.h %_DEST%\inc%_EXT%\bridges\remote\remote.h
+
+..\%__SRC%\lib\irmcxt* %_DEST%\lib%_EXT%\*
+..\%__SRC%\lib\librmcxt.*.* %_DEST%\lib%_EXT%\*
+..\%__SRC%\bin\rmcxt*.dll %_DEST%\bin%_EXT%\*
+
+..\%__SRC%\lib\liburp_uno* %_DEST%\lib%_EXT%\liburp_uno*
+..\%__SRC%\bin\urp_uno* %_DEST%\bin%_EXT%\urp_uno*
+..\%__SRC%\lib\libjava_uno* %_DEST%\lib%_EXT%\libjava_uno*
+..\%__SRC%\bin\java_uno* %_DEST%\bin%_EXT%\java_uno*
+..\%__SRC%\class\java_uno*.jar %_DEST%\bin%_EXT%\java_uno*.jar
+
+..\%__SRC%\bin\msci_uno.* %_DEST%\bin%_EXT%\msci_uno.*
+..\%__SRC%\bin\gcc3_uno.dll %_DEST%\bin%_EXT%\gcc3_uno.dll
+..\%__SRC%\lib\libgcc2_uno.* %_DEST%\lib%_EXT%\libgcc2_uno.*
+..\%__SRC%\lib\libgcc3_uno.* %_DEST%\lib%_EXT%\libgcc3_uno.*
+..\%__SRC%\bin\gcc3_uno.* %_DEST%\bin%_EXT%\gcc3_uno.*
+..\%__SRC%\lib\libsunpro5_uno.* %_DEST%\lib%_EXT%\libsunpro5_uno.*
+
+..\%__SRC%\lib\rmcxt3.lib %_DEST%\lib%_EXT%\rmcxt.lib
+
+
+linklib: librmcxt.*.*
diff --git a/bridges/source/bridge_exports.map b/bridges/source/bridge_exports.map
new file mode 100644
index 000000000000..df39965a2b51
--- /dev/null
+++ b/bridges/source/bridge_exports.map
@@ -0,0 +1,8 @@
+UDK_3_0_0 {
+ global:
+ component_canUnload;
+ uno_initEnvironment;
+ uno_ext_getMapping;
+ local:
+ *;
+};
diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/call.s b/bridges/source/cpp_uno/cc50_solaris_intel/call.s
new file mode 100644
index 000000000000..95bf79632031
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_intel/call.s
@@ -0,0 +1,248 @@
+ .align 4
+ .globl privateSnippetExecutorGeneral
+privateSnippetExecutorGeneral:
+ movl %esp,%ecx
+ pushl %ebp / proper stack frame needed for exception handling
+ movl %esp,%ebp
+ andl $0xFFFFFFF8,%esp / align following 64bit arg
+ subl $0x8,%esp / 64bit nRegReturn
+ pushl %ecx / 32bit pCallStack
+ pushl %edx / 32bit nVtableOffset
+ pushl %eax / 32bit nFunctionIndex
+ call cpp_vtable_call
+ movl 12(%esp),%eax / 64 bit nRegReturn, lower half
+ leave
+ ret
+ .type privateSnippetExecutorGeneral, @function
+ .size privateSnippetExecutorGeneral, .-privateSnippetExecutorGeneral
+
+ .align 4
+ .globl privateSnippetExecutorVoid
+privateSnippetExecutorVoid:
+ movl %esp,%ecx
+ pushl %ebp / proper stack frame needed for exception handling
+ movl %esp,%ebp
+ andl $0xFFFFFFF8,%esp / align following 64bit arg
+ subl $0x8,%esp / 64bit nRegReturn
+ pushl %ecx / 32bit pCallStack
+ pushl %edx / 32bit nVtableOffset
+ pushl %eax / 32bit nFunctionIndex
+ call cpp_vtable_call
+ leave
+ ret
+ .type privateSnippetExecutorVoid, @function
+ .size privateSnippetExecutorVoid, .-privateSnippetExecutorVoid
+
+ .align 4
+ .globl privateSnippetExecutorHyper
+privateSnippetExecutorHyper:
+ movl %esp,%ecx
+ pushl %ebp / proper stack frame needed for exception handling
+ movl %esp,%ebp
+ andl $0xFFFFFFF8,%esp / align following 64bit arg
+ subl $0x8,%esp / 64bit nRegReturn
+ pushl %ecx / 32bit pCallStack
+ pushl %edx / 32bit nVtableOffset
+ pushl %eax / 32bit nFunctionIndex
+ call cpp_vtable_call
+ movl 12(%esp),%eax / 64 bit nRegReturn, lower half
+ movl 16(%esp),%edx / 64 bit nRegReturn, upper half
+ leave
+ ret
+ .type privateSnippetExecutorHyper, @function
+ .size privateSnippetExecutorHyper, .-privateSnippetExecutorHyper
+
+ .align 4
+ .globl privateSnippetExecutorFloat
+privateSnippetExecutorFloat:
+ movl %esp,%ecx
+ pushl %ebp / proper stack frame needed for exception handling
+ movl %esp,%ebp
+ andl $0xFFFFFFF8,%esp / align following 64bit arg
+ subl $0x8,%esp / 64bit nRegReturn
+ pushl %ecx / 32bit pCallStack
+ pushl %edx / 32bit nVtableOffset
+ pushl %eax / 32bit nFunctionIndex
+ call cpp_vtable_call
+ flds 12(%esp) / 64 bit nRegReturn, lower half
+ leave
+ ret
+ .type privateSnippetExecutorFloat, @function
+ .size privateSnippetExecutorFloat, .-privateSnippetExecutorFloat
+
+ .align 4
+ .globl privateSnippetExecutorDouble
+privateSnippetExecutorDouble:
+ movl %esp,%ecx
+ pushl %ebp / proper stack frame needed for exception handling
+ movl %esp,%ebp
+ andl $0xFFFFFFF8,%esp / align following 64bit arg
+ subl $0x8,%esp / 64bit nRegReturn
+ pushl %ecx / 32bit pCallStack
+ pushl %edx / 32bit nVtableOffset
+ pushl %eax / 32bit nFunctionIndex
+ call cpp_vtable_call
+ fldl 12(%esp) / 64 bit nRegReturn
+ leave
+ ret
+ .type privateSnippetExecutorDouble, @function
+ .size privateSnippetExecutorDouble, .-privateSnippetExecutorDouble
+
+ .align 4
+ .globl privateSnippetExecutorStruct
+privateSnippetExecutorStruct:
+ movl %esp,%ecx
+ pushl %ebp / proper stack frame needed for exception handling
+ movl %esp,%ebp
+ andl $0xFFFFFFF8,%esp / align following 64bit arg
+ subl $0x8,%esp / 64bit nRegReturn
+ pushl %ecx / 32bit pCallStack
+ pushl %edx / 32bit nVtableOffset
+ pushl %eax / 32bit nFunctionIndex
+ call cpp_vtable_call
+ movl 12(%esp),%eax / 64 bit nRegReturn, lower half
+ leave
+ ret $4
+ .type privateSnippetExecutorStruct, @function
+ .size privateSnippetExecutorStruct, .-privateSnippetExecutorStruct
+
+ .align 4
+ .globl callVirtualMethod
+callVirtualMethod:
+ pushl %ebp
+ movl %esp, %ebp
+ subl $24, %esp
+ movl %edx, -4(%ebp)
+ movl %ecx, -8(%ebp)
+ movl %eax, -12(%ebp)
+ movl %esp, -16(%ebp)
+ movl %ebx, -20(%ebp)
+
+ / set ebx to GOT
+.L_GOT_BEGIN_2:
+ call .L_GOT_END_2
+.L_GOT_END_2:
+ popl %ebx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-.L_GOT_END_2],%ebx
+.callBeginPosition:
+ movl 28(%ebp), %eax
+ movl %eax, %edx
+ dec %edx
+ shl $2, %edx
+ add 24(%ebp), %edx
+.copyLong:
+ movl 0(%edx), %ecx
+ sub $4, %edx
+ push %ecx
+ dec %eax
+ jne .copyLong
+.doCall:
+ movl 8(%ebp), %edx
+ movl 0(%edx), %edx
+ movl 12(%ebp), %eax
+ add $2, %eax
+ shl $2, %eax
+ add %eax, %edx
+ movl 0(%edx), %edx
+
+ call *%edx
+
+.callVirtualMethodExceptionPosition:
+ / handle returns
+ movl 20(%ebp), %ecx
+
+ / byte types
+ cmp $2, %ecx / typelib_TypeClass_BOOLEAN
+ je .handleByte
+ cmp $3, %ecx
+ je .handleByte / typelib_TypeClass_BYTE
+
+ / half word types
+ cmp $4, %ecx / typelib_TypeClass_SHORT
+ je .handleShort
+ cmp $5, %ecx / typelib_TypeClass_UNSIGNED_SHORT
+ je .handleShort
+
+ / word types
+ cmp $6, %ecx / typelib_TypeClass_LONG
+ je .handleWord
+ cmp $7, %ecx / typelib_TypeClass_UNSIGNED_LONG
+ je .handleWord
+ cmp $1, %ecx / typelib_TypeClass_CHAR (wchar_t)
+ je .handleWord
+ cmp $15, %ecx / typelib_TypeClass_ENUM
+ je .handleWord
+
+ / double word types
+ cmp $8, %ecx / typelib_TypeClass_HYPER
+ je .handleDoubleWord
+ cmp $9, %ecx / typelib_TypeClass_UNSIGNED_HYPER
+ je .handleDoubleWord
+
+ / float
+ cmp $10, %ecx / typelib_TypeClass_FLOAT
+ je .handleFloat
+
+ / double
+ cmp $11, %ecx / typelib_TypeClass_DOUBLE
+ je .handleDouble
+
+ / default: return void
+ jmp .doRestore
+.handleByte:
+ movl 16(%ebp), %ecx
+ movb %al, 0(%ecx)
+ jmp .doRestore
+.handleShort:
+ movl 16(%ebp), %ecx
+ movw %ax, 0(%ecx)
+ jmp .doRestore
+.handleWord:
+ movl 16(%ebp), %ecx
+ movl %eax, 0(%ecx)
+ jmp .doRestore
+.handleDoubleWord:
+ movl 16(%ebp), %ecx
+ movl %eax, 0(%ecx)
+ movl %edx, 4(%ecx)
+ jmp .doRestore
+.handleFloat:
+ movl 16(%ebp), %ecx
+ fstps 0(%ecx)
+ jmp .doRestore
+.handleDouble:
+ movl 16(%ebp), %ecx
+ fstpl 0(%ecx)
+ jmp .doRestore
+.doRestore:
+ movl -4(%ebp), %edx
+ movl -8(%ebp), %ecx
+ movl -12(%ebp), %eax
+ movl -20(%ebp), %ebx
+ movl %ebp, %esp
+ popl %ebp
+ ret
+ .type callVirtualMethod, @function
+ .size callVirtualMethod, .-callVirtualMethod
+
+ .globl callVirtualMethodExceptionHandler
+callVirtualMethodExceptionHandler:
+ movl -4(%ebp), %edx
+ movl -8(%ebp), %ecx
+ movl -12(%ebp), %eax
+ movl -16(%ebp), %esp
+ movl -20(%ebp), %ebx
+ call __1cG__CrunMex_rethrow_q6F_v_@PLT
+ ret
+
+ .type callVirtualMethodExceptionHandler, @function
+ .size callVirtualMethodExceptionHandler, .-callVirtualMethodExceptionHandler
+
+
+ .section .exception_ranges,"aw"
+ .align 4
+
+ .4byte .callBeginPosition@rel
+ .4byte .callVirtualMethodExceptionPosition-.callBeginPosition
+ .4byte callVirtualMethodExceptionHandler-.callBeginPosition
+ .zero 8
diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/cc50_solaris_intel.hxx b/bridges/source/cpp_uno/cc50_solaris_intel/cc50_solaris_intel.hxx
new file mode 100644
index 000000000000..8e938e2c8105
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_intel/cc50_solaris_intel.hxx
@@ -0,0 +1,75 @@
+/* -*- 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 <cstddef>
+#include <rtl/string.hxx>
+#include <typeinfo>
+
+typedef struct _uno_Any uno_Any;
+typedef struct _uno_Mapping uno_Mapping;
+
+// private C50 structures and functions
+namespace __Crun
+{
+ struct static_type_info
+ {
+ std::ptrdiff_t m_pClassName;
+ int m_nSkip1; // must be 0
+ void* m_pMagic; // points to some magic data
+ int m_nMagic[ 4 ];
+ int m_nSkip2[2]; // must be 0
+ };
+ void* ex_alloc(unsigned);
+ void ex_throw( void*, const static_type_info*, void(*)(void*));
+ void* ex_get();
+ void ex_rethrow_q();
+}
+
+namespace __Cimpl
+{
+ const char* ex_name();
+}
+
+extern "C" void _ex_register( void*, int );
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+//##################################################################################################
+//#### exceptions ##################################################################################
+//##################################################################################################
+
+void cc50_solaris_intel_raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+
+void cc50_solaris_intel_fillUnoException(
+ void*, const char*,
+ uno_Any*, uno_Mapping * pCpp2Uno );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/cpp2uno.cxx b/bridges/source/cpp_uno/cc50_solaris_intel/cpp2uno.cxx
new file mode 100644
index 000000000000..0737475c995a
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_intel/cpp2uno.cxx
@@ -0,0 +1,530 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sal/alloca.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "cc50_solaris_intel.hxx"
+
+using namespace com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+void cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ // pCallStack: ret, [return ptr], this, params
+ char * pCppStack = (char *)(pCallStack +1);
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void**)pCppStack;
+ pCppStack += sizeof( void* );
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ // value
+ {
+ pCppArgs[ nPos ] = pUnoArgs[ nPos ] = pCppStack;
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ pCppArgs[nPos] = *(void **)pCppStack;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case no exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::cc50_solaris_intel_raiseException(
+ &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData(
+ pCppArgs[nIndex], pParamTypeDescr,
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+ }
+}
+
+
+//==================================================================================================
+extern "C" void cpp_vtable_call(
+ int nFunctionIndex, int nVtableOffset, void** pCallStack,
+ sal_Int64 nRegReturn )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: ret adr, [ret *], this, params
+ void * pThis;
+ if( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = pCallStack[2];
+ }
+ else
+ {
+ pThis = pCallStack[1];
+ }
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex,
+ "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException( rtl::OUString::createFromAscii("illegal vtable index!"), (XInterface *)pThis );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, &nRegReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, &nRegReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ // standard XInterface vtable calls
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[3] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pCallStack[1] ),
+ &pInterface, pTD,
+ reinterpret_cast< uno_AcquireFunc >(cpp_acquire) );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)&nRegReturn = pCallStack[1];
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, &nRegReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException( rtl::OUString::createFromAscii("no member description found!"), (XInterface *)pThis );
+ }
+ }
+}
+
+//==================================================================================================
+bool isSimpleStruct(typelib_TypeDescriptionReference * type) {
+ typelib_TypeDescription * td = 0;
+ TYPELIB_DANGER_GET(&td, type);
+ OSL_ASSERT(td != 0);
+ for (typelib_CompoundTypeDescription * ctd
+ = reinterpret_cast< typelib_CompoundTypeDescription * >(td);
+ ctd != 0; ctd = ctd->pBaseTypeDescription)
+ {
+ OSL_ASSERT(ctd->aBase.eTypeClass == typelib_TypeClass_STRUCT);
+ for (sal_Int32 i = 0; i < ctd->nMembers; ++i) {
+ typelib_TypeClass c = ctd->ppTypeRefs[i]->eTypeClass;
+ switch (c) {
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_INTERFACE:
+ return false;
+ case typelib_TypeClass_STRUCT:
+ if (!isSimpleStruct(ctd->ppTypeRefs[i])) {
+ return false;
+ }
+ break;
+ default:
+ OSL_ASSERT(
+ c <= typelib_TypeClass_DOUBLE
+ || c == typelib_TypeClass_ENUM);
+ break;
+ }
+ }
+ }
+ TYPELIB_DANGER_RELEASE(td);
+ return true;
+}
+
+extern "C" void privateSnippetExecutorGeneral();
+extern "C" void privateSnippetExecutorVoid();
+extern "C" void privateSnippetExecutorHyper();
+extern "C" void privateSnippetExecutorFloat();
+extern "C" void privateSnippetExecutorDouble();
+extern "C" void privateSnippetExecutorStruct();
+extern "C" typedef void (*PrivateSnippetExecutor)();
+
+int const codeSnippetSize = 16;
+
+unsigned char * codeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ typelib_TypeDescriptionReference * returnType)
+{
+ typelib_TypeClass c = returnType == 0
+ ? typelib_TypeClass_VOID : returnType->eTypeClass;
+ if (returnType != 0 && !bridges::cpp_uno::shared::isSimpleType(c)) {
+ functionIndex |= 0x80000000;
+ }
+ PrivateSnippetExecutor exec;
+ switch (c) {
+ case typelib_TypeClass_VOID:
+ exec = privateSnippetExecutorVoid;
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ exec = privateSnippetExecutorHyper;
+ break;
+ case typelib_TypeClass_FLOAT:
+ exec = privateSnippetExecutorFloat;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ exec = privateSnippetExecutorDouble;
+ break;
+ case typelib_TypeClass_STRUCT:
+ OSL_ASSERT(returnType != 0);
+ // For "simple" (more-or-less POD, but not exactly) structs, the caller
+ // pops the pointer to the return value off the stack, as documented in
+ // the Intel SYSV ABI; for other structs (which includes STRING, TYPE,
+ // ANY, sequences, and interfaces, btw.), the callee pops the pointer to
+ // the return value off the stack:
+ exec = isSimpleStruct(returnType)
+ ? privateSnippetExecutorStruct : privateSnippetExecutorGeneral;
+ break;
+ default:
+ exec = privateSnippetExecutorGeneral;
+ break;
+ }
+ unsigned char * p = code;
+ OSL_ASSERT(sizeof (sal_Int32) == 4);
+ // mov function_index, %eax:
+ *p++ = 0xB8;
+ *reinterpret_cast< sal_Int32 * >(p) = functionIndex;
+ p += sizeof (sal_Int32);
+ // mov vtable_offset, %edx:
+ *p++ = 0xBA;
+ *reinterpret_cast< sal_Int32 * >(p) = vtableOffset;
+ p += sizeof (sal_Int32);
+ // jmp privateSnippetExecutor:
+ *p++ = 0xE9;
+#pragma disable_warn
+ void * e = reinterpret_cast< void * >(exec);
+#pragma enable_warn
+ *reinterpret_cast< sal_Int32 * >(p)
+ = static_cast< unsigned char * >(e) - p - sizeof (sal_Int32);
+ p += sizeof (sal_Int32);
+ OSL_ASSERT(p - code <= codeSnippetSize);
+ return code + codeSnippetSize;
+}
+
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block) {
+ return static_cast< Slot * >(block) + 1;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 3) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block) + 2;
+ slots[-3].fn = 0; // RTTI
+ slots[-2].fn = 0; // null
+ slots[-1].fn = 0; // destructor
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef);
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vtableOffset, 0);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef);
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const *, unsigned char const *)
+{}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/except.cxx b/bridges/source/cpp_uno/cc50_solaris_intel/except.cxx
new file mode 100644
index 000000000000..e0776c19476c
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_intel/except.cxx
@@ -0,0 +1,451 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <cstddef>
+#include <dlfcn.h>
+#include <new.h>
+#include <typeinfo>
+#include <list>
+#include <map>
+#include <rtl/alloc.h>
+#include <osl/diagnose.h>
+
+#include <rtl/strbuf.hxx>
+#include <typelib/typedescription.hxx>
+#include <com/sun/star/uno/Any.hxx>
+
+#include "bridges/cpp_uno/shared/arraypointer.hxx"
+
+#include "cc50_solaris_intel.hxx"
+
+#include <hash.cxx>
+
+// need a += operator for OString and sal_Char
+namespace rtl
+{
+ inline OString& operator+=( OString& rString, sal_Char cAdd )
+ {
+ sal_Char add[2];
+ add[0] = cAdd;
+ add[1] = 0;
+ return rString += add;
+ }
+}
+
+using namespace std;
+using namespace osl;
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+static OString toUNOname( const OString & rRTTIname )
+{
+ OString aRet;
+
+ const sal_Char* pRTTI = rRTTIname.getStr();
+ const sal_Char* pOrg = pRTTI;
+ const sal_Char* pLast = pRTTI;
+
+ while( 1 )
+ {
+ if( *pRTTI == ':' || ! *pRTTI )
+ {
+ if( aRet.getLength() )
+ aRet += ".";
+ aRet += rRTTIname.copy( pLast - pOrg, pRTTI - pLast );
+ while( *pRTTI == ':' )
+ pRTTI++;
+ pLast = pRTTI;
+ if( ! *pRTTI )
+ break;
+ }
+ else
+ pRTTI++;
+ }
+
+ return aRet;
+}
+//==================================================================================================
+static OString toRTTIname( const OString & rUNOname )
+{
+ OStringBuffer aRet( rUNOname.getLength()*2 );
+
+ sal_Int32 nIndex = 0;
+ do
+ {
+ if( nIndex > 0 )
+ aRet.append( "::" );
+ aRet.append( rUNOname.getToken( 0, '.', nIndex ) );
+ } while( nIndex != -1 );
+
+ return aRet.makeStringAndClear();
+}
+//==================================================================================================
+
+static OString toRTTImangledname( const OString & rRTTIname )
+{
+ if( ! rRTTIname.getLength() )
+ return OString();
+
+ OStringBuffer aRet( rRTTIname.getLength()*2 );
+
+ aRet.append( "__1n" );
+ sal_Int32 nIndex = 0;
+ do
+ {
+ OString aToken( rRTTIname.getToken( 0, ':', nIndex ) );
+ int nBytes = aToken.getLength();
+ if( nBytes )
+ {
+ if( nBytes > 25 )
+ {
+ aRet.append( (sal_Char)( nBytes/26 + 'a' ) );
+ aRet.append( (sal_Char)( nBytes%26 + 'A' ) );
+ }
+ else
+ aRet.append( (sal_Char)( nBytes + 'A' ) );
+ for (sal_Int32 i = 0; i < aToken.getLength(); ++i) {
+ char c = aToken[i];
+ if (c == 'Q') {
+ aRet.append("QdD");
+ } else {
+ aRet.append(c);
+ }
+ }
+ }
+ } while( nIndex != -1 );
+
+ aRet.append( '_' );
+
+ return aRet.makeStringAndClear();
+}
+
+//##################################################################################################
+//#### RTTI simulation #############################################################################
+//##################################################################################################
+
+class RTTIHolder
+{
+ std::map< OString, void* > aAllRTTI;
+public:
+ ~RTTIHolder();
+
+ void* getRTTI( const OString& rTypename );
+ void* getRTTI_UnoName( const OString& rUnoTypename )
+ { return getRTTI( toRTTIname( rUnoTypename ) ); }
+
+ void* insertRTTI( const OString& rTypename );
+ void* insertRTTI_UnoName( const OString& rTypename )
+ { return insertRTTI( toRTTIname( rTypename ) ); }
+ void* generateRTTI( typelib_CompoundTypeDescription* pCompTypeDescr );
+};
+
+RTTIHolder::~RTTIHolder()
+{
+ for ( std::map< OString, void* >::const_iterator iPos( aAllRTTI.begin() );
+ iPos != aAllRTTI.end(); ++iPos )
+ {
+ delete[] static_cast< char * >(iPos->second);
+ }
+}
+
+#if OSL_DEBUG_LEVEL > 1
+#include <stdio.h>
+#endif
+
+void* RTTIHolder::getRTTI( const OString& rTypename )
+{
+ std::map< OString, void* >::iterator element;
+
+ element = aAllRTTI.find( rTypename );
+ if( element != aAllRTTI.end() )
+ return (*element).second;
+
+ // create rtti structure
+ element = aAllRTTI.find( rTypename );
+ if( element != aAllRTTI.end() )
+ return (*element).second;
+
+ return NULL;
+}
+
+static long nMagicId = 1;
+
+void* RTTIHolder::insertRTTI( const OString& rTypename )
+{
+ OString aMangledName( toRTTImangledname( rTypename ) );
+ NIST_Hash aHash( aMangledName.getStr(), aMangledName.getLength() );
+
+
+ // rSuperTypename MUST exist !!!
+ std::size_t const RTTI_SIZE = 19; // 14???
+ void** pRTTI = reinterpret_cast< void ** >(
+ new char[RTTI_SIZE * sizeof (void *) + strlen(rTypename.getStr()) + 1]);
+ pRTTI[ 0 ] = reinterpret_cast< void * >(RTTI_SIZE * sizeof (void *));
+ pRTTI[ 1 ] = NULL;
+ pRTTI[ 2 ] = (void*)(7*sizeof(void*));
+ pRTTI[ 3 ] = (void*)aHash.getHash()[0];
+ pRTTI[ 4 ] = (void*)aHash.getHash()[1];
+ pRTTI[ 5 ] = (void*)aHash.getHash()[2];
+ pRTTI[ 6 ] = (void*)aHash.getHash()[3];
+ pRTTI[ 7 ] = NULL;
+ pRTTI[ 8 ] = NULL;
+
+ pRTTI[ 9 ] = pRTTI[ 3 ];
+ pRTTI[ 10 ] = pRTTI[ 4 ];
+ pRTTI[ 11 ] = pRTTI[ 5 ];
+ pRTTI[ 12 ] = pRTTI[ 6 ];
+ pRTTI[ 13 ] = (void*)0x80000000;
+ strcpy(reinterpret_cast< char * >(pRTTI + RTTI_SIZE), rTypename.getStr());
+
+ aAllRTTI[ rTypename ] = (void*)pRTTI;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,
+ "generating base RTTI for type %s:\n"
+ " mangled: %s\n"
+ " hash: %.8x %.8x %.8x %.8x\n",
+ rTypename.getStr(),
+ aMangledName.getStr(),
+ pRTTI[ 3 ], pRTTI[ 4 ], pRTTI[ 5 ], pRTTI[ 6 ]
+ );
+#endif
+ return pRTTI;
+}
+
+void* RTTIHolder::generateRTTI( typelib_CompoundTypeDescription * pCompTypeDescr )
+{
+ OString aUNOCompTypeName( OUStringToOString( pCompTypeDescr->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ OString aRTTICompTypeName( toRTTIname( aUNOCompTypeName ) );
+
+ void* pHaveRTTI = getRTTI( aRTTICompTypeName );
+ if( pHaveRTTI )
+ return pHaveRTTI;
+
+ if( ! pCompTypeDescr->pBaseTypeDescription )
+ // this is a base type
+ return insertRTTI( aRTTICompTypeName );
+
+ // get base class RTTI
+ void* pSuperRTTI = generateRTTI( pCompTypeDescr->pBaseTypeDescription );
+ OSL_ENSURE( pSuperRTTI, "could not generate RTTI for supertype !" );
+
+ // find out the size to allocate for RTTI
+ void** pInherit = (void**)((sal_uInt32)pSuperRTTI + ((sal_uInt32*)pSuperRTTI)[2] + 8);
+ int nInherit;
+ for( nInherit = 1; pInherit[ nInherit*5-1 ] != (void*)0x80000000; nInherit++ )
+ ;
+
+ OString aMangledName( toRTTImangledname( aRTTICompTypeName ) );
+ NIST_Hash aHash( aMangledName.getStr(), aMangledName.getLength() );
+
+ std::size_t const rttiSize = 14 + nInherit * 5;
+ void** pRTTI = reinterpret_cast< void ** >(
+ new char[
+ rttiSize * sizeof (void *)
+ + strlen(aRTTICompTypeName.getStr()) + 1]);
+ pRTTI[ 0 ] = reinterpret_cast< void * >(rttiSize * sizeof (void *));
+ pRTTI[ 1 ] = NULL;
+ pRTTI[ 2 ] = (void*)(7*sizeof(void*));
+ pRTTI[ 3 ] = (void*)aHash.getHash()[0];
+ pRTTI[ 4 ] = (void*)aHash.getHash()[1];
+ pRTTI[ 5 ] = (void*)aHash.getHash()[2];
+ pRTTI[ 6 ] = (void*)aHash.getHash()[3];
+ pRTTI[ 7 ] = NULL;
+ pRTTI[ 8 ] = NULL;
+
+ memcpy( pRTTI+9, pInherit, 4*nInherit*5 );
+ pRTTI[ 8 +nInherit*5 ] = NULL;
+ pRTTI[ 9 +nInherit*5 ] = pRTTI[ 3 ];
+ pRTTI[ 10+nInherit*5 ] = pRTTI[ 4 ];
+ pRTTI[ 11+nInherit*5 ] = pRTTI[ 5 ];
+ pRTTI[ 12+nInherit*5 ] = pRTTI[ 6 ];
+ pRTTI[ 13+nInherit*5 ] = (void*)0x80000000;
+ strcpy(
+ reinterpret_cast< char * >(pRTTI + rttiSize),
+ aRTTICompTypeName.getStr());
+
+ aAllRTTI[ aRTTICompTypeName ] = (void*)pRTTI;
+
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,
+ "generating struct RTTI for type %s:\n"
+ " mangled: %s\n"
+ " hash: %.8x %.8x %.8X %.8x\n",
+ aRTTICompTypeName.getStr(),
+ aMangledName.getStr(),
+ pRTTI[ 3 ], pRTTI[ 4 ], pRTTI[ 5 ], pRTTI[ 6 ]
+ );
+#endif
+
+ return pRTTI;
+}
+
+//__________________________________________________________________________________________________
+
+static void deleteException(
+ void* pExc, unsigned char* thunk, typelib_TypeDescription* pType )
+{
+ uno_destructData(
+ pExc, pType, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ typelib_typedescription_release( pType );
+ delete[] thunk;
+}
+
+//__________________________________________________________________________________________________
+
+//##################################################################################################
+//#### exported ####################################################################################
+//##################################################################################################
+
+void cc50_solaris_intel_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() );
+#endif
+ bridges::cpp_uno::shared::ArrayPointer< unsigned char > thunkPtr(
+ new unsigned char[24]);
+ typelib_TypeDescription * pTypeDescr = 0;
+ // will be released by deleteException
+ typelib_typedescriptionreference_getDescription( &pTypeDescr, pUnoExc->pType );
+
+ void* pRTTI;
+ {
+ static ::osl::Mutex aMutex;
+ ::osl::Guard< ::osl::Mutex > guard( aMutex );
+
+ static RTTIHolder * s_pRTTI = 0;
+ if (! s_pRTTI)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_pRTTI = new RTTIHolder();
+#else
+ static RTTIHolder s_aRTTI;
+ s_pRTTI = &s_aRTTI;
+#endif
+ }
+
+ pRTTI = s_pRTTI->generateRTTI( (typelib_CompoundTypeDescription *)pTypeDescr );
+ }
+
+ // a must be
+ OSL_ENSURE( sizeof(sal_Int32) == sizeof(void *), "### pointer size differs from sal_Int32!" );
+
+ void * pCppExc = __Crun::ex_alloc( pTypeDescr->nSize );
+ uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ uno_any_destruct( pUnoExc, 0 );
+
+ unsigned char * thunk = thunkPtr.release();
+ // movl %esp, %ecx:
+ thunk[0] = 0x8B;
+ thunk[1] = 0xCC;
+ // pushl pTypeDescr:
+ thunk[2] = 0x68;
+ *reinterpret_cast< void ** >(thunk + 3) = pTypeDescr;
+ // pushl thunk:
+ thunk[7] = 0x68;
+ *reinterpret_cast< void ** >(thunk + 8) = thunk;
+ // pushl 4(%ecx):
+ thunk[12] = 0xFF;
+ thunk[13] = 0x71;
+ thunk[14] = 0x04;
+ // call deleteException:
+ thunk[15] = 0xE8;
+#pragma disable_warn
+ void * d = reinterpret_cast< void * >(deleteException);
+#pragma enable_warn
+ *reinterpret_cast< std::ptrdiff_t * >(thunk + 16) =
+ static_cast< unsigned char * >(d) - (thunk + 20);
+ // addl $12, %esp:
+ thunk[20] = 0x83;
+ thunk[21] = 0xC4;
+ thunk[22] = 0x0C;
+ // ret:
+ thunk[23] = 0xC3;
+
+#pragma disable_warn
+ void (* f)(void *) = reinterpret_cast< void (*)(void *) >(thunk);
+#pragma enable_warn
+ __Crun::ex_throw(pCppExc, (const __Crun::static_type_info*)pRTTI, f);
+}
+
+void cc50_solaris_intel_fillUnoException(
+ void* pCppExc,
+ const char* pInfo,
+ uno_Any* pUnoExc,
+ uno_Mapping * pCpp2Uno )
+{
+ OSL_ASSERT( pInfo != 0 );
+ OString uno_name( toUNOname( pInfo ) );
+ OUString aName( OStringToOUString(
+ uno_name, RTL_TEXTENCODING_ASCII_US ) );
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ typelib_typedescription_getByName( &pExcTypeDescr, aName.pData );
+
+ if (pExcTypeDescr == 0) // the thing that should not be
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "exception type not found: ") ) + aName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert(
+ pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString(
+ aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "> c++ exception occured: %s\n",
+ ::rtl::OUStringToOString(
+ pExcTypeDescr->pTypeName,
+ RTL_TEXTENCODING_ASCII_US ).getStr() );
+#endif
+ // construct uno exception any
+ uno_any_constructAndConvert(
+ pUnoExc, pCppExc, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/hash.cxx b/bridges/source/cpp_uno/cc50_solaris_intel/hash.cxx
new file mode 100644
index 000000000000..c1c2c2dc8eb6
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_intel/hash.cxx
@@ -0,0 +1,264 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+
+#ifndef TEST
+#include <sal/types.h>
+#else
+typedef unsigned int sal_uInt32;
+#endif
+
+#include <string.h>
+
+/*
+ * build a hash for a character buffer using the NIST algorithm
+ */
+
+class NIST_Hash
+{
+
+ // helper functions
+ sal_uInt32 f1( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
+ {
+ return z ^ ( x & ( y ^ z ) );
+ }
+
+ sal_uInt32 f2( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
+ {
+ return x ^ y ^ z;
+ }
+
+ sal_uInt32 f3( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
+ {
+ return ( x & y ) + ( z & ( x ^ y ) );
+ }
+
+ sal_uInt32 rotl( sal_uInt32 nValue, sal_uInt32 nBits )
+ {
+ return ( nValue << nBits ) | ( nValue >> (32-nBits) );
+ }
+
+ sal_uInt32 expand_nostore( sal_uInt32 index )
+ {
+ return data[index&15] ^ data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15];
+ }
+
+ sal_uInt32 expand_store( sal_uInt32 index )
+ {
+ return data[index&15] ^= data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15];
+ }
+
+ void subRound( sal_uInt32 a, sal_uInt32& b, sal_uInt32 c, sal_uInt32 d, sal_uInt32& e, sal_uInt32 constant, sal_uInt32 datum, sal_uInt32 nFunction )
+ {
+ e += rotl(a,5);
+ switch( nFunction )
+ {
+ case 1: e += f1( b, c, d );break;
+ case 2:
+ case 4: e += f2( b, c, d );break;
+ case 3: e += f3( b, c, d );break;
+ }
+ e += constant + datum;
+ b = rotl( b, 30 );
+ }
+
+ void transform();
+ void final();
+
+ // data members
+ sal_uInt32 data[16];
+ sal_uInt32 hashdata[5];
+public:
+ NIST_Hash( const char* pString, sal_uInt32 nLen );
+
+ sal_uInt32 *getHash() { return hashdata; }
+};
+
+void NIST_Hash::transform()
+{
+ // constants
+ const sal_uInt32 K2 = 0x5A827999;
+ const sal_uInt32 K3 = 0x6ED9EBA1;
+ const sal_uInt32 K5 = 0x8F1BBCDC;
+ const sal_uInt32 K10 = 0xCA62C1D6;
+
+ sal_uInt32 a, b, c, d, e;
+ a = hashdata[0];
+ b = hashdata[1];
+ c = hashdata[2];
+ d = hashdata[3];
+ e = hashdata[4];
+
+ subRound( a, b, c, d, e, K2, data[ 0], 1 );
+ subRound( e, a, b, c, d, K2, data[ 1], 1 );
+ subRound( d, e, a, b, c, K2, data[ 2], 1 );
+ subRound( c, d, e, a, b, K2, data[ 3], 1 );
+ subRound( b, c, d, e, a, K2, data[ 4], 1 );
+ subRound( a, b, c, d, e, K2, data[ 5], 1 );
+ subRound( e, a, b, c, d, K2, data[ 6], 1 );
+ subRound( d, e, a, b, c, K2, data[ 7], 1 );
+ subRound( c, d, e, a, b, K2, data[ 8], 1 );
+ subRound( b, c, d, e, a, K2, data[ 9], 1 );
+ subRound( a, b, c, d, e, K2, data[10], 1 );
+ subRound( e, a, b, c, d, K2, data[11], 1 );
+ subRound( d, e, a, b, c, K2, data[12], 1 );
+ subRound( c, d, e, a, b, K2, data[13], 1 );
+ subRound( b, c, d, e, a, K2, data[14], 1 );
+ subRound( a, b, c, d, e, K2, data[15], 1 );
+ subRound( e, a, b, c, d, K2, expand_store( 16 ), 1 );
+ subRound( d, e, a, b, c, K2, expand_store( 17 ), 1 );
+ subRound( c, d, e, a, b, K2, expand_store( 18 ), 1 );
+ subRound( b, c, d, e, a, K2, expand_store( 19 ), 1 );
+
+ subRound( a, b, c, d, e, K3, expand_store( 20 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 21 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 22 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 23 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 24 ), 2 );
+ subRound( a, b, c, d, e, K3, expand_store( 25 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 26 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 27 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 28 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 29 ), 2 );
+ subRound( a, b, c, d, e, K3, expand_store( 30 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 31 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 32 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 33 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 34 ), 2 );
+ subRound( a, b, c, d, e, K3, expand_store( 35 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 36 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 37 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 38 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 39 ), 2 );
+
+ subRound( a, b, c, d, e, K5, expand_store( 40 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 41 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 42 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 43 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 44 ), 3 );
+ subRound( a, b, c, d, e, K5, expand_store( 45 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 46 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 47 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 48 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 49 ), 3 );
+ subRound( a, b, c, d, e, K5, expand_store( 50 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 51 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 52 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 53 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 54 ), 3 );
+ subRound( a, b, c, d, e, K5, expand_store( 55 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 56 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 57 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 58 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 59 ), 3 );
+
+ subRound( a, b, c, d, e, K10, expand_store( 60 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 61 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_store( 62 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_store( 63 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_store( 64 ), 4 );
+ subRound( a, b, c, d, e, K10, expand_store( 65 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 66 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_store( 67 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_store( 68 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_store( 69 ), 4 );
+ subRound( a, b, c, d, e, K10, expand_store( 70 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 71 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_store( 72 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_store( 73 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_store( 74 ), 4 );
+ subRound( a, b, c, d, e, K10, expand_store( 75 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 76 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_nostore( 77 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_nostore( 78 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_nostore( 79 ), 4 );
+
+ hashdata[0] += a;
+ hashdata[1] += b;
+ hashdata[2] += c;
+ hashdata[3] += d;
+ hashdata[4] += e;
+}
+
+#define BLOCKSIZE sizeof( data )
+
+NIST_Hash::NIST_Hash( const char* pString, sal_uInt32 nLen )
+{
+ hashdata[0] = 0x67452301;
+ hashdata[1] = 0xefcdab89;
+ hashdata[2] = 0x98badcfe;
+ hashdata[3] = 0x10325476;
+ hashdata[4] = 0xc3d2e1f0;
+
+ sal_uInt32 nBytes = nLen;
+
+ while( nLen >= sizeof( data ) )
+ {
+ memcpy( data, pString, sizeof( data ) );
+ pString += sizeof( data );
+ nLen -= sizeof( data );
+ transform();
+ }
+ memcpy( data, pString, nLen );
+ ((char*)data)[nLen++] = 0x80;
+ if( nLen > sizeof( data ) - 8 )
+ {
+ memset( ((char*)data)+nLen, 0, sizeof( data ) - nLen );
+ transform();
+ memset( data, 0, sizeof( data ) - 8 );
+ }
+ else
+ memset( ((char*)data)+nLen, 0, sizeof( data ) - 8 - nLen );
+ data[14] = 0;
+ data[15] = nBytes << 3;
+ transform();
+}
+
+#ifdef TEST
+#include <stdio.h>
+int main( int argc, const char** argv )
+{
+ const char* pHash = argc < 2 ? argv[0] : argv[1];
+
+ NIST_Hash aHash( pHash, strlen( pHash ) );
+ sal_uInt32* pBits = aHash.getHash();
+
+ printf( "text : %s\n"
+ "bits : 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
+ pHash,
+ pBits[0], pBits[1], pBits[2],pBits[3],pBits[4]
+ );
+ return 0;
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/makefile.mk b/bridges/source/cpp_uno/cc50_solaris_intel/makefile.mk
new file mode 100644
index 000000000000..e3d10f829187
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_intel/makefile.mk
@@ -0,0 +1,75 @@
+#*************************************************************************
+#
+# 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=sunpro5_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+# disable check for PIC code as it would complain about
+# hand coded assembler
+CHECKFORPIC=
+
+.IF "$(COM)$(CPU)" == "C50I" || "$(COM)$(CPU)" == "C52I"
+
+CFLAGS += -O5 -xO5
+
+SLOFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/call.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB= i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH= URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.s
+ CC -c -o $(SLO)$/$(@:b).o $< && touch $@
+
diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/uno2cpp.cxx b/bridges/source/cpp_uno/cc50_solaris_intel/uno2cpp.cxx
new file mode 100644
index 000000000000..7242ccd31ee6
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_intel/uno2cpp.cxx
@@ -0,0 +1,421 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sal/alloca.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "cc50_solaris_intel.hxx"
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+namespace
+{
+
+extern "C" {
+ void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs
+ );
+}
+
+//==================================================================================================
+static inline void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ char * pCppStack = (char *)alloca( ((nParams+3) * sizeof(sal_Int64)) );
+ char * pCppStackStart = pCppStack;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ void * pReturnSpace = 0;
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack
+ = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ pCppStack += sizeof(void *);
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+
+ const int nMaxParams = 32;
+ // args
+ void * args_buffer[3 * nMaxParams];
+ void ** pCppArgs = (void **)(nParams > nMaxParams ? rtl_allocateMemory( 3 * sizeof(void *) * nParams ) : args_buffer);
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ const int nTempBufferSize = 256;
+ sal_Int32 nTempBufferPos = 0;
+ long params_buffer[nTempBufferSize];
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ pCppArgs[ nPos ] = pCppStack;
+ uno_copyAndConvertData( pCppArgs[nPos], pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ if (pParamTypeDescr->nSize > (sizeof(long) * (nTempBufferSize - nTempBufferPos)))
+ {
+ uno_constructData(
+ *(void **)pCppStack = pCppArgs[nPos] = rtl_allocateMemory( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos | 0x80000000; // default constructed for cpp call
+ }
+ else
+ {
+ uno_constructData(
+ *(void **)pCppStack = pCppArgs[nPos] = (params_buffer + nTempBufferPos),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ nTempBufferPos += (pParamTypeDescr->nSize / sizeof(long)) +1;
+ }
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ if (pParamTypeDescr->nSize > (sizeof(long)*(nTempBufferSize - nTempBufferPos)))
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = rtl_allocateMemory( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ pTempIndizes[nTempIndizes] = nPos | 0x80000000; // has to be reconverted
+ }
+ else
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = (params_buffer + nTempBufferPos),
+ pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ nTempBufferPos += (pParamTypeDescr->nSize / sizeof(long)) +1;
+ }
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ try
+ {
+ int nStackLongs = (pCppStack - pCppStackStart)/sizeof(sal_Int32);
+ if( nStackLongs & 1 )
+ // stack has to be 8 byte aligned
+ nStackLongs++;
+
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn,
+ pReturnTypeDescr->eTypeClass,
+ (sal_Int32 *)pCppStackStart,
+ nStackLongs
+ );
+
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ sal_Bool bAllocated = (nIndex & 0x80000000) != 0;
+ nIndex &= 0x7fffffff;
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData(
+ pCppArgs[nIndex], pParamTypeDescr,
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+
+ if (bAllocated)
+ rtl_freeMemory( pCppArgs[nIndex] );
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData(
+ pCppReturn, pReturnTypeDescr,
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ }
+ }
+ catch( ... )
+ {
+ void* pExc = __Crun::ex_get();
+ const char* pName = __Cimpl::ex_name();
+
+ // get exception
+ CPPU_CURRENT_NAMESPACE::cc50_solaris_intel_fillUnoException(
+ pExc, pName, *ppUnoExc,
+ pThis->getBridge()->getCpp2Uno());
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ sal_Bool bAllocated = (nIndex & 0x80000000) != 0;
+ nIndex &= 0x7fffffff;
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData(
+ pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes],
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ if (bAllocated)
+ rtl_freeMemory( pCppArgs[nIndex] );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+
+ if (pCppArgs != (void **)args_buffer)
+ rtl_freeMemory( pCppArgs );
+ if (pReturnSpace)
+ rtl_freeMemory( pReturnSpace );
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; // get, then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/call.s b/bridges/source/cpp_uno/cc50_solaris_sparc/call.s
new file mode 100644
index 000000000000..be4027fda070
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_sparc/call.s
@@ -0,0 +1,199 @@
+.global privateSnippetExecutor
+.type privateSnippetExecutor,2
+privateSnippetExecutor:
+ ! save %sp, -96, %sp already done in code snippet
+ st %i0, [%fp+68]
+ st %i1, [%fp+72]
+ st %i2, [%fp+76]
+ st %i3, [%fp+80]
+ st %i4, [%fp+84]
+ st %i5, [%fp+88]
+ ! %o0: functionIndex, stored by code snippet
+ ! %o1: vtableOffset, stored by code snippet
+ call cpp_vtable_call
+ add %fp, 68, %o2
+.privateSnippetExecutorExceptionPosition:
+ subcc %o0, 11, %g0
+ be .double
+ subcc %o0, 10, %g0
+ be .float
+ ld [%fp+72], %i0
+ ld [%fp+76], %i1
+ ret
+ restore
+.double:
+ ldd [%fp+72], %f0
+ ret
+ restore
+.float:
+ ld [%fp+72], %f0
+ ret
+ restore
+.size privateSnippetExecutor,(.-privateSnippetExecutor)
+.align 8
+
+
+.global callVirtualMethod
+.type callVirtualMethod,2
+callVirtualMethod:
+ ! allocate FIRST stack to have own local registers
+ sethi %hi(-96), %g1
+ or %g1, %lo(-96), %g1
+ subcc %g1, %o5, %g1
+ subcc %g1, %o5, %g1
+ subcc %g1, %o5, %g1
+ subcc %g1, %o5, %g1
+ save %sp, %g1, %sp
+ ! copy stack longs if necessary
+ subcc %i5, 6, %l5
+ ble .copyRegisters
+ nop
+
+ ! prepare source location
+ add %i4, 24, %l4
+
+ ! prepare real stack
+ add %sp, 92, %l3
+
+.copyLong:
+ ld [%l4+0], %l0
+ st %l0, [%l3]
+ add %l4, 4, %l4
+ add %l3, 4, %l3
+ deccc %l5
+ bne .copyLong
+ nop
+.copyRegisters:
+ mov %i5, %l5
+ mov %i4, %l4
+
+ ld [%l4], %o0
+ add %l4, 4, %l4
+ deccc %l5
+ ble .doCall
+
+ ld [%l4], %o1
+ add %l4, 4, %l4
+ deccc %l5
+ ble .doCall
+
+ ld [%l4], %o2
+ add %l4, 4, %l4
+ deccc %l5
+ ble .doCall
+
+ ld [%l4], %o3
+ add %l4, 4, %l4
+ deccc %l5
+ ble .doCall
+
+ ld [%l4], %o4
+ add %l4, 4, %l4
+ deccc %l5
+ ble .doCall
+
+ ld [%l4], %o5
+ add %l4, 4, %l4
+
+ ! prepare complex return pointer
+ st %i2, [%sp+64]
+.doCall:
+ ! get virtual table entry
+ mov %i1, %l1
+ add %l1, 2, %l1
+ sll %l1, 2, %l1
+ ld [%i0], %l3
+ add %l3, %l1, %l1
+ ld [%l1], %l0
+ jmpl %l0,%o7
+ nop
+.callVirtualMethodExceptionPosition:
+ ! handle returns
+
+ !byte types
+ subcc %i3, 2, %l3 ! typelib_TypeClass_BOOLEAN
+ be .handleByte
+ subcc %i3, 3, %l3 ! typelib_TypeClass_BYTE
+ be .handleByte
+
+ ! half word types
+ subcc %i3, 4, %l3 ! typelib_TypeClass_SHORT
+ be .handleShort
+ subcc %i3, 5, %l3 ! typelib_TypeClass_UNSIGNED_SHORT
+ be .handleShort
+ subcc %i3, 1, %l3 ! typelib_TypeClass_CHAR (sal_Unicode==sal_uInt16)
+ be .handleShort
+
+ ! word types
+ subcc %i3, 6, %l3 ! typelib_TypeClass_LONG
+ be .handleWord
+ subcc %i3, 7, %l3 ! typelib_TypeClass_UNSIGNED_LONG
+ be .handleWord
+ subcc %i3, 15, %l3 ! typelib_TypeClass_ENUM
+ be .handleWord
+
+ ! double word types
+ subcc %i3, 8, %l3 ! typelib_TypeClass_HYPER
+ be .handleDoubleWord
+ subcc %i3, 9, %l3 ! typelib_TypeClass_UNSIGNED_HYPER
+ be .handleDoubleWord
+
+ ! float
+ subcc %i3, 10, %l3 ! typelib_TypeClass_FLOAT
+ be .handleFloat
+
+ ! double
+ subcc %i3, 11, %l3 ! typelib_TypeClass_DOUBLE
+ be .handleDouble
+
+ ! default: return void
+ nop ! empty prefetch
+ ba .doRestore
+ nop
+.handleByte:
+ stb %o0, [%i2]
+ ba .doRestore
+ nop
+.handleShort:
+ sth %o0, [%i2]
+ ba .doRestore
+ nop
+.handleWord:
+ st %o0, [%i2]
+ ba .doRestore
+ nop
+.handleDoubleWord:
+ st %o0, [%i2]
+ st %o1, [%i2+4]
+ ba .doRestore
+ nop
+.handleFloat:
+ st %f0, [%i2]
+ ba .doRestore
+ nop
+.handleDouble:
+ std %f0, [%fp-8]
+ ldd [%fp-8], %o0
+ st %o0, [%i2]
+ st %o1, [%i2+4]
+ ba .doRestore
+ nop
+.doRestore:
+ ret
+ restore ! stack frame for own locals
+.size callVirtualMethod,(.-callVirtualMethod)
+.align 8
+
+.rethrow_handler:
+ call __1cG__CrunMex_rethrow_q6F_v_
+ nop
+
+.section ".exception_ranges",#alloc
+.word %r_disp32(.privateSnippetExecutorExceptionPosition)
+.word 0
+.word .rethrow_handler-.privateSnippetExecutorExceptionPosition
+.word 0,0
+.word %r_disp32(.callVirtualMethodExceptionPosition)
+.word 0
+.word .rethrow_handler-.callVirtualMethodExceptionPosition
+.word 0,0
diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/cc50_solaris_sparc.hxx b/bridges/source/cpp_uno/cc50_solaris_sparc/cc50_solaris_sparc.hxx
new file mode 100644
index 000000000000..06667e4a366c
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_sparc/cc50_solaris_sparc.hxx
@@ -0,0 +1,89 @@
+/* -*- 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 <cstddef>
+#include <rtl/string.hxx>
+#include <typeinfo>
+
+typedef struct _uno_Any uno_Any;
+typedef struct _uno_Mapping uno_Mapping;
+
+// private C50 structures and functions
+namespace __Crun
+{
+ struct static_type_info
+ {
+ std::ptrdiff_t m_pClassName;
+ int m_nSkip1; // must be 0
+ void* m_pMagic; // points to some magic data
+ int m_nMagic[ 4 ];
+ int m_nSkip2[2]; // must be 0
+ };
+ void* ex_alloc(unsigned);
+ void ex_throw( void*, const static_type_info*, void(*)(void*));
+ void* ex_get();
+ void ex_rethrow_q() throw();
+}
+
+namespace __Cimpl
+{
+ const char* ex_name();
+}
+
+extern "C" void _ex_register( void*, int );
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+inline char* adjustPointer( char* pIn, typelib_TypeDescription* pType )
+{
+ switch( pType->nSize )
+ {
+ case 1: return pIn + 3;
+ case 2: return pIn + 2;
+ case 3: return pIn + 1;
+ // Huh ? perhaps a char[3] ? Though that would be a pointer
+ // well, we have it anyway for symmetry
+ }
+ return pIn;
+}
+
+//##################################################################################################
+//#### exceptions ##################################################################################
+//##################################################################################################
+
+void cc50_solaris_sparc_raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+
+void cc50_solaris_sparc_fillUnoException(
+ void*, const char*,
+ uno_Any*, uno_Mapping * pCpp2Uno );
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/cpp2uno.cxx b/bridges/source/cpp_uno/cc50_solaris_sparc/cpp2uno.cxx
new file mode 100644
index 000000000000..bfe55d726b3c
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_sparc/cpp2uno.cxx
@@ -0,0 +1,533 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sal/alloca.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "cc50_solaris_sparc.hxx"
+#include "flushcode.hxx"
+
+using namespace com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ // pCallStack: [return ptr], this, params
+ char * pCppStack = (char *)pCallStack;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *pCallStack;
+ pCppStack += sizeof( void* );
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ // value
+ {
+ pCppArgs[ nPos ] = pUnoArgs[ nPos ] =
+ CPPU_CURRENT_NAMESPACE::adjustPointer(
+ pCppStack, pParamTypeDescr );
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ pCppArgs[nPos] = *(void **)pCppStack;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case no exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::cc50_solaris_sparc_raiseException(
+ &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData(
+ pCppArgs[nIndex], pParamTypeDescr,
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: this, params
+ void * pThis;
+ if( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = pCallStack[1];
+ }
+ else
+ {
+ pThis = pCallStack[0];
+ }
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex,
+ "### illegal vtable index!" );
+// if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+// {
+// RuntimeException aExc;
+// aExc.Message = OUString::createFromAscii("illegal vtable index!");
+// aExc.Context = (XInterface *)pThis;
+// throw aExc;
+// }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ // standard XInterface vtable calls
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[2] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pCallStack[0] ),
+ &pInterface, pTD,
+ reinterpret_cast< uno_AcquireFunc >(cpp_acquire) );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = pCallStack[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+// default:
+// {
+// RuntimeException aExc;
+// aExc.Message = OUString::createFromAscii("no member description found!");
+// aExc.Context = (XInterface *)pThis;
+// throw aExc;
+// // is here for dummy
+// eRet = typelib_TypeClass_VOID;
+// }
+ }
+
+ return eRet;
+}
+
+}
+
+//==================================================================================================
+extern "C" int cpp_vtable_call(
+ int nFunctionIndex, int nVtableOffset, void** pCallStack )
+{
+ sal_Int64 nRegReturn;
+ typelib_TypeClass aType = cpp_mediate(
+ nFunctionIndex, nVtableOffset, pCallStack, &nRegReturn );
+ OSL_ASSERT( sizeof(void *) == sizeof(sal_Int32) );
+ switch( aType )
+ {
+ // move return value into register space
+ // (will be loaded by machine code snippet)
+ // Use pCallStack[1/2] instead of pCallStack[0/1], because the former is
+ // properly dword aligned:
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ pCallStack[1] = (void*)*(char*)&nRegReturn;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ pCallStack[1] = (void*)*(short*)&nRegReturn;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ // move long to %i1
+ pCallStack[2] = ((void **)&nRegReturn)[ 1 ];
+ case typelib_TypeClass_FLOAT:
+ default:
+ // move long to %i0
+ pCallStack[1] = ((void **)&nRegReturn)[ 0 ];
+ break;
+ }
+ return aType;
+}
+
+//==================================================================================================
+namespace {
+
+extern "C" void privateSnippetExecutor();
+
+int const codeSnippetSize = 7 * 4;
+
+unsigned char * codeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ bool simpleRetType)
+{
+ sal_uInt32 index = functionIndex;
+ if (!simpleRetType) {
+ index |= 0x80000000;
+ }
+ unsigned int * p = reinterpret_cast< unsigned int * >(code);
+ OSL_ASSERT(sizeof (unsigned int) == 4);
+ // save %sp, -96, %sp ! 92 byte minimal stack frame, + 4 byte dword align:
+ *p++ = 0x9DE3BFA0;
+ // sethi %hi(privateSnippetExecutor), %l0:
+ *p++ = 0x21000000
+ | (reinterpret_cast< unsigned int >(privateSnippetExecutor) >> 10);
+ // sethi %hi(index), %o0:
+ *p++ = 0x11000000 | (index >> 10);
+ // or %o0, %lo(index), %o0:
+ *p++ = 0x90122000 | (index & 0x3FF);
+ // sethi %hi(vtableOffset), %o1:
+ *p++ = 0x13000000 | (vtableOffset >> 10);
+ // jmpl %l0, %lo(privateSnippetExecutor), %g0:
+ *p++ = 0x81C42000
+ | (reinterpret_cast< unsigned int >(privateSnippetExecutor) & 0x3FF);
+ // or %o1, %lo(vtableOffset), %o1:
+ *p++ = 0x92126000 | (vtableOffset & 0x3FF);
+ OSL_ASSERT(
+ reinterpret_cast< unsigned char * >(p) - code <= codeSnippetSize);
+ return code + codeSnippetSize;
+}
+
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 1;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 3) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block) + 2;
+ slots[-3].fn = 0; // RTTI
+ slots[-2].fn = 0; // null
+ slots[-1].fn = 0; // destructor
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const * begin, unsigned char const * end)
+{
+ bridges::cpp_uno::cc50_solaris_sparc::flushCode(begin, end);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx b/bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx
new file mode 100644
index 000000000000..aa2bbde76708
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx
@@ -0,0 +1,447 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <cstddef>
+#include <dlfcn.h>
+#include <new.h>
+#include <typeinfo>
+#include <list>
+#include <map>
+#include <rtl/alloc.h>
+#include <osl/diagnose.h>
+#include <typelib/typedescription.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+#include "cc50_solaris_sparc.hxx"
+#include "flushcode.hxx"
+#include <rtl/strbuf.hxx>
+
+#include "bridges/cpp_uno/shared/arraypointer.hxx"
+
+#include <hash.cxx>
+
+// need a += operator for OString and sal_Char
+namespace rtl
+{
+ inline OString& operator+=( OString& rString, sal_Char cAdd )
+ {
+ sal_Char add[2];
+ add[0] = cAdd;
+ add[1] = 0;
+ return rString += add;
+ }
+}
+
+using namespace std;
+using namespace osl;
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+//==================================================================================================
+static OString toUNOname( const OString & rRTTIname )
+{
+ OString aRet;
+
+ const sal_Char* pRTTI = rRTTIname.getStr();
+ const sal_Char* pOrg = pRTTI;
+ const sal_Char* pLast = pRTTI;
+
+ while( 1 )
+ {
+ if( *pRTTI == ':' || ! *pRTTI )
+ {
+ if( aRet.getLength() )
+ aRet += ".";
+ aRet += rRTTIname.copy( pLast - pOrg, pRTTI - pLast );
+ while( *pRTTI == ':' )
+ pRTTI++;
+ pLast = pRTTI;
+ if( ! *pRTTI )
+ break;
+ }
+ else
+ pRTTI++;
+ }
+
+ return aRet;
+}
+//==================================================================================================
+static OString toRTTIname( const OString & rUNOname )
+{
+ OStringBuffer aRet( rUNOname.getLength()*2 );
+
+ sal_Int32 nIndex = 0;
+ do
+ {
+ if( nIndex > 0 )
+ aRet.append( "::" );
+ aRet.append( rUNOname.getToken( 0, '.', nIndex ) );
+ } while( nIndex != -1 );
+
+ return aRet.makeStringAndClear();
+}
+//==================================================================================================
+
+static OString toRTTImangledname( const OString & rRTTIname )
+{
+ if( ! rRTTIname.getLength() )
+ return OString();
+
+ OStringBuffer aRet( rRTTIname.getLength()*2 );
+
+ aRet.append( "__1n" );
+ sal_Int32 nIndex = 0;
+ do
+ {
+ OString aToken( rRTTIname.getToken( 0, ':', nIndex ) );
+ int nBytes = aToken.getLength();
+ if( nBytes )
+ {
+ if( nBytes > 25 )
+ {
+ aRet.append( (sal_Char)( nBytes/26 + 'a' ) );
+ aRet.append( (sal_Char)( nBytes%26 + 'A' ) );
+ }
+ else
+ aRet.append( (sal_Char)( nBytes + 'A' ) );
+ for (sal_Int32 i = 0; i < aToken.getLength(); ++i) {
+ char c = aToken[i];
+ if (c == 'Q') {
+ aRet.append("QdD");
+ } else {
+ aRet.append(c);
+ }
+ }
+ }
+ } while( nIndex != -1 );
+
+ aRet.append( '_' );
+
+ return aRet.makeStringAndClear();
+}
+
+
+//##################################################################################################
+//#### RTTI simulation #############################################################################
+//##################################################################################################
+
+class RTTIHolder
+{
+ std::map< OString, void* > aAllRTTI;
+public:
+ ~RTTIHolder();
+
+ void* getRTTI( const OString& rTypename );
+ void* getRTTI_UnoName( const OString& rUnoTypename )
+ { return getRTTI( toRTTIname( rUnoTypename ) ); }
+
+ void* insertRTTI( const OString& rTypename );
+ void* insertRTTI_UnoName( const OString& rTypename )
+ { return insertRTTI( toRTTIname( rTypename ) ); }
+ void* generateRTTI( typelib_CompoundTypeDescription* pCompTypeDescr );
+};
+
+RTTIHolder::~RTTIHolder()
+{
+ for ( std::map< OString, void* >::const_iterator iPos( aAllRTTI.begin() );
+ iPos != aAllRTTI.end(); ++iPos )
+ {
+ delete[] static_cast< char * >(iPos->second);
+ }
+}
+
+#if OSL_DEBUG_LEVEL > 1
+#include <stdio.h>
+#endif
+
+void* RTTIHolder::getRTTI( const OString& rTypename )
+{
+ std::map< OString, void* >::iterator element;
+
+ element = aAllRTTI.find( rTypename );
+ if( element != aAllRTTI.end() )
+ return (*element).second;
+
+ // create rtti structure
+ element = aAllRTTI.find( rTypename );
+ if( element != aAllRTTI.end() )
+ return (*element).second;
+
+ return NULL;
+}
+
+void* RTTIHolder::insertRTTI( const OString& rTypename )
+{
+ OString aMangledName( toRTTImangledname( rTypename ) );
+ NIST_Hash aHash( aMangledName.getStr(), aMangledName.getLength() );
+
+ std::size_t const RTTI_SIZE = 19; // 14???
+ void** pRTTI = reinterpret_cast< void ** >(
+ new char[RTTI_SIZE * sizeof (void *) + strlen(rTypename.getStr()) + 1]);
+ pRTTI[ 0 ] = reinterpret_cast< void * >(RTTI_SIZE * sizeof (void *));
+ pRTTI[ 1 ] = NULL;
+ pRTTI[ 2 ] = (void*)(7*sizeof(void*));
+ pRTTI[ 3 ] = (void*)aHash.getHash()[0];
+ pRTTI[ 4 ] = (void*)aHash.getHash()[1];
+ pRTTI[ 5 ] = (void*)aHash.getHash()[2];
+ pRTTI[ 6 ] = (void*)aHash.getHash()[3];
+ pRTTI[ 7 ] = NULL;
+ pRTTI[ 8 ] = NULL;
+
+ pRTTI[ 9 ] = pRTTI[ 3 ];
+ pRTTI[ 10 ] = pRTTI[ 4 ];
+ pRTTI[ 11 ] = pRTTI[ 5 ];
+ pRTTI[ 12 ] = pRTTI[ 6 ];
+ pRTTI[ 13 ] = (void*)0x80000000;
+ strcpy(reinterpret_cast< char * >(pRTTI + RTTI_SIZE), rTypename.getStr());
+
+ aAllRTTI[ rTypename ] = (void*)pRTTI;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,
+ "generating base RTTI for type %s:\n"
+ " mangled: %s\n"
+ " hash: %.8x %.8x %.8x %.8x\n",
+ rTypename.getStr(),
+ aMangledName.getStr(),
+ pRTTI[ 3 ], pRTTI[ 4 ], pRTTI[ 5 ], pRTTI[ 6 ]
+ );
+#endif
+ return pRTTI;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+void* RTTIHolder::generateRTTI( typelib_CompoundTypeDescription * pCompTypeDescr )
+{
+ OString aUNOCompTypeName( OUStringToOString( pCompTypeDescr->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ OString aRTTICompTypeName( toRTTIname( aUNOCompTypeName ) );
+
+ void* pHaveRTTI = getRTTI( aRTTICompTypeName );
+ if( pHaveRTTI )
+ return pHaveRTTI;
+
+ if( ! pCompTypeDescr->pBaseTypeDescription )
+ // this is a base type
+ return insertRTTI( aRTTICompTypeName );
+
+ // get base class RTTI
+ void* pSuperRTTI = generateRTTI( pCompTypeDescr->pBaseTypeDescription );
+ OSL_ENSURE( pSuperRTTI, "could not generate RTTI for supertype !" );
+
+ // find out the size to allocate for RTTI
+ void** pInherit = (void**)((sal_uInt32)pSuperRTTI + ((sal_uInt32*)pSuperRTTI)[2] + 8);
+ int nInherit;
+ for( nInherit = 1; pInherit[ nInherit*5-1 ] != (void*)0x80000000; nInherit++ )
+ ;
+
+ OString aMangledName( toRTTImangledname( aRTTICompTypeName ) );
+ NIST_Hash aHash( aMangledName.getStr(), aMangledName.getLength() );
+
+ std::size_t const rttiSize = 14 + nInherit * 5;
+ void** pRTTI = reinterpret_cast< void ** >(
+ new char[
+ rttiSize * sizeof (void *)
+ + strlen(aRTTICompTypeName.getStr()) + 1]);
+ pRTTI[ 0 ] = reinterpret_cast< void * >(rttiSize * sizeof (void *));
+ pRTTI[ 1 ] = NULL;
+ pRTTI[ 2 ] = (void*)(7*sizeof(void*));
+ pRTTI[ 3 ] = (void*)aHash.getHash()[0];
+ pRTTI[ 4 ] = (void*)aHash.getHash()[1];
+ pRTTI[ 5 ] = (void*)aHash.getHash()[2];
+ pRTTI[ 6 ] = (void*)aHash.getHash()[3];
+ pRTTI[ 7 ] = NULL;
+ pRTTI[ 8 ] = NULL;
+
+ memcpy( pRTTI+9, pInherit, 4*nInherit*5 );
+ pRTTI[ 8 +nInherit*5 ] = NULL;
+ pRTTI[ 9 +nInherit*5 ] = pRTTI[ 3 ];
+ pRTTI[ 10+nInherit*5 ] = pRTTI[ 4 ];
+ pRTTI[ 11+nInherit*5 ] = pRTTI[ 5 ];
+ pRTTI[ 12+nInherit*5 ] = pRTTI[ 6 ];
+ pRTTI[ 13+nInherit*5 ] = (void*)0x80000000;
+ strcpy(
+ reinterpret_cast< char * >(pRTTI + rttiSize),
+ aRTTICompTypeName.getStr());
+
+ aAllRTTI[ aRTTICompTypeName ] = (void*)pRTTI;
+
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,
+ "generating struct RTTI for type %s:\n"
+ " mangled: %s\n"
+ " hash: %.8x %.8x %.8X %.8x\n",
+ aRTTICompTypeName.getStr(),
+ aMangledName.getStr(),
+ pRTTI[ 3 ], pRTTI[ 4 ], pRTTI[ 5 ], pRTTI[ 6 ]
+ );
+#endif
+
+ return pRTTI;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+static void deleteException(
+ void* pExc, unsigned int* thunk, typelib_TypeDescription* pType )
+{
+ uno_destructData(
+ pExc, pType, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ typelib_typedescription_release( pType );
+ delete[] thunk;
+}
+
+//__________________________________________________________________________________________________
+
+//##################################################################################################
+//#### exported ####################################################################################
+//##################################################################################################
+
+void cc50_solaris_sparc_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() );
+#endif
+ bridges::cpp_uno::shared::ArrayPointer< unsigned int > thunkPtr(
+ new unsigned int[6]);
+
+ typelib_TypeDescription * pTypeDescr = 0;
+ // will be released by deleteException
+ typelib_typedescriptionreference_getDescription( &pTypeDescr, pUnoExc->pType );
+
+ void* pRTTI;
+ {
+ static ::osl::Mutex aMutex;
+ ::osl::Guard< ::osl::Mutex > guard( aMutex );
+
+ static RTTIHolder * s_pRTTI = 0;
+ if (! s_pRTTI)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_pRTTI = new RTTIHolder();
+#else
+ static RTTIHolder s_aRTTI;
+ s_pRTTI = &s_aRTTI;
+#endif
+ }
+
+ pRTTI = s_pRTTI->generateRTTI( (typelib_CompoundTypeDescription *)pTypeDescr );
+ }
+
+ // a must be
+ OSL_ENSURE( sizeof(sal_Int32) == sizeof(void *), "### pointer size differs from sal_Int32!" );
+
+ void * pCppExc = __Crun::ex_alloc( pTypeDescr->nSize );
+ uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ uno_any_destruct( pUnoExc, 0 );
+
+ unsigned int * thunk = thunkPtr.release();
+ // sethi %hi(thunk), %o1:
+ thunk[0] = 0x13000000 | (reinterpret_cast< unsigned int >(thunk) >> 10);
+ // or %o1, %lo(thunk), %o1:
+ thunk[1] = 0x92126000 | (reinterpret_cast< unsigned int >(thunk) & 0x3FF);
+ // sethi %hi(pTypeDescr), %o2:
+ thunk[2] = 0x15000000
+ | (reinterpret_cast< unsigned int >(pTypeDescr) >> 10);
+ // sethi %hi(deleteException), %o3
+ thunk[3] = 0x17000000
+ | (reinterpret_cast< unsigned int >(deleteException) >> 10);
+ // jmpl %o3, %lo(deleteException), %g0
+ thunk[4] = 0x81C2E000
+ | (reinterpret_cast< unsigned int >(deleteException) & 0x3FF);
+ // or %o2, %lo(pTypeDescr), %o2:
+ thunk[5] = 0x9412A000
+ | (reinterpret_cast< unsigned int >(pTypeDescr) & 0x3FF);
+ bridges::cpp_uno::cc50_solaris_sparc::flushCode(thunk, thunk + 6);
+
+#pragma disable_warn
+ void (* f)(void *) = reinterpret_cast< void (*)(void *) >(thunk);
+#pragma enable_warn
+ __Crun::ex_throw(pCppExc, (const __Crun::static_type_info*)pRTTI, f);
+}
+
+void cc50_solaris_sparc_fillUnoException(
+ void* pCppExc,
+ const char* pInfo,
+ uno_Any* pUnoExc,
+ uno_Mapping * pCpp2Uno )
+{
+ OSL_ASSERT( pInfo != 0 );
+ OString uno_name( toUNOname( pInfo ) );
+ OUString aName( OStringToOUString(
+ uno_name, RTL_TEXTENCODING_ASCII_US ) );
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ typelib_typedescription_getByName( &pExcTypeDescr, aName.pData );
+
+ if (pExcTypeDescr == 0) // the thing that should not be
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "exception type not found: ") ) + aName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert(
+ pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString(
+ aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "> c++ exception occured: %s\n",
+ ::rtl::OUStringToOString(
+ pExcTypeDescr->pTypeName,
+ RTL_TEXTENCODING_ASCII_US ).getStr() );
+#endif
+ // construct uno exception any
+ uno_any_constructAndConvert(
+ pUnoExc, pCppExc, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+}
+
+}
+
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/flushcode.hxx b/bridges/source/cpp_uno/cc50_solaris_sparc/flushcode.hxx
new file mode 100644
index 000000000000..5d89d81efed8
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_sparc/flushcode.hxx
@@ -0,0 +1,51 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC50_SOLARIS_SPARC_FLUSHCODE_HXX
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC50_SOLARIS_SPARC_FLUSHCODE_HXX
+
+#include "sal/config.h"
+
+extern "C" void sync_instruction_memory(caddr_t addr, int len); // from libc
+
+namespace bridges { namespace cpp_uno { namespace cc50_solaris_sparc {
+
+/**
+ * Flush a region of memory into which code has been written dynamically.
+ */
+inline void flushCode(void const * begin, void const * end) {
+ sync_instruction_memory(
+ static_cast< caddr_t >(const_cast< void * >(begin)),
+ static_cast< char const * >(end) - static_cast< char const * >(begin));
+}
+
+} } }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/hash.cxx b/bridges/source/cpp_uno/cc50_solaris_sparc/hash.cxx
new file mode 100644
index 000000000000..29064c19a28f
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_sparc/hash.cxx
@@ -0,0 +1,265 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+
+#ifndef TEST
+#include <sal/types.h>
+#else
+typedef unsigned int sal_uInt32;
+#endif
+
+#include <string.h>
+
+/*
+ * build a hash for a character buffer using the NIST algorithm
+ */
+
+class NIST_Hash
+{
+
+ // helper functions
+ sal_uInt32 f1( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
+ {
+ return z ^ ( x & ( y ^ z ) );
+ }
+
+ sal_uInt32 f2( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
+ {
+ return x ^ y ^ z;
+ }
+
+ sal_uInt32 f3( sal_uInt32 x, sal_uInt32 y, sal_uInt32 z )
+ {
+ return ( x & y ) + ( z & ( x ^ y ) );
+ }
+
+ sal_uInt32 rotl( sal_uInt32 nValue, sal_uInt32 nBits )
+ {
+ return ( nValue << nBits ) | ( nValue >> (32-nBits) );
+ }
+
+ sal_uInt32 expand_nostore( sal_uInt32 index )
+ {
+ return data[index&15] ^ data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15];
+ }
+
+ sal_uInt32 expand_store( sal_uInt32 index )
+ {
+ return data[index&15] ^= data[(index-14)&15] ^ data[(index-8)&15] ^ data[(index-3)&15];
+ }
+
+ void subRound( sal_uInt32 a, sal_uInt32& b, sal_uInt32 c, sal_uInt32 d, sal_uInt32& e, sal_uInt32 constant, sal_uInt32 datum, sal_uInt32 nFunction )
+ {
+ e += rotl(a,5);
+ switch( nFunction )
+ {
+ case 1: e += f1( b, c, d );break;
+ case 2:
+ case 4: e += f2( b, c, d );break;
+ case 3: e += f3( b, c, d );break;
+ }
+ e += constant + datum;
+ b = rotl( b, 30 );
+ }
+
+ void transform();
+ void final();
+
+ // data members
+ sal_uInt32 data[16];
+ sal_uInt32 hashdata[5];
+public:
+ NIST_Hash( const char* pString, sal_uInt32 nLen );
+
+ sal_uInt32 *getHash() { return hashdata; }
+};
+
+void NIST_Hash::transform()
+{
+ // constants
+ const sal_uInt32 K2 = 0x5A827999;
+ const sal_uInt32 K3 = 0x6ED9EBA1;
+ const sal_uInt32 K5 = 0x8F1BBCDC;
+ const sal_uInt32 K10 = 0xCA62C1D6;
+
+ sal_uInt32 a, b, c, d, e;
+ a = hashdata[0];
+ b = hashdata[1];
+ c = hashdata[2];
+ d = hashdata[3];
+ e = hashdata[4];
+
+ subRound( a, b, c, d, e, K2, data[ 0], 1 );
+ subRound( e, a, b, c, d, K2, data[ 1], 1 );
+ subRound( d, e, a, b, c, K2, data[ 2], 1 );
+ subRound( c, d, e, a, b, K2, data[ 3], 1 );
+ subRound( b, c, d, e, a, K2, data[ 4], 1 );
+ subRound( a, b, c, d, e, K2, data[ 5], 1 );
+ subRound( e, a, b, c, d, K2, data[ 6], 1 );
+ subRound( d, e, a, b, c, K2, data[ 7], 1 );
+ subRound( c, d, e, a, b, K2, data[ 8], 1 );
+ subRound( b, c, d, e, a, K2, data[ 9], 1 );
+ subRound( a, b, c, d, e, K2, data[10], 1 );
+ subRound( e, a, b, c, d, K2, data[11], 1 );
+ subRound( d, e, a, b, c, K2, data[12], 1 );
+ subRound( c, d, e, a, b, K2, data[13], 1 );
+ subRound( b, c, d, e, a, K2, data[14], 1 );
+ subRound( a, b, c, d, e, K2, data[15], 1 );
+ subRound( e, a, b, c, d, K2, expand_store( 16 ), 1 );
+ subRound( d, e, a, b, c, K2, expand_store( 17 ), 1 );
+ subRound( c, d, e, a, b, K2, expand_store( 18 ), 1 );
+ subRound( b, c, d, e, a, K2, expand_store( 19 ), 1 );
+
+ subRound( a, b, c, d, e, K3, expand_store( 20 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 21 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 22 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 23 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 24 ), 2 );
+ subRound( a, b, c, d, e, K3, expand_store( 25 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 26 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 27 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 28 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 29 ), 2 );
+ subRound( a, b, c, d, e, K3, expand_store( 30 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 31 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 32 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 33 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 34 ), 2 );
+ subRound( a, b, c, d, e, K3, expand_store( 35 ), 2 );
+ subRound( e, a, b, c, d, K3, expand_store( 36 ), 2 );
+ subRound( d, e, a, b, c, K3, expand_store( 37 ), 2 );
+ subRound( c, d, e, a, b, K3, expand_store( 38 ), 2 );
+ subRound( b, c, d, e, a, K3, expand_store( 39 ), 2 );
+
+ subRound( a, b, c, d, e, K5, expand_store( 40 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 41 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 42 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 43 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 44 ), 3 );
+ subRound( a, b, c, d, e, K5, expand_store( 45 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 46 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 47 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 48 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 49 ), 3 );
+ subRound( a, b, c, d, e, K5, expand_store( 50 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 51 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 52 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 53 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 54 ), 3 );
+ subRound( a, b, c, d, e, K5, expand_store( 55 ), 3 );
+ subRound( e, a, b, c, d, K5, expand_store( 56 ), 3 );
+ subRound( d, e, a, b, c, K5, expand_store( 57 ), 3 );
+ subRound( c, d, e, a, b, K5, expand_store( 58 ), 3 );
+ subRound( b, c, d, e, a, K5, expand_store( 59 ), 3 );
+
+ subRound( a, b, c, d, e, K10, expand_store( 60 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 61 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_store( 62 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_store( 63 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_store( 64 ), 4 );
+ subRound( a, b, c, d, e, K10, expand_store( 65 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 66 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_store( 67 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_store( 68 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_store( 69 ), 4 );
+ subRound( a, b, c, d, e, K10, expand_store( 70 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 71 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_store( 72 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_store( 73 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_store( 74 ), 4 );
+ subRound( a, b, c, d, e, K10, expand_store( 75 ), 4 );
+ subRound( e, a, b, c, d, K10, expand_store( 76 ), 4 );
+ subRound( d, e, a, b, c, K10, expand_nostore( 77 ), 4 );
+ subRound( c, d, e, a, b, K10, expand_nostore( 78 ), 4 );
+ subRound( b, c, d, e, a, K10, expand_nostore( 79 ), 4 );
+
+ hashdata[0] += a;
+ hashdata[1] += b;
+ hashdata[2] += c;
+ hashdata[3] += d;
+ hashdata[4] += e;
+}
+
+#define BLOCKSIZE sizeof( data )
+
+NIST_Hash::NIST_Hash( const char* pString, sal_uInt32 nLen )
+{
+ hashdata[0] = 0x67452301;
+ hashdata[1] = 0xefcdab89;
+ hashdata[2] = 0x98badcfe;
+ hashdata[3] = 0x10325476;
+ hashdata[4] = 0xc3d2e1f0;
+
+ sal_uInt32 nBytes = nLen;
+
+ while( nLen >= sizeof( data ) )
+ {
+ memcpy( data, pString, sizeof( data ) );
+ pString += sizeof( data );
+ nLen -= sizeof( data );
+ transform();
+ }
+ memcpy( data, pString, nLen );
+ ((char*)data)[nLen++] = 0x80;
+ if( nLen > sizeof( data ) - 8 )
+ {
+ memset( ((char*)data)+nLen, 0, sizeof( data ) - nLen );
+ transform();
+ memset( data, 0, sizeof( data ) - 8 );
+ }
+ else
+ memset( ((char*)data)+nLen, 0, sizeof( data ) - 8 - nLen );
+ data[14] = 0;
+ data[15] = nBytes << 3;
+ transform();
+}
+
+#ifdef TEST
+#include <stdio.h>
+int main( int argc, const char** argv )
+{
+ const char* pHash = argc < 2 ? argv[0] : argv[1];
+
+ NIST_Hash aHash( pHash, strlen( pHash ) );
+ sal_uInt32* pBits = aHash.getHash();
+
+ printf( "text : %s\n"
+ "bits : 0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
+ pHash,
+ pBits[0], pBits[1], pBits[2],pBits[3],pBits[4]
+ );
+ return 0;
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/makefile.mk b/bridges/source/cpp_uno/cc50_solaris_sparc/makefile.mk
new file mode 100644
index 000000000000..2af2f29a02a3
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_sparc/makefile.mk
@@ -0,0 +1,80 @@
+#*************************************************************************
+#
+# 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=sunpro5_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+# disable check for PIC code as it would complain about
+# hand coded assembler
+CHECKFORPIC=
+
+.IF "$(COM)" == "C52" && "$(CPU)"=="S"
+
+#CFLAGS += -O5 -xO5
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+SLOFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/call.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB= i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH= URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+.INCLUDE : target.mk
+
+
+$(SLO)$/%.obj: %.s
+ CC -KPIC -c -o $(SLO)$/$(@:b).o $< && touch $@
+
diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/uno2cpp.cxx b/bridges/source/cpp_uno/cc50_solaris_sparc/uno2cpp.cxx
new file mode 100644
index 000000000000..7b85bc1fee91
--- /dev/null
+++ b/bridges/source/cpp_uno/cc50_solaris_sparc/uno2cpp.cxx
@@ -0,0 +1,399 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sal/alloca.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "cc50_solaris_sparc.hxx"
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+namespace
+{
+
+extern "C" void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs
+ );
+
+//==================================================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // pCppI is cc50_solaris_sparc this pointer
+ OSL_ENSURE( pThis, "### no interface given!" );
+
+ // max space for: [complex ret ptr], values|ptr ...
+ char * pCppStack = (char *)alloca( ((nParams+3) * sizeof(sal_Int64)) );
+ char * pCppStackStart = pCppStack;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack
+ = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ pCppStack += sizeof(void *);
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ pCppArgs[ nPos ] = CPPU_CURRENT_NAMESPACE::adjustPointer(
+ pCppStack, pParamTypeDescr );
+ uno_copyAndConvertData( pCppArgs[nPos], pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+// seems that EH registration for callVirtualMethod is not really
+// necessary
+
+// static unsigned long* pFrameInfo = NULL;
+
+// if( ! pFrameInfo )
+// {
+// pFrameInfo = new unsigned long[ 7 ];
+// pFrameInfo[ 0 ] = 0x40000000 | (((unsigned long)__Crun::ex_rethrow_q) >> 2);
+// pFrameInfo[ 1 ] = 0x01000000;
+// pFrameInfo[ 2 ] = (unsigned long)callVirtualMethodExceptionHandler;
+// pFrameInfo[ 3 ] = 0;
+// pFrameInfo[ 4 ] = (unsigned long)pFrameInfo - (unsigned long)callVirtualMethodExceptionHandler;
+// pFrameInfo[ 5 ] = 0;
+// pFrameInfo[ 6 ] = 0;
+// _ex_register( pFrameInfo+2, 1 );
+// }
+
+ try
+ {
+ int nStackLongs = (pCppStack - pCppStackStart)/sizeof(sal_Int32);
+ if( nStackLongs & 1 )
+ // stack has to be 8 byte aligned
+ nStackLongs++;
+
+ callVirtualMethod(
+ pAdjustedThisPtr,
+ aVtableSlot.index,
+ pCppReturn,
+ pReturnTypeDescr->eTypeClass,
+ (sal_Int32 *)pCppStackStart,
+ nStackLongs
+ );
+
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData(
+ pCppArgs[nIndex], pParamTypeDescr,
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData(
+ pCppReturn, pReturnTypeDescr,
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ }
+ }
+ catch( ... )
+ {
+ void* pExc = __Crun::ex_get();
+ const char* pName = __Cimpl::ex_name();
+
+ // get exception
+ CPPU_CURRENT_NAMESPACE::cc50_solaris_sparc_fillUnoException(
+ pExc, pName, *ppUnoExc, pThis->getBridge()->getCpp2Uno());
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData(
+ pCppArgs[nIndex],
+ ppTempParamTypeDescr[nTempIndizes],
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; // get, then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/callvirtualmethod.hxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/callvirtualmethod.hxx
new file mode 100644
index 000000000000..16f6c1090ff2
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/callvirtualmethod.hxx
@@ -0,0 +1,39 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_CALLVIRTUALMETHOD_Hx
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_CALLVIRTUALMETHOD_Hx
+
+#include "sal/config.h"
+
+extern "C" void callVirtualMethod(
+ unsigned long function, long * stack, sal_Int32 excess);
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/callvirtualmethod.s b/bridges/source/cpp_uno/cc5_solaris_sparc64/callvirtualmethod.s
new file mode 100644
index 000000000000..67c5aa39ade5
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/callvirtualmethod.s
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+.global callVirtualMethod
+.align 8
+callVirtualMethod:
+ ! %o0: unsigned long function
+ ! %o1: unsigned long * stack
+ ! %o2: sal_Int32 excess
+ add %o2, 176, %o3
+ neg %o3
+ save %sp, %o3, %sp
+ ldx [%i1 + 0 * 8], %o0
+ ldx [%i1 + 1 * 8], %o1
+ ldx [%i1 + 2 * 8], %o2
+ ldx [%i1 + 3 * 8], %o3
+ tst %i2
+ bz,pt %xcc, 1f
+ ldx [%i1 + 4 * 8], %o4
+ add %i1, 6 * 8, %l0
+ add %sp, 2047 + 176, %l1
+0: deccc 8, %i2
+ ldx [%l0 + %i2], %l2
+ bnz,pt %xcc, 0b
+ stx %l2, [%l1 + %i2]
+1: call %i0
+ ldx [%i1 + 5 * 8], %o5
+ stx %o0, [%i1 + 0 * 8]
+ stx %o1, [%i1 + 1 * 8]
+ stx %o2, [%i1 + 2 * 8]
+ stx %o3, [%i1 + 3 * 8]
+ ret
+ restore
+.size callVirtualMethod, . - callVirtualMethod
+.type callVirtualMethod, #function
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/cpp2uno.cxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/cpp2uno.cxx
new file mode 100644
index 000000000000..c49330b2223f
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/cpp2uno.cxx
@@ -0,0 +1,614 @@
+/* -*- 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 "precompiled_bridges.hxx"
+#include "sal/config.h"
+
+#include <cstddef>
+#include <cstdlib>
+#include <cstring>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+#include "com/sun/star/uno/genfunc.hxx"
+#include "osl/diagnose.h"
+#include "sal/alloca.h"
+#include "sal/types.h"
+#include "typelib/typeclass.h"
+#include "typelib/typedescription.h"
+#include "typelib/typedescription.hxx"
+#include "uno/any2.h"
+#include "uno/data.h"
+
+#include "exceptions.hxx"
+#include "flushcode.hxx"
+#include "fp.hxx"
+#include "isdirectreturntype.hxx"
+#include "vtableslotcall.hxx"
+
+namespace {
+
+namespace css = com::sun::star;
+
+void loadFpRegsFromStruct(typelib_TypeDescription * type, void * data) {
+ for (typelib_CompoundTypeDescription * t =
+ reinterpret_cast< typelib_CompoundTypeDescription * >(type);
+ t != NULL; t = t->pBaseTypeDescription)
+ {
+ for (sal_Int32 i = 0; i < t->nMembers; ++i) {
+ switch (t->ppTypeRefs[i]->eTypeClass) {
+ case typelib_TypeClass_FLOAT:
+ switch (t->pMemberOffsets[i]) {
+ case 0:
+ fp_loadf0(reinterpret_cast< float * >(data));
+ break;
+ case 4:
+ fp_loadf1(reinterpret_cast< float * >(data) + 1);
+ break;
+ case 8:
+ fp_loadf2(reinterpret_cast< float * >(data) + 2);
+ break;
+ case 12:
+ fp_loadf3(reinterpret_cast< float * >(data) + 3);
+ break;
+ case 16:
+ fp_loadf4(reinterpret_cast< float * >(data) + 4);
+ break;
+ case 20:
+ fp_loadf5(reinterpret_cast< float * >(data) + 5);
+ break;
+ case 24:
+ fp_loadf6(reinterpret_cast< float * >(data) + 6);
+ break;
+ case 28:
+ fp_loadf7(reinterpret_cast< float * >(data) + 7);
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ switch (t->pMemberOffsets[i]) {
+ case 0:
+ fp_loadd0(reinterpret_cast< double * >(data));
+ break;
+ case 8:
+ fp_loadd2(reinterpret_cast< double * >(data) + 1);
+ break;
+ case 16:
+ fp_loadd4(reinterpret_cast< double * >(data) + 2);
+ break;
+ case 24:
+ fp_loadd6(reinterpret_cast< double * >(data) + 3);
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ break;
+ case typelib_TypeClass_STRUCT:
+ {
+ typelib_TypeDescription * td = NULL;
+ TYPELIB_DANGER_GET(&td, t->ppTypeRefs[i]);
+ loadFpRegsFromStruct(td, data);
+ TYPELIB_DANGER_RELEASE(td);
+ break;
+ }
+ }
+ }
+ }
+}
+
+void call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * proxy,
+ css::uno::TypeDescription const & description,
+ bool directReturn, typelib_TypeDescriptionReference * returnType,
+ sal_Int32 count, typelib_MethodParameter * parameters,
+ unsigned long * callStack)
+{
+ typelib_TypeDescription * rtd = NULL;
+ if (returnType != NULL) {
+ TYPELIB_DANGER_GET(&rtd, returnType);
+ }
+ bool retconv =
+ rtd != NULL && bridges::cpp_uno::shared::relatesToInterfaceType(rtd);
+ OSL_ASSERT(!(directReturn && retconv));
+ void * retin;
+ void * retout;
+ char retbuf[32];
+ if (directReturn) {
+ retin = returnType == NULL ? NULL : retbuf;
+ } else {
+ retout = reinterpret_cast< void * >(callStack[0]);
+ retin = retconv ? alloca(rtd->nSize) : retout;
+ }
+ void ** args = static_cast< void ** >(alloca(count * sizeof (void *)));
+ void ** cppArgs = static_cast< void ** >(alloca(count * sizeof (void *)));
+ typelib_TypeDescription ** argtds =
+ static_cast< typelib_TypeDescription ** >(
+ alloca(count * sizeof (typelib_TypeDescription *)));
+ union fp { float f; double d; };
+ fp copies[15];
+ sal_Int32 stackPos = directReturn ? 1 : 2; // skip return ptr and this ptr
+ for (sal_Int32 i = 0; i < count; ++i) {
+ typelib_TypeDescription * ptd = NULL;
+ TYPELIB_DANGER_GET(&ptd, parameters[i].pTypeRef);
+ if (!parameters[i].bOut && bridges::cpp_uno::shared::isSimpleType(ptd))
+ {
+ switch (ptd->eTypeClass) {
+ case typelib_TypeClass_FLOAT:
+ if (stackPos <= 15) {
+ switch (stackPos) {
+ case 1:
+ fp_storef3(&copies[0].f);
+ break;
+ case 2:
+ fp_storef5(&copies[1].f);
+ break;
+ case 3:
+ fp_storef7(&copies[2].f);
+ break;
+ case 4:
+ fp_storef9(&copies[3].f);
+ break;
+ case 5:
+ fp_storef11(&copies[4].f);
+ break;
+ case 6:
+ fp_storef13(&copies[5].f);
+ break;
+ case 7:
+ fp_storef15(&copies[6].f);
+ break;
+ case 8:
+ fp_storef17(&copies[7].f);
+ break;
+ case 9:
+ fp_storef19(&copies[8].f);
+ break;
+ case 10:
+ fp_storef21(&copies[9].f);
+ break;
+ case 11:
+ fp_storef23(&copies[10].f);
+ break;
+ case 12:
+ fp_storef25(&copies[11].f);
+ break;
+ case 13:
+ fp_storef27(&copies[12].f);
+ break;
+ case 14:
+ fp_storef29(&copies[13].f);
+ break;
+ case 15:
+ fp_storef31(&copies[14].f);
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ args[i] = &copies[stackPos - 1].f;
+ } else {
+ args[i] = reinterpret_cast< char * >(callStack + stackPos) +
+ (sizeof (unsigned long) - sizeof (float));
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (stackPos <= 15) {
+ switch (stackPos) {
+ case 1:
+ fp_stored2(&copies[0].d);
+ break;
+ case 2:
+ fp_stored4(&copies[1].d);
+ break;
+ case 3:
+ fp_stored6(&copies[2].d);
+ break;
+ case 4:
+ fp_stored8(&copies[3].d);
+ break;
+ case 5:
+ fp_stored10(&copies[4].d);
+ break;
+ case 6:
+ fp_stored12(&copies[5].d);
+ break;
+ case 7:
+ fp_stored14(&copies[6].d);
+ break;
+ case 8:
+ fp_stored16(&copies[7].d);
+ break;
+ case 9:
+ fp_stored18(&copies[8].d);
+ break;
+ case 10:
+ fp_stored20(&copies[9].d);
+ break;
+ case 11:
+ fp_stored22(&copies[10].d);
+ break;
+ case 12:
+ fp_stored24(&copies[11].d);
+ break;
+ case 13:
+ fp_stored26(&copies[12].d);
+ break;
+ case 14:
+ fp_stored28(&copies[13].d);
+ break;
+ case 15:
+ fp_stored30(&copies[14].d);
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ args[i] = &copies[stackPos - 1].d;
+ } else {
+ args[i] = reinterpret_cast< char * >(callStack + stackPos) +
+ (sizeof (unsigned long) - sizeof (double));
+ }
+ break;
+ default:
+ OSL_ASSERT(ptd->nSize <= 8);
+ args[i] = reinterpret_cast< char * >(callStack + stackPos) +
+ (sizeof (unsigned long) - ptd->nSize);
+ break;
+ }
+ argtds[i] = NULL;
+ TYPELIB_DANGER_RELEASE(ptd);
+ } else {
+ cppArgs[i] = reinterpret_cast< void * >(callStack[stackPos]);
+ if (!parameters[i].bIn) {
+ args[i] = alloca(ptd->nSize);
+ argtds[i] = ptd;
+ } else if (bridges::cpp_uno::shared::relatesToInterfaceType(ptd)) {
+ args[i] = alloca(ptd->nSize);
+ uno_copyAndConvertData(
+ args[i], reinterpret_cast< void * >(callStack[stackPos]),
+ ptd, proxy->getBridge()->getCpp2Uno());
+ argtds[i] = ptd;
+ } else {
+ args[i] = reinterpret_cast< void * >(callStack[stackPos]);
+ argtds[i] = NULL;
+ TYPELIB_DANGER_RELEASE(ptd);
+ }
+ }
+ ++stackPos;
+ }
+ uno_Any exc;
+ uno_Any * pexc = &exc;
+ proxy->getUnoI()->pDispatcher(
+ proxy->getUnoI(), description.get(), retin, args, &pexc);
+ if (pexc != NULL) {
+ for (sal_Int32 i = 0; i < count; ++i) {
+ if (argtds[i] != NULL) {
+ if (parameters[i].bIn) {
+ uno_destructData(args[i], argtds[i], NULL);
+ }
+ TYPELIB_DANGER_RELEASE(argtds[i]);
+ }
+ }
+ if (rtd != NULL) {
+ TYPELIB_DANGER_RELEASE(rtd);
+ }
+ bridges::cpp_uno::cc5_solaris_sparc64::raiseException(
+ &exc, proxy->getBridge()->getUno2Cpp());
+ std::abort(); // just in case
+ }
+ for (sal_Int32 i = 0; i < count; ++i) {
+ if (argtds[i] != NULL) {
+ if (parameters[i].bOut) {
+ uno_destructData(
+ cppArgs[i], argtds[i],
+ reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release));
+ uno_copyAndConvertData(
+ cppArgs[i], args[i], argtds[i],
+ proxy->getBridge()->getUno2Cpp());
+ }
+ uno_destructData(args[i], argtds[i], NULL);
+ TYPELIB_DANGER_RELEASE(argtds[i]);
+ }
+ }
+ if (directReturn) {
+ if (rtd != NULL) {
+ switch (rtd->eTypeClass) {
+ case typelib_TypeClass_VOID:
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ callStack[0] = *reinterpret_cast< sal_Bool * >(retbuf);
+ break;
+ case typelib_TypeClass_BYTE:
+ callStack[0] = *reinterpret_cast< sal_Int8 * >(retbuf);
+ break;
+ case typelib_TypeClass_SHORT:
+ callStack[0] = *reinterpret_cast< sal_Int16 * >(retbuf);
+ break;
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ callStack[0] = *reinterpret_cast< sal_uInt16 * >(retbuf);
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_ENUM:
+ callStack[0] = *reinterpret_cast< sal_Int32 * >(retbuf);
+ break;
+ case typelib_TypeClass_UNSIGNED_LONG:
+ callStack[0] = *reinterpret_cast< sal_uInt32 * >(retbuf);
+ break;
+ case typelib_TypeClass_HYPER:
+ callStack[0] = *reinterpret_cast< sal_Int64 * >(retbuf);
+ break;
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ callStack[0] = *reinterpret_cast< sal_uInt64 * >(retbuf);
+ break;
+ case typelib_TypeClass_FLOAT:
+ fp_loadf0(reinterpret_cast< float * >(retbuf));
+ break;
+ case typelib_TypeClass_DOUBLE:
+ fp_loadd0(reinterpret_cast< double * >(retbuf));
+ break;
+ case typelib_TypeClass_CHAR:
+ callStack[0] = *reinterpret_cast< sal_Unicode * >(retbuf);
+ break;
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_INTERFACE:
+ callStack[0] = reinterpret_cast< unsigned long >(
+ *reinterpret_cast< void ** >(retbuf));
+ break;
+ case typelib_TypeClass_STRUCT:
+ loadFpRegsFromStruct(rtd, retbuf);
+ // fall through
+ case typelib_TypeClass_ANY:
+ std::memcpy(callStack, retbuf, rtd->nSize);
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ }
+ } else if (retconv) {
+ uno_copyAndConvertData(
+ retout, retin, rtd, proxy->getBridge()->getUno2Cpp());
+ uno_destructData(retin, rtd, NULL);
+ }
+ if (rtd != NULL) {
+ TYPELIB_DANGER_RELEASE(rtd);
+ }
+}
+
+extern "C" void vtableCall(
+ sal_Int32 functionIndex, sal_Int32 vtableOffset, unsigned long * callStack)
+{
+ bool direct = static_cast< sal_uInt32 >((functionIndex) & 0x80000000) == 0;
+ functionIndex = static_cast< sal_uInt32 >(functionIndex) & 0x7FFFFFFF;
+ bridges::cpp_uno::shared::CppInterfaceProxy * proxy
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ reinterpret_cast< char * >(callStack[direct ? 0 : 1]) -
+ vtableOffset);
+ typelib_InterfaceTypeDescription * type = proxy->getTypeDescr();
+ OSL_ASSERT(functionIndex < type->nMapFunctionIndexToMemberIndex);
+ sal_Int32 pos = type->pMapFunctionIndexToMemberIndex[functionIndex];
+ css::uno::TypeDescription desc(type->ppAllMembers[pos]);
+ switch (desc.get()->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ if (type->pMapMemberIndexToFunctionIndex[pos] == functionIndex) {
+ // Getter:
+ call(
+ proxy, desc, direct,
+ reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >(
+ desc.get())->pAttributeTypeRef,
+ 0, NULL, callStack);
+ } else {
+ // Setter:
+ typelib_MethodParameter param = {
+ NULL,
+ reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >(
+ desc.get())->pAttributeTypeRef,
+ true, false };
+ call(proxy, desc, true, NULL, 1, &param, callStack);
+ }
+ break;
+ case typelib_TypeClass_INTERFACE_METHOD:
+ switch (functionIndex) {
+ case 1:
+ proxy->acquireProxy();
+ break;
+ case 2:
+ proxy->releaseProxy();
+ break;
+ case 0:
+ {
+ typelib_TypeDescription * td = NULL;
+ TYPELIB_DANGER_GET(
+ &td,
+ reinterpret_cast< css::uno::Type * >(
+ callStack[2])->getTypeLibType());
+ if (td != NULL) {
+ css::uno::XInterface * ifc = NULL;
+ proxy->getBridge()->getCppEnv()->getRegisteredInterface(
+ proxy->getBridge()->getCppEnv(),
+ reinterpret_cast< void ** >(&ifc),
+ proxy->getOid().pData,
+ reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ td));
+ if (ifc != NULL) {
+ uno_any_construct(
+ reinterpret_cast< uno_Any * >(callStack[0]), &ifc,
+ td,
+ reinterpret_cast< uno_AcquireFunc >(
+ css::uno::cpp_acquire));
+ ifc->release();
+ TYPELIB_DANGER_RELEASE(td);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(td);
+ }
+ } // fall through
+ default:
+ call(
+ proxy, desc, direct,
+ reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
+ desc.get())->pReturnTypeRef,
+ reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
+ desc.get())->nParams,
+ reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
+ desc.get())->pParams,
+ callStack);
+ }
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+}
+
+int const codeSnippetSize = 10 * 4;
+
+unsigned char * generateCodeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ bool directReturn)
+{
+ sal_uInt32 index = functionIndex;
+ if (!directReturn) {
+ index |= 0x80000000;
+ }
+ unsigned int * p = reinterpret_cast< unsigned int * >(code);
+ OSL_ASSERT(sizeof (unsigned int) == 4);
+ // 0*4: save %sp, -176, %sp ! minimal stack frame:
+ *p++ = 0x9DE3BF50;
+ // 1*4: rd %pc, %l0:
+ *p++ = 0xA1414000;
+ // 2*4: ldx %l0, (8-1)*4, %l0:
+ *p++ = 0xE05C201C;
+ // 3*4: sethi %hi(index), %o0:
+ *p++ = 0x11000000 | (index >> 10);
+ // 4*4: or %o0, %lo(index), %o0:
+ *p++ = 0x90122000 | (index & 0x3FF);
+ // 5*4: sethi %hi(vtableOffset), %o1:
+ *p++ = 0x13000000 | (vtableOffset >> 10);
+ // 6*4: jmpl %l0, %g0, %g0:
+ *p++ = 0x81C40000;
+ // 7*4: or %o1, %lo(vtableOffset), %o1:
+ *p++ = 0x92126000 | (vtableOffset & 0x3FF);
+ // 8*4: .xword privateSnippetExecutor:
+ *reinterpret_cast< unsigned long * >(p) =
+ reinterpret_cast< unsigned long >(vtableSlotCall);
+ return code + codeSnippetSize;
+}
+
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block) {
+ return static_cast< Slot * >(block) + 1;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 3) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block) + 2;
+ slots[-3].fn = NULL; // RTTI
+ slots[-2].fn = NULL; // null
+ slots[-1].fn = NULL; // destructor
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code;
+ code = generateCodeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::cc5_solaris_sparc64::isDirectReturnType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code;
+ code = generateCodeSnippet(
+ code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code;
+ code = generateCodeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::cc5_solaris_sparc64::isDirectReturnType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const * begin, unsigned char const * end)
+{
+ bridges::cpp_uno::cc5_solaris_sparc64::flushCode(begin, end);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.cxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.cxx
new file mode 100644
index 000000000000..bf6b1512a41d
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.cxx
@@ -0,0 +1,462 @@
+/* -*- 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 "precompiled_bridges.hxx"
+#include "sal/config.h"
+
+#include <cstddef>
+#include <cstring>
+#include <map>
+#include <utility>
+#include <vector>
+
+#include "bridges/cpp_uno/shared/arraypointer.hxx"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/uno/genfunc.hxx"
+#include "osl/diagnose.h"
+#include "osl/mutex.hxx"
+#include "rtl/strbuf.hxx"
+#include "rtl/string.hxx"
+#include "rtl/textenc.h"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "typelib/typeclass.h"
+#include "typelib/typedescription.h"
+#include "uno/any2.h"
+#include "uno/data.h"
+#include "uno/mapping.h"
+
+#include "exceptions.hxx"
+#include "flushcode.hxx"
+
+namespace {
+
+namespace css = com::sun::star;
+
+typedef void (* Function)(void *);
+
+Function toFunction(void * pointer) {
+#pragma disable_warn
+ return reinterpret_cast< Function >(pointer);
+#pragma enable_warn
+}
+
+bool toUnoName(char const * rttiName, rtl::OUString * unoName) {
+ rtl::OStringBuffer buf;
+ for (;;) {
+ char const * p = std::strchr(rttiName, ':');
+ if (p == NULL) {
+ buf.append(rttiName);
+ break;
+ }
+ if (p - rttiName > SAL_MAX_INT32) {
+ return false;
+ }
+ buf.append(rttiName, sal::static_int_cast< sal_Int32 >(p - rttiName));
+ buf.append(".");
+ while (*p == ':') {
+ ++p;
+ }
+ rttiName = p;
+ }
+ *unoName = rtl::OStringToOUString(
+ buf.makeStringAndClear(), RTL_TEXTENCODING_UTF8);
+ //TODO: check conversion failure
+ return true;
+}
+
+class NistHash {
+public:
+ NistHash(rtl::OString const & text);
+
+ sal_uInt32 hashdata[5];
+
+private:
+ static sal_uInt32 f1(sal_uInt32 x, sal_uInt32 y, sal_uInt32 z)
+ { return z ^ (x & (y ^ z)); }
+
+ static sal_uInt32 f2(sal_uInt32 x, sal_uInt32 y, sal_uInt32 z)
+ { return x ^ y ^ z; }
+
+ static sal_uInt32 f3(sal_uInt32 x, sal_uInt32 y, sal_uInt32 z)
+ { return (x & y) + (z & (x ^ y)); }
+
+ static sal_uInt32 rotl(sal_uInt32 value, sal_uInt32 bits)
+ { return (value << bits) | (value >> (32 - bits)); }
+
+ sal_uInt32 expand_nostore(sal_uInt32 index) {
+ return data[index & 15] ^ data[(index - 14) & 15] ^
+ data[(index - 8) & 15] ^ data[(index - 3) & 15];
+ }
+
+ sal_uInt32 expand_store(sal_uInt32 index) {
+ return data[index & 15] ^= data[(index - 14) & 15] ^
+ data[(index - 8) & 15] ^ data[(index - 3) & 15];
+ }
+
+ void subRound(
+ sal_uInt32 a, sal_uInt32 & b, sal_uInt32 c, sal_uInt32 d,
+ sal_uInt32 & e, sal_uInt32 constant, sal_uInt32 datum,
+ sal_uInt32 function)
+ {
+ e += rotl(a, 5);
+ switch (function) {
+ case 1:
+ e += f1(b, c, d);
+ break;
+ case 2:
+ case 4:
+ e += f2(b, c, d);
+ break;
+ case 3:
+ e += f3(b, c, d);
+ break;
+ }
+ e += constant + datum;
+ b = rotl(b, 30);
+ }
+
+ void transform();
+
+ sal_uInt32 data[16];
+};
+
+NistHash::NistHash(rtl::OString const & text) {
+ hashdata[0] = 0x67452301;
+ hashdata[1] = 0xefcdab89;
+ hashdata[2] = 0x98badcfe;
+ hashdata[3] = 0x10325476;
+ hashdata[4] = 0xc3d2e1f0;
+ char const * p = text.getStr();
+ sal_Int32 n = text.getLength();
+ while (n >= sizeof data) {
+ std::memcpy(data, p, sizeof data);
+ p += sizeof data;
+ n -= sizeof data;
+ transform();
+ }
+ std::memcpy(data, p, n);
+ reinterpret_cast< unsigned char *>(data)[n++] = 0x80;
+ if (n > sizeof data - 8) {
+ std::memset(reinterpret_cast< char * >(data) + n, 0, sizeof data - n);
+ transform();
+ std::memset(data, 0, sizeof data - 8);
+ } else {
+ std::memset(
+ reinterpret_cast< char * >(data) + n, 0, sizeof data - 8 - n);
+ }
+ data[14] = 0;
+ data[15] = text.getLength() << 3;
+ transform();
+}
+
+void NistHash::transform() {
+ sal_uInt32 const K2 = 0x5A827999;
+ sal_uInt32 const K3 = 0x6ED9EBA1;
+ sal_uInt32 const K5 = 0x8F1BBCDC;
+ sal_uInt32 const K10 = 0xCA62C1D6;
+ sal_uInt32 a = hashdata[0];
+ sal_uInt32 b = hashdata[1];
+ sal_uInt32 c = hashdata[2];
+ sal_uInt32 d = hashdata[3];
+ sal_uInt32 e = hashdata[4];
+ subRound(a, b, c, d, e, K2, data[ 0], 1);
+ subRound(e, a, b, c, d, K2, data[ 1], 1);
+ subRound(d, e, a, b, c, K2, data[ 2], 1);
+ subRound(c, d, e, a, b, K2, data[ 3], 1);
+ subRound(b, c, d, e, a, K2, data[ 4], 1);
+ subRound(a, b, c, d, e, K2, data[ 5], 1);
+ subRound(e, a, b, c, d, K2, data[ 6], 1);
+ subRound(d, e, a, b, c, K2, data[ 7], 1);
+ subRound(c, d, e, a, b, K2, data[ 8], 1);
+ subRound(b, c, d, e, a, K2, data[ 9], 1);
+ subRound(a, b, c, d, e, K2, data[10], 1);
+ subRound(e, a, b, c, d, K2, data[11], 1);
+ subRound(d, e, a, b, c, K2, data[12], 1);
+ subRound(c, d, e, a, b, K2, data[13], 1);
+ subRound(b, c, d, e, a, K2, data[14], 1);
+ subRound(a, b, c, d, e, K2, data[15], 1);
+ subRound(e, a, b, c, d, K2, expand_store(16), 1);
+ subRound(d, e, a, b, c, K2, expand_store(17), 1);
+ subRound(c, d, e, a, b, K2, expand_store(18), 1);
+ subRound(b, c, d, e, a, K2, expand_store(19), 1);
+ subRound(a, b, c, d, e, K3, expand_store(20), 2);
+ subRound(e, a, b, c, d, K3, expand_store(21), 2);
+ subRound(d, e, a, b, c, K3, expand_store(22), 2);
+ subRound(c, d, e, a, b, K3, expand_store(23), 2);
+ subRound(b, c, d, e, a, K3, expand_store(24), 2);
+ subRound(a, b, c, d, e, K3, expand_store(25), 2);
+ subRound(e, a, b, c, d, K3, expand_store(26), 2);
+ subRound(d, e, a, b, c, K3, expand_store(27), 2);
+ subRound(c, d, e, a, b, K3, expand_store(28), 2);
+ subRound(b, c, d, e, a, K3, expand_store(29), 2);
+ subRound(a, b, c, d, e, K3, expand_store(30), 2);
+ subRound(e, a, b, c, d, K3, expand_store(31), 2);
+ subRound(d, e, a, b, c, K3, expand_store(32), 2);
+ subRound(c, d, e, a, b, K3, expand_store(33), 2);
+ subRound(b, c, d, e, a, K3, expand_store(34), 2);
+ subRound(a, b, c, d, e, K3, expand_store(35), 2);
+ subRound(e, a, b, c, d, K3, expand_store(36), 2);
+ subRound(d, e, a, b, c, K3, expand_store(37), 2);
+ subRound(c, d, e, a, b, K3, expand_store(38), 2);
+ subRound(b, c, d, e, a, K3, expand_store(39), 2);
+ subRound(a, b, c, d, e, K5, expand_store(40), 3);
+ subRound(e, a, b, c, d, K5, expand_store(41), 3);
+ subRound(d, e, a, b, c, K5, expand_store(42), 3);
+ subRound(c, d, e, a, b, K5, expand_store(43), 3);
+ subRound(b, c, d, e, a, K5, expand_store(44), 3);
+ subRound(a, b, c, d, e, K5, expand_store(45), 3);
+ subRound(e, a, b, c, d, K5, expand_store(46), 3);
+ subRound(d, e, a, b, c, K5, expand_store(47), 3);
+ subRound(c, d, e, a, b, K5, expand_store(48), 3);
+ subRound(b, c, d, e, a, K5, expand_store(49), 3);
+ subRound(a, b, c, d, e, K5, expand_store(50), 3);
+ subRound(e, a, b, c, d, K5, expand_store(51), 3);
+ subRound(d, e, a, b, c, K5, expand_store(52), 3);
+ subRound(c, d, e, a, b, K5, expand_store(53), 3);
+ subRound(b, c, d, e, a, K5, expand_store(54), 3);
+ subRound(a, b, c, d, e, K5, expand_store(55), 3);
+ subRound(e, a, b, c, d, K5, expand_store(56), 3);
+ subRound(d, e, a, b, c, K5, expand_store(57), 3);
+ subRound(c, d, e, a, b, K5, expand_store(58), 3);
+ subRound(b, c, d, e, a, K5, expand_store(59), 3);
+ subRound(a, b, c, d, e, K10, expand_store(60), 4);
+ subRound(e, a, b, c, d, K10, expand_store(61), 4);
+ subRound(d, e, a, b, c, K10, expand_store(62), 4);
+ subRound(c, d, e, a, b, K10, expand_store(63), 4);
+ subRound(b, c, d, e, a, K10, expand_store(64), 4);
+ subRound(a, b, c, d, e, K10, expand_store(65), 4);
+ subRound(e, a, b, c, d, K10, expand_store(66), 4);
+ subRound(d, e, a, b, c, K10, expand_store(67), 4);
+ subRound(c, d, e, a, b, K10, expand_store(68), 4);
+ subRound(b, c, d, e, a, K10, expand_store(69), 4);
+ subRound(a, b, c, d, e, K10, expand_store(70), 4);
+ subRound(e, a, b, c, d, K10, expand_store(71), 4);
+ subRound(d, e, a, b, c, K10, expand_store(72), 4);
+ subRound(c, d, e, a, b, K10, expand_store(73), 4);
+ subRound(b, c, d, e, a, K10, expand_store(74), 4);
+ subRound(a, b, c, d, e, K10, expand_store(75), 4);
+ subRound(e, a, b, c, d, K10, expand_store(76), 4);
+ subRound(d, e, a, b, c, K10, expand_nostore(77), 4);
+ subRound(c, d, e, a, b, K10, expand_nostore(78), 4);
+ subRound(b, c, d, e, a, K10, expand_nostore(79), 4);
+ hashdata[0] += a;
+ hashdata[1] += b;
+ hashdata[2] += c;
+ hashdata[3] += d;
+ hashdata[4] += e;
+}
+
+class RttiMap {
+public:
+ static __Crun::static_type_info const * get(
+ typelib_CompoundTypeDescription const * type);
+
+private:
+ RttiMap(); // not defined
+ RttiMap(RttiMap &); // not defined
+ ~RttiMap(); // not defined
+ void operator =(RttiMap &); // not defined
+
+ struct Data {
+ __Crun::static_type_info * info;
+ rtl::OString cppName;
+ std::vector< __Crun::class_base_descr > bases;
+ };
+ typedef std::map< rtl::OUString, Data > Map;
+
+ static void toCppNames(
+ rtl::OUString const & unoName, rtl::OString * cppName,
+ rtl::OString * rttiName);
+
+ static Data const & get_(typelib_CompoundTypeDescription const * type);
+
+ static osl::Mutex m_mutex;
+ static Map * m_map;
+};
+
+osl::Mutex RttiMap::m_mutex;
+RttiMap::Map * RttiMap::m_map;
+
+__Crun::static_type_info const * RttiMap::get(
+ typelib_CompoundTypeDescription const * type)
+{
+ osl::MutexGuard g(m_mutex);
+ if (m_map == NULL) {
+ m_map = new Map; // leaked
+ }
+ return get_(type).info;
+}
+
+void RttiMap::toCppNames(
+ rtl::OUString const & unoName, rtl::OString * cppName,
+ rtl::OString * rttiName)
+{
+ OSL_ASSERT(cppName != NULL && rttiName != NULL);
+ rtl::OStringBuffer bc;
+ rtl::OStringBuffer br;
+ br.append("__1n");
+ for (sal_Int32 i = 0; i != -1;) {
+ rtl::OUString tok(unoName.getToken(0, '.', i));
+ bc.append(rtl::OUStringToOString(tok, RTL_TEXTENCODING_UTF8));
+ // conversion should never fail, as tok should be well-formed ASCII
+ if (i != -1) {
+ bc.append("::");
+ }
+ sal_Int32 len = tok.getLength();
+ sal_Int32 pos = br.getLength();
+ for (sal_Int32 n = len / 26; n > 0; n /= 26) {
+ br.insert(pos, static_cast< char >('a' + (n % 26)));
+ }
+ br.append(static_cast< char >('A' + (len % 26)));
+ for (sal_Int32 j = 0; j < len; ++j) {
+ sal_Unicode c = tok[j];
+ OSL_ASSERT(
+ c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' || c == '_' ||
+ c >= 'a' && c <= 'z');
+ if (c == 'Q') {
+ br.append("QdD");
+ } else {
+ br.append(static_cast< char >(c));
+ }
+ }
+ }
+ br.append('_');
+ *cppName = bc.makeStringAndClear();
+ *rttiName = br.makeStringAndClear();
+}
+
+RttiMap::Data const & RttiMap::get_(
+ typelib_CompoundTypeDescription const * type)
+{
+ rtl::OUString name(type->aBase.pTypeName);
+ Map::iterator it(m_map->find(name));
+ if (it == m_map->end()) {
+ it = m_map->insert(std::make_pair(name, Data())).first;
+ Data & data = it->second;
+ rtl::OString rttiName;
+ toCppNames(name, &data.cppName, &rttiName);
+ data.info = new __Crun::static_type_info;
+ data.info->ty_name = data.cppName.getStr() -
+ reinterpret_cast< char * >(&data.info->ty_name);
+ data.info->reserved = 0;
+ NistHash hash(rttiName);
+ data.info->type_hash[0] = hash.hashdata[0];
+ data.info->type_hash[1] = hash.hashdata[1];
+ data.info->type_hash[2] = hash.hashdata[2];
+ data.info->type_hash[3] = hash.hashdata[3];
+ data.info->flags = 0;
+ data.info->cv_qualifiers = 0;
+ if (type->pBaseTypeDescription != NULL) {
+ data.bases = get_(type->pBaseTypeDescription).bases;
+ OSL_ASSERT(!data.bases.empty());
+ data.bases.back().offset = 0;
+ }
+ __Crun::class_base_descr last;
+ last.type_hash[0] = data.info->type_hash[0];
+ last.type_hash[1] = data.info->type_hash[1];
+ last.type_hash[2] = data.info->type_hash[2];
+ last.type_hash[3] = data.info->type_hash[3];
+ last.offset = 0x8000000000000000;
+ data.bases.push_back(last);
+ data.info->base_table = reinterpret_cast< char * >(&data.bases[0]) -
+ reinterpret_cast< char * >(&data.info->base_table);
+ }
+ return it->second;
+}
+
+void deleteException(
+ void * exception, unsigned int * thunk, typelib_TypeDescription * type)
+{
+ uno_destructData(
+ exception, type,
+ reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release));
+ typelib_typedescription_release(type);
+ delete[] thunk;
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace cc5_solaris_sparc64 {
+
+void raiseException(uno_Any * exception, uno_Mapping * unoToCpp) {
+ bridges::cpp_uno::shared::ArrayPointer< unsigned long > thunkPtr(
+ new unsigned long[4]);
+ typelib_TypeDescription * type = NULL;
+ typelib_typedescriptionreference_getDescription(&type, exception->pType);
+ __Crun::static_type_info const * rtti = RttiMap::get(
+ reinterpret_cast< typelib_CompoundTypeDescription * >(type));
+ void * exc = __Crun::ex_alloc(type->nSize);
+ uno_copyAndConvertData(exc, exception->pData, type, unoToCpp);
+ uno_any_destruct(exception, NULL);
+ unsigned long * thunk = thunkPtr.release();
+ // 0*4: rd %pc, %o1:
+ // 1*4: ldx %o1, (6-0)*4, %o3:
+ thunk[0] = 0x93414000D65A6018;
+ // 2*4: jmpl %o3, %g0, %g0:
+ // 3*4: ldx %o1, (4-0)*4, %o2:
+ thunk[1] = 0x81C2C000D45A6010;
+ // 4*4: .xword type:
+ thunk[2] = reinterpret_cast< unsigned long >(type);
+ // 6*4: .xword deleteException:
+ thunk[3] = reinterpret_cast< unsigned long >(deleteException);
+ flushCode(thunk, thunk + 4);
+ __Crun::ex_throw(exc, rtti, toFunction(thunk));
+}
+
+void fillUnoException(
+ void * cppException, char const * cppName, uno_Any * unoException,
+ uno_Mapping * cppToUno)
+{
+ rtl::OUString name;
+ typelib_TypeDescription * type = NULL;
+ if (toUnoName(cppName, &name)) {
+ typelib_typedescription_getByName(&type, name.pData);
+ }
+ if (type == NULL || type->eTypeClass != typelib_TypeClass_EXCEPTION) {
+ css::uno::RuntimeException exc(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("Not a UNO exception type: ")) +
+ name),
+ css::uno::Reference< css::uno::XInterface >());
+ uno_type_any_constructAndConvert(
+ unoException, &exc, getCppuType(&exc).getTypeLibType(), cppToUno);
+ } else {
+ uno_any_constructAndConvert(unoException, cppException, type, cppToUno);
+ }
+ if (type != NULL) {
+ typelib_typedescription_release(type);
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.hxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.hxx
new file mode 100644
index 000000000000..8ba17dad842f
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/exceptions.hxx
@@ -0,0 +1,75 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_EXCEPTIONS_HXX
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_EXCEPTIONS_HXX
+
+#include "sal/config.h"
+
+#include <cstddef>
+
+#include "typelib/typedescription.h"
+#include "uno/any2.h"
+#include "uno/mapping.h"
+
+// Private CC5 structures and functions:
+namespace __Crun {
+ struct class_base_descr {
+ int type_hash[4];
+ std::size_t offset;
+ };
+ struct static_type_info {
+ std::ptrdiff_t ty_name;
+ std::ptrdiff_t reserved;
+ std::ptrdiff_t base_table;
+ int type_hash[4];
+ unsigned int flags;
+ unsigned int cv_qualifiers;
+ };
+ void * ex_alloc(unsigned long);
+ void ex_throw(void *, static_type_info const *, void (*)(void *));
+ void * ex_get();
+ void ex_rethrow_q() throw ();
+}
+namespace __Cimpl {
+ char const * ex_name();
+}
+
+namespace bridges { namespace cpp_uno { namespace cc5_solaris_sparc64 {
+
+void raiseException(uno_Any * exception, uno_Mapping * unoToCpp);
+
+void fillUnoException(
+ void * cppException, char const * cppName, uno_Any * unoException,
+ uno_Mapping * cppToUno);
+
+} } }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/flushcode.hxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/flushcode.hxx
new file mode 100644
index 000000000000..de7028d3faa2
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/flushcode.hxx
@@ -0,0 +1,51 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_FLUSHCODE_HXX
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_FLUSHCODE_HXX
+
+#include "sal/config.h"
+
+extern "C" void sync_instruction_memory(caddr_t addr, int len); // from libc
+
+namespace bridges { namespace cpp_uno { namespace cc5_solaris_sparc64 {
+
+/**
+ * Flush a region of memory into which code has been written dynamically.
+ */
+inline void flushCode(void const * begin, void const * end) {
+ sync_instruction_memory(
+ static_cast< caddr_t >(const_cast< void * >(begin)),
+ static_cast< char const * >(end) - static_cast< char const * >(begin));
+}
+
+} } }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/fp.hxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/fp.hxx
new file mode 100644
index 000000000000..ba32b141d338
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/fp.hxx
@@ -0,0 +1,116 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_FP_HXX
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_FP_HXX
+
+#include "sal/config.h"
+
+extern "C" {
+
+void fp_loadf0(float *);
+void fp_loadf1(float *);
+void fp_loadf2(float *);
+void fp_loadf3(float *);
+void fp_loadf4(float *);
+void fp_loadf5(float *);
+void fp_loadf6(float *);
+void fp_loadf7(float *);
+void fp_loadf9(float *);
+void fp_loadf11(float *);
+void fp_loadf13(float *);
+void fp_loadf15(float *);
+void fp_loadf17(float *);
+void fp_loadf19(float *);
+void fp_loadf21(float *);
+void fp_loadf23(float *);
+void fp_loadf25(float *);
+void fp_loadf27(float *);
+void fp_loadf29(float *);
+void fp_loadf31(float *);
+
+void fp_storef0(float *);
+void fp_storef1(float *);
+void fp_storef2(float *);
+void fp_storef3(float *);
+void fp_storef4(float *);
+void fp_storef5(float *);
+void fp_storef6(float *);
+void fp_storef7(float *);
+void fp_storef9(float *);
+void fp_storef11(float *);
+void fp_storef13(float *);
+void fp_storef15(float *);
+void fp_storef17(float *);
+void fp_storef19(float *);
+void fp_storef21(float *);
+void fp_storef23(float *);
+void fp_storef25(float *);
+void fp_storef27(float *);
+void fp_storef29(float *);
+void fp_storef31(float *);
+
+void fp_loadd0(double *);
+void fp_loadd2(double *);
+void fp_loadd4(double *);
+void fp_loadd6(double *);
+void fp_loadd8(double *);
+void fp_loadd10(double *);
+void fp_loadd12(double *);
+void fp_loadd14(double *);
+void fp_loadd16(double *);
+void fp_loadd18(double *);
+void fp_loadd20(double *);
+void fp_loadd22(double *);
+void fp_loadd24(double *);
+void fp_loadd26(double *);
+void fp_loadd28(double *);
+void fp_loadd30(double *);
+
+void fp_stored0(double *);
+void fp_stored2(double *);
+void fp_stored4(double *);
+void fp_stored6(double *);
+void fp_stored8(double *);
+void fp_stored10(double *);
+void fp_stored12(double *);
+void fp_stored14(double *);
+void fp_stored16(double *);
+void fp_stored18(double *);
+void fp_stored20(double *);
+void fp_stored22(double *);
+void fp_stored24(double *);
+void fp_stored26(double *);
+void fp_stored28(double *);
+void fp_stored30(double *);
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/fp.s b/bridges/source/cpp_uno/cc5_solaris_sparc64/fp.s
new file mode 100644
index 000000000000..92216d4e08dd
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/fp.s
@@ -0,0 +1,602 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+.global fp_loadf0
+.align 8
+fp_loadf0:
+ retl
+ ld [%o0], %f0
+.size fp_loadf0, . - fp_loadf0
+.type fp_loadf0, #function
+
+.global fp_loadf1
+.align 8
+fp_loadf1:
+ retl
+ ld [%o0], %f1
+.size fp_loadf1, . - fp_loadf1
+.type fp_loadf1, #function
+
+.global fp_loadf2
+.align 8
+fp_loadf2:
+ retl
+ ld [%o0], %f2
+.size fp_loadf2, . - fp_loadf2
+.type fp_loadf2, #function
+
+.global fp_loadf3
+.align 8
+fp_loadf3:
+ retl
+ ld [%o0], %f3
+.size fp_loadf3, . - fp_loadf3
+.type fp_loadf3, #function
+
+.global fp_loadf4
+.align 8
+fp_loadf4:
+ retl
+ ld [%o0], %f4
+.size fp_loadf4, . - fp_loadf4
+.type fp_loadf4, #function
+
+.global fp_loadf5
+.align 8
+fp_loadf5:
+ retl
+ ld [%o0], %f5
+.size fp_loadf5, . - fp_loadf5
+.type fp_loadf5, #function
+
+.global fp_loadf6
+.align 8
+fp_loadf6:
+ retl
+ ld [%o0], %f6
+.size fp_loadf6, . - fp_loadf6
+.type fp_loadf6, #function
+
+.global fp_loadf7
+.align 8
+fp_loadf7:
+ retl
+ ld [%o0], %f7
+.size fp_loadf7, . - fp_loadf7
+.type fp_loadf7, #function
+
+.global fp_loadf9
+.align 8
+fp_loadf9:
+ retl
+ ld [%o0], %f9
+.size fp_loadf9, . - fp_loadf9
+.type fp_loadf9, #function
+
+.global fp_loadf11
+.align 8
+fp_loadf11:
+ retl
+ ld [%o0], %f11
+.size fp_loadf11, . - fp_loadf11
+.type fp_loadf11, #function
+
+.global fp_loadf13
+.align 8
+fp_loadf13:
+ retl
+ ld [%o0], %f13
+.size fp_loadf13, . - fp_loadf13
+.type fp_loadf13, #function
+
+.global fp_loadf15
+.align 8
+fp_loadf15:
+ retl
+ ld [%o0], %f15
+.size fp_loadf15, . - fp_loadf15
+.type fp_loadf15, #function
+
+.global fp_loadf17
+.align 8
+fp_loadf17:
+ retl
+ ld [%o0], %f17
+.size fp_loadf17, . - fp_loadf17
+.type fp_loadf17, #function
+
+.global fp_loadf19
+.align 8
+fp_loadf19:
+ retl
+ ld [%o0], %f19
+.size fp_loadf19, . - fp_loadf19
+.type fp_loadf19, #function
+
+.global fp_loadf21
+.align 8
+fp_loadf21:
+ retl
+ ld [%o0], %f21
+.size fp_loadf21, . - fp_loadf21
+.type fp_loadf21, #function
+
+.global fp_loadf23
+.align 8
+fp_loadf23:
+ retl
+ ld [%o0], %f23
+.size fp_loadf23, . - fp_loadf23
+.type fp_loadf23, #function
+
+.global fp_loadf25
+.align 8
+fp_loadf25:
+ retl
+ ld [%o0], %f25
+.size fp_loadf25, . - fp_loadf25
+.type fp_loadf25, #function
+
+.global fp_loadf27
+.align 8
+fp_loadf27:
+ retl
+ ld [%o0], %f27
+.size fp_loadf27, . - fp_loadf27
+.type fp_loadf27, #function
+
+.global fp_loadf29
+.align 8
+fp_loadf29:
+ retl
+ ld [%o0], %f29
+.size fp_loadf29, . - fp_loadf29
+.type fp_loadf29, #function
+
+.global fp_loadf31
+.align 8
+fp_loadf31:
+ retl
+ ld [%o0], %f31
+.size fp_loadf31, . - fp_loadf31
+.type fp_loadf31, #function
+
+.global fp_storef0
+.align 8
+fp_storef0:
+ retl
+ st %f0, [%o0]
+.size fp_storef0, . - fp_storef0
+.type fp_storef0, #function
+
+.global fp_storef1
+.align 8
+fp_storef1:
+ retl
+ st %f1, [%o0]
+.size fp_storef1, . - fp_storef1
+.type fp_storef1, #function
+
+.global fp_storef2
+.align 8
+fp_storef2:
+ retl
+ st %f2, [%o0]
+.size fp_storef2, . - fp_storef2
+.type fp_storef2, #function
+
+.global fp_storef3
+.align 8
+fp_storef3:
+ retl
+ st %f3, [%o0]
+.size fp_storef3, . - fp_storef3
+.type fp_storef3, #function
+
+.global fp_storef4
+.align 8
+fp_storef4:
+ retl
+ st %f4, [%o0]
+.size fp_storef4, . - fp_storef4
+.type fp_storef4, #function
+
+.global fp_storef5
+.align 8
+fp_storef5:
+ retl
+ st %f5, [%o0]
+.size fp_storef5, . - fp_storef5
+.type fp_storef5, #function
+
+.global fp_storef6
+.align 8
+fp_storef6:
+ retl
+ st %f6, [%o0]
+.size fp_storef6, . - fp_storef6
+.type fp_storef6, #function
+
+.global fp_storef7
+.align 8
+fp_storef7:
+ retl
+ st %f7, [%o0]
+.size fp_storef7, . - fp_storef7
+.type fp_storef7, #function
+
+.global fp_storef9
+.align 8
+fp_storef9:
+ retl
+ st %f9, [%o0]
+.size fp_storef9, . - fp_storef9
+.type fp_storef9, #function
+
+.global fp_storef11
+.align 8
+fp_storef11:
+ retl
+ st %f11, [%o0]
+.size fp_storef11, . - fp_storef11
+.type fp_storef11, #function
+
+.global fp_storef13
+.align 8
+fp_storef13:
+ retl
+ st %f13, [%o0]
+.size fp_storef13, . - fp_storef13
+.type fp_storef13, #function
+
+.global fp_storef15
+.align 8
+fp_storef15:
+ retl
+ st %f15, [%o0]
+.size fp_storef15, . - fp_storef15
+.type fp_storef15, #function
+
+.global fp_storef17
+.align 8
+fp_storef17:
+ retl
+ st %f17, [%o0]
+.size fp_storef17, . - fp_storef17
+.type fp_storef17, #function
+
+.global fp_storef19
+.align 8
+fp_storef19:
+ retl
+ st %f19, [%o0]
+.size fp_storef19, . - fp_storef19
+.type fp_storef19, #function
+
+.global fp_storef21
+.align 8
+fp_storef21:
+ retl
+ st %f21, [%o0]
+.size fp_storef21, . - fp_storef21
+.type fp_storef21, #function
+
+.global fp_storef23
+.align 8
+fp_storef23:
+ retl
+ st %f23, [%o0]
+.size fp_storef23, . - fp_storef23
+.type fp_storef23, #function
+
+.global fp_storef25
+.align 8
+fp_storef25:
+ retl
+ st %f25, [%o0]
+.size fp_storef25, . - fp_storef25
+.type fp_storef25, #function
+
+.global fp_storef27
+.align 8
+fp_storef27:
+ retl
+ st %f27, [%o0]
+.size fp_storef27, . - fp_storef27
+.type fp_storef27, #function
+
+.global fp_storef29
+.align 8
+fp_storef29:
+ retl
+ st %f29, [%o0]
+.size fp_storef29, . - fp_storef29
+.type fp_storef29, #function
+
+.global fp_storef31
+.align 8
+fp_storef31:
+ retl
+ st %f31, [%o0]
+.size fp_storef31, . - fp_storef31
+.type fp_storef31, #function
+
+.global fp_loadd0
+.align 8
+fp_loadd0:
+ retl
+ ldd [%o0], %f0
+.size fp_loadd0, . - fp_loadd0
+.type fp_loadd0, #function
+
+.global fp_loadd2
+.align 8
+fp_loadd2:
+ retl
+ ldd [%o0], %f2
+.size fp_loadd2, . - fp_loadd2
+.type fp_loadd2, #function
+
+.global fp_loadd4
+.align 8
+fp_loadd4:
+ retl
+ ldd [%o0], %f4
+.size fp_loadd4, . - fp_loadd4
+.type fp_loadd4, #function
+
+.global fp_loadd6
+.align 8
+fp_loadd6:
+ retl
+ ldd [%o0], %f6
+.size fp_loadd6, . - fp_loadd6
+.type fp_loadd6, #function
+
+.global fp_loadd8
+.align 8
+fp_loadd8:
+ retl
+ ldd [%o0], %f8
+.size fp_loadd8, . - fp_loadd8
+.type fp_loadd8, #function
+
+.global fp_loadd10
+.align 8
+fp_loadd10:
+ retl
+ ldd [%o0], %f10
+.size fp_loadd10, . - fp_loadd10
+.type fp_loadd10, #function
+
+.global fp_loadd12
+.align 8
+fp_loadd12:
+ retl
+ ldd [%o0], %f12
+.size fp_loadd12, . - fp_loadd12
+.type fp_loadd12, #function
+
+.global fp_loadd14
+.align 8
+fp_loadd14:
+ retl
+ ldd [%o0], %f14
+.size fp_loadd14, . - fp_loadd14
+.type fp_loadd14, #function
+
+.global fp_loadd16
+.align 8
+fp_loadd16:
+ retl
+ ldd [%o0], %f16
+.size fp_loadd16, . - fp_loadd16
+.type fp_loadd16, #function
+
+.global fp_loadd18
+.align 8
+fp_loadd18:
+ retl
+ ldd [%o0], %f18
+.size fp_loadd18, . - fp_loadd18
+.type fp_loadd18, #function
+
+.global fp_loadd20
+.align 8
+fp_loadd20:
+ retl
+ ldd [%o0], %f20
+.size fp_loadd20, . - fp_loadd20
+.type fp_loadd20, #function
+
+.global fp_loadd22
+.align 8
+fp_loadd22:
+ retl
+ ldd [%o0], %f22
+.size fp_loadd22, . - fp_loadd22
+.type fp_loadd22, #function
+
+.global fp_loadd24
+.align 8
+fp_loadd24:
+ retl
+ ldd [%o0], %f24
+.size fp_loadd24, . - fp_loadd24
+.type fp_loadd24, #function
+
+.global fp_loadd26
+.align 8
+fp_loadd26:
+ retl
+ ldd [%o0], %f26
+.size fp_loadd26, . - fp_loadd26
+.type fp_loadd26, #function
+
+.global fp_loadd28
+.align 8
+fp_loadd28:
+ retl
+ ldd [%o0], %f28
+.size fp_loadd28, . - fp_loadd28
+.type fp_loadd28, #function
+
+.global fp_loadd30
+.align 8
+fp_loadd30:
+ retl
+ ldd [%o0], %f30
+.size fp_loadd30, . - fp_loadd30
+.type fp_loadd30, #function
+
+.global fp_stored0
+.align 8
+fp_stored0:
+ retl
+ std %f0, [%o0]
+.size fp_stored0, . - fp_stored0
+.type fp_stored0, #function
+
+.global fp_stored2
+.align 8
+fp_stored2:
+ retl
+ std %f2, [%o0]
+.size fp_stored2, . - fp_stored2
+.type fp_stored2, #function
+
+.global fp_stored4
+.align 8
+fp_stored4:
+ retl
+ std %f4, [%o0]
+.size fp_stored4, . - fp_stored4
+.type fp_stored4, #function
+
+.global fp_stored6
+.align 8
+fp_stored6:
+ retl
+ std %f6, [%o0]
+.size fp_stored6, . - fp_stored6
+.type fp_stored6, #function
+
+.global fp_stored8
+.align 8
+fp_stored8:
+ retl
+ std %f8, [%o0]
+.size fp_stored8, . - fp_stored8
+.type fp_stored8, #function
+
+.global fp_stored10
+.align 8
+fp_stored10:
+ retl
+ std %f10, [%o0]
+.size fp_stored10, . - fp_stored10
+.type fp_stored10, #function
+
+.global fp_stored12
+.align 8
+fp_stored12:
+ retl
+ std %f12, [%o0]
+.size fp_stored12, . - fp_stored12
+.type fp_stored12, #function
+
+.global fp_stored14
+.align 8
+fp_stored14:
+ retl
+ std %f14, [%o0]
+.size fp_stored14, . - fp_stored14
+.type fp_stored14, #function
+
+.global fp_stored16
+.align 8
+fp_stored16:
+ retl
+ std %f16, [%o0]
+.size fp_stored16, . - fp_stored16
+.type fp_stored16, #function
+
+.global fp_stored18
+.align 8
+fp_stored18:
+ retl
+ std %f18, [%o0]
+.size fp_stored18, . - fp_stored18
+.type fp_stored18, #function
+
+.global fp_stored20
+.align 8
+fp_stored20:
+ retl
+ std %f20, [%o0]
+.size fp_stored20, . - fp_stored20
+.type fp_stored20, #function
+
+.global fp_stored22
+.align 8
+fp_stored22:
+ retl
+ std %f22, [%o0]
+.size fp_stored22, . - fp_stored22
+.type fp_stored22, #function
+
+.global fp_stored24
+.align 8
+fp_stored24:
+ retl
+ std %f24, [%o0]
+.size fp_stored24, . - fp_stored24
+.type fp_stored24, #function
+
+.global fp_stored26
+.align 8
+fp_stored26:
+ retl
+ std %f26, [%o0]
+.size fp_stored26, . - fp_stored26
+.type fp_stored26, #function
+
+.global fp_stored28
+.align 8
+fp_stored28:
+ retl
+ std %f28, [%o0]
+.size fp_stored28, . - fp_stored28
+.type fp_stored28, #function
+
+.global fp_stored30
+.align 8
+fp_stored30:
+ retl
+ std %f30, [%o0]
+.size fp_stored30, . - fp_stored30
+.type fp_stored30, #function
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/isdirectreturntype.cxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/isdirectreturntype.cxx
new file mode 100644
index 000000000000..9b004078c35f
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/isdirectreturntype.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 "precompiled_bridges.hxx"
+#include "sal/config.h"
+
+#include <cstddef>
+
+#include "sal/types.h"
+#include "typelib/typeclass.h"
+#include "typelib/typedescription.h"
+
+#include "isdirectreturntype.hxx"
+
+namespace {
+
+bool isPodStruct(typelib_CompoundTypeDescription * type) {
+ for (; type != NULL; type = type->pBaseTypeDescription) {
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ if (!bridges::cpp_uno::cc5_solaris_sparc64::isDirectReturnType(
+ type->ppTypeRefs[i]))
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace cc5_solaris_sparc64 {
+
+bool isDirectReturnType(typelib_TypeDescriptionReference * type) {
+ // Is POD of size <= 32 bytes:
+ switch (type->eTypeClass) {
+ default:
+ return true;
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_INTERFACE:
+ return false;
+ case typelib_TypeClass_STRUCT:
+ {
+ typelib_TypeDescription * t = NULL;
+ TYPELIB_DANGER_GET(&t, type);
+ bool b = t->nSize <= 32 && isPodStruct(
+ reinterpret_cast< typelib_CompoundTypeDescription * >(t));
+ TYPELIB_DANGER_RELEASE(t);
+ return b;
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/isdirectreturntype.hxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/isdirectreturntype.hxx
new file mode 100644
index 000000000000..f9741a8898a5
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/isdirectreturntype.hxx
@@ -0,0 +1,44 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_ISDIRECTRETURNTYPE_x
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_ISDIRECTRETURNTYPE_x
+
+#include "sal/config.h"
+
+#include "typelib/typedescription.h"
+
+namespace bridges { namespace cpp_uno { namespace cc5_solaris_sparc64 {
+
+bool isDirectReturnType(typelib_TypeDescriptionReference * type);
+
+} } }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/makefile.mk b/bridges/source/cpp_uno/cc5_solaris_sparc64/makefile.mk
new file mode 100644
index 000000000000..ec64b1db49dd
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/makefile.mk
@@ -0,0 +1,61 @@
+#*************************************************************************
+#
+# 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 := sunpro5_uno
+ENABLE_EXCEPTIONS := TRUE
+
+.INCLUDE: settings.mk
+
+.IF "$(COM)" == "C52" && "$(CPU)" == "U"
+
+SHL1TARGET = $(TARGET)
+SHL1OBJS = \
+ $(SLO)$/callvirtualmethod.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/exceptions.obj \
+ $(SLO)$/fp.obj \
+ $(SLO)$/isdirectreturntype.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/vtableslotcall.obj
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+SHL1STDLIBS = $(CPPULIB) $(SALLIB)
+SHL1RPATH = URELIB
+SHL1VERSIONMAP = ..$/..$/bridge_exports.map
+SHL1IMPLIB= i$(SHL1TARGET)
+DEF1NAME = $(SHL1TARGET)
+
+SLOFILES = $(SHL1OBJS)
+
+.ENDIF
+
+.INCLUDE: target.mk
+
+$(SLO)$/%.obj: %.s
+ CC -m64 -KPIC -c -o $(SLO)$/$(@:b).o $<
+ touch $@
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/uno2cpp.cxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/uno2cpp.cxx
new file mode 100644
index 000000000000..e6646dca42a1
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/uno2cpp.cxx
@@ -0,0 +1,512 @@
+/* -*- 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 "precompiled_bridges.hxx"
+#include "sal/config.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <cstring>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/genfunc.hxx"
+#include "osl/diagnose.h"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/alloca.h"
+#include "sal/types.h"
+#include "typelib/typeclass.h"
+#include "typelib/typedescription.h"
+#include "uno/any2.h"
+#include "uno/data.h"
+
+#include "callvirtualmethod.hxx"
+#include "exceptions.hxx"
+#include "fp.hxx"
+#include "isdirectreturntype.hxx"
+
+namespace {
+
+namespace css = com::sun::star;
+
+void storeFpRegsToStruct(typelib_TypeDescription * type, void * data) {
+ for (typelib_CompoundTypeDescription * t =
+ reinterpret_cast< typelib_CompoundTypeDescription * >(type);
+ t != NULL; t = t->pBaseTypeDescription)
+ {
+ for (sal_Int32 i = 0; i < t->nMembers; ++i) {
+ switch (t->ppTypeRefs[i]->eTypeClass) {
+ case typelib_TypeClass_FLOAT:
+ switch (t->pMemberOffsets[i]) {
+ case 0:
+ fp_storef0(reinterpret_cast< float * >(data));
+ break;
+ case 4:
+ fp_storef1(reinterpret_cast< float * >(data) + 1);
+ break;
+ case 8:
+ fp_storef2(reinterpret_cast< float * >(data) + 2);
+ break;
+ case 12:
+ fp_storef3(reinterpret_cast< float * >(data) + 3);
+ break;
+ case 16:
+ fp_storef4(reinterpret_cast< float * >(data) + 4);
+ break;
+ case 20:
+ fp_storef5(reinterpret_cast< float * >(data) + 5);
+ break;
+ case 24:
+ fp_storef6(reinterpret_cast< float * >(data) + 6);
+ break;
+ case 28:
+ fp_storef7(reinterpret_cast< float * >(data) + 7);
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ switch (t->pMemberOffsets[i]) {
+ case 0:
+ fp_stored0(reinterpret_cast< double * >(data));
+ break;
+ case 8:
+ fp_stored2(reinterpret_cast< double * >(data) + 1);
+ break;
+ case 16:
+ fp_stored4(reinterpret_cast< double * >(data) + 2);
+ break;
+ case 24:
+ fp_stored6(reinterpret_cast< double * >(data) + 3);
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ break;
+ case typelib_TypeClass_STRUCT:
+ {
+ typelib_TypeDescription * td = NULL;
+ TYPELIB_DANGER_GET(&td, t->ppTypeRefs[i]);
+ storeFpRegsToStruct(td, data);
+ TYPELIB_DANGER_RELEASE(td);
+ break;
+ }
+ }
+ }
+ }
+}
+
+void call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * proxy,
+ bridges::cpp_uno::shared::VtableSlot slot,
+ typelib_TypeDescriptionReference * returnType, sal_Int32 count,
+ typelib_MethodParameter * parameters, void * returnValue, void ** arguments,
+ uno_Any ** exception)
+{
+ bool directRet = bridges::cpp_uno::cc5_solaris_sparc64::isDirectReturnType(
+ returnType);
+ long * stack = static_cast< long * >(
+ alloca(
+ std::max< sal_Int32 >(count + (directRet ? 1 : 2), 4) *
+ sizeof (long)));
+ sal_Int32 sp = 0;
+ typelib_TypeDescription * rtd = NULL;
+ TYPELIB_DANGER_GET(&rtd, returnType);
+ bool retconv = bridges::cpp_uno::shared::relatesToInterfaceType(rtd);
+ OSL_ASSERT(!(directRet && retconv));
+ void * ret;
+ if (!directRet) {
+ ret = retconv ? alloca(rtd->nSize) : returnValue;
+ stack[sp++] = reinterpret_cast< long >(ret);
+ }
+ unsigned long ** thisPtr = reinterpret_cast< unsigned long ** >(
+ proxy->getCppI()) + slot.offset;
+ stack[sp++] = reinterpret_cast< long >(thisPtr);
+ void ** cppArgs = static_cast< void ** >(alloca(count * sizeof (void *)));
+ typelib_TypeDescription ** ptds =
+ static_cast< typelib_TypeDescription ** >(
+ alloca(count * sizeof (typelib_TypeDescription *)));
+ for (sal_Int32 i = 0; i < count; ++i) {
+ if (!parameters[i].bOut &&
+ bridges::cpp_uno::shared::isSimpleType(parameters[i].pTypeRef))
+ {
+ cppArgs[i] = NULL;
+ switch (parameters[i].pTypeRef->eTypeClass) {
+ case typelib_TypeClass_BOOLEAN:
+ stack[sp] = *static_cast< sal_Bool * >(arguments[i]);
+ break;
+ case typelib_TypeClass_BYTE:
+ stack[sp] = *static_cast< sal_Int8 * >(arguments[i]);
+ break;
+ case typelib_TypeClass_SHORT:
+ stack[sp] = *static_cast< sal_Int16 * >(arguments[i]);
+ break;
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ stack[sp] = *static_cast< sal_uInt16 * >(arguments[i]);
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_ENUM:
+ stack[sp] = *static_cast< sal_Int32 * >(arguments[i]);
+ break;
+ case typelib_TypeClass_UNSIGNED_LONG:
+ stack[sp] = *static_cast< sal_uInt32 * >(arguments[i]);
+ break;
+ case typelib_TypeClass_HYPER:
+ stack[sp] = *static_cast< sal_Int64 * >(arguments[i]);
+ break;
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ stack[sp] = *static_cast< sal_uInt64 * >(arguments[i]);
+ break;
+ case typelib_TypeClass_FLOAT:
+ {
+ float * f = static_cast< float * >(arguments[i]);
+ switch (sp) {
+ case 1:
+ fp_loadf3(f);
+ break;
+ case 2:
+ fp_loadf5(f);
+ break;
+ case 3:
+ fp_loadf7(f);
+ break;
+ case 4:
+ fp_loadf9(f);
+ break;
+ case 5:
+ fp_loadf11(f);
+ break;
+ case 6:
+ fp_loadf13(f);
+ break;
+ case 7:
+ fp_loadf15(f);
+ break;
+ case 8:
+ fp_loadf17(f);
+ break;
+ case 9:
+ fp_loadf19(f);
+ break;
+ case 10:
+ fp_loadf21(f);
+ break;
+ case 11:
+ fp_loadf23(f);
+ break;
+ case 12:
+ fp_loadf25(f);
+ break;
+ case 13:
+ fp_loadf27(f);
+ break;
+ case 14:
+ fp_loadf29(f);
+ break;
+ case 15:
+ fp_loadf31(f);
+ break;
+ default:
+ reinterpret_cast< float * >(stack + sp)[1] = *f;
+ break;
+ }
+ break;
+ }
+ case typelib_TypeClass_DOUBLE:
+ {
+ double * d = static_cast< double * >(arguments[i]);
+ switch (sp) {
+ case 1:
+ fp_loadd2(d);
+ break;
+ case 2:
+ fp_loadd4(d);
+ break;
+ case 3:
+ fp_loadd6(d);
+ break;
+ case 4:
+ fp_loadd8(d);
+ break;
+ case 5:
+ fp_loadd10(d);
+ break;
+ case 6:
+ fp_loadd12(d);
+ break;
+ case 7:
+ fp_loadd14(d);
+ break;
+ case 8:
+ fp_loadd16(d);
+ break;
+ case 9:
+ fp_loadd18(d);
+ break;
+ case 10:
+ fp_loadd20(d);
+ break;
+ case 11:
+ fp_loadd22(d);
+ break;
+ case 12:
+ fp_loadd24(d);
+ break;
+ case 13:
+ fp_loadd26(d);
+ break;
+ case 14:
+ fp_loadd28(d);
+ break;
+ case 15:
+ fp_loadd30(d);
+ break;
+ default:
+ *reinterpret_cast< double * >(stack + sp) = *d;
+ break;
+ }
+ break;
+ }
+ case typelib_TypeClass_CHAR:
+ stack[sp] = *static_cast< sal_Unicode * >(arguments[i]);
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ } else {
+ typelib_TypeDescription * ptd = NULL;
+ TYPELIB_DANGER_GET(&ptd, parameters[i].pTypeRef);
+ if (!parameters[i].bIn) {
+ cppArgs[i] = alloca(ptd->nSize);
+ uno_constructData(cppArgs[i], ptd);
+ ptds[i] = ptd;
+ *reinterpret_cast< void ** >(stack + sp) = cppArgs[i];
+ } else if (bridges::cpp_uno::shared::relatesToInterfaceType(ptd)) {
+ cppArgs[i] = alloca(ptd->nSize);
+ uno_copyAndConvertData(
+ cppArgs[i], arguments[i], ptd,
+ proxy->getBridge()->getUno2Cpp());
+ ptds[i] = ptd;
+ *reinterpret_cast< void ** >(stack + sp) = cppArgs[i];
+ } else {
+ cppArgs[i] = NULL;
+ *reinterpret_cast< void ** >(stack + sp) = arguments[i];
+ TYPELIB_DANGER_RELEASE(ptd);
+ }
+ }
+ ++sp;
+ }
+ try {
+ callVirtualMethod(
+ (*thisPtr)[slot.index + 2], stack,
+ std::max< sal_Int32 >(sp - 6, 0) * sizeof (long));
+ } catch (css::uno::Exception &) {
+ void * exc = __Crun::ex_get();
+ char const * name = __Cimpl::ex_name();
+ bridges::cpp_uno::cc5_solaris_sparc64::fillUnoException(
+ exc, name, *exception, proxy->getBridge()->getCpp2Uno());
+ for (sal_Int32 i = 0; i < count; ++i) {
+ if (cppArgs[i] != NULL) {
+ uno_destructData(
+ cppArgs[i], ptds[i],
+ reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release));
+ TYPELIB_DANGER_RELEASE(ptds[i]);
+ }
+ }
+ TYPELIB_DANGER_RELEASE(rtd);
+ return;
+ }
+ *exception = NULL;
+ for (sal_Int32 i = 0; i < count; ++i) {
+ if (cppArgs[i] != NULL) {
+ if (parameters[i].bOut) {
+ if (parameters[i].bIn) {
+ uno_destructData(arguments[i], ptds[i], NULL);
+ }
+ uno_copyAndConvertData(
+ arguments[i], cppArgs[i], ptds[i],
+ proxy->getBridge()->getCpp2Uno());
+ }
+ uno_destructData(
+ cppArgs[i], ptds[i],
+ reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release));
+ TYPELIB_DANGER_RELEASE(ptds[i]);
+ }
+ }
+ if (directRet) {
+ switch (rtd->eTypeClass) {
+ case typelib_TypeClass_FLOAT:
+ fp_storef0(reinterpret_cast< float * >(returnValue));
+ break;
+ case typelib_TypeClass_DOUBLE:
+ fp_stored0(reinterpret_cast< double * >(returnValue));
+ break;
+ case typelib_TypeClass_STRUCT:
+ storeFpRegsToStruct(rtd, stack);
+ // fall through
+ case typelib_TypeClass_ANY:
+ std::memcpy(returnValue, stack, rtd->nSize);
+ break;
+ default:
+ OSL_ASSERT(rtd->nSize <= 8);
+ std::memcpy(
+ returnValue,
+ reinterpret_cast< char * >(stack) + (8 - rtd->nSize),
+ rtd->nSize);
+ break;
+ }
+ } else if (retconv) {
+ uno_copyAndConvertData(
+ returnValue, ret, rtd, proxy->getBridge()->getCpp2Uno());
+ uno_destructData(
+ ret, rtd,
+ reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release));
+ }
+ TYPELIB_DANGER_RELEASE(rtd);
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, typelib_TypeDescription const * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException)
+{
+ bridges::cpp_uno::shared::UnoInterfaceProxy * proxy =
+ static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+ switch (pMemberDescr->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ VtableSlot slot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+ if (pReturn != NULL) {
+ // Getter:
+ call(
+ proxy, slot,
+ (reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)->pAttributeTypeRef),
+ 0, NULL, pReturn, pArgs, ppException);
+ } else {
+ // Setter:
+ typelib_MethodParameter param = {
+ NULL,
+ (reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)->pAttributeTypeRef),
+ true, false };
+ typelib_TypeDescriptionReference * rtd = NULL;
+ typelib_typedescriptionreference_new(
+ &rtd, typelib_TypeClass_VOID,
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("void")).pData);
+ slot.index += 1;
+ call(proxy, slot, rtd, 1, &param, pReturn, pArgs, ppException);
+ typelib_typedescriptionreference_release(rtd);
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ VtableSlot slot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (slot.index) {
+ case 1:
+ pUnoI->acquire(pUnoI);
+ *ppException = NULL;
+ break;
+ case 2:
+ pUnoI->release(pUnoI);
+ *ppException = NULL;
+ break;
+ case 0:
+ {
+ typelib_TypeDescription * td = NULL;
+ TYPELIB_DANGER_GET(
+ &td,
+ reinterpret_cast< css::uno::Type * >(
+ pArgs[0])->getTypeLibType());
+ if (td != NULL) {
+ uno_Interface * ifc = NULL;
+ proxy->pBridge->getUnoEnv()->getRegisteredInterface(
+ proxy->pBridge->getUnoEnv(),
+ reinterpret_cast< void ** >(&ifc),
+ proxy->oid.pData,
+ (reinterpret_cast<
+ typelib_InterfaceTypeDescription * >(td)));
+ if (ifc != NULL) {
+ uno_any_construct(
+ reinterpret_cast< uno_Any * >(pReturn),
+ &ifc, td, NULL);
+ ifc->release(ifc);
+ TYPELIB_DANGER_RELEASE(td);
+ *ppException = NULL;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(td);
+ }
+ } // fall through
+ default:
+ call(
+ proxy, slot,
+ (reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)->pReturnTypeRef),
+ (reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)->nParams),
+ (reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)->pParams),
+ pReturn, pArgs, ppException);
+ }
+ break;
+ }
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/vtableslotcall.hxx b/bridges/source/cpp_uno/cc5_solaris_sparc64/vtableslotcall.hxx
new file mode 100644
index 000000000000..c63f674c1549
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/vtableslotcall.hxx
@@ -0,0 +1,38 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_VTABLESLOTCALL_HXX
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_CC5_SOLARIS_SPARC64_VTABLESLOTCALL_HXX
+
+#include "sal/config.h"
+
+extern "C" void vtableSlotCall();
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/cc5_solaris_sparc64/vtableslotcall.s b/bridges/source/cpp_uno/cc5_solaris_sparc64/vtableslotcall.s
new file mode 100644
index 000000000000..01a22da74fff
--- /dev/null
+++ b/bridges/source/cpp_uno/cc5_solaris_sparc64/vtableslotcall.s
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+.global vtableCall
+
+.global vtableSlotCall
+.align 8
+vtableSlotCall:
+ ! save %sp, -176, %sp already done in code snippet
+ stx %i0, [%fp + 2047 + 128]
+ stx %i1, [%fp + 2047 + 136]
+ stx %i2, [%fp + 2047 + 144]
+ stx %i3, [%fp + 2047 + 152]
+ stx %i4, [%fp + 2047 + 160]
+ stx %i5, [%fp + 2047 + 168]
+ ! %o0: functionIndex, stored by code snippet
+ ! %o1: vtableOffset, stored by code snippet
+ call vtableCall
+ add %fp, 2047 + 128, %o2
+ ldx [%fp + 2047 + 128], %i0
+ ldx [%fp + 2047 + 136], %i1
+ ldx [%fp + 2047 + 144], %i2
+ ldx [%fp + 2047 + 152], %i3
+ ret
+ restore
+.size vtableSlotCall, . - vtableSlotCall
+.type vtableSlotCall, #function
diff --git a/bridges/source/cpp_uno/gcc3_aix_powerpc/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_aix_powerpc/cpp2uno.cxx
new file mode 100644
index 000000000000..e77c7329d0fc
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_aix_powerpc/cpp2uno.cxx
@@ -0,0 +1,663 @@
+/* -*- 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 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: cpp2uno.cxx,v $
+ * $Revision: 1.11 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "share.hxx"
+
+#include <string.h>
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** gpreg, double * fpreg, void ** ovrflw,
+ sal_uInt64 * pRegisterReturn /* space for register return */ )
+{
+ // gpreg: [ret *], this, [gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [remainder of params]
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ sal_Int32 ng = 0;
+ sal_Int32 nf = 0;
+
+ ovrflw -= ppc::MAX_GPR_REGS;
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *gpreg;
+ ++gpreg;
+ ++ng;
+ ++ovrflw;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? __builtin_alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ ++gpreg;
+ ++ng;
+ ++ovrflw;
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)__builtin_alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ // value
+ {
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ if (ng < ppc::MAX_GPR_REGS)
+ {
+ *ovrflw = *gpreg++;
+ ++ng;
+ }
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-1));
+ ++ovrflw;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (ng < ppc::MAX_GPR_REGS)
+ {
+ *ovrflw = *gpreg++;
+ ++ng;
+ }
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-2));
+ ++ovrflw;
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ for (int i = 0; i < 2; ++i)
+ {
+ if (ng < ppc::MAX_GPR_REGS)
+ {
+ *ovrflw = *gpreg++;
+ ++ng;
+ }
+ ++ovrflw;
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (nf < ppc::MAX_SSE_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg;
+ ++fpreg;
+ ++nf;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ }
+ if (ng < ppc::MAX_GPR_REGS)
+ {
+ ng+=2;
+ gpreg+=2;
+ }
+ ovrflw+=2;
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (nf < ppc::MAX_SSE_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg;
+ ++fpreg;
+ ++nf;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ }
+ if (ng < ppc::MAX_GPR_REGS)
+ {
+ ++gpreg;
+ ++ng;
+ }
+ ++ovrflw;
+ break;
+ default:
+ if (ng < ppc::MAX_GPR_REGS)
+ {
+ *ovrflw = *gpreg++;
+ ++ng;
+ }
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ ++ovrflw;
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ void *pCppStack; //temporary stack pointer
+
+ if (ng < ppc::MAX_GPR_REGS)
+ {
+ *ovrflw = *gpreg++;
+ ++ng;
+ }
+ pCppArgs[nPos] = pCppStack = *ovrflw++;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = __builtin_alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = __builtin_alloca( pParamTypeDescr->nSize ),
+ pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException(
+ &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
+ void ** gpreg, double * fpreg, void ** ovrflw,
+ sal_uInt64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (in space allocated for all params properly aligned)]
+
+ void * pThis;
+ if( nFunctionIndex & 0x8000 )
+ {
+ nFunctionIndex &= 0x7fff;
+ pThis = gpreg[1];
+ }
+ else
+ {
+ pThis = gpreg[0];
+ }
+
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pThis );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static sal_uInt64 cpp_vtable_call(sal_Int32 r3, sal_Int32 r4, sal_Int32 r5,
+ sal_Int32 r6, sal_Int32 r7, sal_Int32 r8, sal_Int32 r9,
+ sal_Int32 r10, sal_Int32 firstonstack)
+{
+ volatile unsigned long nOffsetAndIndex;
+
+ __asm__ __volatile__(
+ "mr %0, 11\n\t"
+ : "=r" (nOffsetAndIndex) : );
+
+ sal_Int32 nVtableOffset = (nOffsetAndIndex >> 16);
+ sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFF);
+
+ void ** ovrflw = (void**)&firstonstack;
+
+ sal_Int32 gpreg[ppc::MAX_GPR_REGS];
+ gpreg[0] = r3;
+ gpreg[1] = r4;
+ gpreg[2] = r5;
+ gpreg[3] = r6;
+ gpreg[4] = r7;
+ gpreg[5] = r8;
+ gpreg[6] = r9;
+ gpreg[7] = r10;
+
+ double fpreg[ppc::MAX_SSE_REGS];
+ register double d0 asm("fr1"); fpreg[0] = d0;
+ register double d1 asm("fr2"); fpreg[1] = d1;
+ register double d2 asm("fr3"); fpreg[2] = d2;
+ register double d3 asm("fr4"); fpreg[3] = d3;
+ register double d4 asm("fr5"); fpreg[4] = d4;
+ register double d5 asm("fr6"); fpreg[5] = d5;
+ register double d6 asm("fr7"); fpreg[6] = d6;
+ register double d7 asm("fr8"); fpreg[7] = d7;
+ register double d8 asm("fr9"); fpreg[8] = d8;
+ register double d9 asm("fr10"); fpreg[9] = d9;
+ register double d10 asm("fr11"); fpreg[10] = d10;
+ register double d11 asm("fr12"); fpreg[11] = d11;
+ register double d12 asm("fr13"); fpreg[12] = d12;
+
+#if CMC_DEBUG
+ for(int i = 0; i < 8; ++i)
+ {
+ fprintf(stderr, "general reg %d is %x\n", i, gpreg[i]);
+ }
+ for(int i = 0; i < 13; ++i)
+ {
+ fprintf(stderr, "sse reg %d is %f\n", i, fpreg[i]);
+ fprintf(stderr, "sse reg %d is %llx\n", i, fpreg[i]);
+ }
+ for(int i = -8; i < 8; ++i)
+ {
+ fprintf(stderr, "overflow arg %d is %x\n", i, ovrflw[i]);
+ }
+#endif
+ sal_uInt64 nRegReturn=0;
+
+ typelib_TypeClass aType =
+ cpp_mediate( nFunctionIndex, nVtableOffset, (void**)gpreg, fpreg, ovrflw, &nRegReturn );
+
+ sal_uInt32 *pRegReturn = (sal_uInt32*)&nRegReturn;
+ switch( aType )
+ {
+ case typelib_TypeClass_BOOLEAN:
+ pRegReturn[0] = (sal_uInt32)(*(char *)pRegReturn);
+ break;
+ case typelib_TypeClass_BYTE:
+ pRegReturn[0] = (sal_Int32)(*(unsigned char *)pRegReturn);
+ break;
+ case typelib_TypeClass_SHORT:
+ pRegReturn[0] = (sal_Int32)(*(short *)pRegReturn);
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ pRegReturn[0] = (sal_uInt32)(*(unsigned short *)pRegReturn);
+ break;
+ case typelib_TypeClass_FLOAT:
+ __asm__("lfs 1,%0\n\t" : : "m"(*((float*)&nRegReturn)));
+ break;
+ case typelib_TypeClass_DOUBLE:
+ __asm__("lfd 1,%0\n\t" : : "m"(*((double*)&nRegReturn)));
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ break;
+ default:
+ pRegReturn[0] = (sal_uInt32)(*(unsigned int*)pRegReturn);
+ break;
+ }
+ return nRegReturn;
+}
+
+
+int const codeSnippetSize = 3 * sizeof(void*);
+
+unsigned char * codeSnippet( unsigned char * code, sal_Int16 functionIndex,
+ sal_Int16 vtableOffset, bool simpleRetType )
+{
+ sal_uInt32 nOffsetAndIndex = ( ( vtableOffset ) << 16 ) | (functionIndex );
+ if (! simpleRetType )
+ nOffsetAndIndex |= 0x8000;
+
+ void **raw = (void**)&code[0];
+ memcpy(raw, (char*)cpp_vtable_call, 2 * sizeof(void*));
+ raw[2] = (void*)nOffsetAndIndex;
+
+ return (code + codeSnippetSize);
+}
+
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * bptr, unsigned char const * eptr)
+{
+ int const lineSize = 32;
+ for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
+ __asm__ volatile ("dcbst 0, %0" : : "r"(p) : "memory");
+ }
+ __asm__ volatile ("sync" : : : "memory");
+ for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
+ __asm__ volatile ("icbi 0, %0" : : "r"(p) : "memory");
+ }
+ __asm__ volatile ("isync" : : : "memory");
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0;
+ slots[-1].fn = 0;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_aix_powerpc/except.cxx b/bridges/source/cpp_uno/gcc3_aix_powerpc/except.cxx
new file mode 100644
index 000000000000..b40bfde14391
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_aix_powerpc/except.cxx
@@ -0,0 +1,291 @@
+/* -*- 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 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: except.cxx,v $
+ * $Revision: 1.7 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+#include <string.h>
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * )
+{
+}
+
+//==================================================================================================
+static OUString toUNOname( char const * p ) SAL_THROW( () )
+{
+#ifdef DEBUG
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#ifdef DEBUG
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+}
+
+//==================================================================================================
+class RTTI
+{
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+{
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iiFind( m_generatedRttis.find( unoName ) );
+ if (iiFind == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with _ZTI
+ char const * rttiName = symName.getStr() +4;
+#ifdef DEBUG
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iiFind->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iFind->second;
+ }
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void deleteException( void * pExc )
+{
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ terminate();
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ terminate();
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno )
+{
+ OSL_ENSURE( header, "### no exception header!!!" );
+ if (! header)
+ terminate();
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" );
+ if (! pExcTypeDescr)
+ terminate();
+
+ // construct uno exception any
+ ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ ::typelib_typedescription_release( pExcTypeDescr );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_aix_powerpc/makefile.mk b/bridges/source/cpp_uno/gcc3_aix_powerpc/makefile.mk
new file mode 100644
index 000000000000..a543640e0882
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_aix_powerpc/makefile.mk
@@ -0,0 +1,81 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.8 $
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCAIXPgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+NOOPTFILES= \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/cpp2uno.obj
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS= $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB) \
+ -ldl
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/bridges/source/cpp_uno/gcc3_aix_powerpc/share.hxx b/bridges/source/cpp_uno/gcc3_aix_powerpc/share.hxx
new file mode 100644
index 000000000000..0d7e62714f30
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_aix_powerpc/share.hxx
@@ -0,0 +1,102 @@
+/* -*- 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 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: share.hxx,v $
+ * $Revision: 1.5 $
+ *
+ * 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 "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+ void dummy_can_throw_anything( char const * );
+
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+namespace ppc
+{
+ enum ppclimits { MAX_GPR_REGS = 8, MAX_SSE_REGS = 13 };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_aix_powerpc/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_aix_powerpc/uno2cpp.cxx
new file mode 100644
index 000000000000..69372893fdf3
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_aix_powerpc/uno2cpp.cxx
@@ -0,0 +1,502 @@
+/* -*- 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 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ * $Revision: 1.9 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sys/types.h>
+#include <sys/malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "share.hxx"
+#include <stdio.h>
+#include <string.h>
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+void MapReturn(sal_uInt32 r3, sal_uInt32 r4, double dret, typelib_TypeClass eReturnType, void *pRegisterReturn)
+{
+ switch( eReturnType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ ((long*)pRegisterReturn)[1] = r4;
+ // fall through on purpose
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ ((long*)pRegisterReturn)[0] = r3;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = (unsigned short)r3;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = (unsigned char)r3;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float*)pRegisterReturn = (float)dret;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double*)pRegisterReturn = dret;
+ break;
+ default:
+ break;
+ }
+}
+
+#define DISPLACEMENT -2
+
+static void callVirtualMethod(
+ void * pThis,
+ sal_uInt32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_uInt32 * pStack,
+ sal_uInt32 nStack,
+ double *pFPR,
+ sal_uInt32 nFPR)
+{
+ sal_uInt32 nStackWords = nStack;
+ if (nStackWords < ppc::MAX_GPR_REGS)
+ nStackWords = 0;
+ else
+ nStackWords-=ppc::MAX_GPR_REGS;
+ if (nStackWords)
+ nStackWords = ( nStackWords + 1) & ~1;
+ sal_uInt32 *stack = (sal_uInt32*)__builtin_alloca( nStackWords * sizeof(sal_uInt32) );
+ memcpy(stack+DISPLACEMENT, pStack+ppc::MAX_GPR_REGS, nStack * sizeof(sal_uInt32));
+
+ // Get pointer to method
+ sal_uInt32 pMethod = *((sal_uInt32 *)pThis);
+ pMethod += 4 * nVtableIndex;
+ pMethod = *((sal_uInt32 *)pMethod);
+
+ typedef void (* FunctionCall )( sal_uInt32, sal_uInt32, sal_uInt32, sal_uInt32, sal_uInt32, sal_uInt32, sal_uInt32, sal_uInt32 );
+ FunctionCall pFunc = (FunctionCall)pMethod;
+
+ register double d0 asm("fr1"); d0 = pFPR[0];
+ register double d1 asm("fr2"); d1 = pFPR[1];
+ register double d2 asm("fr3"); d2 = pFPR[2];
+ register double d3 asm("fr4"); d3 = pFPR[3];
+ register double d4 asm("fr5"); d4 = pFPR[4];
+ register double d5 asm("fr6"); d5 = pFPR[5];
+ register double d6 asm("fr7"); d6 = pFPR[6];
+ register double d7 asm("fr8"); d7 = pFPR[7];
+ register double d8 asm("fr9"); d8 = pFPR[8];
+ register double d9 asm("fr10"); d9 = pFPR[9];
+ register double d10 asm("fr11"); d10 = pFPR[10];
+ register double d11 asm("fr12"); d11 = pFPR[11];
+ register double d12 asm("fr13"); d12 = pFPR[12];
+
+ (*pFunc)(pStack[0], pStack[1], pStack[2], pStack[3], pStack[4], pStack[5], pStack[6], pStack[7]);
+
+ register sal_uInt32 r3 asm("r3");
+ register sal_uInt32 r4 asm("r4");
+ MapReturn(r3, r4, d0, eReturnType, pRegisterReturn);
+}
+
+#define INSERT_INT32(pSV, pDS) \
+{ \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>(pSV); \
+}
+
+#define INSERT_INT16(pSV, pDS) \
+{ \
+ *pDS++ = *reinterpret_cast<sal_uInt16 *>(pSV); \
+}
+
+#define INSERT_INT8(pSV, pDS) \
+{ \
+ *pDS++ = *reinterpret_cast<sal_uInt8 *>(pSV); \
+}
+
+#define INSERT_FLOAT(pSV, nr, pFPR, pDS) \
+{ \
+ if (nr < ppc::MAX_SSE_REGS) \
+ { \
+ sal_uInt32 *pDouble = (sal_uInt32 *)&(pFPR[nr++]); \
+ pDouble[0] = *reinterpret_cast<sal_uInt32 *>(pSV); \
+ } \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>(pSV); \
+}
+
+#define INSERT_DOUBLE(pSV, nr, pFPR, pDS) \
+{ \
+ if (nr < ppc::MAX_SSE_REGS) \
+ { \
+ pFPR[nr++] = *reinterpret_cast<double *>(pSV); \
+ } \
+ *pDS++ = reinterpret_cast<sal_uInt32 *>(pSV)[1]; \
+ *pDS++ = reinterpret_cast<sal_uInt32 *>(pSV)[0]; \
+}
+
+#define INSERT_INT64(pSV, pDS) \
+{ \
+ INSERT_INT32(pSV, pDS) \
+ INSERT_INT32(((sal_uInt32*)pSV)+1, pDS) \
+}
+//==================================================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ sal_uInt32 * pStack = (sal_uInt32*)__builtin_alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ sal_uInt32 * pStackStart = pStack;
+
+ double pFPR[ppc::MAX_SSE_REGS];
+ sal_uInt32 nFPR = 0;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? __builtin_alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ INSERT_INT32(&pCppReturn, pStack);
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI()) + aVtableSlot.offset;
+ INSERT_INT32(&pAdjustedThisPtr, pStack);
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)__builtin_alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = pStack, pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ INSERT_INT32(pCppArgs[nPos], pStack);
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ INSERT_INT16(pCppArgs[nPos], pStack);
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ INSERT_INT8(pCppArgs[nPos], pStack);
+ break;
+ case typelib_TypeClass_FLOAT:
+ INSERT_FLOAT(pCppArgs[nPos], nFPR, pFPR, pStack);
+ break;
+ case typelib_TypeClass_DOUBLE:
+ INSERT_DOUBLE(pCppArgs[nPos], nFPR, pFPR, pStack);
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ INSERT_INT64(pCppArgs[nPos], pStack);
+ break;
+ default:
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ pCppArgs[nPos] = __builtin_alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ pCppArgs[nPos] = __builtin_alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ INSERT_INT32(&(pCppArgs[nPos]), pStack);
+ }
+ }
+
+ try
+ {
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass,
+ pStackStart, (pStack - pStackStart), pFPR, nFPR );
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * > (pUnoI);
+ // typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; //get then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_alpha/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_alpha/cpp2uno.cxx
new file mode 100644
index 000000000000..3ee825511d66
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_alpha/cpp2uno.cxx
@@ -0,0 +1,677 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "share.hxx"
+#include <stdio.h>
+
+//Calling Standards:
+// "Calling Standard for Alpha Systems"
+// (Tru64 UNIX Version 5.1 or higher, August 2000)
+//http://www.tru64unix.compaq.com/docs/base_doc/DOCUMENTATION/V51_HTML/ARH9MBTE/TITLE.HTM
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr, "as far as cpp2uno_call\n");
+#endif
+ int nregs = 0; //number of words passed in registers
+
+ // gpreg: [ret *], this, [gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)gpreg;
+ gpreg++;
+ fpreg++;
+ nregs++;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ gpreg++;
+ fpreg++;
+ nregs++;
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int64), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "arg %d of %d\n", nPos, nParams);
+#endif
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "simple type is %d\n", pParamTypeDescr->eTypeClass);
+#endif
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_FLOAT:
+ case typelib_TypeClass_DOUBLE:
+ if (nregs < axp::MAX_WORDS_IN_REGS)
+ {
+ if (pParamTypeDescr->eTypeClass == typelib_TypeClass_FLOAT)
+ {
+ float tmp = (float) (*((double *)fpreg));
+ (*((float *) fpreg)) = tmp;
+ }
+
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg;
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ ovrflw++;
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_BOOLEAN:
+ if (nregs < axp::MAX_WORDS_IN_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg;
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ ovrflw++;
+ }
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (nregs < axp::MAX_WORDS_IN_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg;
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ ovrflw++;
+ }
+ break;
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (nregs < axp::MAX_WORDS_IN_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg;
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ ovrflw++;
+ }
+ break;
+ default:
+ if (nregs < axp::MAX_WORDS_IN_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg;
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ ovrflw++;
+ }
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex, nregs is %d\n", nregs);
+#endif
+
+ void *pCppStack; //temporary stack pointer
+
+ if (nregs < axp::MAX_WORDS_IN_REGS)
+ {
+ pCppArgs[nPos] = pCppStack = *gpreg;
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pCppStack = *ovrflw;
+ ovrflw++;
+ }
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "end of params\n");
+#endif
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//============================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_uInt64 nOffsetAndIndex,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int64)==sizeof(void *), "### unexpected!" );
+
+ sal_Int32 nVtableOffset = (nOffsetAndIndex >> 32);
+ sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFFFFFF);
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "nVTableOffset, nFunctionIndex are %x %x\n", nVtableOffset, nFunctionIndex);
+#endif
+
+#ifdef CMC_DEBUG
+ // Let's figure out what is really going on here
+ {
+ fprintf( stderr, "= cpp_mediate () =\nGPR's (%d): ", 6 );
+ for ( unsigned int i = 0; i < 6; ++i )
+ fprintf( stderr, "0x%lx, ", gpreg[i] );
+ fprintf( stderr, "\n");
+ fprintf( stderr, "\nFPR's (%d): ", 6 );
+ for ( unsigned int i = 0; i < 6; ++i )
+ fprintf( stderr, "0x%lx (%f), ", fpreg[i], fpreg[i] );
+ fprintf( stderr, "\n");
+ }
+#endif
+
+
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ // _this_ ptr is patched cppu_XInterfaceProxy object
+ void * pThis;
+ if( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = gpreg[1];
+ }
+ else
+ {
+ pThis = gpreg[0];
+ }
+
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pCppI );
+ }
+
+ // determine called method
+ OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pCppI );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+long cpp_vtable_call(long r16, long r17, long r18, long r19, long r20, long r21, long firstonstack)
+{
+ register long r1 asm("$1");
+ sal_uInt64 nOffsetAndIndex = r1;
+
+ long sp = (long)&firstonstack;
+
+ sal_uInt64 gpreg[axp::MAX_GPR_REGS];
+ gpreg[0] = r16;
+ gpreg[1] = r17;
+ gpreg[2] = r18;
+ gpreg[3] = r19;
+ gpreg[4] = r20;
+ gpreg[5] = r21;
+
+ double fpreg[axp::MAX_SSE_REGS];
+ register double f16 asm("$f16"); fpreg[0] = f16;
+ register double f17 asm("$f17"); fpreg[1] = f17;
+ register double f18 asm("$f18"); fpreg[2] = f18;
+ register double f19 asm("$f19"); fpreg[3] = f19;
+ register double f20 asm("$f20"); fpreg[4] = f20;
+ register double f21 asm("$f21"); fpreg[5] = f21;
+
+ volatile long nRegReturn[1];
+#ifdef CMC_DEBUG
+ fprintf(stderr, "before mediate with %lx\n",nOffsetAndIndex);
+ fprintf(stderr, "non-doubles are %x %x %x %x %x %x\n", gpreg[0], gpreg[1], gpreg[2], gpreg[3], gpreg[4], gpreg[5]);
+ fprintf(stderr, "doubles are %f %f %f %f %f %f\n", fpreg[0], fpreg[1], fpreg[2], fpreg[3], fpreg[4], fpreg[5]);
+#endif
+ typelib_TypeClass aType =
+ cpp_mediate( nOffsetAndIndex, (void**)gpreg, (void**)fpreg, (void**)sp,
+ (sal_Int64*)nRegReturn );
+#ifdef CMC_DEBUG
+ fprintf(stderr, "after mediate ret is %lx %ld\n", nRegReturn[0], nRegReturn[0]);
+#endif
+
+ switch( aType )
+ {
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ nRegReturn[0] = (unsigned long)(*(unsigned char *)nRegReturn);
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_SHORT:
+ nRegReturn[0] = (unsigned long)(*(unsigned short *)nRegReturn);
+ break;
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_LONG:
+ nRegReturn[0] = (unsigned long)(*(unsigned int *)nRegReturn);
+ break;
+ case typelib_TypeClass_VOID:
+ default:
+ break;
+ case typelib_TypeClass_FLOAT:
+ {
+ double tmp = (double) (*((float *)nRegReturn));
+ (*((double *) nRegReturn)) = tmp;
+ }
+ //deliberate fall through
+ case typelib_TypeClass_DOUBLE:
+ __asm__ ( "ldt $f0,%0\n\t"
+ : : "m" (*((double*)nRegReturn)) : "$f0");
+ break;
+ }
+ return nRegReturn[0];
+}
+
+const int codeSnippetSize = 32;
+
+unsigned char *codeSnippet( unsigned char * code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, bool simple_ret_type )
+{
+ if (! simple_ret_type)
+ nFunctionIndex |= 0x80000000;
+
+ unsigned char * p = code;
+ *(unsigned int*)&p[0] = 0x47fb0401; /* mov $27,$1 */
+ *(unsigned int*)&p[4] = 0xa43b0010; /* ldq $1,16($27) */
+ *(unsigned int*)&p[8] = 0xa77b0018; /* ldq $27,24($27) */
+ *(unsigned int*)&p[12] = 0x6bfb0000; /* jmp $31,($27),0 */
+ *(unsigned int*)&p[16] = nFunctionIndex;
+ *(unsigned int*)&p[20] = nVtableOffset;
+ *(unsigned long*)&p[24] = (unsigned long)cpp_vtable_call;
+ return (code + codeSnippetSize);
+}
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *, unsigned char const *)
+{
+ //http://www.gnu.org/software/lightning/manual/html_node/Standard-functions.html
+ __asm__ __volatile__("call_pal 0x86");
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0;
+ slots[-1].fn = 0;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+#ifdef CMC_DEBUG
+ fprintf(stderr, "in addLocalFunctions functionOffset is %x\n",functionOffset);
+ fprintf(stderr, "in addLocalFunctions vtableOffset is %x\n",vtableOffset);
+#endif
+
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_alpha/except.cxx b/bridges/source/cpp_uno/gcc3_linux_alpha/except.cxx
new file mode 100644
index 000000000000..c0de95532515
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_alpha/except.cxx
@@ -0,0 +1,289 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * )
+{
+}
+
+//==================================================================================================
+static OUString toUNOname( char const * p ) SAL_THROW( () )
+{
+#if OSL_DEBUG_LEVEL > 1
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+}
+
+//==================================================================================================
+class RTTI
+{
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+{
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iRttiFind( m_rttis.find( unoName ) );
+ if (iRttiFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
+ if (iFind == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with _ZTI
+ char const * rttiName = symName.getStr() +4;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iFind->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iRttiFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void deleteException( void * pExc )
+{
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ terminate();
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ terminate();
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno )
+{
+ OSL_ENSURE( header, "### no exception header!!!" );
+ if (! header)
+ terminate();
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" );
+ if (! pExcTypeDescr)
+ terminate();
+
+ // construct uno exception any
+ ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ ::typelib_typedescription_release( pExcTypeDescr );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_alpha/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_alpha/makefile.mk
new file mode 100644
index 000000000000..5376b395e35f
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_alpha/makefile.mk
@@ -0,0 +1,77 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)" == "GCCLINUXL"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer -fno-strict-aliasing
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/gcc3_linux_alpha/share.hxx b/bridges/source/cpp_uno/gcc3_linux_alpha/share.hxx
new file mode 100644
index 000000000000..d76cbf748db3
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_alpha/share.hxx
@@ -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.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+ void dummy_can_throw_anything( char const * );
+
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+namespace axp
+{
+ enum axplimits { MAX_WORDS_IN_REGS = 6, MAX_GPR_REGS = 6, MAX_SSE_REGS = 6 };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_alpha/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_alpha/uno2cpp.cxx
new file mode 100644
index 000000000000..dddda8ab8207
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_alpha/uno2cpp.cxx
@@ -0,0 +1,534 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+void MapReturn(long r0, typelib_TypeClass eTypeClass, sal_uInt64* pRegisterReturn)
+{
+ register float fret asm("$f0");
+ register double dret asm("$f0");
+
+#ifdef CMC_DEBUG
+ fprintf(stderr,"Mapping Return with %lx %ld %f\n", r0, r0, dret);
+#endif
+ switch (eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *pRegisterReturn = r0;
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ *(unsigned int*)pRegisterReturn = (unsigned int)r0;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = (unsigned short)r0;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = (unsigned char)r0;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *reinterpret_cast<float *>( pRegisterReturn ) = fret;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *reinterpret_cast<double *>( pRegisterReturn ) = dret;
+ break;
+ default:
+ break;
+ }
+#ifdef CMC_DEBUG
+ fprintf(stderr, "end of MapReturn with %x\n", pRegisterReturn ? *pRegisterReturn : 0);
+#endif
+}
+
+#define INSERT_FLOAT( pSV, nr, pFPR, pDS ) \
+ { \
+ if ( nr < axp::MAX_WORDS_IN_REGS ) \
+ { \
+ pFPR[nr++] = *reinterpret_cast<float *>( pSV ); \
+ } \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+ }
+
+#define INSERT_DOUBLE( pSV, nr, pFPR, pDS ) \
+ if ( nr < axp::MAX_WORDS_IN_REGS ) \
+ pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
+
+#define INSERT_INT64( pSV, nr, pGPR, pDS ) \
+ if ( nr < axp::MAX_WORDS_IN_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
+
+#define INSERT_INT32( pSV, nr, pGPR, pDS ) \
+ if ( nr < axp::MAX_WORDS_IN_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#define INSERT_INT16( pSV, nr, pGPR, pDS ) \
+ if ( nr < axp::MAX_WORDS_IN_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, nr, pGPR, pDS ) \
+ if ( nr < axp::MAX_WORDS_IN_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+
+namespace
+{
+//==================================================================================================
+void callVirtualMethod(
+ void * pThis, sal_Int32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescription * pReturnTypeDescr,
+ sal_uInt64 *pStack, sal_uInt32 nStack,
+ sal_uInt64 *pGPR, sal_uInt32 nGPR,
+ double *pFPR, sal_uInt32 nFPR)
+{
+ // Should not happen, but...
+ if ( nFPR > axp::MAX_SSE_REGS )
+ nFPR = axp::MAX_SSE_REGS;
+ if ( nGPR > axp::MAX_GPR_REGS )
+ nGPR = axp::MAX_GPR_REGS;
+
+#ifdef CMC_DEBUG
+ // Let's figure out what is really going on here
+ {
+ fprintf( stderr, "= nStack is %d\n", nStack );
+ fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
+ for ( unsigned int i = 0; i < nGPR; ++i )
+ fprintf( stderr, "0x%lx, ", pGPR[i] );
+ fprintf( stderr, "\nFPR's (%d): ", nFPR );
+ for ( unsigned int i = 0; i < nFPR; ++i )
+ fprintf( stderr, "0x%lx (%f), ", pFPR[i], pFPR[i] );
+ fprintf( stderr, "\nStack (%d): ", nStack );
+ for ( unsigned int i = 0; i < nStack; ++i )
+ fprintf( stderr, "0x%lx, ", pStack[i] );
+ fprintf( stderr, "\n" );
+ fprintf( stderr, "pRegisterReturn is %p\n", pRegisterReturn);
+ }
+#endif
+
+ // Load parameters to stack, if necessary
+ // Stack, if used, must be 8-bytes aligned
+ sal_uInt64 *stack = (sal_uInt64 *) __builtin_alloca( nStack * 8 );
+ memcpy( stack, pStack, nStack * 8 );
+
+ // To get pointer to method
+ // a) get the address of the vtable
+ sal_uInt64 pMethod = *((sal_uInt64 *)pThis);
+ // b) get the address from the vtable entry at offset
+ pMethod += 8 * nVtableIndex;
+ pMethod = *((sal_uInt64 *)pMethod);
+
+ typedef void (* FunctionCall )( sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64 );
+ FunctionCall pFunc = (FunctionCall)pMethod;
+
+ switch (nFPR) //deliberate fall through
+ {
+ case 6:
+ asm volatile("ldt $f16,%0" :: "m"(pFPR[5]) : "$f16");
+ case 5:
+ asm volatile("ldt $f17,%0" :: "m"(pFPR[4]) : "$f17");
+ case 4:
+ asm volatile("ldt $f18,%0" :: "m"(pFPR[3]) : "$f18");
+ case 3:
+ asm volatile("ldt $f19,%0" :: "m"(pFPR[2]) : "$f19");
+ case 2:
+ asm volatile("ldt $f20,%0" :: "m"(pFPR[1]) : "$f20");
+ case 1:
+ asm volatile("ldt $f21,%0" :: "m"(pFPR[0]) : "$f21");
+ default:
+ break;
+ }
+
+ (*pFunc)(pGPR[0], pGPR[1], pGPR[2], pGPR[3], pGPR[4], pGPR[5]);
+ register sal_uInt64 r0 __asm__("$0");
+ MapReturn(r0, pReturnTypeDescr->eTypeClass, (sal_uInt64*)pRegisterReturn);
+}
+
+
+//============================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ sal_uInt64 * pStack = (sal_uInt64 *)alloca( (nParams+3) * sizeof(sal_Int64) );
+ sal_uInt64 * pStackStart = pStack;
+
+ sal_uInt64 pGPR[axp::MAX_GPR_REGS];
+ double pFPR[axp::MAX_SSE_REGS];
+ sal_uInt32 nRegs = 0;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ INSERT_INT64( &pCppReturn, nRegs, pGPR, pStack );
+ }
+ }
+ // push "this" pointer
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
+
+ INSERT_INT64( &pAdjustedThisPtr, nRegs, pGPR, pStack );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int64), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ INSERT_INT64( pCppArgs[nPos], nRegs, pGPR, pStack );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ INSERT_INT32( pCppArgs[nPos], nRegs, pGPR, pStack );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ INSERT_INT16( pCppArgs[nPos], nRegs, pGPR, pStack );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ INSERT_INT8( pCppArgs[nPos], nRegs, pGPR, pStack );
+ break;
+ case typelib_TypeClass_FLOAT:
+ INSERT_FLOAT( pCppArgs[nPos], nRegs, pFPR, pStack );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ INSERT_DOUBLE( pCppArgs[nPos], nRegs, pFPR, pStack );
+ break;
+ default:
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ INSERT_INT64( &(pCppArgs[nPos]), nRegs, pGPR, pStack );
+ }
+ }
+
+ try
+ {
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr,
+ pStackStart, (pStack - pStackStart),
+ pGPR, nRegs,
+ pFPR, nRegs );
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions,
+ *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr, "unoInterfaceProxyDispatch\n");
+#endif
+
+
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy *> (pUnoI);
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; //get then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_arm/armhelper.S b/bridges/source/cpp_uno/gcc3_linux_arm/armhelper.S
new file mode 100644
index 000000000000..d5faf15eed6f
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_arm/armhelper.S
@@ -0,0 +1,38 @@
+@ ARM support code for OpenOffice C++/UNO bridging
+@
+@ Written by Peter Naulls <peter@chocky.org>
+@ Modified by Caolan McNamara <caolanm@redhat.com>
+@ Fixed by Michael Casadevall <mcasadevall@kubuntu.org>
+
+#ifdef __ARM_EABI__
+# define UNWIND
+#else
+# define UNWIND @
+#endif
+
+ .file "armhelper.s"
+ .text
+ .align 4
+ .global privateSnippetExecutor
+ .type privateSnippetExecutor, %function
+privateSnippetExecutor:
+ UNWIND .fnstart @ start of unwinder entry
+
+ stmfd sp!, {r0-r3} @ follow other parameters on stack
+ UNWIND .pad #16 @ throw this data away on exception
+ mov r0, ip @ r0 points to functionoffset/vtable
+ mov r1, sp @ r1 points to this and params
+ @ (see cppuno.cxx:codeSnippet())
+ stmfd sp!, {r4,lr} @ save return address
+ @ (r4 pushed to preserve stack alignment)
+ UNWIND .save {r4,lr} @ restore these regs on exception
+
+ bl cpp_vtable_call(PLT)
+
+ add sp, sp, #4 @ no need to restore r4 (we didn't touch it)
+ ldr pc, [sp], #20 @ return, discarding function arguments
+
+ UNWIND .fnend @ end of unwinder entry
+
+ .size privateSnippetExecutor, . - privateSnippetExecutor
+ .section .note.GNU-stack,"",%progbits
diff --git a/bridges/source/cpp_uno/gcc3_linux_arm/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_arm/cpp2uno.cxx
new file mode 100644
index 000000000000..da4f0e34ce3c
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_arm/cpp2uno.cxx
@@ -0,0 +1,551 @@
+/* -*- 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 <malloc.h>
+#include <hash_map>
+
+#include <rtl/alloc.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "share.hxx"
+
+#include <dlfcn.h>
+
+
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+ static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+ {
+ // pCallStack: ret, [return ptr], this, params
+ char * pTopStack = (char *)(pCallStack + 0);
+ char * pCppStack = pTopStack;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+ void * pCppReturn = 0;
+
+ if (pReturnTypeDescr)
+ {
+ if (!arm::return_in_hidden_param(pReturnTypeRef))
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)pCppStack;
+ pCppStack += sizeof(void *);
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32),
+ "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion
+ // cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr =
+ (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut &&
+ bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+#ifdef __ARM_EABI__
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ if ((pCppStack - pTopStack) % 8) pCppStack+=sizeof(sal_Int32); //align to 8
+ break;
+ default:
+ break;
+ }
+#endif
+
+ pCppArgs[nPos] = pCppStack;
+ pUnoArgs[nPos] = pCppStack;
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ break;
+ default:
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ pCppArgs[nPos] = *(void **)pCppStack;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] =
+ alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex],
+ ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc,
+ pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr =
+ ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr,
+ cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex],
+ pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn,
+ pReturnTypeDescr, pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet =
+ (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+ }
+
+
+ //=====================================================================
+ static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+ {
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: [ret *], this, params
+ // _this_ ptr is patched cppu_XInterfaceProxy object
+ void *pThis;
+ if( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = pCallStack[1];
+ }
+ else
+ {
+ pThis = pCallStack[0];
+ }
+
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
+ bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex,
+ "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pCppI );
+ }
+
+ // determine called method
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex,
+ "### illegal vtable index!" );
+ sal_Int32 nMemberPos =
+ pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers,
+ "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] ==
+ nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET(&pTD,
+ reinterpret_cast<Type *>(pCallStack[2])->getTypeLibType());
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pCallStack[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = pCallStack[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ OUString::createFromAscii("no member description found!"),
+ (XInterface *)pCppI );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+ }
+}
+
+//=======================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+
+extern "C" sal_Int64 cpp_vtable_call( long *pFunctionAndOffset,
+ void **pCallStack )
+{
+ sal_Int64 nRegReturn;
+ typelib_TypeClass aType = cpp_mediate( pFunctionAndOffset[0], pFunctionAndOffset[1], pCallStack,
+ &nRegReturn );
+
+ switch( aType )
+ {
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ nRegReturn = (unsigned long)(*(unsigned char *)&nRegReturn);
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_SHORT:
+ nRegReturn = (unsigned long)(*(unsigned short *)&nRegReturn);
+ break;
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_LONG:
+ nRegReturn = (unsigned long)(*(unsigned int *)&nRegReturn);
+ break;
+ case typelib_TypeClass_VOID:
+ default:
+ break;
+ }
+
+ return nRegReturn;
+}
+
+extern "C" void privateSnippetExecutor(void);
+
+namespace
+{
+ const int codeSnippetSize = 20;
+
+ unsigned char *codeSnippet(unsigned char* code, sal_Int32 functionIndex,
+ sal_Int32 vtableOffset, bool bHasHiddenParam)
+ {
+ if (bHasHiddenParam)
+ functionIndex |= 0x80000000;
+
+ unsigned long * p = (unsigned long *)code;
+
+ *p++ = 0xE1A0C00F;
+ *p++ = 0xE59FF004;
+ *p++ = (unsigned long)functionIndex;
+ *p++ = (unsigned long)vtableOffset;
+ *p++ = (unsigned long)privateSnippetExecutor;
+
+ return code + codeSnippetSize;
+ }
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0;
+ slots[-1].fn = 0;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for (sal_Int32 i = 0; i < type->nMembers; ++i)
+ {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ typelib_InterfaceAttributeTypeDescription *pAttrTD =
+ reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( member );
+
+ // Getter:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ arm::return_in_hidden_param( pAttrTD->pAttributeTypeRef ));
+
+ // Setter:
+ if (!pAttrTD->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset, false);
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ (s++)->fn = code + writetoexecdiff;
+
+ typelib_InterfaceMethodTypeDescription *pMethodTD =
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(member);
+
+ code = codeSnippet(code, functionOffset++, vtableOffset,
+ arm::return_in_hidden_param(pMethodTD->pReturnTypeRef));
+ break;
+ }
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const *beg, unsigned char const *end)
+{
+ static void (*clear_cache)(unsigned char const*, unsigned char const*)
+ = (void (*)(unsigned char const*, unsigned char const*))
+ dlsym(RTLD_DEFAULT, "__clear_cache");
+ (*clear_cache)(beg, end);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_arm/except.cxx b/bridges/source/cpp_uno/gcc3_linux_arm/except.cxx
new file mode 100644
index 000000000000..1fc67a2098d6
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_arm/except.cxx
@@ -0,0 +1,342 @@
+/* -*- 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 <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+extern sal_Int32 * pHack;
+extern sal_Int32 nHack;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+ void dummy_can_throw_anything( char const * )
+ {
+ }
+
+ //===================================================================
+ static OUString toUNOname( char const * p ) SAL_THROW( () )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+ }
+
+ //=====================================================================
+ class RTTI
+ {
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+ public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI(typelib_CompoundTypeDescription *) SAL_THROW( () );
+ };
+ //____________________________________________________________________
+ RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+ {
+ }
+ //____________________________________________________________________
+ RTTI::~RTTI() SAL_THROW( () )
+ {
+ dlclose( m_hApp );
+ }
+
+ //____________________________________________________________________
+ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+ {
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind2( m_generatedRttis.find( unoName ) );
+ if (iFind2 == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with _ZTI
+ char const * rttiName = symName.getStr() +4;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iFind2->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iFind->second;
+ }
+
+ return rtti;
+ }
+
+ //------------------------------------------------------------------
+ static void deleteException( void * pExc )
+ {
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+ }
+
+ //==================================================================
+ void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() );
+#endif
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get typedescription for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+ }
+
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+ }
+
+#ifdef __ARM_EABI__
+ static void* getAdjustedPtr(__cxa_exception* header)
+ {
+ return (void*)header->unwindHeader.barrier_cache.bitpattern[0];
+ }
+#else
+ static void* getAdjustedPtr(__cxa_exception* header)
+ {
+ return header->adjustedPtr;
+ }
+#endif
+
+ //===================================================================
+ void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+ {
+ if (! header)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, getAdjustedPtr(header), pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_arm/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_arm/makefile.mk
new file mode 100644
index 000000000000..2c42dec5a415
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_arm/makefile.mk
@@ -0,0 +1,84 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+NO_BSYMBOLIC=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCLINUXRgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+CFLAGSCXX += -fno-omit-frame-pointer -fno-strict-aliasing
+
+NOOPTFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/uno2cpp.obj
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/armhelper.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.S
+ $(CXX) -c -o $(SLO)$/$(@:b).o $< -fPIC ; touch $@
diff --git a/bridges/source/cpp_uno/gcc3_linux_arm/share.hxx b/bridges/source/cpp_uno/gcc3_linux_arm/share.hxx
new file mode 100644
index 000000000000..2b00c6c008b4
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_arm/share.hxx
@@ -0,0 +1,102 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+#ifndef _ARM_SHARE_HXX
+#define _ARM_SHARE_HXX
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+#include <unwind.h>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+ void dummy_can_throw_anything( char const * );
+
+ // -- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+ struct __cxa_exception
+ {
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+#ifdef __ARM_EABI__
+ __cxa_exception *nextPropagatingException;
+ int propagationCount;
+#else
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+#endif
+ _Unwind_Exception unwindHeader;
+ };
+
+ extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+ extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo,
+ void (*dest) (void *) ) __attribute__((noreturn));
+
+ struct __cxa_eh_globals
+ {
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+#ifdef __ARM_EABI__
+ __cxa_exception *propagatingExceptions;
+#endif
+ };
+ extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+ // -----
+
+ //====================================================================
+ void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+ //====================================================================
+ void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+namespace arm
+{
+ enum armlimits { MAX_GPR_REGS = 4 };
+ bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_arm/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_arm/uno2cpp.cxx
new file mode 100644
index 000000000000..00a06643fda5
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_arm/uno2cpp.cxx
@@ -0,0 +1,670 @@
+/* -*- 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 <malloc.h>
+#include <rtl/alloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+
+#include <bridges/cpp_uno/shared/bridge.hxx>
+#include <bridges/cpp_uno/shared/types.hxx>
+#include <bridges/cpp_uno/shared/unointerfaceproxy.hxx>
+#include <bridges/cpp_uno/shared/vtables.hxx>
+
+#include "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+/*
+ * Based on http://gcc.gnu.org/PR41443
+ * References to __SOFTFP__ are incorrect for EABI; the __SOFTFP__ code
+ * should be used for *soft-float ABI* whether or not VFP is enabled,
+ * and __SOFTFP__ does specifically mean soft-float not soft-float ABI.
+ *
+ * Changing the conditionals to __SOFTFP__ || __ARM_EABI__ then
+ * -mfloat-abi=softfp should work. -mfloat-abi=hard won't; that would
+ * need both a new macro to identify the hard-VFP ABI.
+ */
+#if !defined(__ARM_EABI__) && !defined(__SOFTFP__)
+#error Not Implemented
+
+/*
+ some possibly handy code to detect that we have VFP registers
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <elf.h>
+
+#define HWCAP_ARM_VFP 64
+
+int hasVFP(void)
+{
+ int fd = open ("/proc/self/auxv", O_RDONLY);
+ if (fd == -1)
+ return -1;
+
+ int ret = -1;
+
+ Elf32_auxv_t buf[128];
+ ssize_t n;
+ while ((ret == -1) && ((n = read(fd, buf, sizeof (buf))) > 0))
+ {
+ for (int i = 0; i < 128; ++i)
+ {
+ if (buf[i].a_type == AT_HWCAP)
+ {
+ ret = (buf[i].a_un.a_val & HWCAP_ARM_VFP) ? true : false;
+ break;
+ }
+ else if (buf[i].a_type == AT_NULL)
+ {
+ ret = -2;
+ break;
+ }
+ }
+ }
+
+ close (fd);
+ return ret;
+}
+
+#endif
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace arm
+{
+ bool is_complex_struct(const typelib_TypeDescription * type)
+ {
+ const typelib_CompoundTypeDescription * p
+ = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
+ for (sal_Int32 i = 0; i < p->nMembers; ++i)
+ {
+ if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
+ p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
+ {
+ typelib_TypeDescription * t = 0;
+ TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
+ bool b = is_complex_struct(t);
+ TYPELIB_DANGER_RELEASE(t);
+ if (b) {
+ return true;
+ }
+ }
+ else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
+ return true;
+ }
+ if (p->pBaseTypeDescription != 0)
+ return is_complex_struct(&p->pBaseTypeDescription->aBase);
+ return false;
+ }
+
+ bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
+ {
+ if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
+ return false;
+ else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
+ {
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+
+ //A Composite Type not larger than 4 bytes is returned in r0
+ bool bRet = pTypeDescr->nSize > 4 || is_complex_struct(pTypeDescr);
+
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ return bRet;
+ }
+ return true;
+ }
+}
+
+void MapReturn(sal_uInt32 r0, sal_uInt32 r1, typelib_TypeDescriptionReference * pReturnType, sal_uInt32* pRegisterReturn)
+{
+#if !defined(__ARM_EABI__) && !defined(__SOFTFP__)
+ register float fret asm("f0");
+ register double dret asm("f0");
+#endif
+
+ switch( pReturnType->eTypeClass )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ pRegisterReturn[1] = r1;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ pRegisterReturn[0] = r0;
+ break;
+ case typelib_TypeClass_FLOAT:
+#if defined(__ARM_EABI__) || defined(__SOFTFP__)
+ pRegisterReturn[0] = r0;
+#else
+ *(float*)pRegisterReturn = fret;
+#endif
+ break;
+ case typelib_TypeClass_DOUBLE:
+#if defined(__ARM_EABI__) || defined(__SOFTFP__)
+ pRegisterReturn[1] = r1;
+ pRegisterReturn[0] = r0;
+#else
+ *(double*)pRegisterReturn = dret;
+#endif
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ if (!arm::return_in_hidden_param(pReturnType))
+ pRegisterReturn[0] = r0;
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+namespace
+{
+//================================================================
+
+void callVirtualMethod(
+ void * pThis,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeDescriptionReference * pReturnType,
+ sal_uInt32 *pStack,
+ sal_uInt32 nStack,
+ sal_uInt32 *pGPR,
+ sal_uInt32 nGPR) __attribute__((noinline));
+
+void callVirtualMethod(
+ void * pThis,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeDescriptionReference * pReturnType,
+ sal_uInt32 *pStack,
+ sal_uInt32 nStack,
+ sal_uInt32 *pGPR,
+ sal_uInt32 nGPR)
+{
+ // never called
+ if (! pThis)
+ CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
+
+ if ( nStack )
+ {
+ // 8-bytes aligned
+ sal_uInt32 nStackBytes = ( ( nStack + 1 ) >> 1 ) * 8;
+ sal_uInt32 *stack = (sal_uInt32 *) __builtin_alloca( nStackBytes );
+ memcpy( stack, pStack, nStackBytes );
+ }
+
+ // Should not happen, but...
+ if ( nGPR > arm::MAX_GPR_REGS )
+ nGPR = arm::MAX_GPR_REGS;
+
+ sal_uInt32 pMethod = *((sal_uInt32*)pThis);
+ pMethod += 4 * nVtableIndex;
+ pMethod = *((sal_uInt32 *)pMethod);
+
+ typedef void (*FunctionCall )( sal_uInt32, sal_uInt32, sal_uInt32, sal_uInt32);
+ FunctionCall pFunc = (FunctionCall)pMethod;
+
+ (*pFunc)(pGPR[0], pGPR[1], pGPR[2], pGPR[3]);
+
+ sal_uInt32 r0;
+ sal_uInt32 r1;
+
+ // get return value
+ __asm__ __volatile__ (
+ "mov %0, r0\n\t"
+ "mov %1, r1\n\t"
+ : "=r" (r0), "=r" (r1) : );
+
+ MapReturn(r0, r1, pReturnType, (sal_uInt32*)pRegisterReturn);
+}
+}
+
+#define INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < arm::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#ifdef __ARM_EABI__
+#define INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverflow ) \
+ if ( (nr < arm::MAX_GPR_REGS) && (nr % 2) ) \
+ { \
+ ++nr; \
+ } \
+ if ( nr < arm::MAX_GPR_REGS ) \
+ { \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ pGPR[nr++] = *(reinterpret_cast<sal_uInt32 *>( pSV ) + 1); \
+ } \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ { \
+ if ( (pDS - pStart) % 2) \
+ { \
+ ++pDS; \
+ } \
+ *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[0]; \
+ *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[1]; \
+ }
+#else
+#define INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverflow ) \
+ INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow) \
+ INSERT_INT32( ((sal_uInt32*)pSV)+1, nr, pGPR, pDS, bOverflow)
+#endif
+
+#define INSERT_FLOAT( pSV, nr, pFPR, pDS, bOverflow ) \
+ INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow)
+
+#define INSERT_DOUBLE( pSV, nr, pFPR, pDS, pStart, bOverflow ) \
+ INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverflow )
+
+#define INSERT_INT16( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < arm::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < arm::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+
+namespace {
+//=======================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ sal_uInt32 * pStack = (sal_uInt32 *)__builtin_alloca(
+ sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ sal_uInt32 * pStackStart = pStack;
+
+ sal_uInt32 pGPR[arm::MAX_GPR_REGS];
+ sal_uInt32 nGPR = 0;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ bool bOverFlow = false;
+ bool bSimpleReturn = true;
+ if (pReturnTypeDescr)
+ {
+ if (arm::return_in_hidden_param( pReturnTypeRef ) )
+ bSimpleReturn = false;
+
+ if (bSimpleReturn)
+ pCppReturn = pUnoReturn; // direct way for simple types
+ else
+ {
+ // complex return via ptr
+ pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? __builtin_alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+
+ INSERT_INT32( &pCppReturn, nGPR, pGPR, pStack, bOverFlow );
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ INSERT_INT32( &pAdjustedThisPtr, nGPR, pGPR, pStack, bOverFlow );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+// uno_copyAndConvertData( pCppArgs[nPos] = pStack, pUnoArgs[nPos],
+ uno_copyAndConvertData( pCppArgs[nPos] = alloca(8), pUnoArgs[nPos],
+ pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "hyper is %lx\n", pCppArgs[nPos]);
+#endif
+ INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, pStackStart, bOverFlow );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "long is %x\n", pCppArgs[nPos]);
+#endif
+ INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_FLOAT:
+ INSERT_FLOAT( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ INSERT_DOUBLE( pCppArgs[nPos], nGPR, pGPR, pStack, pStackStart, bOverFlow );
+ break;
+ default:
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ INSERT_INT32( &(pCppArgs[nPos]), nGPR, pGPR, pStack, bOverFlow );
+ }
+ }
+
+ try
+ {
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeRef,
+ pStackStart,
+ (pStack - pStackStart),
+ pGPR, nGPR);
+
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+// __asm__ __volatile__ ("sub sp, sp, #2048\n");
+
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+#if OSL_DEBUG_LEVEL > 0
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+#endif
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+#if OSL_DEBUG_LEVEL > 0
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+#endif
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<typelib_InterfaceAttributeTypeDescription const *>
+ (pMemberDescr)));
+
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1;
+ cpp_call(
+ pThis, aVtableSlot, // get, then set method
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+#if OSL_DEBUG_LEVEL > 0
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+#endif
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<typelib_InterfaceMethodTypeDescription const *>
+ (pMemberDescr)));
+
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)(
+ pThis->getBridge()->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_hppa/call.cxx b/bridges/source/cpp_uno/gcc3_linux_hppa/call.cxx
new file mode 100644
index 000000000000..4974bf3f0e82
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_hppa/call.cxx
@@ -0,0 +1,143 @@
+/* -*- 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 <malloc.h>
+#include <rtl/alloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+
+#include <bridges/cpp_uno/shared/bridge.hxx>
+#include <bridges/cpp_uno/shared/types.hxx>
+#include <bridges/cpp_uno/shared/unointerfaceproxy.hxx>
+#include <bridges/cpp_uno/shared/vtables.hxx>
+
+#include "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+void MapReturn(sal_uInt32 ret0, sal_uInt32 ret1, typelib_TypeDescription *pReturnTypeDescr, bool bRegisterReturn, sal_uInt32 *pRegisterReturn)
+{
+ register float fret asm("fr4");
+ register double dret asm("fr4");
+
+ switch (pReturnTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ pRegisterReturn[1] = ret1;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ pRegisterReturn[0] = ret0;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float*)pRegisterReturn = fret;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double*)pRegisterReturn = dret;
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ if (bRegisterReturn)
+ {
+ pRegisterReturn[0] = ret0;
+ pRegisterReturn[1] = ret1;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+//Moved callVirtual into this .cxx so that I can do this and get gcc to not
+//touch r28 without having to learn any more pa-risc assembly than is
+//strictly necessary
+register sal_uInt32 r28 __asm__("%r28");
+
+void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescription *pReturnTypeDescr, bool bRegisterReturn,
+ sal_uInt32 *pStack, sal_uInt32 nStack, sal_uInt32 *pGPR, double *pFPR) __attribute__((noinline));
+
+void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescription *pReturnTypeDescr, bool bRegisterReturn,
+ sal_uInt32 *pStack, sal_uInt32 nStack, sal_uInt32 *pGPR, double *pFPR)
+{
+ register sal_uInt32* sp __asm__("%r30");
+
+ sal_uInt32 pMethod = *((sal_uInt32*)pThis);
+ pMethod += 4 * nVtableIndex;
+ pMethod = *((sal_uInt32 *)pMethod);
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "this is %p\n", pGPR[0]);
+ for (int i = 0; i < hppa::MAX_GPR_REGS ; ++i)
+ fprintf(stderr, "normal reg %d is %d %x\n", i, pGPR[i], pGPR[i]);
+
+ for (int i = 0; i < hppa::MAX_SSE_REGS ; ++i)
+ fprintf(stderr, "float reg %d is %x\n", i, pFPR[i]);
+
+ for (int i = 0; i < nStack; ++i)
+ fprintf(stderr, "stack bytes are %x\n", pStack[i]);
+#endif
+
+ //Always reserve 4 slots, and align to 8 bytes
+ sal_uInt32 nStackBytes = ( ( nStack + 4 + 1 ) >> 1 ) * 8;
+ __builtin_alloca(nStackBytes);
+ sal_uInt32 *stack = sp-8;
+ int o = -5;
+ for (sal_uInt32 i = 0; i < nStack; ++i, --o)
+ stack[o] = pStack[i];
+
+ typedef int (* FunctionCall )( sal_uInt32, sal_uInt32, sal_uInt32, sal_uInt32 );
+ FunctionCall pFunc = (FunctionCall)pMethod;
+
+ asm volatile("fldd %0, %%fr4" : : "m"(pFPR[0]) : "fr4");
+ asm volatile("fldd %0, %%fr5" : : "m"(pFPR[1]) : "fr5");
+ asm volatile("fldd %0, %%fr6" : : "m"(pFPR[2]) : "fr6");
+ asm volatile("fldd %0, %%fr7" : : "m"(pFPR[3]) : "fr7");
+ asm volatile("ldw %0, %%r28" : : "m"(pRegisterReturn) : "r28");
+ (*pFunc)(pGPR[0], pGPR[1], pGPR[2], pGPR[3]);
+
+ register sal_uInt32 r29 __asm__("%r29");
+ MapReturn(r28, r29, pReturnTypeDescr, bRegisterReturn, (sal_uInt32*)pRegisterReturn);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_hppa/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_hppa/cpp2uno.cxx
new file mode 100644
index 000000000000..ebe07d4119b2
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_hppa/cpp2uno.cxx
@@ -0,0 +1,726 @@
+/* -*- 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 <malloc.h>
+#include <hash_map>
+
+#include <rtl/alloc.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "share.hxx"
+
+#include <dlfcn.h>
+
+
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+ static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ long r8, void ** gpreg, double *fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+ {
+ void ** startovrflw = ovrflw;
+ int nregs = 0; //number of words passed in registers
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "cpp2uno_call\n");
+#endif
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+ void * pCppReturn = 0;
+
+ if (pReturnTypeDescr)
+ {
+ if (hppa::isRegisterReturn(pReturnTypeRef))
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "simple return\n");
+#endif
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ else
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex return via r8\n");
+#endif
+ pCppReturn = (void *)r8;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ gpreg++;
+ fpreg++;
+ nregs++;
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion
+ // cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr =
+ (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+ bool bOverFlowUsed = false;
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_DOUBLE:
+ if (nregs < hppa::MAX_WORDS_IN_REGS && (nregs & 1))
+ {
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ if (nregs < hppa::MAX_WORDS_IN_REGS-1)
+ {
+ fpreg++;
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg;
+ gpreg+=2;
+ fpreg+=2;
+ nregs+=2;
+ }
+ else
+ {
+ if ((startovrflw-ovrflw) & 1)
+ ovrflw--;
+ pCppArgs[nPos] = pUnoArgs[nPos] = ((char*)ovrflw - 4);
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw-=2;
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (nregs < hppa::MAX_WORDS_IN_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg;
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw--;
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (nregs < hppa::MAX_WORDS_IN_REGS && (nregs & 1))
+ {
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ if (nregs < hppa::MAX_WORDS_IN_REGS-1)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg;
+ gpreg+=2;
+ fpreg+=2;
+ nregs+=2;
+ }
+ else
+ {
+ if ((startovrflw-ovrflw) & 1)
+ ovrflw--;
+ pCppArgs[nPos] = pUnoArgs[nPos] = ((char*)ovrflw - 4);
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw-=2;
+ break;
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_BOOLEAN:
+ if (nregs < hppa::MAX_WORDS_IN_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ((char*)gpreg + 3);
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ((char*)ovrflw+3);
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw--;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (nregs < hppa::MAX_WORDS_IN_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ((char*)gpreg+2);
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ((char*)ovrflw+2);
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw--;
+ break;
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ default:
+ if (nregs < hppa::MAX_WORDS_IN_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg;
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw--;
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ void *pCppStack;
+
+ if (nregs < hppa::MAX_WORDS_IN_REGS)
+ {
+ pCppArgs[nPos] = pCppStack = *gpreg;
+ gpreg++;
+ fpreg++;
+ nregs++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pCppStack = *ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw--;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "before dispatch\n");
+#endif
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "after dispatch\n");
+#endif
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex],
+ ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc,
+ pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr =
+ ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr,
+ cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex],
+ pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn,
+ pReturnTypeDescr, pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet =
+ (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+ }
+
+
+ //=====================================================================
+ static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+ void ** gpreg, double* fpreg,
+ long sp, long r8,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+
+ {
+ void ** ovrflw = (void**)(sp);
+#ifdef CMC_DEBUG
+ fprintf(stderr, "cpp_mediate with\n");
+ fprintf(stderr, "%x %x\n", nFunctionIndex, nVtableOffset);
+ fprintf(stderr, "and %x %x\n", (long)(ovrflw[0]), (long)(ovrflw[-1]));
+ fprintf(stderr, "and %x %x\n", (long)(ovrflw[-2]), (long)(ovrflw[-3]));
+ fprintf(stderr, "and %x %x\n", (long)(ovrflw[-4]), (long)(ovrflw[-5]));
+ fprintf(stderr, "and %x %x\n", (long)(ovrflw[-6]), (long)(ovrflw[-7]));
+ fprintf(stderr, "and %x %x\n", (long)(ovrflw[-8]), (long)(ovrflw[-9]));
+ fprintf(stderr, "and %x %x\n", (long)(ovrflw[-10]), (long)(ovrflw[-11]));
+ fprintf(stderr, "and %x %x\n", (long)(ovrflw[-12]), (long)(ovrflw[-13]));
+ fprintf(stderr, "and %x %x\n", (long)(ovrflw[-14]), (long)(ovrflw[-15]));
+#endif
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ void * pThis;
+ if (nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = gpreg[1];
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is gpreg[1]\n");
+#endif
+ }
+ else
+ {
+ pThis = gpreg[0];
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is gpreg[0]\n");
+#endif
+ }
+
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
+ bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex,
+ "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pCppI );
+ }
+
+ // determine called method
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex,
+ "### illegal vtable index!" );
+ sal_Int32 nMemberPos =
+ pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers,
+ "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] ==
+ nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ r8, gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ r8, gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET(&pTD,
+ reinterpret_cast<Type *>(gpreg[1])->getTypeLibType());
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( r8 ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = (void*)r8;
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ r8, gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ OUString::createFromAscii("no member description found!"),
+ (XInterface *)pCppI );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+ }
+}
+
+//=======================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+
+sal_Int64 cpp_vtable_call( sal_uInt32 in0, sal_uInt32 in1, sal_uInt32 in2, sal_uInt32 in3, sal_uInt32 firstonstack )
+{
+ register sal_Int32 r21 asm("r21");
+ register sal_Int32 r22 asm("r22");
+ register sal_Int32 r28 asm("r28");
+ sal_Int32 functionIndex = r21;
+ sal_Int32 vtableOffset = r22;
+ sal_Int32 r8 = r28;
+
+ long sp = (long)&firstonstack;
+
+ sal_uInt32 gpreg[hppa::MAX_GPR_REGS];
+ gpreg[0] = in0;
+ gpreg[1] = in1;
+ gpreg[2] = in2;
+ gpreg[3] = in3;
+
+ float fpreg[hppa::MAX_SSE_REGS]; //todo
+ register float f0 asm("fr4"); fpreg[0] = f0;
+ register float f1 asm("fr5"); fpreg[1] = f1;
+ register float f2 asm("fr6"); fpreg[2] = f2;
+ register float f3 asm("fr7"); fpreg[3] = f3;
+
+ double dpreg[hppa::MAX_SSE_REGS]; //todo
+ register double d0 asm("fr4"); dpreg[0] = d0;
+ register double d1 asm("fr5"); dpreg[1] = d1;
+ register double d2 asm("fr6"); dpreg[2] = d2;
+ register double d3 asm("fr7"); dpreg[3] = d3;
+
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "got to cpp_vtable_call with %x %x\n", functionIndex, vtableOffset);
+ for (int i = 0; i < hppa::MAX_GPR_REGS; ++i)
+ fprintf(stderr, "reg %d is %d %x\n", i, gpreg[i], gpreg[i]);
+ for (int i = 0; i < hppa::MAX_SSE_REGS; ++i)
+ fprintf(stderr, "float reg %d is %f %x\n", i, fpreg[i], ((long*)fpreg)[i]);
+ for (int i = 0; i < 4; ++i)
+ fprintf(stderr, "double reg %d is %f %llx\n", i, dpreg[i], ((long long*)dpreg)[i]);
+#endif
+
+ sal_Int64 nRegReturn;
+
+ typelib_TypeClass aType =
+ cpp_mediate( functionIndex, vtableOffset, (void**)gpreg, dpreg, sp, r8, &nRegReturn);
+
+ switch( aType )
+ {
+ case typelib_TypeClass_FLOAT:
+ f0 = (*((float*)&nRegReturn));
+ break;
+ case typelib_TypeClass_DOUBLE:
+ d0 = (*((double*)&nRegReturn));
+ break;
+ default:
+ break;
+ }
+
+ return nRegReturn;
+}
+
+
+namespace
+{
+ const int codeSnippetSize = 44;
+
+# define unldil(v) (((v & 0x7c) << 14) | ((v & 0x180) << 7) | ((v & 0x3) << 12) | ((v & 0xffe00) >> 8) | ((v & 0x100000) >> 20))
+# define L21(v) unldil(((unsigned long)(v) >> 11) & 0x1fffff) //Left 21 bits
+# define R11(v) (((unsigned long)(v) & 0x7FF) << 1) //Right 11 bits
+
+ unsigned char *codeSnippet(unsigned char* code, sal_Int32 functionIndex,
+ sal_Int32 vtableOffset, bool bHasHiddenParam)
+ {
+ if (bHasHiddenParam)
+ functionIndex |= 0x80000000;
+
+ unsigned char * p = code;
+ *(unsigned long*)&p[0] = 0xeaa00000; // b,l 0x8,r21
+ *(unsigned long*)&p[4] = 0xd6a01c1e; // depwi 0,31,2,r21
+ *(unsigned long*)&p[8] = 0x4aa10040; // ldw 32(r21),r1
+
+ *(unsigned long*)&p[12] = 0x22A00000 | L21(functionIndex); // ldil L<functionIndex>,r21
+ *(unsigned long*)&p[16] = 0x36B50000 | R11(functionIndex); // ldo R<functionIndex>,r21
+
+ *(unsigned long*)&p[20] = 0x22C00000 | L21(vtableOffset); // ldil L<vtableOffset>,r22
+ *(unsigned long*)&p[24] = 0x36D60000 | R11(vtableOffset); // ldo R<vtableOffset>,r22
+
+ *(unsigned long*)&p[28] = 0x0c201094; // ldw 0(r1),r20
+ *(unsigned long*)&p[32] = 0xea80c000; // bv r0(r20)
+ *(unsigned long*)&p[36] = 0x0c281093; // ldw 4(r1),r19
+ *(unsigned long*)&p[40] = ((unsigned long)(cpp_vtable_call) & ~2);
+
+ return code + codeSnippetSize;
+ }
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0;
+ slots[-1].fn = 0;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for (sal_Int32 i = 0; i < type->nMembers; ++i)
+ {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset, false);
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset, false);
+ }
+ break;
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset, false);
+ break;
+ }
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const *beg, unsigned char const *end)
+{
+ void *p = (void*)((size_t)beg & ~31);
+ size_t stride = 32;
+ while (p < end)
+ {
+ asm volatile("fdc (%0)\n\t"
+ "sync\n\t"
+ "fic,m %1(%%sr4, %0)\n\t"
+ "sync" : "+r"(p) : "r"(stride) : "memory");
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_hppa/except.cxx b/bridges/source/cpp_uno/gcc3_linux_hppa/except.cxx
new file mode 100644
index 000000000000..36fe7968e19a
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_hppa/except.cxx
@@ -0,0 +1,335 @@
+/* -*- 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 <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+extern sal_Int32 * pHack;
+extern sal_Int32 nHack;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+ void dummy_can_throw_anything( char const * )
+ {
+ }
+
+ //===================================================================
+ static OUString toUNOname( char const * p ) SAL_THROW( () )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+ }
+
+ //=====================================================================
+ class RTTI
+ {
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+ public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI(typelib_CompoundTypeDescription *) SAL_THROW( () );
+ };
+ //____________________________________________________________________
+ RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+ {
+ }
+ //____________________________________________________________________
+ RTTI::~RTTI() SAL_THROW( () )
+ {
+ dlclose( m_hApp );
+ }
+
+ //____________________________________________________________________
+ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+ {
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iRttiFind( m_rttis.find( unoName ) );
+ if (iRttiFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
+ if (iFind == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with _ZTI
+ char const * rttiName = symName.getStr() +4;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iFind->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iRttiFind->second;
+ }
+
+ return rtti;
+ }
+
+ //------------------------------------------------------------------
+ static void deleteException( void * pExc )
+ {
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+ }
+
+ //==================================================================
+ void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() );
+#endif
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get typedescription for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+ }
+
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+ }
+
+ static void* getAdjustedPtr(__cxa_exception* header)
+ {
+ return header->adjustedPtr;
+ }
+
+ //===================================================================
+ void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+ {
+ if (! header)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, getAdjustedPtr(header), pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_hppa/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_hppa/makefile.mk
new file mode 100644
index 000000000000..6fab7a4d1f5f
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_hppa/makefile.mk
@@ -0,0 +1,82 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+NO_BSYMBOLIC=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)" == "GCCLINUXH"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+CFLAGSCXX += -fno-omit-frame-pointer -fno-strict-aliasing
+
+NOOPTFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/call.obj
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/call.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/bridges/source/cpp_uno/gcc3_linux_hppa/share.hxx b/bridges/source/cpp_uno/gcc3_linux_hppa/share.hxx
new file mode 100644
index 000000000000..895acf6b1883
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_hppa/share.hxx
@@ -0,0 +1,102 @@
+/* -*- 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 "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+ void dummy_can_throw_anything( char const * );
+
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+
+namespace hppa
+{
+ enum hppalimits { MAX_WORDS_IN_REGS = 4, MAX_GPR_REGS = 4, MAX_SSE_REGS = 4 };
+
+ bool isRegisterReturn( typelib_TypeDescriptionReference *pTypeRef );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_hppa/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_hppa/uno2cpp.cxx
new file mode 100644
index 000000000000..6d7a5333f1e1
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_hppa/uno2cpp.cxx
@@ -0,0 +1,522 @@
+/* -*- 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 <malloc.h>
+#include <rtl/alloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+
+#include <bridges/cpp_uno/shared/bridge.hxx>
+#include <bridges/cpp_uno/shared/types.hxx>
+#include <bridges/cpp_uno/shared/unointerfaceproxy.hxx>
+#include <bridges/cpp_uno/shared/vtables.hxx>
+
+#include "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescription *pReturnTypeDescr, bool bRegisterReturn,
+ sal_uInt32 *pStack, sal_uInt32 nStack, sal_uInt32 *pGPR, double *pFPR);
+
+#define INSERT_INT32( pSV, nr, pGPR, pDS, bOverFlow )\
+ if (nr < hppa::MAX_WORDS_IN_REGS) \
+ { \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ } \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#define INSERT_INT64( pSV, nr, pGPR, pDS, pStart, bOverFlow )\
+ if ( (nr < hppa::MAX_WORDS_IN_REGS) && (nr % 2) ) \
+ { \
+ ++nr; \
+ } \
+ if ( nr < hppa::MAX_WORDS_IN_REGS ) \
+ { \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ pGPR[nr++] = *(reinterpret_cast<sal_uInt32 *>( pSV ) + 1); \
+ } \
+ else \
+ bOverFlow = true; \
+ if ( bOverFlow ) \
+ { \
+ if ( (pDS - pStart) % 2) \
+ ++pDS; \
+ *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[1]; \
+ *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[0]; \
+ }
+
+#define INSERT_FLOAT( pSV, nr, pFPR, pDS, bOverFlow ) \
+ if (nr < hppa::MAX_WORDS_IN_REGS) \
+ { \
+ sal_uInt32 *pDouble = (sal_uInt32 *)&(pFPR[nr++]); \
+ pDouble[0] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ } \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#define INSERT_DOUBLE( pSV, nr, pFPR, pDS, pStart, bOverFlow ) \
+ if ( (nr < hppa::MAX_WORDS_IN_REGS) && (nr % 2) ) \
+ { \
+ ++nr; \
+ } \
+ if ( nr < hppa::MAX_WORDS_IN_REGS ) \
+ { \
+ sal_uInt32 *pDouble = (sal_uInt32 *)&(pFPR[nr+1]); \
+ pDouble[0] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ pDouble[1] = *(reinterpret_cast<sal_uInt32 *>( pSV ) + 1); \
+ nr+=2; \
+ } \
+ else \
+ bOverFlow = true; \
+ if ( bOverFlow ) \
+ { \
+ if ( (pDS - pStart) % 2) \
+ ++pDS; \
+ *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[1]; \
+ *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[0]; \
+ }
+
+#define INSERT_INT16( pSV, nr, pGPR, pDS, bOverFlow ) \
+ if ( nr < hppa::MAX_WORDS_IN_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, nr, pGPR, pDS, bOverFlow ) \
+ if ( nr < hppa::MAX_WORDS_IN_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+
+namespace hppa
+{
+ bool is_complex_struct(const typelib_TypeDescription * type)
+ {
+ const typelib_CompoundTypeDescription * p
+ = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
+ for (sal_Int32 i = 0; i < p->nMembers; ++i)
+ {
+ if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
+ p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
+ {
+ typelib_TypeDescription * t = 0;
+ TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
+ bool b = is_complex_struct(t);
+ TYPELIB_DANGER_RELEASE(t);
+ if (b) {
+ return true;
+ }
+ }
+ else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
+ return true;
+ }
+ if (p->pBaseTypeDescription != 0)
+ return is_complex_struct(&p->pBaseTypeDescription->aBase);
+ return false;
+ }
+
+ bool isRegisterReturn( typelib_TypeDescriptionReference *pTypeRef )
+ {
+ if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
+ return true;
+ else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
+ {
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+
+ /* If the struct is larger than 8 bytes, then there is a buffer at r8 to stick the return value into */
+ bool bRet = pTypeDescr->nSize <= 8 && !is_complex_struct(pTypeDescr);
+
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ return bRet;
+ }
+ return false;
+ }
+}
+
+
+namespace {
+//=======================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ sal_uInt32 * pStack = (sal_uInt32 *)__builtin_alloca(
+ sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ sal_uInt32 * pStackStart = pStack;
+
+ sal_uInt32 pGPR[hppa::MAX_GPR_REGS];
+ double pFPR[hppa::MAX_SSE_REGS];
+ sal_uInt32 nRegs=0;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+ bool bOverFlow = false;
+ bool bRegisterReturn = true;
+
+ if (pReturnTypeDescr)
+ {
+
+ bRegisterReturn = hppa::isRegisterReturn(pReturnTypeRef);
+ if (bRegisterReturn)
+ pCppReturn = pUnoReturn; // direct way for simple types
+ else
+ {
+ // complex return via ptr
+ pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? __builtin_alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ INSERT_INT32( &pAdjustedThisPtr, nRegs, pGPR, pStack, bOverFlow );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = alloca(8), pUnoArgs[nPos],
+ pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "hyper is %llx\n", *((long long*)pCppArgs[nPos]));
+#endif
+ INSERT_INT64( pCppArgs[nPos], nRegs, pGPR, pStack, pStackStart, bOverFlow );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "long is %x\n", pCppArgs[nPos]);
+#endif
+ INSERT_INT32( pCppArgs[nPos], nRegs, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ INSERT_INT16( pCppArgs[nPos], nRegs, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ INSERT_INT8( pCppArgs[nPos], nRegs, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_FLOAT:
+ INSERT_FLOAT( pCppArgs[nPos], nRegs, pFPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ INSERT_DOUBLE( pCppArgs[nPos], nRegs, pFPR, pStack, pStackStart, bOverFlow );
+ break;
+ default:
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ INSERT_INT32( &(pCppArgs[nPos]), nRegs, pGPR, pStack, bOverFlow );
+ }
+ }
+
+ try
+ {
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr, bRegisterReturn,
+ pStackStart,
+ (pStack - pStackStart), pGPR, pFPR);
+
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+#if OSL_DEBUG_LEVEL > 0
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+#endif
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+#if OSL_DEBUG_LEVEL > 0
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+#endif
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<typelib_InterfaceAttributeTypeDescription const *>
+ (pMemberDescr)));
+
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1;
+ cpp_call(
+ pThis, aVtableSlot, // get, then set method
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+#if OSL_DEBUG_LEVEL > 0
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+#endif
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<typelib_InterfaceMethodTypeDescription const *>
+ (pMemberDescr)));
+
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)(
+ pThis->getBridge()->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_ia64/call.s b/bridges/source/cpp_uno/gcc3_linux_ia64/call.s
new file mode 100644
index 000000000000..8073127da3e3
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_ia64/call.s
@@ -0,0 +1,20 @@
+/* ia64 support code for OpenOffice C++/UNO bridging
+ *
+ * Caolan McNamara <caolanm@redhat.com>
+ */
+ .text
+ .align 16
+ .global privateSnippetExecutor#
+ .proc privateSnippetExecutor#
+privateSnippetExecutor:
+ adds r15 = 8, gp /* r15 now points to real gp value*/
+ ;;
+ ld8 r14 = [gp] /* load nOffsetAndIndex into a handy register */
+ ld8 gp = [r15] /* load real gp value into gp */
+ ;;
+ /* store the address where large structs are "returned" into a handy register */
+ mov r15 = r8
+ ;;
+ br cpp_vtable_call# /* call cpp_vtable_call which'll suck out r14 */
+ ;;
+ .endp privateSnippetExecutor#
diff --git a/bridges/source/cpp_uno/gcc3_linux_ia64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_ia64/cpp2uno.cxx
new file mode 100644
index 000000000000..5a25c25c1ed8
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_ia64/cpp2uno.cxx
@@ -0,0 +1,685 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "share.hxx"
+#include <stdio.h>
+
+extern "C" { extern void (*privateSnippetExecutor)(); }
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+//==================================================================================================
+static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams, long r8,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr, "as far as cpp2uno_call\n");
+#endif
+
+ int ng = 0; //number of gpr registers used
+ int nf = 0; //number of fpr regsiters used
+
+ // gpreg: [ret *], this, [gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if (pReturnTypeDescr)
+ {
+ if ( ia64::return_in_hidden_param( pReturnTypeRef ) ) // complex return via ptr passed as hidden parameter reg (pCppReturn)
+ {
+ pCppReturn = *(void **)gpreg;
+ gpreg++;
+ ng++;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ else if ( ia64::return_via_r8_buffer( pReturnTypeRef ) ) // complex return via ptr passed in r8
+ {
+ pCppReturn = (void *)r8;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+
+ else
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ // pop this
+ gpreg++;
+ ng++;
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int64), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+ bool bOverFlowUsed = false;
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "arg %d of %d\n", nPos, nParams);
+#endif
+
+ //I think it is impossible to get UNO to pass structs as parameters by copy
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "simple\n");
+#endif
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_FLOAT:
+ if (nf < ia64::MAX_SSE_REGS && ng < ia64::MAX_GPR_REGS)
+ {
+ float tmp = (float) (*((double *)fpreg));
+ (*((float *) fpreg)) = tmp;
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
+ nf++;
+ gpreg++;
+ ng++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (nf < ia64::MAX_SSE_REGS && ng < ia64::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
+ nf++;
+ gpreg++;
+ ng++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+ break;
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ default:
+ if (ng < ia64::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg++;
+ ng++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex, ng is %d\n", ng);
+#endif
+ void *pCppStack; //temporary stack pointer
+
+ if (ng < ia64::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pCppStack = *gpreg++;
+ ng++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pCppStack = *ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "end of params\n");
+#endif
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = ia64::return_via_r8_buffer(pReturnTypeRef) ? typelib_TypeClass_VOID : (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_uInt64 nOffsetAndIndex,
+ void ** gpreg, void ** fpreg, long sp, long r8,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int64)==sizeof(void *), "### unexpected!" );
+
+ sal_Int32 nVtableOffset = (nOffsetAndIndex >> 32);
+ sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFFFFFF);
+
+ void ** ovrflw = (void**)(sp);
+
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ void * pThis;
+ if (nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = gpreg[1];
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is gpreg[1]\n");
+#endif
+ }
+ else
+ {
+ pThis = gpreg[0];
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is gpreg[0]\n");
+#endif
+ }
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is %p\n", pThis);
+#endif
+
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is now %p\n", pThis);
+#endif
+
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "indexes are %d %d\n", nFunctionIndex, pTypeDescr->nMapFunctionIndexToMemberIndex);
+#endif
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pThis );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "members are %d %d\n", nMemberPos, pTypeDescr->nAllMembers);
+#endif
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ r8, gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ r8, gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ r8, gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "screwed\n");
+#endif
+
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "end of cpp_mediate\n");
+#endif
+ return eRet;
+}
+}
+
+extern "C" ia64::RegReturn cpp_vtable_call(
+ long in0, long in1, long in2, long in3, long in4, long in5, long in6, long in7,
+ long firstonstack
+ )
+{
+ register long r15 asm("r15");
+ long r8 = r15;
+
+ register long r14 asm("r14");
+ long nOffsetAndIndex = r14;
+
+ long sp = (long)&firstonstack;
+
+ sal_uInt64 gpreg[ia64::MAX_GPR_REGS];
+ gpreg[0] = in0;
+ gpreg[1] = in1;
+ gpreg[2] = in2;
+ gpreg[3] = in3;
+ gpreg[4] = in4;
+ gpreg[5] = in5;
+ gpreg[6] = in6;
+ gpreg[7] = in7;
+
+ double fpreg[ia64::MAX_SSE_REGS];
+ register double f8 asm("f8"); fpreg[0] = f8;
+ register double f9 asm("f9"); fpreg[1] = f9;
+ register double f10 asm("f10"); fpreg[2] = f10;
+ register double f11 asm("f11"); fpreg[3] = f11;
+ register double f12 asm("f12"); fpreg[4] = f12;
+ register double f13 asm("f13"); fpreg[5] = f13;
+ register double f14 asm("f14"); fpreg[6] = f14;
+ register double f15 asm("f15"); fpreg[7] = f15;
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "cpp_vtable_call called with %lx\n", nOffsetAndIndex);
+ fprintf(stderr, "adump is %lx %lx %lx %lx %lx %lx %lx %lx\n", in0, in1, in2, in3, in4, in5, in6, in7);
+ fprintf(stderr, "bdump is %f %f %f %f %f %f %f %f\n", f8, f9, f10, f11, f12, f13, f14, f15);
+#endif
+
+ volatile long nRegReturn[4] = { 0 };
+
+ typelib_TypeClass aType =
+ cpp_mediate( nOffsetAndIndex, (void**)gpreg, (void**)fpreg, sp, r8, (sal_Int64*)&nRegReturn[0]);
+
+ ia64::RegReturn ret;
+ switch( aType )
+ {
+ case typelib_TypeClass_VOID:
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_HYPER:
+ ret.r8 = nRegReturn[0];
+ break;
+ case typelib_TypeClass_FLOAT:
+ asm volatile("ldfs f8=%0" : : "m"((*((float*)&nRegReturn))) : "f8");
+ break;
+ case typelib_TypeClass_DOUBLE:
+ asm volatile("ldfd f8=%0" : : "m"((*((double*)&nRegReturn))) : "f8");
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ ret.r8 = nRegReturn[0];
+ ret.r9 = nRegReturn[1];
+ ret.r10 = nRegReturn[2];
+ ret.r11 = nRegReturn[3];
+ break;
+ }
+ default:
+ break;
+ }
+ return ret;
+}
+
+namespace
+{
+const int codeSnippetSize = 40;
+
+bridges::cpp_uno::shared::VtableFactory::Slot codeSnippet( unsigned char * code, sal_PtrDiff writetoexecdiff, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+ bool bHasHiddenParam )
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr, "size is %d\n", codeSnippetSize);
+ fprintf(stderr,"in codeSnippet functionIndex is %x\n", nFunctionIndex);
+ fprintf(stderr,"in codeSnippet vtableOffset is %x\n", nVtableOffset);
+#endif
+
+ sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
+
+ if ( bHasHiddenParam )
+ nOffsetAndIndex |= 0x80000000;
+
+ long *raw = (long *)code;
+
+ bridges::cpp_uno::shared::VtableFactory::Slot* destination = (bridges::cpp_uno::shared::VtableFactory::Slot*)cpp_vtable_call;
+
+ raw[0] = (long)&privateSnippetExecutor;
+ raw[1] = (long)&raw[2];
+ raw[2] = nOffsetAndIndex;
+ raw[3] = destination->gp_value;
+
+ return *(bridges::cpp_uno::shared::VtableFactory::Slot*)(code+writetoexecdiff);
+}
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *, unsigned char const *)
+{
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot * bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot* bridges::cpp_uno::shared::VtableFactory::initializeBlock(void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ Slot foo = {0,0};
+ slots[-2] = foo;
+ slots[-1] = foo;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** in_slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*in_slots) -= functionCount;
+ Slot * slots = *in_slots;
+#ifdef CMC_DEBUG
+ fprintf(stderr, "in addLocalFunctions functionOffset is %x\n",functionOffset);
+ fprintf(stderr, "in addLocalFunctions vtableOffset is %x\n",vtableOffset);
+#endif
+
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ *slots++ = codeSnippet(
+ code, writetoexecdiff, functionOffset++, vtableOffset,
+ ia64::return_in_hidden_param(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+ code += codeSnippetSize;
+
+
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ *slots++ = codeSnippet(code, writetoexecdiff, functionOffset++, vtableOffset, false);
+ code += codeSnippetSize;
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ *slots++ = codeSnippet(
+ code, writetoexecdiff, functionOffset++, vtableOffset,
+ ia64::return_in_hidden_param(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ code += codeSnippetSize;
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_ia64/except.cxx b/bridges/source/cpp_uno/gcc3_linux_ia64/except.cxx
new file mode 100644
index 000000000000..c0de95532515
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_ia64/except.cxx
@@ -0,0 +1,289 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * )
+{
+}
+
+//==================================================================================================
+static OUString toUNOname( char const * p ) SAL_THROW( () )
+{
+#if OSL_DEBUG_LEVEL > 1
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+}
+
+//==================================================================================================
+class RTTI
+{
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+{
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iRttiFind( m_rttis.find( unoName ) );
+ if (iRttiFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
+ if (iFind == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with _ZTI
+ char const * rttiName = symName.getStr() +4;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iFind->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iRttiFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void deleteException( void * pExc )
+{
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ terminate();
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ terminate();
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno )
+{
+ OSL_ENSURE( header, "### no exception header!!!" );
+ if (! header)
+ terminate();
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" );
+ if (! pExcTypeDescr)
+ terminate();
+
+ // construct uno exception any
+ ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ ::typelib_typedescription_release( pExcTypeDescr );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_ia64/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_ia64/makefile.mk
new file mode 100644
index 000000000000..1e82cfabe260
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_ia64/makefile.mk
@@ -0,0 +1,83 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCLINUXAgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer -fno-strict-aliasing
+
+NOOPTFILES= \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/cpp2uno.obj
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/call.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+
+SHL1OBJS= $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.s
+ $(CC) -c -o $(SLO)$/$(@:b).o $< -fpic ; touch $@
diff --git a/bridges/source/cpp_uno/gcc3_linux_ia64/share.hxx b/bridges/source/cpp_uno/gcc3_linux_ia64/share.hxx
new file mode 100644
index 000000000000..359c9c720212
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_ia64/share.hxx
@@ -0,0 +1,132 @@
+/* -*- 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 "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+ void dummy_can_throw_anything( char const * );
+
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+namespace ia64
+{
+ enum ia64limits { MAX_GPR_REGS = 8, MAX_SSE_REGS = 8, MAX_REG_SLOTS = 8 };
+
+ bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
+ bool return_via_r8_buffer( typelib_TypeDescriptionReference *pTypeRef );
+
+ struct RegReturn
+ {
+ long r8;
+ long r9;
+ long r10;
+ long r11;
+ };
+}
+
+namespace bridges
+{
+ namespace cpp_uno
+ {
+ namespace shared
+ {
+ /*
+ http://www.swag.uwaterloo.ca/asx/ABI.html
+ On Itanium, function pointers are pairs: the function address followed
+ by the global pointer value that should be used when calling the
+ function (code address, gp value)
+ */
+ struct VtableFactory::Slot
+ {
+ sal_uInt64 code_address;
+ sal_uInt64 gp_value;
+ };
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_ia64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_ia64/uno2cpp.cxx
new file mode 100644
index 000000000000..2be69d85ba90
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_ia64/uno2cpp.cxx
@@ -0,0 +1,692 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+void MapReturn(const ia64::RegReturn &rRet, double dret, typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn, sal_uInt64 *pRegisterReturn)
+{
+ switch (pReturnTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ *pRegisterReturn = rRet.r8;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *pRegisterReturn = (unsigned short)rRet.r8;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *pRegisterReturn = (unsigned char)rRet.r8;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *reinterpret_cast<float *>( pRegisterReturn ) = dret;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *reinterpret_cast<double *>( pRegisterReturn ) = dret;
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ sal_uInt32 nRetSize = pReturnTypeDescr->nSize;
+ if (bSimpleReturn && nRetSize <= 32 && nRetSize > 0)
+ memcpy(pRegisterReturn, (void*)&rRet, nRetSize);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+namespace ia64
+{
+ bool is_complex_struct(const typelib_TypeDescription * type)
+ {
+ const typelib_CompoundTypeDescription * p
+ = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
+ for (sal_Int32 i = 0; i < p->nMembers; ++i)
+ {
+ if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
+ p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
+ {
+ typelib_TypeDescription * t = 0;
+ TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
+ bool b = is_complex_struct(t);
+ TYPELIB_DANGER_RELEASE(t);
+ if (b) {
+ return true;
+ }
+ }
+ else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
+ return true;
+ }
+ if (p->pBaseTypeDescription != 0)
+ return is_complex_struct(&p->pBaseTypeDescription->aBase);
+ return false;
+ }
+
+ bool is_complex_struct( typelib_TypeDescriptionReference *pTypeRef )
+ {
+ if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
+ {
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+
+ bool bRet = is_complex_struct( pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+
+ return bRet;
+ }
+ return false;
+ }
+
+ bool return_via_r8_buffer( typelib_TypeDescriptionReference *pTypeRef )
+ {
+ if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
+ {
+ if (is_complex_struct( pTypeRef )) return false;
+
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+
+ /* If the struct is larger than 32 bytes, then there is a buffer at r8 to stick the return value into */
+ bool bRet = pTypeDescr->nSize > 32;
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ return bRet;
+ }
+ return false;
+ }
+
+ bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
+ {
+ if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
+ return false;
+ else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
+ return is_complex_struct( pTypeRef );
+ return true;
+ }
+
+
+}
+
+namespace
+{
+//==================================================================================================
+static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
+ sal_uInt64 *pStack, sal_uInt32 nStack,
+ sal_uInt64 *pGPR, sal_uInt32 nGPR,
+ double *pFPR, sal_uInt32 nFPR)
+{
+ // Stack, if used, must be 16-bytes aligned
+ if ( nStack )
+ nStack = ( nStack + 1 ) & ~1;
+
+ // Should not happen, but...
+ if ( nFPR > ia64::MAX_SSE_REGS )
+ nFPR = ia64::MAX_SSE_REGS;
+ if ( nGPR > ia64::MAX_GPR_REGS )
+ nGPR = ia64::MAX_GPR_REGS;
+
+#ifdef CMC_DEBUG
+ // Let's figure out what is really going on here
+ {
+ fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
+ for ( unsigned int i = 0; i < nGPR; ++i )
+ fprintf( stderr, "0x%lx, ", pGPR[i] );
+ fprintf( stderr, "\nFPR's (%d): ", nFPR );
+ for ( unsigned int i = 0; i < nFPR; ++i )
+ fprintf( stderr, "0x%lx (%f), ", pFPR[i], pFPR[i] );
+ fprintf( stderr, "\nStack (%d): ", nStack );
+ for ( unsigned int i = 0; i < nStack; ++i )
+ fprintf( stderr, "0x%lx, ", pStack[i] );
+ fprintf( stderr, "\n" );
+ fprintf( stderr, "pRegisterReturn is %p\n", pRegisterReturn);
+ }
+#endif
+
+ // Load parameters to stack, if necessary
+ sal_uInt64 *stack = (sal_uInt64 *) __builtin_alloca( nStack * 8 );
+ memcpy( stack, pStack, nStack * 8 );
+
+ // To get pointer to method
+ // a) get the address of the vtable
+ sal_uInt64 pMethod = *((sal_uInt64 *)pThis);
+ // b) get the address from the vtable entry at offset, each entry is 16bytes,
+ // 8 for function pointer, and 8 for global pointer
+ pMethod += 16 * nVtableIndex;
+
+ typedef void (* FunctionCall )( sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64 );
+ FunctionCall pFunc = (FunctionCall)pMethod;
+
+ switch (nFPR) //deliberate fall through
+ {
+ case 8:
+ asm volatile("ldfd f15=%0" : : "m"(pFPR[7]) : "f15");
+ case 7:
+ asm volatile("ldfd f14=%0" : : "m"(pFPR[6]) : "f14");
+ case 6:
+ asm volatile("ldfd f13=%0" : : "m"(pFPR[5]) : "f13");
+ case 5:
+ asm volatile("ldfd f12=%0" : : "m"(pFPR[4]) : "f12");
+ case 4:
+ asm volatile("ldfd f11=%0" : : "m"(pFPR[3]) : "f11");
+ case 3:
+ asm volatile("ldfd f10=%0" : : "m"(pFPR[2]) : "f10");
+ case 2:
+ asm volatile("ldfd f9=%0" : : "m"(pFPR[1]) : "f9");
+ case 1:
+ asm volatile("ldfd f8=%0" : : "m"(pFPR[0]) : "f8");
+ default:
+ break;
+ }
+
+ //stick the return area into r8 for big struct returning
+ asm volatile("ld8 r8=%0" : : "m"(pRegisterReturn) : "r8");
+
+ (*pFunc)(pGPR[0], pGPR[1], pGPR[2], pGPR[3], pGPR[4], pGPR[5], pGPR[6], pGPR[7]);
+
+ register double f8 asm("f8");
+ ia64::RegReturn ret;
+ {
+ register long r8 asm("r8"); ret.r8 = r8;
+ register long r9 asm("r9"); ret.r9 = r9;
+ register long r10 asm("r10"); ret.r10 = r10;
+ register long r11 asm("r11"); ret.r11 = r11;
+ }
+
+ MapReturn(ret, f8, pReturnTypeDescr, bSimpleReturn, (sal_uInt64*)pRegisterReturn);
+}
+
+// Macros for easier insertion of values to registers or stack
+// pSV - pointer to the source
+// nr - order of the value [will be increased if stored to register]
+// pFPR, pGPR - pointer to the registers
+// pDS - pointer to the stack [will be increased if stored here]
+
+// The value in %xmm register is already prepared to be retrieved as a float,
+// thus we treat float and double the same
+#define INSERT_FLOAT( pSV, nfr, pFPR, ngr, pGPR, pDS, bOverflow ) \
+ if ( nfr < ia64::MAX_SSE_REGS && ngr < ia64::MAX_GPR_REGS ) \
+ pFPR[nfr++] = *reinterpret_cast<float *>( pSV ); \
+ if ( ngr < ia64::MAX_GPR_REGS ) \
+ pGPR[ngr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
+
+#define INSERT_DOUBLE( pSV, nfr, pFPR, ngr, pGPR, pDS, bOverflow ) \
+ if ( nfr < ia64::MAX_SSE_REGS && ngr < ia64::MAX_GPR_REGS ) \
+ pFPR[nfr++] = *reinterpret_cast<double *>( pSV ); \
+ if ( ngr < ia64::MAX_GPR_REGS ) \
+ pGPR[ngr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
+
+#define INSERT_INT64( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ia64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
+
+#define INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ia64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#define INSERT_INT16( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ia64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ia64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+
+//==================================================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ sal_uInt64 * pStack = (sal_uInt64 *)alloca( (nParams+3) * sizeof(sal_Int64) );
+ sal_uInt64 * pStackStart = pStack;
+
+ sal_uInt64 pGPR[ia64::MAX_GPR_REGS];
+ sal_uInt32 nGPR = 0;
+
+ double pFPR[ia64::MAX_SSE_REGS];
+ sal_uInt32 nFPR = 0;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ bool bOverFlow = false;
+
+ bool bSimpleReturn = true;
+ if (pReturnTypeDescr)
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "return type is %d\n", pReturnTypeDescr->eTypeClass);
+#endif
+ if ( ia64::return_in_hidden_param(pReturnTypeRef) || ia64::return_via_r8_buffer(pReturnTypeRef) )
+ bSimpleReturn = false;
+
+ if ( bSimpleReturn )
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+#ifdef CMC_DEBUG
+ fprintf(stderr, "simple return\n");
+#endif
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize ) : pUnoReturn);
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pCppReturn/pUnoReturn is %lx/%lx", pCppReturn, pUnoReturn);
+#endif
+ if (!ia64::return_via_r8_buffer(pReturnTypeRef))
+ INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack, bOverFlow );
+ }
+ }
+ // push "this" pointer
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "this pointer is %p\n", pAdjustedThisPtr);
+#endif
+ INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack, bOverFlow );
+
+ // Args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "n params is %d\n", nParams);
+#endif
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "param %d is %d %d %d\n", nPos, rParam.bOut, bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ),
+ pParamTypeDescr->eTypeClass);
+#endif
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+// uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr,
+ uno_copyAndConvertData( pCppArgs[nPos] = pStack, pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "hyper is %lx\n", *(unsigned long*)(pCppArgs[nPos]));
+#endif
+ INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "long is %lx\n", *(unsigned int*)(pCppArgs[nPos]));
+#endif
+ INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "short is %x\n", *(unsigned short*)(pCppArgs[nPos]));
+#endif
+ INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "byte is %x\n", *(unsigned char*)(pCppArgs[nPos]));
+#endif
+ INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_FLOAT:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "a float is %f\n", *(float*)(pCppArgs[nPos]));
+ fprintf(stderr, "b float is %f\n", *(double*)(pCppArgs[nPos]));
+#endif
+ INSERT_FLOAT( pCppArgs[nPos], nFPR, pFPR, nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_DOUBLE:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "double is %f\n", *(double*)(pCppArgs[nPos]));
+#endif
+ INSERT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, nGPR, pGPR, pStack, bOverFlow );
+ break;
+ default:
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+
+ }
+ else // ptr to complex value | ref
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex type again %d\n", rParam.bIn);
+#endif
+ if (! rParam.bIn) // is pure out
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex size is %d\n", pParamTypeDescr->nSize );
+#endif
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "this one\n");
+#endif
+ uno_copyAndConvertData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "that one, passing %lx through\n", pUnoArgs[nPos]);
+#endif
+ pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack, bOverFlow );
+ }
+ }
+
+ try
+ {
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr, bSimpleReturn,
+ pStackStart, ( pStack - pStackStart ),
+ pGPR, nGPR,
+ pFPR, nFPR );
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions,
+ *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy *> (pUnoI);
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; //get then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/call.s b/bridges/source/cpp_uno/gcc3_linux_intel/call.s
new file mode 100644
index 000000000000..45d7c5308d30
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/call.s
@@ -0,0 +1,274 @@
+ .text
+
+.globl privateSnippetExecutorGeneral
+ .type privateSnippetExecutorGeneral,@function
+privateSnippetExecutorGeneral:
+.LFBg:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+.LCFIg0:
+ movl %esp,%ebp
+.LCFIg1:
+ subl $0x8,%esp # 32bit returnValue, and preserve potential 128bit
+ # stack alignment
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call cpp_vtable_call
+ movl 16(%esp),%eax # 32bit returnValue
+ leave
+ ret
+.LFEg:
+ .size privateSnippetExecutorGeneral,.-privateSnippetExecutorGeneral
+
+.globl privateSnippetExecutorVoid
+ .type privateSnippetExecutorVoid,@function
+privateSnippetExecutorVoid:
+.LFBv:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+.LCFIv0:
+ movl %esp,%ebp
+.LCFIv1:
+ andl $0xFFFFFFF0,%esp # preserve potential 128bit stack alignment
+ pushl $0 # 32bit null pointer (returnValue not used)
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call cpp_vtable_call
+ leave
+ ret
+.LFEv:
+ .size privateSnippetExecutorVoid,.-privateSnippetExecutorVoid
+
+.globl privateSnippetExecutorHyper
+ .type privateSnippetExecutorHyper,@function
+privateSnippetExecutorHyper:
+.LFBh:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+.LCFIh0:
+ movl %esp,%ebp
+.LCFIh1:
+ subl $0x8,%esp # 64bit returnValue (preserves potential 128bit
+ # stack alignment)
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call cpp_vtable_call
+ movl 16(%esp),%eax # 64bit returnValue, lower half
+ movl 20(%esp),%edx # 64bit returnValue, upper half
+ leave
+ ret
+.LFEh:
+ .size privateSnippetExecutorHyper,.-privateSnippetExecutorHyper
+
+.globl privateSnippetExecutorFloat
+ .type privateSnippetExecutorFloat,@function
+privateSnippetExecutorFloat:
+.LFBf:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+.LCFIf0:
+ movl %esp,%ebp
+.LCFIf1:
+ subl $0x8,%esp # 32bit returnValue, and preserve potential 128bit
+ # stack alignment
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call cpp_vtable_call
+ flds 16(%esp) # 32bit returnValue
+ leave
+ ret
+.LFEf:
+ .size privateSnippetExecutorFloat,.-privateSnippetExecutorFloat
+
+.globl privateSnippetExecutorDouble
+ .type privateSnippetExecutorDouble,@function
+privateSnippetExecutorDouble:
+.LFBd:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+.LCFId0:
+ movl %esp,%ebp
+.LCFId1:
+ subl $0x8,%esp # 64bit returnValue (preserves potential 128bit
+ # stack alignment)
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call cpp_vtable_call
+ fldl 16(%esp) # 64bit returnValue
+ leave
+ ret
+.LFEd:
+ .size privateSnippetExecutorDouble,.-privateSnippetExecutorDouble
+
+.globl privateSnippetExecutorClass
+ .type privateSnippetExecutorClass,@function
+privateSnippetExecutorClass:
+.LFBc:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+.LCFIc0:
+ movl %esp,%ebp
+.LCFIc1:
+ subl $0x8,%esp # 32bit returnValue, and preserve potential 128bit
+ # stack alignment
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call cpp_vtable_call
+ movl 16(%esp),%eax # 32bit returnValue
+ leave
+ ret $4
+.LFEc:
+ .size privateSnippetExecutorClass,.-privateSnippetExecutorClass
+
+ .section .eh_frame,"a",@progbits
+.Lframe1:
+ .long .LECIE1-.LSCIE1 # length
+.LSCIE1:
+ .long 0 # CIE_ID
+ .byte 1 # version
+ .string "zR" # augmentation
+ .uleb128 1 # code_alignment_factor
+ .sleb128 -4 # data_alignment_factor
+ .byte 8 # return_address_register
+ .uleb128 1 # augmentation size 1:
+ .byte 0x1B # FDE Encoding (pcrel sdata4)
+ # initial_instructions:
+ .byte 0x0C # DW_CFA_def_cfa %esp, 4
+ .uleb128 4
+ .uleb128 4
+ .byte 0x88 # DW_CFA_offset ret, 1
+ .uleb128 1
+ .align 4
+.LECIE1:
+.LSFDEg:
+ .long .LEFDEg-.LASFDEg # length
+.LASFDEg:
+ .long .LASFDEg-.Lframe1 # CIE_pointer
+ .long .LFBg-. # initial_location
+ .long .LFEg-.LFBg # address_range
+ .uleb128 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIg0-.LFBg
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .uleb128 8
+ .byte 0x85 # DW_CFA_offset %ebp, 2
+ .uleb128 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIg1-.LCFIg0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .uleb128 5
+ .align 4
+.LEFDEg:
+.LSFDEv:
+ .long .LEFDEv-.LASFDEv # length
+.LASFDEv:
+ .long .LASFDEv-.Lframe1 # CIE_pointer
+ .long .LFBv-. # initial_location
+ .long .LFEv-.LFBv # address_range
+ .uleb128 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIv0-.LFBv
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .uleb128 8
+ .byte 0x85 # DW_CFA_offset %ebp, 2
+ .uleb128 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIv1-.LCFIv0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .uleb128 5
+ .align 4
+.LEFDEv:
+.LSFDEh:
+ .long .LEFDEh-.LASFDEh # length
+.LASFDEh:
+ .long .LASFDEh-.Lframe1 # CIE_pointer
+ .long .LFBh-. # initial_location
+ .long .LFEh-.LFBh # address_range
+ .uleb128 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIh0-.LFBh
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .uleb128 8
+ .byte 0x85 # DW_CFA_offset %ebp, 2
+ .uleb128 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIh1-.LCFIh0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .uleb128 5
+ .align 4
+.LEFDEh:
+.LSFDEf:
+ .long .LEFDEf-.LASFDEf # length
+.LASFDEf:
+ .long .LASFDEf-.Lframe1 # CIE_pointer
+ .long .LFBf-. # initial_location
+ .long .LFEf-.LFBf # address_range
+ .uleb128 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIf0-.LFBf
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .uleb128 8
+ .byte 0x85 # DW_CFA_offset %ebp, 2
+ .uleb128 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIf1-.LCFIf0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .uleb128 5
+ .align 4
+.LEFDEf:
+.LSFDEd:
+ .long .LEFDEd-.LASFDEd # length
+.LASFDEd:
+ .long .LASFDEd-.Lframe1 # CIE_pointer
+ .long .LFBd-. # initial_location
+ .long .LFEd-.LFBd # address_range
+ .uleb128 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFId0-.LFBd
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .uleb128 8
+ .byte 0x85 # DW_CFA_offset %ebp, 2
+ .uleb128 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFId1-.LCFId0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .uleb128 5
+ .align 4
+.LEFDEd:
+.LSFDEc:
+ .long .LEFDEc-.LASFDEc # length
+.LASFDEc:
+ .long .LASFDEc-.Lframe1 # CIE_pointer
+ .long .LFBc-. # initial_location
+ .long .LFEc-.LFBc # address_range
+ .uleb128 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIc0-.LFBc
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .uleb128 8
+ .byte 0x85 # DW_CFA_offset %ebp, 2
+ .uleb128 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIc1-.LCFIc0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .uleb128 5
+ .align 4
+.LEFDEc:
+ .section .note.GNU-stack,"",@progbits
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx
new file mode 100644
index 000000000000..ccc31f10a407
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/cpp2uno.cxx
@@ -0,0 +1,527 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "share.hxx"
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+void cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** pCallStack,
+ void * pReturnValue )
+{
+ // pCallStack: ret, [return ptr], this, params
+ char * pCppStack = (char *)(pCallStack +1);
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if (pReturnTypeDescr)
+ {
+ if (x86::isSimpleReturnType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pReturnValue; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)pCppStack;
+ pCppStack += sizeof(void *);
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ // value
+ {
+ pCppArgs[nPos] = pCppStack;
+ pUnoArgs[nPos] = pCppStack;
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ break;
+ default:
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ pCppArgs[nPos] = *(void **)pCppStack;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException(
+ &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to eax
+ *static_cast< void ** >(pReturnValue) = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+ }
+}
+
+
+//==================================================================================================
+extern "C" void cpp_vtable_call(
+ int nFunctionIndex, int nVtableOffset, void** pCallStack,
+ void * pReturnValue )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: ret adr, [ret *], this, params
+ void * pThis;
+ if( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = pCallStack[2];
+ }
+ else
+ {
+ pThis = pCallStack[1];
+ }
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pThis );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pReturnValue );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pReturnValue );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[3] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pCallStack[1] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *static_cast< void ** >(pReturnValue) = pCallStack[1];
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pReturnValue );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pThis );
+ }
+ }
+}
+
+//==================================================================================================
+extern "C" void privateSnippetExecutorGeneral();
+extern "C" void privateSnippetExecutorVoid();
+extern "C" void privateSnippetExecutorHyper();
+extern "C" void privateSnippetExecutorFloat();
+extern "C" void privateSnippetExecutorDouble();
+extern "C" void privateSnippetExecutorClass();
+extern "C" typedef void (*PrivateSnippetExecutor)();
+
+int const codeSnippetSize = 16;
+
+#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX)
+namespace
+{
+ PrivateSnippetExecutor returnsInRegister(typelib_TypeDescriptionReference * pReturnTypeRef)
+ {
+ //These archs apparently are returning small structs in registers, while Linux
+ //doesn't
+ PrivateSnippetExecutor exec=NULL;
+
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ const bool bSimpleReturnStruct = x86::isSimpleReturnType(pReturnTypeDescr);
+ const sal_Int32 nRetSize = pReturnTypeDescr->nSize;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ if (bSimpleReturnStruct)
+ {
+ exec = privateSnippetExecutorGeneral; // fills eax
+ if (nRetSize > 4)
+ exec = privateSnippetExecutorHyper; // fills eax/edx
+ }
+ return exec;
+ }
+}
+#endif
+
+unsigned char * codeSnippet(
+ unsigned char * code, sal_PtrDiff writetoexecdiff, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ typelib_TypeDescriptionReference * pReturnTypeRef)
+{
+ PrivateSnippetExecutor exec;
+ typelib_TypeClass eReturnClass = pReturnTypeRef ? pReturnTypeRef->eTypeClass : typelib_TypeClass_VOID;
+ switch (eReturnClass)
+ {
+ case typelib_TypeClass_VOID:
+ exec = privateSnippetExecutorVoid;
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ exec = privateSnippetExecutorHyper;
+ break;
+ case typelib_TypeClass_FLOAT:
+ exec = privateSnippetExecutorFloat;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ exec = privateSnippetExecutorDouble;
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX)
+ exec = returnsInRegister(pReturnTypeRef);
+ if (!exec)
+ {
+ exec = privateSnippetExecutorClass;
+ functionIndex |= 0x80000000;
+ }
+ break;
+#endif
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_INTERFACE:
+ exec = privateSnippetExecutorClass;
+ functionIndex |= 0x80000000;
+ break;
+ default:
+ exec = privateSnippetExecutorGeneral;
+ break;
+ }
+ unsigned char * p = code;
+ OSL_ASSERT(sizeof (sal_Int32) == 4);
+ // mov function_index, %eax:
+ *p++ = 0xB8;
+ *reinterpret_cast< sal_Int32 * >(p) = functionIndex;
+ p += sizeof (sal_Int32);
+ // mov vtable_offset, %edx:
+ *p++ = 0xBA;
+ *reinterpret_cast< sal_Int32 * >(p) = vtableOffset;
+ p += sizeof (sal_Int32);
+ // jmp privateSnippetExecutor:
+ *p++ = 0xE9;
+ *reinterpret_cast< sal_Int32 * >(p)
+ = ((unsigned char *) exec) - p - sizeof (sal_Int32) - writetoexecdiff;
+ p += sizeof (sal_Int32);
+ OSL_ASSERT(p - code <= codeSnippetSize);
+ return code + codeSnippetSize;
+}
+
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block) {
+ return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0;
+ slots[-1].fn = 0;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, writetoexecdiff, functionOffset++, vtableOffset,
+ reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef);
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, writetoexecdiff, functionOffset++, vtableOffset,
+ NULL);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, writetoexecdiff, functionOffset++, vtableOffset,
+ reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef);
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const *, unsigned char const *)
+{}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx
new file mode 100644
index 000000000000..69785be506f1
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx
@@ -0,0 +1,340 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * )
+{
+}
+
+//==================================================================================================
+static OUString toUNOname( char const * p ) SAL_THROW( () )
+{
+#if OSL_DEBUG_LEVEL > 1
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+}
+
+//==================================================================================================
+class RTTI
+{
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+#if defined(FREEBSD) && __FreeBSD_version < 702104
+ : m_hApp( dlopen( 0, RTLD_NOW | RTLD_GLOBAL ) )
+#else
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+#endif
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+{
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iRttiFind( m_rttis.find( unoName ) );
+ if (iRttiFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+#if defined(FREEBSD) && __FreeBSD_version < 702104 /* #i22253# */
+ rtti = (type_info *)dlsym( RTLD_DEFAULT, symName.getStr() );
+#else
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+#endif
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
+ if (iFind == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with _ZTI
+ char const * rttiName = symName.getStr() +4;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iFind->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iRttiFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void deleteException( void * pExc )
+{
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() );
+#endif
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get typedescription for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+{
+ if (! header)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_intel/makefile.mk
new file mode 100644
index 000000000000..6e2b7529247f
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/makefile.mk
@@ -0,0 +1,84 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCLINUXIgcc3" || \
+ "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCOPENBSDIgcc3" || \
+ "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCFREEBSDIgcc3" || \
+ "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCNETBSDIgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer -fno-strict-aliasing
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/call.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.s
+ $(CC) -c -o $(SLO)$/$(@:b).o $<
+ touch $@
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx b/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx
new file mode 100644
index 000000000000..8a3e136bfb7b
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/share.hxx
@@ -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.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * );
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+
+}
+
+namespace x86
+{
+ bool isSimpleReturnType(typelib_TypeDescription * pTD, bool recursive = false);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx
new file mode 100644
index 000000000000..777d4b553db3
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_intel/uno2cpp.cxx
@@ -0,0 +1,507 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD)
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "share.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+// The call instruction within the asm section of callVirtualMethod may throw
+// exceptions. So that the compiler handles this correctly, it is important
+// that (a) callVirtualMethod might call dummy_can_throw_anything (although this
+// never happens at runtime), which in turn can throw exceptions, and (b)
+// callVirtualMethod is not inlined at its call site (so that any exceptions are
+// caught which are thrown from the instruction calling callVirtualMethod):
+void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs ) __attribute__((noinline));
+
+void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs )
+{
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ OSL_ENSURE( pStackLongs && pAdjustedThisPtr, "### null ptr!" );
+ OSL_ENSURE( (sizeof(void *) == 4) && (sizeof(sal_Int32) == 4), "### unexpected size of int!" );
+ OSL_ENSURE( nStackLongs && pStackLongs, "### no stack in callVirtualMethod !" );
+
+ // never called
+ if (! pAdjustedThisPtr) CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
+
+ volatile long edx = 0, eax = 0; // for register returns
+ void * stackptr;
+ asm volatile (
+ "mov %%esp, %6\n\t"
+ // preserve potential 128bit stack alignment
+ "and $0xfffffff0, %%esp\n\t"
+ "mov %0, %%eax\n\t"
+ "lea -4(,%%eax,4), %%eax\n\t"
+ "and $0xf, %%eax\n\t"
+ "sub $0xc, %%eax\n\t"
+ "add %%eax, %%esp\n\t"
+ // copy values
+ "mov %0, %%eax\n\t"
+ "mov %%eax, %%edx\n\t"
+ "dec %%edx\n\t"
+ "shl $2, %%edx\n\t"
+ "add %1, %%edx\n"
+ "Lcopy:\n\t"
+ "pushl 0(%%edx)\n\t"
+ "sub $4, %%edx\n\t"
+ "dec %%eax\n\t"
+ "jne Lcopy\n\t"
+ // do the actual call
+ "mov %2, %%edx\n\t"
+ "mov 0(%%edx), %%edx\n\t"
+ "mov %3, %%eax\n\t"
+ "shl $2, %%eax\n\t"
+ "add %%eax, %%edx\n\t"
+ "mov 0(%%edx), %%edx\n\t"
+ "call *%%edx\n\t"
+ // save return registers
+ "mov %%eax, %4\n\t"
+ "mov %%edx, %5\n\t"
+ // cleanup stack
+ "mov %6, %%esp\n\t"
+ :
+ : "m"(nStackLongs), "m"(pStackLongs), "m"(pAdjustedThisPtr),
+ "m"(nVtableIndex), "m"(eax), "m"(edx), "m"(stackptr)
+ : "eax", "edx" );
+ switch( pReturnTypeDescr->eTypeClass )
+ {
+ case typelib_TypeClass_VOID:
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ ((long*)pRegisterReturn)[1] = edx;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_ENUM:
+ ((long*)pRegisterReturn)[0] = eax;
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = eax;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = eax;
+ break;
+ case typelib_TypeClass_FLOAT:
+ asm ( "fstps %0" : : "m"(*(char *)pRegisterReturn) );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ asm ( "fstpl %0\n\t" : : "m"(*(char *)pRegisterReturn) );
+ break;
+ default:
+ {
+#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX)
+ sal_Int32 const nRetSize = pReturnTypeDescr->nSize;
+ if (bSimpleReturn && nRetSize <= 8 && nRetSize > 0)
+ {
+ if (nRetSize > 4)
+ static_cast<long *>(pRegisterReturn)[1] = edx;
+ static_cast<long *>(pRegisterReturn)[0] = eax;
+ }
+#else
+ (void)bSimpleReturn;
+#endif
+ break;
+ }
+ }
+}
+
+//==================================================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ char * pCppStack =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ char * pCppStackStart = pCppStack;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+ bool bSimpleReturn = true;
+
+ if (pReturnTypeDescr)
+ {
+ bSimpleReturn = x86::isSimpleReturnType(pReturnTypeDescr);
+ if (bSimpleReturn)
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack
+ = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ pCppStack += sizeof(void *);
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ break;
+ default:
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ try
+ {
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr, bSimpleReturn,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+namespace x86
+{
+ bool isSimpleReturnType(typelib_TypeDescription * pTD, bool recursive)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pTD ))
+ return true;
+#if defined (FREEBSD) || defined(NETBSD) || defined(OPENBSD) || defined(MACOSX)
+ // Only structs of exactly 1, 2, 4, or 8 bytes are returned through
+ // registers, see <http://developer.apple.com/documentation/DeveloperTools/
+ // Conceptual/LowLevelABI/Articles/IA32.html>:
+ if (pTD->eTypeClass == typelib_TypeClass_STRUCT &&
+ (recursive || pTD->nSize <= 2 || pTD->nSize == 4 || pTD->nSize == 8))
+ {
+ typelib_CompoundTypeDescription *const pCompTD =
+ (typelib_CompoundTypeDescription *) pTD;
+ for ( sal_Int32 pos = pCompTD->nMembers; pos--; ) {
+ typelib_TypeDescription * pMemberTD = 0;
+ TYPELIB_DANGER_GET( &pMemberTD, pCompTD->ppTypeRefs[pos] );
+ bool const b = isSimpleReturnType(pMemberTD, true);
+ TYPELIB_DANGER_RELEASE( pMemberTD );
+ if (! b)
+ return false;
+ }
+ return true;
+ }
+#else
+ (void)recursive;
+#endif
+ return false;
+ }
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; // get, then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_m68k/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_m68k/cpp2uno.cxx
new file mode 100644
index 000000000000..53542e23f97d
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_m68k/cpp2uno.cxx
@@ -0,0 +1,537 @@
+/* -*- 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 <malloc.h>
+#include <hash_map>
+
+#include <rtl/alloc.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "share.hxx"
+
+#include <dlfcn.h>
+
+
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+ static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ long r8, void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+ {
+ // pCallStack: ret, [return ptr], this, params
+ char * pTopStack = (char *)(pCallStack + 0);
+ char * pCppStack = pTopStack;
+#ifdef CMC_DEBUG
+ fprintf(stderr, "cpp2uno_call\n");
+#endif
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+ void * pCppReturn = 0;
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "simple return\n");
+#endif
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex return\n");
+#endif
+ pCppReturn = (void *)r8;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32),
+ "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion
+ // cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr =
+ (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut &&
+ bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_BOOLEAN:
+ pCppArgs[nPos] = pCppStack + 3;
+ pUnoArgs[nPos] = pCppStack + 3;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ pCppArgs[nPos] = pCppStack + 2;
+ pUnoArgs[nPos] = pCppStack + 2;
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppArgs[nPos] = pCppStack;
+ pUnoArgs[nPos] = pCppStack;
+ pCppStack += sizeof(sal_Int32); // extra long
+ break;
+ default:
+ pCppArgs[nPos] = pCppStack;
+ pUnoArgs[nPos] = pCppStack;
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ pCppArgs[nPos] = *(void **)pCppStack;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "before dispatch\n");
+#endif
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "after dispatch\n");
+#endif
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex],
+ ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc,
+ pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr =
+ ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr,
+ cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex],
+ pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn,
+ pReturnTypeDescr, pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet =
+ (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+ }
+
+
+ //=====================================================================
+ static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+ long sp, long r8,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+ {
+ void ** pCallStack = (void**)(sp);
+#ifdef CMC_DEBUG
+ fprintf(stderr, "cpp_mediate with\n");
+ fprintf(stderr, "%x %x\n", nFunctionIndex, nVtableOffset);
+ fprintf(stderr, "and %x %x\n", pCallStack, pRegisterReturn);
+ fprintf(stderr, "and %x %x\n", pCallStack[0], pCallStack[1]);
+#endif
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ void *pThis = pCallStack[0];
+
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
+ bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex,
+ "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pCppI );
+ }
+
+ // determine called method
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex,
+ "### illegal vtable index!" );
+ sal_Int32 nMemberPos =
+ pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers,
+ "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] ==
+ nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ r8, pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ r8, pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET(&pTD,
+ reinterpret_cast<Type *>(pCallStack[1])->getTypeLibType());
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( r8 ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = (void*)r8;
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ r8, pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ OUString::createFromAscii("no member description found!"),
+ (XInterface *)pCppI );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+ }
+}
+
+//=======================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+
+extern "C" sal_Int64 cpp_vtable_call( long firstonstack )
+{
+ register long d0 asm("d0");
+ long functionIndex = d0;
+
+ register long a1 asm("a1");
+ long r8 = a1;
+
+ register long d1 asm("d1");
+ long vtableOffset = d1;
+
+ long sp = (long)&firstonstack;
+
+ sal_Int64 nRegReturn;
+ cpp_mediate( functionIndex, vtableOffset, sp, r8, &nRegReturn );
+ return nRegReturn;
+}
+
+namespace
+{
+ const int codeSnippetSize = 20;
+
+ //some m68k info : http://www2.biglobe.ne.jp/~inaba/trampolines.html
+
+ unsigned char *codeSnippet(unsigned char* code, sal_Int32 functionIndex,
+ sal_Int32 vtableOffset)
+ {
+ unsigned char * p = code;
+ *(short *)&p[0] = 0x203C; //movel functionIndex,d0
+ *(long *)&p[2] = functionIndex;
+ *(short *)&p[6] = 0x223C; //movel functionIndex,d1
+ *(long *)&p[8] = vtableOffset;
+ *(short *)&p[12] = 0x4EF9; //jmp cpp_vtable_call
+ *(long *)&p[14] = (long)&cpp_vtable_call;
+ *(short *)&p[18] = 0x4E71; //nop
+ return code + codeSnippetSize;
+ }
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0;
+ slots[-1].fn = 0;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for (sal_Int32 i = 0; i < type->nMembers; ++i)
+ {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset);
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset);
+ }
+ break;
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ (s++)->fn = code + writetoexecdiff;
+
+ typelib_InterfaceMethodTypeDescription *pMethodTD =
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(member);
+
+ bool issimple = bridges::cpp_uno::shared::isSimpleType(
+ pMethodTD->pReturnTypeRef);
+
+ code = codeSnippet(code, functionOffset++, vtableOffset);
+ break;
+ }
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const * /*beg*/, unsigned char const * /*end*/)
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_m68k/except.cxx b/bridges/source/cpp_uno/gcc3_linux_m68k/except.cxx
new file mode 100644
index 000000000000..36fe7968e19a
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_m68k/except.cxx
@@ -0,0 +1,335 @@
+/* -*- 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 <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+extern sal_Int32 * pHack;
+extern sal_Int32 nHack;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+ void dummy_can_throw_anything( char const * )
+ {
+ }
+
+ //===================================================================
+ static OUString toUNOname( char const * p ) SAL_THROW( () )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+ }
+
+ //=====================================================================
+ class RTTI
+ {
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+ public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI(typelib_CompoundTypeDescription *) SAL_THROW( () );
+ };
+ //____________________________________________________________________
+ RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+ {
+ }
+ //____________________________________________________________________
+ RTTI::~RTTI() SAL_THROW( () )
+ {
+ dlclose( m_hApp );
+ }
+
+ //____________________________________________________________________
+ type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+ {
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iRttiFind( m_rttis.find( unoName ) );
+ if (iRttiFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
+ if (iFind == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with _ZTI
+ char const * rttiName = symName.getStr() +4;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iFind->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iRttiFind->second;
+ }
+
+ return rtti;
+ }
+
+ //------------------------------------------------------------------
+ static void deleteException( void * pExc )
+ {
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+ }
+
+ //==================================================================
+ void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+ {
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() );
+#endif
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get typedescription for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+ }
+
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+ }
+
+ static void* getAdjustedPtr(__cxa_exception* header)
+ {
+ return header->adjustedPtr;
+ }
+
+ //===================================================================
+ void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+ {
+ if (! header)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, getAdjustedPtr(header), pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_m68k/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_m68k/makefile.mk
new file mode 100644
index 000000000000..3978bda7cb16
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_m68k/makefile.mk
@@ -0,0 +1,80 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+NO_BSYMBOLIC=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCLINUX6gcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+CFLAGSCXX += -fno-omit-frame-pointer -fno-strict-aliasing
+
+NOOPTFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/uno2cpp.obj
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/bridges/source/cpp_uno/gcc3_linux_m68k/share.hxx b/bridges/source/cpp_uno/gcc3_linux_m68k/share.hxx
new file mode 100644
index 000000000000..4ec09c29ff0a
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_m68k/share.hxx
@@ -0,0 +1,94 @@
+/* -*- 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 "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+ void dummy_can_throw_anything( char const * );
+
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_m68k/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_m68k/uno2cpp.cxx
new file mode 100644
index 000000000000..97a9ab0187d9
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_m68k/uno2cpp.cxx
@@ -0,0 +1,494 @@
+/* -*- 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 <malloc.h>
+#include <rtl/alloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+
+#include <bridges/cpp_uno/shared/bridge.hxx>
+#include <bridges/cpp_uno/shared/types.hxx>
+#include <bridges/cpp_uno/shared/unointerfaceproxy.hxx>
+#include <bridges/cpp_uno/shared/vtables.hxx>
+
+#include "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+void MapReturn(long d0, long d1, typelib_TypeClass eReturnType, long *pRegisterReturn)
+{
+ register float fret asm("fp0");
+ register double dret asm("fp0");
+
+ switch( eReturnType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ pRegisterReturn[1] = d1;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ pRegisterReturn[0] = d0;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float*)pRegisterReturn = fret;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double*)pRegisterReturn = dret;
+ break;
+ default:
+ break;
+ }
+}
+
+namespace
+{
+//================================================================
+
+void callVirtualMethod(
+ void * pThis,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_uInt32 *pStack,
+ sal_uInt32 nStack) __attribute__((noinline));
+
+void callVirtualMethod(
+ void * pThis,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_uInt32 *pStack,
+ sal_uInt32 nStack)
+{
+ // never called
+ if (! pThis)
+ CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
+
+ if ( nStack )
+ {
+ // m68k stack is either 2 or 4 bytes aligned, doesn't really matter as
+ // we deal in 4 byte units anyway
+ sal_uInt32 nStackBytes = nStack * sizeof(sal_uInt32);
+ sal_uInt32 *stack = (sal_uInt32 *) __builtin_alloca( nStackBytes );
+ memcpy( stack, pStack, nStackBytes );
+ }
+
+#ifdef CMC_DEBUG
+ // Let's figure out what is really going on here
+ {
+ fprintf( stderr, "\nStack (%d): ", nStack );
+ for ( unsigned int i = 0; i < nStack; ++i )
+ fprintf( stderr, "0x%lx, ", pStack[i] );
+ fprintf( stderr, "\n" );
+ fprintf( stderr, "pRegisterReturn is %p\n", pRegisterReturn);
+ }
+#endif
+
+ sal_uInt32 pMethod = *((sal_uInt32*)pThis);
+ pMethod += 4 * nVtableIndex;
+ pMethod = *((sal_uInt32 *)pMethod);
+
+ typedef long (*FunctionCall )();
+ FunctionCall pFunc = (FunctionCall)pMethod;
+
+ //stick the return area into r8 for big struct returning
+ asm volatile("movel %0,%%a1" : : "m"(pRegisterReturn) : );
+
+ long d0 = (*pFunc)();
+
+ register long d1 asm("d1");
+
+ MapReturn(d0, d1, eReturnType, (long*)pRegisterReturn);
+}
+}
+
+#define INSERT_INT32( pSV, pDS )\
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#define INSERT_INT64( pSV, pDS )\
+ INSERT_INT32( pSV, pDS ) \
+ INSERT_INT32( ((sal_uInt32*)pSV)+1, pDS )
+
+#define INSERT_FLOAT( pSV, pDS ) \
+ INSERT_INT32( pSV, pDS )
+
+#define INSERT_DOUBLE( pSV, pDS ) \
+ INSERT_INT64( pSV, pDS )
+
+#define INSERT_INT16( pSV, pDS ) \
+ *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, pDS ) \
+ *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+
+namespace {
+//=======================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+
+ // max space for: [complex ret ptr], values|ptr ...
+ sal_uInt32 * pStack = (sal_uInt32 *)__builtin_alloca(
+ sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ sal_uInt32 * pStackStart = pStack;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? __builtin_alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+
+// INSERT_INT32( &pCppReturn, pStack );
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ INSERT_INT32( &pAdjustedThisPtr, pStack );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+// uno_copyAndConvertData( pCppArgs[nPos] = pStack, pUnoArgs[nPos],
+ uno_copyAndConvertData( pCppArgs[nPos] = alloca(8), pUnoArgs[nPos],
+ pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "hyper is %lx\n", pCppArgs[nPos]);
+#endif
+ INSERT_INT64( pCppArgs[nPos], pStack );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "long is %x\n", pCppArgs[nPos]);
+#endif
+ INSERT_INT32( pCppArgs[nPos], pStack );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ INSERT_INT16( pCppArgs[nPos], pStack );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ INSERT_INT8( pCppArgs[nPos], pStack );
+ break;
+ case typelib_TypeClass_FLOAT:
+ INSERT_FLOAT( pCppArgs[nPos], pStack );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ INSERT_DOUBLE( pCppArgs[nPos], pStack );
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ INSERT_INT32( &(pCppArgs[nPos]), pStack );
+ }
+ }
+
+ try
+ {
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass,
+ pStackStart,
+ (pStack - pStackStart));
+
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<typelib_InterfaceAttributeTypeDescription const *>
+ (pMemberDescr)));
+
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1;
+ cpp_call(
+ pThis, aVtableSlot, // get, then set method
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<typelib_InterfaceMethodTypeDescription const *>
+ (pMemberDescr)));
+
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)(
+ pThis->getBridge()->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_mips/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_mips/cpp2uno.cxx
new file mode 100644
index 000000000000..b6fd1d461cfd
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_mips/cpp2uno.cxx
@@ -0,0 +1,805 @@
+/* -*- 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 <com/sun/star/uno/genfunc.hxx>
+#include <typelib/typedescription.hxx>
+#include <uno/data.h>
+#include <osl/endian.h>
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+#include "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+using namespace com::sun::star::uno;
+
+//#define BRDEBUG
+
+#ifdef BRDEBUG
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+#endif
+#include <sys/sysmips.h>
+
+#ifdef OSL_BIGENDIAN
+#define IS_BIG_ENDIAN 1
+#else
+#define IS_BIG_ENDIAN 0
+#endif
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+ //==================================================================================================
+ static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** gpreg, void ** /*fpreg*/, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+ {
+ /* Most MIPS ABIs view the arguments as a struct, of which the
+ first N words go in registers and the rest go on the stack. If I < N, the
+ Ith word might go in Ith integer argument register or the Ith
+ floating-point one. For these ABIs, we only need to remember the number
+ of words passed so far. We are interested only in o32 ABI,so it is the
+ case.
+ */
+ int nw = 0; // number of words used by arguments
+
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call1\n");
+#endif
+
+ /* C++ has [ret *] or this as the first arguments, so no arguments will
+ * be passed in floating-point registers?
+ */
+ //int int_seen = 0; // have we seen integer arguments?
+
+ void ** pCppStack; //temporary stack pointer
+
+ // gpreg: [ret *], this, [gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:simplereturn\n");
+#endif
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)gpreg;
+ gpreg++;
+ nw++;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:complexreturn\n");
+#endif
+ }
+ }
+
+ // pop this
+ gpreg++;
+ nw++;
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:nParams=%d\n",nParams);
+#endif
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ // value
+ {
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_DOUBLE:
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:hyper=%d,%p\n",pParamTypeDescr->eTypeClass,gpreg[0]);
+#endif
+ if (nw < 3) {
+ if (nw & 1) {
+ nw++;
+ gpreg++;
+ }
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:gpreg=%p,%p\n",gpreg[0],gpreg[1]);
+#endif
+ pCppArgs[nPos] = gpreg;
+ pUnoArgs[nPos] = gpreg;
+ nw += 2;
+ gpreg += 2;
+ } else {
+ if (((long)ovrflw) & 4) ovrflw++;
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:overflw=%p,%p\n",ovrflw[0],ovrflw[1]);
+#endif
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw += 2;
+ }
+ break;
+
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_BOOLEAN:
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:byte=%p,%p\n",gpreg[0],ovrflw[0]);
+#endif
+ if (nw < 4) {
+ pCppArgs[nPos] = ((char *)gpreg + 3*IS_BIG_ENDIAN);
+ pUnoArgs[nPos] = ((char *)gpreg + 3*IS_BIG_ENDIAN);
+ nw++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = ((char *)ovrflw + 3*IS_BIG_ENDIAN);
+ pUnoArgs[nPos] = ((char *)ovrflw + 3*IS_BIG_ENDIAN);
+ ovrflw++;
+ }
+ break;
+
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:char=%p,%p\n",gpreg[0],ovrflw[0]);
+#endif
+ if (nw < 4) {
+ pCppArgs[nPos] = ((char *)gpreg + 2*IS_BIG_ENDIAN);
+ pUnoArgs[nPos] = ((char *)gpreg + 2*IS_BIG_ENDIAN);
+ nw++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = ((char *)ovrflw + 2*IS_BIG_ENDIAN);
+ pUnoArgs[nPos] = ((char *)ovrflw + 2*IS_BIG_ENDIAN);
+ ovrflw++;
+ }
+ break;
+
+
+ default:
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:def=%p,%p\n",gpreg[0],ovrflw[0]);
+#endif
+ if (nw < 4) {
+ pCppArgs[nPos] = gpreg;
+ pUnoArgs[nPos] = gpreg;
+ nw++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw++;
+ }
+ break;
+
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:ptr|ref\n");
+#endif
+ if (nw < 4) {
+ pCppArgs[nPos] = *(void **)gpreg;
+ pCppStack = gpreg;
+ nw++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = *(void **)ovrflw;
+ pCppStack = ovrflw;
+ ovrflw++;
+ }
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:pCppStack=%p\n",pCppStack);
+#endif
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:related to interface,%p,%d,pUnoargs[%d]=%p\n",*(void**)pCppStack,pParamTypeDescr->nSize,nPos,pUnoArgs[nPos]);
+#endif
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call:direct,pUnoArgs[%d]=%p\n",nPos,pUnoArgs[nPos]);
+#endif
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call2,%p,unoargs=%p\n",pThis->getUnoI()->pDispatcher,pUnoArgs);
+#endif
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp2uno_call2,after dispatch\n");
+#endif
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+ }
+
+
+ //==================================================================================================
+ static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+ {
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate1 gp=%p,fp=%p,ov=%p\n",gpreg,fpreg,ovrflw);
+ fprintf(stderr,"gp=%x,%x,%x,%x\n",gpreg[0],gpreg[1],gpreg[2],gpreg[3]);
+#endif
+
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ void * pThis;
+ if (nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = gpreg[1];
+ }
+ else
+ {
+ pThis = gpreg[0];
+ }
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate12,pThis=%p, nFunctionIndex=%d,nVtableOffset=%d\n",pThis,nFunctionIndex,nVtableOffset);
+#endif
+
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate13,pCppI=%p\n",pCppI);
+#endif
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate2\n");
+#endif
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pThis );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate3\n");
+ OString cstr( OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex );
+#endif
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate4\n");
+#endif
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate5\n");
+#endif
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate51\n");
+#endif
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate52\n");
+#endif
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+#ifdef BRDEBUG
+ fprintf(stderr,"cpp_mediate6\n");
+#endif
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+ }
+
+ //==================================================================================================
+ /**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+// static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** fpregptr, void** ovrflw)
+// static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** ovrflw)
+ static void cpp_vtable_call(void)
+ {
+ int nFunctionIndex;
+ int vTableOffset;
+ void** pCallStack;
+ void** ovrflw;
+
+ sal_Int32 gpreg[4];
+ double fpreg[2];
+
+ //memcpy( fpreg, fpregptr, 16);
+
+ volatile long nRegReturn[2];
+
+ __asm__( "sw $4, %0\n\t"
+ "sw $5, %1\n\t"
+ "sw $6, %2\n\t"
+ "sw $7, %3\n\t"
+ ::"m"(nFunctionIndex), "m"(vTableOffset), "m"(pCallStack), "m"(ovrflw) );
+
+ memcpy( gpreg, pCallStack, 16);
+
+#ifdef BRDEBUG
+ fprintf(stderr,"in cpp_vtable_call nFunctionIndex is %d\n",nFunctionIndex);
+ fprintf(stderr,"in cpp_vtable_call nVtableOffset is %d\n",vTableOffset);
+ fprintf(stderr,"gp=%x,%x,%x,%x\n",gpreg[0],gpreg[1],gpreg[2],gpreg[3]);
+#endif
+
+ //sal_Bool bComplex = nFunctionIndex & 0x80000000 ? sal_True : sal_False;
+
+ typelib_TypeClass aType =
+ cpp_mediate( nFunctionIndex, vTableOffset, (void**)gpreg, (void**)fpreg, ovrflw, (sal_Int64*)nRegReturn );
+
+ switch( aType )
+ {
+
+ // move return value into register space
+ // (will be loaded by machine code snippet)
+
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ __asm__( "lbu $2,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ __asm__( "lhu $2,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+
+ case typelib_TypeClass_SHORT:
+ __asm__( "lh $2,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+
+
+ case typelib_TypeClass_FLOAT:
+ __asm__( "lwc1 $f0,%0\n\t" : :
+ "m" (*((float*)nRegReturn)) );
+ break;
+
+ case typelib_TypeClass_DOUBLE:
+ { register double dret asm("$f0");
+ dret = (*((double*)nRegReturn)); }
+ break;
+
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ __asm__( "lw $3,%0\n\t" : :
+ "m"(nRegReturn[1]) ); // fall through
+
+ default:
+ __asm__( "lw $2,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+ }
+ }
+
+
+ int const codeSnippetSize = 56;
+
+ unsigned char * codeSnippet( unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ bool simpleRetType)
+ {
+
+#ifdef BRDEBUG
+ fprintf(stderr,"in codeSnippet functionIndex is %d\n", functionIndex);
+ fprintf(stderr,"in codeSnippet vtableOffset is %d\n", vtableOffset);
+ fflush(stderr);
+#endif
+
+ if (! simpleRetType )
+ functionIndex |= 0x80000000;
+
+ unsigned long * p = (unsigned long *) code;
+
+ // OSL_ASSERT( sizeof (long) == 4 );
+ OSL_ASSERT((((unsigned long)code) & 0x3) == 0 ); //aligned to 4 otherwise a mistake
+
+ /* generate this code */
+ /*
+ #save regs into argument space required by mips abi
+ c: afa40000 sw a0,0(sp)
+ 10: afa50004 sw a1,4(sp)
+ 14: afa60008 sw a2,8(sp)
+ 18: afa7000c sw a3,12(sp)
+ #a0=index
+ 1c: 3c040000 lui a0,0x0
+ 20: 34840000 ori a0,a0,0x0
+ #a1=offset
+ 24: 3c050000 lui a1,0x0
+ 28: 34a50000 ori a1,a1,0x0
+ #a2=gpregptr
+ 2c: 27a60000 addiu a2,sp,0
+ #a3=ovrflw
+ 30: 27a70010 addiu a3,sp,16
+ #load cpp_vtable_call addr
+ 34: 3c190000 lui t9,0x0
+ 38: 37390000 ori t9,t9,0
+ #jmp to the function,note: we don't use jalr, that will destroy $ra
+ #but be sure to use t9! gp calculation depends on it
+ 3c: 03200008 jr t9
+ 40: 00000000 nop
+
+ be careful, we use the argument space reserved by the caller to
+ write down regs. This can avoid the need to make use of arbitary far away
+ stack space or to allocate a function frame for this code snippet itself.
+ Since only functions with variable arguments will overwrite the space,
+ cpp_vtable_call should be safe.
+ ??? gcc seems change this behavior! cpp_vtable_call overwrite the space!
+ */
+
+ * p++ = 0xafa40000;
+ * p++ = 0xafa50004;
+ * p++ = 0xafa60008;
+ * p++ = 0xafa7000c;
+ * p++ = 0x3c040000 | ((functionIndex>>16) & 0x0000ffff);
+ * p++ = 0x34840000 | (functionIndex & 0x0000ffff);
+ * p++ = 0x3c050000 | ((vtableOffset>>16) & 0x0000ffff);
+ * p++ = 0x34a50000 | (vtableOffset & 0x0000ffff);
+ * p++ = 0x27a60000;
+ * p++ = 0x27a70010;
+ * p++ = 0x3c190000 | ((((unsigned long)cpp_vtable_call) >> 16) & 0x0000ffff);
+ * p++ = 0x37390000 | (((unsigned long)cpp_vtable_call) & 0x0000FFFF);
+ * p++ = 0x03200008;
+ * p++ = 0x00000000;
+ return (code + codeSnippetSize);
+
+ }
+
+
+}
+
+
+#define MIN_LINE_SIZE 32
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * /*bptr*/, unsigned char const * /*eptr*/)
+{
+ sysmips(FLUSH_CACHE,0,0,0);
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0; //null
+ slots[-1].fn = 0; //destructor
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+#ifdef BRDEBUG
+ fprintf(stderr, "in addLocalFunctions functionOffset is %d\n",functionOffset);
+ fprintf(stderr, "in addLocalFunctions vtableOffset is %d\n",vtableOffset);
+ fprintf(stderr, "nMembers=%d\n",type->nMembers);
+ fflush(stderr);
+#endif
+
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_mips/except.cxx b/bridges/source/cpp_uno/gcc3_linux_mips/except.cxx
new file mode 100644
index 000000000000..78d72c0c733b
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_mips/except.cxx
@@ -0,0 +1,327 @@
+/* -*- 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 <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * )
+{
+}
+
+//==================================================================================================
+static OUString toUNOname( char const * p ) SAL_THROW( () )
+{
+#if defined BRIDGES_DEBUG
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if defined BRIDGES_DEBUG
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+}
+
+//==================================================================================================
+class RTTI
+{
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+{
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iRttiFind( m_rttis.find( unoName ) );
+ if (iRttiFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
+ if (iFind == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with _ZTI
+ char const * rttiName = symName.getStr() +4;
+#if defined BRIDGES_DEBUG
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iFind->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iRttiFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void deleteException( void * pExc )
+{
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+#if defined BRIDGES_DEBUG
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() );
+#endif
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get typedescription for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+{
+ if (! header)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if defined _DEBUG
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+#if defined BRIDGES_DEBUG
+ OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if defined _DEBUG
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_mips/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_mips/makefile.mk
new file mode 100644
index 000000000000..f71750e9108d
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_mips/makefile.mk
@@ -0,0 +1,81 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+NO_BSYMBOLIC=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)" == "GCCLINUXM"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer -fno-strict-aliasing
+
+CFLAGSNOOPT=-O0
+
+NOOPTFILES = \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/cpp2uno.obj
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+
+SHL1TARGET=$(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+
+SHL1OBJS= $(SLOFILES)
+SHL1LIBS =$(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/gcc3_linux_mips/share.hxx b/bridges/source/cpp_uno/gcc3_linux_mips/share.hxx
new file mode 100644
index 000000000000..4ec09c29ff0a
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_mips/share.hxx
@@ -0,0 +1,94 @@
+/* -*- 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 "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+ void dummy_can_throw_anything( char const * );
+
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_mips/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_mips/uno2cpp.cxx
new file mode 100644
index 000000000000..82d226f88ea6
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_mips/uno2cpp.cxx
@@ -0,0 +1,599 @@
+/* -*- 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 <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "share.hxx"
+
+//#define BRDEBUG
+#ifdef BRDEBUG
+#include <stdio.h>
+#endif
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+
+ //==================================================================================================
+ static void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ char * pPT,
+ sal_Int32 * pStackLongs,
+ sal_Int32 /*nStackLongs*/)
+ {
+
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ unsigned long * mfunc; // actual function to be invoked
+ void (*ptr)();
+ int gpr[4]; // storage for gpregisters, map to a0-a3
+ int off; // offset used to find function
+ int nw; // number of words mapped
+ long *p; // pointer to parameter overflow area
+ int c; // character of parameter type being decoded
+ int iret, iret2; // temporary function return values
+
+ // never called
+ if (! pAdjustedThisPtr ) CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
+
+#ifdef BRDEBUG
+ fprintf(stderr,"in CallVirtualMethod\n");
+#endif
+
+ // Because of the MIPS O32 calling conventions we could be passing
+ // parameters in both register types and on the stack. To create the
+ // stack parameter area we need we now simply allocate local
+ // variable storage param[] that is at least the size of the parameter stack
+ // (more than enough space) which we can overwrite the parameters into.
+
+ /* p = sp - 512; new sp will be p - 16, but we don't change sp
+ * at this time to avoid breaking ABI--not sure whether changing sp will break
+ * references to local variables. For the same reason, we use abosulte value.
+ */
+ __asm__ __volatile__ (
+ "addiu $2,$29,-512\n\t"
+ "move %0,$2\n\t"
+ :"=r"(p): : "$2","$29" );
+
+#ifdef BRDEBUG
+ if (nStackLongs * 4 > 512 )
+ fprintf(stderr,"too many arguments");
+#endif
+
+ // now begin to load the C++ function arguments into storage
+ nw = 0;
+
+ // now we need to parse the entire signature string */
+ // until we get the END indicator */
+
+ // treat complex return pointer like any other parameter //
+
+#ifdef BRDEBUG
+ fprintf(stderr,"overflow area pointer p=%p\n",p);
+
+ /* Let's figure out what is really going on here*/
+ fprintf(stderr,"callVirtualMethod paramters string is %s\n",pPT);
+ int k = nStackLongs;
+ long * q = (long *)pStackLongs;
+ while (k > 0) {
+ fprintf(stderr,"uno stack is: %x\n",(unsigned int)*q);
+ k--;
+ q++;
+ }
+#endif
+
+ /* parse the argument list up to the ending ) */
+ while (*pPT != 'X') {
+ c = *pPT;
+ switch (c) {
+ case 'D': /* type is double */
+ /* treat the same as long long */
+ case 'H': /* type is long long */
+ if (nw & 1) nw++; /* note even elements gpr[] will map to
+ odd registers*/
+ if (nw < 4) {
+ gpr[nw++] = *pStackLongs;
+ gpr[nw++] = *(pStackLongs+1);
+ } else {
+ if (((long) p) & 4)
+ p++;
+ *p++ = *pStackLongs;
+ *p++ = *(pStackLongs+1);
+ }
+ pStackLongs += 2;
+ break;
+
+ case 'S':
+ if (nw < 4) {
+ gpr[nw++] = *((unsigned short*)pStackLongs);
+ } else {
+ *p++ = *((unsigned short *)pStackLongs);
+ }
+ pStackLongs += 1;
+ break;
+
+ case 'B':
+ if (nw < 4) {
+ gpr[nw++] = *((char *)pStackLongs);
+ } else {
+ *p++ = *((char *)pStackLongs);
+ }
+ pStackLongs += 1;
+ break;
+
+ default:
+ if (nw < 4) {
+ gpr[nw++] = *pStackLongs;
+ } else {
+ *p++ = *pStackLongs;
+ }
+ pStackLongs += 1;
+ break;
+ }
+ pPT++;
+ }
+
+ /* figure out the address of the function we need to invoke */
+ off = nVtableIndex;
+ off = off * 4; // 4 bytes per slot
+ mfunc = *((unsigned long **)pAdjustedThisPtr); // get the address of the vtable
+ mfunc = (unsigned long *)((char *)mfunc + off); // get the address from the vtable entry at offset
+ mfunc = *((unsigned long **)mfunc); // the function is stored at the address
+ ptr = (void (*)())mfunc;
+
+#ifdef BRDEBUG
+ fprintf(stderr,"calling function %p\n",mfunc);
+#endif
+
+ /* Set up the machine registers and invoke the function */
+
+ __asm__ __volatile__ (
+ "lw $4, 0(%0)\n\t"
+ "lw $5, 4(%0)\n\t"
+ "lw $6, 8(%0)\n\t"
+ "lw $7, 12(%0)\n\t"
+ : : "r" (gpr)
+ : "$4", "$5", "$6", "$7"
+ );
+
+ __asm__ __volatile__ ("addiu $29,$29,-528\r\n":::"$29");
+
+ (*ptr)();
+
+ __asm__ __volatile__ ("addiu $29,$29,528\r\n":::"$29");
+
+ __asm__ __volatile__ (
+ "sw $2,%0 \n\t"
+ "sw $3,%1 \n\t"
+ : "=m" (iret), "=m" (iret2) : );
+ register float fret asm("$f0");
+ register double dret asm("$f0");
+
+ switch( eReturnType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ ((long*)pRegisterReturn)[1] = iret2; // fall through
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ ((long*)pRegisterReturn)[0] = iret;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = (unsigned short)iret;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = (unsigned char)iret;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float*)pRegisterReturn = fret;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double*)pRegisterReturn = dret;
+ break;
+ default:
+ break;
+ }
+ }
+
+
+ //==================================================================================================
+ static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+ {
+ // max space for: [complex ret ptr], values|ptr ...
+ char * pCppStack =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ char * pCppStackStart = pCppStack;
+
+ // need to know parameter types for callVirtualMethod so generate a signature string
+ char * pParamType = (char *) alloca(nParams+2);
+ char * pPT = pParamType;
+
+#ifdef BRDEBUG
+ fprintf(stderr,"in cpp_call\n");
+#endif
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ // OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack =
+ (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize ): pUnoReturn); // direct way
+ *pPT++ = 'I'; //signify that a complex return type on stack
+ pCppStack += sizeof(void *);
+ }
+ }
+ // push this
+ void* pAdjustedThisPtr = reinterpret_cast< void **>(pThis->getCppI()) + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+ *pPT++ = 'I';
+
+ // stack space
+ // OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+
+ // we need to know type of each param so that we know whether to use
+ // gpr or fpr to pass in parameters:
+ // Key: I - int, long, pointer, etc means pass in gpr
+ // B - byte value passed in gpr
+ // S - short value passed in gpr
+ // F - float value pass in fpr
+ // D - double value pass in fpr
+ // H - long long int pass in proper pairs of gpr (3,4) (5,6), etc
+ // X - indicates end of parameter description string
+
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ *pPT++ = 'I';
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *pPT++ = 'S';
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *pPT++ = 'B';
+ break;
+ case typelib_TypeClass_FLOAT:
+ *pPT++ = 'F';
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *pPT++ = 'D';
+ pCppStack += sizeof(sal_Int32); // extra long
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *pPT++ = 'H';
+ pCppStack += sizeof(sal_Int32); // extra long
+ break;
+ default:
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // KBH: FIXME: is this the right way to pass these
+ *pPT++='I';
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // terminate the signature string
+ *pPT++='X';
+ *pPT=0;
+
+ try
+ {
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass, pParamType,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions,
+ *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+ }
+
+}
+
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+//==================================================================================================
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy *> (pUnoI);
+ //typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+#ifdef BRDEBUG
+ fprintf(stderr,"in dispatch\n");
+#endif
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; //get then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+}}}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc/cpp2uno.cxx
new file mode 100644
index 000000000000..24354bfa45f8
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc/cpp2uno.cxx
@@ -0,0 +1,795 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <string.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "share.hxx"
+
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ int ng = 0; //number of gpr registers used
+#ifndef __NO_FPRS__
+ int nf = 0; //number of fpr regsiters used
+#endif
+ void ** pCppStack; //temporary stack pointer
+
+ // gpreg: [ret *], this, [gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)gpreg;
+ gpreg++;
+ ng++;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ gpreg++;
+ ng++;
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ // value
+ {
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+
+ case typelib_TypeClass_DOUBLE:
+#ifndef __NO_FPRS__
+ if (nf < 8) {
+ pCppArgs[nPos] = fpreg;
+ pUnoArgs[nPos] = fpreg;
+ nf++;
+ fpreg += 2;
+#else
+ if (ng & 1) {
+ ng++;
+ gpreg++;
+ }
+ if (ng < 8) {
+ pCppArgs[nPos] = gpreg;
+ pUnoArgs[nPos] = gpreg;
+ ng += 2;
+ gpreg += 2;
+#endif
+ } else {
+ if (((long)ovrflw) & 4) ovrflw++;
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw += 2;
+ }
+ break;
+
+ case typelib_TypeClass_FLOAT:
+ // fpreg are all double values so need to
+ // modify fpreg to be a single word float value
+#ifndef __NO_FPRS__
+ if (nf < 8) {
+ float tmp = (float) (*((double *)fpreg));
+ (*((float *) fpreg)) = tmp;
+ pCppArgs[nPos] = fpreg;
+ pUnoArgs[nPos] = fpreg;
+ nf++;
+ fpreg += 2;
+#else
+ if (ng < 8) {
+ pCppArgs[nPos] = gpreg;
+ pUnoArgs[nPos] = gpreg;
+ ng++;
+ gpreg++;
+#endif
+ } else {
+#if 0 /* abi is not being followed correctly */
+ if (((long)ovrflw) & 4) ovrflw++;
+ float tmp = (float) (*((double *)ovrflw));
+ (*((float *) ovrflw)) = tmp;
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw += 2;
+#else
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw += 1;
+#endif
+ }
+ break;
+
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (ng & 1) {
+ ng++;
+ gpreg++;
+ }
+ if (ng < 8) {
+ pCppArgs[nPos] = gpreg;
+ pUnoArgs[nPos] = gpreg;
+ ng += 2;
+ gpreg += 2;
+ } else {
+ if (((long)ovrflw) & 4) ovrflw++;
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw += 2;
+ }
+ break;
+
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_BOOLEAN:
+ if (ng < 8) {
+ pCppArgs[nPos] = (((char *)gpreg) + 3);
+ pUnoArgs[nPos] = (((char *)gpreg) + 3);
+ ng++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = (((char *)ovrflw) + 3);
+ pUnoArgs[nPos] = (((char *)ovrflw) + 3);
+ ovrflw++;
+ }
+ break;
+
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (ng < 8) {
+ pCppArgs[nPos] = (((char *)gpreg)+ 2);
+ pUnoArgs[nPos] = (((char *)gpreg)+ 2);
+ ng++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = (((char *)ovrflw) + 2);
+ pUnoArgs[nPos] = (((char *)ovrflw) + 2);
+ ovrflw++;
+ }
+ break;
+
+
+ default:
+ if (ng < 8) {
+ pCppArgs[nPos] = gpreg;
+ pUnoArgs[nPos] = gpreg;
+ ng++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw++;
+ }
+ break;
+
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+
+ if (ng < 8) {
+ pCppArgs[nPos] = *(void **)gpreg;
+ pCppStack = gpreg;
+ ng++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = *(void **)ovrflw;
+ pCppStack = ovrflw;
+ ovrflw++;
+ }
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ void * pThis;
+ if (nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = gpreg[1];
+ }
+ else
+ {
+ pThis = gpreg[0];
+ }
+
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pThis );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** fpregptr, void** ovrflw)
+{
+ sal_Int32 gpreg[8];
+ memcpy( gpreg, gpregptr, 32);
+
+#ifndef __NO_FPRS__
+ double fpreg[8];
+ memcpy( fpreg, fpregptr, 64);
+#endif
+
+ volatile long nRegReturn[2];
+
+ // fprintf(stderr,"in cpp_vtable_call nFunctionIndex is %x\n",nFunctionIndex);
+ // fprintf(stderr,"in cpp_vtable_call nVtableOffset is %x\n",nVtableOffset);
+ // fflush(stderr);
+
+ typelib_TypeClass aType =
+ cpp_mediate( nFunctionIndex, nVtableOffset, (void**)gpreg,
+#ifndef __NO_FPRS__
+ (void**)fpreg,
+#else
+ NULL,
+#endif
+ ovrflw, (sal_Int64*)nRegReturn );
+
+ switch( aType )
+ {
+
+ // move return value into register space
+ // (will be loaded by machine code snippet)
+
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ __asm__( "lbz 3,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ __asm__( "lhz 3,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+
+ case typelib_TypeClass_FLOAT:
+#ifndef __NO_FPRS__
+ __asm__( "lfs 1,%0\n\t" : :
+ "m" (*((float*)nRegReturn)) );
+ #else
+ __asm__( "lwz 3,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+#endif
+ break;
+
+ case typelib_TypeClass_DOUBLE:
+#ifndef __NO_FPRS__
+ __asm__( "lfd 1,%0\n\t" : :
+ "m" (*((double*)nRegReturn)) );
+#else
+ __asm__( "lwz 3,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ __asm__( "lwz 4,%0\n\t" : :
+ "m"(nRegReturn[1]) );
+#endif
+ break;
+
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ __asm__( "lwz 4,%0\n\t" : :
+ "m"(nRegReturn[1]) ); // fall through
+
+ default:
+ __asm__( "lwz 3,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+ }
+}
+
+
+int const codeSnippetSize = 108;
+
+unsigned char * codeSnippet( unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ bool simpleRetType)
+{
+
+ // fprintf(stderr,"in codeSnippet functionIndex is %x\n", functionIndex);
+ // fprintf(stderr,"in codeSnippet vtableOffset is %x\n", vtableOffset);
+ // fflush(stderr);
+
+ if (! simpleRetType )
+ functionIndex |= 0x80000000;
+
+ unsigned long * p = (unsigned long *) code;
+
+ // OSL_ASSERT( sizeof (long) == 4 );
+ OSL_ASSERT((((unsigned long)code) & 0x3) == 0 ); //aligned to 4 otherwise a mistake
+
+ /* generate this code */
+ // # so first save gpr 3 to gpr 10 (aligned to 4)
+ // stw r3,-2048(r1)
+ // stw r4,-2044(r1)
+ // stw r5,-2040(r1)
+ // stw r6,-2036(r1)
+ // stw r7,-2032(r1)
+ // stw r8,-2028(r1)
+ // stw r9,-2024(r1)
+ // stw r10,-2020(r1)
+
+
+ // # next save fpr 1 to fpr 8 (aligned to 8)
+ // if dedicated floating point registers are used
+ // stfd f1,-2016(r1)
+ // stfd f2,-2008(r1)
+ // stfd f3,-2000(r1)
+ // stfd f4,-1992(r1)
+ // stfd f5,-1984(r1)
+ // stfd f6,-1976(r1)
+ // stfd f7,-1968(r1)
+ // stfd f8,-1960(r1)
+
+ // # now here is where cpp_vtable_call must go
+ // lis r3,-8531
+ // ori r3,r3,48879
+ // mtctr r3
+
+ // # now load up the functionIndex
+ // lis r3,-8531
+ // ori r3,r3,48879
+
+ // # now load up the vtableOffset
+ // lis r4,-8531
+ // ori r4,r4,48879
+
+ // #now load up the pointer to the saved gpr registers
+ // addi r5,r1,-2048
+
+ // #now load up the pointer to the saved fpr registers
+ // addi r6,r1,-2016
+ // if no dedicated floating point registers are used than we have NULL
+ // pointer there
+ // li r6, 0
+ //
+
+ // #now load up the pointer to the overflow call stack
+ // addi r7,r1,8
+ // bctr
+
+ * p++ = 0x9061f800;
+ * p++ = 0x9081f804;
+ * p++ = 0x90a1f808;
+ * p++ = 0x90c1f80c;
+ * p++ = 0x90e1f810;
+ * p++ = 0x9101f814;
+ * p++ = 0x9121f818;
+ * p++ = 0x9141f81c;
+#ifndef __NO_FPRS__
+ * p++ = 0xd821f820;
+ * p++ = 0xd841f828;
+ * p++ = 0xd861f830;
+ * p++ = 0xd881f838;
+ * p++ = 0xd8a1f840;
+ * p++ = 0xd8c1f848;
+ * p++ = 0xd8e1f850;
+ * p++ = 0xd901f858;
+#else
+ /* these nops could be replaced with a smaller codeSnippetSize - 8 * 4 */
+ * p++ = 0x60000000;
+ * p++ = 0x60000000;
+ * p++ = 0x60000000;
+ * p++ = 0x60000000;
+ * p++ = 0x60000000;
+ * p++ = 0x60000000;
+ * p++ = 0x60000000;
+ * p++ = 0x60000000;
+#endif
+ * p++ = 0x3c600000 | (((unsigned long)cpp_vtable_call) >> 16);
+ * p++ = 0x60630000 | (((unsigned long)cpp_vtable_call) & 0x0000FFFF);
+ * p++ = 0x7c6903a6;
+ * p++ = 0x3c600000 | (((unsigned long)functionIndex) >> 16);
+ * p++ = 0x60630000 | (((unsigned long)functionIndex) & 0x0000FFFF);
+ * p++ = 0x3c800000 | (((unsigned long)vtableOffset) >> 16);
+ * p++ = 0x60840000 | (((unsigned long)vtableOffset) & 0x0000FFFF);
+ * p++ = 0x38a1f800;
+#ifndef __NO_FPRS__
+ * p++ = 0x38c1f820;
+#else
+ * p++ = 0x38c00000;
+#endif
+ * p++ = 0x38e10008;
+ * p++ = 0x4e800420;
+ return (code + codeSnippetSize);
+
+}
+
+
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * bptr, unsigned char const * eptr)
+{
+ int const lineSize = 32;
+ for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
+ __asm__ volatile ("dcbst 0, %0" : : "r"(p) : "memory");
+ }
+ __asm__ volatile ("sync" : : : "memory");
+ for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
+ __asm__ volatile ("icbi 0, %0" : : "r"(p) : "memory");
+ }
+ __asm__ volatile ("isync" : : : "memory");
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0;
+ slots[-1].fn = 0;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ // fprintf(stderr, "in addLocalFunctions functionOffset is %x\n",functionOffset);
+ // fprintf(stderr, "in addLocalFunctions vtableOffset is %x\n",vtableOffset);
+ // fflush(stderr);
+
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc/except.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc/except.cxx
new file mode 100644
index 000000000000..c0de95532515
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc/except.cxx
@@ -0,0 +1,289 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * )
+{
+}
+
+//==================================================================================================
+static OUString toUNOname( char const * p ) SAL_THROW( () )
+{
+#if OSL_DEBUG_LEVEL > 1
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+}
+
+//==================================================================================================
+class RTTI
+{
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+{
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iRttiFind( m_rttis.find( unoName ) );
+ if (iRttiFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
+ if (iFind == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with _ZTI
+ char const * rttiName = symName.getStr() +4;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iFind->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iRttiFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void deleteException( void * pExc )
+{
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ terminate();
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ terminate();
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno )
+{
+ OSL_ENSURE( header, "### no exception header!!!" );
+ if (! header)
+ terminate();
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" );
+ if (! pExcTypeDescr)
+ terminate();
+
+ // construct uno exception any
+ ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ ::typelib_typedescription_release( pExcTypeDescr );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_powerpc/makefile.mk
new file mode 100644
index 000000000000..9a752009904e
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc/makefile.mk
@@ -0,0 +1,80 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)$(CPUNAME)" == "GCCLINUXPgcc3POWERPC"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer -fno-strict-aliasing
+
+NOOPTFILES= \
+ $(SLO)$/uno2cpp.obj
+
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS= $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc/share.hxx b/bridges/source/cpp_uno/gcc3_linux_powerpc/share.hxx
new file mode 100644
index 000000000000..4ec09c29ff0a
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc/share.hxx
@@ -0,0 +1,94 @@
+/* -*- 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 "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+ void dummy_can_throw_anything( char const * );
+
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc/uno2cpp.cxx
new file mode 100644
index 000000000000..0ebc44895a78
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc/uno2cpp.cxx
@@ -0,0 +1,675 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "share.hxx"
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+
+//==================================================================================================
+static void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ char * pPT,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs)
+{
+
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ // the basic idea here is to use gpr[8] as a storage area for
+ // the future values of registers r3 to r10 needed for the call,
+ // and similarly fpr[8] as a storage area for the future values
+ // of floating point registers f1 to f8
+
+ unsigned long * mfunc; // actual function to be invoked
+ void (*ptr)();
+ int gpr[8]; // storage for gpregisters, map to r3-r10
+ int off; // offset used to find function
+#ifndef __NO_FPRS__
+ double fpr[8]; // storage for fpregisters, map to f1-f8
+ int f; // number of fprs mapped so far
+ double dret; // temporary function return values
+#endif
+ int n; // number of gprs mapped so far
+ long *p; // pointer to parameter overflow area
+ int c; // character of parameter type being decoded
+ int iret, iret2;
+
+ // Because of the Power PC calling conventions we could be passing
+ // parameters in both register types and on the stack. To create the
+ // stack parameter area we need we now simply allocate local
+ // variable storage param[] that is at least the size of the parameter stack
+ // (more than enough space) which we can overwrite the parameters into.
+
+ // Note: This keeps us from having to decode the signature twice and
+ // prevents problems with later local variables.
+
+ // Note: could require up to 2*nStackLongs words of parameter stack area
+ // if the call has many float parameters (i.e. floats take up only 1
+ // word on the stack but double takes 2 words in parameter area in the
+ // stack frame .
+
+ // Update! floats on the outgoing parameter stack only take up 1 word
+ // (stfs is used) which is not correct according to the ABI but we
+ // will match what the compiler does until this is figured out
+
+ // this grows the current stack to the appropriate size
+ // and sets the outgoing stack pointer p to the right place
+ __asm__ __volatile__ (
+ "rlwinm %0,%0,3,3,28\n\t"
+ "addi %0,%0,22\n\t"
+ "rlwinm %0,%0,0,4,28\n\t"
+ "lwz 0,0(1)\n\t"
+ "subf 1,%0,1\n\t"
+ "stw 0,0(1)\n\t"
+ : : "r" (nStackLongs) : "0" );
+
+ __asm__ __volatile__ ( "addi %0,1,8" : "=r" (p) : );
+
+ // never called
+ // if (! pAdjustedThisPtr ) dummy_can_throw_anything("xxx"); // address something
+
+
+ // now begin to load the C++ function arguments into storage
+ n = 0;
+#ifndef __NO_FPRS__
+ f = 0;
+#endif
+
+ // now we need to parse the entire signature string */
+ // until we get the END indicator */
+
+ // treat complex return pointer like any other parameter //
+
+#if 0
+ /* Let's figure out what is really going on here*/
+ fprintf(stderr,"callVirtualMethod paramters string is %s\n",pPT);
+ int k = nStackLongs;
+ long * q = (long *)pStackLongs;
+ while (k > 0) {
+ fprintf(stderr,"uno stack is: %x\n",*q);
+ k--;
+ q++;
+ }
+#endif
+
+ /* parse the argument list up to the ending ) */
+ while (*pPT != 'X') {
+ c = *pPT;
+ switch (c) {
+ case 'D': /* type is double */
+#ifndef __NO_FPRS__
+ if (f < 8) {
+ fpr[f++] = *((double *)pStackLongs); /* store in register */
+#else
+ if (n & 1)
+ n++;
+ if (n < 8) {
+ gpr[n++] = *pStackLongs;
+ gpr[n++] = *(pStackLongs+1);
+#endif
+ } else {
+ if (((long) p) & 4)
+ p++;
+ *p++ = *pStackLongs; /* or on the parameter stack */
+ *p++ = *(pStackLongs + 1);
+ }
+ pStackLongs += 2;
+ break;
+
+ case 'F': /* type is float */
+ /* this assumes that floats are stored as 1 32 bit word on param
+ stack and that if passed in parameter stack to C, should be
+ as double word.
+
+ Whoops: the abi is not actually followed by gcc, need to
+ store floats as a *single* word on outgoing parameter stack
+ to match what gcc actually does
+ */
+#ifndef __NO_FPRS__
+ if (f < 8) {
+ fpr[f++] = *((float *)pStackLongs);
+#else
+ if (n < 8) {
+ gpr[n++] = *pStackLongs;
+#endif
+ } else {
+#if 0 /* if abi were followed */
+ if (((long) p) & 4)
+ p++;
+ *((double *)p) = *((float *)pStackLongs);
+ p += 2;
+#else
+ *((float *)p) = *((float *)pStackLongs);
+ p += 1;
+#endif
+ }
+ pStackLongs += 1;
+ break;
+
+ case 'H': /* type is long long */
+ if (n & 1) n++; /* note even elements gpr[] will map to
+ odd registers*/
+ if (n <= 6) {
+ gpr[n++] = *pStackLongs;
+ gpr[n++] = *(pStackLongs+1);
+ } else {
+ if (((long) p) & 4)
+ p++;
+ *p++ = *pStackLongs;
+ *p++ = *(pStackLongs+1);
+ }
+ pStackLongs += 2;
+ break;
+
+ case 'S':
+ if (n < 8) {
+ gpr[n++] = *((unsigned short*)pStackLongs);
+ } else {
+ *p++ = *((unsigned short *)pStackLongs);
+ }
+ pStackLongs += 1;
+ break;
+
+ case 'B':
+ if (n < 8) {
+ gpr[n++] = *((char *)pStackLongs);
+ } else {
+ *p++ = *((char *)pStackLongs);
+ }
+ pStackLongs += 1;
+ break;
+
+ default:
+ if (n < 8) {
+ gpr[n++] = *pStackLongs;
+ } else {
+ *p++ = *pStackLongs;
+ }
+ pStackLongs += 1;
+ break;
+ }
+ pPT++;
+ }
+
+ /* figure out the address of the function we need to invoke */
+ off = nVtableIndex;
+ off = off * 4; // 4 bytes per slot
+ mfunc = *((unsigned long **)pAdjustedThisPtr); // get the address of the vtable
+ mfunc = (unsigned long *)((char *)mfunc + off); // get the address from the vtable entry at offset
+ mfunc = *((unsigned long **)mfunc); // the function is stored at the address
+ ptr = (void (*)())mfunc;
+
+ /* Set up the machine registers and invoke the function */
+
+ __asm__ __volatile__ (
+ "lwz 3, 0(%0)\n\t"
+ "lwz 4, 4(%0)\n\t"
+ "lwz 5, 8(%0)\n\t"
+ "lwz 6, 12(%0)\n\t"
+ "lwz 7, 16(%0)\n\t"
+ "lwz 8, 20(%0)\n\t"
+ "lwz 9, 24(%0)\n\t"
+ "lwz 10, 28(%0)\n\t"
+#ifndef __NO_FPRS__
+ "lfd 1, 0(%1)\n\t"
+ "lfd 2, 8(%1)\n\t"
+ "lfd 3, 16(%1)\n\t"
+ "lfd 4, 24(%1)\n\t"
+ "lfd 5, 32(%1)\n\t"
+ "lfd 6, 40(%1)\n\t"
+ "lfd 7, 48(%1)\n\t"
+ "lfd 8, 56(%1)\n\t"
+ : : "r" (gpr), "r" (fpr)
+#else
+ : : "r" (gpr)
+#endif
+ : "0", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"
+ );
+
+ (*ptr)();
+
+ __asm__ __volatile__ (
+ "mr %0, 3\n\t"
+ "mr %1, 4\n\t"
+#ifndef __NO_FPRS__
+ "fmr %2, 1\n\t"
+ : "=r" (iret), "=r" (iret2), "=f" (dret)
+#else
+ : "=r" (iret), "=r" (iret2)
+#endif
+ : );
+
+ switch( eReturnType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ ((long*)pRegisterReturn)[0] = iret;
+ ((long*)pRegisterReturn)[1] = iret2;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ ((long*)pRegisterReturn)[0] = iret;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = (unsigned short)iret;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = (unsigned char)iret;
+ break;
+ case typelib_TypeClass_FLOAT:
+#ifndef __NO_FPRS__
+ *(float*)pRegisterReturn = (float)dret;
+#else
+ ((unsigned int*)pRegisterReturn)[0] = iret;
+#endif
+ break;
+ case typelib_TypeClass_DOUBLE:
+#ifndef __NO_FPRS__
+ *(double*)pRegisterReturn = dret;
+#else
+ ((unsigned int*)pRegisterReturn)[0] = iret;
+ ((unsigned int*)pRegisterReturn)[1] = iret2;
+#endif
+ break;
+ default:
+ break;
+ }
+}
+
+
+//==================================================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ char * pCppStack =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ char * pCppStackStart = pCppStack;
+
+ // need to know parameter types for callVirtualMethod so generate a signature string
+ char * pParamType = (char *) alloca(nParams+2);
+ char * pPT = pParamType;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ // OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack =
+ (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize ): pUnoReturn); // direct way
+ *pPT++ = 'I'; //signify that a complex return type on stack
+ pCppStack += sizeof(void *);
+ }
+ }
+ // push this
+ void* pAdjustedThisPtr = reinterpret_cast< void **>(pThis->getCppI()) + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+ *pPT++ = 'I';
+
+ // stack space
+ // OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+
+ // we need to know type of each param so that we know whether to use
+ // gpr or fpr to pass in parameters:
+ // Key: I - int, long, pointer, etc means pass in gpr
+ // B - byte value passed in gpr
+ // S - short value passed in gpr
+ // F - float value pass in fpr
+ // D - double value pass in fpr
+ // H - long long int pass in proper pairs of gpr (3,4) (5,6), etc
+ // X - indicates end of parameter description string
+
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ *pPT++ = 'I';
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *pPT++ = 'S';
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *pPT++ = 'B';
+ break;
+ case typelib_TypeClass_FLOAT:
+ *pPT++ = 'F';
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *pPT++ = 'D';
+ pCppStack += sizeof(sal_Int32); // extra long
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *pPT++ = 'H';
+ pCppStack += sizeof(sal_Int32); // extra long
+ default:
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // KBH: FIXME: is this the right way to pass these
+ *pPT++='I';
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // terminate the signature string
+ *pPT++='X';
+ *pPT=0;
+
+ try
+ {
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass, pParamType,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions,
+ *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy *> (pUnoI);
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; //get then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
new file mode 100644
index 000000000000..f8e1fb9cd98a
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
@@ -0,0 +1,723 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "share.hxx"
+#include <stdio.h>
+#include <string.h>
+
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr, "as far as cpp2uno_call\n");
+#endif
+
+ int ng = 0; //number of gpr registers used
+ int nf = 0; //number of fpr regsiters used
+
+ // gpreg: [ret *], this, [gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)gpreg;
+ gpreg++;
+ ng++;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ gpreg++;
+ ng++;
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int64), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+ bool bOverFlowUsed = false;
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "arg %d of %d\n", nPos, nParams);
+#endif
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "simple\n");
+#endif
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_FLOAT:
+ case typelib_TypeClass_DOUBLE:
+ if (nf < ppc64::MAX_SSE_REGS)
+ {
+ if (pParamTypeDescr->eTypeClass == typelib_TypeClass_FLOAT)
+ {
+ float tmp = (float) (*((double *)fpreg));
+ (*((float *) fpreg)) = tmp;
+ }
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
+ nf++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+ break;
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_BOOLEAN:
+ if (ng < ppc64::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-1));
+ ng++;
+ gpreg++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-1));
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (ng < ppc64::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-2));
+ ng++;
+ gpreg++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-2));
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+ break;
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (ng < ppc64::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-4));
+ ng++;
+ gpreg++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-4));
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+ break;
+ default:
+ if (ng < ppc64::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg++;
+ ng++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex, ng is %d\n", ng);
+#endif
+ void *pCppStack; //temporary stack pointer
+
+ if (ng < ppc64::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pCppStack = *gpreg++;
+ ng++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pCppStack = *ovrflw;
+ bOverFlowUsed = true;
+ }
+ if (bOverFlowUsed) ovrflw++;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "end of params\n");
+#endif
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_uInt64 nOffsetAndIndex,
+ void ** gpreg, void ** fpreg, long sp,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int64)==sizeof(void *), "### unexpected!" );
+
+ sal_Int32 nVtableOffset = (nOffsetAndIndex >> 32);
+ sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFFFFFF);
+
+ long sf = *(long*)sp;
+ void ** ovrflw = (void**)(sf + 112);
+
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ void * pThis;
+ if (nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = gpreg[1];
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is gpreg[1]\n");
+#endif
+ }
+ else
+ {
+ pThis = gpreg[0];
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is gpreg[0]\n");
+#endif
+ }
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is %lx\n", pThis);
+#endif
+
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pThis is now %lx\n", pThis);
+#endif
+
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "indexes are %d %d\n", nFunctionIndex, pTypeDescr->nMapFunctionIndexToMemberIndex);
+#endif
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pThis );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "members are %d %d\n", nMemberPos, pTypeDescr->nAllMembers);
+#endif
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "screwed\n");
+#endif
+
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "end of cpp_mediate\n");
+#endif
+ return eRet;
+}
+
+extern "C" void privateSnippetExecutor( ... )
+{
+ volatile long nOffsetAndIndex;
+
+ //mr %r3, %r11 # move into arg1 the 64bit value passed from OOo
+ __asm__ __volatile__ (
+ "mr %0, 11\n\t"
+ : "=r" (nOffsetAndIndex) : );
+
+ sal_uInt64 gpreg[ppc64::MAX_GPR_REGS];
+ double fpreg[ppc64::MAX_SSE_REGS];
+
+ __asm__ __volatile__ (
+ "std 3, 0(%0)\t\n"
+ "std 4, 8(%0)\t\n"
+ "std 5, 16(%0)\t\n"
+ "std 6, 24(%0)\t\n"
+ "std 7, 32(%0)\t\n"
+ "std 8, 40(%0)\t\n"
+ "std 9, 48(%0)\t\n"
+ "std 10, 56(%0)\t\n"
+ "stfd 1, 0(%1)\t\n"
+ "stfd 2, 8(%1)\t\n"
+ "stfd 3, 16(%1)\t\n"
+ "stfd 4, 24(%1)\t\n"
+ "stfd 5, 32(%1)\t\n"
+ "stfd 6, 40(%1)\t\n"
+ "stfd 7, 48(%1)\t\n"
+ "stfd 8, 56(%1)\t\n"
+ "stfd 9, 64(%1)\t\n"
+ "stfd 10, 72(%1)\t\n"
+ "stfd 11, 80(%1)\t\n"
+ "stfd 12, 88(%1)\t\n"
+ "stfd 13, 96(%1)\t\n"
+ : : "r" (gpreg), "r" (fpreg)
+ : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
+ "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", "fr8", "fr9",
+ "fr10", "fr11", "fr12", "fr13"
+ );
+
+ volatile long sp;
+
+ //stack pointer
+ __asm__ __volatile__ (
+ "mr %0, 1\n\t"
+ : "=r" (sp) : );
+
+ volatile long nRegReturn[1];
+
+ typelib_TypeClass aType =
+ cpp_mediate( nOffsetAndIndex, (void**)gpreg, (void**)fpreg, sp, (sal_Int64*)nRegReturn);
+
+ switch( aType )
+ {
+ case typelib_TypeClass_VOID:
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ __asm__( "lbz 3,%0\n\t"
+ : : "m" (nRegReturn[0]) );
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ __asm__( "lhz 3,%0\n\t"
+ : : "m" (nRegReturn[0]) );
+ break;
+ case typelib_TypeClass_SHORT:
+ __asm__( "lha 3,%0\n\t"
+ : : "m" (nRegReturn[0]) );
+ break;
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ __asm__( "lwz 3,%0\n\t"
+ : : "m"(nRegReturn[0]) );
+ break;
+ case typelib_TypeClass_LONG:
+ __asm__( "lwa 3,%0\n\t"
+ : : "m"(nRegReturn[0]) );
+ break;
+ case typelib_TypeClass_FLOAT:
+ __asm__( "lfs 1,%0\n\t"
+ : : "m" (*((float*)nRegReturn)) );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ __asm__( "lfd 1,%0\n\t"
+ : : "m" (*((double*)nRegReturn)) );
+ break;
+ default:
+ __asm__( "ld 3,%0\n\t"
+ : : "m" (nRegReturn[0]) );
+ break;
+ }
+}
+
+const int codeSnippetSize = 24;
+
+unsigned char * codeSnippet( unsigned char * code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+ bool simpleRetType)
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr,"in codeSnippet functionIndex is %x\n", nFunctionIndex);
+ fprintf(stderr,"in codeSnippet vtableOffset is %x\n", nVtableOffset);
+#endif
+
+ sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
+
+ if ( !simpleRetType )
+ nOffsetAndIndex |= 0x80000000;
+
+ void ** raw = (void **)&code[0];
+ memcpy(raw, (char*) privateSnippetExecutor, 16);
+ raw[2] = (void*) nOffsetAndIndex;
+#ifdef CMC_DEBUG
+ fprintf(stderr, "in: offset/index is %x %x %d, %lx\n",
+ nFunctionIndex, nVtableOffset, !simpleRetType, raw[2]);
+#endif
+ return (code + codeSnippetSize);
+}
+
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * bptr, unsigned char const * eptr)
+{
+ int const lineSize = 32;
+ for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
+ __asm__ volatile ("dcbst 0, %0" : : "r"(p) : "memory");
+ }
+ __asm__ volatile ("sync" : : : "memory");
+ for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
+ __asm__ volatile ("icbi 0, %0" : : "r"(p) : "memory");
+ }
+ __asm__ volatile ("isync" : : : "memory");
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0;
+ slots[-1].fn = 0;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+#ifdef CMC_DEBUG
+ fprintf(stderr, "in addLocalFunctions functionOffset is %x\n",functionOffset);
+ fprintf(stderr, "in addLocalFunctions vtableOffset is %x\n",vtableOffset);
+#endif
+
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/except.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/except.cxx
new file mode 100644
index 000000000000..c0de95532515
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/except.cxx
@@ -0,0 +1,289 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * )
+{
+}
+
+//==================================================================================================
+static OUString toUNOname( char const * p ) SAL_THROW( () )
+{
+#if OSL_DEBUG_LEVEL > 1
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+}
+
+//==================================================================================================
+class RTTI
+{
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+{
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iRttiFind( m_rttis.find( unoName ) );
+ if (iRttiFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
+ if (iFind == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with _ZTI
+ char const * rttiName = symName.getStr() +4;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iFind->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iRttiFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void deleteException( void * pExc )
+{
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ terminate();
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ terminate();
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno )
+{
+ OSL_ENSURE( header, "### no exception header!!!" );
+ if (! header)
+ terminate();
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" );
+ if (! pExcTypeDescr)
+ terminate();
+
+ // construct uno exception any
+ ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ ::typelib_typedescription_release( pExcTypeDescr );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_powerpc64/makefile.mk
new file mode 100644
index 000000000000..77763d7c8b54
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/makefile.mk
@@ -0,0 +1,79 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)$(CPUNAME)" == "GCCLINUXPgcc3POWERPC64"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer -fno-strict-aliasing
+
+NOOPTFILES= \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/cpp2uno.obj
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+
+SHL1OBJS= $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx
new file mode 100644
index 000000000000..38ed48ee06c8
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx
@@ -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.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+ void dummy_can_throw_anything( char const * );
+
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+namespace ppc64
+{
+ enum ppclimits { MAX_GPR_REGS = 8, MAX_SSE_REGS = 13 };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
new file mode 100644
index 000000000000..04ceddab4c5f
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
@@ -0,0 +1,603 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+void MapReturn(long r3, double dret, typelib_TypeClass eTypeClass, void *pRegisterReturn)
+{
+ switch (eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = r3;
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ *reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) = r3;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *reinterpret_cast<sal_uInt16 *>( pRegisterReturn ) = (unsigned short)r3;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) = (unsigned char)r3;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *reinterpret_cast<float *>( pRegisterReturn ) = dret;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *reinterpret_cast<double *>( pRegisterReturn ) = dret;
+ break;
+ default:
+ break;
+ }
+}
+
+namespace
+{
+//==================================================================================================
+static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescription * pReturnTypeDescr,
+ sal_uInt64 *pStack, sal_uInt32 nStack,
+ sal_uInt64 *pGPR, sal_uInt32 nGPR,
+ double *pFPR, sal_uInt32 nFPR)
+{
+ // Stack, if used, must be 16-bytes aligned
+ if ( nStack )
+ nStack = ( nStack + 1 ) & ~1;
+
+ // Should not happen, but...
+ if ( nFPR > ppc64::MAX_SSE_REGS )
+ nFPR = ppc64::MAX_SSE_REGS;
+ if ( nGPR > ppc64::MAX_GPR_REGS )
+ nGPR = ppc64::MAX_GPR_REGS;
+
+#ifdef CMC_DEBUG
+ // Let's figure out what is really going on here
+ {
+ fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
+ for ( int i = 0; i < nGPR; ++i )
+ fprintf( stderr, "0x%lx, ", pGPR[i] );
+ fprintf( stderr, "\nFPR's (%d): ", nFPR );
+ for ( int i = 0; i < nFPR; ++i )
+ fprintf( stderr, "0x%lx (%f), ", pFPR[i], pFPR[i] );
+ fprintf( stderr, "\nStack (%d): ", nStack );
+ for ( int i = 0; i < nStack; ++i )
+ fprintf( stderr, "0x%lx, ", pStack[i] );
+ fprintf( stderr, "\n" );
+ }
+#endif
+
+ // Load parameters to stack, if necessary
+ sal_uInt64 *stack = (sal_uInt64 *) __builtin_alloca( nStack * 8 );
+ memcpy( stack, pStack, nStack * 8 );
+
+ // Get pointer to method
+ sal_uInt64 pMethod = *((sal_uInt64 *)pThis);
+ pMethod += 8 * nVtableIndex;
+ pMethod = *((sal_uInt64 *)pMethod);
+
+ typedef void (* FunctionCall )( sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64 );
+ FunctionCall pFunc = (FunctionCall)pMethod;
+
+ volatile double dret;
+
+ // fill registers
+ __asm__ __volatile__ (
+ "ld 3, 0(%0)\n\t"
+ "ld 4, 8(%0)\n\t"
+ "ld 5, 16(%0)\n\t"
+ "ld 6, 24(%0)\n\t"
+ "ld 7, 32(%0)\n\t"
+ "ld 8, 40(%0)\n\t"
+ "ld 9, 48(%0)\n\t"
+ "ld 10, 56(%0)\n\t"
+ "lfd 1, 0(%1)\n\t"
+ "lfd 2, 8(%1)\n\t"
+ "lfd 3, 16(%1)\n\t"
+ "lfd 4, 24(%1)\n\t"
+ "lfd 5, 32(%1)\n\t"
+ "lfd 6, 40(%1)\n\t"
+ "lfd 7, 48(%1)\n\t"
+ "lfd 8, 56(%1)\n\t"
+ "lfd 9, 64(%1)\n\t"
+ "lfd 10, 72(%1)\n\t"
+ "lfd 11, 80(%1)\n\t"
+ "lfd 12, 88(%1)\n\t"
+ "lfd 13, 96(%1)\n\t"
+ : : "r" (pGPR), "r" (pFPR)
+ : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
+ "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", "fr8", "fr9",
+ "fr10", "fr11", "fr12", "fr13"
+ );
+
+ // tell gcc that r3 to r11 are not available to it for doing the TOC and exception munge on the func call
+ register sal_uInt64 r3 asm("r3");
+ register sal_uInt64 r4 asm("r4");
+ register sal_uInt64 r5 asm("r5");
+ register sal_uInt64 r6 asm("r6");
+ register sal_uInt64 r7 asm("r7");
+ register sal_uInt64 r8 asm("r8");
+ register sal_uInt64 r9 asm("r9");
+ register sal_uInt64 r10 asm("r10");
+ register sal_uInt64 r11 asm("r11");
+
+ (*pFunc)(r3, r4, r5, r6, r7, r8, r9, r10);
+
+ // get return value
+ __asm__ __volatile__ (
+ "mr %1, 3\n\t"
+ "mr %2, 4\n\t"
+ "fmr %0, 1\n\t"
+ : "=f" (dret), "=r" (r3), "=r" (r4) : );
+
+ MapReturn(r3, dret, pReturnTypeDescr->eTypeClass, pRegisterReturn);
+}
+
+// Macros for easier insertion of values to registers or stack
+// pSV - pointer to the source
+// nr - order of the value [will be increased if stored to register]
+// pFPR, pGPR - pointer to the registers
+// pDS - pointer to the stack [will be increased if stored here]
+
+// The value in %xmm register is already prepared to be retrieved as a float,
+// thus we treat float and double the same
+#define INSERT_FLOAT( pSV, nr, pFPR, pDS, bOverflow ) \
+ if ( nr < ppc64::MAX_SSE_REGS ) \
+ pFPR[nr++] = *reinterpret_cast<float *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
+
+#define INSERT_DOUBLE( pSV, nr, pFPR, pDS, bOverflow ) \
+ if ( nr < ppc64::MAX_SSE_REGS ) \
+ pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
+
+#define INSERT_INT64( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ppc64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
+
+#define INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ppc64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#define INSERT_INT16( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ppc64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, nr, pGPR, pDS, bOverflow ) \
+ if ( nr < ppc64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
+ else \
+ bOverFlow = true; \
+ if (bOverFlow) \
+ *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+
+//==================================================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ sal_uInt64 * pStack = (sal_uInt64 *)alloca( (nParams+3) * sizeof(sal_Int64) );
+ sal_uInt64 * pStackStart = pStack;
+
+ sal_uInt64 pGPR[ppc64::MAX_GPR_REGS];
+ sal_uInt32 nGPR = 0;
+
+ double pFPR[ppc64::MAX_SSE_REGS];
+ sal_uInt32 nFPR = 0;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ bool bOverFlow = false;
+
+ if (pReturnTypeDescr)
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "return type is %d\n", pReturnTypeDescr->eTypeClass);
+#endif
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+#ifdef CMC_DEBUG
+ fprintf(stderr, "simple return\n");
+#endif
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize ) : pUnoReturn);
+#ifdef CMC_DEBUG
+ fprintf(stderr, "pCppReturn/pUnoReturn is %lx/%lx", pCppReturn, pUnoReturn);
+#endif
+ INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack, bOverFlow );
+ }
+ }
+ // push "this" pointer
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
+#ifdef CMC_DEBUG
+ fprintf(stderr, "this pointer is %p\n", pAdjustedThisPtr);
+#endif
+ INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack, bOverFlow );
+
+ // Args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "n params is %d\n", nParams);
+#endif
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "param %d is %d %d %d\n", nPos, rParam.bOut, bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ),
+ pParamTypeDescr->eTypeClass);
+#endif
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+// uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr,
+ uno_copyAndConvertData( pCppArgs[nPos] = pStack, pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "hyper is %lx\n", pCppArgs[nPos]);
+#endif
+ INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+#ifdef CMC_DEBUG
+ fprintf(stderr, "long is %x\n", pCppArgs[nPos]);
+#endif
+ INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_FLOAT:
+ INSERT_FLOAT( pCppArgs[nPos], nFPR, pFPR, pStack, bOverFlow );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ INSERT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, pStack, bOverFlow );
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+
+ }
+ else // ptr to complex value | ref
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex type again %d\n", rParam.bIn);
+#endif
+ if (! rParam.bIn) // is pure out
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex size is %d\n", pParamTypeDescr->nSize );
+#endif
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "this one\n");
+#endif
+ uno_copyAndConvertData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "that one, passing %lx through\n", pUnoArgs[nPos]);
+#endif
+ pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack, bOverFlow );
+ }
+ }
+
+ try
+ {
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr,
+ pStackStart, ( pStack - pStackStart ),
+ pGPR, nGPR,
+ pFPR, nFPR );
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions,
+ *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy *> (pUnoI);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; //get then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_s390/cpp2uno.cxx
new file mode 100644
index 000000000000..f259387a98bf
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390/cpp2uno.cxx
@@ -0,0 +1,696 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "share.hxx"
+#include <stdio.h>
+#include <string.h>
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ int ng = 0; //number of gpr registers used
+ int nf = 0; //number of fpr regsiters used
+ void ** pCppStack; //temporary stack pointer
+
+ // gpreg: [ret *], this, [gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)gpreg;
+ gpreg++;
+ ng++;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ gpreg++;
+ ng++;
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value
+ {
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+
+ case typelib_TypeClass_DOUBLE:
+ if (nf < 2) {
+ pCppArgs[nPos] = fpreg;
+ pUnoArgs[nPos] = fpreg;
+ nf++;
+ fpreg += 2;
+ } else {
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw += 2;
+ }
+ break;
+
+ case typelib_TypeClass_FLOAT:
+ // fpreg are all double values so need to
+ // modify fpreg to be a single word float value
+ if (nf < 2) {
+// float tmp = (float) (*((double *)fpreg));
+// (*((float *) fpreg)) = tmp;
+ pCppArgs[nPos] = fpreg;
+ pUnoArgs[nPos] = fpreg;
+ nf++;
+ fpreg += 2;
+ } else {
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw += 1;
+ }
+ break;
+
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (ng < 4) {
+ pCppArgs[nPos] = gpreg;
+ pUnoArgs[nPos] = gpreg;
+ ng += 2;
+ gpreg += 2;
+ } else {
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw += 2;
+ }
+ break;
+
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_BOOLEAN:
+ if (ng < 5) {
+ pCppArgs[nPos] = (((char *)gpreg) + 3);
+ pUnoArgs[nPos] = (((char *)gpreg) + 3);
+ ng++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = (((char *)ovrflw) + 3);
+ pUnoArgs[nPos] = (((char *)ovrflw) + 3);
+ ovrflw++;
+ }
+ break;
+
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (ng < 5) {
+ pCppArgs[nPos] = (((char *)gpreg)+ 2);
+ pUnoArgs[nPos] = (((char *)gpreg)+ 2);
+ ng++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = (((char *)ovrflw) + 2);
+ pUnoArgs[nPos] = (((char *)ovrflw) + 2);
+ ovrflw++;
+ }
+ break;
+
+
+ default:
+ if (ng < 5) {
+ pCppArgs[nPos] = gpreg;
+ pUnoArgs[nPos] = gpreg;
+ ng++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = ovrflw;
+ pUnoArgs[nPos] = ovrflw;
+ ovrflw++;
+ }
+ break;
+
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+
+ if (ng < 5) {
+ pCppArgs[nPos] = *(void **)gpreg;
+ pCppStack = gpreg;
+ ng++;
+ gpreg++;
+ } else {
+ pCppArgs[nPos] = *(void **)ovrflw;
+ pCppStack = ovrflw;
+ ovrflw++;
+ }
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//============================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_uInt32 nOffsetAndIndex,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ sal_Int16 nVtableOffset = (nOffsetAndIndex >> 16);
+ sal_Int16 nFunctionIndex = (nOffsetAndIndex & 0xFFFF);
+
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ // _this_ ptr is patched cppu_XInterfaceProxy object
+ void * pThis;
+ if( nFunctionIndex & 0x8000 )
+ {
+ nFunctionIndex &= 0x7fff;
+ pThis = gpreg[1];
+ }
+ else
+ {
+ pThis = gpreg[0];
+ }
+
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pCppI );
+ }
+
+ // determine called method
+ OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pCppI );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static void privateSnippetExecutor( sal_uInt32 nOffsetAndIndex, void** gpregptr, void** fpregptr, void** ovrflw)
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr, "privateSnippetExecutor\n");
+#endif
+
+
+ sal_Int32 gpreg[8];
+ double fpreg[8];
+
+ memcpy( gpreg, gpregptr, 32);
+ memcpy( fpreg, fpregptr, 64);
+
+ volatile long nRegReturn[2];
+
+ typelib_TypeClass aType =
+ cpp_mediate( nOffsetAndIndex, (void**)gpreg, (void**)fpreg, ovrflw,
+ (sal_Int64*)nRegReturn );
+
+ switch( aType )
+ {
+
+ // move return value into register space
+ // (will be loaded by machine code snippet)
+
+ case typelib_TypeClass_BOOLEAN:
+ {
+ unsigned long tmp = (unsigned long)(*(unsigned char *)nRegReturn);
+ __asm__ volatile ( "l 2,%0\n\t" : :
+ "m"(tmp) : "2" );
+ break;
+ }
+ case typelib_TypeClass_BYTE:
+ {
+ long tmp = (long)(*(signed char *)nRegReturn);
+ __asm__ volatile ( "l 2,%0\n\t" : :
+ "m"(tmp) : "2" );
+ break;
+ }
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ {
+ unsigned long tmp = (unsigned long)(*(unsigned short *)nRegReturn);
+ __asm__ volatile ( "l 2,%0\n\t" : :
+ "m"(tmp) : "2" );
+ break;
+ }
+ case typelib_TypeClass_SHORT:
+ {
+ long tmp = (long)(*(short *)nRegReturn);
+ __asm__ volatile ( "l 2,%0\n\t" : :
+ "m"(tmp) : "2" );
+ break;
+ }
+ case typelib_TypeClass_FLOAT:
+ __asm__ volatile ( "le 0,%0\n\t" : :
+ "m" (*((float*)nRegReturn)) : "16" );
+ break;
+
+ case typelib_TypeClass_DOUBLE:
+ __asm__ volatile ( "ld 0,%0\n\t" : :
+ "m" (*((double*)nRegReturn)) : "16" );
+ break;
+
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ __asm__ volatile ( "lm 2,3,%0\n\t" : :
+ "m"(nRegReturn[0]) : "2", "3" );
+ break;
+
+ default:
+ __asm__ volatile ( "l 2,%0\n\t" : :
+ "m"(nRegReturn[0]) : "2" );
+ break;
+ }
+}
+
+const int codeSnippetSize = 50;
+
+unsigned char* codeSnippet( unsigned char * code, sal_Int16 nFunctionIndex, sal_Int16 nVtableOffset, bool simple_ret_type )
+{
+ sal_uInt32 nOffsetAndIndex = ( ( nVtableOffset ) << 16 ) | ( nFunctionIndex );
+
+ if (! simple_ret_type)
+ nOffsetAndIndex |= 0x8000;
+
+ OSL_ASSERT( sizeof (long) == 4 );
+
+ /* generate this code */
+ // lr %r0,%r13
+ // bras %r13,0x6
+ // .long privateSnippetExecutor
+ // .long nOffsetAndIndex
+ // stm %r2,%r6,8(%r15)
+ // std %f0,64(%r15)
+ // std %f2,72(%r15)
+
+ // l %r2,4(%r13)
+ // la %r3,8(%r15)
+ // la %r4,64(%r15)
+ // la %r5,96(%r15)
+ // l %r1,0(%r13)
+ // lr %r13,%r0
+ // br %r1
+
+ unsigned char * p = code;
+ *reinterpret_cast< sal_Int16 * >(p) = 0x180d;
+ p += sizeof(sal_Int16);
+ *reinterpret_cast< sal_Int32 * >(p) = 0xa7d50006;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) =
+ reinterpret_cast< sal_Int32 >(privateSnippetExecutor);
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) = nOffsetAndIndex;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) = 0x9026f008;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) = 0x6000f040;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) = 0x6020f048;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) = 0x5820d004;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) = 0x4130f008;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) = 0x4140f040;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) = 0x4150f060;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(p) = 0x5810d000;
+ p += sizeof(sal_Int32);
+ *reinterpret_cast< sal_Int16 * >(p) = 0x18d0;
+ p += sizeof(sal_Int16);
+ *reinterpret_cast< sal_Int16 * >(p) = 0x07f1;
+ p += sizeof(sal_Int16);
+
+ return (code + codeSnippetSize);
+}
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *, unsigned char const *)
+{
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0;
+ slots[-1].fn = 0;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+#ifdef CMC_DEBUG
+ fprintf(stderr, "in addLocalFunctions functionOffset is %x\n",functionOffset);
+ fprintf(stderr, "in addLocalFunctions vtableOffset is %x\n",vtableOffset);
+#endif
+
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390/except.cxx b/bridges/source/cpp_uno/gcc3_linux_s390/except.cxx
new file mode 100644
index 000000000000..c0de95532515
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390/except.cxx
@@ -0,0 +1,289 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * )
+{
+}
+
+//==================================================================================================
+static OUString toUNOname( char const * p ) SAL_THROW( () )
+{
+#if OSL_DEBUG_LEVEL > 1
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+}
+
+//==================================================================================================
+class RTTI
+{
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+{
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iRttiFind( m_rttis.find( unoName ) );
+ if (iRttiFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
+ if (iFind == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with _ZTI
+ char const * rttiName = symName.getStr() +4;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iFind->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iRttiFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void deleteException( void * pExc )
+{
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ terminate();
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ terminate();
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno )
+{
+ OSL_ENSURE( header, "### no exception header!!!" );
+ if (! header)
+ terminate();
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" );
+ if (! pExcTypeDescr)
+ terminate();
+
+ // construct uno exception any
+ ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ ::typelib_typedescription_release( pExcTypeDescr );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_s390/makefile.mk
new file mode 100644
index 000000000000..bda85f359210
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390/makefile.mk
@@ -0,0 +1,77 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)$(CPUNAME)" == "GCCLINUX3gcc3S390"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer -fno-strict-aliasing
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390/share.hxx b/bridges/source/cpp_uno/gcc3_linux_s390/share.hxx
new file mode 100644
index 000000000000..4ec09c29ff0a
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390/share.hxx
@@ -0,0 +1,94 @@
+/* -*- 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 "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+ void dummy_can_throw_anything( char const * );
+
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_s390/uno2cpp.cxx
new file mode 100644
index 000000000000..a87cc8e182c8
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390/uno2cpp.cxx
@@ -0,0 +1,637 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+static sal_Int32
+invoke_count_words(char * pPT)
+{
+ sal_Int32 overflow = 0, gpr = 0, fpr = 0;
+ int c; // character of parameter type being decoded
+
+ while (*pPT != 'X') {
+ c = *pPT;
+ switch (c) {
+ case 'D': /* type is double */
+ if (fpr < 2) fpr++; else overflow+=2;
+ break;
+
+ case 'F': /* type is float */
+ if (fpr < 2) fpr++; else overflow++;
+ break;
+
+ case 'H': /* type is long long */
+ if (gpr < 4) gpr+=2; else gpr=5, overflow+=2;
+ break;
+
+ case 'S':
+ case 'T':
+ case 'B':
+ case 'C':
+ if (gpr < 5) gpr++; else overflow++;
+ break;
+
+ default:
+ if (gpr < 5) gpr++; else overflow++;
+ break;
+ }
+ pPT++;
+ }
+ /* Round up number of overflow words to ensure stack
+ stays aligned to 8 bytes. */
+ return (overflow + 1) & ~1;
+}
+
+static void
+//invoke_copy_to_stack(sal_Int32 paramCount, sal_Int32 * pStackLongs, char * pPT, sal_Int32* d_ov, sal_Int32 overflow)
+invoke_copy_to_stack(sal_Int32 * pStackLongs, char * pPT, sal_Int32* d_ov, sal_Int32 overflow)
+{
+ sal_Int32 *d_gpr = d_ov + overflow;
+ sal_Int64 *d_fpr = (sal_Int64 *)(d_gpr + 5);
+ sal_Int32 gpr = 0, fpr = 0;
+ char c;
+
+ while (*pPT != 'X') {
+ c = *pPT;
+ switch (c) {
+ case 'D': /* type is double */
+ if (fpr < 2)
+ *((double*) d_fpr) = *((double *)pStackLongs), d_fpr++, fpr++;
+ else
+ *((double*) d_ov ) = *((double *)pStackLongs), d_ov+=2;
+
+ pStackLongs += 2;
+ break;
+
+ case 'F': /* type is float */
+ if (fpr < 2) {
+ *((sal_Int64*) d_fpr) = 0;
+ *((float*) d_fpr) = *((float *)pStackLongs), d_fpr++, fpr++;
+ }
+ else {
+ *((sal_Int64*) d_ov) = 0;
+ *((float*) d_ov ) = *((float *)pStackLongs), d_ov++;
+ }
+
+ pStackLongs += 1;
+ break;
+
+ case 'H': /* type is long long */
+ if (gpr < 4) {
+ *((sal_Int64*) d_gpr) = *((sal_Int64*) pStackLongs), d_gpr+=2, gpr+=2;
+ }
+ else {
+ *((sal_Int64*) d_ov ) = *((sal_Int64*) pStackLongs), d_ov+=2, gpr=5;
+ }
+ pStackLongs += 2;
+ break;
+
+ case 'S':
+ if (gpr < 5)
+ *((sal_uInt32*)d_gpr) = *((unsigned short*)pStackLongs), d_gpr++, gpr++;
+ else
+ *((sal_uInt32*)d_ov ) = *((unsigned short*)pStackLongs), d_ov++;
+ pStackLongs += 1;
+ break;
+
+ case 'T':
+ if (gpr < 5)
+ *((sal_Int32*)d_gpr) = *((signed short*)pStackLongs), d_gpr++, gpr++;
+ else
+ *((sal_Int32*)d_ov ) = *((signed short*)pStackLongs), d_ov++;
+ pStackLongs += 1;
+ break;
+
+ case 'B':
+ if (gpr < 5)
+ *((sal_uInt32*)d_gpr) = *((unsigned char*)pStackLongs), d_gpr++, gpr++;
+ else
+ *((sal_uInt32*)d_ov ) = *((unsigned char*)pStackLongs), d_ov++;
+ pStackLongs += 1;
+ break;
+
+ case 'C':
+ if (gpr < 5)
+ *((sal_Int32*)d_gpr) = *((signed char*)pStackLongs), d_gpr++, gpr++;
+ else
+ *((sal_Int32*)d_ov ) = *((signed char*)pStackLongs), d_ov++;
+ pStackLongs += 1;
+ break;
+
+ default:
+ if (gpr < 5)
+ *((sal_Int32*)d_gpr) = *pStackLongs, d_gpr++, gpr++;
+ else
+ *((sal_Int32*)d_ov ) = *pStackLongs, d_ov++;
+ pStackLongs += 1;
+ break;
+ }
+ pPT++;
+ }
+}
+
+//==================================================================================================
+static void callVirtualMethod(
+ void * pThis,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ char * pPT,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs)
+{
+
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ // the basic idea here is to use gpr[5] as a storage area for
+ // the future values of registers r2 to r6 needed for the call,
+ // and similarly fpr[2] as a storage area for the future values
+ // of floating point registers f0 to f2
+
+ sal_Int32 *vtable = *(sal_Int32 **)pThis;
+// sal_Int32 method = vtable[nVtableIndex + 2];
+ sal_Int32 method = vtable[nVtableIndex];
+ sal_Int32 overflow = invoke_count_words (pPT);
+ sal_Int32 result;
+ volatile double dret; // temporary function return values
+ volatile float fret;
+ volatile int iret, iret2;
+
+ void * dummy = alloca(32); // dummy alloca to force r11 usage for exception handling
+
+ __asm__ __volatile__
+ (
+ "lr 7,15\n\t"
+ "ahi 7,-48\n\t"
+
+ "lr 3,%2\n\t"
+ "sll 3,2\n\t"
+ "lcr 3,3\n\t"
+ "l 2,0(15)\n\t"
+ "la 15,0(3,7)\n\t"
+ "st 2,0(15)\n\t"
+
+ "lr 2,%0\n\t"
+ "lr 3,%1\n\t"
+ "la 4,96(15)\n\t"
+ "lr 5,%2\n\t"
+ "basr 14,%3\n\t"
+
+ "ld 0,116(7)\n\t"
+ "ld 2,124(7)\n\t"
+ "lm 2,6,96(7)\n\t"
+ :
+ : "r" (pStackLongs),
+ "r" (pPT),
+ "r" (overflow),
+ "a" (invoke_copy_to_stack),
+ "a" (method),
+ "X" (dummy)
+ : "2", "3", "4", "5", "6", "7", "memory"
+ );
+// "basr 14,%8\n\t"
+
+ (*(void (*)())method)();
+
+ __asm__ __volatile__
+ (
+ "la 15,48(7)\n\t"
+
+ "lr %2,2\n\t"
+ "lr %3,3\n\t"
+ "ler %0,0\n\t"
+ "ldr %1,0\n\t"
+
+ : "=f" (fret), "=f" (dret), "=r" (iret), "=r" (iret2)
+ );
+
+ switch( eReturnType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+// ((long*)pRegisterReturn)[0] = iret;
+ ((long*)pRegisterReturn)[1] = iret2;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ ((long*)pRegisterReturn)[0] = iret;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = (unsigned short)iret;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = (unsigned char)iret;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float*)pRegisterReturn = fret;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double*)pRegisterReturn = dret;
+ break;
+ }
+}
+
+
+//============================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ char * pCppStack =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ char * pCppStackStart = pCppStack;
+
+ // need to know parameter types for callVirtualMethod so generate a signature string
+ char * pParamType = (char *) alloca(nParams+2);
+ char * pPT = pParamType;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ *pPT++ = 'I'; //signify that a complex return type on stack
+ pCppStack += sizeof(void *);
+ }
+ }
+ // push "this" pointer
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+ *pPT++ = 'I';
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+
+ // we need to know type of each param so that we know whether to use
+ // gpr or fpr to pass in parameters:
+ // Key: I - int, long, pointer, etc means pass in gpr
+ // B - byte value passed in gpr
+ // S - short value passed in gpr
+ // F - float value pass in fpr
+ // D - double value pass in fpr
+ // H - long long int pass in proper pairs of gpr (3,4) (5,6), etc
+ // X - indicates end of parameter description string
+
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ *pPT++ = 'I';
+ break;
+ case typelib_TypeClass_SHORT:
+ *pPT++ = 'T';
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *pPT++ = 'S';
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ *pPT++ = 'B';
+ break;
+ case typelib_TypeClass_BYTE:
+ *pPT++ = 'C';
+ break;
+ case typelib_TypeClass_FLOAT:
+ *pPT++ = 'F';
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *pPT++ = 'D';
+ pCppStack += sizeof(sal_Int32); // extra long
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *pPT++ = 'H';
+ pCppStack += sizeof(sal_Int32); // extra long
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // KBH: FIXME: is this the right way to pass these
+ *pPT++='I';
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // terminate the signature string
+ *pPT++='X';
+ *pPT=0;
+
+ try
+ {
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass, pParamType,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions,
+ *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr, "unoInterfaceProxyDispatch\n");
+#endif
+
+
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy *> (pUnoI);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; //get then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390x/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_s390x/cpp2uno.cxx
new file mode 100644
index 000000000000..b491f661bff9
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390x/cpp2uno.cxx
@@ -0,0 +1,658 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "share.hxx"
+#include <stdio.h>
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr, "as far as cpp2uno_call\n");
+#endif
+ int ng = 0; //number of gpr registers used
+ int nf = 0; //number of fpr regsiters used
+
+ // gpreg: [ret *], this, [gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)gpreg;
+ gpreg++;
+ ng++;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ gpreg++;
+ ng++;
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int64), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "arg %d of %d\n", nPos, nParams);
+#endif
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "simple\n");
+#endif
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_FLOAT:
+ case typelib_TypeClass_DOUBLE:
+ if (nf < s390x::MAX_SSE_REGS)
+ {
+ if (pParamTypeDescr->eTypeClass == typelib_TypeClass_FLOAT)
+ {
+ float tmp = (float) (*((double *)fpreg));
+ (*((float *) fpreg)) = tmp;
+ }
+
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
+ nf++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ ovrflw++;
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_BOOLEAN:
+ if (ng < s390x::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-1));
+ ng++;
+ gpreg++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-1));
+ ovrflw++;
+ }
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (ng < s390x::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-2));
+ ng++;
+ gpreg++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-2));
+ ovrflw++;
+ }
+ break;
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (ng < s390x::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-4));
+ ng++;
+ gpreg++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-4));
+ ovrflw++;
+ }
+ break;
+ default:
+ if (ng < s390x::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg++;
+ ng++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
+ ovrflw++;
+ }
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+#ifdef CMC_DEBUG
+ fprintf(stderr, "complex, ng is %d\n", ng);
+#endif
+
+ void *pCppStack; //temporary stack pointer
+
+ if (ng < s390x::MAX_GPR_REGS)
+ {
+ pCppArgs[nPos] = pCppStack = *gpreg++;
+ ng++;
+ }
+ else
+ {
+ pCppArgs[nPos] = pCppStack = *ovrflw;
+ ovrflw++;
+ }
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "end of params\n");
+#endif
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//============================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_uInt64 nOffsetAndIndex,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int64)==sizeof(void *), "### unexpected!" );
+
+ sal_Int32 nVtableOffset = (nOffsetAndIndex >> 32);
+ sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFFFFFF);
+
+#ifdef CMC_DEBUG
+ fprintf(stderr, "nVTableOffset, nFunctionIndex are %x %x\n", nVtableOffset, nFunctionIndex);
+#endif
+
+#ifdef CMC_DEBUG
+ // Let's figure out what is really going on here
+ {
+ fprintf( stderr, "= cpp_mediate () =\nGPR's (%d): ", 5 );
+ for ( unsigned int i = 0; i < 5; ++i )
+ fprintf( stderr, "0x%lx, ", gpreg[i] );
+ fprintf( stderr, "\n");
+ fprintf( stderr, "\nFPR's (%d): ", 4 );
+ for ( unsigned int i = 0; i < 4; ++i )
+ fprintf( stderr, "0x%lx (%f), ", fpreg[i], fpreg[i] );
+ fprintf( stderr, "\n");
+ }
+#endif
+
+
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+
+ // _this_ ptr is patched cppu_XInterfaceProxy object
+ void * pThis;
+ if( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = gpreg[1];
+ }
+ else
+ {
+ pThis = gpreg[0];
+ }
+
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pCppI );
+ }
+
+ // determine called method
+ OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pCppI );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+long privateSnippetExecutor(long r2, long r3, long r4, long r5, long r6, long firstonstack)
+{
+ register long r0 asm("r0");
+ sal_uInt64 nOffsetAndIndex = r0;
+
+ long sp = (long)&firstonstack;
+
+ sal_uInt64 gpreg[s390x::MAX_GPR_REGS];
+ gpreg[0] = r2;
+ gpreg[1] = r3;
+ gpreg[2] = r4;
+ gpreg[3] = r5;
+ gpreg[4] = r6;
+
+ double fpreg[s390x::MAX_SSE_REGS];
+ register double f0 asm("f0"); fpreg[0] = f0;
+ register double f2 asm("f2"); fpreg[1] = f2;
+ register double f4 asm("f4"); fpreg[2] = f4;
+ register double f6 asm("f6"); fpreg[3] = f6;
+
+ volatile long nRegReturn[1];
+#ifdef CMC_DEBUG
+ fprintf(stderr, "before mediate with %lx\n",nOffsetAndIndex);
+ fprintf(stderr, "doubles are %f %f %f %f\n", fpreg[0], fpreg[1], fpreg[2], fpreg[3]);
+#endif
+ typelib_TypeClass aType =
+ cpp_mediate( nOffsetAndIndex, (void**)gpreg, (void**)fpreg, (void**)sp,
+ (sal_Int64*)nRegReturn );
+#ifdef CMC_DEBUG
+ fprintf(stderr, "after mediate ret is %lx %ld\n", nRegReturn[0], nRegReturn[0]);
+#endif
+
+ switch( aType )
+ {
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ nRegReturn[0] = (unsigned long)(*(unsigned char *)nRegReturn);
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_SHORT:
+ nRegReturn[0] = (unsigned long)(*(unsigned short *)nRegReturn);
+ break;
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_LONG:
+ nRegReturn[0] = (unsigned long)(*(unsigned int *)nRegReturn);
+ break;
+ case typelib_TypeClass_VOID:
+ default:
+ break;
+ case typelib_TypeClass_FLOAT:
+ {
+ double tmp = (double) (*((float *)nRegReturn));
+ (*((double *) nRegReturn)) = tmp;
+ }
+ //deliberate fall through
+ case typelib_TypeClass_DOUBLE:
+ __asm__ ( "ld 0,%0\n\t"
+ : : "m" (*((double*)nRegReturn)) );
+ break;
+ }
+ return nRegReturn[0];
+}
+
+const int codeSnippetSize = 32;
+
+unsigned char *codeSnippet( unsigned char * code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, bool simple_ret_type )
+{
+ sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_Int64) nFunctionIndex );
+
+ if (! simple_ret_type)
+ nOffsetAndIndex |= 0x80000000;
+
+ unsigned char * p = code;
+ *(short *)&p[0] = 0x0d10; /* basr %r1,0 */
+ *(short *)&p[2] = 0xeb01; /* lmg %r0,%r1,14(%r1) */
+ *(short *)&p[4] = 0x100e;
+ *(short *)&p[6] = 0x0004;
+ *(short *)&p[8] = 0x07f1; /* br %r1 */
+ *(long *)&p[16] = (long)nOffsetAndIndex;
+ *(long *)&p[24] = (long)&privateSnippetExecutor;
+ return (code + codeSnippetSize);
+}
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const *, unsigned char const *)
+{
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0;
+ slots[-1].fn = 0;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+#ifdef CMC_DEBUG
+ fprintf(stderr, "in addLocalFunctions functionOffset is %x\n",functionOffset);
+ fprintf(stderr, "in addLocalFunctions vtableOffset is %x\n",vtableOffset);
+#endif
+
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390x/except.cxx b/bridges/source/cpp_uno/gcc3_linux_s390x/except.cxx
new file mode 100644
index 000000000000..c0de95532515
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390x/except.cxx
@@ -0,0 +1,289 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * )
+{
+}
+
+//==================================================================================================
+static OUString toUNOname( char const * p ) SAL_THROW( () )
+{
+#if OSL_DEBUG_LEVEL > 1
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+}
+
+//==================================================================================================
+class RTTI
+{
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+{
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iRttiFind( m_rttis.find( unoName ) );
+ if (iRttiFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
+ if (iFind == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with _ZTI
+ char const * rttiName = symName.getStr() +4;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iFind->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iRttiFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void deleteException( void * pExc )
+{
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ terminate();
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ terminate();
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno )
+{
+ OSL_ENSURE( header, "### no exception header!!!" );
+ if (! header)
+ terminate();
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" );
+ if (! pExcTypeDescr)
+ terminate();
+
+ // construct uno exception any
+ ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ ::typelib_typedescription_release( pExcTypeDescr );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390x/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_s390x/makefile.mk
new file mode 100644
index 000000000000..9539dd6edf9b
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390x/makefile.mk
@@ -0,0 +1,77 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)$(CPUNAME)" == "GCCLINUX3gcc3S390X"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer -fno-strict-aliasing
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390x/share.hxx b/bridges/source/cpp_uno/gcc3_linux_s390x/share.hxx
new file mode 100644
index 000000000000..69176377606b
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390x/share.hxx
@@ -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.
+ *
+ ************************************************************************/
+
+#include "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+ void dummy_can_throw_anything( char const * );
+
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+namespace s390x
+{
+ enum s390xlimits { MAX_GPR_REGS = 5, MAX_SSE_REGS = 4 };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_s390x/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_s390x/uno2cpp.cxx
new file mode 100644
index 000000000000..d3fec618c301
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_s390x/uno2cpp.cxx
@@ -0,0 +1,539 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "share.hxx"
+
+#include <stdio.h>
+#include <string.h>
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+void MapReturn(long r2, double f0, typelib_TypeClass eTypeClass, sal_uInt64* pRegisterReturn)
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr,"Mapping Return with %lx %ld %f\n", r2, r2, f0);
+#endif
+ switch (eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *pRegisterReturn = r2;
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ *(unsigned int*)pRegisterReturn = (unsigned int)r2;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = (unsigned short)r2;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = (unsigned char)r2;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *reinterpret_cast<float *>( pRegisterReturn ) = f0;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *reinterpret_cast<double *>( pRegisterReturn ) = f0;
+ break;
+ default:
+ break;
+ }
+#ifdef CMC_DEBUG
+ fprintf(stderr, "end of MapReturn with %x\n", pRegisterReturn ? *pRegisterReturn : 0);
+#endif
+}
+
+#define INSERT_FLOAT( pSV, nr, pFPR, pDS ) \
+ { \
+ if ( nr < s390x::MAX_SSE_REGS ) \
+ { \
+ pFPR[nr++] = *reinterpret_cast<float *>( pSV ); \
+ } \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+ }
+
+#define INSERT_DOUBLE( pSV, nr, pFPR, pDS ) \
+ if ( nr < s390x::MAX_SSE_REGS ) \
+ pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
+
+#define INSERT_INT64( pSV, nr, pGPR, pDS ) \
+ if ( nr < s390x::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
+
+#define INSERT_INT32( pSV, nr, pGPR, pDS ) \
+ if ( nr < s390x::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#define INSERT_INT16( pSV, nr, pGPR, pDS ) \
+ if ( nr < s390x::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, nr, pGPR, pDS ) \
+ if ( nr < s390x::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+
+namespace
+{
+//==================================================================================================
+void callVirtualMethod(
+ void * pThis, sal_Int32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescription * pReturnTypeDescr,
+ sal_uInt64 *pStack, sal_uInt32 nStack,
+ sal_uInt64 *pGPR, sal_uInt32 nGPR,
+ double *pFPR, sal_uInt32 nFPR)
+{
+ // Should not happen, but...
+ if ( nFPR > s390x::MAX_SSE_REGS )
+ nFPR = s390x::MAX_SSE_REGS;
+ if ( nGPR > s390x::MAX_GPR_REGS )
+ nGPR = s390x::MAX_GPR_REGS;
+
+#ifdef CMC_DEBUG
+ // Let's figure out what is really going on here
+ {
+ fprintf( stderr, "= nStack is %d\n", nStack );
+ fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
+ for ( unsigned int i = 0; i < nGPR; ++i )
+ fprintf( stderr, "0x%lx, ", pGPR[i] );
+ fprintf( stderr, "\nFPR's (%d): ", nFPR );
+ for ( unsigned int i = 0; i < nFPR; ++i )
+ fprintf( stderr, "0x%lx (%f), ", pFPR[i], pFPR[i] );
+ fprintf( stderr, "\nStack (%d): ", nStack );
+ for ( unsigned int i = 0; i < nStack; ++i )
+ fprintf( stderr, "0x%lx, ", pStack[i] );
+ fprintf( stderr, "\n" );
+ fprintf( stderr, "pRegisterReturn is %p\n", pRegisterReturn);
+ }
+#endif
+
+ // Load parameters to stack, if necessary
+ // Stack, if used, must be 8-bytes aligned
+ sal_uInt64 *stack = (sal_uInt64 *) __builtin_alloca( nStack * 8 );
+ memcpy( stack, pStack, nStack * 8 );
+
+ // To get pointer to method
+ // a) get the address of the vtable
+ sal_uInt64 pMethod = *((sal_uInt64 *)pThis);
+ // b) get the address from the vtable entry at offset
+ pMethod += 8 * nVtableIndex;
+ pMethod = *((sal_uInt64 *)pMethod);
+
+ typedef void (* FunctionCall )( sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64 );
+ FunctionCall pFunc = (FunctionCall)pMethod;
+
+ switch (nFPR) //deliberate fall through
+ {
+ case 4:
+ asm volatile("ld 6,%0" :: "m"(pFPR[3]) : "16");
+ case 3:
+ asm volatile("ld 4,%0" :: "m"(pFPR[2]) : "16");
+ case 2:
+ asm volatile("ld 2,%0" :: "m"(pFPR[1]) : "16");
+ case 1:
+ asm volatile("ld 0,%0" :: "m"(pFPR[0]) : "16");
+ default:
+ break;
+ }
+
+ volatile long r2;
+ volatile double f0;
+
+ (*pFunc)(pGPR[0], pGPR[1], pGPR[2], pGPR[3], pGPR[4]);
+
+ __asm__ __volatile__ (
+ "lgr %0,2\n\t"
+ "ldr %1,0\n\t"
+ : "=r" (r2), "=f" (f0)
+ : :
+ );
+
+ MapReturn(r2, f0, pReturnTypeDescr->eTypeClass, (sal_uInt64*)pRegisterReturn);
+}
+
+
+//============================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ sal_uInt64 * pStack = (sal_uInt64 *)alloca( (nParams+3) * sizeof(sal_Int64) );
+ sal_uInt64 * pStackStart = pStack;
+
+ sal_uInt64 pGPR[s390x::MAX_GPR_REGS];
+ sal_uInt32 nGPR = 0;
+
+ double pFPR[s390x::MAX_SSE_REGS];
+ sal_uInt32 nFPR = 0;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack );
+ }
+ }
+ // push "this" pointer
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
+
+ INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int64), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_FLOAT:
+ INSERT_FLOAT( pCppArgs[nPos], nFPR, pFPR, pStack );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ INSERT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, pStack );
+ break;
+ default:
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack );
+ }
+ }
+
+ try
+ {
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr,
+ pStackStart, (pStack - pStackStart),
+ pGPR, nGPR,
+ pFPR, nFPR );
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions,
+ *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+#ifdef CMC_DEBUG
+ fprintf(stderr, "unoInterfaceProxyDispatch\n");
+#endif
+
+
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy *> (pUnoI);
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; //get then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_sparc/call.s b/bridges/source/cpp_uno/gcc3_linux_sparc/call.s
new file mode 100644
index 000000000000..09c611237968
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_sparc/call.s
@@ -0,0 +1,10 @@
+.global doFlushCode
+doFlushCode:
+.L: flush %o0
+ deccc %o1
+ bne .L
+ add %o0, 8, %o0
+ retl
+ nop
+.size doFlushCode,(.-doFlushCode)
+.align 8
diff --git a/bridges/source/cpp_uno/gcc3_linux_sparc/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_sparc/cpp2uno.cxx
new file mode 100644
index 000000000000..1546432e5980
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_sparc/cpp2uno.cxx
@@ -0,0 +1,578 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <com/sun/star/uno/genfunc.hxx>
+#include <typelib/typedescription.hxx>
+#include <uno/data.h>
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+#include "share.hxx"
+
+using namespace com::sun::star::uno;
+
+namespace
+{
+//==================================================================================================
+static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ // pCallStack: [ret ptr], this, params
+ char * pCppStack = (char *)pCallStack;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void**)pCppStack;
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ pCppStack += sizeof( void* );
+ }
+ }
+ // pop this
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = CPPU_CURRENT_NAMESPACE::adjustPointer(pCppStack, pParamTypeDescr);
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ {
+ if ((reinterpret_cast< long >(pCppStack) & 7) != 0)
+ {
+ OSL_ASSERT( sizeof (double) == sizeof (sal_Int64) );
+ void * pDest = alloca( sizeof (sal_Int64) );
+ *reinterpret_cast< sal_Int32 * >(pDest) =
+ *reinterpret_cast< sal_Int32 const * >(pCppStack);
+ *(reinterpret_cast< sal_Int32 * >(pDest) + 1) =
+ *(reinterpret_cast< sal_Int32 const * >(pCppStack) + 1);
+ pCppArgs[nPos] = pUnoArgs[nPos] = pDest;
+ }
+ pCppStack += sizeof (sal_Int32); // extra long
+ break;
+ default:
+ break;
+ }
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ pCppArgs[nPos] = *(void **)pCppStack;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ CPPU_CURRENT_NAMESPACE::raiseException(&aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: this, params
+ // eventual [ret*] lies at pCallStack -1
+ // so count down pCallStack by one to keep it simple
+ // pCallStack: this, params
+ // eventual [ret*] lies at pCallStack -1
+ // so count down pCallStack by one to keep it simple
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ static_cast< char * >(*pCallStack) - nVtableOffset);
+ if ((nFunctionIndex & 0x80000000) != 0) {
+ nFunctionIndex &= 0x7FFFFFFF;
+ --pCallStack;
+ }
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex,
+ "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException( rtl::OUString::createFromAscii("illegal vtable index!"), (XInterface *)pCppI );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+#if defined BRIDGES_DEBUG
+ OString cstr( OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex );
+#endif
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[2] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pCallStack[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = pCallStack[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(rtl::OUString::createFromAscii("no member description found!"), (XInterface *)pCppI );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+ return eRet;
+}
+
+
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static void cpp_vtable_call()
+{
+ sal_Int64 nRegReturn;
+ int nFunctionIndex;
+ void** pCallStack;
+ int vTableOffset;
+
+void * pRegReturn = &nRegReturn;
+
+ __asm__( "st %%i0, %0\n\t"
+ "st %%i1, %1\n\t"
+ "st %%i2, %2\n\t"
+ : : "m"(nFunctionIndex), "m"(pCallStack), "m"(vTableOffset) );
+
+// fprintf(stderr,"cpp_mediate nFunctionIndex=%x\n",nFunctionIndex);
+// fflush(stderr);
+
+ sal_Bool bComplex = nFunctionIndex & 0x80000000 ? sal_True : sal_False;
+ typelib_TypeClass aType =
+ cpp_mediate( nFunctionIndex, vTableOffset, pCallStack+17, (sal_Int64*)&nRegReturn );
+
+ switch( aType )
+ {
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ __asm__( "ld %0, %%l0\n\t"
+ "ldsb [%%l0], %%i0\n"
+ : : "m"(pRegReturn) );
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ __asm__( "ld %0, %%l0\n\t"
+ "ldsh [%%l0], %%i0\n"
+ : : "m"(pRegReturn) );
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ __asm__( "ld %0, %%l0\n\t"
+ "ld [%%l0], %%i0\n\t"
+ "add %%l0, 4, %%l0\n\t"
+ "ld [%%l0], %%i1\n\t"
+ : : "m"(pRegReturn) );
+
+ break;
+ case typelib_TypeClass_FLOAT:
+ __asm__( "ld %0, %%l0\n\t"
+ "ld [%%l0], %%f0\n"
+ : : "m"(pRegReturn) );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ __asm__( "ld %0, %%l0\n\t"
+ "ldd [%%l0], %%f0\n"
+ : : "m"(pRegReturn) );
+ break;
+ case typelib_TypeClass_VOID:
+ break;
+ default:
+ __asm__( "ld %0, %%l0\n\t"
+ "ld [%%l0], %%i0\n"
+ : : "m"(pRegReturn) );
+ break;
+ }
+
+ if( bComplex )
+ {
+ __asm__( "add %i7, 4, %i7\n\t" );
+ // after call to complex return valued funcion there is an unimp instruction
+ }
+
+}
+//__________________________________________________________________________________________________
+
+int const codeSnippetSize = 56;
+unsigned char * codeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ bool simpleRetType)
+{
+ sal_uInt32 index = functionIndex;
+ if (!simpleRetType) {
+ index |= 0x80000000;
+ }
+ unsigned int * p = reinterpret_cast< unsigned int * >(code);
+ OSL_ASSERT(sizeof (unsigned int) == 4);
+ // st %o0, [%sp+68]:
+ *p++ = 0xD023A044;
+ // st %o1, [%sp+72]:
+ *p++ = 0xD223A048;
+ // st %o2, [%sp+76]:
+ *p++ = 0xD423A04C;
+ // st %o3, [%sp+80]:
+ *p++ = 0xD623A050;
+ // st %o4, [%sp+84]:
+ *p++ = 0xD823A054;
+ // st %o5, [%sp+88]:
+ *p++ = 0xDA23A058;
+ // sethi %hi(index), %o0:
+ *p++ = 0x11000000 | (index >> 10);
+ // or %o0, %lo(index), %o0:
+ *p++ = 0x90122000 | (index & 0x3FF);
+ // sethi %hi(vtableOffset), %o2:
+ *p++ = 0x15000000 | (vtableOffset >> 10);
+ // or %o2, %lo(vtableOffset), %o2:
+ *p++ = 0x9412A000 | (vtableOffset & 0x3FF);
+ // sethi %hi(cpp_vtable_call), %o3:
+ *p++ = 0x17000000 | (reinterpret_cast< unsigned int >(cpp_vtable_call) >> 10);
+ // or %o3, %lo(cpp_vtable_call), %o3:
+ *p++ = 0x9612E000 | (reinterpret_cast< unsigned int >(cpp_vtable_call) & 0x3FF);
+ // jmpl %o3, %g0:
+ *p++ = 0x81C2C000;
+ // mov %sp, %o1:
+ *p++ = 0x9210000E;
+ OSL_ASSERT(
+ reinterpret_cast< unsigned char * >(p) - code <= codeSnippetSize);
+ return code + codeSnippetSize;
+}
+
+} //end of namespace
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0; //null
+ slots[-1].fn = 0; //destructor
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vTableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vTableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(code, functionOffset++, vTableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet(
+ code, functionOffset++, vTableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+// use flush code from cc50_solaris_sparc
+
+extern "C" void doFlushCode(unsigned long address, unsigned long count);
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const * begin, unsigned char const * end)
+{
+ unsigned long n = end - begin;
+ if (n != 0) {
+ unsigned long adr = reinterpret_cast< unsigned long >(begin);
+ unsigned long off = adr & 7;
+ doFlushCode(adr - off, (n + off + 7) >> 3);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_sparc/except.cxx b/bridges/source/cpp_uno/gcc3_linux_sparc/except.cxx
new file mode 100644
index 000000000000..6e61196df98e
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_sparc/except.cxx
@@ -0,0 +1,330 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * )
+{
+}
+
+//==================================================================================================
+static OUString toUNOname( char const * p ) SAL_THROW( () )
+{
+#if defined BRIDGES_DEBUG
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if defined BRIDGES_DEBUG
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+}
+
+//==================================================================================================
+class RTTI
+{
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+{
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iiFind( m_generatedRttis.find( unoName ) );
+ if (iiFind == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with _ZTI
+ char const * rttiName = symName.getStr() +4;
+#if defined BRIDGES_DEBUG
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iiFind->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void deleteException( void * pExc )
+{
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+#if defined BRIDGES_DEBUG
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() );
+#endif
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get typedescription for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+{
+ if (! header)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if defined _DEBUG
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+#if defined BRIDGES_DEBUG
+ OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if defined _DEBUG
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_sparc/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_sparc/makefile.mk
new file mode 100644
index 000000000000..3940038247c3
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_sparc/makefile.mk
@@ -0,0 +1,85 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)" == "GCCLINUXS"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# # work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer -fno-strict-aliasing
+
+CFLAGSNOOPT=-O0
+
+NOOPTFILES = \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/call.obj
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/call.obj
+
+
+SHL1TARGET=$(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS= $(SLOFILES)
+SHL1LIBS =$(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.s
+ $(ASM) $(AFLAGS) -o $(SLO)$/$(@:b).o $< && touch $@
diff --git a/bridges/source/cpp_uno/gcc3_linux_sparc/share.hxx b/bridges/source/cpp_uno/gcc3_linux_sparc/share.hxx
new file mode 100644
index 000000000000..3526f19082cd
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_sparc/share.hxx
@@ -0,0 +1,100 @@
+/* -*- 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 "uno/mapping.h"
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+namespace CPPU_CURRENT_NAMESPACE
+{
+void dummy_can_throw_anything( char const * );
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+
+inline char* adjustPointer( char* pIn, typelib_TypeDescription* pType )
+{
+ switch( pType->nSize )
+ {
+ case 1: return pIn + 3;
+ case 2: return pIn + 2;
+ case 3: return pIn + 1;
+ // Huh ? perhaps a char[3] ? Though that would be a pointer
+ // well, we have it anyway for symmetry
+ }
+ return pIn;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_sparc/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_sparc/uno2cpp.cxx
new file mode 100644
index 000000000000..0cf6d21c80e7
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_sparc/uno2cpp.cxx
@@ -0,0 +1,603 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <malloc.h>
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "share.hxx"
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+namespace
+{
+//==================================================================================================
+// The call instruction within the asm section of callVirtualMethod may throw
+// exceptions. So that the compiler handles this correctly, it is important
+// that (a) callVirtualMethod might call dummy_can_throw_anything (although this
+// never happens at runtime), which in turn can throw exceptions, and (b)
+// callVirtualMethod is not inlined at its call site (so that any exceptions are
+// caught which are thrown from the instruction calling callVirtualMethod):
+
+void callVirtualMethod( void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs ) __attribute__((noinline));
+
+void callVirtualMethod( void * pAdjustedThisPtr,
+ sal_Int32 /* nVtableIndex */,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+#if OSL_DEBUG_LEVEL > 0
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs)
+#else
+ sal_Int32 * /*pStackLongs*/,
+ sal_Int32 /*nStackLongs*/)
+#endif
+{
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ OSL_ENSURE( pStackLongs && pAdjustedThisPtr, "### null ptr!" );
+ OSL_ENSURE( (sizeof(void *) == 4) &&
+ (sizeof(sal_Int32) == 4), "### unexpected size of int!" );
+ OSL_ENSURE( nStackLongs && pStackLongs, "### no stack in callVirtualMethod !" );
+
+ // never called
+ if (! pAdjustedThisPtr) CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
+
+ volatile long o0 = 0, o1 = 0; // for register returns
+ volatile double f0d = 0;
+ volatile float f0f = 0;
+ volatile long long saveReg[7];
+
+ __asm__ (
+ // save registers
+ "std %%l0, [%4]\n\t"
+ "mov %4, %%l0\n\t"
+ "mov %%l0, %%l1\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%l2, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%l4, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%o0, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%o2, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%o4, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%l6, [%%l0]\n\t"
+ "mov %%l1, %%l7\n\t"
+
+ // increase our own stackframe if necessary
+ "mov %%sp, %%l3\n\t" // save stack ptr for readjustment
+
+ "subcc %%i5, 7, %%l0\n\t"
+ "ble .LmoveOn\n\t"
+ "nop\n\t"
+
+ "sll %%l0, 2, %%l0\n\t"
+ "add %%l0, 96, %%l0\n\t"
+ "mov %%sp, %%l1\n\t" // old stack ptr
+ "sub %%sp, %%l0, %%l0\n\t" // future stack ptr
+ "andcc %%l0, 7, %%g0\n\t" // align stack to 8
+ "be .LisAligned\n\t"
+ "nop\n\t"
+ "sub %%l0, 4, %%l0\n"
+ ".LisAligned:\n\t"
+ "mov %%l0, %%o5\n\t" // save newly computed stack ptr
+ "add %%g0, 16, %%o4\n"
+
+ // now copy longs down to save register window
+ // and local variables
+ ".LcopyDown:\n\t"
+ "ld [%%l1], %%l2\n\t"
+ "st %%l2,[%%l0]\n\t"
+ "add %%l0, 4, %%l0\n\t"
+ "add %%l1, 4, %%l1\n\t"
+ "subcc %%o4, 1, %%o4\n\t"
+ "bne .LcopyDown\n\t"
+
+ "mov %%o5, %%sp\n\t" // move new stack ptr (hopefully) atomically
+ // while register window is valid in both spaces
+ // (scheduling might hit in copyDown loop)
+
+ "sub %%i5, 7, %%l0\n\t" // copy parameters past the sixth to stack
+ "add %%i4, 28, %%l1\n\t"
+ "add %%sp, 92, %%l2\n"
+ ".LcopyLong:\n\t"
+ "ld [%%l1], %%o0\n\t"
+ "st %%o0, [%%l2]\n\t"
+ "add %%l1, 4, %%l1\n\t"
+ "add %%l2, 4, %%l2\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "bne .LcopyLong\n\t"
+ "nop\n"
+
+ ".LmoveOn:\n\t"
+ "mov %%i5, %%l0\n\t" // prepare out registers
+ "mov %%i4, %%l1\n\t"
+
+ "ld [%%l1], %%o0\n\t" // prepare complex return ptr
+ "st %%o0, [%%sp+64]\n\t"
+ "sub %%l0, 1, %%l0\n\t"
+ "add %%l1, 4, %%l1\n\t"
+
+ "ld [%%l1], %%o0\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o1\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o2\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o3\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o4\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o5\n"
+
+ ".LdoCall:\n\t"
+ "ld [%%i0], %%l0\n\t" // get vtable ptr
+
+"sll %%i1, 2, %%l6\n\t"
+// "add %%l6, 8, %%l6\n\t"
+ "add %%l6, %%l0, %%l0\n\t"
+// // vtable has 8byte wide entries,
+// // upper half contains 2 half words, of which the first
+// // is the this ptr patch !
+// // first entry is (or __tf)
+
+// "ldsh [%%l0], %%l6\n\t" // load this ptr patch
+// "add %%l6, %%o0, %%o0\n\t" // patch this ptr
+
+// "add %%l0, 4, %%l0\n\t" // get virtual function ptr
+ "ld [%%l0], %%l0\n\t"
+
+ "ld [%%i4], %%l2\n\t"
+ "subcc %%l2, %%g0, %%l2\n\t"
+ "bne .LcomplexCall\n\t"
+ "nop\n\t"
+ "call %%l0\n\t"
+ "nop\n\t"
+ "ba .LcallReturned\n\t"
+ "nop\n"
+ ".LcomplexCall:\n\t"
+ "call %%l0\n\t"
+ "nop\n\t"
+ "unimp\n"
+
+ ".LcallReturned:\n\t"
+ "mov %%l3, %%sp\n\t" // readjust stack so that our locals are where they belong
+ "st %%o0, %0\n\t" // save possible return registers into our locals
+ "st %%o1, %1\n\t"
+ "std %%f0, %2\n\t"
+ "st %%f0, %3\n\t"
+
+ // restore registers
+ "ldd [%%l7], %%l0\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%l2\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%l4\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%o0\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%o2\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%o4\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%l6\n\t"
+ : :
+ "m"(o0),
+ "m"(o1),
+ "m"(f0d),
+ "m"(f0f),
+ "r"(&saveReg[0])
+ );
+ switch( eReturnType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ ((long*)pRegisterReturn)[1] = o1;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ ((long*)pRegisterReturn)[0] = o0;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = (unsigned short)o0;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = (unsigned char)o0;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float*)pRegisterReturn = f0f;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double*)pRegisterReturn = f0d;
+ break;
+ default:
+ break;
+ }
+}
+
+//=================================================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: complex ret ptr, this, values|ptr ...
+ char * pCppStack =
+ (char *)alloca( (nParams+2) * sizeof(sal_Int64) );
+ char * pCppStackStart = pCppStack;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ *(void**)pCppStack = NULL;
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack = (bridges::cpp_uno::shared::relatesToInterfaceType(pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ }
+ pCppStack += sizeof(void*);
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ pCppArgs[ nPos ] = CPPU_CURRENT_NAMESPACE::adjustPointer(pCppStack, pParamTypeDescr );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ OSL_ASSERT( sizeof (double) == sizeof (sal_Int64) );
+ *reinterpret_cast< sal_Int32 * >(pCppStack) =
+ *reinterpret_cast< sal_Int32 const * >(pUnoArgs[ nPos ]);
+ pCppStack += sizeof (sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(pCppStack) =
+ *(reinterpret_cast< sal_Int32 const * >(pUnoArgs[ nPos ] ) + 1);
+ break;
+ default:
+ uno_copyAndConvertData(
+ pCppArgs[nPos], pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ try
+ {
+ int nStackLongs = (pCppStack - pCppStackStart)/sizeof(sal_Int32);
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic" );
+
+ if( nStackLongs & 1 )
+ // stack has to be 8 byte aligned
+ nStackLongs++;
+ callVirtualMethod(
+ pAdjustedThisPtr,
+ aVtableSlot.index,
+ pCppReturn,
+ pReturnTypeDescr->eTypeClass,
+ (sal_Int32 *)pCppStackStart,
+ nStackLongs);
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch( ... )
+ {
+ // get exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions,
+ *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+#if defined BRIDGES_DEBUG
+ OString cstr( OUStringToOString( pMemberDescr->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "received dispatch( %s )\n", cstr.getStr() );
+#endif
+
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+// typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; // get, then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx
new file mode 100644
index 000000000000..e62f71d2c32a
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx
@@ -0,0 +1,350 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+// This is an implementation of the x86-64 ABI as described in 'System V
+// Application Binary Interface, AMD64 Architecture Processor Supplement'
+// (http://www.x86-64.org/documentation/abi-0.95.pdf)
+//
+// The code in this file is a modification of src/x86/ffi64.c from libffi
+// (http://sources.redhat.com/libffi/) which is under the following license:
+
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 2002 Bo Thorsen <bo@suse.de>
+
+ x86-64 Foreign Function Interface
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+#include <abi.hxx>
+
+#include <rtl/ustring.hxx>
+
+using namespace x86_64;
+
+typedef struct
+{
+ /* Registers for argument passing. */
+ long gpr[MAX_GPR_REGS];
+ __int128_t sse[MAX_SSE_REGS];
+
+ /* Stack space for arguments. */
+ char argspace[0];
+} stackLayout;
+
+/* Register class used for passing given 64bit part of the argument.
+ These represent classes as documented by the PS ABI, with the exception
+ of SSESF, SSEDF classes, that are basically SSE class, just gcc will
+ use SF or DFmode move instead of DImode to avoid reformating penalties.
+
+ Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
+ whenever possible (upper half does contain padding).
+ */
+enum x86_64_reg_class
+{
+ X86_64_NO_CLASS,
+ X86_64_INTEGER_CLASS,
+ X86_64_INTEGERSI_CLASS,
+ X86_64_SSE_CLASS,
+ X86_64_SSESF_CLASS,
+ X86_64_SSEDF_CLASS,
+ X86_64_SSEUP_CLASS,
+ X86_64_X87_CLASS,
+ X86_64_X87UP_CLASS,
+ X86_64_MEMORY_CLASS
+};
+
+#define MAX_CLASSES 4
+
+/* x86-64 register passing implementation. See x86-64 ABI for details. Goal
+ of this code is to classify each 8bytes of incoming argument by the register
+ class and assign registers accordingly. */
+
+/* Return the union class of CLASS1 and CLASS2.
+ See the x86-64 PS ABI for details. */
+
+static enum x86_64_reg_class
+merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
+{
+ /* Rule #1: If both classes are equal, this is the resulting class. */
+ if (class1 == class2)
+ return class1;
+
+ /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
+ the other class. */
+ if (class1 == X86_64_NO_CLASS)
+ return class2;
+ if (class2 == X86_64_NO_CLASS)
+ return class1;
+
+ /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
+ if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
+ return X86_64_MEMORY_CLASS;
+
+ /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
+ if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
+ || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
+ return X86_64_INTEGERSI_CLASS;
+ if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
+ || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
+ return X86_64_INTEGER_CLASS;
+
+ /* Rule #5: If one of the classes is X87 or X87UP class, MEMORY is used. */
+ if (class1 == X86_64_X87_CLASS || class1 == X86_64_X87UP_CLASS
+ || class2 == X86_64_X87_CLASS || class2 == X86_64_X87UP_CLASS)
+ return X86_64_MEMORY_CLASS;
+
+ /* Rule #6: Otherwise class SSE is used. */
+ return X86_64_SSE_CLASS;
+}
+
+/* Classify the argument of type TYPE and mode MODE.
+ CLASSES will be filled by the register class used to pass each word
+ of the operand. The number of words is returned. In case the parameter
+ should be passed in memory, 0 is returned. As a special case for zero
+ sized containers, classes[0] will be NO_CLASS and 1 is returned.
+
+ See the x86-64 PS ABI for details.
+*/
+static int
+classify_argument( typelib_TypeDescriptionReference *pTypeRef, enum x86_64_reg_class classes[], int byteOffset )
+{
+ switch ( pTypeRef->eTypeClass )
+ {
+ case typelib_TypeClass_VOID:
+ classes[0] = X86_64_NO_CLASS;
+ return 1;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_ENUM:
+ if ( ( byteOffset % 8 + pTypeRef->pType->nSize ) <= 4 )
+ classes[0] = X86_64_INTEGERSI_CLASS;
+ else
+ classes[0] = X86_64_INTEGER_CLASS;
+ return 1;
+ case typelib_TypeClass_FLOAT:
+ if ( ( byteOffset % 8 ) == 0 )
+ classes[0] = X86_64_SSESF_CLASS;
+ else
+ classes[0] = X86_64_SSE_CLASS;
+ return 1;
+ case typelib_TypeClass_DOUBLE:
+ classes[0] = X86_64_SSEDF_CLASS;
+ return 1;
+ /*case LONGDOUBLE:
+ classes[0] = X86_64_X87_CLASS;
+ classes[1] = X86_64_X87UP_CLASS;
+ return 2;*/
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_TYPEDEF:
+ case typelib_TypeClass_UNION:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_ARRAY:
+ case typelib_TypeClass_INTERFACE:
+ return 0;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+
+ const int UNITS_PER_WORD = 8;
+ int words = ( pTypeDescr->nSize + UNITS_PER_WORD - 1 ) / UNITS_PER_WORD;
+ enum x86_64_reg_class subclasses[MAX_CLASSES];
+
+ /* If the struct is larger than 16 bytes, pass it on the stack. */
+ if ( pTypeDescr->nSize > 16 )
+ {
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ return 0;
+ }
+
+ for ( int i = 0; i < words; i++ )
+ classes[i] = X86_64_NO_CLASS;
+
+ const typelib_CompoundTypeDescription *pStruct = reinterpret_cast<const typelib_CompoundTypeDescription*>( pTypeDescr );
+
+ /* Merge the fields of structure. */
+ for ( sal_Int32 nMember = 0; nMember < pStruct->nMembers; ++nMember )
+ {
+ typelib_TypeDescriptionReference *pTypeInStruct = pStruct->ppTypeRefs[ nMember ];
+ int offset = byteOffset + pStruct->pMemberOffsets[ nMember ];
+
+ int num = classify_argument( pTypeInStruct, subclasses, offset );
+
+ if ( num == 0 )
+ {
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ return 0;
+ }
+
+ for ( int i = 0; i < num; i++ )
+ {
+ int pos = offset / 8;
+ classes[i + pos] = merge_classes( subclasses[i], classes[i + pos] );
+ }
+ }
+
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+
+ /* Final merger cleanup. */
+ for ( int i = 0; i < words; i++ )
+ {
+ /* If one class is MEMORY, everything should be passed in
+ memory. */
+ if ( classes[i] == X86_64_MEMORY_CLASS )
+ return 0;
+
+ /* The X86_64_SSEUP_CLASS should be always preceded by
+ X86_64_SSE_CLASS. */
+ if ( classes[i] == X86_64_SSEUP_CLASS
+ && ( i == 0 || classes[i - 1] != X86_64_SSE_CLASS ) )
+ classes[i] = X86_64_SSE_CLASS;
+
+ /* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */
+ if ( classes[i] == X86_64_X87UP_CLASS
+ && ( i == 0 || classes[i - 1] != X86_64_X87_CLASS ) )
+ classes[i] = X86_64_SSE_CLASS;
+ }
+ return words;
+ }
+
+ default:
+#if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE( "Unhandled case: pType->eTypeClass == %d\n", pTypeRef->eTypeClass );
+#endif
+ OSL_ASSERT(0);
+ }
+ return 0; /* Never reached. */
+}
+
+/* Examine the argument and return set number of register required in each
+ class. Return 0 iff parameter should be passed in memory. */
+bool x86_64::examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool bInReturn, int &nUsedGPR, int &nUsedSSE )
+{
+ enum x86_64_reg_class classes[MAX_CLASSES];
+ int n;
+
+ n = classify_argument( pTypeRef, classes, 0 );
+
+ if ( n == 0 )
+ return false;
+
+ nUsedGPR = 0;
+ nUsedSSE = 0;
+ for ( n--; n >= 0; n-- )
+ switch ( classes[n] )
+ {
+ case X86_64_INTEGER_CLASS:
+ case X86_64_INTEGERSI_CLASS:
+ nUsedGPR++;
+ break;
+ case X86_64_SSE_CLASS:
+ case X86_64_SSESF_CLASS:
+ case X86_64_SSEDF_CLASS:
+ nUsedSSE++;
+ break;
+ case X86_64_NO_CLASS:
+ case X86_64_SSEUP_CLASS:
+ break;
+ case X86_64_X87_CLASS:
+ case X86_64_X87UP_CLASS:
+ if ( !bInReturn )
+ return false;
+ break;
+ default:
+#if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE( "Unhandled case: classes[n] == %d\n", classes[n] );
+#endif
+ OSL_ASSERT(0);
+ }
+ return true;
+}
+
+bool x86_64::return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
+{
+ int g, s;
+
+ return examine_argument( pTypeRef, true, g, s ) == 0;
+}
+
+void x86_64::fill_struct( typelib_TypeDescriptionReference *pTypeRef, const sal_uInt64 *pGPR, const double *pSSE, void *pStruct )
+{
+ enum x86_64_reg_class classes[MAX_CLASSES];
+ int n;
+
+ n = classify_argument( pTypeRef, classes, 0 );
+
+ sal_uInt64 *pStructAlign = reinterpret_cast<sal_uInt64 *>( pStruct );
+ for ( n--; n >= 0; n-- )
+ switch ( classes[n] )
+ {
+ case X86_64_INTEGER_CLASS:
+ case X86_64_INTEGERSI_CLASS:
+ *pStructAlign++ = *pGPR++;
+ break;
+ case X86_64_SSE_CLASS:
+ case X86_64_SSESF_CLASS:
+ case X86_64_SSEDF_CLASS:
+ *pStructAlign++ = *reinterpret_cast<const sal_uInt64 *>( pSSE++ );
+ break;
+ default:
+ break;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx
new file mode 100644
index 000000000000..c9f71f18078b
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx
@@ -0,0 +1,70 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef _BRIDGES_CPP_UNO_X86_64_ABI_HXX_
+#define _BRIDGES_CPP_UNO_X86_64_ABI_HXX_
+
+// This is an implementation of the x86-64 ABI as described in 'System V
+// Application Binary Interface, AMD64 Architecture Processor Supplement'
+// (http://www.x86-64.org/documentation/abi-0.95.pdf)
+
+#include <typelib/typedescription.hxx>
+
+namespace x86_64
+{
+
+/* 6 general purpose registers are used for parameter passing */
+const sal_uInt32 MAX_GPR_REGS = 6;
+
+/* 8 SSE registers are used for parameter passing */
+const sal_uInt32 MAX_SSE_REGS = 8;
+
+/* Count number of required registers.
+
+ Examine the argument and return set number of register required in each
+ class.
+
+ Return false iff parameter should be passed in memory.
+*/
+bool examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool bInReturn, int &nUsedGPR, int &nUsedSSE );
+
+/** Does function that returns this type use a hidden parameter, or registers?
+
+ The value can be returned either in a hidden 1st parameter (which is a
+ pointer to a structure allocated by the caller), or in registers (rax, rdx
+ for the integers, xmm0, xmm1 for the floating point numbers).
+*/
+bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
+
+void fill_struct( typelib_TypeDescriptionReference *pTypeRef, const sal_uInt64* pGPR, const double* pSSE, void *pStruct );
+
+} // namespace x86_64
+
+#endif // _BRIDGES_CPP_UNO_X86_64_ABI_HXX_
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/call.s b/bridges/source/cpp_uno/gcc3_linux_x86-64/call.s
new file mode 100644
index 000000000000..a0572ef61641
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/call.s
@@ -0,0 +1,96 @@
+ .text
+ .align 2
+.globl privateSnippetExecutor
+ .type privateSnippetExecutor, @function
+privateSnippetExecutor:
+.LFB3:
+ pushq %rbp
+.LCFI0:
+ movq %rsp, %rbp
+.LCFI1:
+ subq $160, %rsp
+.LCFI2:
+ movq %r10, -152(%rbp) # Save (nVtableOffset << 32) + nFunctionIndex
+
+ movq %rdi, -112(%rbp) # Save GP registers
+ movq %rsi, -104(%rbp)
+ movq %rdx, -96(%rbp)
+ movq %rcx, -88(%rbp)
+ movq %r8 , -80(%rbp)
+ movq %r9 , -72(%rbp)
+
+ movsd %xmm0, -64(%rbp) # Save FP registers
+ movsd %xmm1, -56(%rbp)
+ movsd %xmm2, -48(%rbp)
+ movsd %xmm3, -40(%rbp)
+ movsd %xmm4, -32(%rbp)
+ movsd %xmm5, -24(%rbp)
+ movsd %xmm6, -16(%rbp)
+ movsd %xmm7, -8(%rbp)
+
+ leaq -144(%rbp), %r9 # 6th param: sal_uInt64 * pRegisterReturn
+ leaq 16(%rbp), %r8 # 5rd param: void ** ovrflw
+ leaq -64(%rbp), %rcx # 4th param: void ** fpreg
+ leaq -112(%rbp), %rdx # 3rd param: void ** gpreg
+ movl -148(%rbp), %esi # 2nd param: sal_int32 nVtableOffset
+ movl -152(%rbp), %edi # 1st param: sal_int32 nFunctionIndex
+
+ call cpp_vtable_call
+
+ cmp $10, %rax # typelib_TypeClass_FLOAT
+ je .Lfloat
+ cmp $11, %rax # typelib_TypeClass_DOUBLE
+ je .Lfloat
+
+ movq -144(%rbp), %rax # Return value (int case)
+ movq -136(%rbp), %rdx # Return value (int case)
+ movq -144(%rbp), %xmm0 # Return value (int case)
+ movq -136(%rbp), %xmm1 # Return value (int case)
+ jmp .Lfinish
+.Lfloat:
+ movlpd -144(%rbp), %xmm0 # Return value (float/double case)
+
+.Lfinish:
+ leave
+ ret
+.LFE3:
+ .size privateSnippetExecutor, .-privateSnippetExecutor
+ .section .eh_frame,"a",@progbits
+.Lframe1:
+ .long .LECIE1-.LSCIE1
+.LSCIE1:
+ .long 0x0
+ .byte 0x1
+ .string "zR"
+ .uleb128 0x1
+ .sleb128 -8
+ .byte 0x10
+ .uleb128 0x1
+ .byte 0x1b
+ .byte 0xc
+ .uleb128 0x7
+ .uleb128 0x8
+ .byte 0x90
+ .uleb128 0x1
+ .align 8
+.LECIE1:
+.LSFDE1:
+ .long .LEFDE1-.LASFDE1
+.LASFDE1:
+ .long .LASFDE1-.Lframe1
+ .long .LFB3-.
+ .long .LFE3-.LFB3
+ .uleb128 0x0
+ .byte 0x4
+ .long .LCFI0-.LFB3
+ .byte 0xe
+ .uleb128 0x10
+ .byte 0x86
+ .uleb128 0x2
+ .byte 0x4
+ .long .LCFI1-.LCFI0
+ .byte 0xd
+ .uleb128 0x6
+ .align 8
+.LEFDE1:
+ .section .note.GNU-stack,"",@progbits
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx
new file mode 100644
index 000000000000..512b7d1f3f34
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx
@@ -0,0 +1,523 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <hash_map>
+
+#include <rtl/alloc.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "abi.hxx"
+#include "share.hxx"
+
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+//==================================================================================================
+
+// Perform the UNO call
+//
+// We must convert the paramaters stored in gpreg, fpreg and ovrflw to UNO
+// arguments and call pThis->getUnoI()->pDispatcher.
+//
+// gpreg: [ret *], this, [gpr params]
+// fpreg: [fpr params]
+// ovrflw: [gpr or fpr params (properly aligned)]
+//
+// [ret *] is present when we are returning a structure bigger than 16 bytes
+// Simple types are returned in rax, rdx (int), or xmm0, xmm1 (fp).
+// Similarly structures <= 16 bytes are in rax, rdx, xmm0, xmm1 as necessary.
+static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_uInt64 * pRegisterReturn /* space for register return */ )
+{
+ unsigned int nr_gpr = 0; //number of gpr registers used
+ unsigned int nr_fpr = 0; //number of fpr registers used
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if ( pReturnTypeDescr )
+ {
+ if ( x86_64::return_in_hidden_param( pReturnTypeRef ) )
+ {
+ pCppReturn = *gpreg++;
+ nr_gpr++;
+
+ pUnoReturn = ( bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn ); // direct way
+ }
+ else
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+
+ // pop this
+ gpreg++;
+ nr_gpr++;
+
+ // stack space
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+
+ int nUsedGPR = 0;
+ int nUsedSSE = 0;
+#if OSL_DEBUG_LEVEL > 0
+ bool bFitsRegisters =
+#endif
+ x86_64::examine_argument( rParam.pTypeRef, false, nUsedGPR, nUsedSSE );
+ if ( !rParam.bOut && bridges::cpp_uno::shared::isSimpleType( rParam.pTypeRef ) ) // value
+ {
+ // Simple types must fit exactly one register on x86_64
+ OSL_ASSERT( bFitsRegisters && ( ( nUsedSSE == 1 && nUsedGPR == 0 ) || ( nUsedSSE == 0 && nUsedGPR == 1 ) ) );
+
+ if ( nUsedSSE == 1 )
+ {
+ if ( nr_fpr < x86_64::MAX_SSE_REGS )
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
+ nr_fpr++;
+ }
+ else
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
+ }
+ else if ( nUsedGPR == 1 )
+ {
+ if ( nr_gpr < x86_64::MAX_GPR_REGS )
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg++;
+ nr_gpr++;
+ }
+ else
+ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
+ }
+ }
+ else // struct <= 16 bytes || ptr to complex value || ref
+ {
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ void *pCppStack;
+ if ( nr_gpr < x86_64::MAX_GPR_REGS )
+ {
+ pCppArgs[nPos] = pCppStack = *gpreg++;
+ nr_gpr++;
+ }
+ else
+ pCppArgs[nPos] = pCppStack = *ovrflw++;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else if ( bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ) ) // is in/inout
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ if ( pUnoExc )
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if ( pParams[nIndex].bOut ) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if ( pCppReturn ) // has complex return
+ {
+ if ( pUnoReturn != pCppReturn ) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if ( pReturnTypeDescr )
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+extern "C" typelib_TypeClass cpp_vtable_call(
+ sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_uInt64 * pRegisterReturn /* space for register return */ )
+{
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (properly aligned)]
+ void * pThis;
+ if ( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = gpreg[1];
+ }
+ else
+ {
+ pThis = gpreg[0];
+ }
+ pThis = static_cast<char *>( pThis ) - nVtableOffset;
+
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
+ bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( pThis );
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!\n" );
+ if ( nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex )
+ {
+ throw RuntimeException( OUString(RTL_CONSTASCII_USTRINGPARAM("illegal vtable index!")),
+ reinterpret_cast<XInterface *>( pCppI ) );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!\n" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch ( aMemberDescr.get()->eTypeClass )
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ typelib_TypeDescriptionReference *pAttrTypeRef =
+ reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( aMemberDescr.get() )->pAttributeTypeRef;
+
+ if ( pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex )
+ {
+ // is GET method
+ eRet = cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef,
+ 0, 0, // no params
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef = pAttrTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch ( nFunctionIndex )
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast<Type *>( gpreg[2] )->getTypeLibType() );
+ if ( pTD )
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)
+ ( pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface,
+ pCppI->getOid().pData,
+ reinterpret_cast<typelib_InterfaceTypeDescription *>( pTD ) );
+
+ if ( pInterface )
+ {
+ ::uno_any_construct( reinterpret_cast<uno_Any *>( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+
+ reinterpret_cast<void **>( pRegisterReturn )[0] = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ {
+ typelib_InterfaceMethodTypeDescription *pMethodTD =
+ reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( aMemberDescr.get() );
+
+ eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
+ pMethodTD->pReturnTypeRef,
+ pMethodTD->nParams,
+ pMethodTD->pParams,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException( OUString(RTL_CONSTASCII_USTRINGPARAM("no member description found!")),
+ reinterpret_cast<XInterface *>( pCppI ) );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+//==================================================================================================
+extern "C" void privateSnippetExecutor( ... );
+
+const int codeSnippetSize = 24;
+
+// Generate a trampoline that redirects method calls to
+// privateSnippetExecutor().
+//
+// privateSnippetExecutor() saves all the registers that are used for
+// parameter passing on x86_64, and calls the cpp_vtable_call().
+// When it returns, privateSnippetExecutor() sets the return value.
+//
+// Note: The code snippet we build here must not create a stack frame,
+// otherwise the UNO exceptions stop working thanks to non-existing
+// unwinding info.
+unsigned char * codeSnippet( unsigned char * code,
+ sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+ bool bHasHiddenParam ) SAL_THROW( () )
+{
+ sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
+
+ if ( bHasHiddenParam )
+ nOffsetAndIndex |= 0x80000000;
+
+ // movq $<nOffsetAndIndex>, %r10
+ *reinterpret_cast<sal_uInt16 *>( code ) = 0xba49;
+ *reinterpret_cast<sal_uInt64 *>( code + 2 ) = nOffsetAndIndex;
+
+ // movq $<address of the privateSnippetExecutor>, %r11
+ *reinterpret_cast<sal_uInt16 *>( code + 10 ) = 0xbb49;
+ *reinterpret_cast<sal_uInt64 *>( code + 12 ) = reinterpret_cast<sal_uInt64>( privateSnippetExecutor );
+
+ // jmpq *%r11
+ *reinterpret_cast<sal_uInt32 *>( code + 20 ) = 0x00e3ff49;
+
+ return code + codeSnippetSize;
+}
+
+//==================================================================================================
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+//==================================================================================================
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+//==================================================================================================
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0;
+ slots[-1].fn = 0;
+ return slots + slotCount;
+}
+
+//==================================================================================================
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 nFunctionOffset,
+ sal_Int32 functionCount, sal_Int32 nVtableOffset )
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for ( sal_Int32 nPos = 0; nPos < type->nMembers; ++nPos )
+ {
+ typelib_TypeDescription * pTD = 0;
+
+ TYPELIB_DANGER_GET( &pTD, type->ppMembers[ nPos ] );
+ OSL_ASSERT( pTD );
+
+ if ( typelib_TypeClass_INTERFACE_ATTRIBUTE == pTD->eTypeClass )
+ {
+ typelib_InterfaceAttributeTypeDescription *pAttrTD =
+ reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( pTD );
+
+ // get method
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
+ x86_64::return_in_hidden_param( pAttrTD->pAttributeTypeRef ) );
+
+ if ( ! pAttrTD->bReadOnly )
+ {
+ // set method
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet( code, nFunctionOffset++, nVtableOffset, false );
+ }
+ }
+ else if ( typelib_TypeClass_INTERFACE_METHOD == pTD->eTypeClass )
+ {
+ typelib_InterfaceMethodTypeDescription *pMethodTD =
+ reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( pTD );
+
+ (s++)->fn = code + writetoexecdiff;
+ code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
+ x86_64::return_in_hidden_param( pMethodTD->pReturnTypeRef ) );
+ }
+ else
+ OSL_ASSERT( false );
+
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ return code;
+}
+
+//==================================================================================================
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const *, unsigned char const * )
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx
new file mode 100644
index 000000000000..759f28764fa7
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/except.cxx
@@ -0,0 +1,340 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * )
+{
+}
+
+//==================================================================================================
+static OUString toUNOname( char const * p ) SAL_THROW( () )
+{
+#if OSL_DEBUG_LEVEL > 1
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+}
+
+//==================================================================================================
+class RTTI
+{
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+#if defined(FREEBSD) && __FreeBSD_version < 702104
+ : m_hApp( dlopen( 0, RTLD_NOW | RTLD_GLOBAL ) )
+#else
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+#endif
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+{
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+#if defined(FREEBSD) && __FreeBSD_version < 702104 /* #i22253# */
+ rtti = (type_info *)dlsym( RTLD_DEFAULT, symName.getStr() );
+#else
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+#endif
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind2( m_generatedRttis.find( unoName ) );
+ if (iFind2 == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with _ZTI
+ char const * rttiName = symName.getStr() +4;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iFind2->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void deleteException( void * pExc )
+{
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() );
+#endif
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get typedescription for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+{
+ if (! header)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_x86-64/makefile.mk
new file mode 100644
index 000000000000..156ca4f27d4a
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/makefile.mk
@@ -0,0 +1,83 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCLINUXXgcc3" || \
+ "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCOPENBSDXgcc3" || \
+ "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCFREEBSDXgcc3" || \
+ "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCNETBSDXgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer -fno-strict-aliasing
+
+SLOFILES= \
+ $(SLO)$/abi.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/call.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.s
+ $(CC) -c -o $(SLO)$/$(@:b).o $<
+ touch $@
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx
new file mode 100644
index 000000000000..da2367ad172b
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx
@@ -0,0 +1,93 @@
+/* -*- 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 "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * );
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx
new file mode 100644
index 000000000000..767961b9c691
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx
@@ -0,0 +1,574 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rtl/alloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+
+#include <bridges/cpp_uno/shared/bridge.hxx>
+#include <bridges/cpp_uno/shared/types.hxx>
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "abi.hxx"
+#include "share.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+//==================================================================================================
+static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn,
+ sal_uInt64 *pStack, sal_uInt32 nStack,
+ sal_uInt64 *pGPR, sal_uInt32 nGPR,
+ double *pFPR, sal_uInt32 nFPR) __attribute__((noinline));
+
+static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn,
+ sal_uInt64 *pStack, sal_uInt32 nStack,
+ sal_uInt64 *pGPR, sal_uInt32 nGPR,
+ double *pFPR, sal_uInt32 nFPR)
+{
+#if OSL_DEBUG_LEVEL > 1
+ // Let's figure out what is really going on here
+ {
+ fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
+ for ( unsigned int i = 0; i < nGPR; ++i )
+ fprintf( stderr, "0x%lx, ", pGPR[i] );
+ fprintf( stderr, "\nFPR's (%d): ", nFPR );
+ for ( unsigned int i = 0; i < nFPR; ++i )
+ fprintf( stderr, "%f, ", pFPR[i] );
+ fprintf( stderr, "\nStack (%d): ", nStack );
+ for ( unsigned int i = 0; i < nStack; ++i )
+ fprintf( stderr, "0x%lx, ", pStack[i] );
+ fprintf( stderr, "\n" );
+ }
+#endif
+
+ // The call instruction within the asm section of callVirtualMethod may throw
+ // exceptions. So that the compiler handles this correctly, it is important
+ // that (a) callVirtualMethod might call dummy_can_throw_anything (although this
+ // never happens at runtime), which in turn can throw exceptions, and (b)
+ // callVirtualMethod is not inlined at its call site (so that any exceptions are
+ // caught which are thrown from the instruction calling callVirtualMethod):
+ if ( !pThis )
+ CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything( "xxx" ); // address something
+
+ // Should not happen, but...
+ if ( nFPR > x86_64::MAX_SSE_REGS )
+ nFPR = x86_64::MAX_SSE_REGS;
+ if ( nGPR > x86_64::MAX_GPR_REGS )
+ nGPR = x86_64::MAX_GPR_REGS;
+
+ // Get pointer to method
+ sal_uInt64 pMethod = *((sal_uInt64 *)pThis);
+ pMethod += 8 * nVtableIndex;
+ pMethod = *((sal_uInt64 *)pMethod);
+
+ // Load parameters to stack, if necessary
+ if ( nStack )
+ {
+ // 16-bytes aligned
+ sal_uInt32 nStackBytes = ( ( nStack + 1 ) >> 1 ) * 16;
+ sal_uInt64 *pCallStack = (sal_uInt64 *) __builtin_alloca( nStackBytes );
+ memcpy( pCallStack, pStack, nStackBytes );
+ }
+
+ // Return values
+ sal_uInt64 rax;
+ sal_uInt64 rdx;
+ double xmm0;
+ double xmm1;
+
+ asm volatile (
+
+ // Fill the xmm registers
+ "movq %2, %%rax\n\t"
+
+ "movsd (%%rax), %%xmm0\n\t"
+ "movsd 8(%%rax), %%xmm1\n\t"
+ "movsd 16(%%rax), %%xmm2\n\t"
+ "movsd 24(%%rax), %%xmm3\n\t"
+ "movsd 32(%%rax), %%xmm4\n\t"
+ "movsd 40(%%rax), %%xmm5\n\t"
+ "movsd 48(%%rax), %%xmm6\n\t"
+ "movsd 56(%%rax), %%xmm7\n\t"
+
+ // Fill the general purpose registers
+ "movq %1, %%rax\n\t"
+
+ "movq (%%rax), %%rdi\n\t"
+ "movq 8(%%rax), %%rsi\n\t"
+ "movq 16(%%rax), %%rdx\n\t"
+ "movq 24(%%rax), %%rcx\n\t"
+ "movq 32(%%rax), %%r8\n\t"
+ "movq 40(%%rax), %%r9\n\t"
+
+ // Perform the call
+ "movq %0, %%r11\n\t"
+ "movq %3, %%rax\n\t"
+ "call *%%r11\n\t"
+
+ // Fill the return values
+ "movq %%rax, %4\n\t"
+ "movq %%rdx, %5\n\t"
+ "movsd %%xmm0, %6\n\t"
+ "movsd %%xmm1, %7\n\t"
+ :
+ : "m" ( pMethod ), "m" ( pGPR ), "m" ( pFPR ), "m" ( nFPR ),
+ "m" ( rax ), "m" ( rdx ), "m" ( xmm0 ), "m" ( xmm1 )
+ : "rax", "rdi", "rsi", "rdx", "rcx", "r8", "r9", "r11"
+ );
+
+ switch (pReturnTypeRef->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = rax;
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ *reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt32*>( &rax );
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *reinterpret_cast<sal_uInt16 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt16*>( &rax );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt8*>( &rax );
+ break;
+ case typelib_TypeClass_FLOAT:
+ case typelib_TypeClass_DOUBLE:
+ *reinterpret_cast<double *>( pRegisterReturn ) = xmm0;
+ break;
+ default:
+ {
+ sal_Int32 const nRetSize = pReturnTypeRef->pType->nSize;
+ if (bSimpleReturn && nRetSize <= 16 && nRetSize > 0)
+ {
+ sal_uInt64 longs[2];
+ longs[0] = rax;
+ longs[1] = rdx;
+
+ double doubles[2];
+ doubles[0] = xmm0;
+ doubles[1] = xmm1;
+ x86_64::fill_struct( pReturnTypeRef, &longs[0], &doubles[0], pRegisterReturn);
+ }
+ break;
+ }
+ }
+}
+
+//==================================================================================================
+
+// Macros for easier insertion of values to registers or stack
+// pSV - pointer to the source
+// nr - order of the value [will be increased if stored to register]
+// pFPR, pGPR - pointer to the registers
+// pDS - pointer to the stack [will be increased if stored here]
+
+// The value in %xmm register is already prepared to be retrieved as a float,
+// thus we treat float and double the same
+#define INSERT_FLOAT_DOUBLE( pSV, nr, pFPR, pDS ) \
+ if ( nr < x86_64::MAX_SSE_REGS ) \
+ pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
+
+#define INSERT_INT64( pSV, nr, pGPR, pDS ) \
+ if ( nr < x86_64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
+
+#define INSERT_INT32( pSV, nr, pGPR, pDS ) \
+ if ( nr < x86_64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#define INSERT_INT16( pSV, nr, pGPR, pDS ) \
+ if ( nr < x86_64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, nr, pGPR, pDS ) \
+ if ( nr < x86_64::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+
+//==================================================================================================
+
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // Maxium space for [complex ret ptr], values | ptr ...
+ // (but will be used less - some of the values will be in pGPR and pFPR)
+ sal_uInt64 *pStack = (sal_uInt64 *)__builtin_alloca( (nParams + 3) * sizeof(sal_uInt64) );
+ sal_uInt64 *pStackStart = pStack;
+
+ sal_uInt64 pGPR[x86_64::MAX_GPR_REGS];
+ sal_uInt32 nGPR = 0;
+
+ double pFPR[x86_64::MAX_SSE_REGS];
+ sal_uInt32 nFPR = 0;
+
+ // Return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion (see below)
+
+ bool bSimpleReturn = true;
+ if ( pReturnTypeDescr )
+ {
+ if ( x86_64::return_in_hidden_param( pReturnTypeRef ) )
+ bSimpleReturn = false;
+
+ if ( bSimpleReturn )
+ pCppReturn = pUnoReturn; // direct way for simple types
+ else
+ {
+ // complex return via ptr
+ pCppReturn = bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )?
+ __builtin_alloca( pReturnTypeDescr->nSize ) : pUnoReturn;
+ INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack );
+ }
+ }
+
+ // Push "this" pointer
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
+ INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack );
+
+ // Args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // Indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // Type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_FLOAT:
+ case typelib_TypeClass_DOUBLE:
+ INSERT_FLOAT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, pStack );
+ break;
+ default:
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack );
+ }
+ }
+
+ try
+ {
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeRef, bSimpleReturn,
+ pStackStart, ( pStack - pStackStart ),
+ pGPR, nGPR,
+ pFPR, nFPR );
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+//==================================================================================================
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+#if OSL_DEBUG_LEVEL > 0
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+#endif
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+#if OSL_DEBUG_LEVEL > 0
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+#endif
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; // get, then set method
+ cpp_call(
+ pThis, aVtableSlot, // get, then set method
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+#if OSL_DEBUG_LEVEL > 0
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+#endif
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)(
+ pThis->getBridge()->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_macosx_intel/call.s b/bridges/source/cpp_uno/gcc3_macosx_intel/call.s
new file mode 100644
index 000000000000..814af56f4c34
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_intel/call.s
@@ -0,0 +1,327 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+ .text
+
+.align 1, 0x90
+.globl _privateSnippetExecutorGeneral
+_privateSnippetExecutorGeneral:
+LFBg:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+LCFIg0:
+ movl %esp,%ebp
+LCFIg1:
+ subl $0x8,%esp # padding + 32bit returnValue
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call L_cpp_vtable_call$stub
+ movl 16(%esp),%eax # 32bit returnValue
+ leave
+ ret
+LFEg:
+ .long .-_privateSnippetExecutorGeneral
+
+.align 1, 0x90
+.globl _privateSnippetExecutorVoid
+_privateSnippetExecutorVoid:
+LFBv:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+LCFIv0:
+ movl %esp,%ebp
+LCFIv1:
+ sub $8,%esp # padding
+ pushl $0 # 32bit null pointer (returnValue not used)
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call L_cpp_vtable_call$stub
+ leave
+ ret
+LFEv:
+ .long .-_privateSnippetExecutorVoid
+
+.align 1, 0x90
+.globl _privateSnippetExecutorHyper
+_privateSnippetExecutorHyper:
+LFBh:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+LCFIh0:
+ movl %esp,%ebp
+LCFIh1:
+ subl $0x8,%esp # 64bit returnValue
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call L_cpp_vtable_call$stub
+ movl 16(%esp),%eax # 64bit returnValue, lower half
+ movl 20(%esp),%edx # 64bit returnValue, upper half
+ leave
+ ret
+LFEh:
+ .long .-_privateSnippetExecutorHyper
+
+.align 1, 0x90
+.globl _privateSnippetExecutorFloat
+_privateSnippetExecutorFloat:
+LFBf:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+LCFIf0:
+ movl %esp,%ebp
+LCFIf1:
+ subl $0x8,%esp # padding + 32bit returnValue
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call L_cpp_vtable_call$stub
+ flds 16(%esp) # 32bit returnValue
+ leave
+ ret
+LFEf:
+ .long .-_privateSnippetExecutorFloat
+
+.align 1, 0x90
+.globl _privateSnippetExecutorDouble
+_privateSnippetExecutorDouble:
+LFBd:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+LCFId0:
+ movl %esp,%ebp
+LCFId1:
+ subl $0x8,%esp # 64bit returnValue
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call L_cpp_vtable_call$stub
+ fldl 16(%esp) # 64bit returnValue
+ leave
+ ret
+LFEd:
+ .long .-_privateSnippetExecutorDouble
+
+.align 1, 0x90
+.globl _privateSnippetExecutorClass
+_privateSnippetExecutorClass:
+LFBc:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+LCFIc0:
+ movl %esp,%ebp
+LCFIc1:
+ subl $0x8,%esp # padding + 32bit returnValue
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call L_cpp_vtable_call$stub
+ movl 16(%esp),%eax # 32bit returnValue
+ leave
+ ret $4
+LFEc:
+ .long .-_privateSnippetExecutorClass
+
+ .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
+EH_frame1:
+ .set L$set$frame1,LECIE1-LSCIE1
+ .long L$set$frame1 # length
+LSCIE1:
+ .long 0 # CIE_ID
+ .byte 1 # version
+ .ascii "zPR\0" # augmentation
+ .byte 1 # code_alignment_factor (.uleb128 1)
+ .byte 0x7c # data_alignment_factor (.sleb128 -4)
+ .byte 8 # return_address_register
+ .byte 0x6 # augmentation size 7:
+ .byte 0x9b # ???
+ .long L___gxx_personality_v0$non_lazy_ptr-.
+ .byte 0x10
+ # initial_instructions:
+ .byte 0x0C # DW_CFA_def_cfa %esp, 4
+ .byte 5
+ .byte 4
+ .byte 0x88 # DW_CFA_offset ret, 1
+ .byte 1
+ .align 2
+LECIE1:
+ .globl _privateSnippetExecutorGeneral.eh
+_privateSnippetExecutorGeneral.eh:
+LSFDEg:
+ .set L$set$g1,LEFDEg-LASFDEg
+ .long L$set$g1 # length
+LASFDEg:
+ .long LASFDEg-EH_frame1 # CIE_pointer
+ .long LFBg-. # initial_location
+ .long LFEg-LFBg # address_range
+ .byte 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIg0-LFBg
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .byte 8
+ .byte 0x84 # DW_CFA_offset %ebp, 2
+ .byte 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIg1-LCFIg0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .byte 4
+ .align 2
+LEFDEg:
+ .globl _privateSnippetExecutorVoid.eh
+_privateSnippetExecutorVoid.eh:
+LSFDEv:
+ .set L$set$v1,LEFDEv-LASFDEv
+ .long L$set$v1 # length
+LASFDEv:
+ .long LASFDEv-EH_frame1 # CIE_pointer
+ .long LFBv-. # initial_location
+ .long LFEv-LFBv # address_range
+ .byte 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIv0-LFBv
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .byte 8
+ .byte 0x84 # DW_CFA_offset %ebp, 2
+ .byte 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIv1-LCFIv0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .byte 4
+ .align 2
+LEFDEv:
+ .globl _privateSnippetExecutorHyper.eh
+_privateSnippetExecutorHyper.eh:
+LSFDEh:
+ .set L$set$h1,LEFDEh-LASFDEh
+ .long L$set$h1 # length
+LASFDEh:
+ .long LASFDEh-EH_frame1 # CIE_pointer
+ .long LFBh-. # initial_location
+ .long LFEh-LFBh # address_range
+ .byte 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIh0-LFBh
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .byte 8
+ .byte 0x84 # DW_CFA_offset %ebp, 2
+ .byte 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIh1-LCFIh0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .byte 4
+ .align 2
+LEFDEh:
+ .globl _privateSnippetExecutorFloat.eh
+_privateSnippetExecutorFloat.eh:
+LSFDEf:
+ .set L$set$f1,LEFDEf-LASFDEf
+ .long L$set$f1 # length
+LASFDEf:
+ .long LASFDEf-EH_frame1 # CIE_pointer
+ .long LFBf-. # initial_location
+ .long LFEf-LFBf # address_range
+ .byte 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIf0-LFBf
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .byte 8
+ .byte 0x84 # DW_CFA_offset %ebp, 2
+ .byte 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIf1-LCFIf0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .byte 4
+ .align 2
+LEFDEf:
+ .globl _privateSnippetExecutorDouble.eh
+_privateSnippetExecutorDouble.eh:
+LSFDEd:
+ .set L$set$d1,LEFDEd-LASFDEd
+ .long L$set$d1 # length
+LASFDEd:
+ .long LASFDEd-EH_frame1 # CIE_pointer
+ .long LFBd-. # initial_location
+ .long LFEd-LFBd # address_range
+ .byte 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFId0-LFBd
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .byte 8
+ .byte 0x84 # DW_CFA_offset %ebp, 2
+ .byte 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFId1-LCFId0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .byte 4
+ .align 2
+LEFDEd:
+ .globl _privateSnippetExecutorClass.eh
+_privateSnippetExecutorClass.eh:
+LSFDEc:
+ .set L$set$c1,LEFDEc-LASFDEc
+ .long L$set$c1 # length
+LASFDEc:
+ .long LASFDEc-EH_frame1 # CIE_pointer
+ .long LFBc-. # initial_location
+ .long LFEc-LFBc # address_range
+ .byte 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIc0-LFBc
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .byte 8
+ .byte 0x84 # DW_CFA_offset %ebp, 2
+ .byte 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long LCFIc1-LCFIc0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .byte 4
+ .align 2
+LEFDEc:
+ .section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
+L_cpp_vtable_call$stub:
+ .indirect_symbol _cpp_vtable_call
+ hlt ; hlt ; hlt ; hlt ; hlt
+ .section __IMPORT,__pointers,non_lazy_symbol_pointers
+L___gxx_personality_v0$non_lazy_ptr:
+ .indirect_symbol ___gxx_personality_v0
+ .long 0
+ .constructor
+ .destructor
+ .align 1
+ .subsections_via_symbols
diff --git a/bridges/source/cpp_uno/gcc3_macosx_intel/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_macosx_intel/cpp2uno.cxx
new file mode 100644
index 000000000000..11c1d0f10db2
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_intel/cpp2uno.cxx
@@ -0,0 +1,522 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "share.hxx"
+
+#include "boost/static_assert.hpp"
+#include <stdio.h>
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+void cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** pCallStack,
+ void * pReturnValue )
+{
+ // pCallStack: ret, [return ptr], this, params
+ char * pCppStack = (char *)(pCallStack +1);
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if (pReturnTypeDescr)
+ {
+ // xxx todo: test PolyStructy<STRUCT<long>> foo()
+ if (CPPU_CURRENT_NAMESPACE::isSimpleReturnType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pReturnValue; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)pCppStack;
+ pCppStack += sizeof(void *);
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ // value
+ {
+ pCppArgs[nPos] = pCppStack;
+ pUnoArgs[nPos] = pCppStack;
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ default:
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ pCppArgs[nPos] = *(void **)pCppStack;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException(
+ &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ if (pReturnValue != pCppReturn) {
+ // complex return ptr is set to eax if return value
+ // is not transferred via eax[/edx]:
+ *static_cast< void ** >(pReturnValue) = pCppReturn;
+ }
+ }
+ if (pReturnTypeDescr)
+ {
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+ }
+}
+
+
+//==================================================================================================
+extern "C" void cpp_vtable_call(
+ int nFunctionIndex, int nVtableOffset, void** pCallStack,
+ void * pReturnValue )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: ret adr, [ret *], this, params
+ void * pThis;
+ if( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = pCallStack[2];
+ }
+ else
+ {
+ pThis = pCallStack[1];
+ }
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "%p %p %p pThis=%p, pCppI=%p, function index=%d, vtable offset=%d\n", pCallStack[0], pCallStack[1], pCallStack[2], pThis, pCppI, nFunctionIndex, nVtableOffset );
+#endif
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "name=%s\n", rtl::OUStringToOString(pTypeDescr->aBase.pTypeName, RTL_TEXTENCODING_UTF8).getStr() );
+#endif
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pThis );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+#if OSL_DEBUG_LEVEL > 1
+ fprintf(stderr, "calling %s\n", rtl::OUStringToOString(aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_UTF8).getStr());
+#endif
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pReturnValue );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pReturnValue );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[3] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pCallStack[1] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *static_cast< void ** >(pReturnValue) = pCallStack[1];
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pReturnValue );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pThis );
+ }
+ }
+}
+
+//==================================================================================================
+extern "C" void privateSnippetExecutorGeneral();
+extern "C" void privateSnippetExecutorVoid();
+extern "C" void privateSnippetExecutorHyper();
+extern "C" void privateSnippetExecutorFloat();
+extern "C" void privateSnippetExecutorDouble();
+extern "C" void privateSnippetExecutorClass();
+extern "C" typedef void (*PrivateSnippetExecutor)();
+
+int const codeSnippetSize = 16;
+
+unsigned char * codeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ typelib_TypeDescriptionReference * pReturnTypeRef)
+{
+ PrivateSnippetExecutor exec;
+ if (pReturnTypeRef == 0) {
+ exec = privateSnippetExecutorVoid;
+ }
+ else {
+ switch (pReturnTypeRef->eTypeClass) {
+ case typelib_TypeClass_VOID:
+ exec = privateSnippetExecutorVoid;
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ exec = privateSnippetExecutorHyper;
+ break;
+ case typelib_TypeClass_FLOAT:
+ exec = privateSnippetExecutorFloat;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ exec = privateSnippetExecutorDouble;
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION: {
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ bool const bSimpleReturnStruct =
+ CPPU_CURRENT_NAMESPACE::isSimpleReturnType(pReturnTypeDescr);
+ sal_Int32 const nRetSize = pReturnTypeDescr->nSize;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ if (bSimpleReturnStruct && nRetSize <= 8) {
+ exec = privateSnippetExecutorGeneral; // fills eax
+ if (nRetSize > 4)
+ exec = privateSnippetExecutorHyper; // fills eax/edx
+ break;
+ }
+ }
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_INTERFACE:
+ case typelib_TypeClass_ANY:
+ functionIndex |= 0x80000000;
+ exec = privateSnippetExecutorClass;
+ break;
+ default:
+ exec = privateSnippetExecutorGeneral;
+ break;
+ }
+ }
+ unsigned char * p = code;
+ OSL_ASSERT(sizeof (sal_Int32) == 4);
+ // mov function_index, %eax:
+ *p++ = 0xB8;
+ *reinterpret_cast< sal_Int32 * >(p) = functionIndex;
+ p += sizeof (sal_Int32);
+ // mov vtable_offset, %edx:
+ *p++ = 0xBA;
+ *reinterpret_cast< sal_Int32 * >(p) = vtableOffset;
+ p += sizeof (sal_Int32);
+ // jmp privateSnippetExecutor:
+ *p++ = 0xE9;
+ *reinterpret_cast< sal_Int32 * >(p)
+ = ((unsigned char *) exec) - p - sizeof (sal_Int32);
+ p += sizeof (sal_Int32);
+ OSL_ASSERT(p - code <= codeSnippetSize);
+ return code + codeSnippetSize;
+}
+
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0;
+ slots[-1].fn = 0;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef);
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ 0 /* indicates VOID */);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef);
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const *, unsigned char const *)
+{}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_macosx_intel/except.cxx b/bridges/source/cpp_uno/gcc3_macosx_intel/except.cxx
new file mode 100644
index 000000000000..c8cc3cd17257
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_intel/except.cxx
@@ -0,0 +1,331 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * )
+{
+}
+
+//==================================================================================================
+static OUString toUNOname( char const * p ) SAL_THROW( () )
+{
+#if OSL_DEBUG_LEVEL > 1
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+}
+
+//==================================================================================================
+class RTTI
+{
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+{
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind2( m_generatedRttis.find( unoName ) );
+ if (iFind2 == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with _ZTI
+ char const * rttiName = symName.getStr() +4;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iFind2->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void deleteException( void * pExc )
+{
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() );
+#endif
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get typedescription for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+{
+ if (! header)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_macosx_intel/makefile.mk b/bridges/source/cpp_uno/gcc3_macosx_intel/makefile.mk
new file mode 100644
index 000000000000..7bca40bbaf97
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_intel/makefile.mk
@@ -0,0 +1,76 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCMACOSXIgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/call.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+SHL1RPATH = URELIB
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.s
+ $(CC) -c -o $(SLO)$/$(@:b).o $<
+ touch $@
diff --git a/bridges/source/cpp_uno/gcc3_macosx_intel/share.hxx b/bridges/source/cpp_uno/gcc3_macosx_intel/share.hxx
new file mode 100644
index 000000000000..8b105c0880b3
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_intel/share.hxx
@@ -0,0 +1,95 @@
+/* -*- 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 "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+bool isSimpleReturnType(typelib_TypeDescription * pTD, bool recursive = false);
+
+void dummy_can_throw_anything( char const * );
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_macosx_intel/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_macosx_intel/uno2cpp.cxx
new file mode 100644
index 000000000000..aaf696608e41
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_intel/uno2cpp.cxx
@@ -0,0 +1,496 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "share.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+// The call instruction within the asm section of callVirtualMethod may throw
+// exceptions. So that the compiler handles this correctly, it is important
+// that (a) callVirtualMethod might call dummy_can_throw_anything (although this
+// never happens at runtime), which in turn can throw exceptions, and (b)
+// callVirtualMethod is not inlined at its call site (so that any exceptions are
+// caught which are thrown from the instruction calling callVirtualMethod):
+void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs ) __attribute__((noinline));
+
+void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs )
+{
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ OSL_ENSURE( pStackLongs && pAdjustedThisPtr, "### null ptr!" );
+ OSL_ENSURE( (sizeof(void *) == 4) && (sizeof(sal_Int32) == 4), "### unexpected size of int!" );
+ OSL_ENSURE( nStackLongs && pStackLongs, "### no stack in callVirtualMethod !" );
+
+ // never called
+ if (! pAdjustedThisPtr) CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
+
+ volatile long edx = 0, eax = 0; // for register returns
+ void * stackptr;
+ asm volatile (
+ "mov %%esp, %6\n\t"
+ "mov %0, %%eax\n\t"
+ "mov %%eax, %%edx\n\t"
+ // stack padding to keep stack aligned:
+ "shl $2, %%eax\n\t"
+ "neg %%eax\n\t"
+ "add %%esp, %%eax\n\t"
+ "and $0xf, %%eax\n\t"
+ "sub %%eax, %%esp\n\t"
+ // copy:
+ "mov %%edx, %%eax\n\t"
+ "dec %%edx\n\t"
+ "shl $2, %%edx\n\t"
+ "add %1, %%edx\n"
+ "Lcopy:\n\t"
+ "pushl 0(%%edx)\n\t"
+ "sub $4, %%edx\n\t"
+ "dec %%eax\n\t"
+ "jne Lcopy\n\t"
+ // do the actual call
+ "mov %2, %%edx\n\t"
+ "mov 0(%%edx), %%edx\n\t"
+ "mov %3, %%eax\n\t"
+ "shl $2, %%eax\n\t"
+ "add %%eax, %%edx\n\t"
+ "mov 0(%%edx), %%edx\n\t"
+ "call *%%edx\n\t"
+ // save return registers
+ "mov %%eax, %4\n\t"
+ "mov %%edx, %5\n\t"
+ // cleanup stack
+ "mov %6, %%esp\n\t"
+ :
+ : "m"(nStackLongs), "m"(pStackLongs), "m"(pAdjustedThisPtr),
+ "m"(nVtableIndex), "m"(eax), "m"(edx), "m"(stackptr)
+ : "eax", "edx" );
+ switch( pReturnTypeDescr->eTypeClass )
+ {
+ case typelib_TypeClass_VOID:
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ ((long*)pRegisterReturn)[1] = edx;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_ENUM:
+ ((long*)pRegisterReturn)[0] = eax;
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = eax;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = eax;
+ break;
+ case typelib_TypeClass_FLOAT:
+ asm ( "fstps %0" : : "m"(*(char *)pRegisterReturn) );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ asm ( "fstpl %0\n\t" : : "m"(*(char *)pRegisterReturn) );
+ break;
+ default: {
+ sal_Int32 const nRetSize = pReturnTypeDescr->nSize;
+ if (bSimpleReturn && nRetSize <= 8 && nRetSize > 0) {
+ if (nRetSize > 4)
+ static_cast<long *>(pRegisterReturn)[1] = edx;
+ static_cast<long *>(pRegisterReturn)[0] = eax;
+ }
+ break;
+ }
+ }
+}
+
+//==================================================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ char * pCppStack =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ char * pCppStackStart = pCppStack;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+ bool bSimpleReturn = true;
+
+ if (pReturnTypeDescr)
+ {
+ bSimpleReturn = CPPU_CURRENT_NAMESPACE::isSimpleReturnType(
+ pReturnTypeDescr);
+ if (bSimpleReturn)
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ // complex return via ptr
+ *(void **)pCppStack = pCppReturn;
+ pCppStack += sizeof(void *);
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ default:
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ try
+ {
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr, bSimpleReturn,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr, "caught C++ exception\n" );
+#endif
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+namespace CPPU_CURRENT_NAMESPACE {
+bool isSimpleReturnType(typelib_TypeDescription * pTD, bool recursive)
+{
+ if (bridges::cpp_uno::shared::isSimpleType( pTD ))
+ return true;
+ // Only structs of exactly 1, 2, 4, or 8 bytes are returned through
+ // registers, see <http://developer.apple.com/documentation/DeveloperTools/
+ // Conceptual/LowLevelABI/Articles/IA32.html>:
+ if (pTD->eTypeClass == typelib_TypeClass_STRUCT &&
+ (recursive || pTD->nSize <= 2 || pTD->nSize == 4 || pTD->nSize == 8))
+ {
+ typelib_CompoundTypeDescription *const pCompTD =
+ (typelib_CompoundTypeDescription *) pTD;
+ for ( sal_Int32 pos = pCompTD->nMembers; pos--; ) {
+ typelib_TypeDescription * pMemberTD = 0;
+ TYPELIB_DANGER_GET( &pMemberTD, pCompTD->ppTypeRefs[pos] );
+ bool const b = isSimpleReturnType(pMemberTD, true);
+ TYPELIB_DANGER_RELEASE( pMemberTD );
+ if (! b)
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+}
+
+//==================================================================================================
+
+namespace bridges { namespace cpp_uno { namespace shared {
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; // get, then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_macosx_powerpc/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_macosx_powerpc/cpp2uno.cxx
new file mode 100644
index 000000000000..f3515a86ea08
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_powerpc/cpp2uno.cxx
@@ -0,0 +1,732 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "share.hxx"
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+
+ // gpreg: [ret *], this, [gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (space for entire parameter list in structure format properly aligned)]
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ sal_Int32 ngpreg = 0;
+ sal_Int32 nfpreg = 0;
+
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *gpreg;
+ ngpreg++;
+ ++ovrflw;
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ ngpreg++;
+ ++ovrflw;
+
+ // after handling optional return pointer and "this"
+ // make use of the space that is allocated to store all parameters in the callers stack
+ // by comying the proper registers filled with parameters to that space
+ char * pCppStack = (char *)ovrflw;
+
+
+ sal_Int32 nPos;
+
+ for ( nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ if (rParam.bOut)
+ {
+ if (ngpreg < 8)
+ {
+ *(sal_Int32 *)pCppStack = ((sal_Int32 *)gpreg)[ngpreg++];
+ }
+ pCppStack += sizeof (sal_Int32);
+ }
+ else
+ {
+ switch (rParam.pTypeRef->eTypeClass)
+ {
+ case typelib_TypeClass_FLOAT:
+ if (nfpreg < 13)
+ {
+ *(float *)pCppStack = ((double *)fpreg)[nfpreg++];
+ }
+ pCppStack += sizeof (float);
+ ngpreg += 1;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (nfpreg < 13)
+ {
+ *(double *)pCppStack = ((double *)fpreg)[nfpreg++];
+ }
+ pCppStack += sizeof (double);
+ ngpreg += 2;
+ break;
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_HYPER:
+ if (ngpreg < 8)
+ {
+ *(sal_Int32 *)pCppStack = ((sal_Int32 *)gpreg)[ngpreg++];
+ }
+ pCppStack += sizeof (sal_Int32);
+ // fall through on purpose
+ default:
+ if (ngpreg < 8)
+ {
+ *(sal_Int32 *)pCppStack = ((sal_Int32 *)gpreg)[ngpreg++];
+ }
+ pCppStack += sizeof (sal_Int32);
+ }
+ }
+ }
+
+ // now the stack has all of the paramters stored in it ready to be processed
+ // so we are ready to build the uno call stack
+ pCppStack = (char *)ovrflw;
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ // value
+ {
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ pCppArgs[nPos] = pCppStack +3;
+ pUnoArgs[nPos] = pCppStack +3;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ pCppArgs[nPos] = pCppStack +2;
+ pUnoArgs[nPos] = pCppStack +2;
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppArgs[nPos] = pCppStack;
+ pUnoArgs[nPos] = pCppStack;
+ pCppStack += sizeof(sal_Int32); // extra long (two regs)
+ break;
+ default:
+ pCppArgs[nPos] = pCppStack;
+ pUnoArgs[nPos] = pCppStack;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ pCppArgs[nPos] = *(void **)pCppStack;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException(
+ &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to return reg
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
+ void ** gpreg, void ** fpreg, void ** ovrflw,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // gpreg: [ret *], this, [other gpr params]
+ // fpreg: [fpr params]
+ // ovrflw: [gpr or fpr params (in space allocated for all params properly aligned)]
+
+ void * pThis;
+ if( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = gpreg[1];
+ }
+ else
+ {
+ pThis = gpreg[0];
+ }
+
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(pThis);
+
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pThis );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( gpreg[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = gpreg[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ gpreg, fpreg, ovrflw, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** gpregptr, void** fpregptr, void** ovrflw)
+{
+ sal_Int32 gpreg[8];
+ double fpreg[13];
+
+ // FIXME: why are we restoring the volatile ctr register here
+ sal_Int32 ctrsave = ((sal_Int32*)gpregptr)[-1];
+
+ memcpy( gpreg, gpregptr, 32);
+ memcpy( fpreg, fpregptr, 104);
+
+ volatile long nRegReturn[2];
+
+ // sal_Bool bComplex = nFunctionIndex & 0x80000000 ? sal_True : sal_False;
+
+ typelib_TypeClass aType =
+ cpp_mediate( nFunctionIndex, nVtableOffset, (void**)gpreg, (void**)fpreg, ovrflw, (sal_Int64*)nRegReturn );
+
+ // FIXME: why are we restoring the volatile ctr register here
+ // FIXME: and why are we putting back the values for r4, r5, and r6 as well
+ // FIXME: this makes no sense to me, all of these registers are volatile!
+ __asm__( "lwz r4, %0\n\t"
+ "mtctr r4\n\t"
+ "lwz r4, %1\n\t"
+ "lwz r5, %2\n\t"
+ "lwz r6, %3\n\t"
+ : : "m"(ctrsave), "m"(gpreg[1]), "m"(gpreg[2]), "m"(gpreg[3]) );
+
+ switch( aType )
+ {
+
+ // move return value into register space
+ // (will be loaded by machine code snippet)
+
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ __asm__( "lbz r3,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ __asm__( "lhz r3,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+
+ case typelib_TypeClass_FLOAT:
+ __asm__( "lfs f1,%0\n\t" : :
+ "m" (*((float*)nRegReturn)) );
+ break;
+
+ case typelib_TypeClass_DOUBLE:
+ __asm__( "lfd f1,%0\n\t" : :
+ "m" (*((double*)nRegReturn)) );
+ break;
+
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ __asm__( "lwz r4,%0\n\t" : :
+ "m"(nRegReturn[1]) ); // fall through
+
+ default:
+ __asm__( "lwz r3,%0\n\t" : :
+ "m"(nRegReturn[0]) );
+ break;
+ }
+}
+
+
+int const codeSnippetSize = 136;
+
+unsigned char * codeSnippet( unsigned char * code, sal_Int32 functionIndex,
+ sal_Int32 vtableOffset, bool simpleRetType )
+{
+ if (! simpleRetType )
+ functionIndex |= 0x80000000;
+
+ // OSL_ASSERT( sizeof (long) == 4 );
+
+ // FIXME: why are we leaving an 8k gap in the stack here
+ // FIXME: is this to allow room for signal handling frames?
+ // FIXME: seems like overkill here but this is what was done for Mac OSX for gcc2
+ // FIXME: also why no saving of the non-volatile CR pieces here, to be safe
+ // FIXME: we probably should
+
+ /* generate this code */
+
+ // # so first save gpr 3 to gpr 10 (aligned to 4)
+ // stw r3, -8000(r1)
+ // stw r4, -7996(r1)
+ // stw r5, -7992(r1)
+ // stw r6, -7988(r1)
+ // stw r7, -7984(r1)
+ // stw r8, -7980(r1)
+ // stw r9, -7976(r1)
+ // stw r10,-7972(r1)
+
+ // # next save fpr 1 to fpr 13 (aligned to 8)
+ // stfd f1, -7968(r1)
+ // stfd f2, -7960(r1)
+ // stfd f3, -7952(r1)
+ // stfd f4, -7944(r1)
+ // stfd f5, -7936(r1)
+ // stfd f6, -7928(r1)
+ // stfd f7, -7920(r1)
+ // stfd f8, -7912(r1)
+ // stfd f9, -7904(r1)
+ // stfd f10,-7896(r1)
+ // stfd f11,-7888(r1)
+ // stfd f12,-7880(r1)
+ // stfd f13,-7872(r1)
+
+ // FIXME: ctr is volatile, while are we saving it and not CR?
+ // mfctr r3
+ // stw r3, -8004(r1)
+
+ // # now here is where cpp_vtable_call must go
+ // lis r3,0xdead
+ // ori r3,r3,0xbeef
+ // mtctr r3
+
+ // # now load up the functionIndex number
+ // lis r3, 0xdead
+ // ori r3,r3,0xbeef
+
+ // # now load up the vtableOffset
+ // lis r4, 0xdead
+ // ori r4,r4,0xbeef
+
+ // #now load up the pointer to the saved gpr registers
+ // addi r5,r1,-8000
+
+ // #now load up the pointer to the saved fpr registers
+ // addi r6,r1,-7968
+
+ // #now load up the pointer to the overflow call stack
+ // addi r7,r1,24 # frame pointer plus 24
+
+ // bctr
+
+ unsigned long * p = (unsigned long *) code;
+
+ * p++ = 0x9061e0c0;
+ * p++ = 0x9081e0c4;
+ * p++ = 0x90a1e0c8;
+ * p++ = 0x90c1e0cc;
+ * p++ = 0x90e1e0d0;
+ * p++ = 0x9101e0d4;
+ * p++ = 0x9121e0d8;
+ * p++ = 0x9141e0dc;
+ * p++ = 0xd821e0e0;
+ * p++ = 0xd841e0e8;
+ * p++ = 0xd861e0f0;
+ * p++ = 0xd881e0f8;
+ * p++ = 0xd8a1e100;
+ * p++ = 0xd8c1e108;
+ * p++ = 0xd8e1e110;
+ * p++ = 0xd901e118;
+ * p++ = 0xd921e120;
+ * p++ = 0xd941e128;
+ * p++ = 0xd961e130;
+ * p++ = 0xd981e138;
+ * p++ = 0xd9a1e140;
+ * p++ = 0x7c6902a6;
+ * p++ = 0x9061e0bc;
+ * p++ = 0x3c600000 | (((unsigned long)cpp_vtable_call) >> 16);
+ * p++ = 0x60630000 | (((unsigned long)cpp_vtable_call) & 0x0000FFFF);
+ * p++ = 0x7c6903a6;
+ * p++ = 0x3c600000 | (((unsigned long)functionIndex) >> 16);
+ * p++ = 0x60630000 | (((unsigned long)functionIndex) & 0x0000FFFF);
+ * p++ = 0x3c800000 | (((unsigned long)vtableOffset) >> 16);
+ * p++ = 0x60840000 | (((unsigned long)vtableOffset) & 0x0000FFFF);
+ * p++ = 0x38a1e0c0;
+ * p++ = 0x38c1e0e0;
+ * p++ = 0x38e10018;
+ * p++ = 0x4e800420;
+
+ return (code + codeSnippetSize);
+
+}
+
+
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(unsigned char const * bptr, unsigned char const * eptr)
+{
+ int const lineSize = 32;
+ for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
+ __asm__ volatile ("dcbst 0, %0" : : "r"(p) : "memory");
+ }
+ __asm__ volatile ("sync" : : : "memory");
+ for (unsigned char const * p = bptr; p < eptr + lineSize; p += lineSize) {
+ __asm__ volatile ("icbi 0, %0" : : "r"(p) : "memory");
+ }
+ __asm__ volatile ("isync" : : : "memory");
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0;
+ slots[-1].fn = 0;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+
+ // fprintf(stderr, "in addLocalFunctions functionOffset is %x\n",functionOffset);
+ // fprintf(stderr, "in addLocalFunctions vtableOffset is %x\n",vtableOffset);
+ // fflush(stderr);
+
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_macosx_powerpc/except.cxx b/bridges/source/cpp_uno/gcc3_macosx_powerpc/except.cxx
new file mode 100644
index 000000000000..abc3ad10fc37
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_powerpc/except.cxx
@@ -0,0 +1,288 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * )
+{
+}
+
+//==================================================================================================
+static OUString toUNOname( char const * p ) SAL_THROW( () )
+{
+#ifdef DEBUG
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#ifdef DEBUG
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+}
+
+//==================================================================================================
+class RTTI
+{
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+{
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iiFind( m_generatedRttis.find( unoName ) );
+ if (iiFind == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with _ZTI
+ char const * rttiName = symName.getStr() +4;
+#ifdef DEBUG
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iiFind->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void deleteException( void * pExc )
+{
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ terminate();
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ terminate();
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno )
+{
+ OSL_ENSURE( header, "### no exception header!!!" );
+ if (! header)
+ terminate();
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" );
+ if (! pExcTypeDescr)
+ terminate();
+
+ // construct uno exception any
+ ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ ::typelib_typedescription_release( pExcTypeDescr );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_macosx_powerpc/makefile.mk b/bridges/source/cpp_uno/gcc3_macosx_powerpc/makefile.mk
new file mode 100644
index 000000000000..381d39c607c1
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_powerpc/makefile.mk
@@ -0,0 +1,78 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCMACOSXPgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+NOOPTFILES= \
+ $(SLO)$/uno2cpp.obj
+
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS= $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB) \
+ -ldl
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/gcc3_macosx_powerpc/share.hxx b/bridges/source/cpp_uno/gcc3_macosx_powerpc/share.hxx
new file mode 100644
index 000000000000..4ec09c29ff0a
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_powerpc/share.hxx
@@ -0,0 +1,94 @@
+/* -*- 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 "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+ void dummy_can_throw_anything( char const * );
+
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_macosx_powerpc/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_macosx_powerpc/uno2cpp.cxx
new file mode 100644
index 000000000000..39388fc602f0
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_powerpc/uno2cpp.cxx
@@ -0,0 +1,637 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sys/types.h>
+#include <sys/malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "share.hxx"
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+static void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ char * pPT,
+ sal_Int32 * pStackLongs,
+ sal_Int32 /* nStackLongs */)
+{
+
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ // the basic idea here is to use gpr[8] as a storage area for
+ // the future values of registers r3 to r10 needed for the call,
+ // and similarly fpr[13] as a storage area for the future values
+ // of floating point registers f1 to f13
+
+ unsigned long * mfunc; // actual function to be invoked
+ void (*ptr)();
+ int gpr[8]; // storage for gpregisters, map to r3-r10
+ int off; // offset used to find function
+ double fpr[13]; // storage for fpregisters, map to f1-f13
+ int n; // number of gprs mapped so far
+ int f; // number of fprs mapped so far
+ volatile long *p; // pointer to parameter overflow area
+ int c; // character of parameter type being decoded
+ volatile double dret; // temporary function return values
+ volatile int iret, iret2;
+
+ // Because of the Power PC calling conventions we could be passing
+ // parameters in both register types and on the stack. To create the
+ // stack parameter area we need we now simply allocate local
+ // variable storage param[] that is at least the size of the parameter stack
+ // (more than enough space) which we can overwrite the parameters into.
+
+ // Note: This keeps us from having to decode the signature twice and
+ // prevents problems with later local variables.
+
+ // FIXME: I do not believe the following is true but we will keep the
+ // FIXME: extra space just to be safe until proven otherwise
+
+ // Note: could require up to 2*nStackLongs words of parameter stack area
+ // if the call has many float parameters (i.e. floats take up only 1
+ // word on the stack but take 2 words in parameter area in the
+ // stack frame .
+
+
+ // unsigned long param[(2*nStackLongs)];
+
+ /* now begin to load the C++ function arguments into storage */
+ n = 0;
+ f = 0;
+
+
+ /* set up a pointer to the stack parameter area */
+ __asm__ ( "addi %0,r1,24" : "=r" (p) : /* no inputs */ );
+
+ // #i94421#, work around compiler error:
+ volatile long * pCopy = p;
+ (void) pCopy; // avoid warning about unused variable
+
+ // never called
+ // if (! pAdjustedThisPtr )CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
+
+
+ // now we need to parse the entire signature string
+ // until we get the END indicator
+
+ // treat complex return pointer like any other parameter
+
+ // parse the argument list up to the ending )
+
+ while (*pPT != 'X') {
+ c = *pPT;
+ switch (c) {
+
+ case 'D': /* type is double */
+ if (f < 13) {
+ fpr[f++] = *((double *)pStackLongs); /* store in register */
+ n+=2;
+ p+=2;
+ } else {
+ *p++ = *pStackLongs; /* or on the parameter stack */
+ *p++ = *(pStackLongs + 1);
+ }
+ pStackLongs += 2;
+ break;
+
+ case 'F': /* type is float */
+ /* floats are stored as 1 32 bit word on param stack */
+ if (f < 13) {
+ fpr[f++] = *((float *)pStackLongs);
+ n+=1;
+ p++;
+ } else {
+ *((float *)p) = *((float *)pStackLongs);
+ p += 1;
+ }
+ pStackLongs += 1;
+ break;
+
+ case 'H': /* type is long long */
+ if (n < 8)
+ {
+ gpr[n++] = *pStackLongs;
+ p++;
+ }
+ else
+ *p++ = *pStackLongs;
+ if(n < 8)
+ {
+ gpr[n++] = *(pStackLongs+1);
+ p++;
+ }
+ else
+ *p++ = *(pStackLongs+1);
+ pStackLongs += 2;
+ break;
+
+ case 'S':
+ if (n < 8) {
+ gpr[n++] = *((unsigned short*)pStackLongs);
+ p++;
+ } else {
+ *p++ = *((unsigned short *)pStackLongs);
+ }
+ pStackLongs += 1;
+ break;
+
+ case 'B':
+ if (n < 8) {
+ gpr[n++] = *((char *)pStackLongs);
+ p++;
+ } else {
+ *p++ = *((char *)pStackLongs);
+ }
+ pStackLongs += 1;
+ break;
+
+ default:
+ if (n < 8) {
+ gpr[n++] = *pStackLongs;
+ p++;
+ } else {
+ *p++ = *pStackLongs;
+ }
+ pStackLongs += 1;
+ break;
+ }
+ pPT++;
+ }
+
+
+ /* figure out the address of the function we need to invoke */
+ off = nVtableIndex;
+ off = off * 4; // 4 bytes per slot
+ mfunc = *((unsigned long **)pAdjustedThisPtr); // get the address of the vtable
+ mfunc = (unsigned long *)((char *)mfunc + off); // get the address from the vtable entry at offset
+ mfunc = *((unsigned long **)mfunc); // the function is stored at the address
+ ptr = (void (*)())mfunc;
+
+ /* Set up the machine registers and invoke the function */
+
+ __asm__ __volatile__ (
+ "lwz r3, 0(%0)\n\t"
+ "lwz r4, 4(%0)\n\t"
+ "lwz r5, 8(%0)\n\t"
+ "lwz r6, 12(%0)\n\t"
+ "lwz r7, 16(%0)\n\t"
+ "lwz r8, 20(%0)\n\t"
+ "lwz r9, 24(%0)\n\t"
+ "lwz r10, 28(%0)\n\t"
+ "lfd f1, 0(%1)\n\t"
+ "lfd f2, 8(%1)\n\t"
+ "lfd f3, 16(%1)\n\t"
+ "lfd f4, 24(%1)\n\t"
+ "lfd f5, 32(%1)\n\t"
+ "lfd f6, 40(%1)\n\t"
+ "lfd f7, 48(%1)\n\t"
+ "lfd f8, 56(%1)\n\t"
+ "lfd f9, 64(%1)\n\t"
+ "lfd f10, 72(%1)\n\t"
+ "lfd f11, 80(%1)\n\t"
+ "lfd f12, 88(%1)\n\t"
+ "lfd f13, 96(%1)\n\t"
+ : : "r" (gpr), "r" (fpr)
+ : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
+ "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9",
+ "f10", "f11", "f12", "f13"
+ );
+
+ (*ptr)();
+
+
+ __asm__ __volatile__ (
+ "stw r3, %1\n\t"
+ "stw r4, %2\n\t"
+ "stfd f1, %0\n\t"
+ : : "m" (dret), "m" (iret), "m" (iret2)
+ );
+
+
+ switch( eReturnType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ ((long*)pRegisterReturn)[1] = iret2;
+ // fall thru on purpose
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ ((long*)pRegisterReturn)[0] = iret;
+ break;
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = (unsigned short)iret;
+ break;
+
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = (unsigned char)iret;
+ break;
+
+ case typelib_TypeClass_FLOAT:
+ *(float*)pRegisterReturn = (float)dret;
+ break;
+
+ case typelib_TypeClass_DOUBLE:
+ *(double*)pRegisterReturn = dret;
+ break;
+ default:
+ break;
+ }
+}
+
+
+//==================================================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ char * pCppStack =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ char * pCppStackStart = pCppStack;
+
+ // need to know parameter types for callVirtualMethod so generate a signature string
+ char * pParamType = (char *) alloca(nParams+2);
+ char * pPT = pParamType;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack
+ = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ *pPT++ = 'C'; //signify that a complex return type on stack
+ pCppStack += sizeof(void *);
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+ *pPT++ = 'I';
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+
+ // we need to know type of each param so that we know whether to use
+ // gpr or fpr to pass in parameters:
+ // Key: I - int, long, pointer, etc means pass in gpr
+ // B - byte value passed in gpr
+ // S - short value passed in gpr
+ // F - float value pass in fpr
+ // D - double value pass in fpr
+ // H - long long int pass in proper pairs of gpr (3,4) (5,6), etc
+ // X - indicates end of parameter description string
+
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ *pPT++ = 'I';
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *pPT++ = 'S';
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *pPT++ = 'B';
+ break;
+ case typelib_TypeClass_FLOAT:
+ *pPT++ = 'F';
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *pPT++ = 'D';
+ pCppStack += sizeof(sal_Int32); // extra long
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *pPT++ = 'H';
+ pCppStack += sizeof(sal_Int32); // extra long
+ default:
+ break;
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ *pPT++='I';
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // terminate the signature string
+ *pPT++='X';
+ *pPT=0;
+
+ try
+ {
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass, pParamType,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * > (pUnoI);
+ // typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; //get then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_os2_intel/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_os2_intel/cpp2uno.cxx
new file mode 100644
index 000000000000..8b19ff92760c
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_os2_intel/cpp2uno.cxx
@@ -0,0 +1,528 @@
+/* -*- 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 <sal/alloca.h>
+#include <stdio.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "share.hxx"
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ // pCallStack: ret, [return ptr], this, params
+ char * pCppStack = (char *)(pCallStack +1);
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)pCppStack;
+ pCppStack += sizeof(void *);
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ // value
+ {
+ pCppArgs[nPos] = pCppStack;
+ pUnoArgs[nPos] = pCppStack;
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ pCppArgs[nPos] = *(void **)pCppStack;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc = {0}; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+#if OSL_DEBUG_LEVEL > 1
+ if (pUnoExc != NULL)
+ fprintf( stderr, ">cpp2uno_call pUnoExc %x\n", pUnoExc);
+#endif
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException(
+ &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: ret adr, [ret *], this, params
+ void * pThis;
+ if( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = pCallStack[2];
+ }
+ else
+ {
+ pThis = pCallStack[1];
+ }
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pThis );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[3] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pCallStack[1] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = pCallStack[1];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static void cpp_vtable_call(
+ int nFunctionIndex, int nVtableOffset, void** pCallStack )
+ __attribute__((regparm(3)));
+
+void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** pCallStack )
+{
+ volatile long nRegReturn[2];
+ typelib_TypeClass aType = cpp_mediate(
+ nFunctionIndex, nVtableOffset, pCallStack, (sal_Int64*)nRegReturn );
+
+ switch( aType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ __asm__( "movl %1, %%edx\n\t"
+ "movl %0, %%eax\n"
+ : : "m"(nRegReturn[0]), "m"(nRegReturn[1]) );
+ break;
+ case typelib_TypeClass_FLOAT:
+ __asm__( "flds %0\n\t"
+ "fstp %%st(0)\n\t"
+ "flds %0\n"
+ : : "m"(*(float *)nRegReturn) );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ __asm__( "fldl %0\n\t"
+ "fstp %%st(0)\n\t"
+ "fldl %0\n"
+ : : "m"(*(double *)nRegReturn) );
+ break;
+// case typelib_TypeClass_UNSIGNED_SHORT:
+// case typelib_TypeClass_SHORT:
+// __asm__( "movswl %0, %%eax\n"
+// : : "m"(nRegReturn) );
+// break;
+ default:
+ __asm__( "movl %0, %%eax\n"
+ : : "m"(nRegReturn[0]) );
+ break;
+ }
+}
+
+
+//==================================================================================================
+int const codeSnippetSize = 20;
+
+unsigned char * codeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ bool simpleRetType)
+{
+ if (!simpleRetType) {
+ functionIndex |= 0x80000000;
+ }
+ unsigned char * p = code;
+ OSL_ASSERT(sizeof (sal_Int32) == 4);
+ // mov function_index, %eax:
+ *p++ = 0xB8;
+ *reinterpret_cast< sal_Int32 * >(p) = functionIndex;
+ p += sizeof (sal_Int32);
+ // mov vtable_offset, %edx:
+ *p++ = 0xBA;
+ *reinterpret_cast< sal_Int32 * >(p) = vtableOffset;
+ p += sizeof (sal_Int32);
+ // mov %esp, %ecx:
+ *p++ = 0x89;
+ *p++ = 0xE1;
+ // jmp cpp_vtable_call:
+ *p++ = 0xE9;
+ *reinterpret_cast< sal_Int32 * >(p)
+ = ((unsigned char *) cpp_vtable_call) - p - sizeof (sal_Int32);
+ p += sizeof (sal_Int32);
+ OSL_ASSERT(p - code <= codeSnippetSize);
+ return code + codeSnippetSize;
+}
+
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0;
+ slots[-1].fn = 0;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const *, unsigned char const *)
+{}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_os2_intel/defs/gcc3_uno.def b/bridges/source/cpp_uno/gcc3_os2_intel/defs/gcc3_uno.def
new file mode 100644
index 000000000000..d6b247ec996b
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_os2_intel/defs/gcc3_uno.def
@@ -0,0 +1,915 @@
+LIBRARY gcc3_uno INITINSTANCE TERMINSTANCE
+DATA MULTIPLE
+DESCRIPTION 'StarView 3.00 680 '
+EXPORTS
+_GetVersionInfo
+_component_canUnload
+_uno_initEnvironment
+_uno_ext_getMapping
+
+;lmax=20
+;smax=_component_canUnload
+
+;__ZTIN4test19TestBridgeExceptionE
+
+__ZTIN10comphelper18OPropertyContainerE
+__ZTIN10comphelper24OPropertyContainerHelperE
+__ZTIN10comphelper25OPropertyArrayUsageHelperIN9configmgr22OConfigurationProviderEEE
+__ZTIN3com3sun4star13configuration17XTemplateInstanceE
+__ZTIN3com3sun4star13configuration18XTemplateContainerE
+__ZTIN3com3sun4star13configuration29InvalidBootstrapFileExceptionE
+__ZTIN3com3sun4star13configuration29MissingBootstrapFileExceptionE
+__ZTIN3com3sun4star13configuration31InstallationIncompleteExceptionE
+__ZTIN3com3sun4star13configuration32CannotLoadConfigurationExceptionE
+__ZTIN3com3sun4star13configuration7backend13XLayerHandlerE
+__ZTIN3com3sun4star13configuration7backend14XSchemaHandlerE
+__ZTIN3com3sun4star13configuration7backend14XUpdateHandlerE
+__ZTIN3com3sun4star13configuration7backend15XCompositeLayerE
+__ZTIN3com3sun4star13configuration7backend15XSchemaSupplierE
+__ZTIN3com3sun4star13configuration7backend15XUpdatableLayerE
+__ZTIN3com3sun4star13configuration7backend16XBackendEntitiesE
+__ZTIN3com3sun4star13configuration7backend18XMultiLayerStratumE
+__ZTIN3com3sun4star13configuration7backend21BackendSetupExceptionE
+__ZTIN3com3sun4star13configuration7backend22BackendAccessExceptionE
+__ZTIN3com3sun4star13configuration7backend22CannotConnectExceptionE
+__ZTIN3com3sun4star13configuration7backend22MalformedDataExceptionE
+__ZTIN3com3sun4star13configuration7backend23ConnectionLostExceptionE
+__ZTIN3com3sun4star13configuration7backend23XBackendChangesListenerE
+__ZTIN3com3sun4star13configuration7backend23XBackendChangesNotifierE
+__ZTIN3com3sun4star13configuration7backend24StratumCreationExceptionE
+__ZTIN3com3sun4star13configuration7backend24XVersionedSchemaSupplierE
+__ZTIN3com3sun4star13configuration7backend29AuthenticationFailedExceptionE
+__ZTIN3com3sun4star13configuration7backend33InsufficientAccessRightsExceptionE
+__ZTIN3com3sun4star13configuration7backend39InvalidAuthenticationMechanismExceptionE
+__ZTIN3com3sun4star13configuration7backend6XLayerE
+__ZTIN3com3sun4star13configuration7backend7XSchemaE
+__ZTIN3com3sun4star13configuration7backend8XBackendE
+__ZTIN3com3sun4star2io11IOExceptionE
+__ZTIN3com3sun4star2io12XInputStreamE
+__ZTIN3com3sun4star2io13XOutputStreamE
+__ZTIN3com3sun4star2io15XActiveDataSinkE
+__ZTIN3com3sun4star2io16XDataInputStreamE
+__ZTIN3com3sun4star2io17XActiveDataSourceE
+__ZTIN3com3sun4star2io20WrongFormatExceptionE
+__ZTIN3com3sun4star2io21NotConnectedExceptionE
+__ZTIN3com3sun4star2io22UnexpectedEOFExceptionE
+__ZTIN3com3sun4star2io27BufferSizeExceededExceptionE
+__ZTIN3com3sun4star3uno10XInterfaceE
+__ZTIN3com3sun4star3uno15XCurrentContextE
+__ZTIN3com3sun4star3uno16RuntimeExceptionE
+__ZTIN3com3sun4star3uno17XComponentContextE
+__ZTIN3com3sun4star3uno5XWeakE
+__ZTIN3com3sun4star3uno9ExceptionE
+__ZTIN3com3sun4star3xml3sax12SAXExceptionE
+__ZTIN3com3sun4star3xml3sax14XAttributeListE
+__ZTIN3com3sun4star3xml3sax16XDocumentHandlerE
+;__ZTIN3com3sun4star4l
+__ZTIN3com3sun4star4lang10XComponentE
+__ZTIN3com3sun4star4lang10XUnoTunnelE
+__ZTIN3com3sun4star4lang12XLocalizableE
+__ZTIN3com3sun4star4lang12XServiceInfoE
+__ZTIN3com3sun4star4lang13XTypeProviderE
+__ZTIN3com3sun4star4lang14XEventListenerE
+__ZTIN3com3sun4star4lang15XInitializationE
+__ZTIN3com3sun4star4lang17DisposedExceptionE
+__ZTIN3com3sun4star4lang18NoSupportExceptionE
+__ZTIN3com3sun4star4lang20NullPointerExceptionE
+__ZTIN3com3sun4star4lang20XMultiServiceFactoryE
+__ZTIN3com3sun4star4lang21XSingleServiceFactoryE
+__ZTIN3com3sun4star4lang22IllegalAccessExceptionE
+__ZTIN3com3sun4star4lang22WrappedTargetExceptionE
+__ZTIN3com3sun4star4lang23XSingleComponentFactoryE
+__ZTIN3com3sun4star4lang24IllegalArgumentExceptionE
+__ZTIN3com3sun4star4lang29ServiceNotRegisteredExceptionE
+__ZTIN3com3sun4star4lang29WrappedTargetRuntimeExceptionE
+__ZTIN3com3sun4star4task17XInteractionAbortE
+__ZTIN3com3sun4star4task17XInteractionRetryE
+__ZTIN3com3sun4star4task19XInteractionApproveE
+__ZTIN3com3sun4star4task19XInteractionRequestE
+__ZTIN3com3sun4star4task22XInteractionDisapproveE
+__ZTIN3com3sun4star4task24XInteractionContinuationE
+__ZTIN3com3sun4star4util10XFlushableE
+__ZTIN3com3sun4star4util12XRefreshableE
+__ZTIN3com3sun4star4util12XTimeStampedE
+__ZTIN3com3sun4star4util13XChangesBatchE
+__ZTIN3com3sun4star4util13XStringEscapeE
+__ZTIN3com3sun4star4util16XChangesNotifierE
+__ZTIN3com3sun4star5beans10XExactNameE
+__ZTIN3com3sun4star5beans12XPropertySetE
+__ZTIN3com3sun4star5beans14XPropertyStateE
+__ZTIN3com3sun4star5beans16XFastPropertySetE
+__ZTIN3com3sun4star5beans16XPropertySetInfoE
+__ZTIN3com3sun4star5beans17XMultiPropertySetE
+__ZTIN3com3sun4star5beans18XPropertyWithStateE
+__ZTIN3com3sun4star5beans20XMultiPropertyStatesE
+__ZTIN3com3sun4star5beans21PropertyVetoExceptionE
+__ZTIN3com3sun4star5beans24UnknownPropertyExceptionE
+__ZTIN3com3sun4star5beans24XHierarchicalPropertySetE
+__ZTIN3com3sun4star5beans29XMultiHierarchicalPropertySetE
+__ZTIN3com3sun4star5beans9XPropertyE
+__ZTIN3com3sun4star6script22CannotConvertExceptionE
+__ZTIN3com3sun4star8registry12XRegistryKeyE
+__ZTIN3com3sun4star8registry15XSimpleRegistryE
+__ZTIN3com3sun4star8registry21InvalidValueExceptionE
+__ZTIN3com3sun4star8registry22MergeConflictExceptionE
+__ZTIN3com3sun4star8registry24InvalidRegistryExceptionE
+__ZTIN3com3sun4star9container10XContainerE
+__ZTIN3com3sun4star9container11XNameAccessE
+__ZTIN3com3sun4star9container12XNameReplaceE
+__ZTIN3com3sun4star9container14XElementAccessE
+__ZTIN3com3sun4star9container14XNameContainerE
+__ZTIN3com3sun4star9container17XHierarchicalNameE
+__ZTIN3com3sun4star9container21ElementExistExceptionE
+__ZTIN3com3sun4star9container22NoSuchElementExceptionE
+__ZTIN3com3sun4star9container23XHierarchicalNameAccessE
+__ZTIN3com3sun4star9container6XChildE
+__ZTIN3com3sun4star9container6XNamedE
+__ZTIN3vos10IReferenceE
+__ZTIN3vos10OReferenceE
+__ZTIN3vos6OTimerE
+__ZTIN3vos7OObjectE
+__ZTIN3vos7OThreadE
+__ZTIN3vos9IRunnableE
+__ZTIN4cppu11ImplHelper2IN3com3sun4star8registry15XSimpleRegistryENS3_4util10XFlushableEEE
+__ZTIN4cppu11ImplHelper4IN3com3sun4star4lang20XMultiServiceFactoryENS4_12XLocalizableENS3_4util12XRefreshableENS7_10XFlushableEEE
+__ZTIN4cppu11ImplHelper6IN3com3sun4star5beans12XPropertySetENS4_17XMultiPropertySetENS4_24XHierarchicalPropertySetENS4_29XMultiHierarchicalPropertySetENS4_14XPropertyStateENS4_20XMultiPropertyStatesEEE
+__ZTIN4cppu11ImplHelper6IN3com3sun4star9container11XNameAccessENS4_17XHierarchicalNameENS4_23XHierarchicalNameAccessENS4_10XContainerENS3_5beans10XExactNameENS9_9XPropertyEEE
+__ZTIN4cppu11ImplHelper9IN3com3sun4star9container11XNameAccessENS4_17XHierarchicalNameENS4_23XHierarchicalNameAccessENS4_10XContainerENS3_5beans10XExactNameENS9_9XPropertyENS9_16XPropertySetInfoENS3_13configuration18XTemplateCo!_yPkJc2
+__ZTIN4cppu11OWeakObjectE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend13XLayerHandlerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend14XSchemaHandlerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend15XCompositeLayerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend23XBackendChangesListenerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star2io13XOutputStreamEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star2io16XDataInputStreamEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star3uno15XCurrentContextEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star3xml3sax14XAttributeListEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star3xml3sax16XDocumentHandlerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4lang14XEventListenerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4lang23XSingleComponentFactoryEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task17XInteractionAbortEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task17XInteractionRetryEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task19XInteractionApproveEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task19XInteractionRequestEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task22XInteractionDisapproveEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star5beans16XPropertySetInfoEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star8registry12XRegistryKeyEEE
+__ZTIN4cppu15WeakImplHelper2IN3com3sun4star13configuration7backend13XLayerHandlerENS5_6XLayerEEE
+__ZTIN4cppu15WeakImplHelper2IN3com3sun4star3uno15XCurrentContextENS3_4lang10XUnoTunnelEEE
+__ZTIN4cppu15WeakImplHelper3IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_13configuration7backend14XUpdateHandlerEEE
+__ZTIN4cppu15WeakImplHelper3IN3com3sun4star9container6XChildENS4_6XNamedENS3_4lang12XServiceInfoEEE
+__ZTIN4cppu15WeakImplHelper4IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_2io15XActiveDataSinkENS3_13configuration7backend6XLayerEEE
+__ZTIN4cppu15WeakImplHelper4IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_2io15XActiveDataSinkENS3_13configuration7backend7XSchemaEEE
+__ZTIN4cppu15WeakImplHelper4IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_2io17XActiveDataSourceENS3_13configuration7backend13XLayerHandlerEEE
+__ZTIN4cppu15WeakImplHelper5IN3com3sun4star9container6XNamedENS3_4util16XChangesNotifierENS3_4lang10XComponentENS8_12XServiceInfoENS8_12XLocalizableEEE
+__ZTIN4cppu15WeakImplHelper6IN3com3sun4star9container6XChildENS4_6XNamedENS3_4lang10XComponentENS7_12XServiceInfoENS3_13configuration17XTemplateInstanceENS7_10XUnoTunnelEEE
+__ZTIN4cppu15WeakImplHelper6IN3com3sun4star9container6XNamedENS3_4util16XChangesNotifierENS3_4lang10XComponentENS8_12XServiceInfoENS8_12XLocalizableENS6_13XChangesBatchEEE
+__ZTIN4cppu18OPropertySetHelperE
+__ZTIN4cppu22ImplInheritanceHelper1IN9configmgr7localbe16LocalStratumBaseEN3com3sun4star13configuration7backend18XMultiLayerStratumEEE
+__ZTIN4cppu22ImplInheritanceHelper2IN9configmgr7localbe19LayerPropertyHelperEN3com3sun4star13configuration7backend15XUpdatableLayerENS6_4util12XTimeStampedEEE
+__ZTIN4cppu22ImplInheritanceHelper2IN9configmgr7localbe19LayerPropertyHelperEN3com3sun4star13configuration7backend6XLayerENS6_4util12XTimeStampedEEE
+__ZTIN4cppu22ImplInheritanceHelper3IN9configmgr7localbe19LayerPropertyHelperEN3com3sun4star13configuration7backend15XUpdatableLayerENS8_15XCompositeLayerENS6_4util12XTimeStampedEEE
+__ZTIN4cppu24WeakComponentImplHelper1IN3com3sun4star4lang12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper2IN3com3sun4star4lang20XMultiServiceFactoryENS4_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper3IN3com3sun4star13configuration7backend24XVersionedSchemaSupplierENS3_4lang15XInitializationENS7_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper3IN3com3sun4star3uno17XComponentContextENS4_15XCurrentContextENS3_4lang12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper3IN3com3sun4star4lang15XInitializationENS3_13configuration7backend16XBackendEntitiesENS4_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper5IN3com3sun4star13configuration7backend15XSchemaSupplierENS5_18XMultiLayerStratumENS5_16XBackendEntitiesENS3_4lang15XInitializationENS9_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper5IN3com3sun4star13configuration7backend8XBackendENS5_16XBackendEntitiesENS5_15XSchemaSupplierENS3_4lang15XInitializationENS9_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper7IN3com3sun4star13configuration7backend8XBackendENS5_16XBackendEntitiesENS5_24XVersionedSchemaSupplierENS5_23XBackendChangesNotifierENS5_23XBackendChangesListenerENS3_4lang15XInitializationEN!_7c1rO0
+__ZTIN4cppu27WeakComponentImplHelperBaseE
+__ZTIN9configmgr10BasicGroupE
+__ZTIN9configmgr10IInterfaceE
+__ZTIN9configmgr10NodeActionE
+__ZTIN9configmgr10RefcountedE
+__ZTIN9configmgr10RemoveNodeE
+__ZTIN9configmgr10SearchNodeE
+__ZTIN9configmgr11NoncopyableE
+__ZTIN9configmgr11TreeManagerE
+__ZTIN9configmgr11TreeUpdaterE
+__ZTIN9configmgr11ValueChangeE
+__ZTIN9configmgr12CollectNamesE
+__ZTIN9configmgr12ITreeManagerE
+__ZTIN9configmgr12ONameCreatorE
+__ZTIN9configmgr12OPathCreatorINS_13configuration12AbsolutePathEEE
+__ZTIN9configmgr12OPathCreatorINS_13configuration12RelativePathEEE
+__ZTIN9configmgr13BasicValueSetE
+__ZTIN9configmgr13configuration100_GLOBAL__N__ZN9configmgr13configuration12TemplateName18makeSimpleTypeNameERKN3com3sun4star3uno4TypeE12TypeDetectorE
+__ZTIN9configmgr13configuration11InvalidNameE
+__ZTIN9configmgr13configuration11NodeVisitorE
+__ZTIN9configmgr13configuration11SetNodeImplE
+__ZTIN9configmgr13configuration12TypeMismatchE
+__ZTIN9configmgr13configuration13GroupNodeImplE
+__ZTIN9configmgr13configuration14SetNodeVisitorE
+__ZTIN9configmgr13configuration15ValueMemberNode12DeferredImplE
+__ZTIN9configmgr13configuration18GroupMemberVisitorE
+__ZTIN9configmgr13configuration19ConstraintViolationE
+__ZTIN9configmgr13configuration19DeferredSetNodeImplE
+__ZTIN9configmgr13configuration19WrappedUnoExceptionE
+__ZTIN9configmgr13configuration21DeferredGroupNodeImplE
+__ZTIN9configmgr13configuration21TemplateProvider_ImplE
+__ZTIN9configmgr13configuration28SpecialTemplateProvider_ImplE
+__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv15CollectValueIDsE
+__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv17SetVisitorAdapterE
+__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv19GroupVisitorAdapterE
+__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv21FindNonDefaultElementE
+__ZTIN9configmgr13configuration88_GLOBAL__N__ZN9configmgr13configuration17GroupUpdateHelperC2ERKNS0_4TreeERKNS0_7NodeRefE13NodeDefaulterE
+__ZTIN9configmgr13configuration8NodeImplE
+__ZTIN9configmgr13configuration8TemplateE
+__ZTIN9configmgr13configuration9ExceptionE
+__ZTIN9configmgr13INodeListenerE
+__ZTIN9configmgr13OInnerSetInfoE
+__ZTIN9configmgr13OMergeChangesE
+__ZTIN9configmgr13OProviderImplE
+__ZTIN9configmgr13PWMutexHolderE
+__ZTIN9configmgr13SubtreeChangeE
+__ZTIN9configmgr14BasicSetAccessE
+__ZTIN9configmgr14OStripDefaultsE
+__ZTIN9configmgr15BasicSetElementE
+__ZTIN9configmgr15IConfigListenerE
+__ZTIN9configmgr15OInnerGroupInfoE
+__ZTIN9configmgr15ProviderFactoryE
+__ZTIN9configmgr15ProviderWrapperE
+__ZTIN9configmgr16BasicGroupAccessE
+__ZTIN9configmgr16BasicPropertySetE
+__ZTIN9configmgr16BasicRootElementE
+__ZTIN9configmgr16BootstrapContextE
+__ZTIN9configmgr16ChangeTreeActionE
+__ZTIN9configmgr16ComponentContextE
+__ZTIN9configmgr16IDefaultProviderE
+__ZTIN9configmgr16ITemplateManagerE
+__ZTIN9configmgr16NodeModificationE
+__ZTIN9configmgr16OMergeRemoveNodeE
+__ZTIN9configmgr16OPropagateLevelsE
+__ZTIN9configmgr16UnoContextTunnel6TunnelE
+__ZTIN9configmgr17AttributeListImplE
+__ZTIN9configmgr17BasicInnerElementE
+__ZTIN9configmgr17CacheClientAccessE
+__ZTIN9configmgr17ExtendedCacheDataE
+__ZTIN9configmgr17OInnerGroupUpdateE
+__ZTIN9configmgr17OMergeValueChangeE
+__ZTIN9configmgr17TemplateCacheDataE
+__ZTIN9configmgr18BasicUpdateElementE
+__ZTIN9configmgr18CacheLoadingAccessE
+__ZTIN9configmgr18DisposingForwarderE
+__ZTIN9configmgr18IConfigBroadcasterE
+__ZTIN9configmgr18IConfigTreeManagerE
+__ZTIN9configmgr18OSetElementSetInfoE
+__ZTIN9configmgr19OInnerTreeSetUpdateE
+__ZTIN9configmgr19ORootElementSetInfoE
+__ZTIN9configmgr20OCacheWriteScheduler5TimerE
+__ZTIN9configmgr20OInnerValueSetUpdateE
+__ZTIN9configmgr20OMergeTreeChangeListE
+__ZTIN9configmgr20OSetElementGroupInfoE
+__ZTIN9configmgr20ServiceComponentImplE
+__ZTIN9configmgr21ORootElementGroupInfoE
+__ZTIN9configmgr21OTreeDisposeScheduler5TimerE
+__ZTIN9configmgr21SubtreeChangeReferrerE
+__ZTIN9configmgr22ChangeTreeModificationE
+__ZTIN9configmgr22IConfigDefaultProviderE
+__ZTIN9configmgr22IConfigTemplateManagerE
+__ZTIN9configmgr22OConfigurationProviderE
+__ZTIN9configmgr22OConfigurationRegistryE
+__ZTIN9configmgr22OSetElementGroupUpdateE
+__ZTIN9configmgr23ConfigChangeBroadcasterE
+__ZTIN9configmgr23IDefaultableTreeManagerE
+__ZTIN9configmgr23ORootElementGroupUpdateE
+__ZTIN9configmgr24OSetElementTreeSetUpdateE
+__ZTIN9configmgr25OConfigurationRegistryKeyE
+__ZTIN9configmgr25ORootElementTreeSetUpdateE
+__ZTIN9configmgr25OSetElementValueSetUpdateE
+__ZTIN9configmgr26OProviderDisposingListenerE
+__ZTIN9configmgr26ORootElementValueSetUpdateE
+__ZTIN9configmgr3xml11BasicParserE
+__ZTIN9configmgr3xml11LayerWriterE
+__ZTIN9configmgr3xml13ElementParser12BadValueTypeE
+__ZTIN9configmgr3xml13ParserServiceIN3com3sun4star13configuration7backend6XLayerEEE
+__ZTIN9configmgr3xml13ParserServiceIN3com3sun4star13configuration7backend7XSchemaEEE
+__ZTIN9configmgr3xml13WriterServiceIN3com3sun4star13configuration7backend13XLayerHandlerEEE
+__ZTIN9configmgr3xml18LayerParserServiceE
+__ZTIN9configmgr3xml19SchemaParserServiceE
+__ZTIN9configmgr4data10SetVisitorE
+__ZTIN9configmgr4data11NodeVisitorE
+__ZTIN9configmgr4data11TreeSegment4ImplE
+__ZTIN9configmgr4data15TreeNodeBuilder12LinkSetNodesE
+__ZTIN9configmgr4data20BasicDataTreeBuilderE
+__ZTIN9configmgr4data21ConvertingNodeBuilderE
+__ZTIN9configmgr4data21DataTreeDefaultMergerE
+__ZTIN9configmgr4data22CopyingDataTreeBuilder18ElementListBuilderE
+__ZTIN9configmgr4data22CopyingDataTreeBuilderE
+__ZTIN9configmgr4data24ConvertingSubnodeBuilderE
+__ZTIN9configmgr4data25ConvertingDataTreeBuilder18ElementListBuilderE
+__ZTIN9configmgr4data25ConvertingDataTreeBuilderE
+__ZTIN9configmgr4view12ViewStrategyE
+__ZTIN9configmgr4view18DirectViewStrategyE
+__ZTIN9configmgr4view20ReadOnlyViewStrategyE
+__ZTIN9configmgr5INodeE
+__ZTIN9configmgr6ChangeE
+__ZTIN9configmgr6memory11HeapManagerE
+__ZTIN9configmgr6memory14SimpleHeapLockE
+__ZTIN9configmgr6memory21SimpleHeapManagerBaseE
+__ZTIN9configmgr6memory25SimpleCheckingHeapManagerE
+__ZTIN9configmgr6memory8DataLockE
+__ZTIN9configmgr7AddNodeE
+__ZTIN9configmgr7backend10NodeUpdateE
+__ZTIN9configmgr7backend11NamedUpdateE
+__ZTIN9configmgr7backend11NodeReplaceE
+__ZTIN9configmgr7backend11PropertyAddE
+__ZTIN9configmgr7backend12ResultHolderINS0_12NodeInstanceEE10RCInstanceE
+__ZTIN9configmgr7backend12ResultHolderINS0_16TemplateInstanceEE10RCInstanceE
+__ZTIN9configmgr7backend12ResultHolderINS0_17ComponentInstanceEE10RCInstanceE
+__ZTIN9configmgr7backend13BackendAccessE
+__ZTIN9configmgr7backend13ElementUpdateE
+__ZTIN9configmgr7backend13PropertyResetE
+__ZTIN9configmgr7backend13SchemaBuilderE
+__ZTIN9configmgr7backend13UpdateServiceE
+__ZTIN9configmgr7backend14PropertyUpdateE
+__ZTIN9configmgr7backend15CacheControllerE
+__ZTIN9configmgr7backend16NodeModificationE
+__ZTIN9configmgr7backend17BasicUpdateMergerE
+__ZTIN9configmgr7backend17BinaryReader_ImplE
+__ZTIN9configmgr7backend17INodeDataListenerE
+__ZTIN9configmgr7backend17INodeDataProviderE
+__ZTIN9configmgr7backend17LayerMergeHandlerE
+__ZTIN9configmgr7backend17LayerUpdateMergerE
+__ZTIN9configmgr7backend18BasicImportHandlerE
+__ZTIN9configmgr7backend18BinaryWriteHandlerE
+__ZTIN9configmgr7backend18ImportMergeHandlerE
+__ZTIN9configmgr7backend18LayerUpdateHandlerE
+__ZTIN9configmgr7backend19ICachedDataListenerE
+__ZTIN9configmgr7backend19ICachedDataNotifierE
+__ZTIN9configmgr7backend19ICachedDataProviderE
+__ZTIN9configmgr7backend19IDirectDataProviderE
+__ZTIN9configmgr7backend19IMergedDataProviderE
+__ZTIN9configmgr7backend19INodeUpdateProviderE
+__ZTIN9configmgr7backend19LayerDefaultRemoverE
+__ZTIN9configmgr7backend19MultiStratumBackendE
+__ZTIN9configmgr7backend20IDefaultDataProviderE
+__ZTIN9configmgr7backend20SingleBackendAdapterE
+__ZTIN9configmgr7backend21BackendChangeNotifierE
+__ZTIN9configmgr7backend21IDataProviderMetaDataE
+__ZTIN9configmgr7backend21ITemplateDataProviderE
+__ZTIN9configmgr7backend21OInvalidateTreeThreadE
+__ZTIN9configmgr7backend22CacheChangeMulticasterE
+__ZTIN9configmgr7backend22IComponentDataProviderE
+__ZTIN9configmgr7backend8NodeDropE
+__ZTIN9configmgr7localbe16LocalStratumBaseE
+__ZTIN9configmgr7localbe17LocalMultiStratumE
+__ZTIN9configmgr7localbe18FlatLocalFileLayerE
+__ZTIN9configmgr7localbe18LocalSingleBackendE
+__ZTIN9configmgr7localbe19BasicLocalFileLayerE
+__ZTIN9configmgr7localbe19LayerPropertyHelperE
+__ZTIN9configmgr7localbe19LocalSchemaSupplierE
+__ZTIN9configmgr7localbe20SimpleLocalFileLayerE
+__ZTIN9configmgr7localbe23CompositeLocalFileLayerE
+__ZTIN9configmgr7localbe23LocalStratumMutexHolderE
+__ZTIN9configmgr7localbe27FullCompositeLocalFileLayerE
+__ZTIN9configmgr7localbe28BasicCompositeLocalFileLayerE
+__ZTIN9configmgr7SubtreeE
+__ZTIN9configmgr8BasicSetE
+__ZTIN9configmgr8ISubtreeE
+__ZTIN9configmgr8OOptionsE
+__ZTIN9configmgr9apihelper15BroadcasterBaseE
+__ZTIN9configmgr9apihelper17PropertySetHelperE
+__ZTIN9configmgr9apihelper18InteractionRequestE
+__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task17XInteractionAbortEEE
+__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task17XInteractionRetryEEE
+__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task19XInteractionApproveEEE
+__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task22XInteractionDisapproveEEE
+__ZTIN9configmgr9apihelper24SimpleInteractionRequestE
+__ZTIN9configmgr9apihelper31ConfigurationInteractionHandler7ContextE
+__ZTIN9configmgr9CacheDataE
+__ZTIN9configmgr9configapi10NodeAccessE
+__ZTIN9configmgr9configapi10SetElementE
+__ZTIN9configmgr9configapi11ApiTreeImpl16ComponentAdapterE
+__ZTIN9configmgr9configapi11Broadcaster4ImplE
+__ZTIN9configmgr9configapi11NodeElementE
+__ZTIN9configmgr9configapi11OSetElementINS0_15NodeGroupAccessEEE
+__ZTIN9configmgr9configapi11OSetElementINS0_17NodeSetInfoAccessEEE
+__ZTIN9configmgr9configapi11OSetElementINS0_17NodeTreeSetAccessEEE
+__ZTIN9configmgr9configapi11OSetElementINS0_18NodeValueSetAccessEEE
+__ZTIN9configmgr9configapi11OSetElementINS0_19NodeGroupInfoAccessEEE
+__ZTIN9configmgr9configapi11RootElementE
+__ZTIN9configmgr9configapi11TreeElementE
+__ZTIN9configmgr9configapi12InnerElementE
+__ZTIN9configmgr9configapi13NodeSetAccessE
+__ZTIN9configmgr9configapi13OInnerElementINS0_15NodeGroupAccessEEE
+__ZTIN9configmgr9configapi13OInnerElementINS0_17NodeSetInfoAccessEEE
+__ZTIN9configmgr9configapi13OInnerElementINS0_17NodeTreeSetAccessEEE
+__ZTIN9configmgr9configapi13OInnerElementINS0_18NodeValueSetAccessEEE
+__ZTIN9configmgr9configapi13OInnerElementINS0_19NodeGroupInfoAccessEEE
+__ZTIN9configmgr9configapi14ObjectRegistryE
+__ZTIN9configmgr9configapi15ApiRootTreeImpl12NodeListenerE
+__ZTIN9configmgr9configapi15NodeGroupAccessE
+__ZTIN9configmgr9configapi16OReadRootElementINS0_17NodeSetInfoAccessEEE
+__ZTIN9configmgr9configapi16OReadRootElementINS0_19NodeGroupInfoAccessEEE
+__ZTIN9configmgr9configapi17CollectPropertiesE
+__ZTIN9configmgr9configapi17NodeSetInfoAccessE
+__ZTIN9configmgr9configapi17NodeTreeSetAccessE
+__ZTIN9configmgr9configapi17UpdateRootElementE
+__ZTIN9configmgr9configapi18NodeValueSetAccessE
+__ZTIN9configmgr9configapi18OUpdateRootElementINS0_15NodeGroupAccessEEE
+__ZTIN9configmgr9configapi18OUpdateRootElementINS0_17NodeTreeSetAccessEEE
+__ZTIN9configmgr9configapi18OUpdateRootElementINS0_18NodeValueSetAccessEEE
+__ZTIN9configmgr9configapi19NodeGroupInfoAccessE
+__ZTIN9configmgr9configapi19NodePropertySetInfoE
+__ZTIN9configmgr9configapi19UpdateObjectFactoryE
+__ZTIN9configmgr9configapi21ReadOnlyObjectFactoryE
+__ZTIN9configmgr9configapi7FactoryE
+__ZTIN9configmgr9configapi8internal15SearchExactNameE
+__ZTIN9configmgr9OProviderE
+__ZTIN9configmgr9ValueNodeE
+__ZTIN9salhelper21SimpleReferenceObjectE
+;__ZTISt9bad_alloc
+;__ZTISt9exception
+
+
+IMPORTS
+__ZTIN10comphelper18OPropertyContainerE=configmg.__ZTIN10comphelper18OPropertyContainerE
+__ZTIN10comphelper24OPropertyContainerHelperE=configmg.__ZTIN10comphelper24OPropertyContainerHelperE
+__ZTIN10comphelper25OPropertyArrayUsageHelperIN9configmgr22OConfigurationProviderEEE=configmg.__ZTIN10comphelper25OPropertyArrayUsageHelperIN9configmgr22OConfigurationProviderEEE
+__ZTIN3com3sun4star13configuration17XTemplateInstanceE=configmg.__ZTIN3com3sun4star13configuration17XTemplateInstanceE
+__ZTIN3com3sun4star13configuration18XTemplateContainerE=configmg.__ZTIN3com3sun4star13configuration18XTemplateContainerE
+__ZTIN3com3sun4star13configuration29InvalidBootstrapFileExceptionE=configmg.__ZTIN3com3sun4star13configuration29InvalidBootstrapFileExceptionE
+__ZTIN3com3sun4star13configuration29MissingBootstrapFileExceptionE=configmg.__ZTIN3com3sun4star13configuration29MissingBootstrapFileExceptionE
+__ZTIN3com3sun4star13configuration31InstallationIncompleteExceptionE=configmg.__ZTIN3com3sun4star13configuration31InstallationIncompleteExceptionE
+__ZTIN3com3sun4star13configuration32CannotLoadConfigurationExceptionE=configmg.__ZTIN3com3sun4star13configuration32CannotLoadConfigurationExceptionE
+__ZTIN3com3sun4star13configuration7backend13XLayerHandlerE=configmg.__ZTIN3com3sun4star13configuration7backend13XLayerHandlerE
+__ZTIN3com3sun4star13configuration7backend14XLayerImporterE=configmg.__ZTIN3com3sun4star13configuration7backend14XLayerImporterE
+__ZTIN3com3sun4star13configuration7backend14XSchemaHandlerE=configmg.__ZTIN3com3sun4star13configuration7backend14XSchemaHandlerE
+__ZTIN3com3sun4star13configuration7backend14XUpdateHandlerE=configmg.__ZTIN3com3sun4star13configuration7backend14XUpdateHandlerE
+__ZTIN3com3sun4star13configuration7backend15XCompositeLayerE=configmg.__ZTIN3com3sun4star13configuration7backend15XCompositeLayerE
+__ZTIN3com3sun4star13configuration7backend15XSchemaSupplierE=configmg.__ZTIN3com3sun4star13configuration7backend15XSchemaSupplierE
+__ZTIN3com3sun4star13configuration7backend15XUpdatableLayerE=configmg.__ZTIN3com3sun4star13configuration7backend15XUpdatableLayerE
+__ZTIN3com3sun4star13configuration7backend16XBackendEntitiesE=configmg.__ZTIN3com3sun4star13configuration7backend16XBackendEntitiesE
+__ZTIN3com3sun4star13configuration7backend18XMultiLayerStratumE=configmg.__ZTIN3com3sun4star13configuration7backend18XMultiLayerStratumE
+__ZTIN3com3sun4star13configuration7backend19XSingleLayerStratumE=configmg.__ZTIN3com3sun4star13configuration7backend19XSingleLayerStratumE
+__ZTIN3com3sun4star13configuration7backend21BackendSetupExceptionE=configmg.__ZTIN3com3sun4star13configuration7backend21BackendSetupExceptionE
+__ZTIN3com3sun4star13configuration7backend22BackendAccessExceptionE=configmg.__ZTIN3com3sun4star13configuration7backend22BackendAccessExceptionE
+__ZTIN3com3sun4star13configuration7backend22CannotConnectExceptionE=configmg.__ZTIN3com3sun4star13configuration7backend22CannotConnectExceptionE
+__ZTIN3com3sun4star13configuration7backend22MalformedDataExceptionE=configmg.__ZTIN3com3sun4star13configuration7backend22MalformedDataExceptionE
+__ZTIN3com3sun4star13configuration7backend23ConnectionLostExceptionE=configmg.__ZTIN3com3sun4star13configuration7backend23ConnectionLostExceptionE
+__ZTIN3com3sun4star13configuration7backend23XBackendChangesListenerE=configmg.__ZTIN3com3sun4star13configuration7backend23XBackendChangesListenerE
+__ZTIN3com3sun4star13configuration7backend23XBackendChangesNotifierE=configmg.__ZTIN3com3sun4star13configuration7backend23XBackendChangesNotifierE
+__ZTIN3com3sun4star13configuration7backend24StratumCreationExceptionE=configmg.__ZTIN3com3sun4star13configuration7backend24StratumCreationExceptionE
+__ZTIN3com3sun4star13configuration7backend24XVersionedSchemaSupplierE=configmg.__ZTIN3com3sun4star13configuration7backend24XVersionedSchemaSupplierE
+__ZTIN3com3sun4star13configuration7backend29AuthenticationFailedExceptionE=configmg.__ZTIN3com3sun4star13configuration7backend29AuthenticationFailedExceptionE
+__ZTIN3com3sun4star13configuration7backend33InsufficientAccessRightsExceptionE=configmg.__ZTIN3com3sun4star13configuration7backend33InsufficientAccessRightsExceptionE
+__ZTIN3com3sun4star13configuration7backend39InvalidAuthenticationMechanismExceptionE=configmg.__ZTIN3com3sun4star13configuration7backend39InvalidAuthenticationMechanismExceptionE
+__ZTIN3com3sun4star13configuration7backend6XLayerE=configmg.__ZTIN3com3sun4star13configuration7backend6XLayerE
+__ZTIN3com3sun4star13configuration7backend7XSchemaE=configmg.__ZTIN3com3sun4star13configuration7backend7XSchemaE
+__ZTIN3com3sun4star13configuration7backend8XBackendE=configmg.__ZTIN3com3sun4star13configuration7backend8XBackendE
+__ZTIN3com3sun4star2io11IOExceptionE=configmg.__ZTIN3com3sun4star2io11IOExceptionE
+__ZTIN3com3sun4star2io12XInputStreamE=configmg.__ZTIN3com3sun4star2io12XInputStreamE
+__ZTIN3com3sun4star2io13XOutputStreamE=configmg.__ZTIN3com3sun4star2io13XOutputStreamE
+__ZTIN3com3sun4star2io15XActiveDataSinkE=configmg.__ZTIN3com3sun4star2io15XActiveDataSinkE
+__ZTIN3com3sun4star2io16XDataInputStreamE=configmg.__ZTIN3com3sun4star2io16XDataInputStreamE
+__ZTIN3com3sun4star2io17XActiveDataSourceE=configmg.__ZTIN3com3sun4star2io17XActiveDataSourceE
+__ZTIN3com3sun4star2io20WrongFormatExceptionE=configmg.__ZTIN3com3sun4star2io20WrongFormatExceptionE
+__ZTIN3com3sun4star2io21NotConnectedExceptionE=configmg.__ZTIN3com3sun4star2io21NotConnectedExceptionE
+__ZTIN3com3sun4star2io22UnexpectedEOFExceptionE=configmg.__ZTIN3com3sun4star2io22UnexpectedEOFExceptionE
+__ZTIN3com3sun4star2io27BufferSizeExceededExceptionE=configmg.__ZTIN3com3sun4star2io27BufferSizeExceededExceptionE
+__ZTIN3com3sun4star3uno10XInterfaceE=configmg.__ZTIN3com3sun4star3uno10XInterfaceE
+__ZTIN3com3sun4star3uno15XCurrentContextE=configmg.__ZTIN3com3sun4star3uno15XCurrentContextE
+;__ZTIN3com3sun4star3uno16RuntimeExceptionE=configmg.__ZTIN3com3sun4star3uno16RuntimeExceptionE
+__ZTIN3com3sun4star3uno17XComponentContextE=configmg.__ZTIN3com3sun4star3uno17XComponentContextE
+__ZTIN3com3sun4star3uno5XWeakE=configmg.__ZTIN3com3sun4star3uno5XWeakE
+;__ZTIN3com3sun4star3uno9ExceptionE=configmg.__ZTIN3com3sun4star3uno9ExceptionE
+__ZTIN3com3sun4star3xml3sax12SAXExceptionE=configmg.__ZTIN3com3sun4star3xml3sax12SAXExceptionE
+__ZTIN3com3sun4star3xml3sax14XAttributeListE=configmg.__ZTIN3com3sun4star3xml3sax14XAttributeListE
+__ZTIN3com3sun4star3xml3sax16XDocumentHandlerE=configmg.__ZTIN3com3sun4star3xml3sax16XDocumentHandlerE
+__ZTIN3com3sun4star4lang10XComponentE=configmg.__ZTIN3com3sun4star4lang10XComponentE
+__ZTIN3com3sun4star4lang10XUnoTunnelE=configmg.__ZTIN3com3sun4star4lang10XUnoTunnelE
+__ZTIN3com3sun4star4lang12XLocalizableE=configmg.__ZTIN3com3sun4star4lang12XLocalizableE
+__ZTIN3com3sun4star4lang12XServiceInfoE=configmg.__ZTIN3com3sun4star4lang12XServiceInfoE
+__ZTIN3com3sun4star4lang13XTypeProviderE=configmg.__ZTIN3com3sun4star4lang13XTypeProviderE
+__ZTIN3com3sun4star4lang14XEventListenerE=configmg.__ZTIN3com3sun4star4lang14XEventListenerE
+__ZTIN3com3sun4star4lang15XInitializationE=configmg.__ZTIN3com3sun4star4lang15XInitializationE
+__ZTIN3com3sun4star4lang17DisposedExceptionE=configmg.__ZTIN3com3sun4star4lang17DisposedExceptionE
+__ZTIN3com3sun4star4lang18NoSupportExceptionE=configmg.__ZTIN3com3sun4star4lang18NoSupportExceptionE
+__ZTIN3com3sun4star4lang20NullPointerExceptionE=configmg.__ZTIN3com3sun4star4lang20NullPointerExceptionE
+__ZTIN3com3sun4star4lang20XMultiServiceFactoryE=configmg.__ZTIN3com3sun4star4lang20XMultiServiceFactoryE
+__ZTIN3com3sun4star4lang21XSingleServiceFactoryE=configmg.__ZTIN3com3sun4star4lang21XSingleServiceFactoryE
+__ZTIN3com3sun4star4lang22IllegalAccessExceptionE=configmg.__ZTIN3com3sun4star4lang22IllegalAccessExceptionE
+__ZTIN3com3sun4star4lang22WrappedTargetExceptionE=configmg.__ZTIN3com3sun4star4lang22WrappedTargetExceptionE
+__ZTIN3com3sun4star4lang23XSingleComponentFactoryE=configmg.__ZTIN3com3sun4star4lang23XSingleComponentFactoryE
+__ZTIN3com3sun4star4lang24IllegalArgumentExceptionE=configmg.__ZTIN3com3sun4star4lang24IllegalArgumentExceptionE
+__ZTIN3com3sun4star4lang29ServiceNotRegisteredExceptionE=configmg.__ZTIN3com3sun4star4lang29ServiceNotRegisteredExceptionE
+__ZTIN3com3sun4star4lang29WrappedTargetRuntimeExceptionE=configmg.__ZTIN3com3sun4star4lang29WrappedTargetRuntimeExceptionE
+__ZTIN3com3sun4star4task17XInteractionAbortE=configmg.__ZTIN3com3sun4star4task17XInteractionAbortE
+__ZTIN3com3sun4star4task17XInteractionRetryE=configmg.__ZTIN3com3sun4star4task17XInteractionRetryE
+__ZTIN3com3sun4star4task19XInteractionApproveE=configmg.__ZTIN3com3sun4star4task19XInteractionApproveE
+__ZTIN3com3sun4star4task19XInteractionRequestE=configmg.__ZTIN3com3sun4star4task19XInteractionRequestE
+__ZTIN3com3sun4star4task22XInteractionDisapproveE=configmg.__ZTIN3com3sun4star4task22XInteractionDisapproveE
+__ZTIN3com3sun4star4task24XInteractionContinuationE=configmg.__ZTIN3com3sun4star4task24XInteractionContinuationE
+__ZTIN3com3sun4star4task4XJobE=configmg.__ZTIN3com3sun4star4task4XJobE
+__ZTIN3com3sun4star4util10XFlushableE=configmg.__ZTIN3com3sun4star4util10XFlushableE
+__ZTIN3com3sun4star4util12XRefreshableE=configmg.__ZTIN3com3sun4star4util12XRefreshableE
+__ZTIN3com3sun4star4util12XTimeStampedE=configmg.__ZTIN3com3sun4star4util12XTimeStampedE
+__ZTIN3com3sun4star4util13XChangesBatchE=configmg.__ZTIN3com3sun4star4util13XChangesBatchE
+__ZTIN3com3sun4star4util13XStringEscapeE=configmg.__ZTIN3com3sun4star4util13XStringEscapeE
+__ZTIN3com3sun4star4util16XChangesNotifierE=configmg.__ZTIN3com3sun4star4util16XChangesNotifierE
+__ZTIN3com3sun4star5beans10XExactNameE=configmg.__ZTIN3com3sun4star5beans10XExactNameE
+__ZTIN3com3sun4star5beans12XPropertySetE=configmg.__ZTIN3com3sun4star5beans12XPropertySetE
+__ZTIN3com3sun4star5beans14XPropertyStateE=configmg.__ZTIN3com3sun4star5beans14XPropertyStateE
+__ZTIN3com3sun4star5beans16XFastPropertySetE=configmg.__ZTIN3com3sun4star5beans16XFastPropertySetE
+__ZTIN3com3sun4star5beans16XPropertySetInfoE=configmg.__ZTIN3com3sun4star5beans16XPropertySetInfoE
+__ZTIN3com3sun4star5beans17XMultiPropertySetE=configmg.__ZTIN3com3sun4star5beans17XMultiPropertySetE
+__ZTIN3com3sun4star5beans18XPropertyWithStateE=configmg.__ZTIN3com3sun4star5beans18XPropertyWithStateE
+__ZTIN3com3sun4star5beans20XMultiPropertyStatesE=configmg.__ZTIN3com3sun4star5beans20XMultiPropertyStatesE
+__ZTIN3com3sun4star5beans21PropertyVetoExceptionE=configmg.__ZTIN3com3sun4star5beans21PropertyVetoExceptionE
+__ZTIN3com3sun4star5beans24UnknownPropertyExceptionE=configmg.__ZTIN3com3sun4star5beans24UnknownPropertyExceptionE
+__ZTIN3com3sun4star5beans24XHierarchicalPropertySetE=configmg.__ZTIN3com3sun4star5beans24XHierarchicalPropertySetE
+__ZTIN3com3sun4star5beans25XPropertiesChangeListenerE=configmg.__ZTIN3com3sun4star5beans25XPropertiesChangeListenerE
+__ZTIN3com3sun4star5beans29XMultiHierarchicalPropertySetE=configmg.__ZTIN3com3sun4star5beans29XMultiHierarchicalPropertySetE
+__ZTIN3com3sun4star5beans9XPropertyE=configmg.__ZTIN3com3sun4star5beans9XPropertyE
+__ZTIN3com3sun4star6script22CannotConvertExceptionE=configmg.__ZTIN3com3sun4star6script22CannotConvertExceptionE
+__ZTIN3com3sun4star8registry12XRegistryKeyE=configmg.__ZTIN3com3sun4star8registry12XRegistryKeyE
+__ZTIN3com3sun4star8registry15XSimpleRegistryE=configmg.__ZTIN3com3sun4star8registry15XSimpleRegistryE
+__ZTIN3com3sun4star8registry21InvalidValueExceptionE=configmg.__ZTIN3com3sun4star8registry21InvalidValueExceptionE
+__ZTIN3com3sun4star8registry22MergeConflictExceptionE=configmg.__ZTIN3com3sun4star8registry22MergeConflictExceptionE
+__ZTIN3com3sun4star8registry24InvalidRegistryExceptionE=configmg.__ZTIN3com3sun4star8registry24InvalidRegistryExceptionE
+__ZTIN3com3sun4star9container10XContainerE=configmg.__ZTIN3com3sun4star9container10XContainerE
+__ZTIN3com3sun4star9container11XNameAccessE=configmg.__ZTIN3com3sun4star9container11XNameAccessE
+__ZTIN3com3sun4star9container12XNameReplaceE=configmg.__ZTIN3com3sun4star9container12XNameReplaceE
+__ZTIN3com3sun4star9container14XElementAccessE=configmg.__ZTIN3com3sun4star9container14XElementAccessE
+__ZTIN3com3sun4star9container14XNameContainerE=configmg.__ZTIN3com3sun4star9container14XNameContainerE
+__ZTIN3com3sun4star9container17XHierarchicalNameE=configmg.__ZTIN3com3sun4star9container17XHierarchicalNameE
+__ZTIN3com3sun4star9container21ElementExistExceptionE=configmg.__ZTIN3com3sun4star9container21ElementExistExceptionE
+__ZTIN3com3sun4star9container22NoSuchElementExceptionE=configmg.__ZTIN3com3sun4star9container22NoSuchElementExceptionE
+__ZTIN3com3sun4star9container23XHierarchicalNameAccessE=configmg.__ZTIN3com3sun4star9container23XHierarchicalNameAccessE
+__ZTIN3com3sun4star9container6XChildE=configmg.__ZTIN3com3sun4star9container6XChildE
+__ZTIN3com3sun4star9container6XNamedE=configmg.__ZTIN3com3sun4star9container6XNamedE
+__ZTIN3vos10IReferenceE=configmg.__ZTIN3vos10IReferenceE
+__ZTIN3vos10OReferenceE=configmg.__ZTIN3vos10OReferenceE
+__ZTIN3vos6OTimerE=configmg.__ZTIN3vos6OTimerE
+__ZTIN3vos7OObjectE=configmg.__ZTIN3vos7OObjectE
+__ZTIN3vos7OThreadE=configmg.__ZTIN3vos7OThreadE
+__ZTIN3vos9IRunnableE=configmg.__ZTIN3vos9IRunnableE
+__ZTIN4cppu11ImplHelper2IN3com3sun4star8registry15XSimpleRegistryENS3_4util10XFlushableEEE=configmg.__ZTIN4cppu11ImplHelper2IN3com3sun4star8registry15XSimpleRegistryENS3_4util10XFlushableEEE
+__ZTIN4cppu11ImplHelper4IN3com3sun4star4lang20XMultiServiceFactoryENS4_12XLocalizableENS3_4util12XRefreshableENS7_10XFlushableEEE=configmg.__ZTIN4cppu11ImplHelper4IN3com3sun4star4lang20XMultiServiceFactoryENS4_12XLocalizableENS3_4util12XRefreshableENS7_10XFlushableEEE
+__ZTIN4cppu11ImplHelper6IN3com3sun4star5beans12XPropertySetENS4_17XMultiPropertySetENS4_24XHierarchicalPropertySetENS4_29XMultiHierarchicalPropertySetENS4_14XPropertyStateENS4_20XMultiPropertyStatesEEE=configmg.__ZTIN4cppu11ImplHelper6IN3com3sun4star5beans12XPropertySetENS4_17XMultiPropertySetENS4_24XHierarchicalPropertySetENS4_29XMultiHierarchicalPropertySetENS4_14XPropertyStateENS4_20XMultiPropertyStatesEEE
+__ZTIN4cppu11ImplHelper6IN3com3sun4star9container11XNameAccessENS4_17XHierarchicalNameENS4_23XHierarchicalNameAccessENS4_10XContainerENS3_5beans10XExactNameENS9_9XPropertyEEE=configmg.__ZTIN4cppu11ImplHelper6IN3com3sun4star9container11XNameAccessENS4_17XHierarchicalNameENS4_23XHierarchicalNameAccessENS4_10XContainerENS3_5beans10XExactNameENS9_9XPropertyEEE
+__ZTIN4cppu11ImplHelper9IN3com3sun4star9container11XNameAccessENS4_17XHierarchicalNameENS4_23XHierarchicalNameAccessENS4_10XContainerENS3_5beans10XExactNameENS9_9XPropertyENS9_16XPropertySetInfoENS3_13configuration18XTemplateCo!_yPkJc2=configmg.__ZTIN4cppu11ImplHelper9IN3com3sun4star9container11XNameAccessENS4_17XHierarchicalNameENS4_23XHierarchicalNameAccessENS4_10XContainerENS3_5beans10XExactNameENS9_9XPropertyENS9_16XPropertySetInfoENS3_13configuration18XTemplateCo!_yPkJc2
+__ZTIN4cppu11OWeakObjectE=configmg.__ZTIN4cppu11OWeakObjectE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend13XLayerHandlerEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend13XLayerHandlerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend14XSchemaHandlerEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend14XSchemaHandlerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend15XCompositeLayerEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend15XCompositeLayerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend23XBackendChangesListenerEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend23XBackendChangesListenerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend6XLayerEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star13configuration7backend6XLayerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star2io12XInputStreamEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star2io12XInputStreamEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star2io13XOutputStreamEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star2io13XOutputStreamEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star2io16XDataInputStreamEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star2io16XDataInputStreamEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star3uno15XCurrentContextEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star3uno15XCurrentContextEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star3xml3sax14XAttributeListEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star3xml3sax14XAttributeListEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star3xml3sax16XDocumentHandlerEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star3xml3sax16XDocumentHandlerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4lang14XEventListenerEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4lang14XEventListenerEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4lang23XSingleComponentFactoryEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4lang23XSingleComponentFactoryEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task17XInteractionAbortEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task17XInteractionAbortEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task17XInteractionRetryEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task17XInteractionRetryEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task19XInteractionApproveEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task19XInteractionApproveEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task19XInteractionRequestEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task19XInteractionRequestEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task22XInteractionDisapproveEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star4task22XInteractionDisapproveEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star5beans16XPropertySetInfoEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star5beans16XPropertySetInfoEEE
+__ZTIN4cppu15WeakImplHelper1IN3com3sun4star8registry12XRegistryKeyEEE=configmg.__ZTIN4cppu15WeakImplHelper1IN3com3sun4star8registry12XRegistryKeyEEE
+__ZTIN4cppu15WeakImplHelper2IN3com3sun4star13configuration7backend13XLayerHandlerENS5_6XLayerEEE=configmg.__ZTIN4cppu15WeakImplHelper2IN3com3sun4star13configuration7backend13XLayerHandlerENS5_6XLayerEEE
+__ZTIN4cppu15WeakImplHelper2IN3com3sun4star3uno15XCurrentContextENS3_4lang10XUnoTunnelEEE=configmg.__ZTIN4cppu15WeakImplHelper2IN3com3sun4star3uno15XCurrentContextENS3_4lang10XUnoTunnelEEE
+__ZTIN4cppu15WeakImplHelper2IN3com3sun4star4task4XJobENS3_4lang12XServiceInfoEEE=configmg.__ZTIN4cppu15WeakImplHelper2IN3com3sun4star4task4XJobENS3_4lang12XServiceInfoEEE
+__ZTIN4cppu15WeakImplHelper3IN3com3sun4star13configuration7backend14XLayerImporterENS3_4lang15XInitializationENS7_12XServiceInfoEEE=configmg.__ZTIN4cppu15WeakImplHelper3IN3com3sun4star13configuration7backend14XLayerImporterENS3_4lang15XInitializationENS7_12XServiceInfoEEE
+__ZTIN4cppu15WeakImplHelper3IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_13configuration7backend14XUpdateHandlerEEE=configmg.__ZTIN4cppu15WeakImplHelper3IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_13configuration7backend14XUpdateHandlerEEE
+__ZTIN4cppu15WeakImplHelper3IN3com3sun4star9container6XChildENS4_6XNamedENS3_4lang12XServiceInfoEEE=configmg.__ZTIN4cppu15WeakImplHelper3IN3com3sun4star9container6XChildENS4_6XNamedENS3_4lang12XServiceInfoEEE
+__ZTIN4cppu15WeakImplHelper4IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_2io15XActiveDataSinkENS3_13configuration7backend6XLayerEEE=configmg.__ZTIN4cppu15WeakImplHelper4IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_2io15XActiveDataSinkENS3_13configuration7backend6XLayerEEE
+__ZTIN4cppu15WeakImplHelper4IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_2io15XActiveDataSinkENS3_13configuration7backend7XSchemaEEE=configmg.__ZTIN4cppu15WeakImplHelper4IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_2io15XActiveDataSinkENS3_13configuration7backend7XSchemaEEE
+__ZTIN4cppu15WeakImplHelper4IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_2io17XActiveDataSourceENS3_13configuration7backend13XLayerHandlerEEE=configmg.__ZTIN4cppu15WeakImplHelper4IN3com3sun4star4lang15XInitializationENS4_12XServiceInfoENS3_2io17XActiveDataSourceENS3_13configuration7backend13XLayerHandlerEEE
+__ZTIN4cppu15WeakImplHelper5IN3com3sun4star9container6XNamedENS3_4util16XChangesNotifierENS3_4lang10XComponentENS8_12XServiceInfoENS8_12XLocalizableEEE=configmg.__ZTIN4cppu15WeakImplHelper5IN3com3sun4star9container6XNamedENS3_4util16XChangesNotifierENS3_4lang10XComponentENS8_12XServiceInfoENS8_12XLocalizableEEE
+__ZTIN4cppu15WeakImplHelper6IN3com3sun4star9container6XChildENS4_6XNamedENS3_4lang10XComponentENS7_12XServiceInfoENS3_13configuration17XTemplateInstanceENS7_10XUnoTunnelEEE=configmg.__ZTIN4cppu15WeakImplHelper6IN3com3sun4star9container6XChildENS4_6XNamedENS3_4lang10XComponentENS7_12XServiceInfoENS3_13configuration17XTemplateInstanceENS7_10XUnoTunnelEEE
+__ZTIN4cppu15WeakImplHelper6IN3com3sun4star9container6XNamedENS3_4util16XChangesNotifierENS3_4lang10XComponentENS8_12XServiceInfoENS8_12XLocalizableENS6_13XChangesBatchEEE=configmg.__ZTIN4cppu15WeakImplHelper6IN3com3sun4star9container6XNamedENS3_4util16XChangesNotifierENS3_4lang10XComponentENS8_12XServiceInfoENS8_12XLocalizableENS6_13XChangesBatchEEE
+__ZTIN4cppu18OPropertySetHelperE=configmg.__ZTIN4cppu18OPropertySetHelperE
+__ZTIN4cppu22ImplInheritanceHelper1IN9configmgr7localbe16LocalStratumBaseEN3com3sun4star13configuration7backend18XMultiLayerStratumEEE=configmg.__ZTIN4cppu22ImplInheritanceHelper1IN9configmgr7localbe16LocalStratumBaseEN3com3sun4star13configuration7backend18XMultiLayerStratumEEE
+__ZTIN4cppu22ImplInheritanceHelper1IN9configmgr7localbe16LocalStratumBaseEN3com3sun4star13configuration7backend19XSingleLayerStratumEEE=configmg.__ZTIN4cppu22ImplInheritanceHelper1IN9configmgr7localbe16LocalStratumBaseEN3com3sun4star13configuration7backend19XSingleLayerStratumEEE
+__ZTIN4cppu22ImplInheritanceHelper2IN9configmgr7localbe19LayerPropertyHelperEN3com3sun4star13configuration7backend15XUpdatableLayerENS6_4util12XTimeStampedEEE=configmg.__ZTIN4cppu22ImplInheritanceHelper2IN9configmgr7localbe19LayerPropertyHelperEN3com3sun4star13configuration7backend15XUpdatableLayerENS6_4util12XTimeStampedEEE
+__ZTIN4cppu22ImplInheritanceHelper2IN9configmgr7localbe19LayerPropertyHelperEN3com3sun4star13configuration7backend6XLayerENS6_4util12XTimeStampedEEE=configmg.__ZTIN4cppu22ImplInheritanceHelper2IN9configmgr7localbe19LayerPropertyHelperEN3com3sun4star13configuration7backend6XLayerENS6_4util12XTimeStampedEEE
+__ZTIN4cppu22ImplInheritanceHelper3IN9configmgr7localbe19LayerPropertyHelperEN3com3sun4star13configuration7backend15XUpdatableLayerENS8_15XCompositeLayerENS6_4util12XTimeStampedEEE=configmg.__ZTIN4cppu22ImplInheritanceHelper3IN9configmgr7localbe19LayerPropertyHelperEN3com3sun4star13configuration7backend15XUpdatableLayerENS8_15XCompositeLayerENS6_4util12XTimeStampedEEE
+__ZTIN4cppu24WeakComponentImplHelper1IN3com3sun4star4lang12XServiceInfoEEE=configmg.__ZTIN4cppu24WeakComponentImplHelper1IN3com3sun4star4lang12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper2IN3com3sun4star4lang20XMultiServiceFactoryENS4_12XServiceInfoEEE=configmg.__ZTIN4cppu24WeakComponentImplHelper2IN3com3sun4star4lang20XMultiServiceFactoryENS4_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper3IN3com3sun4star13configuration7backend24XVersionedSchemaSupplierENS3_4lang15XInitializationENS7_12XServiceInfoEEE=configmg.__ZTIN4cppu24WeakComponentImplHelper3IN3com3sun4star13configuration7backend24XVersionedSchemaSupplierENS3_4lang15XInitializationENS7_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper3IN3com3sun4star3uno17XComponentContextENS4_15XCurrentContextENS3_4lang12XServiceInfoEEE=configmg.__ZTIN4cppu24WeakComponentImplHelper3IN3com3sun4star3uno17XComponentContextENS4_15XCurrentContextENS3_4lang12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper3IN3com3sun4star4lang15XInitializationENS3_13configuration7backend16XBackendEntitiesENS4_12XServiceInfoEEE=configmg.__ZTIN4cppu24WeakComponentImplHelper3IN3com3sun4star4lang15XInitializationENS3_13configuration7backend16XBackendEntitiesENS4_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper5IN3com3sun4star13configuration7backend15XSchemaSupplierENS5_18XMultiLayerStratumENS5_16XBackendEntitiesENS3_4lang15XInitializationENS9_12XServiceInfoEEE=configmg.__ZTIN4cppu24WeakComponentImplHelper5IN3com3sun4star13configuration7backend15XSchemaSupplierENS5_18XMultiLayerStratumENS5_16XBackendEntitiesENS3_4lang15XInitializationENS9_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper5IN3com3sun4star13configuration7backend8XBackendENS5_16XBackendEntitiesENS5_15XSchemaSupplierENS3_4lang15XInitializationENS9_12XServiceInfoEEE=configmg.__ZTIN4cppu24WeakComponentImplHelper5IN3com3sun4star13configuration7backend8XBackendENS5_16XBackendEntitiesENS5_15XSchemaSupplierENS3_4lang15XInitializationENS9_12XServiceInfoEEE
+__ZTIN4cppu24WeakComponentImplHelper7IN3com3sun4star13configuration7backend8XBackendENS5_16XBackendEntitiesENS5_24XVersionedSchemaSupplierENS5_23XBackendChangesNotifierENS5_23XBackendChangesListenerENS3_4lang15XInitializationEN!_7c1rO0=configmg.__ZTIN4cppu24WeakComponentImplHelper7IN3com3sun4star13configuration7backend8XBackendENS5_16XBackendEntitiesENS5_24XVersionedSchemaSupplierENS5_23XBackendChangesNotifierENS5_23XBackendChangesListenerENS3_4lang15XInitializationEN!_7c1rO0
+__ZTIN4cppu27WeakComponentImplHelperBaseE=configmg.__ZTIN4cppu27WeakComponentImplHelperBaseE
+__ZTIN9configmgr10BasicGroupE=configmg.__ZTIN9configmgr10BasicGroupE
+__ZTIN9configmgr10IInterfaceE=configmg.__ZTIN9configmgr10IInterfaceE
+__ZTIN9configmgr10NodeActionE=configmg.__ZTIN9configmgr10NodeActionE
+__ZTIN9configmgr10RefcountedE=configmg.__ZTIN9configmgr10RefcountedE
+__ZTIN9configmgr10RemoveNodeE=configmg.__ZTIN9configmgr10RemoveNodeE
+__ZTIN9configmgr10SearchNodeE=configmg.__ZTIN9configmgr10SearchNodeE
+__ZTIN9configmgr11ApplyUpdateE=configmg.__ZTIN9configmgr11ApplyUpdateE
+__ZTIN9configmgr11NoncopyableE=configmg.__ZTIN9configmgr11NoncopyableE
+__ZTIN9configmgr11TreeManagerE=configmg.__ZTIN9configmgr11TreeManagerE
+__ZTIN9configmgr11TreeUpdaterE=configmg.__ZTIN9configmgr11TreeUpdaterE
+__ZTIN9configmgr11ValueChangeE=configmg.__ZTIN9configmgr11ValueChangeE
+__ZTIN9configmgr12AdjustUpdateE=configmg.__ZTIN9configmgr12AdjustUpdateE
+__ZTIN9configmgr12CollectNamesE=configmg.__ZTIN9configmgr12CollectNamesE
+__ZTIN9configmgr12ITreeManagerE=configmg.__ZTIN9configmgr12ITreeManagerE
+__ZTIN9configmgr12ONameCreatorE=configmg.__ZTIN9configmgr12ONameCreatorE
+__ZTIN9configmgr12OPathCreatorINS_13configuration12AbsolutePathEEE=configmg.__ZTIN9configmgr12OPathCreatorINS_13configuration12AbsolutePathEEE
+__ZTIN9configmgr12OPathCreatorINS_13configuration12RelativePathEEE=configmg.__ZTIN9configmgr12OPathCreatorINS_13configuration12RelativePathEEE
+__ZTIN9configmgr13BasicValueSetE=configmg.__ZTIN9configmgr13BasicValueSetE
+__ZTIN9configmgr13INodeListenerE=configmg.__ZTIN9configmgr13INodeListenerE
+__ZTIN9configmgr13OInnerSetInfoE=configmg.__ZTIN9configmgr13OInnerSetInfoE
+__ZTIN9configmgr13OMergeChangesE=configmg.__ZTIN9configmgr13OMergeChangesE
+__ZTIN9configmgr13OProviderImplE=configmg.__ZTIN9configmgr13OProviderImplE
+__ZTIN9configmgr13PWMutexHolderE=configmg.__ZTIN9configmgr13PWMutexHolderE
+__ZTIN9configmgr13SubtreeChangeE=configmg.__ZTIN9configmgr13SubtreeChangeE
+__ZTIN9configmgr13configuration100_GLOBAL__N__ZN9configmgr13configuration12TemplateName18makeSimpleTypeNameERKN3com3sun4star3uno4TypeE12TypeDetectorE=configmg.__ZTIN9configmgr13configuration100_GLOBAL__N__ZN9configmgr13configuration12TemplateName18makeSimpleTypeNameERKN3com3sun4star3uno4TypeE12TypeDetectorE
+__ZTIN9configmgr13configuration11InvalidNameE=configmg.__ZTIN9configmgr13configuration11InvalidNameE
+__ZTIN9configmgr13configuration11NodeVisitorE=configmg.__ZTIN9configmgr13configuration11NodeVisitorE
+__ZTIN9configmgr13configuration11SetNodeImplE=configmg.__ZTIN9configmgr13configuration11SetNodeImplE
+__ZTIN9configmgr13configuration12RootTreeImplE=configmg.__ZTIN9configmgr13configuration12RootTreeImplE
+__ZTIN9configmgr13configuration12SetResetImplE=configmg.__ZTIN9configmgr13configuration12SetResetImplE
+__ZTIN9configmgr13configuration12TypeMismatchE=configmg.__ZTIN9configmgr13configuration12TypeMismatchE
+__ZTIN9configmgr13configuration13GroupNodeImplE=configmg.__ZTIN9configmgr13configuration13GroupNodeImplE
+__ZTIN9configmgr13configuration13SetChangeImplE=configmg.__ZTIN9configmgr13configuration13SetChangeImplE
+__ZTIN9configmgr13configuration13SetInsertImplE=configmg.__ZTIN9configmgr13configuration13SetInsertImplE
+__ZTIN9configmgr13configuration13SetRemoveImplE=configmg.__ZTIN9configmgr13configuration13SetRemoveImplE
+__ZTIN9configmgr13configuration14CollectChangesE=configmg.__ZTIN9configmgr13configuration14CollectChangesE
+__ZTIN9configmgr13configuration14NodeChangeImplE=configmg.__ZTIN9configmgr13configuration14NodeChangeImplE
+__ZTIN9configmgr13configuration14SetNodeVisitorE=configmg.__ZTIN9configmgr13configuration14SetNodeVisitorE
+__ZTIN9configmgr13configuration14SetReplaceImplE=configmg.__ZTIN9configmgr13configuration14SetReplaceImplE
+__ZTIN9configmgr13configuration14ValueResetImplE=configmg.__ZTIN9configmgr13configuration14ValueResetImplE
+__ZTIN9configmgr13configuration15ElementTreeImplE=configmg.__ZTIN9configmgr13configuration15ElementTreeImplE
+__ZTIN9configmgr13configuration15TreeImplBuilderE=configmg.__ZTIN9configmgr13configuration15TreeImplBuilderE
+__ZTIN9configmgr13configuration15ValueChangeImplE=configmg.__ZTIN9configmgr13configuration15ValueChangeImplE
+__ZTIN9configmgr13configuration15ValueMemberNode12DeferredImplE=configmg.__ZTIN9configmgr13configuration15ValueMemberNode12DeferredImplE
+__ZTIN9configmgr13configuration16ValueReplaceImplE=configmg.__ZTIN9configmgr13configuration16ValueReplaceImplE
+__ZTIN9configmgr13configuration18GroupMemberVisitorE=configmg.__ZTIN9configmgr13configuration18GroupMemberVisitorE
+__ZTIN9configmgr13configuration19ConstraintViolationE=configmg.__ZTIN9configmgr13configuration19ConstraintViolationE
+__ZTIN9configmgr13configuration19DeferredSetNodeImplE=configmg.__ZTIN9configmgr13configuration19DeferredSetNodeImplE
+__ZTIN9configmgr13configuration19WrappedUnoExceptionE=configmg.__ZTIN9configmgr13configuration19WrappedUnoExceptionE
+__ZTIN9configmgr13configuration20DefaultProviderProxyE=configmg.__ZTIN9configmgr13configuration20DefaultProviderProxyE
+__ZTIN9configmgr13configuration20SetElementChangeImplE=configmg.__ZTIN9configmgr13configuration20SetElementChangeImplE
+__ZTIN9configmgr13configuration20ValueElementNodeImplE=configmg.__ZTIN9configmgr13configuration20ValueElementNodeImplE
+__ZTIN9configmgr13configuration21DeferredGroupNodeImplE=configmg.__ZTIN9configmgr13configuration21DeferredGroupNodeImplE
+__ZTIN9configmgr13configuration21TemplateProvider_ImplE=configmg.__ZTIN9configmgr13configuration21TemplateProvider_ImplE
+__ZTIN9configmgr13configuration28SpecialTemplateProvider_ImplE=configmg.__ZTIN9configmgr13configuration28SpecialTemplateProvider_ImplE
+__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv15CollectValueIDsE=configmg.__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv15CollectValueIDsE
+__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv17SetVisitorAdapterE=configmg.__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv17SetVisitorAdapterE
+__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv19GroupVisitorAdapterE=configmg.__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv19GroupVisitorAdapterE
+__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv21FindNonDefaultElementE=configmg.__ZTIN9configmgr13configuration55_GLOBAL__N__ZNK9configmgr13configuration4Tree7getViewEv21FindNonDefaultElementE
+__ZTIN9configmgr13configuration88_GLOBAL__N__ZN9configmgr13configuration17GroupUpdateHelperC2ERKNS0_4TreeERKNS0_7NodeRefE13NodeDefaulterE=configmg.__ZTIN9configmgr13configuration88_GLOBAL__N__ZN9configmgr13configuration17GroupUpdateHelperC2ERKNS0_4TreeERKNS0_7NodeRefE13NodeDefaulterE
+__ZTIN9configmgr13configuration8NodeImplE=configmg.__ZTIN9configmgr13configuration8NodeImplE
+__ZTIN9configmgr13configuration8TemplateE=configmg.__ZTIN9configmgr13configuration8TemplateE
+__ZTIN9configmgr13configuration8TreeImplE=configmg.__ZTIN9configmgr13configuration8TreeImplE
+__ZTIN9configmgr13configuration9ExceptionE=configmg.__ZTIN9configmgr13configuration9ExceptionE
+__ZTIN9configmgr14BasicSetAccessE=configmg.__ZTIN9configmgr14BasicSetAccessE
+__ZTIN9configmgr14ONodeConverterE=configmg.__ZTIN9configmgr14ONodeConverterE
+__ZTIN9configmgr14OStripDefaultsE=configmg.__ZTIN9configmgr14OStripDefaultsE
+__ZTIN9configmgr15BasicSetElementE=configmg.__ZTIN9configmgr15BasicSetElementE
+__ZTIN9configmgr15IConfigListenerE=configmg.__ZTIN9configmgr15IConfigListenerE
+__ZTIN9configmgr15OInnerGroupInfoE=configmg.__ZTIN9configmgr15OInnerGroupInfoE
+__ZTIN9configmgr15ProviderFactoryE=configmg.__ZTIN9configmgr15ProviderFactoryE
+__ZTIN9configmgr15ProviderWrapperE=configmg.__ZTIN9configmgr15ProviderWrapperE
+__ZTIN9configmgr16BasicGroupAccessE=configmg.__ZTIN9configmgr16BasicGroupAccessE
+__ZTIN9configmgr16BasicPropertySetE=configmg.__ZTIN9configmgr16BasicPropertySetE
+__ZTIN9configmgr16BasicRootElementE=configmg.__ZTIN9configmgr16BasicRootElementE
+__ZTIN9configmgr16BootstrapContextE=configmg.__ZTIN9configmgr16BootstrapContextE
+__ZTIN9configmgr16ChangeTreeActionE=configmg.__ZTIN9configmgr16ChangeTreeActionE
+__ZTIN9configmgr16ComponentContextE=configmg.__ZTIN9configmgr16ComponentContextE
+__ZTIN9configmgr16IDefaultProviderE=configmg.__ZTIN9configmgr16IDefaultProviderE
+__ZTIN9configmgr16ITemplateManagerE=configmg.__ZTIN9configmgr16ITemplateManagerE
+__ZTIN9configmgr16NodeModificationE=configmg.__ZTIN9configmgr16NodeModificationE
+__ZTIN9configmgr16OMergeRemoveNodeE=configmg.__ZTIN9configmgr16OMergeRemoveNodeE
+__ZTIN9configmgr16OPropagateLevelsE=configmg.__ZTIN9configmgr16OPropagateLevelsE
+__ZTIN9configmgr16UnoContextTunnel6TunnelE=configmg.__ZTIN9configmgr16UnoContextTunnel6TunnelE
+__ZTIN9configmgr17AttributeListImplE=configmg.__ZTIN9configmgr17AttributeListImplE
+__ZTIN9configmgr17BasicInnerElementE=configmg.__ZTIN9configmgr17BasicInnerElementE
+__ZTIN9configmgr17CacheClientAccessE=configmg.__ZTIN9configmgr17CacheClientAccessE
+__ZTIN9configmgr17ExtendedCacheDataE=configmg.__ZTIN9configmgr17ExtendedCacheDataE
+__ZTIN9configmgr17ExtendedCacheLineE=configmg.__ZTIN9configmgr17ExtendedCacheLineE
+__ZTIN9configmgr17OInnerGroupUpdateE=configmg.__ZTIN9configmgr17OInnerGroupUpdateE
+__ZTIN9configmgr17OMergeValueChangeE=configmg.__ZTIN9configmgr17OMergeValueChangeE
+__ZTIN9configmgr17TemplateCacheDataE=configmg.__ZTIN9configmgr17TemplateCacheDataE
+__ZTIN9configmgr18BasicUpdateElementE=configmg.__ZTIN9configmgr18BasicUpdateElementE
+__ZTIN9configmgr18CacheLoadingAccessE=configmg.__ZTIN9configmgr18CacheLoadingAccessE
+__ZTIN9configmgr18DisposingForwarderE=configmg.__ZTIN9configmgr18DisposingForwarderE
+__ZTIN9configmgr18IConfigBroadcasterE=configmg.__ZTIN9configmgr18IConfigBroadcasterE
+__ZTIN9configmgr18IConfigTreeManagerE=configmg.__ZTIN9configmgr18IConfigTreeManagerE
+__ZTIN9configmgr18OSetElementSetInfoE=configmg.__ZTIN9configmgr18OSetElementSetInfoE
+__ZTIN9configmgr19OInnerTreeSetUpdateE=configmg.__ZTIN9configmgr19OInnerTreeSetUpdateE
+__ZTIN9configmgr19ORootElementSetInfoE=configmg.__ZTIN9configmgr19ORootElementSetInfoE
+__ZTIN9configmgr20OCacheWriteScheduler5TimerE=configmg.__ZTIN9configmgr20OCacheWriteScheduler5TimerE
+__ZTIN9configmgr20OChangeActionCounterE=configmg.__ZTIN9configmgr20OChangeActionCounterE
+__ZTIN9configmgr20OCreateSubtreeActionE=configmg.__ZTIN9configmgr20OCreateSubtreeActionE
+__ZTIN9configmgr20OInnerValueSetUpdateE=configmg.__ZTIN9configmgr20OInnerValueSetUpdateE
+__ZTIN9configmgr20OMergeTreeChangeListE=configmg.__ZTIN9configmgr20OMergeTreeChangeListE
+__ZTIN9configmgr20OSetElementGroupInfoE=configmg.__ZTIN9configmgr20OSetElementGroupInfoE
+__ZTIN9configmgr20ServiceComponentImplE=configmg.__ZTIN9configmgr20ServiceComponentImplE
+__ZTIN9configmgr21ORootElementGroupInfoE=configmg.__ZTIN9configmgr21ORootElementGroupInfoE
+__ZTIN9configmgr21OSLInputStreamWrapperE=configmg.__ZTIN9configmgr21OSLInputStreamWrapperE
+__ZTIN9configmgr21OTreeDisposeScheduler5TimerE=configmg.__ZTIN9configmgr21OTreeDisposeScheduler5TimerE
+__ZTIN9configmgr21SubtreeChangeReferrerE=configmg.__ZTIN9configmgr21SubtreeChangeReferrerE
+__ZTIN9configmgr22ChangeTreeModificationE=configmg.__ZTIN9configmgr22ChangeTreeModificationE
+__ZTIN9configmgr22IConfigDefaultProviderE=configmg.__ZTIN9configmgr22IConfigDefaultProviderE
+__ZTIN9configmgr22IConfigTemplateManagerE=configmg.__ZTIN9configmgr22IConfigTemplateManagerE
+__ZTIN9configmgr22OConfigurationProviderE=configmg.__ZTIN9configmgr22OConfigurationProviderE
+__ZTIN9configmgr22OConfigurationRegistryE=configmg.__ZTIN9configmgr22OConfigurationRegistryE
+__ZTIN9configmgr22OSLOutputStreamWrapperE=configmg.__ZTIN9configmgr22OSLOutputStreamWrapperE
+__ZTIN9configmgr22OSetElementGroupUpdateE=configmg.__ZTIN9configmgr22OSetElementGroupUpdateE
+__ZTIN9configmgr23ConfigChangeBroadcasterE=configmg.__ZTIN9configmgr23ConfigChangeBroadcasterE
+__ZTIN9configmgr23IDefaultableTreeManagerE=configmg.__ZTIN9configmgr23IDefaultableTreeManagerE
+__ZTIN9configmgr23ORootElementGroupUpdateE=configmg.__ZTIN9configmgr23ORootElementGroupUpdateE
+__ZTIN9configmgr24OSetElementTreeSetUpdateE=configmg.__ZTIN9configmgr24OSetElementTreeSetUpdateE
+__ZTIN9configmgr25OConfigurationRegistryKeyE=configmg.__ZTIN9configmgr25OConfigurationRegistryKeyE
+__ZTIN9configmgr25ORootElementTreeSetUpdateE=configmg.__ZTIN9configmgr25ORootElementTreeSetUpdateE
+__ZTIN9configmgr25OSetElementValueSetUpdateE=configmg.__ZTIN9configmgr25OSetElementValueSetUpdateE
+__ZTIN9configmgr26OConfigurationProviderImplE=configmg.__ZTIN9configmgr26OConfigurationProviderImplE
+__ZTIN9configmgr26OProviderDisposingListenerE=configmg.__ZTIN9configmgr26OProviderDisposingListenerE
+__ZTIN9configmgr26ORootElementValueSetUpdateE=configmg.__ZTIN9configmgr26ORootElementValueSetUpdateE
+__ZTIN9configmgr26PropertiesFilteredNotifierE=configmg.__ZTIN9configmgr26PropertiesFilteredNotifierE
+__ZTIN9configmgr28ForwardTreeDifferenceBuilderE=configmg.__ZTIN9configmgr28ForwardTreeDifferenceBuilderE
+__ZTIN9configmgr29BackwardTreeDifferenceBuilderE=configmg.__ZTIN9configmgr29BackwardTreeDifferenceBuilderE
+__ZTIN9configmgr29OSLInputBufferedStreamWrapperE=configmg.__ZTIN9configmgr29OSLInputBufferedStreamWrapperE
+__ZTIN9configmgr3xml11BasicParserE=configmg.__ZTIN9configmgr3xml11BasicParserE
+__ZTIN9configmgr3xml11LayerParserE=configmg.__ZTIN9configmgr3xml11LayerParserE
+__ZTIN9configmgr3xml11LayerWriterE=configmg.__ZTIN9configmgr3xml11LayerWriterE
+__ZTIN9configmgr3xml12SchemaParserE=configmg.__ZTIN9configmgr3xml12SchemaParserE
+__ZTIN9configmgr3xml13ElementParser12BadValueTypeE=configmg.__ZTIN9configmgr3xml13ElementParser12BadValueTypeE
+__ZTIN9configmgr3xml13ParserServiceIN3com3sun4star13configuration7backend6XLayerEEE=configmg.__ZTIN9configmgr3xml13ParserServiceIN3com3sun4star13configuration7backend6XLayerEEE
+__ZTIN9configmgr3xml13ParserServiceIN3com3sun4star13configuration7backend7XSchemaEEE=configmg.__ZTIN9configmgr3xml13ParserServiceIN3com3sun4star13configuration7backend7XSchemaEEE
+__ZTIN9configmgr3xml13WriterServiceIN3com3sun4star13configuration7backend13XLayerHandlerEEE=configmg.__ZTIN9configmgr3xml13WriterServiceIN3com3sun4star13configuration7backend13XLayerHandlerEEE
+__ZTIN9configmgr3xml18LayerParserServiceE=configmg.__ZTIN9configmgr3xml18LayerParserServiceE
+__ZTIN9configmgr3xml19SchemaParserServiceE=configmg.__ZTIN9configmgr3xml19SchemaParserServiceE
+__ZTIN9configmgr4data10SetVisitorE=configmg.__ZTIN9configmgr4data10SetVisitorE
+__ZTIN9configmgr4data11NodeVisitorE=configmg.__ZTIN9configmgr4data11NodeVisitorE
+__ZTIN9configmgr4data11TreeSegment4ImplE=configmg.__ZTIN9configmgr4data11TreeSegment4ImplE
+__ZTIN9configmgr4data15TreeNodeBuilder12LinkSetNodesE=configmg.__ZTIN9configmgr4data15TreeNodeBuilder12LinkSetNodesE
+__ZTIN9configmgr4data20BasicDataTreeBuilderE=configmg.__ZTIN9configmgr4data20BasicDataTreeBuilderE
+__ZTIN9configmgr4data21ConvertingNodeBuilderE=configmg.__ZTIN9configmgr4data21ConvertingNodeBuilderE
+__ZTIN9configmgr4data21DataTreeDefaultMergerE=configmg.__ZTIN9configmgr4data21DataTreeDefaultMergerE
+__ZTIN9configmgr4data22CopyingDataTreeBuilder18ElementListBuilderE=configmg.__ZTIN9configmgr4data22CopyingDataTreeBuilder18ElementListBuilderE
+__ZTIN9configmgr4data22CopyingDataTreeBuilderE=configmg.__ZTIN9configmgr4data22CopyingDataTreeBuilderE
+__ZTIN9configmgr4data24ConvertingSubnodeBuilderE=configmg.__ZTIN9configmgr4data24ConvertingSubnodeBuilderE
+__ZTIN9configmgr4data25ConvertingDataTreeBuilder18ElementListBuilderE=configmg.__ZTIN9configmgr4data25ConvertingDataTreeBuilder18ElementListBuilderE
+__ZTIN9configmgr4data25ConvertingDataTreeBuilderE=configmg.__ZTIN9configmgr4data25ConvertingDataTreeBuilderE
+__ZTIN9configmgr4view11NodeFactoryE=configmg.__ZTIN9configmgr4view11NodeFactoryE
+__ZTIN9configmgr4view12ViewStrategyE=configmg.__ZTIN9configmgr4view12ViewStrategyE
+__ZTIN9configmgr4view18DirectViewStrategyE=configmg.__ZTIN9configmgr4view18DirectViewStrategyE
+__ZTIN9configmgr4view20DeferredViewStrategyE=configmg.__ZTIN9configmgr4view20DeferredViewStrategyE
+__ZTIN9configmgr4view20ReadOnlyViewStrategyE=configmg.__ZTIN9configmgr4view20ReadOnlyViewStrategyE
+__ZTIN9configmgr4view72_GLOBAL__N__ZNK9configmgr4view12ViewStrategy13checkInstanceERKNS0_4TreeE19GroupMemberDispatchE=configmg.__ZTIN9configmgr4view72_GLOBAL__N__ZNK9configmgr4view12ViewStrategy13checkInstanceERKNS0_4TreeE19GroupMemberDispatchE
+__ZTIN9configmgr5INodeE=configmg.__ZTIN9configmgr5INodeE
+__ZTIN9configmgr6ChangeE=configmg.__ZTIN9configmgr6ChangeE
+__ZTIN9configmgr6memory11HeapManagerE=configmg.__ZTIN9configmgr6memory11HeapManagerE
+__ZTIN9configmgr6memory14SimpleHeapLockE=configmg.__ZTIN9configmgr6memory14SimpleHeapLockE
+__ZTIN9configmgr6memory21SimpleHeapManagerBaseE=configmg.__ZTIN9configmgr6memory21SimpleHeapManagerBaseE
+__ZTIN9configmgr6memory25SimpleCheckingHeapManagerE=configmg.__ZTIN9configmgr6memory25SimpleCheckingHeapManagerE
+__ZTIN9configmgr6memory8DataLockE=configmg.__ZTIN9configmgr6memory8DataLockE
+__ZTIN9configmgr7AddNodeE=configmg.__ZTIN9configmgr7AddNodeE
+__ZTIN9configmgr7SubtreeE=configmg.__ZTIN9configmgr7SubtreeE
+__ZTIN9configmgr7backend10EmptyLayerE=configmg.__ZTIN9configmgr7backend10EmptyLayerE
+__ZTIN9configmgr7backend10NodeUpdateE=configmg.__ZTIN9configmgr7backend10NodeUpdateE
+__ZTIN9configmgr7backend11NamedUpdateE=configmg.__ZTIN9configmgr7backend11NamedUpdateE
+__ZTIN9configmgr7backend11NodeReplaceE=configmg.__ZTIN9configmgr7backend11NodeReplaceE
+__ZTIN9configmgr7backend11PropertyAddE=configmg.__ZTIN9configmgr7backend11PropertyAddE
+__ZTIN9configmgr7backend12ResultHolderINS0_12NodeInstanceEE10RCInstanceE=configmg.__ZTIN9configmgr7backend12ResultHolderINS0_12NodeInstanceEE10RCInstanceE
+__ZTIN9configmgr7backend12ResultHolderINS0_16TemplateInstanceEE10RCInstanceE=configmg.__ZTIN9configmgr7backend12ResultHolderINS0_16TemplateInstanceEE10RCInstanceE
+__ZTIN9configmgr7backend12ResultHolderINS0_17ComponentInstanceEE10RCInstanceE=configmg.__ZTIN9configmgr7backend12ResultHolderINS0_17ComponentInstanceEE10RCInstanceE
+__ZTIN9configmgr7backend13BackendAccessE=configmg.__ZTIN9configmgr7backend13BackendAccessE
+__ZTIN9configmgr7backend13ElementUpdateE=configmg.__ZTIN9configmgr7backend13ElementUpdateE
+__ZTIN9configmgr7backend13ImportServiceE=configmg.__ZTIN9configmgr7backend13ImportServiceE
+__ZTIN9configmgr7backend13PropertyResetE=configmg.__ZTIN9configmgr7backend13PropertyResetE
+__ZTIN9configmgr7backend13SchemaBuilderE=configmg.__ZTIN9configmgr7backend13SchemaBuilderE
+__ZTIN9configmgr7backend13UpdateServiceE=configmg.__ZTIN9configmgr7backend13UpdateServiceE
+__ZTIN9configmgr7backend14PropertyUpdateE=configmg.__ZTIN9configmgr7backend14PropertyUpdateE
+__ZTIN9configmgr7backend15CacheControllerE=configmg.__ZTIN9configmgr7backend15CacheControllerE
+__ZTIN9configmgr7backend16NodeModificationE=configmg.__ZTIN9configmgr7backend16NodeModificationE
+__ZTIN9configmgr7backend16UpdateDispatcherE=configmg.__ZTIN9configmgr7backend16UpdateDispatcherE
+__ZTIN9configmgr7backend17BasicUpdateMergerE=configmg.__ZTIN9configmgr7backend17BasicUpdateMergerE
+__ZTIN9configmgr7backend17BinaryReader_ImplE=configmg.__ZTIN9configmgr7backend17BinaryReader_ImplE
+__ZTIN9configmgr7backend17CopyImportServiceE=configmg.__ZTIN9configmgr7backend17CopyImportServiceE
+__ZTIN9configmgr7backend17INodeDataListenerE=configmg.__ZTIN9configmgr7backend17INodeDataListenerE
+__ZTIN9configmgr7backend17INodeDataProviderE=configmg.__ZTIN9configmgr7backend17INodeDataProviderE
+__ZTIN9configmgr7backend17LayerMergeHandlerE=configmg.__ZTIN9configmgr7backend17LayerMergeHandlerE
+__ZTIN9configmgr7backend17LayerUpdateMergerE=configmg.__ZTIN9configmgr7backend17LayerUpdateMergerE
+__ZTIN9configmgr7backend17RequireEmptyLayerE=configmg.__ZTIN9configmgr7backend17RequireEmptyLayerE
+__ZTIN9configmgr7backend18BasicImportHandlerE=configmg.__ZTIN9configmgr7backend18BasicImportHandlerE
+__ZTIN9configmgr7backend18BinaryWriteHandlerE=configmg.__ZTIN9configmgr7backend18BinaryWriteHandlerE
+__ZTIN9configmgr7backend18ImportMergeHandlerE=configmg.__ZTIN9configmgr7backend18ImportMergeHandlerE
+__ZTIN9configmgr7backend18LayerUpdateHandlerE=configmg.__ZTIN9configmgr7backend18LayerUpdateHandlerE
+__ZTIN9configmgr7backend18MergeImportServiceE=configmg.__ZTIN9configmgr7backend18MergeImportServiceE
+__ZTIN9configmgr7backend19ICachedDataListenerE=configmg.__ZTIN9configmgr7backend19ICachedDataListenerE
+__ZTIN9configmgr7backend19ICachedDataNotifierE=configmg.__ZTIN9configmgr7backend19ICachedDataNotifierE
+__ZTIN9configmgr7backend19ICachedDataProviderE=configmg.__ZTIN9configmgr7backend19ICachedDataProviderE
+__ZTIN9configmgr7backend19IDirectDataProviderE=configmg.__ZTIN9configmgr7backend19IDirectDataProviderE
+__ZTIN9configmgr7backend19IMergedDataProviderE=configmg.__ZTIN9configmgr7backend19IMergedDataProviderE
+__ZTIN9configmgr7backend19INodeUpdateProviderE=configmg.__ZTIN9configmgr7backend19INodeUpdateProviderE
+__ZTIN9configmgr7backend19LayerDefaultRemoverE=configmg.__ZTIN9configmgr7backend19LayerDefaultRemoverE
+__ZTIN9configmgr7backend19MultiStratumBackendE=configmg.__ZTIN9configmgr7backend19MultiStratumBackendE
+__ZTIN9configmgr7backend20IDefaultDataProviderE=configmg.__ZTIN9configmgr7backend20IDefaultDataProviderE
+__ZTIN9configmgr7backend20SingleBackendAdapterE=configmg.__ZTIN9configmgr7backend20SingleBackendAdapterE
+__ZTIN9configmgr7backend21BackendChangeNotifierE=configmg.__ZTIN9configmgr7backend21BackendChangeNotifierE
+__ZTIN9configmgr7backend21BackendStrataListenerE=configmg.__ZTIN9configmgr7backend21BackendStrataListenerE
+__ZTIN9configmgr7backend21IDataProviderMetaDataE=configmg.__ZTIN9configmgr7backend21IDataProviderMetaDataE
+__ZTIN9configmgr7backend21ITemplateDataProviderE=configmg.__ZTIN9configmgr7backend21ITemplateDataProviderE
+__ZTIN9configmgr7backend21OInvalidateTreeThreadE=configmg.__ZTIN9configmgr7backend21OInvalidateTreeThreadE
+__ZTIN9configmgr7backend22CacheChangeMulticasterE=configmg.__ZTIN9configmgr7backend22CacheChangeMulticasterE
+__ZTIN9configmgr7backend22IComponentDataProviderE=configmg.__ZTIN9configmgr7backend22IComponentDataProviderE
+__ZTIN9configmgr7backend8NodeDropE=configmg.__ZTIN9configmgr7backend8NodeDropE
+__ZTIN9configmgr7localbe16LocalDataStratumE=configmg.__ZTIN9configmgr7localbe16LocalDataStratumE
+__ZTIN9configmgr7localbe16LocalStratumBaseE=configmg.__ZTIN9configmgr7localbe16LocalStratumBaseE
+__ZTIN9configmgr7localbe17LocalMultiStratumE=configmg.__ZTIN9configmgr7localbe17LocalMultiStratumE
+__ZTIN9configmgr7localbe17LocalOutputStreamE=configmg.__ZTIN9configmgr7localbe17LocalOutputStreamE
+__ZTIN9configmgr7localbe18FlatLocalFileLayerE=configmg.__ZTIN9configmgr7localbe18FlatLocalFileLayerE
+__ZTIN9configmgr7localbe18LocalSingleBackendE=configmg.__ZTIN9configmgr7localbe18LocalSingleBackendE
+__ZTIN9configmgr7localbe18LocalSingleStratumE=configmg.__ZTIN9configmgr7localbe18LocalSingleStratumE
+__ZTIN9configmgr7localbe19BasicLocalFileLayerE=configmg.__ZTIN9configmgr7localbe19BasicLocalFileLayerE
+__ZTIN9configmgr7localbe19LayerPropertyHelperE=configmg.__ZTIN9configmgr7localbe19LayerPropertyHelperE
+__ZTIN9configmgr7localbe19LocalSchemaSupplierE=configmg.__ZTIN9configmgr7localbe19LocalSchemaSupplierE
+__ZTIN9configmgr7localbe20LocalReadonlyStratumE=configmg.__ZTIN9configmgr7localbe20LocalReadonlyStratumE
+__ZTIN9configmgr7localbe20LocalResourceStratumE=configmg.__ZTIN9configmgr7localbe20LocalResourceStratumE
+__ZTIN9configmgr7localbe20SimpleLocalFileLayerE=configmg.__ZTIN9configmgr7localbe20SimpleLocalFileLayerE
+__ZTIN9configmgr7localbe22LocalDataImportServiceE=configmg.__ZTIN9configmgr7localbe22LocalDataImportServiceE
+__ZTIN9configmgr7localbe22LocalSingleStratumBaseE=configmg.__ZTIN9configmgr7localbe22LocalSingleStratumBaseE
+__ZTIN9configmgr7localbe23CompositeLocalFileLayerE=configmg.__ZTIN9configmgr7localbe23CompositeLocalFileLayerE
+__ZTIN9configmgr7localbe23LocalStratumMutexHolderE=configmg.__ZTIN9configmgr7localbe23LocalStratumMutexHolderE
+__ZTIN9configmgr7localbe27FullCompositeLocalFileLayerE=configmg.__ZTIN9configmgr7localbe27FullCompositeLocalFileLayerE
+__ZTIN9configmgr7localbe28BasicCompositeLocalFileLayerE=configmg.__ZTIN9configmgr7localbe28BasicCompositeLocalFileLayerE
+__ZTIN9configmgr7localbe28LocalHierarchyBrowserServiceE=configmg.__ZTIN9configmgr7localbe28LocalHierarchyBrowserServiceE
+__ZTIN9configmgr8BasicSetE=configmg.__ZTIN9configmgr8BasicSetE
+__ZTIN9configmgr8ISubtreeE=configmg.__ZTIN9configmgr8ISubtreeE
+__ZTIN9configmgr8OOptionsE=configmg.__ZTIN9configmgr8OOptionsE
+__ZTIN9configmgr9CacheDataE=configmg.__ZTIN9configmgr9CacheDataE
+__ZTIN9configmgr9CacheLineE=configmg.__ZTIN9configmgr9CacheLineE
+__ZTIN9configmgr9OProviderE=configmg.__ZTIN9configmgr9OProviderE
+__ZTIN9configmgr9ValueNodeE=configmg.__ZTIN9configmgr9ValueNodeE
+__ZTIN9configmgr9apihelper15BroadcasterBaseE=configmg.__ZTIN9configmgr9apihelper15BroadcasterBaseE
+__ZTIN9configmgr9apihelper17PropertySetHelperE=configmg.__ZTIN9configmgr9apihelper17PropertySetHelperE
+__ZTIN9configmgr9apihelper18InteractionRequestE=configmg.__ZTIN9configmgr9apihelper18InteractionRequestE
+__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task17XInteractionAbortEEE=configmg.__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task17XInteractionAbortEEE
+__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task17XInteractionRetryEEE=configmg.__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task17XInteractionRetryEEE
+__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task19XInteractionApproveEEE=configmg.__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task19XInteractionApproveEEE
+__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task22XInteractionDisapproveEEE=configmg.__ZTIN9configmgr9apihelper23InteractionContinuationIN3com3sun4star4task22XInteractionDisapproveEEE
+__ZTIN9configmgr9apihelper24SimpleInteractionRequestE=configmg.__ZTIN9configmgr9apihelper24SimpleInteractionRequestE
+__ZTIN9configmgr9apihelper31ConfigurationInteractionHandler7ContextE=configmg.__ZTIN9configmgr9apihelper31ConfigurationInteractionHandler7ContextE
+__ZTIN9configmgr9configapi10NodeAccessE=configmg.__ZTIN9configmgr9configapi10NodeAccessE
+__ZTIN9configmgr9configapi10SetElementE=configmg.__ZTIN9configmgr9configapi10SetElementE
+__ZTIN9configmgr9configapi11ApiTreeImpl16ComponentAdapterE=configmg.__ZTIN9configmgr9configapi11ApiTreeImpl16ComponentAdapterE
+__ZTIN9configmgr9configapi11Broadcaster4ImplE=configmg.__ZTIN9configmgr9configapi11Broadcaster4ImplE
+__ZTIN9configmgr9configapi11NodeElementE=configmg.__ZTIN9configmgr9configapi11NodeElementE
+__ZTIN9configmgr9configapi11OSetElementINS0_15NodeGroupAccessEEE=configmg.__ZTIN9configmgr9configapi11OSetElementINS0_15NodeGroupAccessEEE
+__ZTIN9configmgr9configapi11OSetElementINS0_17NodeSetInfoAccessEEE=configmg.__ZTIN9configmgr9configapi11OSetElementINS0_17NodeSetInfoAccessEEE
+__ZTIN9configmgr9configapi11OSetElementINS0_17NodeTreeSetAccessEEE=configmg.__ZTIN9configmgr9configapi11OSetElementINS0_17NodeTreeSetAccessEEE
+__ZTIN9configmgr9configapi11OSetElementINS0_18NodeValueSetAccessEEE=configmg.__ZTIN9configmgr9configapi11OSetElementINS0_18NodeValueSetAccessEEE
+__ZTIN9configmgr9configapi11OSetElementINS0_19NodeGroupInfoAccessEEE=configmg.__ZTIN9configmgr9configapi11OSetElementINS0_19NodeGroupInfoAccessEEE
+__ZTIN9configmgr9configapi11RootElementE=configmg.__ZTIN9configmgr9configapi11RootElementE
+__ZTIN9configmgr9configapi11TreeElementE=configmg.__ZTIN9configmgr9configapi11TreeElementE
+__ZTIN9configmgr9configapi12InnerElementE=configmg.__ZTIN9configmgr9configapi12InnerElementE
+__ZTIN9configmgr9configapi12NotifierImplE=configmg.__ZTIN9configmgr9configapi12NotifierImplE
+__ZTIN9configmgr9configapi13NodeSetAccessE=configmg.__ZTIN9configmgr9configapi13NodeSetAccessE
+__ZTIN9configmgr9configapi13OInnerElementINS0_15NodeGroupAccessEEE=configmg.__ZTIN9configmgr9configapi13OInnerElementINS0_15NodeGroupAccessEEE
+__ZTIN9configmgr9configapi13OInnerElementINS0_17NodeSetInfoAccessEEE=configmg.__ZTIN9configmgr9configapi13OInnerElementINS0_17NodeSetInfoAccessEEE
+__ZTIN9configmgr9configapi13OInnerElementINS0_17NodeTreeSetAccessEEE=configmg.__ZTIN9configmgr9configapi13OInnerElementINS0_17NodeTreeSetAccessEEE
+__ZTIN9configmgr9configapi13OInnerElementINS0_18NodeValueSetAccessEEE=configmg.__ZTIN9configmgr9configapi13OInnerElementINS0_18NodeValueSetAccessEEE
+__ZTIN9configmgr9configapi13OInnerElementINS0_19NodeGroupInfoAccessEEE=configmg.__ZTIN9configmgr9configapi13OInnerElementINS0_19NodeGroupInfoAccessEEE
+__ZTIN9configmgr9configapi14ObjectRegistryE=configmg.__ZTIN9configmgr9configapi14ObjectRegistryE
+__ZTIN9configmgr9configapi15ApiRootTreeImpl12NodeListenerE=configmg.__ZTIN9configmgr9configapi15ApiRootTreeImpl12NodeListenerE
+__ZTIN9configmgr9configapi15NodeGroupAccessE=configmg.__ZTIN9configmgr9configapi15NodeGroupAccessE
+__ZTIN9configmgr9configapi16CollectNodeNamesE=configmg.__ZTIN9configmgr9configapi16CollectNodeNamesE
+__ZTIN9configmgr9configapi16OReadRootElementINS0_17NodeSetInfoAccessEEE=configmg.__ZTIN9configmgr9configapi16OReadRootElementINS0_17NodeSetInfoAccessEEE
+__ZTIN9configmgr9configapi16OReadRootElementINS0_19NodeGroupInfoAccessEEE=configmg.__ZTIN9configmgr9configapi16OReadRootElementINS0_19NodeGroupInfoAccessEEE
+__ZTIN9configmgr9configapi17CollectPropertiesE=configmg.__ZTIN9configmgr9configapi17CollectPropertiesE
+__ZTIN9configmgr9configapi17NodeSetInfoAccessE=configmg.__ZTIN9configmgr9configapi17NodeSetInfoAccessE
+__ZTIN9configmgr9configapi17NodeTreeSetAccessE=configmg.__ZTIN9configmgr9configapi17NodeTreeSetAccessE
+__ZTIN9configmgr9configapi17UpdateRootElementE=configmg.__ZTIN9configmgr9configapi17UpdateRootElementE
+__ZTIN9configmgr9configapi18NodeValueSetAccessE=configmg.__ZTIN9configmgr9configapi18NodeValueSetAccessE
+__ZTIN9configmgr9configapi18OUpdateRootElementINS0_15NodeGroupAccessEEE=configmg.__ZTIN9configmgr9configapi18OUpdateRootElementINS0_15NodeGroupAccessEEE
+__ZTIN9configmgr9configapi18OUpdateRootElementINS0_17NodeTreeSetAccessEEE=configmg.__ZTIN9configmgr9configapi18OUpdateRootElementINS0_17NodeTreeSetAccessEEE
+__ZTIN9configmgr9configapi18OUpdateRootElementINS0_18NodeValueSetAccessEEE=configmg.__ZTIN9configmgr9configapi18OUpdateRootElementINS0_18NodeValueSetAccessEEE
+__ZTIN9configmgr9configapi19CollectPropertyInfoE=configmg.__ZTIN9configmgr9configapi19CollectPropertyInfoE
+__ZTIN9configmgr9configapi19NodeGroupInfoAccessE=configmg.__ZTIN9configmgr9configapi19NodeGroupInfoAccessE
+__ZTIN9configmgr9configapi19NodePropertySetInfoE=configmg.__ZTIN9configmgr9configapi19NodePropertySetInfoE
+__ZTIN9configmgr9configapi19UpdateObjectFactoryE=configmg.__ZTIN9configmgr9configapi19UpdateObjectFactoryE
+__ZTIN9configmgr9configapi21ReadOnlyObjectFactoryE=configmg.__ZTIN9configmgr9configapi21ReadOnlyObjectFactoryE
+__ZTIN9configmgr9configapi7FactoryE=configmg.__ZTIN9configmgr9configapi7FactoryE
+__ZTIN9configmgr9configapi8internal15SearchExactNameE=configmg.__ZTIN9configmgr9configapi8internal15SearchExactNameE
+__ZTIN9salhelper21SimpleReferenceObjectE=configmg.__ZTIN9salhelper21SimpleReferenceObjectE
+
+EXPORTS
+__ZTIN3com3sun4star3ucb31InteractiveAugmentedIOExceptionE
+__ZTIN3com3sun4star3ucb22InteractiveIOExceptionE
+__ZTIN3com3sun4star4task28ClassifiedInteractionRequestE
+__ZTIN3com3sun4star3ucb18NameClashExceptionE
+__ZTIN3com3sun4star3ucb27UnsupportedCommandExceptionE
+IMPORTS
+__ZTIN3com3sun4star3ucb31InteractiveAugmentedIOExceptionE=ucpfile1.__ZTIN3com3sun4star3ucb31InteractiveAugmentedIOExceptionE
+__ZTIN3com3sun4star3ucb22InteractiveIOExceptionE=ucpfile1.__ZTIN3com3sun4star3ucb22InteractiveIOExceptionE
+__ZTIN3com3sun4star4task28ClassifiedInteractionRequestE=ucpfile1.__ZTIN3com3sun4star4task28ClassifiedInteractionRequestE
+__ZTIN3com3sun4star3ucb18NameClashExceptionE=ucpfile1.__ZTIN3com3sun4star3ucb18NameClashExceptionE
+__ZTIN3com3sun4star3ucb27UnsupportedCommandExceptionE=ucpfile1.__ZTIN3com3sun4star3ucb27UnsupportedCommandExceptionE
+
+EXPORTS
+__ZTIN3com3sun4star3ucb34InteractiveBadTransferURLExceptionE
+IMPORTS
+__ZTIN3com3sun4star3ucb34InteractiveBadTransferURLExceptionE=ucb1.__ZTIN3com3sun4star3ucb34InteractiveBadTransferURLExceptionE
diff --git a/bridges/source/cpp_uno/gcc3_os2_intel/except.cxx b/bridges/source/cpp_uno/gcc3_os2_intel/except.cxx
new file mode 100644
index 000000000000..99c2f62d1476
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_os2_intel/except.cxx
@@ -0,0 +1,351 @@
+/* -*- 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 <stdio.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+#ifdef TEST
+#include "test/TestBridgeException.hpp"
+#endif
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+//==================================================================================================
+//YD static handle to this dll, to allow rtti symbol lookup
+static void* hmod;
+
+//==================================================================================================
+//YD required to run test programs, because exe cannot export symbols!
+#ifdef TEST
+using namespace ::test;
+
+void dymmy_TestBridgeException() throw( ::test::TestBridgeException)
+{
+ throw TestBridgeException();
+}
+#endif
+
+//==================================================================================================
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * )
+{
+}
+
+//==================================================================================================
+static OUString toUNOname( char const * p ) SAL_THROW( () )
+{
+#if OSL_DEBUG_LEVEL > 1
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+}
+
+//==================================================================================================
+class RTTI
+{
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ //void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+// : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+// dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+{
+ type_info * rtti = NULL;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("__ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ //rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+ if (hmod == NULL)
+ hmod = dlopen( "gcc3_uno.dll", 0);
+
+ if (hmod)
+ rtti = (type_info *)dlsym( hmod, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
+ if (iFind == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with __ZTI
+ char const * rttiName = symName.getStr() +5;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iFind->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void deleteException( void * pExc )
+{
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() );
+#endif
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get typedescription for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+{
+ if (! header)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_os2_intel/makefile.mk b/bridges/source/cpp_uno/gcc3_os2_intel/makefile.mk
new file mode 100644
index 000000000000..641eef166cfd
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_os2_intel/makefile.mk
@@ -0,0 +1,73 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+NO_BSYMBOLIC=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCOS2Igcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=defs$/gcc3_uno.def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/gcc3_os2_intel/share.hxx b/bridges/source/cpp_uno/gcc3_os2_intel/share.hxx
new file mode 100644
index 000000000000..da2367ad172b
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_os2_intel/share.hxx
@@ -0,0 +1,93 @@
+/* -*- 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 "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * );
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_os2_intel/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_os2_intel/uno2cpp.cxx
new file mode 100644
index 000000000000..64be1daa086e
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_os2_intel/uno2cpp.cxx
@@ -0,0 +1,454 @@
+/* -*- 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 <malloc.h>
+#include <sal/alloca.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "share.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+// The call instruction within the asm section of callVirtualMethod may throw
+// exceptions. So that the compiler handles this correctly, it is important
+// that (a) callVirtualMethod might call dummy_can_throw_anything (although this
+// never happens at runtime), which in turn can throw exceptions, and (b)
+// callVirtualMethod is not inlined at its call site (so that any exceptions are
+// caught which are thrown from the instruction calling callVirtualMethod):
+static void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs );
+// __attribute__((noinline));
+
+//==================================================================================================
+static void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs )
+{
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ OSL_ENSURE( pStackLongs && pAdjustedThisPtr, "### null ptr!" );
+ OSL_ENSURE( (sizeof(void *) == 4) && (sizeof(sal_Int32) == 4), "### unexpected size of int!" );
+ OSL_ENSURE( nStackLongs && pStackLongs, "### no stack in callVirtualMethod !" );
+
+ // never called
+ if (! pAdjustedThisPtr) CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
+
+ /* figure out the address of the function we need to invoke */
+ unsigned long * mfunc; // actual function to be invoked
+ int off; // offset used to find function
+ void (*ptr)();
+ off = nVtableIndex;
+ off = off * 4; // 4 bytes per slot
+ mfunc = *((unsigned long **)pAdjustedThisPtr); // get the address of the vtable
+ mfunc = (unsigned long *)((char *)mfunc + off); // get the address from the vtable entry at offset
+ mfunc = *((unsigned long **)mfunc); // the function is stored at the address
+ ptr = (void (*)())mfunc;
+
+ volatile long edx = 0, eax = 0; // for register returns
+ void * stackptr;
+ asm volatile (
+ "mov %%esp, %6\n\t"
+ // copy values
+ "mov %0, %%eax\n\t"
+ "mov %%eax, %%edx\n\t"
+ "dec %%edx\n\t"
+ "shl $2, %%edx\n\t"
+ "add %1, %%edx\n"
+ "Lcopy:\n\t"
+ "pushl 0(%%edx)\n\t"
+ "sub $4, %%edx\n\t"
+ "dec %%eax\n\t"
+ "jne Lcopy\n\t"
+ :
+ : "m"(nStackLongs), "m"(pStackLongs), "m"(pAdjustedThisPtr),
+ "m"(nVtableIndex), "m"(eax), "m"(edx), "m"(stackptr)
+ : "eax", "edx" );
+
+ (*ptr)();
+
+ asm volatile (
+ // save return registers
+ "mov %%eax, %4\n\t"
+ "mov %%edx, %5\n\t"
+ // cleanup stack
+ "mov %6, %%esp\n\t"
+ :
+ : "m"(nStackLongs), "m"(pStackLongs), "m"(pAdjustedThisPtr),
+ "m"(nVtableIndex), "m"(eax), "m"(edx), "m"(stackptr)
+ : "eax", "edx" );
+ switch( eReturnType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ ((long*)pRegisterReturn)[1] = edx;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_ENUM:
+ ((long*)pRegisterReturn)[0] = eax;
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = eax;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = eax;
+ break;
+ case typelib_TypeClass_FLOAT:
+ asm ( "fstps %0" : : "m"(*(char *)pRegisterReturn) );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ asm ( "fstpl %0\n\t" : : "m"(*(char *)pRegisterReturn) );
+ break;
+ }
+}
+
+//==================================================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ char * pCppStack =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ char * pCppStackStart = pCppStack;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack
+ = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ pCppStack += sizeof(void *);
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ try
+ {
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; // get, then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_solaris_intel/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_solaris_intel/cpp2uno.cxx
new file mode 100644
index 000000000000..1c16f6550120
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_intel/cpp2uno.cxx
@@ -0,0 +1,526 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sal/alloca.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "share.hxx"
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ // pCallStack: ret, [return ptr], this, params
+ char * pCppStack = (char *)(pCallStack +1);
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)pCppStack;
+ pCppStack += sizeof(void *);
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ // value
+ {
+ pCppArgs[nPos] = pCppStack;
+ pUnoArgs[nPos] = pCppStack;
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ pCppArgs[nPos] = *(void **)pCppStack;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException(
+ &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: ret adr, [ret *], this, params
+ void * pThis;
+ if( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = pCallStack[2];
+ }
+ else
+ {
+ pThis = pCallStack[1];
+ }
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pThis );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[3] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pCallStack[1] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = pCallStack[1];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static void cpp_vtable_call(
+ int nFunctionIndex, int nVtableOffset, void** pCallStack )
+ __attribute__((regparm(3)));
+
+void cpp_vtable_call( int nFunctionIndex, int nVtableOffset, void** pCallStack )
+{
+ volatile long nRegReturn[2];
+ typelib_TypeClass aType = cpp_mediate(
+ nFunctionIndex, nVtableOffset, pCallStack, (sal_Int64*)nRegReturn );
+
+ switch( aType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ __asm__( "movl %1, %%edx\n\t"
+ "movl %0, %%eax\n"
+ : : "m"(nRegReturn[0]), "m"(nRegReturn[1]) );
+ break;
+ case typelib_TypeClass_FLOAT:
+ __asm__( "flds %0\n\t"
+ "fstp %%st(0)\n\t"
+ "flds %0\n"
+ : : "m"(*(float *)nRegReturn) );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ __asm__( "fldl %0\n\t"
+ "fstp %%st(0)\n\t"
+ "fldl %0\n"
+ : : "m"(*(double *)nRegReturn) );
+ break;
+// case typelib_TypeClass_UNSIGNED_SHORT:
+// case typelib_TypeClass_SHORT:
+// __asm__( "movswl %0, %%eax\n"
+// : : "m"(nRegReturn) );
+// break;
+ default:
+ __asm__( "movl %0, %%eax\n"
+ : : "m"(nRegReturn[0]) );
+ break;
+ }
+}
+
+
+//==================================================================================================
+int const codeSnippetSize = 20;
+
+unsigned char * codeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ bool simpleRetType)
+{
+ if (!simpleRetType) {
+ functionIndex |= 0x80000000;
+ }
+ unsigned char * p = code;
+ OSL_ASSERT(sizeof (sal_Int32) == 4);
+ // mov function_index, %eax:
+ *p++ = 0xB8;
+ *reinterpret_cast< sal_Int32 * >(p) = functionIndex;
+ p += sizeof (sal_Int32);
+ // mov vtable_offset, %edx:
+ *p++ = 0xBA;
+ *reinterpret_cast< sal_Int32 * >(p) = vtableOffset;
+ p += sizeof (sal_Int32);
+ // mov %esp, %ecx:
+ *p++ = 0x89;
+ *p++ = 0xE1;
+ // jmp cpp_vtable_call:
+ *p++ = 0xE9;
+ *reinterpret_cast< sal_Int32 * >(p)
+ = ((unsigned char *) cpp_vtable_call) - p - sizeof (sal_Int32);
+ p += sizeof (sal_Int32);
+ OSL_ASSERT(p - code <= codeSnippetSize);
+ return code + codeSnippetSize;
+}
+
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0;
+ slots[-1].fn = 0;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vtableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const *, unsigned char const *)
+{}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_solaris_intel/except.cxx b/bridges/source/cpp_uno/gcc3_solaris_intel/except.cxx
new file mode 100644
index 000000000000..5dfc476edafd
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_intel/except.cxx
@@ -0,0 +1,331 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * )
+{
+}
+
+//==================================================================================================
+static OUString toUNOname( char const * p ) SAL_THROW( () )
+{
+#if OSL_DEBUG_LEVEL > 1
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+}
+
+//==================================================================================================
+class RTTI
+{
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+{
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
+ if (iFind == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with _ZTI
+ char const * rttiName = symName.getStr() +4;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iFind->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void deleteException( void * pExc )
+{
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() );
+#endif
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get typedescription for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+{
+ if (! header)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_solaris_intel/makefile.mk b/bridges/source/cpp_uno/gcc3_solaris_intel/makefile.mk
new file mode 100644
index 000000000000..ccc0cb9e0402
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_intel/makefile.mk
@@ -0,0 +1,73 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCSOLARISIgcc3"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/gcc3_solaris_intel/share.hxx b/bridges/source/cpp_uno/gcc3_solaris_intel/share.hxx
new file mode 100644
index 000000000000..da2367ad172b
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_intel/share.hxx
@@ -0,0 +1,93 @@
+/* -*- 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 "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * );
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_solaris_intel/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_solaris_intel/uno2cpp.cxx
new file mode 100644
index 000000000000..8035256d4db8
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_intel/uno2cpp.cxx
@@ -0,0 +1,430 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+#include <sal/alloca.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "share.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+static void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs )
+{
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ OSL_ENSURE( pStackLongs && pAdjustedThisPtr, "### null ptr!" );
+ OSL_ENSURE( (sizeof(void *) == 4) && (sizeof(sal_Int32) == 4), "### unexpected size of int!" );
+ OSL_ENSURE( nStackLongs && pStackLongs, "### no stack in callVirtualMethod !" );
+
+ // never called
+ if (! pAdjustedThisPtr) CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
+
+ volatile long edx = 0, eax = 0; // for register returns
+ void * stackptr;
+ asm volatile (
+ "mov %%esp, %6\n\t"
+ // copy values
+ "mov %0, %%eax\n\t"
+ "mov %%eax, %%edx\n\t"
+ "dec %%edx\n\t"
+ "shl $2, %%edx\n\t"
+ "add %1, %%edx\n"
+ "Lcopy:\n\t"
+ "pushl 0(%%edx)\n\t"
+ "sub $4, %%edx\n\t"
+ "dec %%eax\n\t"
+ "jne Lcopy\n\t"
+ // do the actual call
+ "mov %2, %%edx\n\t"
+ "mov 0(%%edx), %%edx\n\t"
+ "mov %3, %%eax\n\t"
+ "shl $2, %%eax\n\t"
+ "add %%eax, %%edx\n\t"
+ "mov 0(%%edx), %%edx\n\t"
+ "call *%%edx\n\t"
+ // save return registers
+ "mov %%eax, %4\n\t"
+ "mov %%edx, %5\n\t"
+ // cleanup stack
+ "mov %6, %%esp\n\t"
+ :
+ : "m"(nStackLongs), "m"(pStackLongs), "m"(pAdjustedThisPtr),
+ "m"(nVtableIndex), "m"(eax), "m"(edx), "m"(stackptr)
+ : "eax", "edx" );
+ switch( eReturnType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ ((long*)pRegisterReturn)[1] = edx;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_ENUM:
+ ((long*)pRegisterReturn)[0] = eax;
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = eax;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = eax;
+ break;
+ case typelib_TypeClass_FLOAT:
+ asm ( "fstps %0" : : "m"(*(char *)pRegisterReturn) );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ asm ( "fstpl %0\n\t" : : "m"(*(char *)pRegisterReturn) );
+ break;
+ }
+}
+
+//==================================================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ char * pCppStack =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ char * pCppStackStart = pCppStack;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack
+ = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ pCppStack += sizeof(void *);
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ try
+ {
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; // get, then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_solaris_sparc/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_solaris_sparc/cpp2uno.cxx
new file mode 100644
index 000000000000..e6b0273b97a9
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_sparc/cpp2uno.cxx
@@ -0,0 +1,567 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <com/sun/star/uno/genfunc.hxx>
+#include <typelib/typedescription.hxx>
+#include <uno/data.h>
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+#include "share.hxx"
+#include <sal/alloca.h>
+
+using namespace com::sun::star::uno;
+
+namespace
+{
+//==================================================================================================
+static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ // pCallStack: [ret ptr], this, params
+ char * pCppStack = (char *)pCallStack;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void**)pCppStack;
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ pCppStack += sizeof( void* );
+ }
+ }
+ // pop this
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr )) // value
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = CPPU_CURRENT_NAMESPACE::adjustPointer(pCppStack, pParamTypeDescr);
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ {
+ if ((reinterpret_cast< long >(pCppStack) & 7) != 0)
+ {
+ OSL_ASSERT( sizeof (double) == sizeof (sal_Int64) );
+ void * pDest = alloca( sizeof (sal_Int64) );
+ *reinterpret_cast< sal_Int32 * >(pDest) =
+ *reinterpret_cast< sal_Int32 const * >(pCppStack);
+ *(reinterpret_cast< sal_Int32 * >(pDest) + 1) =
+ *(reinterpret_cast< sal_Int32 const * >(pCppStack) + 1);
+ pCppArgs[nPos] = pUnoArgs[nPos] = pDest;
+ }
+ pCppStack += sizeof (sal_Int32); // extra long
+ break;
+ }
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ pCppArgs[nPos] = *(void **)pCppStack;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ CPPU_CURRENT_NAMESPACE::raiseException(&aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+
+//==================================================================================================
+static typelib_TypeClass cpp_mediate(
+ sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: this, params
+ // eventual [ret*] lies at pCallStack -1
+ // so count down pCallStack by one to keep it simple
+ // pCallStack: this, params
+ // eventual [ret*] lies at pCallStack -1
+ // so count down pCallStack by one to keep it simple
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ static_cast< char * >(*pCallStack) - nVtableOffset);
+ if ((nFunctionIndex & 0x80000000) != 0) {
+ nFunctionIndex &= 0x7FFFFFFF;
+ --pCallStack;
+ }
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex,
+ "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException( rtl::OUString::createFromAscii("illegal vtable index!"), (XInterface *)pCppI );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+#if defined BRIDGES_DEBUG
+ OString cstr( OUStringToOString( aMemberDescr.get()->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "calling %s, nFunctionIndex=%d\n", cstr.getStr(), nFunctionIndex );
+#endif
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[2] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pCallStack[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = pCallStack[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(rtl::OUString::createFromAscii("no member description found!"), (XInterface *)pCppI );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+ return eRet;
+}
+
+
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static void cpp_vtable_call()
+{
+ volatile sal_Int64 nRegReturn;
+ int nFunctionIndex;
+ void** pCallStack;
+ int vTableOffset;
+
+ __asm__( "st %%i0, %0\n\t"
+ "st %%i1, %1\n\t"
+ "st %%i2, %2\n\t"
+ : : "m"(nFunctionIndex), "m"(pCallStack), "m"(vTableOffset) );
+
+// fprintf(stderr,"cpp_mediate nFunctionIndex=%x\n",nFunctionIndex);
+// fflush(stderr);
+
+ sal_Bool bComplex = nFunctionIndex & 0x80000000 ? sal_True : sal_False;
+ typelib_TypeClass aType =
+ cpp_mediate( nFunctionIndex, vTableOffset, pCallStack+17, (sal_Int64*)&nRegReturn );
+
+ switch( aType )
+ {
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ __asm__( "ld %0, %%l0\n\t"
+ "ldsb [%%l0], %%i0\n"
+ : : "m"(&nRegReturn) );
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ __asm__( "ld %0, %%l0\n\t"
+ "ldsh [%%l0], %%i0\n"
+ : : "m"(&nRegReturn) );
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+
+ __asm__( "ld %0, %%l0\n\t"
+ "ld [%%l0], %%i0\n\t"
+ "ld %1, %%l0\n\t"
+ "ld [%%l0], %%i1\n\t"
+ : : "m"(&nRegReturn), "m"(((long*)&nRegReturn) +1) );
+
+ break;
+ case typelib_TypeClass_FLOAT:
+ __asm__( "ld %0, %%l0\n\t"
+ "ld [%%l0], %%f0\n"
+ : : "m"(&nRegReturn) );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ __asm__( "ld %0, %%l0\n\t"
+ "ldd [%%l0], %%f0\n"
+ : : "m"(&nRegReturn) );
+ break;
+ case typelib_TypeClass_VOID:
+ break;
+ default:
+ __asm__( "ld %0, %%l0\n\t"
+ "ld [%%l0], %%i0\n"
+ : : "m"(&nRegReturn) );
+ break;
+ }
+
+ if( bComplex )
+ {
+ __asm__( "add %i7, 4, %i7\n\t" );
+ // after call to complex return valued funcion there is an unimp instruction
+ }
+
+}
+//__________________________________________________________________________________________________
+
+int const codeSnippetSize = 56;
+unsigned char * codeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ bool simpleRetType)
+{
+ sal_uInt32 index = functionIndex;
+ if (!simpleRetType) {
+ index |= 0x80000000;
+ }
+ unsigned int * p = reinterpret_cast< unsigned int * >(code);
+ OSL_ASSERT(sizeof (unsigned int) == 4);
+ // st %o0, [%sp+68]:
+ *p++ = 0xD023A044;
+ // st %o1, [%sp+72]:
+ *p++ = 0xD223A048;
+ // st %o2, [%sp+76]:
+ *p++ = 0xD423A04C;
+ // st %o3, [%sp+80]:
+ *p++ = 0xD623A050;
+ // st %o4, [%sp+84]:
+ *p++ = 0xD823A054;
+ // st %o5, [%sp+88]:
+ *p++ = 0xDA23A058;
+ // sethi %hi(index), %o0:
+ *p++ = 0x11000000 | (index >> 10);
+ // or %o0, %lo(index), %o0:
+ *p++ = 0x90122000 | (index & 0x3FF);
+ // sethi %hi(vtableOffset), %o2:
+ *p++ = 0x15000000 | (vtableOffset >> 10);
+ // or %o2, %lo(vtableOffset), %o2:
+ *p++ = 0x9412A000 | (vtableOffset & 0x3FF);
+ // sethi %hi(cpp_vtable_call), %o3:
+ *p++ = 0x17000000 | (reinterpret_cast< unsigned int >(cpp_vtable_call) >> 10);
+ // or %o3, %lo(cpp_vtable_call), %o3:
+ *p++ = 0x9612E000 | (reinterpret_cast< unsigned int >(cpp_vtable_call) & 0x3FF);
+ // jmpl %o3, %g0:
+ *p++ = 0x81C2C000;
+ // mov %sp, %o1:
+ *p++ = 0x9210000E;
+ OSL_ASSERT(
+ reinterpret_cast< unsigned char * >(p) - code <= codeSnippetSize);
+ return code + codeSnippetSize;
+}
+
+} //end of namespace
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0; //null
+ slots[-1].fn = 0; //destructor
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vTableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vTableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef));
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vTableOffset, true);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vTableOffset,
+ bridges::cpp_uno::shared::isSimpleType(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const *, unsigned char const *)
+ {
+ //TODO: IZ 25819 flush the instruction cache (there probably is OS support for this)
+ }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_solaris_sparc/except.cxx b/bridges/source/cpp_uno/gcc3_solaris_sparc/except.cxx
new file mode 100644
index 000000000000..8d0be02e7d93
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_sparc/except.cxx
@@ -0,0 +1,329 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <stdio.h>
+#include <dlfcn.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * )
+{
+}
+
+//==================================================================================================
+static OUString toUNOname( char const * p ) SAL_THROW( () )
+{
+#if defined BRIDGES_DEBUG
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if defined BRIDGES_DEBUG
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+}
+
+//==================================================================================================
+class RTTI
+{
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+ void * m_hApp;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+ : m_hApp( dlopen( 0, RTLD_LAZY ) )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+ dlclose( m_hApp );
+}
+
+//__________________________________________________________________________________________________
+type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+{
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
+ if (iFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ rtti = (type_info *)dlsym( m_hApp, symName.getStr() );
+
+ if (rtti)
+ {
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
+ }
+ else
+ {
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
+ if (iFind == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with _ZTI
+ char const * rttiName = symName.getStr() +4;
+#if defined BRIDGES_DEBUG
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iFind->second;
+ }
+ }
+ }
+ else
+ {
+ rtti = iFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void deleteException( void * pExc )
+{
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+#if defined BRIDGES_DEBUG
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() );
+#endif
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get typedescription for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+{
+ if (! header)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if defined _DEBUG
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+#if defined BRIDGES_DEBUG
+ OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if defined _DEBUG
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_solaris_sparc/makefile.mk b/bridges/source/cpp_uno/gcc3_solaris_sparc/makefile.mk
new file mode 100644
index 000000000000..2fcc5fbdd8d8
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_sparc/makefile.mk
@@ -0,0 +1,77 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)$(OS)$(CPU)" == "GCCSOLARISS"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+
+CFLAGSNOOPT=-O0
+
+NOOPTFILES = \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/cpp2uno.obj
+
+SLOFILES= \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj
+
+
+SHL1TARGET=$(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS= $(SLOFILES)
+SHL1LIBS =$(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/gcc3_solaris_sparc/share.hxx b/bridges/source/cpp_uno/gcc3_solaris_sparc/share.hxx
new file mode 100644
index 000000000000..3526f19082cd
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_sparc/share.hxx
@@ -0,0 +1,100 @@
+/* -*- 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 "uno/mapping.h"
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+namespace CPPU_CURRENT_NAMESPACE
+{
+void dummy_can_throw_anything( char const * );
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+
+inline char* adjustPointer( char* pIn, typelib_TypeDescription* pType )
+{
+ switch( pType->nSize )
+ {
+ case 1: return pIn + 3;
+ case 2: return pIn + 2;
+ case 3: return pIn + 1;
+ // Huh ? perhaps a char[3] ? Though that would be a pointer
+ // well, we have it anyway for symmetry
+ }
+ return pIn;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_solaris_sparc/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_solaris_sparc/uno2cpp.cxx
new file mode 100644
index 000000000000..b1c2767609f4
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_solaris_sparc/uno2cpp.cxx
@@ -0,0 +1,598 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <malloc.h>
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "share.hxx"
+
+#include <sal/alloca.h>
+
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+namespace
+{
+//==================================================================================================
+// The call instruction within the asm section of callVirtualMethod may throw
+// exceptions. So that the compiler handles this correctly, it is important
+// that (a) callVirtualMethod might call dummy_can_throw_anything (although this
+// never happens at runtime), which in turn can throw exceptions, and (b)
+// callVirtualMethod is not inlined at its call site (so that any exceptions are
+// caught which are thrown from the instruction calling callVirtualMethod):
+
+void callVirtualMethod( void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs ) __attribute__((noinline));
+
+void callVirtualMethod( void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs )
+{
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ OSL_ENSURE( pStackLongs && pAdjustedThisPtr, "### null ptr!" );
+ OSL_ENSURE( (sizeof(void *) == 4) &&
+ (sizeof(sal_Int32) == 4), "### unexpected size of int!" );
+ OSL_ENSURE( nStackLongs && pStackLongs, "### no stack in callVirtualMethod !" );
+
+ // never called
+ if (! pAdjustedThisPtr) CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
+
+ volatile long o0 = 0, o1 = 0; // for register returns
+ volatile double f0d = 0;
+ volatile float f0f = 0;
+ volatile long long saveReg[7];
+
+ __asm__ (
+ // save registers
+ "std %%l0, [%4]\n\t"
+ "mov %4, %%l0\n\t"
+ "mov %%l0, %%l1\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%l2, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%l4, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%o0, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%o2, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%o4, [%%l0]\n\t"
+ "add %%l0, 8, %%l0\n\t"
+ "std %%l6, [%%l0]\n\t"
+ "mov %%l1, %%l7\n\t"
+
+ // increase our own stackframe if necessary
+ "mov %%sp, %%l3\n\t" // save stack ptr for readjustment
+
+ "subcc %%i5, 7, %%l0\n\t"
+ "ble .LmoveOn\n\t"
+ "nop\n\t"
+
+ "sll %%l0, 2, %%l0\n\t"
+ "add %%l0, 96, %%l0\n\t"
+ "mov %%sp, %%l1\n\t" // old stack ptr
+ "sub %%sp, %%l0, %%l0\n\t" // future stack ptr
+ "andcc %%l0, 7, %%g0\n\t" // align stack to 8
+ "be .LisAligned\n\t"
+ "nop\n\t"
+ "sub %%l0, 4, %%l0\n"
+ ".LisAligned:\n\t"
+ "mov %%l0, %%o5\n\t" // save newly computed stack ptr
+ "add %%g0, 16, %%o4\n"
+
+ // now copy longs down to save register window
+ // and local variables
+ ".LcopyDown:\n\t"
+ "ld [%%l1], %%l2\n\t"
+ "st %%l2,[%%l0]\n\t"
+ "add %%l0, 4, %%l0\n\t"
+ "add %%l1, 4, %%l1\n\t"
+ "subcc %%o4, 1, %%o4\n\t"
+ "bne .LcopyDown\n\t"
+
+ "mov %%o5, %%sp\n\t" // move new stack ptr (hopefully) atomically
+ // while register window is valid in both spaces
+ // (scheduling might hit in copyDown loop)
+
+ "sub %%i5, 7, %%l0\n\t" // copy parameters past the sixth to stack
+ "add %%i4, 28, %%l1\n\t"
+ "add %%sp, 92, %%l2\n"
+ ".LcopyLong:\n\t"
+ "ld [%%l1], %%o0\n\t"
+ "st %%o0, [%%l2]\n\t"
+ "add %%l1, 4, %%l1\n\t"
+ "add %%l2, 4, %%l2\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "bne .LcopyLong\n\t"
+ "nop\n"
+
+ ".LmoveOn:\n\t"
+ "mov %%i5, %%l0\n\t" // prepare out registers
+ "mov %%i4, %%l1\n\t"
+
+ "ld [%%l1], %%o0\n\t" // prepare complex return ptr
+ "st %%o0, [%%sp+64]\n\t"
+ "sub %%l0, 1, %%l0\n\t"
+ "add %%l1, 4, %%l1\n\t"
+
+ "ld [%%l1], %%o0\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o1\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o2\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o3\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o4\n\t"
+ "subcc %%l0, 1, %%l0\n\t"
+ "be .LdoCall\n\t"
+ "nop\n\t"
+
+ "add %%l1, 4, %%l1\n\t"
+ "ld [%%l1], %%o5\n"
+
+ ".LdoCall:\n\t"
+ "ld [%%i0], %%l0\n\t" // get vtable ptr
+
+"sll %%i1, 2, %%l6\n\t"
+// "add %%l6, 8, %%l6\n\t"
+ "add %%l6, %%l0, %%l0\n\t"
+// // vtable has 8byte wide entries,
+// // upper half contains 2 half words, of which the first
+// // is the this ptr patch !
+// // first entry is (or __tf)
+
+// "ldsh [%%l0], %%l6\n\t" // load this ptr patch
+// "add %%l6, %%o0, %%o0\n\t" // patch this ptr
+
+// "add %%l0, 4, %%l0\n\t" // get virtual function ptr
+ "ld [%%l0], %%l0\n\t"
+
+ "ld [%%i4], %%l2\n\t"
+ "subcc %%l2, %%g0, %%l2\n\t"
+ "bne .LcomplexCall\n\t"
+ "nop\n\t"
+ "call %%l0\n\t"
+ "nop\n\t"
+ "ba .LcallReturned\n\t"
+ "nop\n"
+ ".LcomplexCall:\n\t"
+ "call %%l0\n\t"
+ "nop\n\t"
+ "unimp\n"
+
+ ".LcallReturned:\n\t"
+ "mov %%l3, %%sp\n\t" // readjust stack so that our locals are where they belong
+ "st %%o0, %0\n\t" // save possible return registers into our locals
+ "st %%o1, %1\n\t"
+ "std %%f0, %2\n\t"
+ "st %%f0, %3\n\t"
+
+ // restore registers
+ "ldd [%%l7], %%l0\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%l2\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%l4\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%o0\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%o2\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%o4\n\t"
+ "add %%l7, 8, %%l7\n\t"
+ "ldd [%%l7], %%l6\n\t"
+ : :
+ "m"(o0),
+ "m"(o1),
+ "m"(f0d),
+ "m"(f0f),
+ "r"(&saveReg[0])
+ );
+ switch( eReturnType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ ((long*)pRegisterReturn)[1] = o1;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ ((long*)pRegisterReturn)[0] = o0;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = (unsigned short)o0;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = (unsigned char)o0;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float*)pRegisterReturn = f0f;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double*)pRegisterReturn = f0d;
+ break;
+ }
+}
+
+//=================================================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: complex ret ptr, this, values|ptr ...
+ char * pCppStack =
+ (char *)alloca( (nParams+2) * sizeof(sal_Int64) );
+ char * pCppStackStart = pCppStack;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ *(void**)pCppStack = NULL;
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack = (bridges::cpp_uno::shared::relatesToInterfaceType(pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ }
+ pCppStack += sizeof(void*);
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ pCppArgs[ nPos ] = CPPU_CURRENT_NAMESPACE::adjustPointer(pCppStack, pParamTypeDescr );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ OSL_ASSERT( sizeof (double) == sizeof (sal_Int64) );
+ *reinterpret_cast< sal_Int32 * >(pCppStack) =
+ *reinterpret_cast< sal_Int32 const * >(pUnoArgs[ nPos ]);
+ pCppStack += sizeof (sal_Int32);
+ *reinterpret_cast< sal_Int32 * >(pCppStack) =
+ *(reinterpret_cast< sal_Int32 const * >(pUnoArgs[ nPos ] ) + 1);
+ break;
+ default:
+ uno_copyAndConvertData(
+ pCppArgs[nPos], pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ try
+ {
+ int nStackLongs = (pCppStack - pCppStackStart)/sizeof(sal_Int32);
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic" );
+
+ if( nStackLongs & 1 )
+ // stack has to be 8 byte aligned
+ nStackLongs++;
+ callVirtualMethod(
+ pAdjustedThisPtr,
+ aVtableSlot.index,
+ pCppReturn,
+ pReturnTypeDescr->eTypeClass,
+ (sal_Int32 *)pCppStackStart,
+ nStackLongs);
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch( ... )
+ {
+ // get exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions,
+ *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+#if defined BRIDGES_DEBUG
+ OString cstr( OUStringToOString( pMemberDescr->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "received dispatch( %s )\n", cstr.getStr() );
+#endif
+
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; // get, then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/mingw_intel/call.s b/bridges/source/cpp_uno/mingw_intel/call.s
new file mode 100644
index 000000000000..47327d9a4650
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_intel/call.s
@@ -0,0 +1,261 @@
+ .text
+
+.globl _privateSnippetExecutorGeneral
+_privateSnippetExecutorGeneral:
+.LFBg:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+.LCFIg0:
+ movl %esp,%ebp
+.LCFIg1:
+ subl $0x4,%esp # 32bit returnValue
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call _cpp_vtable_call
+ movl 16(%esp),%eax # 32bit returnValue
+ leave
+ ret
+.LFEg:
+ .long .-_privateSnippetExecutorGeneral
+
+.globl _privateSnippetExecutorVoid
+_privateSnippetExecutorVoid:
+.LFBv:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+.LCFIv0:
+ movl %esp,%ebp
+.LCFIv1:
+ pushl $0 # 32bit null pointer (returnValue not used)
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call _cpp_vtable_call
+ leave
+ ret
+.LFEv:
+ .long .-_privateSnippetExecutorVoid
+
+.globl _privateSnippetExecutorHyper
+_privateSnippetExecutorHyper:
+.LFBh:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+.LCFIh0:
+ movl %esp,%ebp
+.LCFIh1:
+ subl $0x8,%esp # 64bit returnValue
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call _cpp_vtable_call
+ movl 16(%esp),%eax # 64bit returnValue, lower half
+ movl 20(%esp),%edx # 64bit returnValue, upper half
+ leave
+ ret
+.LFEh:
+ .long .-_privateSnippetExecutorHyper
+
+.globl _privateSnippetExecutorFloat
+_privateSnippetExecutorFloat:
+.LFBf:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+.LCFIf0:
+ movl %esp,%ebp
+.LCFIf1:
+ subl $0x4,%esp # 32bit returnValue
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call _cpp_vtable_call
+ flds 16(%esp) # 32bit returnValue
+ leave
+ ret
+.LFEf:
+ .long .-_privateSnippetExecutorFloat
+
+.globl _privateSnippetExecutorDouble
+_privateSnippetExecutorDouble:
+.LFBd:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+.LCFId0:
+ movl %esp,%ebp
+.LCFId1:
+ subl $0x8,%esp # 64bit returnValue
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call _cpp_vtable_call
+ fldl 16(%esp) # 64bit returnValue
+ leave
+ ret
+.LFEd:
+ .long .-_privateSnippetExecutorDouble
+
+.globl _privateSnippetExecutorClass
+_privateSnippetExecutorClass:
+.LFBc:
+ movl %esp,%ecx
+ pushl %ebp # proper stack frame needed for exception handling
+.LCFIc0:
+ movl %esp,%ebp
+.LCFIc1:
+ subl $0x4,%esp # 32bit returnValue
+ pushl %esp # 32bit &returnValue
+ pushl %ecx # 32bit pCallStack
+ pushl %edx # 32bit nVtableOffset
+ pushl %eax # 32bit nFunctionIndex
+ call _cpp_vtable_call
+ movl 16(%esp),%eax # 32bit returnValue
+ leave
+ ret $4
+.LFEc:
+ .long .-_privateSnippetExecutorClass
+
+ .section .eh_frame,"dr"
+.Lframe1:
+ .long .LECIE1-.LSCIE1 # length
+.LSCIE1:
+ .long 0 # CIE_ID
+ .byte 1 # version
+ .string "zR" # augmentation
+ .uleb128 1 # code_alignment_factor
+ .sleb128 -4 # data_alignment_factor
+ .byte 8 # return_address_register
+ .uleb128 1 # augmentation size 1:
+ .byte 0x1B # FDE Encoding (pcrel sdata4)
+ # initial_instructions:
+ .byte 0x0C # DW_CFA_def_cfa %esp, 4
+ .uleb128 4
+ .uleb128 4
+ .byte 0x88 # DW_CFA_offset ret, 1
+ .uleb128 1
+ .align 4
+.LECIE1:
+.LSFDEg:
+ .long .LEFDEg-.LASFDEg # length
+.LASFDEg:
+ .long .LASFDEg-.Lframe1 # CIE_pointer
+ .long .LFBg-. # initial_location
+ .long .LFEg-.LFBg # address_range
+ .uleb128 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIg0-.LFBg
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .uleb128 8
+ .byte 0x85 # DW_CFA_offset %ebp, 2
+ .uleb128 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIg1-.LCFIg0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .uleb128 5
+ .align 4
+.LEFDEg:
+.LSFDEv:
+ .long .LEFDEv-.LASFDEv # length
+.LASFDEv:
+ .long .LASFDEv-.Lframe1 # CIE_pointer
+ .long .LFBv-. # initial_location
+ .long .LFEv-.LFBv # address_range
+ .uleb128 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIv0-.LFBv
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .uleb128 8
+ .byte 0x85 # DW_CFA_offset %ebp, 2
+ .uleb128 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIv1-.LCFIv0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .uleb128 5
+ .align 4
+.LEFDEv:
+.LSFDEh:
+ .long .LEFDEh-.LASFDEh # length
+.LASFDEh:
+ .long .LASFDEh-.Lframe1 # CIE_pointer
+ .long .LFBh-. # initial_location
+ .long .LFEh-.LFBh # address_range
+ .uleb128 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIh0-.LFBh
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .uleb128 8
+ .byte 0x85 # DW_CFA_offset %ebp, 2
+ .uleb128 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIh1-.LCFIh0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .uleb128 5
+ .align 4
+.LEFDEh:
+.LSFDEf:
+ .long .LEFDEf-.LASFDEf # length
+.LASFDEf:
+ .long .LASFDEf-.Lframe1 # CIE_pointer
+ .long .LFBf-. # initial_location
+ .long .LFEf-.LFBf # address_range
+ .uleb128 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIf0-.LFBf
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .uleb128 8
+ .byte 0x85 # DW_CFA_offset %ebp, 2
+ .uleb128 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIf1-.LCFIf0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .uleb128 5
+ .align 4
+.LEFDEf:
+.LSFDEd:
+ .long .LEFDEd-.LASFDEd # length
+.LASFDEd:
+ .long .LASFDEd-.Lframe1 # CIE_pointer
+ .long .LFBd-. # initial_location
+ .long .LFEd-.LFBd # address_range
+ .uleb128 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFId0-.LFBd
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .uleb128 8
+ .byte 0x85 # DW_CFA_offset %ebp, 2
+ .uleb128 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFId1-.LCFId0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .uleb128 5
+ .align 4
+.LEFDEd:
+.LSFDEc:
+ .long .LEFDEc-.LASFDEc # length
+.LASFDEc:
+ .long .LASFDEc-.Lframe1 # CIE_pointer
+ .long .LFBc-. # initial_location
+ .long .LFEc-.LFBc # address_range
+ .uleb128 0 # augmentation size 0
+ # instructions:
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIc0-.LFBc
+ .byte 0x0E # DW_CFA_def_cfa_offset 8
+ .uleb128 8
+ .byte 0x85 # DW_CFA_offset %ebp, 2
+ .uleb128 2
+ .byte 0x04 # DW_CFA_advance_loc4
+ .long .LCFIc1-.LCFIc0
+ .byte 0x0D # DW_CFA_def_cfa_register %ebp
+ .uleb128 5
+ .align 4
+.LEFDEc:
diff --git a/bridges/source/cpp_uno/mingw_intel/cpp2uno.cxx b/bridges/source/cpp_uno/mingw_intel/cpp2uno.cxx
new file mode 100644
index 000000000000..cd74da7462df
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_intel/cpp2uno.cxx
@@ -0,0 +1,521 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+#include <sal/alloca.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "share.hxx"
+#include "smallstruct.hxx"
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+void cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** pCallStack,
+ void * pReturnValue )
+{
+ // pCallStack: ret, [return ptr], this, params
+ char * pCppStack = (char *)(pCallStack +1);
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pReturnValue; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ if (!bridges::cpp_uno::shared::isSmallStruct(pReturnTypeDescr)) {
+ pCppReturn = *(void **)pCppStack;
+ pCppStack += sizeof(void *);
+ }
+ else {
+ pCppReturn = pReturnValue;
+ }
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+ // pop this
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ // value
+ {
+ pCppArgs[nPos] = pCppStack;
+ pUnoArgs[nPos] = pCppStack;
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ break;
+ default:
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ pCppArgs[nPos] = *(void **)pCppStack;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException(
+ &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ if (pReturnValue != pCppReturn)
+ // complex return ptr is set to eax
+ *static_cast< void ** >(pReturnValue) = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+ }
+}
+
+
+//==================================================================================================
+extern "C" void cpp_vtable_call(
+ int nFunctionIndex, int nVtableOffset, void** pCallStack,
+ void * pReturnValue )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: ret adr, [ret *], this, params
+ void * pThis;
+ if( nFunctionIndex & 0x80000000 )
+ {
+ nFunctionIndex &= 0x7fffffff;
+ pThis = pCallStack[2];
+ }
+ else
+ {
+ pThis = pCallStack[1];
+ }
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("illegal vtable index!"),
+ (XInterface *)pThis );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pReturnValue );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pReturnValue );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[3] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pCallStack[1] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *static_cast< void ** >(pReturnValue) = pCallStack[1];
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pReturnValue );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString::createFromAscii("no member description found!"),
+ (XInterface *)pThis );
+ }
+ }
+}
+
+//==================================================================================================
+extern "C" void privateSnippetExecutorGeneral();
+extern "C" void privateSnippetExecutorVoid();
+extern "C" void privateSnippetExecutorHyper();
+extern "C" void privateSnippetExecutorFloat();
+extern "C" void privateSnippetExecutorDouble();
+extern "C" void privateSnippetExecutorClass();
+extern "C" typedef void (*PrivateSnippetExecutor)();
+
+int const codeSnippetSize = 16;
+
+unsigned char * codeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset,
+ typelib_TypeDescriptionReference * returnType)
+{
+ typelib_TypeDescription * returnTypeDescr = 0;
+ if (returnType)
+ TYPELIB_DANGER_GET( &returnTypeDescr, returnType );
+
+ typelib_TypeClass returnTypeClass = returnType ? returnType->eTypeClass : typelib_TypeClass_VOID;
+ if (!bridges::cpp_uno::shared::isSimpleType(returnTypeClass) &&
+ !bridges::cpp_uno::shared::isSmallStruct(returnTypeDescr)) {
+ functionIndex |= 0x80000000;
+ }
+ PrivateSnippetExecutor exec;
+ switch (returnTypeClass) {
+ case typelib_TypeClass_VOID:
+ exec = privateSnippetExecutorVoid;
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ exec = privateSnippetExecutorHyper;
+ break;
+ case typelib_TypeClass_FLOAT:
+ exec = privateSnippetExecutorFloat;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ exec = privateSnippetExecutorDouble;
+ break;
+ case typelib_TypeClass_STRUCT:
+ if (bridges::cpp_uno::shared::isSmallStruct(returnTypeDescr)) {
+ if (returnType->pType->nSize <= 4) {
+ exec = privateSnippetExecutorGeneral;
+ }
+ else if (returnType->pType->nSize <= 8) {
+ exec = privateSnippetExecutorHyper;
+ }
+ }
+ else {
+ exec = privateSnippetExecutorClass;
+ }
+ break;
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_INTERFACE:
+ exec = privateSnippetExecutorClass;
+ break;
+ default:
+ exec = privateSnippetExecutorGeneral;
+ break;
+ }
+ if (returnType)
+ TYPELIB_DANGER_RELEASE( returnTypeDescr );
+ unsigned char * p = code;
+ OSL_ASSERT(sizeof (sal_Int32) == 4);
+ // mov function_index, %eax:
+ *p++ = 0xB8;
+ *reinterpret_cast< sal_Int32 * >(p) = functionIndex;
+ p += sizeof (sal_Int32);
+ // mov vtable_offset, %edx:
+ *p++ = 0xBA;
+ *reinterpret_cast< sal_Int32 * >(p) = vtableOffset;
+ p += sizeof (sal_Int32);
+ // jmp privateSnippetExecutor:
+ *p++ = 0xE9;
+ *reinterpret_cast< sal_Int32 * >(p)
+ = ((unsigned char *) exec) - p - sizeof (sal_Int32);
+ p += sizeof (sal_Int32);
+ OSL_ASSERT(p - code <= codeSnippetSize);
+ return code + codeSnippetSize;
+}
+
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0;
+ slots[-1].fn = 0;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code,
+ typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for (sal_Int32 i = 0; i < type->nMembers; ++i) {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ OSL_ASSERT(member != 0);
+ switch (member->eTypeClass) {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ // Getter:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >(
+ member)->pAttributeTypeRef);
+ // Setter:
+ if (!reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member)->bReadOnly)
+ {
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ NULL);
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE_METHOD:
+ (s++)->fn = code;
+ code = codeSnippet(
+ code, functionOffset++, vtableOffset,
+ reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
+ member)->pReturnTypeRef);
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const *, unsigned char const *)
+{}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/mingw_intel/dllinit.cxx b/bridges/source/cpp_uno/mingw_intel/dllinit.cxx
new file mode 100644
index 000000000000..d215a3124470
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_intel/dllinit.cxx
@@ -0,0 +1,59 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+
+#include <windows.h>
+
+
+void dso_init(void);
+void dso_exit(void);
+
+
+extern "C" BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpvReserved)
+{
+ switch(dwReason) {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hModule);
+
+ dso_init();
+ break;
+
+ case DLL_PROCESS_DETACH:
+ if (!lpvReserved)
+ dso_exit();
+ break;
+ }
+
+ return TRUE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/mingw_intel/except.cxx b/bridges/source/cpp_uno/mingw_intel/except.cxx
new file mode 100644
index 000000000000..7a4aca8b1b4d
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_intel/except.cxx
@@ -0,0 +1,316 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <string.h>
+#include <cxxabi.h>
+#include <hash_map>
+
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+
+#include "share.hxx"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::__cxxabiv1;
+
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * )
+{
+}
+
+//==================================================================================================
+static OUString toUNOname( char const * p ) SAL_THROW( () )
+{
+#if OSL_DEBUG_LEVEL > 1
+ char const * start = p;
+#endif
+
+ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
+
+ OUStringBuffer buf( 64 );
+ OSL_ASSERT( 'N' == *p );
+ ++p; // skip N
+
+ while ('E' != *p)
+ {
+ // read chars count
+ long n = (*p++ - '0');
+ while ('0' <= *p && '9' >= *p)
+ {
+ n *= 10;
+ n += (*p++ - '0');
+ }
+ buf.appendAscii( p, n );
+ p += n;
+ if ('E' != *p)
+ buf.append( (sal_Unicode)'.' );
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ OUString ret( buf.makeStringAndClear() );
+ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
+ return ret;
+#else
+ return buf.makeStringAndClear();
+#endif
+}
+
+//==================================================================================================
+class RTTI
+{
+ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
+
+ Mutex m_mutex;
+ t_rtti_map m_rttis;
+ t_rtti_map m_generatedRttis;
+
+public:
+ RTTI() SAL_THROW( () );
+ ~RTTI() SAL_THROW( () );
+
+ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+RTTI::RTTI() SAL_THROW( () )
+{
+}
+//__________________________________________________________________________________________________
+RTTI::~RTTI() SAL_THROW( () )
+{
+}
+
+//__________________________________________________________________________________________________
+type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
+{
+ type_info * rtti;
+
+ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
+
+ MutexGuard guard( m_mutex );
+ t_rtti_map::const_iterator iRttiFind( m_rttis.find( unoName ) );
+ if (iRttiFind == m_rttis.end())
+ {
+ // RTTI symbol
+ OStringBuffer buf( 64 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM("__ZTIN") );
+ sal_Int32 index = 0;
+ do
+ {
+ OUString token( unoName.getToken( 0, '.', index ) );
+ buf.append( token.getLength() );
+ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
+ buf.append( c_token );
+ }
+ while (index >= 0);
+ buf.append( 'E' );
+
+ OString symName( buf.makeStringAndClear() );
+ // try to lookup the symbol in the generated rtti map
+ t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
+ if (iFind == m_generatedRttis.end())
+ {
+ // we must generate it !
+ // symbol and rtti-name is nearly identical,
+ // the symbol is prefixed with __ZTI
+ char const * rttiName = symName.getStr() +5;
+#if OSL_DEBUG_LEVEL > 1
+ fprintf( stderr,"generated rtti for %s\n", rttiName );
+#endif
+ if (pTypeDescr->pBaseTypeDescription)
+ {
+ // ensure availability of base
+ type_info * base_rtti = getRTTI(
+ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
+ rtti = new __si_class_type_info(
+ strdup( rttiName ), (__class_type_info *)base_rtti );
+ }
+ else
+ {
+ // this class has no base class
+ rtti = new __class_type_info( strdup( rttiName ) );
+ }
+
+ pair< t_rtti_map::iterator, bool > insertion(
+ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
+ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
+ }
+ else // taking already generated rtti
+ {
+ rtti = iFind->second;
+ }
+ }
+ else
+ {
+ rtti = iRttiFind->second;
+ }
+
+ return rtti;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void deleteException( void * pExc )
+{
+ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
+ typelib_TypeDescription * pTD = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+ ::typelib_typedescription_getByName( &pTD, unoName.pData );
+ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
+ if (pTD)
+ {
+ ::uno_destructData( pExc, pTD, cpp_release );
+ ::typelib_typedescription_release( pTD );
+ }
+}
+
+//==================================================================================================
+void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr(
+ OUStringToOString(
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() );
+#endif
+ void * pCppExc;
+ type_info * rtti;
+
+ {
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+ OSL_ASSERT( pTypeDescr );
+ if (! pTypeDescr)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get typedescription for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+
+ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ // avoiding locked counts
+ static RTTI * s_rtti = 0;
+ if (! s_rtti)
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_rtti)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_rtti = new RTTI();
+#else
+ static RTTI rtti_data;
+ s_rtti = &rtti_data;
+#endif
+ }
+ }
+ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
+ if (! rtti)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
+ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
+ Reference< XInterface >() );
+ }
+ }
+
+ __cxa_throw( pCppExc, rtti, deleteException );
+}
+
+//==================================================================================================
+void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+{
+ if (! header)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ return;
+ }
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ OUString unoName( toUNOname( header->exceptionType->name() ) );
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
+ fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() );
+#endif
+ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
+ if (0 == pExcTypeDescr)
+ {
+ RuntimeException aRE(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName,
+ Reference< XInterface >() );
+ Type const & rType = ::getCppuType( &aRE );
+ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr.getStr() );
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/mingw_intel/makefile.mk b/bridges/source/cpp_uno/mingw_intel/makefile.mk
new file mode 100644
index 000000000000..2c7a8da48527
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_intel/makefile.mk
@@ -0,0 +1,91 @@
+#*************************************************************************
+#
+# 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=gcc3_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+.IF "$(COM)" == "GCC"
+
+.IF "$(cppu_no_leak)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+.IF "$(EXCEPTIONS)" == "sjlj"
+CFLAGS += -DBROKEN_ALLOCA
+.ENDIF
+
+# In case someone enabled the non-standard -fomit-frame-pointer which does not
+# work with the .cxx sources in this directory:
+CFLAGSCXX += -fno-omit-frame-pointer
+
+NOOPTFILES= \
+ $(SLO)$/uno2cpp.obj
+
+CFLAGSNOOPT=-O0
+
+SLOFILES= \
+ $(SLO)$/dllinit.obj \
+ $(SLO)$/smallstruct.obj \
+ $(SLO)$/except.obj \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/call.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+DEF1NAME= $(SHL1TARGET)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+$(SLO)$/%.obj: %.s
+ $(CC) -c -o $(SLO)$/$(@:b).obj $<
+ touch $@
diff --git a/bridges/source/cpp_uno/mingw_intel/share.hxx b/bridges/source/cpp_uno/mingw_intel/share.hxx
new file mode 100644
index 000000000000..da2367ad172b
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_intel/share.hxx
@@ -0,0 +1,93 @@
+/* -*- 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 "uno/mapping.h"
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * );
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/mingw_intel/smallstruct.cxx b/bridges/source/cpp_uno/mingw_intel/smallstruct.cxx
new file mode 100644
index 000000000000..bcfb0df87902
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_intel/smallstruct.cxx
@@ -0,0 +1,82 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "bridges/cpp_uno/shared/types.hxx"
+
+#include "typelib/typeclass.h"
+#include "typelib/typedescription.h"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+namespace {
+bool isSimpleStruct(typelib_TypeDescription const * type) {
+ switch (type->eTypeClass) {
+ case typelib_TypeClass_STRUCT:
+ {
+ typelib_CompoundTypeDescription const * p
+ = reinterpret_cast< typelib_CompoundTypeDescription const * >(
+ type);
+ for (sal_Int32 i = 0; i < p->nMembers; ++i) {
+ switch (p->ppTypeRefs[i]->eTypeClass) {
+ case typelib_TypeClass_STRUCT:
+ {
+ typelib_TypeDescription * t = 0;
+ TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
+ bool b = isSimpleStruct(t);
+ TYPELIB_DANGER_RELEASE(t);
+ if (!b) {
+ return false;
+ }
+ }
+ break;
+
+ default:
+ if (!isSimpleType(p->ppTypeRefs[i]->eTypeClass))
+ return false;
+ break;
+ }
+ }
+ }
+ return true;
+
+ default:
+ return false;
+ }
+}
+}
+
+bool isSmallStruct(typelib_TypeDescription const * type) {
+ return (type->nSize <= 8 && isSimpleStruct(type));
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/mingw_intel/smallstruct.hxx b/bridges/source/cpp_uno/mingw_intel/smallstruct.hxx
new file mode 100644
index 000000000000..f1eae96e6734
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_intel/smallstruct.hxx
@@ -0,0 +1,38 @@
+/* -*- 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 "typelib/typeclass.h"
+#include "typelib/typedescription.h"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+bool isSmallStruct(typelib_TypeDescription const * type);
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/mingw_intel/uno2cpp.cxx b/bridges/source/cpp_uno/mingw_intel/uno2cpp.cxx
new file mode 100644
index 000000000000..cbbe1312c464
--- /dev/null
+++ b/bridges/source/cpp_uno/mingw_intel/uno2cpp.cxx
@@ -0,0 +1,503 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include <uno/data.h>
+#include <sal/alloca.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "share.hxx"
+#include "smallstruct.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+// The call instruction within the asm section of callVirtualMethod may throw
+// exceptions. So that the compiler handles this correctly, it is important
+// that (a) callVirtualMethod might call dummy_can_throw_anything (although this
+// never happens at runtime), which in turn can throw exceptions, and (b)
+// callVirtualMethod is not inlined at its call site (so that any exceptions are
+// caught which are thrown from the instruction calling callVirtualMethod):
+void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeDescription const * returnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs ) __attribute__((noinline));
+
+void callVirtualMethod(
+ void * pAdjustedThisPtr,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeDescription const * returnType,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs )
+{
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ OSL_ENSURE( pStackLongs && pAdjustedThisPtr, "### null ptr!" );
+ OSL_ENSURE( (sizeof(void *) == 4) && (sizeof(sal_Int32) == 4), "### unexpected size of int!" );
+ OSL_ENSURE( nStackLongs && pStackLongs, "### no stack in callVirtualMethod !" );
+
+ // never called
+ if (! pAdjustedThisPtr) CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
+
+ volatile long edx = 0, eax = 0; // for register returns
+ void * stackptr;
+ asm volatile (
+ "mov %%esp, %6\n\t"
+ // copy values
+ "mov %0, %%eax\n\t"
+ "mov %%eax, %%edx\n\t"
+ "dec %%edx\n\t"
+ "shl $2, %%edx\n\t"
+ "add %1, %%edx\n"
+ "Lcopy:\n\t"
+ "pushl 0(%%edx)\n\t"
+ "sub $4, %%edx\n\t"
+ "dec %%eax\n\t"
+ "jne Lcopy\n\t"
+ // do the actual call
+ "mov %2, %%edx\n\t"
+ "mov 0(%%edx), %%edx\n\t"
+ "mov %3, %%eax\n\t"
+ "shl $2, %%eax\n\t"
+ "add %%eax, %%edx\n\t"
+ "mov 0(%%edx), %%edx\n\t"
+ "call *%%edx\n\t"
+ // save return registers
+ "mov %%eax, %4\n\t"
+ "mov %%edx, %5\n\t"
+ // cleanup stack
+ "mov %6, %%esp\n\t"
+ :
+ : "m"(nStackLongs), "m"(pStackLongs), "m"(pAdjustedThisPtr),
+ "m"(nVtableIndex), "m"(eax), "m"(edx), "m"(stackptr)
+ : "eax", "edx" );
+ switch( returnType->eTypeClass )
+ {
+ case typelib_TypeClass_VOID:
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ ((long*)pRegisterReturn)[1] = edx;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_ENUM:
+ ((long*)pRegisterReturn)[0] = eax;
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = eax;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = eax;
+ break;
+ case typelib_TypeClass_FLOAT:
+ asm ( "fstps %0" : : "m"(*(char *)pRegisterReturn) );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ asm ( "fstpl %0\n\t" : : "m"(*(char *)pRegisterReturn) );
+ break;
+ case typelib_TypeClass_STRUCT:
+ if (bridges::cpp_uno::shared::isSmallStruct(returnType)) {
+ if (returnType->nSize <= 1) {
+ *(unsigned char*)pRegisterReturn = eax;
+ }
+ else if (returnType->nSize <= 2) {
+ *(unsigned short*)pRegisterReturn = eax;
+ }
+ else if (returnType->nSize <= 8) {
+ ((long*)pRegisterReturn)[0] = eax;
+ if (returnType->nSize > 4) {
+ ((long*)pRegisterReturn)[1] = edx;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+//==================================================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ char * pCppStack =
+#ifdef BROKEN_ALLOCA
+ (char *)malloc( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+#else
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+#endif
+ char * pCppStackStart = pCppStack;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn
+ = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+#ifdef BROKEN_ALLOCA
+ ? malloc( pReturnTypeDescr->nSize )
+#else
+ ? alloca( pReturnTypeDescr->nSize )
+#endif
+ : pUnoReturn); // direct way
+ if (!bridges::cpp_uno::shared::isSmallStruct(pReturnTypeDescr)) {
+ *(void **)pCppStack = pCppReturn;
+ pCppStack += sizeof(void *);
+ }
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ *(void**)pCppStack = pAdjustedThisPtr;
+ pCppStack += sizeof( void* );
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+#ifdef BROKEN_ALLOCA
+ void ** pCppArgs = (void **)malloc( 3 * sizeof(void *) * nParams );
+#else
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+#endif
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ break;
+ default:
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+#ifdef BROKEN_ALLOCA
+ *(void **)pCppStack = pCppArgs[nPos] = malloc( pParamTypeDescr->nSize ),
+#else
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+#endif
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+#ifdef BROKEN_ALLOCA
+ *(void **)pCppStack = pCppArgs[nPos] = malloc( pParamTypeDescr->nSize ),
+#else
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+#endif
+ pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ try
+ {
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+#ifdef BROKEN_ALLOCA
+ free( pCppArgs[nIndex] );
+#endif
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+#ifdef BROKEN_ALLOCA
+ free( pCppArgs[nIndex] );
+#endif
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+#ifdef BROKEN_ALLOCA
+ free( pCppReturn );
+#endif
+ }
+#ifdef BROKEN_ALLOCA
+ free( pCppStackStart );
+#endif
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; // get, then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx b/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx
new file mode 100644
index 000000000000..b2687fddc543
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx
@@ -0,0 +1,491 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "msci.hxx"
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+static inline typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ // pCallStack: ret, this, [complex return ptr], params
+ char * pCppStack = (char *)(pCallStack +2);
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ {
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ }
+
+ void * pUnoReturn = 0;
+ void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ }
+ else // complex return via ptr (pCppReturn)
+ {
+ pCppReturn = *(void **)pCppStack;
+ pCppStack += sizeof(void *);
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // parameters
+ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
+ void ** pCppArgs = pUnoArgs + nParams;
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ // value
+ {
+ pCppArgs[nPos] = pCppStack;
+ pUnoArgs[nPos] = pCppStack;
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ break;
+ default:
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ pCppArgs[nPos] = *(void **)pCppStack;
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndizes[nTempIndizes] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ ::uno_copyAndConvertData(
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ *(void **)pCppStack, pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = *(void **)pCppStack;
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occured...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ while (nTempIndizes--)
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ {
+ ::uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
+ }
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ if (pReturnTypeDescr)
+ {
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+
+ CPPU_CURRENT_NAMESPACE::msci_raiseException(
+ &aUnoExc, pThis->getBridge()->getUno2Cpp() );
+ // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occured...
+ {
+ // temporary params
+ while (nTempIndizes--)
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ ::uno_destructData(
+ pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+ ::uno_copyAndConvertData(
+ pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ ::uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ ::uno_copyAndConvertData(
+ pCppReturn, pUnoReturn, pReturnTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ ::uno_destructData(
+ pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ // complex return ptr is set to eax
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+}
+
+//==================================================================================================
+static typelib_TypeClass __cdecl cpp_mediate(
+ void ** pCallStack, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+{
+ OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
+
+ // pCallStack: ret adr, this, [ret *], params
+ void * pThis = static_cast< char * >(pCallStack[1]) - nVtableOffset;
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
+ = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex,
+ "### illegal vtable index!" );
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("illegal vtable index!") ),
+ (XInterface *)pThis );
+ }
+
+ // determine called method
+ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ // standard XInterface vtable calls
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[3] )->getTypeLibType() );
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pCallStack[2] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = pCallStack[2];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException(
+ rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("no member description found!") ),
+ (XInterface *)pThis );
+ // is here for dummy
+ eRet = typelib_TypeClass_VOID;
+ }
+ }
+
+ return eRet;
+}
+
+//==================================================================================================
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+static __declspec(naked) void __cdecl cpp_vtable_call(void)
+{
+__asm
+ {
+ sub esp, 8 // space for immediate return type
+ push esp
+ push edx // vtable offset
+ push eax // function index
+ mov eax, esp
+ add eax, 20
+ push eax // original stack ptr
+
+ call cpp_mediate
+ add esp, 16
+
+ cmp eax, typelib_TypeClass_FLOAT
+ je Lfloat
+ cmp eax, typelib_TypeClass_DOUBLE
+ je Ldouble
+ cmp eax, typelib_TypeClass_HYPER
+ je Lhyper
+ cmp eax, typelib_TypeClass_UNSIGNED_HYPER
+ je Lhyper
+ // rest is eax
+ pop eax
+ add esp, 4
+ ret
+Lhyper:
+ pop eax
+ pop edx
+ ret
+Lfloat:
+ fld dword ptr [esp]
+ add esp, 8
+ ret
+Ldouble:
+ fld qword ptr [esp]
+ add esp, 8
+ ret
+ }
+}
+
+//==================================================================================================
+int const codeSnippetSize = 16;
+
+unsigned char * codeSnippet(
+ unsigned char * code, sal_Int32 functionIndex, sal_Int32 vtableOffset)
+{
+ unsigned char * p = code;
+ OSL_ASSERT(sizeof (sal_Int32) == 4);
+ // mov eax, functionIndex:
+ *p++ = 0xB8;
+ *reinterpret_cast< sal_Int32 * >(p) = functionIndex;
+ p += sizeof (sal_Int32);
+ // mov edx, vtableOffset:
+ *p++ = 0xBA;
+ *reinterpret_cast< sal_Int32 * >(p) = vtableOffset;
+ p += sizeof (sal_Int32);
+ // jmp rel32 cpp_vtable_call:
+ *p++ = 0xE9;
+ *reinterpret_cast< sal_Int32 * >(p)
+ = ((unsigned char *) cpp_vtable_call) - p - sizeof (sal_Int32);
+ p += sizeof (sal_Int32);
+ OSL_ASSERT(p - code <= codeSnippetSize);
+ return code + codeSnippetSize;
+}
+
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 1;
+}
+
+sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 1) * sizeof (Slot) + slotCount * codeSnippetSize;
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount)
+{
+ struct Rtti {
+ sal_Int32 n0, n1, n2;
+ type_info * rtti;
+ Rtti():
+ n0(0), n1(0), n2(0),
+ rtti(CPPU_CURRENT_NAMESPACE::msci_getRTTI(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.uno.XInterface"))))
+ {}
+ };
+ static Rtti rtti;
+
+ Slot * slots = mapBlockToVtable(block);
+ slots[-1].fn = &rtti;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots, unsigned char * code,
+ typelib_InterfaceTypeDescription const *, sal_Int32 functionOffset,
+ sal_Int32 functionCount, sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for (sal_Int32 i = 0; i < functionCount; ++i) {
+ (s++)->fn = code;
+ code = codeSnippet(code, functionOffset++, vtableOffset);
+ }
+ return code;
+}
+
+void bridges::cpp_uno::shared::VtableFactory::flushCode(
+ unsigned char const *, unsigned char const *)
+{}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/dllinit.cxx b/bridges/source/cpp_uno/msvc_win32_intel/dllinit.cxx
new file mode 100644
index 000000000000..cfbc58650f0d
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_intel/dllinit.cxx
@@ -0,0 +1,61 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+
+#pragma warning(push,1) // disable warnings within system headers
+#include <windows.h>
+#pragma warning(pop)
+
+
+void dso_init(void);
+void dso_exit(void);
+
+
+extern "C" BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpvReserved)
+{
+ switch(dwReason) {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hModule);
+
+ dso_init();
+ break;
+
+ case DLL_PROCESS_DETACH:
+ if (!lpvReserved)
+ dso_exit();
+ break;
+ }
+
+ return TRUE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/except.cxx b/bridges/source/cpp_uno/msvc_win32_intel/except.cxx
new file mode 100644
index 000000000000..4bda7cfa9074
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_intel/except.cxx
@@ -0,0 +1,634 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#pragma warning( disable : 4237 )
+#include <hash_map>
+#include <sal/config.h>
+#include <malloc.h>
+#include <new.h>
+#include <typeinfo.h>
+#include <signal.h>
+
+#include "rtl/alloc.h"
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
+
+#include "com/sun/star/uno/Any.hxx"
+
+#include "msci.hxx"
+
+
+#pragma pack(push, 8)
+
+using namespace ::com::sun::star::uno;
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+//==================================================================================================
+static inline OUString toUNOname( OUString const & rRTTIname ) throw ()
+{
+ OUStringBuffer aRet( 64 );
+ OUString aStr( rRTTIname.copy( 4, rRTTIname.getLength()-4-2 ) ); // filter .?AUzzz@yyy@xxx@@
+ sal_Int32 nPos = aStr.getLength();
+ while (nPos > 0)
+ {
+ sal_Int32 n = aStr.lastIndexOf( '@', nPos );
+ aRet.append( aStr.copy( n +1, nPos -n -1 ) );
+ if (n >= 0)
+ {
+ aRet.append( (sal_Unicode)'.' );
+ }
+ nPos = n;
+ }
+ return aRet.makeStringAndClear();
+}
+//==================================================================================================
+static inline OUString toRTTIname( OUString const & rUNOname ) throw ()
+{
+ OUStringBuffer aRet( 64 );
+ aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM(".?AV") ); // class ".?AV"; struct ".?AU"
+ sal_Int32 nPos = rUNOname.getLength();
+ while (nPos > 0)
+ {
+ sal_Int32 n = rUNOname.lastIndexOf( '.', nPos );
+ aRet.append( rUNOname.copy( n +1, nPos -n -1 ) );
+ aRet.append( (sal_Unicode)'@' );
+ nPos = n;
+ }
+ aRet.append( (sal_Unicode)'@' );
+ return aRet.makeStringAndClear();
+}
+
+
+//##################################################################################################
+//#### RTTI simulation #############################################################################
+//##################################################################################################
+
+
+typedef hash_map< OUString, void *, OUStringHash, equal_to< OUString > > t_string2PtrMap;
+
+//==================================================================================================
+class RTTInfos
+{
+ Mutex _aMutex;
+ t_string2PtrMap _allRTTI;
+
+ static OUString toRawName( OUString const & rUNOname ) throw ();
+public:
+ type_info * getRTTI( OUString const & rUNOname ) throw ();
+
+ RTTInfos();
+ ~RTTInfos();
+};
+
+//==================================================================================================
+class __type_info
+{
+ friend type_info * RTTInfos::getRTTI( OUString const & ) throw ();
+ friend int msci_filterCppException(
+ LPEXCEPTION_POINTERS, uno_Any *, uno_Mapping * );
+
+public:
+ virtual ~__type_info() throw ();
+
+ inline __type_info( void * m_data, const char * m_d_name ) throw ()
+ : _m_data( m_data )
+ { ::strcpy( _m_d_name, m_d_name ); } // #100211# - checked
+
+private:
+ void * _m_data;
+ char _m_d_name[1];
+};
+//__________________________________________________________________________________________________
+__type_info::~__type_info() throw ()
+{
+}
+//__________________________________________________________________________________________________
+type_info * RTTInfos::getRTTI( OUString const & rUNOname ) throw ()
+{
+ // a must be
+ OSL_ENSURE( sizeof(__type_info) == sizeof(type_info), "### type info structure size differ!" );
+
+ MutexGuard aGuard( _aMutex );
+ t_string2PtrMap::const_iterator const iFind( _allRTTI.find( rUNOname ) );
+
+ // check if type is already available
+ if (iFind == _allRTTI.end())
+ {
+ // insert new type_info
+ OString aRawName( OUStringToOString( toRTTIname( rUNOname ), RTL_TEXTENCODING_ASCII_US ) );
+ __type_info * pRTTI = new( ::rtl_allocateMemory( sizeof(__type_info) + aRawName.getLength() ) )
+ __type_info( NULL, aRawName.getStr() );
+
+ // put into map
+ pair< t_string2PtrMap::iterator, bool > insertion(
+ _allRTTI.insert( t_string2PtrMap::value_type( rUNOname, pRTTI ) ) );
+ OSL_ENSURE( insertion.second, "### rtti insertion failed?!" );
+
+ return (type_info *)pRTTI;
+ }
+ else
+ {
+ return (type_info *)iFind->second;
+ }
+}
+//__________________________________________________________________________________________________
+RTTInfos::RTTInfos() throw ()
+{
+}
+//__________________________________________________________________________________________________
+RTTInfos::~RTTInfos() throw ()
+{
+#if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE( "> freeing generated RTTI infos... <\n" );
+#endif
+
+ MutexGuard aGuard( _aMutex );
+ for ( t_string2PtrMap::const_iterator iPos( _allRTTI.begin() );
+ iPos != _allRTTI.end(); ++iPos )
+ {
+ __type_info * pType = (__type_info *)iPos->second;
+ pType->~__type_info(); // obsolete, but good style...
+ ::rtl_freeMemory( pType );
+ }
+}
+
+
+//##################################################################################################
+//#### Exception raising ###########################################################################
+//##################################################################################################
+
+
+//==================================================================================================
+struct ObjectFunction
+{
+ char somecode[12];
+ typelib_TypeDescription * _pTypeDescr; // type of object
+
+ inline static void * operator new ( size_t nSize );
+ inline static void operator delete ( void * pMem );
+
+ ObjectFunction( typelib_TypeDescription * pTypeDescr, void * fpFunc ) throw ();
+ ~ObjectFunction() throw ();
+};
+
+inline void * ObjectFunction::operator new ( size_t nSize )
+{
+ void * pMem = rtl_allocateMemory( nSize );
+ if (pMem != 0)
+ {
+ DWORD old_protect;
+#if OSL_DEBUG_LEVEL > 0
+ BOOL success =
+#endif
+ VirtualProtect( pMem, nSize, PAGE_EXECUTE_READWRITE, &old_protect );
+ OSL_ENSURE( success, "VirtualProtect() failed!" );
+ }
+ return pMem;
+}
+
+inline void ObjectFunction::operator delete ( void * pMem )
+{
+ rtl_freeMemory( pMem );
+}
+
+//__________________________________________________________________________________________________
+ObjectFunction::ObjectFunction( typelib_TypeDescription * pTypeDescr, void * fpFunc ) throw ()
+ : _pTypeDescr( pTypeDescr )
+{
+ ::typelib_typedescription_acquire( _pTypeDescr );
+
+ unsigned char * pCode = (unsigned char *)somecode;
+ // a must be!
+ OSL_ENSURE( (void *)this == (void *)pCode, "### unexpected!" );
+
+ // push ObjectFunction this
+ *pCode++ = 0x68;
+ *(void **)pCode = this;
+ pCode += sizeof(void *);
+ // jmp rel32 fpFunc
+ *pCode++ = 0xe9;
+ *(sal_Int32 *)pCode = ((unsigned char *)fpFunc) - pCode - sizeof(sal_Int32);
+}
+//__________________________________________________________________________________________________
+ObjectFunction::~ObjectFunction() throw ()
+{
+ ::typelib_typedescription_release( _pTypeDescr );
+}
+
+//==================================================================================================
+static void * __cdecl __copyConstruct( void * pExcThis, void * pSource, ObjectFunction * pThis )
+ throw ()
+{
+ ::uno_copyData( pExcThis, pSource, pThis->_pTypeDescr, cpp_acquire );
+ return pExcThis;
+}
+//==================================================================================================
+static void * __cdecl __destruct( void * pExcThis, ObjectFunction * pThis )
+ throw ()
+{
+ ::uno_destructData( pExcThis, pThis->_pTypeDescr, cpp_release );
+ return pExcThis;
+}
+
+// these are non virtual object methods; there is no this ptr on stack => ecx supplies _this_ ptr
+
+//==================================================================================================
+static __declspec(naked) void copyConstruct() throw ()
+{
+ __asm
+ {
+ // ObjectFunction this already on stack
+ push [esp+8] // source exc object this
+ push ecx // exc object
+ call __copyConstruct
+ add esp, 12 // + ObjectFunction this
+ ret 4
+ }
+}
+//==================================================================================================
+static __declspec(naked) void destruct() throw ()
+{
+ __asm
+ {
+ // ObjectFunction this already on stack
+ push ecx // exc object
+ call __destruct
+ add esp, 8 // + ObjectFunction this
+ ret
+ }
+}
+
+//==================================================================================================
+struct ExceptionType
+{
+ sal_Int32 _n0;
+ type_info * _pTypeInfo;
+ sal_Int32 _n1, _n2, _n3, _n4;
+ ObjectFunction * _pCopyCtor;
+ sal_Int32 _n5;
+
+ inline ExceptionType( typelib_TypeDescription * pTypeDescr ) throw ()
+ : _n0( 0 )
+ , _n1( 0 )
+ , _n2( -1 )
+ , _n3( 0 )
+ , _n4( pTypeDescr->nSize )
+ , _pCopyCtor( new ObjectFunction( pTypeDescr, copyConstruct ) )
+ , _n5( 0 )
+ { _pTypeInfo = msci_getRTTI( pTypeDescr->pTypeName ); }
+ inline ~ExceptionType() throw ()
+ { delete _pCopyCtor; }
+};
+//==================================================================================================
+struct RaiseInfo
+{
+ sal_Int32 _n0;
+ ObjectFunction * _pDtor;
+ sal_Int32 _n2;
+ void * _types;
+ sal_Int32 _n3, _n4;
+
+ RaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ();
+ ~RaiseInfo() throw ();
+};
+//__________________________________________________________________________________________________
+RaiseInfo::RaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ()
+ : _n0( 0 )
+ , _pDtor( new ObjectFunction( pTypeDescr, destruct ) )
+ , _n2( 0 )
+ , _n3( 0 )
+ , _n4( 0 )
+{
+ // a must be
+ OSL_ENSURE( sizeof(sal_Int32) == sizeof(ExceptionType *), "### pointer size differs from sal_Int32!" );
+
+ typelib_CompoundTypeDescription * pCompTypeDescr;
+
+ // info count
+ sal_Int32 nLen = 0;
+ for ( pCompTypeDescr = (typelib_CompoundTypeDescription*)pTypeDescr;
+ pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
+ {
+ ++nLen;
+ }
+
+ // info count accompanied by type info ptrs: type, base type, base base type, ...
+ _types = ::rtl_allocateMemory( sizeof(sal_Int32) + (sizeof(ExceptionType *) * nLen) );
+ *(sal_Int32 *)_types = nLen;
+
+ ExceptionType ** ppTypes = (ExceptionType **)((sal_Int32 *)_types + 1);
+
+ sal_Int32 nPos = 0;
+ for ( pCompTypeDescr = (typelib_CompoundTypeDescription*)pTypeDescr;
+ pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
+ {
+ ppTypes[nPos++] = new ExceptionType( (typelib_TypeDescription *)pCompTypeDescr );
+ }
+}
+//__________________________________________________________________________________________________
+RaiseInfo::~RaiseInfo() throw ()
+{
+ ExceptionType ** ppTypes = (ExceptionType **)((sal_Int32 *)_types + 1);
+ for ( sal_Int32 nTypes = *(sal_Int32 *)_types; nTypes--; )
+ {
+ delete ppTypes[nTypes];
+ }
+ ::rtl_freeMemory( _types );
+
+ delete _pDtor;
+}
+
+//==================================================================================================
+class ExceptionInfos
+{
+ Mutex _aMutex;
+ t_string2PtrMap _allRaiseInfos;
+
+public:
+ static void * getRaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ();
+
+ ExceptionInfos() throw ();
+ ~ExceptionInfos() throw ();
+};
+//__________________________________________________________________________________________________
+ExceptionInfos::ExceptionInfos() throw ()
+{
+}
+//__________________________________________________________________________________________________
+ExceptionInfos::~ExceptionInfos() throw ()
+{
+#if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE( "> freeing exception infos... <\n" );
+#endif
+
+ MutexGuard aGuard( _aMutex );
+ for ( t_string2PtrMap::const_iterator iPos( _allRaiseInfos.begin() );
+ iPos != _allRaiseInfos.end(); ++iPos )
+ {
+ delete (RaiseInfo *)iPos->second;
+ }
+}
+//__________________________________________________________________________________________________
+void * ExceptionInfos::getRaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ()
+{
+ static ExceptionInfos * s_pInfos = 0;
+ if (! s_pInfos)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! s_pInfos)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_pInfos = new ExceptionInfos();
+#else
+ static ExceptionInfos s_allExceptionInfos;
+ s_pInfos = &s_allExceptionInfos;
+#endif
+ }
+ }
+
+ OSL_ASSERT( pTypeDescr &&
+ (pTypeDescr->eTypeClass == typelib_TypeClass_STRUCT ||
+ pTypeDescr->eTypeClass == typelib_TypeClass_EXCEPTION) );
+
+ void * pRaiseInfo;
+
+ OUString const & rTypeName = *reinterpret_cast< OUString * >( &pTypeDescr->pTypeName );
+ MutexGuard aGuard( s_pInfos->_aMutex );
+ t_string2PtrMap::const_iterator const iFind(
+ s_pInfos->_allRaiseInfos.find( rTypeName ) );
+ if (iFind == s_pInfos->_allRaiseInfos.end())
+ {
+ pRaiseInfo = new RaiseInfo( pTypeDescr );
+ // put into map
+ pair< t_string2PtrMap::iterator, bool > insertion(
+ s_pInfos->_allRaiseInfos.insert( t_string2PtrMap::value_type( rTypeName, pRaiseInfo ) ) );
+ OSL_ENSURE( insertion.second, "### raise info insertion failed?!" );
+ }
+ else
+ {
+ // reuse existing info
+ pRaiseInfo = iFind->second;
+ }
+
+ return pRaiseInfo;
+}
+
+
+//##################################################################################################
+//#### exported ####################################################################################
+//##################################################################################################
+
+
+//##################################################################################################
+type_info * msci_getRTTI( OUString const & rUNOname )
+{
+ static RTTInfos * s_pRTTIs = 0;
+ if (! s_pRTTIs)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! s_pRTTIs)
+ {
+#ifdef LEAK_STATIC_DATA
+ s_pRTTIs = new RTTInfos();
+#else
+ static RTTInfos s_aRTTIs;
+ s_pRTTIs = &s_aRTTIs;
+#endif
+ }
+ }
+ return s_pRTTIs->getRTTI( rUNOname );
+}
+
+//##################################################################################################
+void msci_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+ // no ctor/dtor in here: this leads to dtors called twice upon RaiseException()!
+ // thus this obj file will be compiled without opt, so no inling of
+ // ExceptionInfos::getRaiseInfo()
+
+ // construct cpp exception object
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
+
+ void * pCppExc = alloca( pTypeDescr->nSize );
+ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+
+ // a must be
+ OSL_ENSURE(
+ sizeof(sal_Int32) == sizeof(void *),
+ "### pointer size differs from sal_Int32!" );
+ DWORD arFilterArgs[3];
+ arFilterArgs[0] = MSVC_magic_number;
+ arFilterArgs[1] = (DWORD)pCppExc;
+ arFilterArgs[2] = (DWORD)ExceptionInfos::getRaiseInfo( pTypeDescr );
+
+ // destruct uno exception
+ ::uno_any_destruct( pUnoExc, 0 );
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+
+ // last point to release anything not affected by stack unwinding
+ RaiseException( MSVC_ExceptionCode, EXCEPTION_NONCONTINUABLE, 3, arFilterArgs );
+}
+
+//##############################################################################
+int msci_filterCppException(
+ EXCEPTION_POINTERS * pPointers, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
+{
+ if (pPointers == 0)
+ return EXCEPTION_CONTINUE_SEARCH;
+ EXCEPTION_RECORD * pRecord = pPointers->ExceptionRecord;
+ // handle only C++ exceptions:
+ if (pRecord == 0 || pRecord->ExceptionCode != MSVC_ExceptionCode)
+ return EXCEPTION_CONTINUE_SEARCH;
+
+#if _MSC_VER < 1300 // MSVC -6
+ bool rethrow = (pRecord->NumberParameters < 3 ||
+ pRecord->ExceptionInformation[ 2 ] == 0);
+#else
+ bool rethrow = __CxxDetectRethrow( &pRecord );
+ OSL_ASSERT( pRecord == pPointers->ExceptionRecord );
+#endif
+ if (rethrow && pRecord == pPointers->ExceptionRecord)
+ {
+ // hack to get msvcrt internal _curexception field:
+ pRecord = *reinterpret_cast< EXCEPTION_RECORD ** >(
+ reinterpret_cast< char * >( __pxcptinfoptrs() ) +
+ // as long as we don't demand msvcr source as build prerequisite
+ // (->platform sdk), we have to code those offsets here.
+ //
+ // crt\src\mtdll.h:
+ // offsetof (_tiddata, _curexception) -
+ // offsetof (_tiddata, _tpxcptinfoptrs):
+#if _MSC_VER < 1300
+ 0x18 // msvcrt,dll
+#elif _MSC_VER < 1310
+ 0x20 // msvcr70.dll
+#elif _MSC_VER < 1400
+ 0x24 // msvcr71.dll
+#else
+ 0x28 // msvcr80.dll
+#endif
+ );
+ }
+ // rethrow: handle only C++ exceptions:
+ if (pRecord == 0 || pRecord->ExceptionCode != MSVC_ExceptionCode)
+ return EXCEPTION_CONTINUE_SEARCH;
+
+ if (pRecord->NumberParameters == 3 &&
+// pRecord->ExceptionInformation[ 0 ] == MSVC_magic_number &&
+ pRecord->ExceptionInformation[ 1 ] != 0 &&
+ pRecord->ExceptionInformation[ 2 ] != 0)
+ {
+ void * types = reinterpret_cast< RaiseInfo * >(
+ pRecord->ExceptionInformation[ 2 ] )->_types;
+ if (types != 0 && *reinterpret_cast< DWORD * >( types ) > 0) // count
+ {
+ ExceptionType * pType = *reinterpret_cast< ExceptionType ** >(
+ reinterpret_cast< DWORD * >( types ) + 1 );
+ if (pType != 0 && pType->_pTypeInfo != 0)
+ {
+ OUString aRTTIname(
+ OStringToOUString(
+ reinterpret_cast< __type_info * >(
+ pType->_pTypeInfo )->_m_d_name,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OUString aUNOname( toUNOname( aRTTIname ) );
+
+ typelib_TypeDescription * pExcTypeDescr = 0;
+ typelib_typedescription_getByName(
+ &pExcTypeDescr, aUNOname.pData );
+ if (pExcTypeDescr == 0)
+ {
+ OUStringBuffer buf;
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM(
+ "[msci_uno bridge error] UNO type of "
+ "C++ exception unknown: \"") );
+ buf.append( aUNOname );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "\", RTTI-name=\"") );
+ buf.append( aRTTIname );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
+ RuntimeException exc(
+ buf.makeStringAndClear(), Reference< XInterface >() );
+ uno_type_any_constructAndConvert(
+ pUnoExc, &exc,
+ ::getCppuType( &exc ).getTypeLibType(), pCpp2Uno );
+#if _MSC_VER < 1400 // msvcr80.dll cleans up, different from former msvcrs
+ // if (! rethrow):
+ // though this unknown exception leaks now, no user-defined
+ // exception is ever thrown thru the binary C-UNO dispatcher
+ // call stack.
+#endif
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert(
+ pUnoExc, (void *) pRecord->ExceptionInformation[1],
+ pExcTypeDescr, pCpp2Uno );
+#if _MSC_VER < 1400 // msvcr80.dll cleans up, different from former msvcrs
+ if (! rethrow)
+ {
+ uno_destructData(
+ (void *) pRecord->ExceptionInformation[1],
+ pExcTypeDescr, cpp_release );
+ }
+#endif
+ typelib_typedescription_release( pExcTypeDescr );
+ }
+
+ return EXCEPTION_EXECUTE_HANDLER;
+ }
+ }
+ }
+ // though this unknown exception leaks now, no user-defined exception
+ // is ever thrown thru the binary C-UNO dispatcher call stack.
+ RuntimeException exc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "[msci_uno bridge error] unexpected "
+ "C++ exception occured!") ),
+ Reference< XInterface >() );
+ uno_type_any_constructAndConvert(
+ pUnoExc, &exc, ::getCppuType( &exc ).getTypeLibType(), pCpp2Uno );
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+
+}
+
+#pragma pack(pop)
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/makefile.mk b/bridges/source/cpp_uno/msvc_win32_intel/makefile.mk
new file mode 100644
index 000000000000..194d8d6736f6
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_intel/makefile.mk
@@ -0,0 +1,83 @@
+#*************************************************************************
+#
+# 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=msci_uno
+LIBTARGET=no
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+.IF "$(COM)" == "MSC"
+
+.IF "$(debug)" != ""
+CFLAGS += -Ob0
+.ENDIF
+
+.IF "$(cppu_no_leak)" == ""
+.IF "$(bndchk)" == ""
+CFLAGS += -DLEAK_STATIC_DATA
+.ENDIF
+.ENDIF
+
+
+SLOFILES= \
+ $(SLO)$/cpp2uno.obj \
+ $(SLO)$/uno2cpp.obj \
+ $(SLO)$/dllinit.obj \
+ $(SLO)$/except.obj
+
+NOOPTFILES= \
+ $(SLO)$/except.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(TARGET)
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1OBJS = $(SLOFILES)
+SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(SALLIB)
+
+DEF1NAME=$(SHL1TARGET)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/msci.hxx b/bridges/source/cpp_uno/msvc_win32_intel/msci.hxx
new file mode 100644
index 000000000000..ecc4e22960d7
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_intel/msci.hxx
@@ -0,0 +1,59 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#pragma warning(push, 1)
+#include <windows.h>
+#pragma warning(pop)
+
+#include "rtl/ustring.hxx"
+
+
+class type_info;
+typedef struct _uno_Any uno_Any;
+typedef struct _uno_Mapping uno_Mapping;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+const DWORD MSVC_ExceptionCode = 0xe06d7363;
+const long MSVC_magic_number = 0x19930520L;
+
+//==============================================================================
+type_info * msci_getRTTI( ::rtl::OUString const & rUNOname );
+
+//==============================================================================
+int msci_filterCppException(
+ EXCEPTION_POINTERS * pPointers, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno );
+
+//==============================================================================
+void msci_raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx b/bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx
new file mode 100644
index 000000000000..0a131e94a05b
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx
@@ -0,0 +1,468 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <malloc.h>
+
+#include <com/sun/star/uno/genfunc.hxx>
+#include <uno/data.h>
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/types.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "msci.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+
+//==================================================================================================
+inline static void callVirtualMethod(
+ void * pAdjustedThisPtr, sal_Int32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeClass eReturnTypeClass,
+ sal_Int32 * pStackLongs, sal_Int32 nStackLongs )
+{
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ OSL_ENSURE( pStackLongs && pAdjustedThisPtr, "### null ptr!" );
+ OSL_ENSURE( (sizeof(void *) == 4) &&
+ (sizeof(sal_Int32) == 4), "### unexpected size of int!" );
+
+__asm
+ {
+ mov eax, nStackLongs
+ test eax, eax
+ je Lcall
+ // copy values
+ mov ecx, eax
+ shl eax, 2 // sizeof(sal_Int32) == 4
+ add eax, pStackLongs // params stack space
+Lcopy: sub eax, 4
+ push dword ptr [eax]
+ dec ecx
+ jne Lcopy
+Lcall:
+ // call
+ mov ecx, pAdjustedThisPtr
+ push ecx // this ptr
+ mov edx, [ecx] // pvft
+ mov eax, nVtableIndex
+ shl eax, 2 // sizeof(void *) == 4
+ add edx, eax
+ call [edx] // interface method call must be __cdecl!!!
+
+ // register return
+ mov ecx, eReturnTypeClass
+ cmp ecx, typelib_TypeClass_VOID
+ je Lcleanup
+ mov ebx, pRegisterReturn
+// int32
+ cmp ecx, typelib_TypeClass_LONG
+ je Lint32
+ cmp ecx, typelib_TypeClass_UNSIGNED_LONG
+ je Lint32
+ cmp ecx, typelib_TypeClass_ENUM
+ je Lint32
+// int8
+ cmp ecx, typelib_TypeClass_BOOLEAN
+ je Lint8
+ cmp ecx, typelib_TypeClass_BYTE
+ je Lint8
+// int16
+ cmp ecx, typelib_TypeClass_CHAR
+ je Lint16
+ cmp ecx, typelib_TypeClass_SHORT
+ je Lint16
+ cmp ecx, typelib_TypeClass_UNSIGNED_SHORT
+ je Lint16
+// float
+ cmp ecx, typelib_TypeClass_FLOAT
+ je Lfloat
+// double
+ cmp ecx, typelib_TypeClass_DOUBLE
+ je Ldouble
+// int64
+ cmp ecx, typelib_TypeClass_HYPER
+ je Lint64
+ cmp ecx, typelib_TypeClass_UNSIGNED_HYPER
+ je Lint64
+ jmp Lcleanup // no simple type
+Lint8:
+ mov byte ptr [ebx], al
+ jmp Lcleanup
+Lint16:
+ mov word ptr [ebx], ax
+ jmp Lcleanup
+Lfloat:
+ fstp dword ptr [ebx]
+ jmp Lcleanup
+Ldouble:
+ fstp qword ptr [ebx]
+ jmp Lcleanup
+Lint64:
+ mov dword ptr [ebx], eax
+ mov dword ptr [ebx+4], edx
+ jmp Lcleanup
+Lint32:
+ mov dword ptr [ebx], eax
+ jmp Lcleanup
+Lcleanup:
+ // cleanup stack (obsolete though because of function)
+ mov eax, nStackLongs
+ shl eax, 2 // sizeof(sal_Int32) == 4
+ add eax, 4 // this ptr
+ add esp, eax
+ }
+}
+
+//==================================================================================================
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc ) throw ()
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ char * pCppStack = (char *)alloca( sizeof(sal_Int32) + (nParams * sizeof(sal_Int64)) );
+ char * pCppStackStart = pCppStack;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack
+ = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ pCppStack += sizeof(void *);
+ }
+ }
+
+ // stack space
+
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut
+ && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ ::uno_copyAndConvertData(
+ pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_DOUBLE:
+ pCppStack += sizeof(sal_Int32); // extra long
+ break;
+ default:
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ ::uno_constructData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pParamTypeDescr ))
+ {
+ ::uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ __try
+ {
+ // pCppI is msci this pointer
+ callVirtualMethod(
+ reinterpret_cast< void ** >(pThis->getCppI()) + aVtableSlot.offset,
+ aVtableSlot.index,
+ pCppReturn, pReturnTypeDescr->eTypeClass,
+ (sal_Int32 *)pCppStackStart,
+ (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ }
+ __except (CPPU_CURRENT_NAMESPACE::msci_filterCppException(
+ GetExceptionInformation(),
+ *ppUnoExc, pThis->getBridge()->getCpp2Uno() ))
+ {
+ // *ppUnoExc was constructed by filter function
+ // temporary params
+ while (nTempIndizes--)
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ ::uno_destructData(
+ pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes],
+ cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ {
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+ // end here
+ return;
+ }
+
+ // NO exception occured
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ while (nTempIndizes--)
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr =
+ ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ ::uno_destructData(
+ pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ ::uno_copyAndConvertData(
+ pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ ::uno_copyAndConvertData(
+ pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ ::uno_destructData(
+ pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ ::uno_copyAndConvertData(
+ pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ ::uno_destructData(
+ pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ {
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ pMemberDescr)));
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1; // get, then set method
+ cpp_call(
+ pThis, aVtableSlot,
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ pMemberDescr)));
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->getUnoEnv()->getRegisteredInterface)(
+ pThis->pBridge->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/shared/bridge.cxx b/bridges/source/cpp_uno/shared/bridge.cxx
new file mode 100644
index 000000000000..0b76b0ca1a8a
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/bridge.cxx
@@ -0,0 +1,229 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+
+#include "component.hxx"
+
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+
+#include "com/sun/star/uno/XInterface.hpp"
+#include "osl/diagnose.h"
+#include "osl/interlck.h"
+#include "rtl/ustring.h"
+#include "sal/types.h"
+#include "typelib/typedescription.h"
+#include "uno/dispatcher.h"
+#include "uno/environment.h"
+#include "uno/mapping.h"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void freeMapping(uno_Mapping * pMapping)
+{
+ delete static_cast< Bridge::Mapping * >( pMapping )->pBridge;
+}
+
+void acquireMapping(uno_Mapping * pMapping)
+{
+ static_cast< Bridge::Mapping * >( pMapping )->pBridge->acquire();
+}
+
+void releaseMapping(uno_Mapping * pMapping)
+{
+ static_cast< Bridge::Mapping * >( pMapping )->pBridge->release();
+}
+
+void cpp2unoMapping(
+ uno_Mapping * pMapping, void ** ppUnoI, void * pCppI,
+ typelib_InterfaceTypeDescription * pTypeDescr)
+{
+ OSL_ENSURE( ppUnoI && pTypeDescr, "### null ptr!" );
+ if (*ppUnoI)
+ {
+ (*reinterpret_cast< uno_Interface * >( *ppUnoI )->release)(
+ reinterpret_cast< uno_Interface * >( *ppUnoI ) );
+ *ppUnoI = 0;
+ }
+ if (pCppI)
+ {
+ Bridge * pBridge = static_cast< Bridge::Mapping * >( pMapping )->pBridge;
+
+ // get object id of interface to be wrapped
+ rtl_uString * pOId = 0;
+ (*pBridge->pCppEnv->getObjectIdentifier)(
+ pBridge->pCppEnv, &pOId, pCppI );
+ OSL_ASSERT( pOId );
+
+ // try to get any known interface from target environment
+ (*pBridge->pUnoEnv->getRegisteredInterface)(
+ pBridge->pUnoEnv, ppUnoI, pOId, pTypeDescr );
+
+ if (! *ppUnoI) // no existing interface, register new proxy interface
+ {
+ // try to publish a new proxy (refcount initially 1)
+ uno_Interface * pSurrogate
+ = bridges::cpp_uno::shared::UnoInterfaceProxy::create(
+ pBridge,
+ static_cast< ::com::sun::star::uno::XInterface * >( pCppI ),
+ pTypeDescr, pOId );
+
+ // proxy may be exchanged during registration
+ (*pBridge->pUnoEnv->registerProxyInterface)(
+ pBridge->pUnoEnv, reinterpret_cast< void ** >( &pSurrogate ),
+ freeUnoInterfaceProxy, pOId,
+ pTypeDescr );
+
+ *ppUnoI = pSurrogate;
+ }
+ ::rtl_uString_release( pOId );
+ }
+}
+
+void uno2cppMapping(
+ uno_Mapping * pMapping, void ** ppCppI, void * pUnoI,
+ typelib_InterfaceTypeDescription * pTypeDescr)
+{
+ OSL_ASSERT( ppCppI && pTypeDescr );
+ if (*ppCppI)
+ {
+ static_cast< ::com::sun::star::uno::XInterface * >( *ppCppI )->
+ release();
+ *ppCppI = 0;
+ }
+ if (pUnoI)
+ {
+ Bridge * pBridge = static_cast< Bridge::Mapping * >( pMapping )->pBridge;
+
+ // get object id of uno interface to be wrapped
+ rtl_uString * pOId = 0;
+ (*pBridge->pUnoEnv->getObjectIdentifier)(
+ pBridge->pUnoEnv, &pOId, pUnoI );
+ OSL_ASSERT( pOId );
+
+ // try to get any known interface from target environment
+ (*pBridge->pCppEnv->getRegisteredInterface)(
+ pBridge->pCppEnv, ppCppI, pOId, pTypeDescr );
+
+ if (! *ppCppI) // no existing interface, register new proxy interface
+ {
+ // try to publish a new proxy (ref count initially 1)
+ com::sun::star::uno::XInterface * pProxy
+ = bridges::cpp_uno::shared::CppInterfaceProxy::create(
+ pBridge, static_cast< uno_Interface * >( pUnoI ),
+ pTypeDescr, pOId );
+
+ // proxy may be exchanged during registration
+ (*pBridge->pCppEnv->registerProxyInterface)(
+ pBridge->pCppEnv, reinterpret_cast< void ** >( &pProxy ),
+ freeCppInterfaceProxy, pOId,
+ pTypeDescr );
+
+ *ppCppI = pProxy;
+ }
+ ::rtl_uString_release( pOId );
+ }
+}
+
+uno_Mapping * Bridge::createMapping(
+ uno_ExtEnvironment * pCppEnv, uno_ExtEnvironment * pUnoEnv,
+ bool bExportCpp2Uno) SAL_THROW(())
+{
+ Bridge * bridge = new Bridge(pCppEnv, pUnoEnv, bExportCpp2Uno);
+ return bExportCpp2Uno ? &bridge->aCpp2Uno : &bridge->aUno2Cpp;
+}
+
+void Bridge::acquire() SAL_THROW(())
+{
+ if (1 == osl_incrementInterlockedCount( &nRef ))
+ {
+ if (bExportCpp2Uno)
+ {
+ uno_Mapping * pMapping = &aCpp2Uno;
+ ::uno_registerMapping(
+ &pMapping, freeMapping, (uno_Environment *)pCppEnv,
+ (uno_Environment *)pUnoEnv, 0 );
+ }
+ else
+ {
+ uno_Mapping * pMapping = &aUno2Cpp;
+ ::uno_registerMapping(
+ &pMapping, freeMapping, (uno_Environment *)pUnoEnv,
+ (uno_Environment *)pCppEnv, 0 );
+ }
+ }
+}
+
+void Bridge::release() SAL_THROW(())
+{
+ if (! osl_decrementInterlockedCount( &nRef ))
+ {
+ ::uno_revokeMapping( bExportCpp2Uno ? &aCpp2Uno : &aUno2Cpp );
+ }
+}
+
+Bridge::Bridge(
+ uno_ExtEnvironment * pCppEnv_, uno_ExtEnvironment * pUnoEnv_,
+ bool bExportCpp2Uno_) SAL_THROW(())
+ : nRef( 1 )
+ , pCppEnv( pCppEnv_ )
+ , pUnoEnv( pUnoEnv_ )
+ , bExportCpp2Uno( bExportCpp2Uno_ )
+{
+ bridges::cpp_uno::shared::g_moduleCount.modCnt.acquire(
+ &bridges::cpp_uno::shared::g_moduleCount.modCnt );
+
+ aCpp2Uno.pBridge = this;
+ aCpp2Uno.acquire = acquireMapping;
+ aCpp2Uno.release = releaseMapping;
+ aCpp2Uno.mapInterface = cpp2unoMapping;
+
+ aUno2Cpp.pBridge = this;
+ aUno2Cpp.acquire = acquireMapping;
+ aUno2Cpp.release = releaseMapping;
+ aUno2Cpp.mapInterface = uno2cppMapping;
+
+ (*((uno_Environment *)pCppEnv)->acquire)( (uno_Environment *)pCppEnv );
+ (*((uno_Environment *)pUnoEnv)->acquire)( (uno_Environment *)pUnoEnv );
+}
+
+Bridge::~Bridge() SAL_THROW(())
+{
+ (*((uno_Environment *)pUnoEnv)->release)( (uno_Environment *)pUnoEnv );
+ (*((uno_Environment *)pCppEnv)->release)( (uno_Environment *)pCppEnv );
+ bridges::cpp_uno::shared::g_moduleCount.modCnt.release(
+ &bridges::cpp_uno::shared::g_moduleCount.modCnt );
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/shared/component.cxx b/bridges/source/cpp_uno/shared/component.cxx
new file mode 100644
index 000000000000..2c89217c9721
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/component.cxx
@@ -0,0 +1,275 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "component.hxx"
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "osl/diagnose.h"
+#include "osl/mutex.hxx"
+#include "osl/time.h"
+#include "rtl/process.h"
+#include "rtl/unload.h"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "uno/environment.h"
+#include "uno/lbnames.h"
+#include "uno/mapping.h"
+#include "cppu/EnvDcp.hxx"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+} } }
+
+namespace {
+
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) \
+ || (defined(__GNUC__) && defined(__APPLE__))
+static ::rtl::OUString * s_pStaticOidPart = 0;
+#endif
+
+const ::rtl::OUString & SAL_CALL cppu_cppenv_getStaticOIdPart() SAL_THROW( () )
+{
+#if ! ((defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) \
+ || (defined(__GNUC__) && defined(__APPLE__)))
+ static ::rtl::OUString * s_pStaticOidPart = 0;
+#endif
+ if (! s_pStaticOidPart)
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if (! s_pStaticOidPart)
+ {
+ ::rtl::OUStringBuffer aRet( 64 );
+ aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") );
+ // good guid
+ sal_uInt8 ar[16];
+ ::rtl_getGlobalProcessId( ar );
+ for ( sal_Int32 i = 0; i < 16; ++i )
+ {
+ aRet.append( (sal_Int32)ar[i], 16 );
+ }
+#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) \
+ || (defined(__GNUC__) && defined(__APPLE__))
+ s_pStaticOidPart = new ::rtl::OUString( aRet.makeStringAndClear() );
+#else
+ static ::rtl::OUString s_aStaticOidPart(
+ aRet.makeStringAndClear() );
+ s_pStaticOidPart = &s_aStaticOidPart;
+#endif
+ }
+ }
+ return *s_pStaticOidPart;
+}
+
+}
+
+extern "C" {
+
+static void s_stub_computeObjectIdentifier(va_list * pParam)
+ SAL_THROW( () )
+{
+ uno_ExtEnvironment * pEnv = va_arg(*pParam, uno_ExtEnvironment *);
+ rtl_uString ** ppOId = va_arg(*pParam, rtl_uString **);
+ void * pInterface = va_arg(*pParam, void *);
+
+
+ OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" );
+ if (pEnv && ppOId && pInterface)
+ {
+ if (*ppOId)
+ {
+ rtl_uString_release( *ppOId );
+ *ppOId = 0;
+ }
+
+ try
+ {
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XInterface > xHome(
+ reinterpret_cast< ::com::sun::star::uno::XInterface * >(
+ pInterface ),
+ ::com::sun::star::uno::UNO_QUERY );
+ OSL_ENSURE( xHome.is(), "### query to XInterface failed!" );
+ if (xHome.is())
+ {
+ // interface
+ ::rtl::OUStringBuffer oid( 64 );
+ oid.append( reinterpret_cast< sal_Int64 >(xHome.get()), 16 );
+ oid.append( (sal_Unicode)';' );
+ // ;environment[context]
+ oid.append(
+ *reinterpret_cast< ::rtl::OUString const * >(
+ &((uno_Environment *) pEnv)->pTypeName ) );
+ oid.append( (sal_Unicode)'[' );
+ oid.append(
+ reinterpret_cast< sal_Int64 >(
+ ((uno_Environment *)pEnv)->pContext),
+ 16 );
+ // ];good guid
+ oid.append( cppu_cppenv_getStaticOIdPart() );
+ ::rtl::OUString aRet( oid.makeStringAndClear() );
+ ::rtl_uString_acquire( *ppOId = aRet.pData );
+ }
+ }
+ catch (::com::sun::star::uno::RuntimeException &)
+ {
+ OSL_ENSURE(
+ 0, "### RuntimeException occured udring queryInterface()!" );
+ }
+ }
+}
+
+static void SAL_CALL computeObjectIdentifier(
+ uno_ExtEnvironment * pExtEnv, rtl_uString ** ppOId, void * pInterface )
+ SAL_THROW( () )
+{
+ uno_Environment_invoke(&pExtEnv->aBase, s_stub_computeObjectIdentifier, pExtEnv, ppOId, pInterface);
+}
+
+static void s_stub_acquireInterface(va_list * pParam)
+ SAL_THROW( () )
+{
+ /*uno_ExtEnvironment * pExtEnv = */va_arg(*pParam, uno_ExtEnvironment *);
+ void * pCppI = va_arg(*pParam, void *);
+
+ reinterpret_cast< ::com::sun::star::uno::XInterface * >( pCppI )->acquire();
+}
+
+static void SAL_CALL acquireInterface( uno_ExtEnvironment * pExtEnv, void * pCppI )
+ SAL_THROW( () )
+{
+ uno_Environment_invoke(&pExtEnv->aBase, s_stub_acquireInterface, pExtEnv, pCppI);
+}
+
+static void s_stub_releaseInterface(va_list * pParam)
+ SAL_THROW( () )
+{
+ /*uno_ExtEnvironment * pExtEnv = */va_arg(*pParam, uno_ExtEnvironment *);
+ void * pCppI = va_arg(*pParam, void *);
+
+ reinterpret_cast< ::com::sun::star::uno::XInterface * >( pCppI )->release();
+}
+
+static void SAL_CALL releaseInterface( uno_ExtEnvironment * pExtEnv, void * pCppI )
+ SAL_THROW( () )
+{
+ uno_Environment_invoke(&pExtEnv->aBase, s_stub_releaseInterface, pExtEnv, pCppI);
+}
+
+static void SAL_CALL environmentDisposing( uno_Environment * ) SAL_THROW( () )
+{
+ bridges::cpp_uno::shared::g_moduleCount.modCnt.release(
+ &bridges::cpp_uno::shared::g_moduleCount.modCnt );
+}
+
+sal_Bool SAL_CALL component_canUnload(TimeValue * pTime) SAL_THROW_EXTERN_C() {
+ return bridges::cpp_uno::shared::g_moduleCount.canUnload(
+ &bridges::cpp_uno::shared::g_moduleCount, pTime);
+}
+
+void SAL_CALL uno_initEnvironment(uno_Environment * pCppEnv)
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ENSURE( pCppEnv->pExtEnv, "### expected extended environment!" );
+ OSL_ENSURE(
+ ::rtl_ustr_ascii_compare_WithLength(
+ pCppEnv->pTypeName->buffer, rtl_str_getLength(CPPU_CURRENT_LANGUAGE_BINDING_NAME), CPPU_CURRENT_LANGUAGE_BINDING_NAME )
+ == 0,
+ "### wrong environment type!" );
+ bridges::cpp_uno::shared::g_moduleCount.modCnt.acquire(
+ &bridges::cpp_uno::shared::g_moduleCount.modCnt );
+ ((uno_ExtEnvironment *)pCppEnv)->computeObjectIdentifier
+ = computeObjectIdentifier;
+ ((uno_ExtEnvironment *)pCppEnv)->acquireInterface = acquireInterface;
+ ((uno_ExtEnvironment *)pCppEnv)->releaseInterface = releaseInterface;
+ pCppEnv->environmentDisposing = environmentDisposing;
+}
+
+void SAL_CALL uno_ext_getMapping(
+ uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo)
+ SAL_THROW_EXTERN_C()
+{
+ OSL_ASSERT( ppMapping && pFrom && pTo );
+ if (ppMapping && pFrom && pTo && pFrom->pExtEnv && pTo->pExtEnv)
+ {
+ uno_Mapping * pMapping = 0;
+
+ rtl::OUString from_envTypeName(cppu::EnvDcp::getTypeName(pFrom->pTypeName));
+ rtl::OUString to_envTypeName(cppu::EnvDcp::getTypeName(pTo->pTypeName));
+
+ if (0 == rtl_ustr_ascii_compare(
+ from_envTypeName.pData->buffer,
+ CPPU_CURRENT_LANGUAGE_BINDING_NAME ) &&
+ 0 == rtl_ustr_ascii_compare(
+ to_envTypeName.pData->buffer, UNO_LB_UNO ))
+ {
+ // ref count initially 1
+ pMapping = bridges::cpp_uno::shared::Bridge::createMapping(
+ pFrom->pExtEnv, pTo->pExtEnv, sal_True );
+ ::uno_registerMapping(
+ &pMapping, bridges::cpp_uno::shared::freeMapping,
+ (uno_Environment *)pFrom->pExtEnv,
+ (uno_Environment *)pTo->pExtEnv, 0 );
+ }
+ else if (0 == rtl_ustr_ascii_compare(
+ to_envTypeName.pData->buffer,
+ CPPU_CURRENT_LANGUAGE_BINDING_NAME ) &&
+ 0 == rtl_ustr_ascii_compare(
+ from_envTypeName.pData->buffer, UNO_LB_UNO ))
+ {
+ // ref count initially 1
+ pMapping = bridges::cpp_uno::shared::Bridge::createMapping(
+ pTo->pExtEnv, pFrom->pExtEnv, sal_False );
+ ::uno_registerMapping(
+ &pMapping, bridges::cpp_uno::shared::freeMapping,
+ (uno_Environment *)pFrom->pExtEnv,
+ (uno_Environment *)pTo->pExtEnv, 0 );
+ }
+
+ if (*ppMapping)
+ {
+ (*(*ppMapping)->release)( *ppMapping );
+ }
+ if (pMapping)
+ *ppMapping = pMapping;
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/shared/component.hxx b/bridges/source/cpp_uno/shared/component.hxx
new file mode 100644
index 000000000000..7be6cd7a6355
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/component.hxx
@@ -0,0 +1,42 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_SHARED_COMPONENT_HXX
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_SHARED_COMPONENT_HXX
+
+#include "rtl/unload.h"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+extern rtl_StandardModuleCount g_moduleCount;
+
+} } }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/shared/cppinterfaceproxy.cxx b/bridges/source/cpp_uno/shared/cppinterfaceproxy.cxx
new file mode 100644
index 000000000000..5b3c8eeba37e
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/cppinterfaceproxy.cxx
@@ -0,0 +1,208 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
+
+#include "guardedarray.hxx"
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "com/sun/star/uno/XInterface.hpp"
+#include "osl/diagnose.h"
+#include "osl/getglobalmutex.hxx"
+#include "osl/interlck.h"
+#include "osl/mutex.hxx"
+#include "rtl/instance.hxx"
+#include "typelib/typedescription.h"
+
+#include <cstddef>
+#include <new>
+
+
+static bridges::cpp_uno::shared::VtableFactory * pInstance;
+
+#if defined(__GNUG__) && !defined(__MINGW32__)
+void dso_init(void) __attribute__((constructor));
+void dso_exit(void) __attribute__((destructor));
+#endif
+
+void dso_init(void) {
+ if (!pInstance)
+ pInstance = new bridges::cpp_uno::shared::VtableFactory();
+}
+
+void dso_exit(void) {
+ if (pInstance)
+ {
+ delete pInstance;
+ pInstance = NULL;
+ }
+}
+
+#ifdef __SUNPRO_CC
+# pragma init(dso_init)
+# pragma fini(dso_exit)
+#endif
+
+
+
+namespace {
+
+struct InitVtableFactory {
+ bridges::cpp_uno::shared::VtableFactory * operator()() {
+ return pInstance;
+ }
+};
+
+bridges::cpp_uno::shared::VtableFactory * getVtableFactory() {
+ return rtl_Instance<
+ bridges::cpp_uno::shared::VtableFactory, InitVtableFactory,
+ osl::MutexGuard, osl::GetGlobalMutex >::create(
+ InitVtableFactory(), osl::GetGlobalMutex());
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void freeCppInterfaceProxy(uno_ExtEnvironment * pEnv, void * pInterface)
+{
+ CppInterfaceProxy * pThis = CppInterfaceProxy::castInterfaceToProxy(
+ pInterface);
+ if (pEnv != pThis->pBridge->getCppEnv()) {
+ OSL_ASSERT(false);
+ }
+
+ (*pThis->pBridge->getUnoEnv()->revokeInterface)(
+ pThis->pBridge->getUnoEnv(), pThis->pUnoI );
+ (*pThis->pUnoI->release)( pThis->pUnoI );
+ ::typelib_typedescription_release(
+ (typelib_TypeDescription *)pThis->pTypeDescr );
+ pThis->pBridge->release();
+
+#if OSL_DEBUG_LEVEL > 1
+ *(int *)pInterface = 0xdeadbabe;
+#endif
+ pThis->~CppInterfaceProxy();
+ delete[] reinterpret_cast< char * >(pThis);
+}
+
+com::sun::star::uno::XInterface * CppInterfaceProxy::create(
+ bridges::cpp_uno::shared::Bridge * pBridge, uno_Interface * pUnoI,
+ typelib_InterfaceTypeDescription * pTypeDescr, rtl::OUString const & rOId)
+ SAL_THROW(())
+{
+ typelib_typedescription_complete(
+ reinterpret_cast< typelib_TypeDescription ** >(&pTypeDescr));
+ bridges::cpp_uno::shared::VtableFactory::Vtables aVtables(
+ getVtableFactory()->getVtables(pTypeDescr));
+ bridges::cpp_uno::shared::GuardedArray< char > pMemory(
+ new char[
+ sizeof (CppInterfaceProxy)
+ + (aVtables.count - 1) * sizeof (void **)]);
+ new(pMemory.get()) CppInterfaceProxy(pBridge, pUnoI, pTypeDescr, rOId);
+ CppInterfaceProxy * pProxy = reinterpret_cast< CppInterfaceProxy * >(
+ pMemory.release());
+ for (sal_Int32 i = 0; i < aVtables.count; ++i) {
+ pProxy->vtables[i] = VtableFactory::mapBlockToVtable(
+ aVtables.blocks[i].start);
+ }
+ return castProxyToInterface(pProxy);
+}
+
+void CppInterfaceProxy::acquireProxy() SAL_THROW(())
+{
+ if (1 == osl_incrementInterlockedCount( &nRef ))
+ {
+ // rebirth of proxy zombie
+ // register at cpp env
+ void * pThis = castProxyToInterface( this );
+ (*pBridge->getCppEnv()->registerProxyInterface)(
+ pBridge->getCppEnv(), &pThis, freeCppInterfaceProxy, oid.pData,
+ pTypeDescr );
+ OSL_ASSERT( pThis == castProxyToInterface( this ) );
+ }
+}
+
+void CppInterfaceProxy::releaseProxy() SAL_THROW(())
+{
+ if (! osl_decrementInterlockedCount( &nRef )) // last release
+ {
+ // revoke from cpp env
+ (*pBridge->getCppEnv()->revokeInterface)(
+ pBridge->getCppEnv(), castProxyToInterface( this ) );
+ }
+}
+
+CppInterfaceProxy::CppInterfaceProxy(
+ bridges::cpp_uno::shared::Bridge * pBridge_, uno_Interface * pUnoI_,
+ typelib_InterfaceTypeDescription * pTypeDescr_, rtl::OUString const & rOId_)
+ SAL_THROW(())
+ : nRef( 1 )
+ , pBridge( pBridge_ )
+ , pUnoI( pUnoI_ )
+ , pTypeDescr( pTypeDescr_ )
+ , oid( rOId_ )
+{
+ pBridge->acquire();
+ ::typelib_typedescription_acquire( (typelib_TypeDescription *)pTypeDescr );
+ (*pUnoI->acquire)( pUnoI );
+ (*pBridge->getUnoEnv()->registerInterface)(
+ pBridge->getUnoEnv(), reinterpret_cast< void ** >( &pUnoI ), oid.pData,
+ pTypeDescr );
+}
+
+CppInterfaceProxy::~CppInterfaceProxy()
+{}
+
+com::sun::star::uno::XInterface * CppInterfaceProxy::castProxyToInterface(
+ CppInterfaceProxy * pProxy)
+{
+ return reinterpret_cast< com::sun::star::uno::XInterface * >(
+ &pProxy->vtables);
+}
+
+CppInterfaceProxy * CppInterfaceProxy::castInterfaceToProxy(void * pInterface)
+{
+ // pInterface == &pProxy->vtables (this emulated offsetof is not truly
+ // portable):
+ char const * const base = reinterpret_cast< char const * >(16);
+ std::ptrdiff_t const offset = reinterpret_cast< char const * >(
+ &reinterpret_cast< CppInterfaceProxy const * >(base)->vtables) - base;
+ return reinterpret_cast< CppInterfaceProxy * >(
+ static_cast< char * >(pInterface) - offset);
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/shared/guardedarray.hxx b/bridges/source/cpp_uno/shared/guardedarray.hxx
new file mode 100644
index 000000000000..9e4e0f3b0cad
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/guardedarray.hxx
@@ -0,0 +1,55 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_SHARED_GUARDEDARRAY_HXX
+#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_SHARED_GUARDEDARRAY_HXX
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+template< typename T > class GuardedArray {
+public:
+ explicit GuardedArray(T * thePointer): pointer(thePointer) {}
+
+ ~GuardedArray() { delete[] pointer; }
+
+ T * get() const { return pointer; }
+
+ T * release() { T * p = pointer; pointer = 0; return p; }
+
+private:
+ GuardedArray(GuardedArray &); // not implemented
+ void operator =(GuardedArray); // not implemented
+
+ T * pointer;
+};
+
+} } }
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/shared/makefile.mk b/bridges/source/cpp_uno/shared/makefile.mk
new file mode 100644
index 000000000000..4ce8122f3261
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/makefile.mk
@@ -0,0 +1,53 @@
+#*************************************************************************
+#
+# 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 = cpp_uno_shared
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE: settings.mk
+
+SLOFILES = \
+ $(SLO)$/bridge.obj \
+ $(SLO)$/component.obj \
+ $(SLO)$/cppinterfaceproxy.obj \
+ $(SLO)$/types.obj \
+ $(SLO)$/unointerfaceproxy.obj \
+ $(SLO)$/vtablefactory.obj \
+ $(SLO)$/vtables.obj
+
+# Disable optimization for cppinterfaceproxy.cxx -
+# attribute constructor / destructor do not get called otherwise.
+.IF "$(COM)" == "GCC"
+NOOPTFILES = \
+ $(SLO)$/cppinterfaceproxy.obj
+.ENDIF
+
+
+.INCLUDE: target.mk
diff --git a/bridges/source/cpp_uno/shared/types.cxx b/bridges/source/cpp_uno/shared/types.cxx
new file mode 100644
index 000000000000..cf442082f283
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/types.cxx
@@ -0,0 +1,129 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "bridges/cpp_uno/shared/types.hxx"
+#define INCLUDED_BRIDGES_CPP_UNO_SHARED_VTABLES_HXX
+
+#include "typelib/typeclass.h"
+#include "typelib/typedescription.h"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+bool isSimpleType(typelib_TypeClass typeClass) {
+ return typeClass <= typelib_TypeClass_DOUBLE
+ || typeClass == typelib_TypeClass_ENUM;
+}
+
+bool isSimpleType(typelib_TypeDescriptionReference const * type) {
+ return isSimpleType(type->eTypeClass);
+}
+
+bool isSimpleType(typelib_TypeDescription const * type) {
+ return isSimpleType(type->eTypeClass);
+}
+
+bool relatesToInterfaceType(typelib_TypeDescription const * type) {
+ switch (type->eTypeClass) {
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_INTERFACE:
+ return true;
+
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_CompoundTypeDescription const * p
+ = reinterpret_cast< typelib_CompoundTypeDescription const * >(
+ type);
+ for (sal_Int32 i = 0; i < p->nMembers; ++i) {
+ switch (p->ppTypeRefs[i]->eTypeClass) {
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_INTERFACE:
+ return true;
+
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_SEQUENCE:
+ {
+ typelib_TypeDescription * t = 0;
+ TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
+ bool b = relatesToInterfaceType(t);
+ TYPELIB_DANGER_RELEASE(t);
+ if (b) {
+ return true;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ if (p->pBaseTypeDescription != 0) {
+ return relatesToInterfaceType(&p->pBaseTypeDescription->aBase);
+ }
+ }
+ break;
+
+ case typelib_TypeClass_SEQUENCE:
+ switch (reinterpret_cast< typelib_IndirectTypeDescription const * >(
+ type)->pType->eTypeClass) {
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_INTERFACE:
+ return true;
+
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_SEQUENCE:
+ {
+ typelib_TypeDescription * t = 0;
+ TYPELIB_DANGER_GET(
+ &t,
+ reinterpret_cast< typelib_IndirectTypeDescription const * >(
+ type)->pType);
+ bool b = relatesToInterfaceType(t);
+ TYPELIB_DANGER_RELEASE(t);
+ return b;
+ }
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return false;
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/shared/unointerfaceproxy.cxx b/bridges/source/cpp_uno/shared/unointerfaceproxy.cxx
new file mode 100644
index 000000000000..e3159f12190d
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/unointerfaceproxy.cxx
@@ -0,0 +1,145 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
+
+#include "bridges/cpp_uno/shared/bridge.hxx"
+
+#include "com/sun/star/uno/XInterface.hpp"
+#include "osl/diagnose.h"
+#include "osl/interlck.h"
+#include "typelib/typedescription.h"
+#include "uno/dispatcher.h"
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void freeUnoInterfaceProxy(uno_ExtEnvironment * pEnv, void * pProxy)
+{
+ UnoInterfaceProxy * pThis =
+ static_cast< UnoInterfaceProxy * >(
+ reinterpret_cast< uno_Interface * >( pProxy ) );
+ if (pEnv != pThis->pBridge->getUnoEnv()) {
+ OSL_ASSERT(false);
+ }
+
+ (*pThis->pBridge->getCppEnv()->revokeInterface)(
+ pThis->pBridge->getCppEnv(), pThis->pCppI );
+ pThis->pCppI->release();
+ ::typelib_typedescription_release(
+ (typelib_TypeDescription *)pThis->pTypeDescr );
+ pThis->pBridge->release();
+
+#if OSL_DEBUG_LEVEL > 1
+ *(int *)pProxy = 0xdeadbabe;
+#endif
+ delete pThis;
+}
+
+void acquireProxy(uno_Interface * pUnoI)
+{
+ if (1 == osl_incrementInterlockedCount(
+ & static_cast< UnoInterfaceProxy * >( pUnoI )->nRef ))
+ {
+ // rebirth of proxy zombie
+ // register at uno env
+#if OSL_DEBUG_LEVEL > 1
+ void * pThis = pUnoI;
+#endif
+ (*static_cast< UnoInterfaceProxy * >( pUnoI )->pBridge->getUnoEnv()->
+ registerProxyInterface)(
+ static_cast< UnoInterfaceProxy * >( pUnoI )->pBridge->getUnoEnv(),
+ reinterpret_cast< void ** >( &pUnoI ), freeUnoInterfaceProxy,
+ static_cast< UnoInterfaceProxy * >( pUnoI )->oid.pData,
+ static_cast< UnoInterfaceProxy * >( pUnoI )->pTypeDescr );
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ASSERT( pThis == pUnoI );
+#endif
+ }
+}
+
+void releaseProxy(uno_Interface * pUnoI)
+{
+ if (! osl_decrementInterlockedCount(
+ & static_cast< UnoInterfaceProxy * >( pUnoI )->nRef ))
+ {
+ // revoke from uno env on last release
+ (*static_cast< UnoInterfaceProxy * >( pUnoI )->pBridge->getUnoEnv()->
+ revokeInterface)(
+ static_cast< UnoInterfaceProxy * >( pUnoI )->pBridge->getUnoEnv(),
+ pUnoI );
+ }
+}
+
+UnoInterfaceProxy * UnoInterfaceProxy::create(
+ bridges::cpp_uno::shared::Bridge * pBridge,
+ com::sun::star::uno::XInterface * pCppI,
+ typelib_InterfaceTypeDescription * pTypeDescr,
+ rtl::OUString const & rOId) SAL_THROW(())
+{
+ return new UnoInterfaceProxy(pBridge, pCppI, pTypeDescr, rOId);
+}
+
+UnoInterfaceProxy::UnoInterfaceProxy(
+ bridges::cpp_uno::shared::Bridge * pBridge_,
+ com::sun::star::uno::XInterface * pCppI_,
+ typelib_InterfaceTypeDescription * pTypeDescr_, rtl::OUString const & rOId_)
+ SAL_THROW(())
+ : nRef( 1 )
+ , pBridge( pBridge_ )
+ , pCppI( pCppI_ )
+ , pTypeDescr( pTypeDescr_ )
+ , oid( rOId_ )
+{
+ pBridge->acquire();
+ ::typelib_typedescription_acquire( (typelib_TypeDescription *)pTypeDescr );
+ if (! ((typelib_TypeDescription *)pTypeDescr)->bComplete)
+ ::typelib_typedescription_complete(
+ (typelib_TypeDescription **)&pTypeDescr );
+ OSL_ENSURE(
+ ((typelib_TypeDescription *)pTypeDescr)->bComplete,
+ "### type is incomplete!" );
+ pCppI->acquire();
+ (*pBridge->getCppEnv()->registerInterface)(
+ pBridge->getCppEnv(), reinterpret_cast< void ** >( &pCppI ), oid.pData,
+ pTypeDescr );
+
+ // uno_Interface
+ acquire = acquireProxy;
+ release = releaseProxy;
+ pDispatcher = unoInterfaceProxyDispatch;
+}
+
+UnoInterfaceProxy::~UnoInterfaceProxy()
+{}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/shared/vtablefactory.cxx b/bridges/source/cpp_uno/shared/vtablefactory.cxx
new file mode 100644
index 000000000000..02247de10bf3
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/vtablefactory.cxx
@@ -0,0 +1,385 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#if defined OS2
+#define INCL_DOS
+#define INCL_DOSMISC
+#endif
+
+#include "bridges/cpp_uno/shared/vtablefactory.hxx"
+
+#include "guardedarray.hxx"
+
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "osl/thread.h"
+#include "osl/security.hxx"
+#include "osl/file.hxx"
+#include "osl/diagnose.h"
+#include "osl/mutex.hxx"
+#include "rtl/alloc.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "typelib/typedescription.hxx"
+
+#include <hash_map>
+#include <new>
+#include <vector>
+
+#if defined SAL_UNX
+#include <unistd.h>
+#include <string.h>
+#include <sys/mman.h>
+#elif defined SAL_W32
+#define WIN32_LEAN_AND_MEAN
+#ifdef _MSC_VER
+#pragma warning(push,1) // disable warnings within system headers
+#endif
+#include <windows.h>
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+#elif defined SAL_OS2
+#define INCL_DOS
+#define INCL_DOSMISC
+#include <os2.h>
+#else
+#error Unsupported platform
+#endif
+
+using bridges::cpp_uno::shared::VtableFactory;
+
+namespace {
+
+extern "C" void * SAL_CALL allocExec(rtl_arena_type *, sal_Size * size) {
+ sal_Size pagesize;
+#if defined SAL_UNX
+#if defined FREEBSD || defined NETBSD || defined OPENBSD
+ pagesize = getpagesize();
+#else
+ pagesize = sysconf(_SC_PAGESIZE);
+#endif
+#elif defined SAL_W32
+ SYSTEM_INFO info;
+ GetSystemInfo(&info);
+ pagesize = info.dwPageSize;
+#elif defined(SAL_OS2)
+ ULONG ulPageSize;
+ DosQuerySysInfo(QSV_PAGE_SIZE, QSV_PAGE_SIZE, &ulPageSize, sizeof(ULONG));
+ pagesize = (sal_Size)ulPageSize;
+#else
+#error Unsupported platform
+#endif
+ sal_Size n = (*size + (pagesize - 1)) & ~(pagesize - 1);
+ void * p;
+#if defined SAL_UNX
+ p = mmap(
+ 0, n, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1,
+ 0);
+ if (p == MAP_FAILED) {
+ p = 0;
+ }
+ else if (mprotect (static_cast<char*>(p), n, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
+ {
+ munmap (static_cast<char*>(p), n);
+ p = 0;
+ }
+#elif defined SAL_W32
+ p = VirtualAlloc(0, n, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
+#elif defined(SAL_OS2)
+ p = 0;
+ DosAllocMem( &p, n, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_ANY);
+#endif
+ if (p != 0) {
+ *size = n;
+ }
+ return p;
+}
+
+extern "C" void SAL_CALL freeExec(
+ rtl_arena_type *, void * address, sal_Size size)
+{
+#if defined SAL_UNX
+ munmap(static_cast< char * >(address), size);
+#elif defined SAL_W32
+ (void) size; // unused
+ VirtualFree(address, 0, MEM_RELEASE);
+#elif defined(SAL_OS2)
+ (void) DosFreeMem( address);
+#endif
+}
+
+}
+
+class VtableFactory::GuardedBlocks: public std::vector< Block > {
+public:
+ GuardedBlocks(VtableFactory const & factory):
+ m_factory(factory), m_guarded(true) {}
+
+ ~GuardedBlocks();
+
+ void unguard() { m_guarded = false; }
+
+private:
+ GuardedBlocks(GuardedBlocks &); // not implemented
+ void operator =(GuardedBlocks); // not implemented
+
+ VtableFactory const & m_factory;
+ bool m_guarded;
+};
+
+VtableFactory::GuardedBlocks::~GuardedBlocks() {
+ if (m_guarded) {
+ for (iterator i(begin()); i != end(); ++i) {
+ m_factory.freeBlock(*i);
+ }
+ }
+}
+
+class VtableFactory::BaseOffset {
+public:
+ BaseOffset(typelib_InterfaceTypeDescription * type) { calculate(type, 0); }
+
+ sal_Int32 getFunctionOffset(rtl::OUString const & name) const
+ { return m_map.find(name)->second; }
+
+private:
+ sal_Int32 calculate(
+ typelib_InterfaceTypeDescription * type, sal_Int32 offset);
+
+ typedef std::hash_map< rtl::OUString, sal_Int32, rtl::OUStringHash > Map;
+
+ Map m_map;
+};
+
+sal_Int32 VtableFactory::BaseOffset::calculate(
+ typelib_InterfaceTypeDescription * type, sal_Int32 offset)
+{
+ rtl::OUString name(type->aBase.pTypeName);
+ if (m_map.find(name) == m_map.end()) {
+ for (sal_Int32 i = 0; i < type->nBaseTypes; ++i) {
+ offset = calculate(type->ppBaseTypes[i], offset);
+ }
+ m_map.insert(Map::value_type(name, offset));
+ typelib_typedescription_complete(
+ reinterpret_cast< typelib_TypeDescription ** >(&type));
+ offset += bridges::cpp_uno::shared::getLocalFunctions(type);
+ }
+ return offset;
+}
+
+VtableFactory::VtableFactory(): m_arena(
+ rtl_arena_create(
+ "bridges::cpp_uno::shared::VtableFactory",
+ sizeof (void *), // to satisfy alignment requirements
+ 0, reinterpret_cast< rtl_arena_type * >(-1), allocExec, freeExec, 0))
+{
+ if (m_arena == 0) {
+ throw std::bad_alloc();
+ }
+}
+
+VtableFactory::~VtableFactory() {
+ {
+ osl::MutexGuard guard(m_mutex);
+ for (Map::iterator i(m_map.begin()); i != m_map.end(); ++i) {
+ for (sal_Int32 j = 0; j < i->second.count; ++j) {
+ freeBlock(i->second.blocks[j]);
+ }
+ delete[] i->second.blocks;
+ }
+ }
+ rtl_arena_destroy(m_arena);
+}
+
+VtableFactory::Vtables VtableFactory::getVtables(
+ typelib_InterfaceTypeDescription * type)
+{
+ rtl::OUString name(type->aBase.pTypeName);
+ osl::MutexGuard guard(m_mutex);
+ Map::iterator i(m_map.find(name));
+ if (i == m_map.end()) {
+ GuardedBlocks blocks(*this);
+ createVtables(blocks, BaseOffset(type), type, true);
+ Vtables vtables;
+ OSL_ASSERT(blocks.size() <= SAL_MAX_INT32);
+ vtables.count = static_cast< sal_Int32 >(blocks.size());
+ bridges::cpp_uno::shared::GuardedArray< Block > guardedBlocks(
+ new Block[vtables.count]);
+ vtables.blocks = guardedBlocks.get();
+ for (sal_Int32 j = 0; j < vtables.count; ++j) {
+ vtables.blocks[j] = blocks[j];
+ }
+ i = m_map.insert(Map::value_type(name, vtables)).first;
+ guardedBlocks.release();
+ blocks.unguard();
+ }
+ return i->second;
+}
+
+#ifdef USE_DOUBLE_MMAP
+bool VtableFactory::createBlock(Block &block, sal_Int32 slotCount) const
+{
+ sal_Size size = getBlockSize(slotCount);
+ sal_Size pagesize = sysconf(_SC_PAGESIZE);
+ block.size = (size + (pagesize - 1)) & ~(pagesize - 1);
+ block.start = block.exec = NULL;
+ block.fd = -1;
+
+ osl::Security aSecurity;
+ rtl::OUString strDirectory;
+ rtl::OUString strURLDirectory;
+ if (aSecurity.getHomeDir(strURLDirectory))
+ osl::File::getSystemPathFromFileURL(strURLDirectory, strDirectory);
+
+ for (int i = strDirectory.getLength() == 0 ? 1 : 0; i < 2; ++i)
+ {
+ if (!strDirectory.getLength())
+ strDirectory = rtl::OUString::createFromAscii("/tmp");
+
+ strDirectory += rtl::OUString::createFromAscii("/.execoooXXXXXX");
+ rtl::OString aTmpName = rtl::OUStringToOString(strDirectory, osl_getThreadTextEncoding());
+ char *tmpfname = new char[aTmpName.getLength()+1];
+ strncpy(tmpfname, aTmpName.getStr(), aTmpName.getLength()+1);
+ if ((block.fd = mkstemp(tmpfname)) == -1)
+ perror("creation of executable memory area failed");
+ if (block.fd == -1)
+ {
+ delete[] tmpfname;
+ break;
+ }
+ unlink(tmpfname);
+ delete[] tmpfname;
+ if (ftruncate(block.fd, block.size) == -1)
+ {
+ perror("truncation of executable memory area failed");
+ close(block.fd);
+ block.fd = -1;
+ break;
+ }
+ block.start = mmap(NULL, block.size, PROT_READ | PROT_WRITE, MAP_SHARED, block.fd, 0);
+ if (block.start== MAP_FAILED) {
+ block.start = 0;
+ }
+ block.exec = mmap(NULL, block.size, PROT_READ | PROT_EXEC, MAP_SHARED, block.fd, 0);
+ if (block.exec == MAP_FAILED) {
+ block.exec = 0;
+ }
+
+ //All good
+ if (block.start && block.exec && block.fd != -1)
+ break;
+
+ freeBlock(block);
+
+ strDirectory = rtl::OUString();
+ }
+ if (!block.start || !block.exec || block.fd == -1)
+ {
+ //Fall back to non-doublemmaped allocation
+ block.fd = -1;
+ block.start = block.exec = rtl_arena_alloc(m_arena, &block.size);
+ }
+ return (block.start != 0 && block.exec != 0);
+}
+
+void VtableFactory::freeBlock(Block const & block) const {
+ //if the double-map failed we were allocated on the arena
+ if (block.fd == -1 && block.start == block.exec && block.start != NULL)
+ rtl_arena_free(m_arena, block.start, block.size);
+ else
+ {
+ if (block.start) munmap(block.start, block.size);
+ if (block.exec) munmap(block.exec, block.size);
+ if (block.fd != -1) close(block.fd);
+ }
+}
+#else
+bool VtableFactory::createBlock(Block &block, sal_Int32 slotCount) const
+{
+ block.size = getBlockSize(slotCount);
+ block.start = rtl_arena_alloc(m_arena, &block.size);
+ return block.start != 0;
+}
+
+void VtableFactory::freeBlock(Block const & block) const {
+ rtl_arena_free(m_arena, block.start, block.size);
+}
+#endif
+
+void VtableFactory::createVtables(
+ GuardedBlocks & blocks, BaseOffset const & baseOffset,
+ typelib_InterfaceTypeDescription * type, bool includePrimary) const
+{
+ if (includePrimary) {
+ sal_Int32 slotCount
+ = bridges::cpp_uno::shared::getPrimaryFunctions(type);
+ Block block;
+ if (!createBlock(block, slotCount)) {
+ throw std::bad_alloc();
+ }
+ try {
+ Slot * slots = initializeBlock(block.start, slotCount);
+ unsigned char * codeBegin =
+ reinterpret_cast< unsigned char * >(slots);
+ unsigned char * code = codeBegin;
+ sal_Int32 vtableOffset = blocks.size() * sizeof (Slot *);
+ for (typelib_InterfaceTypeDescription const * type2 = type;
+ type2 != 0; type2 = type2->pBaseTypeDescription)
+ {
+ code = addLocalFunctions(
+ &slots, code,
+#ifdef USE_DOUBLE_MMAP
+ sal_IntPtr(block.exec) - sal_IntPtr(block.start),
+#endif
+ type2,
+ baseOffset.getFunctionOffset(type2->aBase.pTypeName),
+ bridges::cpp_uno::shared::getLocalFunctions(type2),
+ vtableOffset);
+ }
+ flushCode(codeBegin, code);
+#ifdef USE_DOUBLE_MMAP
+ //Finished generating block, swap writable pointer with executable
+ //pointer
+ ::std::swap(block.start, block.exec);
+#endif
+ blocks.push_back(block);
+ } catch (...) {
+ freeBlock(block);
+ throw;
+ }
+ }
+ for (sal_Int32 i = 0; i < type->nBaseTypes; ++i) {
+ createVtables(blocks, baseOffset, type->ppBaseTypes[i], i != 0);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/shared/vtables.cxx b/bridges/source/cpp_uno/shared/vtables.cxx
new file mode 100644
index 000000000000..40436d0224fb
--- /dev/null
+++ b/bridges/source/cpp_uno/shared/vtables.cxx
@@ -0,0 +1,157 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "bridges/cpp_uno/shared/vtables.hxx"
+
+#include "osl/diagnose.h"
+#include "sal/types.h"
+#include "typelib/typedescription.h"
+
+#include <algorithm>
+
+namespace
+{
+
+/**
+ * Calculates the number of vtables associated with an interface type.
+ *
+ * <p>Multiple-inheritance C++ classes have more than one vtable.</p>
+ *
+ * @param type a non-null pointer to an interface type description
+ * @return the number of vtables associated with the given interface type
+ */
+sal_Int32 getVtableCount(typelib_InterfaceTypeDescription const * type) {
+ sal_Int32 n = 0;
+ for (sal_Int32 i = 0; i < type->nBaseTypes; ++i) {
+ n += getVtableCount(type->ppBaseTypes[i]);
+ }
+ return std::max< sal_Int32 >(n, 1);
+}
+
+/**
+ * Maps a local member index to a local function index.
+ *
+ * <p><em>Local</em> members/functions are those not inherited from any base
+ * types. The number of <em>functions</em> is potentially larger than the
+ * number of <em>members</em>, as each read&ndash;write attribute member counts
+ * as two functions.</p>
+ *
+ * @param type a non-null pointer to an interface type description
+ * @param localMember a local member index, relative to the given interface type
+ * @return the local function index corresponding to the given local member
+ * index, relative to the given interface type
+ */
+sal_Int32 mapLocalMemberToLocalFunction(
+ typelib_InterfaceTypeDescription * type, sal_Int32 localMember)
+{
+ typelib_typedescription_complete(
+ reinterpret_cast< typelib_TypeDescription ** >(&type));
+ sal_Int32 localMemberOffset = type->nAllMembers - type->nMembers;
+ sal_Int32 localFunctionOffset = type->nMapFunctionIndexToMemberIndex
+ - bridges::cpp_uno::shared::getLocalFunctions(type);
+ return type->pMapMemberIndexToFunctionIndex[localMemberOffset + localMember]
+ - localFunctionOffset;
+}
+
+// Since on Solaris we compile with --instances=static, getVtableSlot cannot be
+// a template function, with explicit instantiates for
+// T = typelib_InterfaceAttributeTypeDescription and
+// T = typelib_InterfaceMethodTypeDescription in this file; hence, there are two
+// overloaded versions of getVtableSlot that both delegate to this template
+// function:
+template< typename T > bridges::cpp_uno::shared::VtableSlot doGetVtableSlot(
+ T const * ifcMember)
+{
+ bridges::cpp_uno::shared::VtableSlot slot;
+ slot.offset = 0;
+ T * member = const_cast< T * >(ifcMember);
+ while (member->pBaseRef != 0) {
+ OSL_ASSERT(member->nIndex < member->pInterface->nBaseTypes);
+ for (sal_Int32 i = 0; i < member->nIndex; ++i) {
+ slot.offset += getVtableCount(member->pInterface->ppBaseTypes[i]);
+ }
+ typelib_TypeDescription * desc = 0;
+ typelib_typedescriptionreference_getDescription(
+ &desc, member->pBaseRef);
+ OSL_ASSERT(
+ desc != 0 && desc->eTypeClass == member->aBase.aBase.eTypeClass);
+ if (member != ifcMember) {
+ typelib_typedescription_release(&member->aBase.aBase);
+ }
+ member = reinterpret_cast< T * >(desc);
+ }
+ slot.index
+ = bridges::cpp_uno::shared::getPrimaryFunctions(
+ member->pInterface->pBaseTypeDescription)
+ + mapLocalMemberToLocalFunction(member->pInterface, member->nIndex);
+ if (member != ifcMember) {
+ typelib_typedescription_release(&member->aBase.aBase);
+ }
+ return slot;
+}
+
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+sal_Int32 getLocalFunctions(typelib_InterfaceTypeDescription const * type) {
+ return type->nMembers == 0
+ ? 0
+ : (type->nMapFunctionIndexToMemberIndex
+ - type->pMapMemberIndexToFunctionIndex[
+ type->nAllMembers - type->nMembers]);
+}
+
+sal_Int32 getPrimaryFunctions(typelib_InterfaceTypeDescription * type) {
+ sal_Int32 n = 0;
+ for (; type != 0; type = type->pBaseTypeDescription) {
+ typelib_typedescription_complete(
+ reinterpret_cast< typelib_TypeDescription ** >(&type));
+ n += getLocalFunctions(type);
+ }
+ return n;
+}
+
+VtableSlot getVtableSlot(
+ typelib_InterfaceAttributeTypeDescription const * ifcMember)
+{
+ return doGetVtableSlot(ifcMember);
+}
+
+VtableSlot getVtableSlot(
+ typelib_InterfaceMethodTypeDescription const * ifcMember)
+{
+ return doGetVtableSlot(ifcMember);
+}
+
+} } }
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_info_holder.java b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_info_holder.java
new file mode 100644
index 000000000000..223b53a7013f
--- /dev/null
+++ b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_info_holder.java
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.bridges.jni_uno;
+
+import com.sun.star.lib.util.NativeLibraryLoader;
+
+//==============================================================================
+public final class JNI_info_holder
+{
+ static {
+ NativeLibraryLoader.loadLibrary(JNI_info_holder.class.getClassLoader(),
+ "java_uno");
+ }
+
+ private static JNI_info_holder s_holder = new JNI_info_holder();
+
+ private static long s_jni_info_handle;
+
+ //__________________________________________________________________________
+ private native void finalize( long jni_info_handle );
+
+ //__________________________________________________________________________
+ protected void finalize()
+ {
+ finalize( s_jni_info_handle );
+ }
+}
diff --git a/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_proxy.java b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_proxy.java
new file mode 100644
index 000000000000..076d568e9c91
--- /dev/null
+++ b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_proxy.java
@@ -0,0 +1,218 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.bridges.jni_uno;
+
+import com.sun.star.lib.util.AsynchronousFinalizer;
+import com.sun.star.lib.util.NativeLibraryLoader;
+import com.sun.star.uno.Type;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.IEnvironment;
+import com.sun.star.uno.IQueryInterface;
+
+
+//==============================================================================
+public final class JNI_proxy implements java.lang.reflect.InvocationHandler
+{
+ static {
+ NativeLibraryLoader.loadLibrary(JNI_proxy.class.getClassLoader(),
+ "java_uno");
+ }
+ protected static ClassLoader s_classloader =
+ JNI_proxy.class.getClassLoader();
+ protected static Class s_InvocationHandler [] =
+ new Class [] { java.lang.reflect.InvocationHandler.class };
+
+ protected long m_bridge_handle;
+ protected IEnvironment m_java_env;
+ protected long m_receiver_handle;
+ protected long m_td_handle;
+ protected Type m_type;
+ protected String m_oid;
+ protected Class m_class;
+
+ //__________________________________________________________________________
+ public static String get_stack_trace( Throwable throwable )
+ throws Throwable
+ {
+ boolean current_trace = false;
+ if (null == throwable)
+ {
+ throwable = new Throwable();
+ current_trace = true;
+ }
+ java.io.StringWriter string_writer =
+ new java.io.StringWriter();
+ java.io.PrintWriter print_writer =
+ new java.io.PrintWriter( string_writer, true );
+ throwable.printStackTrace( print_writer );
+ print_writer.flush();
+ print_writer.close();
+ string_writer.flush();
+ String trace = string_writer.toString();
+ if (current_trace)
+ {
+ // cut out first two lines
+ int n = trace.indexOf( '\n' );
+ n = trace.indexOf( '\n', n +1 );
+ trace = trace.substring( n +1 );
+ }
+ return "\njava stack trace:\n" + trace;
+ }
+
+ //__________________________________________________________________________
+ private native void finalize( long bridge_handle );
+
+ //__________________________________________________________________________
+ public void finalize()
+ {
+ AsynchronousFinalizer.add(new AsynchronousFinalizer.Job() {
+ public void run() throws Throwable {
+ JNI_proxy.this.finalize( m_bridge_handle );
+ }
+ });
+ }
+
+ //__________________________________________________________________________
+ private JNI_proxy(
+ long bridge_handle, IEnvironment java_env,
+ long receiver_handle, long td_handle, Type type, String oid )
+ {
+ m_bridge_handle = bridge_handle;
+ m_java_env = java_env;
+ m_receiver_handle = receiver_handle;
+ m_td_handle = td_handle;
+ m_type = type;
+ m_oid = oid;
+ m_class = m_type.getZClass();
+ }
+
+ //__________________________________________________________________________
+ public static Object create(
+ long bridge_handle, IEnvironment java_env,
+ long receiver_handle, long td_handle, Type type, String oid,
+ java.lang.reflect.Constructor proxy_ctor )
+ throws Throwable
+ {
+ JNI_proxy handler = new JNI_proxy(
+ bridge_handle, java_env, receiver_handle, td_handle, type, oid );
+ Object proxy = proxy_ctor.newInstance( new Object [] { handler } );
+ return java_env.registerInterface( proxy, new String [] { oid }, type );
+ }
+
+ //__________________________________________________________________________
+ public static java.lang.reflect.Constructor get_proxy_ctor( Class clazz )
+ throws Throwable
+ {
+ Class proxy_class = java.lang.reflect.Proxy.getProxyClass(
+ s_classloader,
+ new Class [] { clazz, IQueryInterface.class,
+ com.sun.star.lib.uno.Proxy.class } );
+ return proxy_class.getConstructor( s_InvocationHandler );
+ }
+
+ //__________________________________________________________________________
+ private native Object dispatch_call(
+ long bridge_handle, String decl_class, String method, Object args [] )
+ throws Throwable;
+
+ // InvocationHandler impl
+ //__________________________________________________________________________
+ public Object invoke(
+ Object proxy, java.lang.reflect.Method method, Object args [] )
+ throws Throwable
+ {
+ Class decl_class = method.getDeclaringClass();
+ String method_name = method.getName();
+
+ if (Object.class.equals( decl_class ))
+ {
+ if (method_name.equals( "hashCode" ))
+ {
+ // int hashCode()
+ return new Integer( m_oid.hashCode() );
+ }
+ else if (method_name.equals( "equals" ))
+ {
+ // boolean equals( Object obj )
+ return isSame(args[0]);
+ }
+ else if (method_name.equals( "toString" ))
+ {
+ // String toString()
+ return this.toString() + " [oid=" + m_oid +
+ ", type=" + m_type.getTypeName() + "]";
+ }
+ }
+ // UNO interface call
+ else if (decl_class.isAssignableFrom( m_class ))
+ {
+ // dispatch interface call
+ return dispatch_call(
+ m_bridge_handle, decl_class.getName(), method_name, args );
+ }
+ // IQueryInterface impl
+ else if (IQueryInterface.class.equals( decl_class ))
+ {
+ if (method_name.equals( "queryInterface" ))
+ {
+ // Object queryInterface( Type type )
+ Object registered_proxy =
+ m_java_env.getRegisteredInterface( m_oid, (Type)args[ 0 ] );
+ if (null == registered_proxy)
+ {
+ return dispatch_call(
+ m_bridge_handle,
+ "com.sun.star.uno.XInterface", method_name, args );
+ }
+ else
+ {
+ return registered_proxy;
+ }
+ }
+ else if (method_name.equals( "isSame" ))
+ {
+ // boolean isSame( Object object )
+ return isSame(args[0]);
+ }
+ else if (method_name.equals( "getOid" ))
+ {
+ // String getOid()
+ return m_oid;
+ }
+ }
+
+ throw new com.sun.star.uno.RuntimeException(
+ "[jni_uno bridge error] unexpected call on proxy " +
+ proxy.toString() + ": " + method.toString() );
+ }
+
+ private Boolean isSame(Object obj) {
+ return new Boolean(obj != null
+ && m_oid.equals(UnoRuntime.generateOid(obj)));
+ }
+}
diff --git a/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/makefile.mk b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/makefile.mk
new file mode 100644
index 000000000000..5d3eb9fea1f5
--- /dev/null
+++ b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/makefile.mk
@@ -0,0 +1,53 @@
+#*************************************************************************
+#
+# 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=java_uno
+PACKAGE=com$/sun$/star$/bridges$/jni_uno
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+JARFILES=jurt.jar ridl.jar
+JAVAFILES=$(subst,$(CLASSDIR)$/$(PACKAGE)$/, $(subst,.class,.java $(JAVACLASSFILES)))
+
+JAVACLASSFILES= \
+ $(CLASSDIR)$/$(PACKAGE)$/JNI_proxy.class \
+ $(CLASSDIR)$/$(PACKAGE)$/JNI_info_holder.class
+
+JARCLASSDIRS=$(PACKAGE)
+JARTARGET=$(TARGET).jar
+JARCOMPRESS=TRUE
+JARCLASSPATH = $(JARFILES) ../../lib/ ../bin/
+CUSTOMMANIFESTFILE = manifest
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/manifest b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/manifest
new file mode 100644
index 000000000000..7ad02e156d9a
--- /dev/null
+++ b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/manifest
@@ -0,0 +1 @@
+Sealed: true
diff --git a/bridges/source/jni_uno/java_uno.map b/bridges/source/jni_uno/java_uno.map
new file mode 100644
index 000000000000..376f7ea979bb
--- /dev/null
+++ b/bridges/source/jni_uno/java_uno.map
@@ -0,0 +1,27 @@
+UDK_3_0_0 {
+ global:
+ uno_initEnvironment;
+ uno_ext_getMapping;
+ component_canUnload;
+ local:
+ *;
+};
+
+UDK_3.1 {
+ global:
+ Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J;
+ Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call;
+ Java_com_sun_star_bridges_jni_1uno_JNI_1info_1holder_finalize__J;
+} UDK_3_0_0;
+
+UDK_3.2 {
+ global:
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_attach;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_create;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_destroy;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_detach;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_dispose;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_enter;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_threadId;
+ Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_putJob;
+} UDK_3.1;
diff --git a/bridges/source/jni_uno/jni_base.h b/bridges/source/jni_uno/jni_base.h
new file mode 100644
index 000000000000..7601648ad93a
--- /dev/null
+++ b/bridges/source/jni_uno/jni_base.h
@@ -0,0 +1,295 @@
+/* -*- 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_JNI_BASE_H
+#define INCLUDED_JNI_BASE_H
+
+#if defined (__SUNPRO_CC) || defined (__SUNPRO_C)
+// workaround solaris include trouble on jumbo
+#include <stdarg.h>
+namespace std
+{
+typedef __va_list va_list;
+}
+#endif
+#include <memory>
+
+#include "jvmaccess/unovirtualmachine.hxx"
+#include "jvmaccess/virtualmachine.hxx"
+
+#include "osl/diagnose.h"
+
+#include "rtl/alloc.h"
+#include "rtl/ustring.hxx"
+
+#include "uno/environment.h"
+#include "typelib/typedescription.h"
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+
+namespace jni_uno
+{
+
+class JNI_info;
+
+//==============================================================================
+struct BridgeRuntimeError
+{
+ ::rtl::OUString m_message;
+
+ inline BridgeRuntimeError( ::rtl::OUString const & message )
+ : m_message( message )
+ {}
+};
+
+
+//==============================================================================
+class JNI_context
+{
+ JNI_info const * m_jni_info;
+ JNIEnv * m_env;
+ jobject m_class_loader;
+
+ JNI_context( JNI_context & ); // not impl
+ void operator = ( JNI_context ); // not impl
+
+ void java_exc_occured() const;
+public:
+ inline explicit JNI_context(
+ JNI_info const * jni_info, JNIEnv * env, jobject class_loader )
+ : m_jni_info( jni_info ),
+ m_env( env ),
+ m_class_loader( class_loader )
+ {}
+
+ inline JNI_info const * get_info() const
+ { return m_jni_info; }
+
+ inline JNIEnv * operator -> () const
+ { return m_env; }
+ inline JNIEnv * get_jni_env() const
+ { return m_env; }
+
+ // does not handle exceptions, *classClass will be null if exception
+ // occurred:
+ void getClassForName(jclass * classClass, jmethodID * methodForName) const;
+
+ // if inException, does not handle exceptions, in which case returned value
+ // will be null if exception occurred:
+ jclass findClass(
+ char const * name, jclass classClass, jmethodID methodForName,
+ bool inException) const;
+
+ inline void ensure_no_exception() const; // throws BridgeRuntimeError
+ inline bool assert_no_exception() const; // asserts and clears exception
+
+ ::rtl::OUString get_stack_trace( jobject jo_exc = 0 ) const;
+};
+
+//______________________________________________________________________________
+inline void JNI_context::ensure_no_exception() const
+{
+ if (JNI_FALSE != m_env->ExceptionCheck())
+ {
+ java_exc_occured();
+ }
+}
+
+//______________________________________________________________________________
+inline bool JNI_context::assert_no_exception() const
+{
+ if (JNI_FALSE != m_env->ExceptionCheck())
+ {
+ m_env->ExceptionClear();
+ OSL_ENSURE( 0, "unexpected java exception occured!" );
+ return false;
+ }
+ return true;
+}
+
+
+//==============================================================================
+class JNI_guarded_context
+ : private ::jvmaccess::VirtualMachine::AttachGuard,
+ public JNI_context
+{
+ JNI_guarded_context( JNI_guarded_context & ); // not impl
+ void operator = ( JNI_guarded_context ); // not impl
+
+public:
+ inline explicit JNI_guarded_context(
+ JNI_info const * jni_info, ::jvmaccess::UnoVirtualMachine * vm_access )
+ : AttachGuard( vm_access->getVirtualMachine() ),
+ JNI_context(
+ jni_info, AttachGuard::getEnvironment(),
+ static_cast< jobject >(vm_access->getClassLoader()) )
+ {}
+};
+
+
+//==============================================================================
+class JLocalAutoRef
+{
+ JNI_context const & m_jni;
+ jobject m_jo;
+
+public:
+ inline JLocalAutoRef( JNI_context const & jni )
+ : m_jni( jni ),
+ m_jo( 0 )
+ {}
+ inline explicit JLocalAutoRef( JNI_context const & jni, jobject jo )
+ : m_jni( jni ),
+ m_jo( jo )
+ {}
+ inline JLocalAutoRef( JLocalAutoRef & auto_ref );
+ inline ~JLocalAutoRef() SAL_THROW( () );
+
+ inline jobject get() const
+ { return m_jo; }
+ inline bool is() const
+ { return (0 != m_jo); }
+ inline jobject release();
+ inline void reset();
+ inline void reset( jobject jo );
+ inline JLocalAutoRef & operator = ( JLocalAutoRef & auto_ref );
+};
+
+//______________________________________________________________________________
+inline JLocalAutoRef::~JLocalAutoRef() SAL_THROW( () )
+{
+ if (0 != m_jo)
+ m_jni->DeleteLocalRef( m_jo );
+}
+
+//______________________________________________________________________________
+inline JLocalAutoRef::JLocalAutoRef( JLocalAutoRef & auto_ref )
+ : m_jni( auto_ref.m_jni ),
+ m_jo( auto_ref.m_jo )
+{
+ auto_ref.m_jo = 0;
+}
+
+//______________________________________________________________________________
+inline jobject JLocalAutoRef::release()
+{
+ jobject jo = m_jo;
+ m_jo = 0;
+ return jo;
+}
+
+//______________________________________________________________________________
+inline void JLocalAutoRef::reset()
+{
+ if (0 != m_jo)
+ m_jni->DeleteLocalRef( m_jo );
+ m_jo = 0;
+}
+
+//______________________________________________________________________________
+inline void JLocalAutoRef::reset( jobject jo )
+{
+ if (jo != m_jo)
+ {
+ if (0 != m_jo)
+ m_jni->DeleteLocalRef( m_jo );
+ m_jo = jo;
+ }
+}
+
+//______________________________________________________________________________
+inline JLocalAutoRef & JLocalAutoRef::operator = ( JLocalAutoRef & auto_ref )
+{
+ OSL_ASSERT( m_jni.get_jni_env() == auto_ref.m_jni.get_jni_env() );
+ reset( auto_ref.m_jo );
+ auto_ref.m_jo = 0;
+ return *this;
+}
+
+
+//==============================================================================
+struct rtl_mem
+{
+ inline static void * operator new ( size_t nSize )
+ { return rtl_allocateMemory( nSize ); }
+ inline static void operator delete ( void * mem )
+ { if (mem) rtl_freeMemory( mem ); }
+ inline static void * operator new ( size_t, void * mem )
+ { return mem; }
+ inline static void operator delete ( void *, void * )
+ {}
+
+ static inline ::std::auto_ptr< rtl_mem > allocate( ::std::size_t bytes );
+};
+
+//______________________________________________________________________________
+inline ::std::auto_ptr< rtl_mem > rtl_mem::allocate( ::std::size_t bytes )
+{
+ void * p = rtl_allocateMemory( bytes );
+ if (0 == p)
+ throw BridgeRuntimeError( OUSTR("out of memory!") );
+ return ::std::auto_ptr< rtl_mem >( (rtl_mem *)p );
+}
+
+
+//==============================================================================
+class TypeDescr
+{
+ typelib_TypeDescription * m_td;
+
+ TypeDescr( TypeDescr & ); // not impl
+ void operator = ( TypeDescr ); // not impl
+
+public:
+ inline explicit TypeDescr( typelib_TypeDescriptionReference * td_ref );
+ inline ~TypeDescr() SAL_THROW( () )
+ { TYPELIB_DANGER_RELEASE( m_td ); }
+
+ inline typelib_TypeDescription * get() const
+ { return m_td; }
+};
+
+//______________________________________________________________________________
+inline TypeDescr::TypeDescr( typelib_TypeDescriptionReference * td_ref )
+ : m_td( 0 )
+{
+ TYPELIB_DANGER_GET( &m_td, td_ref );
+ if (0 == m_td)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("cannot get comprehensive type description for ") +
+ ::rtl::OUString::unacquired( &td_ref->pTypeName ) );
+ }
+}
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/jni_uno/jni_bridge.cxx b/bridges/source/jni_uno/jni_bridge.cxx
new file mode 100644
index 000000000000..3f9f22a98c38
--- /dev/null
+++ b/bridges/source/jni_uno/jni_bridge.cxx
@@ -0,0 +1,572 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "jni_bridge.h"
+
+#include "jvmaccess/unovirtualmachine.hxx"
+#include "rtl/ref.hxx"
+#include "rtl/unload.h"
+#include "rtl/strbuf.hxx"
+#include "uno/lbnames.h"
+
+
+using namespace ::std;
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::jni_uno;
+
+namespace
+{
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+void SAL_CALL Mapping_acquire( uno_Mapping * mapping )
+ SAL_THROW_EXTERN_C()
+{
+ Mapping const * that = static_cast< Mapping const * >( mapping );
+ that->m_bridge->acquire();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL Mapping_release( uno_Mapping * mapping )
+ SAL_THROW_EXTERN_C()
+{
+ Mapping const * that = static_cast< Mapping const * >( mapping );
+ that->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;
+ jobject javaI = (jobject) pIn;
+
+ OSL_ASSERT( sizeof (void *) == sizeof (jobject) );
+ OSL_ENSURE( ppUnoI && td, "### null ptr!" );
+
+ if (0 == javaI)
+ {
+ if (0 != *ppUnoI)
+ {
+ uno_Interface * p = *(uno_Interface **)ppUnoI;
+ (*p->release)( p );
+ *ppUnoI = 0;
+ }
+ }
+ else
+ {
+ try
+ {
+ Bridge const * bridge =
+ static_cast< Mapping const * >( mapping )->m_bridge;
+ JNI_guarded_context jni(
+ bridge->m_jni_info,
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext ) );
+
+ JNI_interface_type_info const * info =
+ static_cast< JNI_interface_type_info const * >(
+ bridge->m_jni_info->get_type_info(
+ jni, (typelib_TypeDescription *)td ) );
+ uno_Interface * pUnoI = bridge->map_to_uno( jni, javaI, info );
+ if (0 != *ppUnoI)
+ {
+ uno_Interface * p = *(uno_Interface **)ppUnoI;
+ (*p->release)( p );
+ }
+ *ppUnoI = pUnoI;
+ }
+ catch (BridgeRuntimeError & err)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg(
+ OUStringToOString(
+ OUSTR("[jni_uno bridge error] ") + err.m_message,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+#else
+ (void) err; // unused
+#endif
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ OSL_ENSURE(
+ 0,
+ "[jni_uno bridge error] attaching current thread "
+ "to java failed!" );
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL Mapping_map_to_java(
+ uno_Mapping * mapping, void ** ppOut,
+ void * pIn, typelib_InterfaceTypeDescription * td )
+ SAL_THROW_EXTERN_C()
+{
+ jobject * ppJavaI = (jobject *) ppOut;
+ uno_Interface * pUnoI = (uno_Interface *)pIn;
+
+ OSL_ASSERT( sizeof (void *) == sizeof (jobject) );
+ OSL_ENSURE( ppJavaI && td, "### null ptr!" );
+
+ try
+ {
+ if (0 == pUnoI)
+ {
+ if (0 != *ppJavaI)
+ {
+ Bridge const * bridge =
+ static_cast< Mapping const * >( mapping )->m_bridge;
+ JNI_guarded_context jni(
+ bridge->m_jni_info,
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext ) );
+ jni->DeleteGlobalRef( *ppJavaI );
+ *ppJavaI = 0;
+ }
+ }
+ else
+ {
+ Bridge const * bridge =
+ static_cast< Mapping const * >( mapping )->m_bridge;
+ JNI_guarded_context jni(
+ bridge->m_jni_info,
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext ) );
+
+ JNI_interface_type_info const * info =
+ static_cast< JNI_interface_type_info const * >(
+ bridge->m_jni_info->get_type_info(
+ jni, (typelib_TypeDescription *)td ) );
+ jobject jlocal = bridge->map_to_java( jni, pUnoI, info );
+ if (0 != *ppJavaI)
+ jni->DeleteGlobalRef( *ppJavaI );
+ *ppJavaI = jni->NewGlobalRef( jlocal );
+ jni->DeleteLocalRef( jlocal );
+ }
+ }
+ catch (BridgeRuntimeError & err)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg(
+ OUStringToOString(
+ OUSTR("[jni_uno bridge error] ") + err.m_message,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+#else
+ (void) err; // unused
+#endif
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ OSL_ENSURE(
+ 0,
+ "[jni_uno bridge error] attaching current thread to java failed!" );
+ }
+}
+
+//______________________________________________________________________________
+void SAL_CALL Bridge_free( uno_Mapping * mapping )
+ SAL_THROW_EXTERN_C()
+{
+ Mapping * that = static_cast< Mapping * >( mapping );
+ delete that->m_bridge;
+}
+
+}
+
+rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+}
+
+namespace jni_uno
+{
+
+//______________________________________________________________________________
+void Bridge::acquire() const SAL_THROW( () )
+{
+ if (1 == osl_incrementInterlockedCount( &m_ref ))
+ {
+ if (m_registered_java2uno)
+ {
+ uno_Mapping * mapping = const_cast< Mapping * >( &m_java2uno );
+ uno_registerMapping(
+ &mapping, Bridge_free,
+ m_java_env, (uno_Environment *)m_uno_env, 0 );
+ }
+ else
+ {
+ uno_Mapping * mapping = const_cast< Mapping * >( &m_uno2java );
+ uno_registerMapping(
+ &mapping, Bridge_free,
+ (uno_Environment *)m_uno_env, m_java_env, 0 );
+ }
+ }
+}
+
+//______________________________________________________________________________
+void Bridge::release() const SAL_THROW( () )
+{
+ if (! osl_decrementInterlockedCount( &m_ref ))
+ {
+ uno_revokeMapping(
+ m_registered_java2uno
+ ? const_cast< Mapping * >( &m_java2uno )
+ : const_cast< Mapping * >( &m_uno2java ) );
+ }
+}
+
+//______________________________________________________________________________
+Bridge::Bridge(
+ uno_Environment * java_env, uno_ExtEnvironment * uno_env,
+ bool registered_java2uno )
+ : m_ref( 1 ),
+ m_uno_env( uno_env ),
+ m_java_env( java_env ),
+ m_registered_java2uno( registered_java2uno )
+{
+ // bootstrapping bridge jni_info
+ m_jni_info = JNI_info::get_jni_info(
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ m_java_env->pContext ) );
+
+ OSL_ASSERT( 0 != m_java_env && 0 != m_uno_env );
+ (*((uno_Environment *)m_uno_env)->acquire)( (uno_Environment *)m_uno_env );
+ (*m_java_env->acquire)( m_java_env );
+
+ // java2uno
+ m_java2uno.acquire = Mapping_acquire;
+ m_java2uno.release = Mapping_release;
+ m_java2uno.mapInterface = Mapping_map_to_uno;
+ m_java2uno.m_bridge = this;
+ // uno2java
+ m_uno2java.acquire = Mapping_acquire;
+ m_uno2java.release = Mapping_release;
+ m_uno2java.mapInterface = Mapping_map_to_java;
+ m_uno2java.m_bridge = this;
+
+ (*g_moduleCount.modCnt.acquire)( &g_moduleCount.modCnt );
+}
+
+//______________________________________________________________________________
+Bridge::~Bridge() SAL_THROW( () )
+{
+ (*m_java_env->release)( m_java_env );
+ (*((uno_Environment *)m_uno_env)->release)( (uno_Environment *)m_uno_env );
+
+ (*g_moduleCount.modCnt.release)( &g_moduleCount.modCnt );
+}
+
+
+//______________________________________________________________________________
+void JNI_context::java_exc_occured() const
+{
+ // !don't rely on JNI_info!
+
+ JLocalAutoRef jo_exc( *this, m_env->ExceptionOccurred() );
+ m_env->ExceptionClear();
+ OSL_ASSERT( jo_exc.is() );
+ if (! jo_exc.is())
+ {
+ throw BridgeRuntimeError(
+ OUSTR("java exception occured, but not available!?") +
+ get_stack_trace() );
+ }
+
+ // call toString(); don't rely on m_jni_info
+ jclass jo_class = m_env->FindClass( "java/lang/Object" );
+ if (JNI_FALSE != m_env->ExceptionCheck())
+ {
+ m_env->ExceptionClear();
+ throw BridgeRuntimeError(
+ OUSTR("cannot get class java.lang.Object!") + get_stack_trace() );
+ }
+ JLocalAutoRef jo_Object( *this, jo_class );
+ // method Object.toString()
+ jmethodID method_Object_toString = m_env->GetMethodID(
+ (jclass) jo_Object.get(), "toString", "()Ljava/lang/String;" );
+ if (JNI_FALSE != m_env->ExceptionCheck())
+ {
+ m_env->ExceptionClear();
+ throw BridgeRuntimeError(
+ OUSTR("cannot get method id of java.lang.Object.toString()!") +
+ get_stack_trace() );
+ }
+ OSL_ASSERT( 0 != method_Object_toString );
+
+ JLocalAutoRef jo_descr(
+ *this, m_env->CallObjectMethodA(
+ jo_exc.get(), method_Object_toString, 0 ) );
+ if (m_env->ExceptionCheck()) // no chance at all
+ {
+ m_env->ExceptionClear();
+ throw BridgeRuntimeError(
+ OUSTR("error examining java exception object!") +
+ get_stack_trace() );
+ }
+
+ jsize len = m_env->GetStringLength( (jstring) jo_descr.get() );
+ auto_ptr< rtl_mem > ustr_mem(
+ rtl_mem::allocate(
+ sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) ) );
+ rtl_uString * ustr = (rtl_uString *)ustr_mem.get();
+ m_env->GetStringRegion( (jstring) jo_descr.get(), 0, len, ustr->buffer );
+ if (m_env->ExceptionCheck())
+ {
+ m_env->ExceptionClear();
+ throw BridgeRuntimeError(
+ OUSTR("invalid java string object!") + get_stack_trace() );
+ }
+ ustr->refCount = 1;
+ ustr->length = len;
+ ustr->buffer[ len ] = '\0';
+ OUString message( (rtl_uString *)ustr_mem.release(), SAL_NO_ACQUIRE );
+
+ throw BridgeRuntimeError( message + get_stack_trace( jo_exc.get() ) );
+}
+
+//______________________________________________________________________________
+void JNI_context::getClassForName(
+ jclass * classClass, jmethodID * methodForName) const
+{
+ jclass c = m_env->FindClass("java/lang/Class");
+ if (c != 0) {
+ *methodForName = m_env->GetStaticMethodID(
+ c, "forName",
+ "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;");
+ }
+ *classClass = c;
+}
+
+//______________________________________________________________________________
+jclass JNI_context::findClass(
+ char const * name, jclass classClass, jmethodID methodForName,
+ bool inException) const
+{
+ jclass c = 0;
+ JLocalAutoRef s(*this, m_env->NewStringUTF(name));
+ if (s.is()) {
+ jvalue a[3];
+ a[0].l = s.get();
+ a[1].z = JNI_FALSE;
+ a[2].l = m_class_loader;
+ c = static_cast< jclass >(
+ m_env->CallStaticObjectMethodA(classClass, methodForName, a));
+ }
+ if (!inException) {
+ ensure_no_exception();
+ }
+ return c;
+}
+
+//______________________________________________________________________________
+OUString JNI_context::get_stack_trace( jobject jo_exc ) const
+{
+ JLocalAutoRef jo_JNI_proxy(
+ *this,
+ find_class( *this, "com.sun.star.bridges.jni_uno.JNI_proxy", true ) );
+ if (assert_no_exception())
+ {
+ // static method JNI_proxy.get_stack_trace()
+ jmethodID method = m_env->GetStaticMethodID(
+ (jclass) jo_JNI_proxy.get(), "get_stack_trace",
+ "(Ljava/lang/Throwable;)Ljava/lang/String;" );
+ if (assert_no_exception() && (0 != method))
+ {
+ jvalue arg;
+ arg.l = jo_exc;
+ JLocalAutoRef jo_stack_trace(
+ *this, m_env->CallStaticObjectMethodA(
+ (jclass) jo_JNI_proxy.get(), method, &arg ) );
+ if (assert_no_exception())
+ {
+ jsize len =
+ m_env->GetStringLength( (jstring) jo_stack_trace.get() );
+ auto_ptr< rtl_mem > ustr_mem(
+ rtl_mem::allocate(
+ sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) ) );
+ rtl_uString * ustr = (rtl_uString *)ustr_mem.get();
+ m_env->GetStringRegion(
+ (jstring) jo_stack_trace.get(), 0, len, ustr->buffer );
+ if (assert_no_exception())
+ {
+ ustr->refCount = 1;
+ ustr->length = len;
+ ustr->buffer[ len ] = '\0';
+ return OUString(
+ (rtl_uString *)ustr_mem.release(), SAL_NO_ACQUIRE );
+ }
+ }
+ }
+ }
+ return OUString();
+}
+
+}
+
+using namespace ::jni_uno;
+
+extern "C"
+{
+namespace
+{
+
+//------------------------------------------------------------------------------
+void SAL_CALL java_env_disposing( uno_Environment * java_env )
+ SAL_THROW_EXTERN_C()
+{
+ ::jvmaccess::UnoVirtualMachine * machine =
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ java_env->pContext );
+ java_env->pContext = 0;
+ machine->release();
+}
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL uno_initEnvironment( uno_Environment * java_env )
+ SAL_THROW_EXTERN_C()
+{
+ java_env->environmentDisposing = java_env_disposing;
+ java_env->pExtEnv = 0; // no extended support
+ OSL_ASSERT( 0 != java_env->pContext );
+
+ ::jvmaccess::UnoVirtualMachine * machine =
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ java_env->pContext );
+ machine->acquire();
+}
+
+//------------------------------------------------------------------------------
+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;
+ }
+
+ OSL_ASSERT( JNI_FALSE == sal_False );
+ OSL_ASSERT( JNI_TRUE == sal_True );
+ OSL_ASSERT( sizeof (jboolean) == sizeof (sal_Bool) );
+ OSL_ASSERT( sizeof (jchar) == sizeof (sal_Unicode) );
+ OSL_ASSERT( sizeof (jdouble) == sizeof (double) );
+ OSL_ASSERT( sizeof (jfloat) == sizeof (float) );
+ OSL_ASSERT( sizeof (jbyte) == sizeof (sal_Int8) );
+ OSL_ASSERT( sizeof (jshort) == sizeof (sal_Int16) );
+ OSL_ASSERT( sizeof (jint) == sizeof (sal_Int32) );
+ OSL_ASSERT( sizeof (jlong) == sizeof (sal_Int64) );
+ if ((JNI_FALSE == sal_False) &&
+ (JNI_TRUE == sal_True) &&
+ (sizeof (jboolean) == sizeof (sal_Bool)) &&
+ (sizeof (jchar) == sizeof (sal_Unicode)) &&
+ (sizeof (jdouble) == sizeof (double)) &&
+ (sizeof (jfloat) == sizeof (float)) &&
+ (sizeof (jbyte) == sizeof (sal_Int8)) &&
+ (sizeof (jshort) == sizeof (sal_Int16)) &&
+ (sizeof (jint) == sizeof (sal_Int32)) &&
+ (sizeof (jlong) == sizeof (sal_Int64)))
+ {
+ 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_JAVA) ) &&
+ to_env_typename.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) ))
+ {
+ Bridge * bridge =
+ new Bridge( pFrom, pTo->pExtEnv, true ); // ref count = 1
+ mapping = &bridge->m_java2uno;
+ 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_JAVA) ))
+ {
+ Bridge * bridge =
+ new Bridge( pTo, pFrom->pExtEnv, false ); // ref count = 1
+ mapping = &bridge->m_uno2java;
+ uno_registerMapping(
+ &mapping, Bridge_free,
+ (uno_Environment *)pFrom->pExtEnv, pTo, 0 );
+ }
+ }
+ catch (BridgeRuntimeError & err)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg(
+ OUStringToOString(
+ OUSTR("[jni_uno bridge error] ") + err.m_message,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+#else
+ (void) err; // unused
+#endif
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ OSL_ENSURE(
+ 0,
+ "[jni_uno bridge error] attaching current thread "
+ "to java failed!" );
+ }
+
+ *ppMapping = mapping;
+ }
+}
+
+//------------------------------------------------------------------------------
+sal_Bool SAL_CALL component_canUnload( TimeValue * pTime )
+ SAL_THROW_EXTERN_C()
+{
+ return (*g_moduleCount.canUnload)( &g_moduleCount, pTime );
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/jni_uno/jni_bridge.h b/bridges/source/jni_uno/jni_bridge.h
new file mode 100644
index 000000000000..f2298fbdbe46
--- /dev/null
+++ b/bridges/source/jni_uno/jni_bridge.h
@@ -0,0 +1,127 @@
+/* -*- 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_JNI_BRIDGE_H
+#define INCLUDED_JNI_BRIDGE_H
+
+#include "jni_base.h"
+#include "jni_info.h"
+#include "jni_helper.h"
+
+#include "osl/diagnose.h"
+#include "osl/interlck.h"
+
+#include "uno/mapping.h"
+#include "uno/dispatcher.h"
+
+#include "com/sun/star/uno/XInterface.hpp"
+
+
+namespace jni_uno
+{
+
+//==== holds environments and mappings =========================================
+struct Bridge;
+struct Mapping : public uno_Mapping
+{
+ Bridge * m_bridge;
+};
+
+//==============================================================================
+struct Bridge
+{
+ mutable oslInterlockedCount m_ref;
+
+ uno_ExtEnvironment * m_uno_env;
+ uno_Environment * m_java_env;
+
+ Mapping m_java2uno;
+ Mapping m_uno2java;
+ bool m_registered_java2uno;
+
+ JNI_info const * m_jni_info;
+
+ //
+ ~Bridge() SAL_THROW( () );
+ explicit Bridge(
+ uno_Environment * java_env, uno_ExtEnvironment * uno_env,
+ bool registered_java2uno );
+
+ void acquire() const;
+ void release() const;
+
+ // jni_data.cxx
+ void map_to_uno(
+ JNI_context const & jni,
+ void * uno_data, jvalue java_data,
+ typelib_TypeDescriptionReference * type,
+ JNI_type_info const * info /* maybe 0 */,
+ bool assign, bool out_param,
+ bool special_wrapped_integral_types = false ) const;
+ void map_to_java(
+ JNI_context const & jni,
+ jvalue * java_data, void const * uno_data,
+ typelib_TypeDescriptionReference * type,
+ JNI_type_info const * info /* maybe 0 */,
+ bool in_param, bool out_param,
+ bool special_wrapped_integral_types = false ) const;
+
+ // jni_uno2java.cxx
+ void handle_uno_exc(
+ JNI_context const & jni, uno_Any * uno_exc ) const;
+ void call_java(
+ jobject javaI,
+ typelib_InterfaceTypeDescription * iface_td,
+ sal_Int32 local_member_index, sal_Int32 function_pos_offset,
+ typelib_TypeDescriptionReference * return_type,
+ typelib_MethodParameter * params, sal_Int32 nParams,
+ void * uno_ret, void * uno_args [], uno_Any ** uno_exc ) const;
+ jobject map_to_java(
+ JNI_context const & jni,
+ uno_Interface * pUnoI, JNI_interface_type_info const * info ) const;
+
+ // jni_java2uno.cxx
+ void handle_java_exc(
+ JNI_context const & jni,
+ JLocalAutoRef const & jo_exc, uno_Any * uno_exc ) const;
+ jobject call_uno(
+ JNI_context const & jni,
+ uno_Interface * pUnoI, typelib_TypeDescription * member_td,
+ typelib_TypeDescriptionReference * return_tdref,
+ sal_Int32 nParams, typelib_MethodParameter const * pParams,
+ jobjectArray jo_args ) const;
+ uno_Interface * map_to_uno(
+ JNI_context const & jni,
+ jobject javaI, JNI_interface_type_info const * info ) const;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/jni_uno/jni_data.cxx b/bridges/source/jni_uno/jni_data.cxx
new file mode 100644
index 000000000000..aca455d154ed
--- /dev/null
+++ b/bridges/source/jni_uno/jni_data.cxx
@@ -0,0 +1,2579 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "jni_bridge.h"
+
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "uno/sequence2.h"
+
+
+using namespace ::std;
+using namespace ::rtl;
+
+namespace jni_uno
+{
+
+//------------------------------------------------------------------------------
+inline rtl_mem * seq_allocate( sal_Int32 nElements, sal_Int32 nSize )
+{
+ auto_ptr< rtl_mem > seq(
+ rtl_mem::allocate( SAL_SEQUENCE_HEADER_SIZE + (nElements * nSize) ) );
+ uno_Sequence * p = (uno_Sequence *)seq.get();
+ p->nRefCount = 1;
+ p->nElements = nElements;
+ return seq.release();
+}
+
+//______________________________________________________________________________
+namespace {
+
+void createDefaultUnoValue(
+ JNI_context const & jni, void * uno_data,
+ typelib_TypeDescriptionReference * type,
+ JNI_type_info const * info /* maybe 0 */, bool assign)
+{
+ switch (type->eTypeClass) {
+ case typelib_TypeClass_BOOLEAN:
+ *static_cast< sal_Bool * >(uno_data) = false;
+ break;
+
+ case typelib_TypeClass_BYTE:
+ *static_cast< sal_Int8 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_SHORT:
+ *static_cast< sal_Int16 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *static_cast< sal_uInt16 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_LONG:
+ *static_cast< sal_Int32 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_UNSIGNED_LONG:
+ *static_cast< sal_uInt32 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_HYPER:
+ *static_cast< sal_Int64 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *static_cast< sal_uInt64 * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_FLOAT:
+ *static_cast< float * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_DOUBLE:
+ *static_cast< double * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_CHAR:
+ *static_cast< sal_Unicode * >(uno_data) = 0;
+ break;
+
+ case typelib_TypeClass_STRING:
+ if (!assign) {
+ *static_cast< rtl_uString ** >(uno_data) = 0;
+ }
+ rtl_uString_new(static_cast< rtl_uString ** >(uno_data));
+ break;
+
+ case typelib_TypeClass_TYPE:
+ if (assign) {
+ typelib_typedescriptionreference_release(
+ *static_cast< typelib_TypeDescriptionReference ** >(uno_data));
+ }
+ *static_cast< typelib_TypeDescriptionReference ** >(uno_data)
+ = *typelib_static_type_getByTypeClass(typelib_TypeClass_VOID);
+ OSL_ASSERT(
+ *static_cast< typelib_TypeDescriptionReference ** >(uno_data) != 0);
+ typelib_typedescriptionreference_acquire(
+ *static_cast< typelib_TypeDescriptionReference ** >(uno_data));
+ break;
+
+ case typelib_TypeClass_ANY:
+ if (assign) {
+ uno_any_destruct(static_cast< uno_Any * >(uno_data), 0);
+ }
+ uno_any_construct(
+ static_cast< uno_Any * >(uno_data), 0,
+ jni.get_info()->m_XInterface_type_info->m_td.get(), 0);
+ break;
+
+ case typelib_TypeClass_SEQUENCE:
+ {
+ auto_ptr< rtl_mem > seq(seq_allocate(0, 0));
+ if (assign) {
+ uno_type_destructData(uno_data, type, 0);
+ }
+ *static_cast< uno_Sequence ** >(uno_data)
+ = reinterpret_cast< uno_Sequence * >(seq.release());
+ break;
+ }
+
+ case typelib_TypeClass_ENUM:
+ {
+ typelib_TypeDescription * td = 0;
+ TYPELIB_DANGER_GET(&td, type);
+ *static_cast< sal_Int32 * >(uno_data)
+ = (reinterpret_cast< typelib_EnumTypeDescription * >(td)->
+ nDefaultEnumValue);
+ TYPELIB_DANGER_RELEASE(td);
+ break;
+ }
+
+ case typelib_TypeClass_STRUCT:
+ {
+ if (info == 0) {
+ info = jni.get_info()->get_type_info(jni, type);
+ }
+ JNI_compound_type_info const * comp_info
+ = static_cast< JNI_compound_type_info const * >(info);
+ typelib_CompoundTypeDescription * comp_td
+ = reinterpret_cast< typelib_CompoundTypeDescription * >(
+ comp_info->m_td.get());
+ sal_Int32 nPos = 0;
+ sal_Int32 nMembers = comp_td->nMembers;
+ try {
+ if (comp_td->pBaseTypeDescription != 0) {
+ createDefaultUnoValue(
+ jni, uno_data,
+ comp_td->pBaseTypeDescription->aBase.pWeakRef,
+ comp_info->m_base, assign);
+ }
+ for (; nPos < nMembers; ++nPos) {
+ createDefaultUnoValue(
+ jni,
+ (static_cast< char * >(uno_data)
+ + comp_td->pMemberOffsets[nPos]),
+ comp_td->ppTypeRefs[nPos], 0, assign);
+ }
+ } catch (...) {
+ if (!assign) {
+ for (sal_Int32 i = 0; i < nPos; ++i) {
+ uno_type_destructData(
+ (static_cast< char * >(uno_data)
+ + comp_td->pMemberOffsets[i]),
+ comp_td->ppTypeRefs[i], 0);
+ }
+ if (comp_td->pBaseTypeDescription != 0) {
+ uno_destructData(
+ uno_data, &comp_td->pBaseTypeDescription->aBase, 0);
+ }
+ }
+ throw;
+ }
+ }
+ break;
+
+ case typelib_TypeClass_INTERFACE:
+ if (assign) {
+ uno_Interface * p = *static_cast< uno_Interface ** >(uno_data);
+ if (p != 0) {
+ (*p->release)(p);
+ }
+ }
+ *static_cast< uno_Interface ** >(uno_data) = 0;
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+}
+
+}
+
+void Bridge::map_to_uno(
+ JNI_context const & jni,
+ void * uno_data, jvalue java_data,
+ typelib_TypeDescriptionReference * type,
+ JNI_type_info const * info /* maybe 0 */,
+ bool assign, bool out_param,
+ bool special_wrapped_integral_types ) const
+{
+ OSL_ASSERT(
+ !out_param ||
+ (1 == jni->GetArrayLength( (jarray) java_data.l )) );
+
+ switch (type->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ if (out_param)
+ {
+ jni->GetCharArrayRegion(
+ (jcharArray) java_data.l, 0, 1, (jchar *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jchar *) uno_data = jni->CallCharMethodA(
+ java_data.l, m_jni_info->m_method_Character_charValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jchar *) uno_data = java_data.c;
+ }
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ if (out_param)
+ {
+ jni->GetBooleanArrayRegion(
+ (jbooleanArray) java_data.l, 0, 1, (jboolean *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jboolean *) uno_data = jni->CallBooleanMethodA(
+ java_data.l, m_jni_info->m_method_Boolean_booleanValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jboolean *) uno_data = java_data.z;
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ if (out_param)
+ {
+ jni->GetByteArrayRegion(
+ (jbyteArray) java_data.l, 0, 1, (jbyte *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jbyte *) uno_data = jni->CallByteMethodA(
+ java_data.l, m_jni_info->m_method_Byte_byteValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jbyte *) uno_data = java_data.b;
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (out_param)
+ {
+ jni->GetShortArrayRegion(
+ (jshortArray) java_data.l, 0, 1, (jshort *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jshort *) uno_data = jni->CallShortMethodA(
+ java_data.l, m_jni_info->m_method_Short_shortValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jshort *) uno_data = java_data.s;
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (out_param)
+ {
+ jni->GetIntArrayRegion(
+ (jintArray) java_data.l, 0, 1, (jint *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jint *) uno_data = jni->CallIntMethodA(
+ java_data.l, m_jni_info->m_method_Integer_intValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jint *) uno_data = java_data.i;
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (out_param)
+ {
+ jni->GetLongArrayRegion(
+ (jlongArray) java_data.l, 0, 1, (jlong *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jlong *) uno_data = jni->CallLongMethodA(
+ java_data.l, m_jni_info->m_method_Long_longValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jlong *) uno_data = java_data.j;
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (out_param)
+ {
+ jni->GetFloatArrayRegion(
+ (jfloatArray) java_data.l, 0, 1, (jfloat *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jfloat *) uno_data = jni->CallFloatMethodA(
+ java_data.l, m_jni_info->m_method_Float_floatValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jfloat *) uno_data = java_data.f;
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (out_param)
+ {
+ jni->GetDoubleArrayRegion(
+ (jdoubleArray) java_data.l, 0, 1, (jdouble *) uno_data );
+ jni.ensure_no_exception();
+ }
+ else if (special_wrapped_integral_types)
+ {
+ *(jdouble *) uno_data = jni->CallDoubleMethodA(
+ java_data.l, m_jni_info->m_method_Double_doubleValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ *(jdouble *) uno_data = java_data.d;
+ }
+ break;
+ case typelib_TypeClass_STRING:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+ if (0 == java_data.l)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ if (! assign)
+ *(rtl_uString **)uno_data = 0;
+ jstring_to_ustring(
+ jni, (rtl_uString **)uno_data, (jstring) java_data.l );
+ break;
+ }
+ case typelib_TypeClass_TYPE:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+ if (0 == java_data.l)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+
+ // type name
+ JLocalAutoRef jo_type_name(
+ jni, jni->GetObjectField(
+ java_data.l, m_jni_info->m_field_Type__typeName ) );
+ if (! jo_type_name.is())
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] incomplete type object: "
+ "no type name!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ OUString type_name(
+ jstring_to_oustring( jni, (jstring) jo_type_name.get() ) );
+ ::com::sun::star::uno::TypeDescription td( type_name );
+ if (! td.is())
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] UNO type not found: ") );
+ buf.append( type_name );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ typelib_typedescriptionreference_acquire( td.get()->pWeakRef );
+ if (assign)
+ {
+ typelib_typedescriptionreference_release(
+ *(typelib_TypeDescriptionReference **)uno_data );
+ }
+ *(typelib_TypeDescriptionReference **)uno_data = td.get()->pWeakRef;
+ break;
+ }
+ case typelib_TypeClass_ANY:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+
+ uno_Any * pAny = (uno_Any *)uno_data;
+ if (0 == java_data.l) // null-ref maps to XInterface null-ref
+ {
+ if (assign)
+ uno_any_destruct( pAny, 0 );
+ uno_any_construct(
+ pAny, 0, m_jni_info->m_XInterface_type_info->m_td.get(), 0 );
+ break;
+ }
+
+ JLocalAutoRef jo_type( jni );
+ JLocalAutoRef jo_wrapped_holder( jni );
+
+ if (JNI_FALSE != jni->IsInstanceOf(
+ java_data.l, m_jni_info->m_class_Any ))
+ {
+ // boxed any
+ jo_type.reset( jni->GetObjectField(
+ java_data.l, m_jni_info->m_field_Any__type ) );
+ if (! jo_type.is())
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] no type set at "
+ "com.sun.star.uno.Any!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ // wrapped value
+ jo_wrapped_holder.reset(
+ jni->GetObjectField(
+ java_data.l, m_jni_info->m_field_Any__object ) );
+ java_data.l = jo_wrapped_holder.get();
+ }
+ else
+ {
+ // create type out of class
+ JLocalAutoRef jo_class( jni, jni->GetObjectClass( java_data.l ) );
+ jo_type.reset( create_type( jni, (jclass) jo_class.get() ) );
+#if OSL_DEBUG_LEVEL > 1
+ {
+ JLocalAutoRef jo_toString(
+ jni, jni->CallObjectMethodA(
+ java_data.l, m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ OUString toString(
+ jstring_to_oustring( jni, (jstring) jo_toString.get() ) );
+ }
+#endif
+ }
+
+ // get type name
+ JLocalAutoRef jo_type_name(
+ jni, jni->GetObjectField(
+ jo_type.get(), m_jni_info->m_field_Type__typeName ) );
+ jni.ensure_no_exception();
+ OUString type_name(
+ jstring_to_oustring( jni, (jstring) jo_type_name.get() ) );
+
+ ::com::sun::star::uno::TypeDescription value_td( type_name );
+ if (! value_td.is())
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] UNO type not found: ") );
+ buf.append( type_name );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ typelib_TypeClass type_class = value_td.get()->eTypeClass;
+
+ if (assign)
+ {
+ uno_any_destruct( pAny, 0 );
+ }
+ try
+ {
+ switch (type_class)
+ {
+ case typelib_TypeClass_VOID:
+ pAny->pData = &pAny->pReserved;
+ break;
+ case typelib_TypeClass_CHAR:
+ pAny->pData = &pAny->pReserved;
+ *(jchar *) pAny->pData = jni->CallCharMethodA(
+ java_data.l, m_jni_info->m_method_Character_charValue, 0 );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ pAny->pData = &pAny->pReserved;
+ *(jboolean *) pAny->pData = jni->CallBooleanMethodA(
+ java_data.l, m_jni_info->m_method_Boolean_booleanValue, 0 );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_BYTE:
+ pAny->pData = &pAny->pReserved;
+ *(jbyte *) pAny->pData = jni->CallByteMethodA(
+ java_data.l, m_jni_info->m_method_Byte_byteValue, 0 );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ pAny->pData = &pAny->pReserved;
+ *(jshort *) pAny->pData = jni->CallShortMethodA(
+ java_data.l, m_jni_info->m_method_Short_shortValue, 0 );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ pAny->pData = &pAny->pReserved;
+ *(jint *) pAny->pData = jni->CallIntMethodA(
+ java_data.l, m_jni_info->m_method_Integer_intValue, 0 );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (sizeof (sal_Int64) <= sizeof (void *))
+ {
+ pAny->pData = &pAny->pReserved;
+ *(jlong *) pAny->pData = jni->CallLongMethodA(
+ java_data.l, m_jni_info->m_method_Long_longValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ auto_ptr< rtl_mem > mem(
+ rtl_mem::allocate( sizeof (sal_Int64) ) );
+ *(jlong *) mem.get() = jni->CallLongMethodA(
+ java_data.l, m_jni_info->m_method_Long_longValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = mem.release();
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (sizeof (float) <= sizeof (void *))
+ {
+ pAny->pData = &pAny->pReserved;
+ *(jfloat *) pAny->pData = jni->CallFloatMethodA(
+ java_data.l, m_jni_info->m_method_Float_floatValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ auto_ptr< rtl_mem > mem(
+ rtl_mem::allocate( sizeof (float) ) );
+ *(jfloat *) mem.get() = jni->CallFloatMethodA(
+ java_data.l, m_jni_info->m_method_Float_floatValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = mem.release();
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (sizeof (double) <= sizeof (void *))
+ {
+ pAny->pData = &pAny->pReserved;
+ *(jdouble *) pAny->pData =
+ jni->CallDoubleMethodA(
+ java_data.l,
+ m_jni_info->m_method_Double_doubleValue, 0 );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ auto_ptr< rtl_mem > mem(
+ rtl_mem::allocate( sizeof (double) ) );
+ *(jdouble *) mem.get() =
+ jni->CallDoubleMethodA(
+ java_data.l,
+ m_jni_info->m_method_Double_doubleValue, 0 );
+ jni.ensure_no_exception();
+ pAny->pData = mem.release();
+ }
+ break;
+ case typelib_TypeClass_STRING:
+ // opt: anies often contain strings; copy string directly
+ pAny->pReserved = 0;
+ pAny->pData = &pAny->pReserved;
+ jstring_to_ustring(
+ jni, (rtl_uString **)pAny->pData,
+ (jstring) java_data.l );
+ break;
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_INTERFACE:
+ pAny->pData = &pAny->pReserved;
+ map_to_uno(
+ jni, pAny->pData, java_data,
+ value_td.get()->pWeakRef, 0,
+ false /* no assign */, false /* no out param */ );
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ auto_ptr< rtl_mem > mem(
+ rtl_mem::allocate( value_td.get()->nSize ) );
+ map_to_uno(
+ jni, mem.get(), java_data, value_td.get()->pWeakRef, 0,
+ false /* no assign */, false /* no out param */ );
+ pAny->pData = mem.release();
+ break;
+ }
+ default:
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( type_name );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] unsupported value type "
+ "of any!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+ }
+ catch (...)
+ {
+ if (assign)
+ {
+ // restore to valid any
+ uno_any_construct( pAny, 0, 0, 0 );
+ }
+ throw;
+ }
+ typelib_typedescriptionreference_acquire( value_td.get()->pWeakRef );
+ pAny->pType = value_td.get()->pWeakRef;
+ break;
+ }
+ case typelib_TypeClass_ENUM:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+ if (0 == java_data.l)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+
+ *(jint *) uno_data = jni->GetIntField(
+ java_data.l, m_jni_info->m_field_Enum_m_value );
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+ if (0 == java_data.l)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+
+ if (0 == info)
+ info = m_jni_info->get_type_info( jni, type );
+ JNI_compound_type_info const * comp_info =
+ static_cast< JNI_compound_type_info const * >( info );
+
+ typelib_CompoundTypeDescription * comp_td =
+ (typelib_CompoundTypeDescription *)comp_info->m_td.get();
+ bool polymorphic
+ = comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
+ && reinterpret_cast< typelib_StructTypeDescription * >(
+ comp_td)->pParameterizedTypes != 0;
+
+ sal_Int32 nPos = 0;
+ sal_Int32 nMembers = comp_td->nMembers;
+ try
+ {
+ if (0 != comp_td->pBaseTypeDescription)
+ {
+ map_to_uno(
+ jni, uno_data, java_data,
+ ((typelib_TypeDescription *) comp_td->pBaseTypeDescription)
+ ->pWeakRef,
+ comp_info->m_base,
+ assign, false /* no out param */ );
+ }
+
+ for ( ; nPos < nMembers; ++nPos )
+ {
+ void * p = (char *)uno_data + comp_td->pMemberOffsets[ nPos ];
+ typelib_TypeDescriptionReference * member_type =
+ comp_td->ppTypeRefs[ nPos ];
+ jfieldID field_id = comp_info->m_fields[ nPos ];
+ bool parameterizedType = polymorphic
+ && reinterpret_cast< typelib_StructTypeDescription * >(
+ comp_td)->pParameterizedTypes[nPos];
+ switch (member_type->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jchar *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jchar *) p = jni->GetCharField(
+ java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jboolean *) p = false;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jboolean *) p = jni->GetBooleanField(
+ java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jbyte *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jbyte *) p = jni->GetByteField(
+ java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jshort *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jshort *) p = jni->GetShortField(
+ java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jint *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jint *) p = jni->GetIntField( java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jlong *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jlong *) p = jni->GetLongField(
+ java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jfloat *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jfloat *) p = jni->GetFloatField(
+ java_data.l, field_id );
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (parameterizedType) {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectField( java_data.l, field_id ) );
+ if ( jo.get() == 0 ) {
+ *(jdouble *) p = 0;
+ } else {
+ jvalue val;
+ val.l = jo.get();
+ map_to_uno(
+ jni, p, val, member_type, 0, assign, false,
+ true );
+ }
+ } else {
+ *(jdouble *) p = jni->GetDoubleField(
+ java_data.l, field_id );
+ }
+ break;
+ default:
+ {
+ JLocalAutoRef jo_field( jni );
+ bool checkNull;
+ if (0 == field_id)
+ {
+ // special for Message: call Throwable.getMessage()
+ OSL_ASSERT(
+ type_equals(
+ type,
+ m_jni_info->m_Exception_type.getTypeLibType() )
+ || type_equals(
+ type,
+ m_jni_info->m_RuntimeException_type.
+ getTypeLibType() ) );
+ OSL_ASSERT( 0 == nPos ); // first member
+ // call getMessage()
+ jo_field.reset(
+ jni->CallObjectMethodA(
+ java_data.l,
+ m_jni_info->m_method_Throwable_getMessage, 0 )
+ );
+ jni.ensure_no_exception();
+ checkNull = true;
+ }
+ else
+ {
+ jo_field.reset(
+ jni->GetObjectField( java_data.l, field_id ) );
+ checkNull = parameterizedType;
+ }
+ if (checkNull && !jo_field.is()) {
+ createDefaultUnoValue(jni, p, member_type, 0, assign);
+ } else {
+ jvalue val;
+ val.l = jo_field.get();
+ map_to_uno(
+ jni, p, val, member_type, 0,
+ assign, false /* no out param */ );
+ }
+ break;
+ }
+ }
+ }
+ }
+ catch (...)
+ {
+ if (! assign)
+ {
+ // cleanup
+ for ( sal_Int32 nCleanup = 0; nCleanup < nPos; ++nCleanup )
+ {
+ void * p =
+ (char *)uno_data + comp_td->pMemberOffsets[ nCleanup ];
+ uno_type_destructData(
+ p, comp_td->ppTypeRefs[ nCleanup ], 0 );
+ }
+ if (0 != comp_td->pBaseTypeDescription)
+ {
+ uno_destructData(
+ uno_data,
+ (typelib_TypeDescription *) comp_td
+ ->pBaseTypeDescription, 0 );
+ }
+ }
+ throw;
+ }
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+ if (0 == java_data.l)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+
+ TypeDescr td( type );
+ typelib_TypeDescriptionReference * element_type =
+ ((typelib_IndirectTypeDescription *)td.get())->pType;
+
+ auto_ptr< rtl_mem > seq;
+ sal_Int32 nElements = jni->GetArrayLength( (jarray) java_data.l );
+
+ switch (element_type->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ seq.reset( seq_allocate( nElements, sizeof (sal_Unicode) ) );
+ jni->GetCharArrayRegion(
+ (jcharArray) java_data.l, 0, nElements,
+ (jchar *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ seq.reset( seq_allocate( nElements, sizeof (sal_Bool) ) );
+ jni->GetBooleanArrayRegion(
+ (jbooleanArray) java_data.l, 0, nElements,
+ (jboolean *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_BYTE:
+ seq.reset( seq_allocate( nElements, sizeof (sal_Int8) ) );
+ jni->GetByteArrayRegion(
+ (jbyteArray) java_data.l, 0, nElements,
+ (jbyte *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ seq.reset( seq_allocate( nElements, sizeof (sal_Int16) ) );
+ jni->GetShortArrayRegion(
+ (jshortArray) java_data.l, 0, nElements,
+ (jshort *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ seq.reset( seq_allocate( nElements, sizeof (sal_Int32) ) );
+ jni->GetIntArrayRegion(
+ (jintArray) java_data.l, 0, nElements,
+ (jint *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ seq.reset( seq_allocate( nElements, sizeof (sal_Int64) ) );
+ jni->GetLongArrayRegion(
+ (jlongArray) java_data.l, 0, nElements,
+ (jlong *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_FLOAT:
+ seq.reset( seq_allocate( nElements, sizeof (float) ) );
+ jni->GetFloatArrayRegion(
+ (jfloatArray) java_data.l, 0, nElements,
+ (jfloat *)((uno_Sequence *)seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_DOUBLE:
+ seq.reset( seq_allocate( nElements, sizeof (double) ) );
+ jni->GetDoubleArrayRegion(
+ (jdoubleArray) java_data.l, 0, nElements,
+ (jdouble *) ((uno_Sequence *) seq.get())->elements );
+ jni.ensure_no_exception();
+ break;
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_INTERFACE:
+ {
+ TypeDescr element_td( element_type );
+ seq.reset( seq_allocate( nElements, element_td.get()->nSize ) );
+
+ JNI_type_info const * element_info;
+ if (typelib_TypeClass_STRUCT == element_type->eTypeClass ||
+ typelib_TypeClass_EXCEPTION == element_type->eTypeClass ||
+ typelib_TypeClass_INTERFACE == element_type->eTypeClass)
+ {
+ element_info =
+ m_jni_info->get_type_info( jni, element_td.get() );
+ }
+ else
+ {
+ element_info = 0;
+ }
+
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ try
+ {
+ JLocalAutoRef jo(
+ jni, jni->GetObjectArrayElement(
+ (jobjectArray) java_data.l, nPos ) );
+ jni.ensure_no_exception();
+ jvalue val;
+ val.l = jo.get();
+ void * p =
+ ((uno_Sequence *)seq.get())->elements +
+ (nPos * element_td.get()->nSize);
+ map_to_uno(
+ jni, p, val, element_td.get()->pWeakRef, element_info,
+ false /* no assign */, false /* no out param */ );
+ }
+ catch (...)
+ {
+ // cleanup
+ for ( sal_Int32 nCleanPos = 0;
+ nCleanPos < nPos; ++nCleanPos )
+ {
+ void * p =
+ ((uno_Sequence *)seq.get())->elements +
+ (nCleanPos * element_td.get()->nSize);
+ uno_destructData( p, element_td.get(), 0 );
+ }
+ throw;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] unsupported sequence element"
+ " type: ") );
+ buf.append( OUString::unacquired( &element_type->pTypeName ) );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+
+ if (assign)
+ uno_destructData( uno_data, td.get(), 0 );
+ *(uno_Sequence **)uno_data = (uno_Sequence *)seq.release();
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ JLocalAutoRef jo_out_holder( jni );
+ if (out_param)
+ {
+ jo_out_holder.reset(
+ jni->GetObjectArrayElement( (jobjectArray) java_data.l, 0 ) );
+ jni.ensure_no_exception();
+ java_data.l = jo_out_holder.get();
+ }
+
+ if (0 == java_data.l) // null-ref
+ {
+ if (assign)
+ {
+ uno_Interface * p = *(uno_Interface **)uno_data;
+ if (0 != p)
+ (*p->release)( p );
+ }
+ *(uno_Interface **)uno_data = 0;
+ }
+ else
+ {
+ if (0 == info)
+ info = m_jni_info->get_type_info( jni, type );
+ JNI_interface_type_info const * iface_info =
+ static_cast< JNI_interface_type_info const * >( info );
+ uno_Interface * pUnoI = map_to_uno( jni, java_data.l, iface_info );
+ if (assign)
+ {
+ uno_Interface * p = *(uno_Interface **)uno_data;
+ if (0 != p)
+ (*p->release)( p );
+ }
+ *(uno_Interface **)uno_data = pUnoI;
+ }
+ break;
+ }
+ default:
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+}
+
+//##############################################################################
+
+//______________________________________________________________________________
+void Bridge::map_to_java(
+ JNI_context const & jni,
+ jvalue * java_data, void const * uno_data,
+ typelib_TypeDescriptionReference * type,
+ JNI_type_info const * info /* maybe 0 */,
+ bool in_param, bool out_param,
+ bool special_wrapped_integral_types ) const
+{
+ switch (type->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewCharArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetCharArrayRegion(
+ (jcharArray) jo_ar.get(), 0, 1, (jchar *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetCharArrayRegion(
+ (jcharArray) java_data->l, 0, 1, (jchar *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.c = *(jchar const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Character,
+ m_jni_info->m_ctor_Character_with_char, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->c = *(jchar const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewBooleanArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetBooleanArrayRegion(
+ (jbooleanArray) jo_ar.get(),
+ 0, 1, (jboolean *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetBooleanArrayRegion(
+ (jbooleanArray) java_data->l,
+ 0, 1, (jboolean *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.z = *(jboolean const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Boolean,
+ m_jni_info->m_ctor_Boolean_with_boolean, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->z = *(jboolean const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewByteArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetByteArrayRegion(
+ (jbyteArray) jo_ar.get(), 0, 1, (jbyte *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetByteArrayRegion(
+ (jbyteArray) java_data->l, 0, 1, (jbyte *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.b = *(jbyte const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Byte,
+ m_jni_info->m_ctor_Byte_with_byte, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->b = *(jbyte const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewShortArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetShortArrayRegion(
+ (jshortArray) jo_ar.get(), 0, 1, (jshort *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetShortArrayRegion(
+ (jshortArray) java_data->l, 0, 1, (jshort *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.s = *(jshort const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Short,
+ m_jni_info->m_ctor_Short_with_short, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->s = *(jshort const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewIntArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetIntArrayRegion(
+ (jintArray) jo_ar.get(), 0, 1, (jint *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetIntArrayRegion(
+ (jintArray) java_data->l, 0, 1, (jint *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.i = *(jint const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Integer,
+ m_jni_info->m_ctor_Integer_with_int, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->i = *(jint const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewLongArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetLongArrayRegion(
+ (jlongArray)jo_ar.get(), 0, 1, (jlong *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetLongArrayRegion(
+ (jlongArray)java_data->l, 0, 1, (jlong *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.j = *(jlong const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Long,
+ m_jni_info->m_ctor_Long_with_long, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->j = *(jlong const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewFloatArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetFloatArrayRegion(
+ (jfloatArray) jo_ar.get(), 0, 1, (jfloat *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetFloatArrayRegion(
+ (jfloatArray) java_data->l, 0, 1, (jfloat *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.f = *(jfloat const *) uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Float,
+ m_jni_info->m_ctor_Float_with_float, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->f = *(jfloat const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_ar( jni, jni->NewDoubleArray( 1 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ jni->SetDoubleArrayRegion(
+ (jdoubleArray) jo_ar.get(),
+ 0, 1, (jdouble *) uno_data );
+ jni.ensure_no_exception();
+ }
+ java_data->l = jo_ar.release();
+ }
+ else
+ {
+ if (in_param)
+ {
+ jni->SetDoubleArrayRegion(
+ (jdoubleArray) java_data->l,
+ 0, 1, (jdouble *) uno_data );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ else if (special_wrapped_integral_types)
+ {
+ jvalue arg;
+ arg.d = *(double const *)uno_data;
+ java_data->l = jni->NewObjectA(
+ m_jni_info->m_class_Double,
+ m_jni_info->m_ctor_Double_with_double, &arg );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ java_data->d = *(jdouble const *) uno_data;
+ }
+ break;
+ case typelib_TypeClass_STRING:
+ {
+ if (out_param)
+ {
+ JLocalAutoRef jo_in( jni );
+ if (in_param)
+ {
+ jo_in.reset(
+ ustring_to_jstring(
+ jni, *(rtl_uString * const *) uno_data ) );
+ }
+ if (0 == java_data->l)
+ {
+ java_data->l = jni->NewObjectArray(
+ 1, m_jni_info->m_class_String, jo_in.get() );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_in.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ OSL_ASSERT( in_param );
+ java_data->l =
+ ustring_to_jstring( jni, *(rtl_uString * const *) uno_data );
+ }
+ break;
+ }
+ case typelib_TypeClass_TYPE:
+ {
+ if (out_param)
+ {
+ JLocalAutoRef jo_in( jni );
+ if (in_param)
+ {
+ jo_in.reset(
+ create_type(
+ jni,
+ *(typelib_TypeDescriptionReference * const *) uno_data )
+ );
+ }
+ if (0 == java_data->l)
+ {
+ java_data->l = jni->NewObjectArray(
+ 1, m_jni_info->m_class_Type, jo_in.get() );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_in.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ OSL_ASSERT( in_param );
+ java_data->l =
+ create_type(
+ jni,
+ *(typelib_TypeDescriptionReference * const *) uno_data );
+ }
+ break;
+ }
+ case typelib_TypeClass_ANY:
+ {
+ JLocalAutoRef jo_any( jni );
+ if (in_param)
+ {
+ uno_Any const * pAny = (uno_Any const *)uno_data;
+
+#if defined BRIDGES_JNI_UNO_FORCE_BOXED_ANY
+ if (typelib_TypeClass_VOID == pAny->pType->eTypeClass)
+ {
+ jo_any.reset(
+ jni->NewLocalRef( m_jni_info->m_object_Any_VOID ) );
+ }
+ else
+ {
+ jvalue args[ 2 ];
+ map_to_java(
+ jni, &args[ 1 ], pAny->pData, pAny->pType, 0,
+ true /* in */, false /* no out */,
+ true /* create integral wrappers */ );
+ jo_any.reset( args[ 1 ].l );
+ // build up com.sun.star.uno.Any
+ JLocalAutoRef jo_type( jni, create_type( jni, pAny->pType ) );
+ args[ 0 ].l = jo_type.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args ) );
+ jni.ensure_no_exception();
+ }
+#else
+ switch (pAny->pType->eTypeClass)
+ {
+ case typelib_TypeClass_VOID:
+ jo_any.reset(
+ jni->NewLocalRef( m_jni_info->m_object_Any_VOID ) );
+ break;
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ {
+ jvalue args[ 2 ];
+ args[ 0 ].s = *(jshort const *) pAny->pData;
+ JLocalAutoRef jo_val(
+ jni, jni->NewObjectA(
+ m_jni_info->m_class_Short,
+ m_jni_info->m_ctor_Short_with_short, args ) );
+ jni.ensure_no_exception();
+ // box up in com.sun.star.uno.Any
+ args[ 0 ].l = m_jni_info->m_object_Type_UNSIGNED_SHORT;
+ args[ 1 ].l = jo_val.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args ) );
+ jni.ensure_no_exception();
+ break;
+ }
+ case typelib_TypeClass_UNSIGNED_LONG:
+ {
+ jvalue args[ 2 ];
+ args[ 0 ].i = *(jint const *) pAny->pData;
+ JLocalAutoRef jo_val(
+ jni, jni->NewObjectA(
+ m_jni_info->m_class_Integer,
+ m_jni_info->m_ctor_Integer_with_int, args ) );
+ jni.ensure_no_exception();
+ // box up in com.sun.star.uno.Any
+ args[ 0 ].l = m_jni_info->m_object_Type_UNSIGNED_LONG;
+ args[ 1 ].l = jo_val.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args ) );
+ jni.ensure_no_exception();
+ break;
+ }
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ {
+ jvalue args[ 2 ];
+ args[ 0 ].j = *(jlong const *) pAny->pData;
+ JLocalAutoRef jo_val(
+ jni, jni->NewObjectA(
+ m_jni_info->m_class_Long,
+ m_jni_info->m_ctor_Long_with_long, args ) );
+ jni.ensure_no_exception();
+ // box up in com.sun.star.uno.Any
+ args[ 0 ].l = m_jni_info->m_object_Type_UNSIGNED_HYPER;
+ args[ 1 ].l = jo_val.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args ) );
+ jni.ensure_no_exception();
+ break;
+ }
+ case typelib_TypeClass_STRING: // opt strings
+ jo_any.reset( ustring_to_jstring(
+ jni, (rtl_uString *) pAny->pReserved ) );
+ break;
+ case typelib_TypeClass_SEQUENCE:
+ {
+ jvalue java_data2;
+ // prefetch sequence td
+ TypeDescr seq_td( pAny->pType );
+ map_to_java(
+ jni, &java_data2, pAny->pData, seq_td.get()->pWeakRef, 0,
+ true /* in */, false /* no out */,
+ true /* create integral wrappers */ );
+ jo_any.reset( java_data2.l );
+
+ // determine inner element type
+ ::com::sun::star::uno::Type element_type(
+ ((typelib_IndirectTypeDescription *)seq_td.get())->pType );
+ while (typelib_TypeClass_SEQUENCE ==
+ element_type.getTypeLibType()->eTypeClass)
+ {
+ TypeDescr element_td( element_type.getTypeLibType() );
+ typelib_typedescriptionreference_assign(
+ reinterpret_cast< typelib_TypeDescriptionReference ** >(
+ &element_type ),
+ ((typelib_IndirectTypeDescription *)element_td.get())
+ ->pType );
+ }
+ // box up only if unsigned element type
+ switch (element_type.getTypeLibType()->eTypeClass)
+ {
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ {
+ jvalue args[ 2 ];
+ JLocalAutoRef jo_type(
+ jni, create_type( jni, seq_td.get()->pWeakRef ) );
+ args[ 0 ].l = jo_type.get();
+ args[ 1 ].l = jo_any.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args ) );
+ jni.ensure_no_exception();
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ uno_Interface * pUnoI = (uno_Interface *)pAny->pReserved;
+ if (is_XInterface( pAny->pType ))
+ {
+ if (0 != pUnoI)
+ {
+ jo_any.reset(
+ map_to_java(
+ jni, pUnoI,
+ m_jni_info->m_XInterface_type_info ) );
+ }
+ // else: empty XInterface ref maps to null-ref
+ }
+ else
+ {
+ JNI_interface_type_info const * iface_info =
+ static_cast< JNI_interface_type_info const * >(
+ m_jni_info->get_type_info( jni, pAny->pType ) );
+ if (0 != pUnoI)
+ {
+ jo_any.reset( map_to_java( jni, pUnoI, iface_info ) );
+ }
+ // box up in com.sun.star.uno.Any
+ jvalue args[ 2 ];
+ args[ 0 ].l = iface_info->m_type;
+ args[ 1 ].l = jo_any.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args ) );
+ jni.ensure_no_exception();
+ }
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ {
+ // Do not lose information about type arguments of instantiated
+ // polymorphic struct types:
+ rtl::OUString const & name = rtl::OUString::unacquired(
+ &pAny->pType->pTypeName);
+ OSL_ASSERT(name.getLength() > 0);
+ if (name[name.getLength() - 1] == '>')
+ {
+ // Box up in com.sun.star.uno.Any:
+ JLocalAutoRef jo_type(jni, create_type(jni, pAny->pType));
+ jvalue java_data2;
+ map_to_java(
+ jni, &java_data2, pAny->pData, pAny->pType, 0, true,
+ false);
+ jo_any.reset(java_data2.l);
+ jvalue args[2];
+ args[0].l = jo_type.get();
+ args[1].l = jo_any.get();
+ jo_any.reset(
+ jni->NewObjectA(
+ m_jni_info->m_class_Any,
+ m_jni_info->m_ctor_Any_with_Type_Object, args));
+ jni.ensure_no_exception();
+ break;
+ }
+ // fall through
+ }
+ default:
+ {
+ jvalue java_data2;
+ map_to_java(
+ jni, &java_data2, pAny->pData, pAny->pType, 0,
+ true /* in */, false /* no out */,
+ true /* create integral wrappers */ );
+ jo_any.reset( java_data2.l );
+ break;
+ }
+ }
+#endif
+ }
+
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ java_data->l = jni->NewObjectArray(
+ 1, m_jni_info->m_class_Object, jo_any.get() );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_any.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ java_data->l = jo_any.release();
+ }
+ break;
+ }
+ case typelib_TypeClass_ENUM:
+ {
+ OUString const & type_name = OUString::unacquired( &type->pTypeName );
+ OString class_name(
+ OUStringToOString( type_name, RTL_TEXTENCODING_JAVA_UTF8 ) );
+ JLocalAutoRef jo_enum_class(
+ jni, find_class( jni, class_name.getStr() ) );
+
+ JLocalAutoRef jo_enum( jni );
+ if (in_param)
+ {
+ // call static <enum_class>.fromInt( int )
+ OStringBuffer sig_buf( 5 + class_name.getLength() );
+ sig_buf.append( RTL_CONSTASCII_STRINGPARAM("(I)L") );
+ sig_buf.append( class_name.replace( '.', '/' ) );
+ sig_buf.append( ';' );
+ OString sig( sig_buf.makeStringAndClear() );
+ jmethodID method_id = jni->GetStaticMethodID(
+ (jclass) jo_enum_class.get(), "fromInt", sig.getStr() );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != method_id );
+
+ jvalue arg;
+ arg.i = *(jint const *) uno_data;
+ jo_enum.reset(
+ jni->CallStaticObjectMethodA(
+ (jclass) jo_enum_class.get(), method_id, &arg ) );
+ jni.ensure_no_exception();
+ }
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ java_data->l = jni->NewObjectArray(
+ 1, (jclass) jo_enum_class.get(), jo_enum.get() );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_enum.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ java_data->l = jo_enum.release();
+ }
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ if (0 == info)
+ info = m_jni_info->get_type_info( jni, type );
+ JNI_compound_type_info const * comp_info =
+ static_cast< JNI_compound_type_info const * >( info );
+
+ JLocalAutoRef jo_comp( jni );
+ if (in_param)
+ {
+ if (typelib_TypeClass_EXCEPTION == type->eTypeClass)
+ {
+ JLocalAutoRef jo_message(
+ jni, ustring_to_jstring( jni, *(rtl_uString **)uno_data ) );
+ jvalue arg;
+ arg.l = jo_message.get();
+ jo_comp.reset(
+ jni->NewObjectA(
+ comp_info->m_class, comp_info->m_exc_ctor, &arg ) );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jo_comp.reset( jni->AllocObject( comp_info->m_class ) );
+ jni.ensure_no_exception();
+ }
+
+ for ( JNI_compound_type_info const * linfo = comp_info;
+ 0 != linfo;
+ linfo = static_cast< JNI_compound_type_info const * >(
+ linfo->m_base ) )
+ {
+ typelib_CompoundTypeDescription * comp_td =
+ (typelib_CompoundTypeDescription *)linfo->m_td.get();
+ typelib_TypeDescriptionReference ** ppMemberTypeRefs =
+ comp_td->ppTypeRefs;
+ sal_Int32 * pMemberOffsets = comp_td->pMemberOffsets;
+ bool polymorphic
+ = comp_td->aBase.eTypeClass == typelib_TypeClass_STRUCT
+ && reinterpret_cast< typelib_StructTypeDescription * >(
+ comp_td)->pParameterizedTypes != 0;
+ for ( sal_Int32 nPos = comp_td->nMembers; nPos--; )
+ {
+ jfieldID field_id = linfo->m_fields[ nPos ];
+ if (0 != field_id)
+ {
+ void const * p =
+ (char const *)uno_data + pMemberOffsets[ nPos ];
+ typelib_TypeDescriptionReference * member_type =
+ ppMemberTypeRefs[ nPos ];
+ bool parameterizedType = polymorphic
+ && (reinterpret_cast<
+ typelib_StructTypeDescription * >(comp_td)->
+ pParameterizedTypes[nPos]);
+ switch (member_type->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.c = *(jchar const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Character,
+ m_jni_info->m_ctor_Character_with_char,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetCharField(
+ jo_comp.get(),
+ field_id, *(jchar const *) p );
+ }
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.z = *(jboolean const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Boolean,
+ m_jni_info->m_ctor_Boolean_with_boolean,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetBooleanField(
+ jo_comp.get(),
+ field_id, *(jboolean const *) p );
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.b = *(jbyte const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Byte,
+ m_jni_info->m_ctor_Byte_with_byte,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetByteField(
+ jo_comp.get(),
+ field_id, *(jbyte const *) p );
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.s = *(jshort const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Short,
+ m_jni_info->m_ctor_Short_with_short,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetShortField(
+ jo_comp.get(),
+ field_id, *(jshort const *) p );
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.i = *(jint const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Integer,
+ m_jni_info->m_ctor_Integer_with_int,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetIntField(
+ jo_comp.get(),
+ field_id, *(jint const *) p );
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.j = *(jlong const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Long,
+ m_jni_info->m_ctor_Long_with_long,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetLongField(
+ jo_comp.get(),
+ field_id, *(jlong const *) p );
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.f = *(jfloat const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Float,
+ m_jni_info->m_ctor_Float_with_float,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetFloatField(
+ jo_comp.get(),
+ field_id, *(jfloat const *) p );
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (parameterizedType) {
+ jvalue arg;
+ arg.d = *(jdouble const *) p;
+ JLocalAutoRef jo(
+ jni,
+ jni->NewObjectA(
+ m_jni_info->m_class_Double,
+ m_jni_info->m_ctor_Double_with_double,
+ &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo.get() );
+ } else {
+ jni->SetDoubleField(
+ jo_comp.get(),
+ field_id, *(jdouble const *) p );
+ }
+ break;
+ case typelib_TypeClass_STRING: // string opt here
+ {
+ JLocalAutoRef jo_string(
+ jni, ustring_to_jstring(
+ jni, *(rtl_uString * const *) p ) );
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo_string.get() );
+ break;
+ }
+ default:
+ {
+ jvalue java_data2;
+ map_to_java(
+ jni, &java_data2, p, member_type, 0,
+ true /* in */, false /* no out */ );
+ JLocalAutoRef jo_obj( jni, java_data2.l );
+ jni->SetObjectField(
+ jo_comp.get(), field_id, jo_obj.get() );
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ java_data->l =
+ jni->NewObjectArray( 1, comp_info->m_class, jo_comp.get() );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_comp.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ java_data->l = jo_comp.release();
+ }
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ // xxx todo: possible opt for pure out sequences
+ JLocalAutoRef jo_ar( jni );
+
+ sal_Int32 nElements;
+ uno_Sequence const * seq = 0;
+ if (in_param)
+ {
+ seq = *(uno_Sequence * const *)uno_data;
+ nElements = seq->nElements;
+ }
+ else
+ {
+ nElements = 0;
+ }
+
+ TypeDescr td( type );
+ typelib_TypeDescriptionReference * element_type =
+ ((typelib_IndirectTypeDescription *)td.get())->pType;
+
+ switch (element_type->eTypeClass)
+ {
+ case typelib_TypeClass_CHAR:
+ jo_ar.reset( jni->NewCharArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetCharArrayRegion(
+ (jcharArray) jo_ar.get(),
+ 0, nElements, (jchar *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ jo_ar.reset( jni->NewBooleanArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetBooleanArrayRegion(
+ (jbooleanArray) jo_ar.get(),
+ 0, nElements, (jboolean *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_BYTE:
+ jo_ar.reset( jni->NewByteArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetByteArrayRegion(
+ (jbyteArray) jo_ar.get(),
+ 0, nElements, (jbyte *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ jo_ar.reset( jni->NewShortArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetShortArrayRegion(
+ (jshortArray) jo_ar.get(),
+ 0, nElements, (jshort *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ jo_ar.reset( jni->NewIntArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetIntArrayRegion(
+ (jintArray) jo_ar.get(),
+ 0, nElements, (jint *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ jo_ar.reset( jni->NewLongArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetLongArrayRegion(
+ (jlongArray) jo_ar.get(),
+ 0, nElements, (jlong *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ jo_ar.reset( jni->NewFloatArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetFloatArrayRegion(
+ (jfloatArray) jo_ar.get(),
+ 0, nElements, (jfloat *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ jo_ar.reset( jni->NewDoubleArray( nElements ) );
+ jni.ensure_no_exception();
+ if (0 < nElements)
+ {
+ jni->SetDoubleArrayRegion(
+ (jdoubleArray) jo_ar.get(),
+ 0, nElements, (jdouble *) seq->elements );
+ jni.ensure_no_exception();
+ }
+ break;
+ case typelib_TypeClass_STRING:
+ jo_ar.reset(
+ jni->NewObjectArray(
+ nElements, m_jni_info->m_class_String, 0 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ rtl_uString * const * pp =
+ (rtl_uString * const *) seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ JLocalAutoRef jo_string(
+ jni, ustring_to_jstring( jni, pp[ nPos ] ) );
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(), nPos, jo_string.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ break;
+ case typelib_TypeClass_TYPE:
+ jo_ar.reset(
+ jni->NewObjectArray( nElements, m_jni_info->m_class_Type, 0 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ typelib_TypeDescriptionReference * const * pp =
+ (typelib_TypeDescriptionReference * const *)seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ jvalue val;
+ map_to_java(
+ jni, &val, &pp[ nPos ], element_type, 0,
+ true /* in */, false /* no out */ );
+ JLocalAutoRef jo_element( jni, val.l );
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(), nPos, jo_element.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ break;
+ case typelib_TypeClass_ANY:
+ jo_ar.reset(
+ jni->NewObjectArray(
+ nElements, m_jni_info->m_class_Object, 0 ) );
+ jni.ensure_no_exception();
+ if (in_param)
+ {
+ uno_Any const * p = (uno_Any const *)seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ jvalue val;
+ map_to_java(
+ jni, &val, &p[ nPos ], element_type, 0,
+ true /* in */, false /* no out */ );
+ JLocalAutoRef jo_element( jni, val.l );
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(), nPos, jo_element.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ break;
+ case typelib_TypeClass_ENUM:
+ {
+ OUString const & element_type_name =
+ OUString::unacquired( &element_type->pTypeName );
+ OString class_name(
+ OUStringToOString(
+ element_type_name, RTL_TEXTENCODING_JAVA_UTF8 ) );
+ JLocalAutoRef jo_enum_class(
+ jni, find_class( jni, class_name.getStr() ) );
+
+ jo_ar.reset(
+ jni->NewObjectArray(
+ nElements, (jclass) jo_enum_class.get(), 0 ) );
+ jni.ensure_no_exception();
+
+ if (0 < nElements)
+ {
+ // call static <enum_class>.fromInt( int )
+ OStringBuffer sig_buf( 5 + class_name.getLength() );
+ sig_buf.append( RTL_CONSTASCII_STRINGPARAM("(I)L") );
+ sig_buf.append( class_name.replace( '.', '/' ) );
+ sig_buf.append( ';' );
+ OString sig( sig_buf.makeStringAndClear() );
+ jmethodID method_id = jni->GetStaticMethodID(
+ (jclass) jo_enum_class.get(), "fromInt", sig.getStr() );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != method_id );
+
+ sal_Int32 const * p = (sal_Int32 const *)seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ jvalue arg;
+ arg.i = p[ nPos ];
+ JLocalAutoRef jo_enum(
+ jni, jni->CallStaticObjectMethodA(
+ (jclass) jo_enum_class.get(), method_id, &arg ) );
+ jni.ensure_no_exception();
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(), nPos, jo_enum.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ JNI_type_info const * element_info =
+ m_jni_info->get_type_info( jni, element_type );
+
+ jo_ar.reset(
+ jni->NewObjectArray( nElements, element_info->m_class, 0 ) );
+ jni.ensure_no_exception();
+
+ if (0 < nElements)
+ {
+ char * p = (char *)seq->elements;
+ sal_Int32 nSize = element_info->m_td.get()->nSize;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ jvalue val;
+ map_to_java(
+ jni, &val, p + (nSize * nPos),
+ element_type, element_info,
+ true /* in */, false /* no out */ );
+ JLocalAutoRef jo_element( jni, val.l );
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(), nPos, jo_element.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ OStringBuffer buf( 64 );
+ JNI_info::append_sig(
+ &buf, element_type, false /* use class XInterface */,
+ false /* '.' instead of '/' */ );
+ OString class_name( buf.makeStringAndClear() );
+ JLocalAutoRef jo_seq_class(
+ jni, find_class( jni, class_name.getStr() ) );
+
+ jo_ar.reset(
+ jni->NewObjectArray(
+ nElements, (jclass) jo_seq_class.get(), 0 ) );
+ jni.ensure_no_exception();
+
+ if (0 < nElements)
+ {
+ TypeDescr element_td( element_type );
+ uno_Sequence ** elements = (uno_Sequence **) seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ jvalue java_data2;
+ map_to_java(
+ jni, &java_data2, elements + nPos, element_type, 0,
+ true /* in */, false /* no out */ );
+ JLocalAutoRef jo_seq( jni, java_data2.l );
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(), nPos, jo_seq.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ JNI_interface_type_info const * iface_info =
+ static_cast< JNI_interface_type_info const * >(
+ m_jni_info->get_type_info( jni, element_type ) );
+
+ jo_ar.reset(
+ jni->NewObjectArray( nElements, iface_info->m_class, 0 ) );
+ jni.ensure_no_exception();
+
+ if (0 < nElements)
+ {
+ uno_Interface ** pp = (uno_Interface **)seq->elements;
+ for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos )
+ {
+ uno_Interface * pUnoI = pp[ nPos ];
+ if (0 != pUnoI)
+ {
+ JLocalAutoRef jo_element(
+ jni, map_to_java( jni, pUnoI, iface_info ) );
+ jni->SetObjectArrayElement(
+ (jobjectArray) jo_ar.get(),
+ nPos, jo_element.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ }
+ break;
+ }
+ default:
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_java():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("] unsupported element type: ") );
+ buf.append( OUString::unacquired( &element_type->pTypeName ) );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ JLocalAutoRef jo_element_class(
+ jni, jni->GetObjectClass( jo_ar.get() ) );
+ if (in_param)
+ {
+ java_data->l = jni->NewObjectArray(
+ 1, (jclass) jo_element_class.get(), jo_ar.get() );
+ }
+ else
+ {
+ java_data->l = jni->NewObjectArray(
+ 1, (jclass) jo_element_class.get(), 0 );
+ }
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_ar.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ java_data->l = jo_ar.release();
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ JLocalAutoRef jo_iface( jni );
+ if (in_param)
+ {
+ uno_Interface * pUnoI = *(uno_Interface * const *)uno_data;
+ if (0 != pUnoI)
+ {
+ if (0 == info)
+ info = m_jni_info->get_type_info( jni, type );
+ JNI_interface_type_info const * iface_info =
+ static_cast< JNI_interface_type_info const * >( info );
+ jo_iface.reset( map_to_java( jni, pUnoI, iface_info ) );
+ }
+ }
+ if (out_param)
+ {
+ if (0 == java_data->l)
+ {
+ if (0 == info)
+ info = m_jni_info->get_type_info( jni, type );
+ java_data->l =
+ jni->NewObjectArray( 1, info->m_class, jo_iface.get() );
+ jni.ensure_no_exception();
+ }
+ else
+ {
+ jni->SetObjectArrayElement(
+ (jobjectArray) java_data->l, 0, jo_iface.get() );
+ jni.ensure_no_exception();
+ }
+ }
+ else
+ {
+ java_data->l = jo_iface.release();
+ }
+ break;
+ }
+ default:
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_java():") );
+ buf.append( OUString::unacquired( &type->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/jni_uno/jni_helper.h b/bridges/source/jni_uno/jni_helper.h
new file mode 100644
index 000000000000..293bf82d868e
--- /dev/null
+++ b/bridges/source/jni_uno/jni_helper.h
@@ -0,0 +1,165 @@
+/* -*- 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_JNI_HELPER_H
+#define INCLUDED_JNI_HELPER_H
+
+#include "jni_base.h"
+#include "jni_info.h"
+
+
+namespace jni_uno
+{
+
+//------------------------------------------------------------------------------
+inline void jstring_to_ustring(
+ JNI_context const & jni, rtl_uString ** out_ustr, jstring jstr )
+{
+ if (0 == jstr)
+ {
+ rtl_uString_new( out_ustr );
+ }
+ else
+ {
+ jsize len = jni->GetStringLength( jstr );
+ ::std::auto_ptr< rtl_mem > mem(
+ rtl_mem::allocate(
+ sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) ) );
+ rtl_uString * ustr = (rtl_uString *)mem.get();
+ jni->GetStringRegion( jstr, 0, len, (jchar *) ustr->buffer );
+ jni.ensure_no_exception();
+ ustr->refCount = 1;
+ ustr->length = len;
+ ustr->buffer[ len ] = '\0';
+ mem.release();
+ if (0 != *out_ustr)
+ rtl_uString_release( *out_ustr );
+ *out_ustr = ustr;
+ }
+}
+
+//------------------------------------------------------------------------------
+inline ::rtl::OUString jstring_to_oustring(
+ JNI_context const & jni, jstring jstr )
+{
+ rtl_uString * ustr = 0;
+ jstring_to_ustring( jni, &ustr, jstr );
+ return ::rtl::OUString( ustr, SAL_NO_ACQUIRE );
+}
+
+//------------------------------------------------------------------------------
+inline jstring ustring_to_jstring(
+ JNI_context const & jni, rtl_uString const * ustr )
+{
+ jstring jstr = jni->NewString( (jchar const *) ustr->buffer, ustr->length );
+ jni.ensure_no_exception();
+ return jstr;
+}
+
+
+//------------------------------------------------------------------------------
+// if inException, does not handle exceptions, in which case returned value will
+// be null if exception occurred:
+inline jclass find_class(
+ JNI_context const & jni, char const * class_name, bool inException = false )
+{
+ // find_class may be called before the JNI_info is set:
+ jclass c=0;
+ jmethodID m;
+ JNI_info const * info = jni.get_info();
+ if (info == 0) {
+ jni.getClassForName(&c, &m);
+ if (c == 0) {
+ if (inException) {
+ return 0;
+ }
+ jni.ensure_no_exception();
+ }
+ } else {
+ c = info->m_class_Class;
+ m = info->m_method_Class_forName;
+ }
+ return jni.findClass(class_name, c, m, inException);
+}
+
+
+//------------------------------------------------------------------------------
+inline jobject create_type( JNI_context const & jni, jclass clazz )
+{
+ JNI_info const * jni_info = jni.get_info();
+ jvalue arg;
+ arg.l = clazz;
+ jobject jo_type = jni->NewObjectA(
+ jni_info->m_class_Type, jni_info->m_ctor_Type_with_Class, &arg );
+ jni.ensure_no_exception();
+ return jo_type;
+}
+
+//------------------------------------------------------------------------------
+inline jobject create_type(
+ JNI_context const & jni, typelib_TypeDescriptionReference * type )
+{
+ JNI_info const * jni_info = jni.get_info();
+ jvalue args[ 2 ];
+ // get type class
+ args[ 0 ].i = type->eTypeClass;
+ JLocalAutoRef jo_type_class(
+ jni, jni->CallStaticObjectMethodA(
+ jni_info->m_class_TypeClass,
+ jni_info->m_method_TypeClass_fromInt, args ) );
+ jni.ensure_no_exception();
+ // construct type
+ JLocalAutoRef jo_type_name(
+ jni, ustring_to_jstring( jni, type->pTypeName ) );
+ args[ 0 ].l = jo_type_name.get();
+ args[ 1 ].l = jo_type_class.get();
+ jobject jo_type = jni->NewObjectA(
+ jni_info->m_class_Type,
+ jni_info->m_ctor_Type_with_Name_TypeClass, args );
+ jni.ensure_no_exception();
+ return jo_type;
+}
+
+//------------------------------------------------------------------------------
+inline jobject compute_oid( JNI_context const & jni, jobject jo )
+{
+ JNI_info const * jni_info = jni.get_info();
+ jvalue arg;
+ arg.l= jo;
+ jobject jo_oid = jni->CallStaticObjectMethodA(
+ jni_info->m_class_UnoRuntime,
+ jni_info->m_method_UnoRuntime_generateOid, &arg );
+ jni.ensure_no_exception();
+ return jo_oid;
+}
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/jni_uno/jni_info.cxx b/bridges/source/jni_uno/jni_info.cxx
new file mode 100644
index 000000000000..6df598859d0a
--- /dev/null
+++ b/bridges/source/jni_uno/jni_info.cxx
@@ -0,0 +1,999 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include "jni_bridge.h"
+
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+#include "jvmaccess/unovirtualmachine.hxx"
+#include "rtl/string.hxx"
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
+
+#include "uno/lbnames.h"
+
+
+namespace css = ::com::sun::star;
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+
+namespace jni_uno
+{
+
+//______________________________________________________________________________
+JNI_type_info::JNI_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td )
+ : m_td( td ),
+ m_class( 0 )
+{
+ m_td.makeComplete();
+ if (! m_td.get()->bComplete)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("cannot make type complete: ") );
+ buf.append( OUString::unacquired( &m_td.get()->pTypeName ) );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+}
+
+
+//______________________________________________________________________________
+void JNI_interface_type_info::destroy( JNIEnv * jni_env )
+{
+ JNI_type_info::destruct( jni_env );
+ jni_env->DeleteGlobalRef( m_proxy_ctor );
+ jni_env->DeleteGlobalRef( m_type );
+ delete [] m_methods;
+ delete this;
+}
+
+//______________________________________________________________________________
+JNI_interface_type_info::JNI_interface_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td_ )
+ : JNI_type_info( jni, td_ )
+{
+ OSL_ASSERT( typelib_TypeClass_INTERFACE == m_td.get()->eTypeClass );
+
+ OUString const & uno_name = OUString::unacquired( &m_td.get()->pTypeName );
+ JNI_info const * jni_info = jni.get_info();
+
+ JLocalAutoRef jo_class(
+ jni,
+ find_class(
+ jni,
+ ( OUStringToOString( uno_name, RTL_TEXTENCODING_JAVA_UTF8 ).
+ getStr() ) ) );
+ JLocalAutoRef jo_type( jni, create_type( jni, (jclass) jo_class.get() ) );
+
+ // get proxy ctor
+ jvalue arg;
+ arg.l = jo_class.get();
+ JLocalAutoRef jo_proxy_ctor(
+ jni, jni->CallStaticObjectMethodA(
+ jni_info->m_class_JNI_proxy,
+ jni_info->m_method_JNI_proxy_get_proxy_ctor, &arg ) );
+
+ if (is_XInterface( m_td.get()->pWeakRef ))
+ {
+ m_methods = 0; // no methods
+ }
+ else
+ {
+ // retrieve method ids for all direct members
+ try
+ {
+ typelib_InterfaceTypeDescription * td =
+ reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ m_td.get() );
+ m_methods = new jmethodID[ td->nMapFunctionIndexToMemberIndex ];
+ sal_Int32 nMethodIndex = 0;
+ typelib_TypeDescriptionReference ** ppMembers = td->ppMembers;
+ sal_Int32 nMembers = td->nMembers;
+
+ for ( sal_Int32 nPos = 0; nPos < nMembers; ++nPos )
+ {
+ TypeDescr member_td( ppMembers[ nPos ] );
+
+ OStringBuffer sig_buf( 64 );
+
+ if (typelib_TypeClass_INTERFACE_METHOD ==
+ member_td.get()->eTypeClass) // method
+ {
+ typelib_InterfaceMethodTypeDescription * method_td =
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member_td.get() );
+
+ sig_buf.append( '(' );
+ for ( sal_Int32 i = 0; i < method_td->nParams; ++i )
+ {
+ typelib_MethodParameter const & param =
+ method_td->pParams[ i ];
+ if (param.bOut)
+ sig_buf.append( '[' );
+ JNI_info::append_sig( &sig_buf, param.pTypeRef );
+ }
+ sig_buf.append( ')' );
+ JNI_info::append_sig( &sig_buf, method_td->pReturnTypeRef );
+
+ OString method_signature( sig_buf.makeStringAndClear() );
+ OString method_name(
+ OUStringToOString( OUString::unacquired(
+ &method_td->aBase.pMemberName ),
+ RTL_TEXTENCODING_JAVA_UTF8 ) );
+
+ m_methods[ nMethodIndex ] = jni->GetMethodID(
+ (jclass) jo_class.get(), method_name.getStr(),
+ method_signature.getStr() );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_methods[ nMethodIndex ] );
+ ++nMethodIndex;
+ }
+ else // attribute
+ {
+ OSL_ASSERT(
+ typelib_TypeClass_INTERFACE_ATTRIBUTE ==
+ member_td.get()->eTypeClass );
+ typelib_InterfaceAttributeTypeDescription * attribute_td =
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member_td.get() );
+
+ // type sig
+ JNI_info::append_sig(
+ &sig_buf, attribute_td->pAttributeTypeRef );
+ OString type_sig( sig_buf.makeStringAndClear() );
+ sig_buf.ensureCapacity( 64 );
+ // member name
+ OUString const & member_name =
+ OUString::unacquired(
+ &attribute_td->aBase.pMemberName );
+
+ // getter
+ sig_buf.append( RTL_CONSTASCII_STRINGPARAM("()") );
+ sig_buf.append( type_sig );
+ OString method_signature( sig_buf.makeStringAndClear() );
+ OUStringBuffer name_buf( 3 + member_name.getLength() );
+ name_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("get") );
+ name_buf.append( member_name );
+ OString method_name(
+ OUStringToOString(
+ name_buf.makeStringAndClear(),
+ RTL_TEXTENCODING_JAVA_UTF8 ) );
+ m_methods[ nMethodIndex ] = jni->GetMethodID(
+ (jclass) jo_class.get(), method_name.getStr(),
+ method_signature.getStr() );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_methods[ nMethodIndex ] );
+ ++nMethodIndex;
+ if (! attribute_td->bReadOnly)
+ {
+ // setter
+ sig_buf.ensureCapacity( 64 );
+ sig_buf.append( '(' );
+ sig_buf.append( type_sig );
+ sig_buf.append( RTL_CONSTASCII_STRINGPARAM(")V") );
+ method_signature = sig_buf.makeStringAndClear();
+ name_buf.ensureCapacity( 3 + member_name.getLength() );
+ name_buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("set") );
+ name_buf.append( member_name );
+ method_name = OUStringToOString(
+ name_buf.makeStringAndClear(),
+ RTL_TEXTENCODING_JAVA_UTF8 );
+ m_methods[ nMethodIndex ] = jni->GetMethodID(
+ (jclass) jo_class.get(), method_name.getStr(),
+ method_signature.getStr() );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_methods[ nMethodIndex ] );
+ ++nMethodIndex;
+ }
+ }
+ }
+ }
+ catch (...)
+ {
+ delete [] m_methods;
+ throw;
+ }
+ }
+ m_class = (jclass) jni->NewGlobalRef( jo_class.get() );
+ m_type = jni->NewGlobalRef( jo_type.get() );
+ m_proxy_ctor = jni->NewGlobalRef( jo_proxy_ctor.get() );
+}
+
+
+//______________________________________________________________________________
+void JNI_compound_type_info::destroy( JNIEnv * jni_env )
+{
+ JNI_type_info::destruct( jni_env );
+ delete [] m_fields;
+ delete this;
+}
+
+//______________________________________________________________________________
+JNI_compound_type_info::JNI_compound_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td_ )
+ : JNI_type_info( jni, td_ ),
+ m_exc_ctor( 0 ),
+ m_fields( 0 )
+{
+ OSL_ASSERT( typelib_TypeClass_STRUCT == m_td.get()->eTypeClass ||
+ typelib_TypeClass_EXCEPTION == m_td.get()->eTypeClass );
+ typelib_CompoundTypeDescription * td =
+ reinterpret_cast< typelib_CompoundTypeDescription * >( m_td.get() );
+
+ OUString const & uno_name =
+ OUString::unacquired( &((typelib_TypeDescription *)td)->pTypeName );
+
+ // Erase type arguments of instantiated polymorphic struct types:
+ OUString nucleus;
+ sal_Int32 i = uno_name.indexOf( '<' );
+ if ( i < 0 ) {
+ nucleus = uno_name;
+ } else {
+ nucleus = uno_name.copy( 0, i );
+ }
+ JLocalAutoRef jo_class(
+ jni,
+ find_class(
+ jni,
+ OUStringToOString(
+ nucleus, RTL_TEXTENCODING_JAVA_UTF8 ).getStr() ) );
+
+ JNI_info const * jni_info = jni.get_info();
+
+ if (typelib_TypeClass_EXCEPTION == m_td.get()->eTypeClass)
+ {
+ // retrieve exc ctor( msg )
+ m_exc_ctor = jni->GetMethodID(
+ (jclass) jo_class.get(), "<init>", "(Ljava/lang/String;)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_exc_ctor );
+ }
+
+ // retrieve info for base type
+ typelib_TypeDescription * base_td =
+ reinterpret_cast< typelib_TypeDescription * >(
+ td->pBaseTypeDescription );
+ m_base = (0 == base_td ? 0 : jni_info->get_type_info( jni, base_td ));
+
+ try
+ {
+ if (type_equals(
+ ((typelib_TypeDescription *)td)->pWeakRef,
+ jni_info->m_Exception_type.getTypeLibType() ) ||
+ type_equals(
+ ((typelib_TypeDescription *)td)->pWeakRef,
+ jni_info->m_RuntimeException_type.getTypeLibType() ))
+ {
+ m_fields = new jfieldID[ 2 ];
+ m_fields[ 0 ] = 0; // special Throwable.getMessage()
+ // field Context
+ m_fields[ 1 ] = jni->GetFieldID(
+ (jclass) jo_class.get(), "Context", "Ljava/lang/Object;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_fields[ 1 ] );
+ }
+ else
+ {
+ // retrieve field ids for all direct members
+ sal_Int32 nMembers = td->nMembers;
+ m_fields = new jfieldID[ nMembers ];
+
+ for ( sal_Int32 nPos = 0; nPos < nMembers; ++nPos )
+ {
+ OString sig;
+ if (td->aBase.eTypeClass == typelib_TypeClass_STRUCT
+ && reinterpret_cast< typelib_StructTypeDescription * >(
+ td)->pParameterizedTypes != 0
+ && reinterpret_cast< typelib_StructTypeDescription * >(
+ td)->pParameterizedTypes[nPos])
+ {
+ sig = OString(
+ RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;"));
+ } else {
+ OStringBuffer sig_buf( 32 );
+ JNI_info::append_sig( &sig_buf, td->ppTypeRefs[ nPos ] );
+ sig = sig_buf.makeStringAndClear();
+ }
+
+ OString member_name(
+ OUStringToOString(
+ OUString::unacquired( &td->ppMemberNames[ nPos ] ),
+ RTL_TEXTENCODING_JAVA_UTF8 ) );
+
+ m_fields[ nPos ] = jni->GetFieldID(
+ (jclass) jo_class.get(), member_name.getStr(),
+ sig.getStr() );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_fields[ nPos ] );
+ }
+ }
+ }
+ catch (...)
+ {
+ delete [] m_fields;
+ throw;
+ }
+
+ m_class = (jclass) jni->NewGlobalRef( jo_class.get() );
+}
+
+
+//______________________________________________________________________________
+JNI_type_info const * JNI_info::create_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td ) const
+{
+ OUString const & uno_name = OUString::unacquired( &td->pTypeName );
+
+ JNI_type_info * new_info;
+ switch (td->eTypeClass)
+ {
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ new_info = new JNI_compound_type_info( jni, td );
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ new_info = new JNI_interface_type_info( jni, td );
+ break;
+ }
+ default:
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("type info not supported for ") );
+ buf.append( uno_name );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+
+ // look up
+ JNI_type_info * info;
+ ClearableMutexGuard guard( m_mutex );
+ JNI_type_info_holder & holder = m_type_map[ uno_name ];
+ if (0 == holder.m_info) // new insertion
+ {
+ holder.m_info = new_info;
+ guard.clear();
+ info = new_info;
+ }
+ else // inserted in the meantime
+ {
+ info = holder.m_info;
+ guard.clear();
+ new_info->destroy( jni.get_jni_env() );
+ }
+ return info;
+}
+
+//______________________________________________________________________________
+JNI_type_info const * JNI_info::get_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td ) const
+{
+ if (is_XInterface( td->pWeakRef ))
+ {
+ return m_XInterface_type_info;
+ }
+
+ OUString const & uno_name = OUString::unacquired( &td->pTypeName );
+ JNI_type_info const * info;
+ ClearableMutexGuard guard( m_mutex );
+
+ t_str2type::const_iterator iFind( m_type_map.find( uno_name ) );
+ if (iFind == m_type_map.end())
+ {
+ guard.clear();
+ info = create_type_info( jni, td );
+ }
+ else
+ {
+ info = iFind->second.m_info;
+ }
+
+ return info;
+}
+
+//______________________________________________________________________________
+JNI_type_info const * JNI_info::get_type_info(
+ JNI_context const & jni, typelib_TypeDescriptionReference * type ) const
+{
+ if (is_XInterface( type ))
+ {
+ return m_XInterface_type_info;
+ }
+
+ OUString const & uno_name = OUString::unacquired( &type->pTypeName );
+ JNI_type_info const * info;
+ ClearableMutexGuard guard( m_mutex );
+ t_str2type::const_iterator iFind( m_type_map.find( uno_name ) );
+ if (iFind == m_type_map.end())
+ {
+ guard.clear();
+ TypeDescr td( type );
+ info = create_type_info( jni, td.get() );
+ }
+ else
+ {
+ info = iFind->second.m_info;
+ }
+
+ return info;
+}
+
+//______________________________________________________________________________
+JNI_type_info const * JNI_info::get_type_info(
+ JNI_context const & jni, OUString const & uno_name ) const
+{
+ if (uno_name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") ))
+ {
+ return m_XInterface_type_info;
+ }
+
+ JNI_type_info const * info;
+ ClearableMutexGuard guard( m_mutex );
+ t_str2type::const_iterator iFind( m_type_map.find( uno_name ) );
+ if (iFind == m_type_map.end())
+ {
+ guard.clear();
+ css::uno::TypeDescription td( uno_name );
+ if (! td.is())
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("UNO type not found: ") );
+ buf.append( uno_name );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ info = create_type_info( jni, td.get() );
+ }
+ else
+ {
+ info = iFind->second.m_info;
+ }
+
+ return info;
+}
+
+//______________________________________________________________________________
+JNI_info::JNI_info(
+ JNIEnv * jni_env, jobject class_loader, jclass classClass,
+ jmethodID methodForName )
+ : m_class_Class( classClass ),
+ m_method_Class_forName( methodForName ),
+ m_class_JNI_proxy( 0 ),
+ m_XInterface_queryInterface_td(
+ (reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ css::uno::TypeDescription(
+ ::getCppuType(
+ (css::uno::Reference< css::uno::XInterface > const *)0 ) )
+ .get())->ppMembers[ 0 ] ) ),
+ m_Exception_type( ::getCppuType( (css::uno::Exception const *)0 ) ),
+ m_RuntimeException_type(
+ ::getCppuType( (css::uno::RuntimeException const *)0 ) ),
+ m_void_type( ::getCppuVoidType() ),
+ m_XInterface_type_info( 0 )
+{
+ JNI_context jni( this, jni_env, class_loader ); // !no proper jni_info!
+
+ // class lookup
+ JLocalAutoRef jo_Object(
+ jni, find_class( jni, "java.lang.Object" ) );
+ JLocalAutoRef jo_Class(
+ jni, find_class( jni, "java.lang.Class" ) );
+ JLocalAutoRef jo_Throwable(
+ jni, find_class( jni, "java.lang.Throwable" ) );
+ JLocalAutoRef jo_Character(
+ jni, find_class( jni, "java.lang.Character" ) );
+ JLocalAutoRef jo_Boolean(
+ jni, find_class( jni, "java.lang.Boolean" ) );
+ JLocalAutoRef jo_Byte(
+ jni, find_class( jni, "java.lang.Byte" ) );
+ JLocalAutoRef jo_Short(
+ jni, find_class( jni, "java.lang.Short" ) );
+ JLocalAutoRef jo_Integer(
+ jni, find_class( jni, "java.lang.Integer" ) );
+ JLocalAutoRef jo_Long(
+ jni, find_class( jni, "java.lang.Long" ) );
+ JLocalAutoRef jo_Float(
+ jni, find_class( jni, "java.lang.Float" ) );
+ JLocalAutoRef jo_Double(
+ jni, find_class( jni, "java.lang.Double" ) );
+ JLocalAutoRef jo_String(
+ jni, find_class( jni, "java.lang.String" ) );
+ JLocalAutoRef jo_RuntimeException(
+ jni, find_class( jni, "com.sun.star.uno.RuntimeException" ) );
+ JLocalAutoRef jo_UnoRuntime(
+ jni, find_class( jni, "com.sun.star.uno.UnoRuntime" ) );
+ JLocalAutoRef jo_Any(
+ jni, find_class( jni, "com.sun.star.uno.Any" ) );
+ JLocalAutoRef jo_Enum(
+ jni, find_class( jni, "com.sun.star.uno.Enum" ) );
+ JLocalAutoRef jo_Type(
+ jni, find_class( jni, "com.sun.star.uno.Type" ) );
+ JLocalAutoRef jo_TypeClass(
+ jni, find_class( jni, "com.sun.star.uno.TypeClass" ) );
+ JLocalAutoRef jo_IEnvironment(
+ jni, find_class( jni, "com.sun.star.uno.IEnvironment" ) );
+ JLocalAutoRef jo_JNI_proxy(
+ jni, find_class( jni, "com.sun.star.bridges.jni_uno.JNI_proxy" ) );
+
+ // method Object.toString()
+ m_method_Object_toString = jni->GetMethodID(
+ (jclass) jo_Object.get(), "toString", "()Ljava/lang/String;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Object_toString );
+ // method Class.getName()
+ m_method_Class_getName = jni->GetMethodID(
+ (jclass) jo_Class.get(), "getName", "()Ljava/lang/String;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Class_getName );
+
+ // method Throwable.getMessage()
+ m_method_Throwable_getMessage = jni->GetMethodID(
+ (jclass) jo_Throwable.get(), "getMessage", "()Ljava/lang/String;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Throwable_getMessage );
+
+ // method Character.charValue()
+ m_method_Character_charValue = jni->GetMethodID(
+ (jclass) jo_Character.get(), "charValue", "()C" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Character_charValue );
+ // method Boolean.booleanValue()
+ m_method_Boolean_booleanValue = jni->GetMethodID(
+ (jclass) jo_Boolean.get(), "booleanValue", "()Z" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Boolean_booleanValue );
+ // method Byte.byteValue()
+ m_method_Byte_byteValue = jni->GetMethodID(
+ (jclass) jo_Byte.get(), "byteValue", "()B" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Byte_byteValue );
+ // method Short.shortValue()
+ m_method_Short_shortValue = jni->GetMethodID(
+ (jclass) jo_Short.get(), "shortValue", "()S" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Short_shortValue );
+ // method Integer.intValue()
+ m_method_Integer_intValue = jni->GetMethodID(
+ (jclass) jo_Integer.get(), "intValue", "()I" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Integer_intValue );
+ // method Long.longValue()
+ m_method_Long_longValue = jni->GetMethodID(
+ (jclass) jo_Long.get(), "longValue", "()J" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Long_longValue );
+ // method Float.floatValue()
+ m_method_Float_floatValue = jni->GetMethodID(
+ (jclass) jo_Float.get(), "floatValue", "()F" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Float_floatValue );
+ // method Double.doubleValue()
+ m_method_Double_doubleValue = jni->GetMethodID(
+ (jclass) jo_Double.get(), "doubleValue", "()D" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_Double_doubleValue );
+
+ // ctor Character( char )
+ m_ctor_Character_with_char = jni->GetMethodID(
+ (jclass) jo_Character.get(), "<init>", "(C)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Character_with_char );
+ // ctor Boolean( boolean )
+ m_ctor_Boolean_with_boolean = jni->GetMethodID(
+ (jclass) jo_Boolean.get(), "<init>", "(Z)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Boolean_with_boolean );
+ // ctor Byte( byte )
+ m_ctor_Byte_with_byte = jni->GetMethodID(
+ (jclass) jo_Byte.get(), "<init>", "(B)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Byte_with_byte );
+ // ctor Short( short )
+ m_ctor_Short_with_short = jni->GetMethodID(
+ (jclass) jo_Short.get(), "<init>", "(S)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Short_with_short );
+ // ctor Integer( int )
+ m_ctor_Integer_with_int = jni->GetMethodID(
+ (jclass) jo_Integer.get(), "<init>", "(I)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Integer_with_int );
+ // ctor Long( long )
+ m_ctor_Long_with_long = jni->GetMethodID(
+ (jclass) jo_Long.get(), "<init>", "(J)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Long_with_long );
+ // ctor Float( float )
+ m_ctor_Float_with_float = jni->GetMethodID(
+ (jclass) jo_Float.get(), "<init>", "(F)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Float_with_float );
+ // ctor Double( double )
+ m_ctor_Double_with_double = jni->GetMethodID(
+ (jclass) jo_Double.get(), "<init>", "(D)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Double_with_double );
+
+ // static method UnoRuntime.generateOid()
+ m_method_UnoRuntime_generateOid = jni->GetStaticMethodID(
+ (jclass) jo_UnoRuntime.get(),
+ "generateOid", "(Ljava/lang/Object;)Ljava/lang/String;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_UnoRuntime_generateOid );
+ // static method UnoRuntime.queryInterface()
+ m_method_UnoRuntime_queryInterface = jni->GetStaticMethodID(
+ (jclass) jo_UnoRuntime.get(),
+ "queryInterface",
+ "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)Ljava/lang/Object;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_UnoRuntime_queryInterface );
+
+ // field Enum.m_value
+ m_field_Enum_m_value = jni->GetFieldID(
+ (jclass) jo_Enum.get(), "m_value", "I" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_Enum_m_value );
+
+ // static method TypeClass.fromInt()
+ m_method_TypeClass_fromInt = jni->GetStaticMethodID(
+ (jclass) jo_TypeClass.get(),
+ "fromInt", "(I)Lcom/sun/star/uno/TypeClass;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_TypeClass_fromInt );
+
+ // ctor Type( Class )
+ m_ctor_Type_with_Class = jni->GetMethodID(
+ (jclass) jo_Type.get(), "<init>", "(Ljava/lang/Class;)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Type_with_Class );
+ // ctor Type( String, TypeClass )
+ m_ctor_Type_with_Name_TypeClass = jni->GetMethodID(
+ (jclass) jo_Type.get(),
+ "<init>", "(Ljava/lang/String;Lcom/sun/star/uno/TypeClass;)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Type_with_Name_TypeClass );
+ // field Type._typeName
+ m_field_Type__typeName = jni->GetFieldID(
+ (jclass) jo_Type.get(), "_typeName", "Ljava/lang/String;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_Type__typeName );
+
+ // ctor Any( Type, Object )
+ m_ctor_Any_with_Type_Object = jni->GetMethodID(
+ (jclass) jo_Any.get(),
+ "<init>", "(Lcom/sun/star/uno/Type;Ljava/lang/Object;)V" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_ctor_Any_with_Type_Object );
+
+ // field Any._type
+ m_field_Any__type = jni->GetFieldID(
+ (jclass) jo_Any.get(), "_type", "Lcom/sun/star/uno/Type;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_Any__type );
+ // field Any._object
+ m_field_Any__object = jni->GetFieldID(
+ (jclass) jo_Any.get(), "_object", "Ljava/lang/Object;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_Any__object );
+
+ // method IEnvironment.getRegisteredInterface()
+ m_method_IEnvironment_getRegisteredInterface = jni->GetMethodID(
+ (jclass) jo_IEnvironment.get(),
+ "getRegisteredInterface",
+ "(Ljava/lang/String;Lcom/sun/star/uno/Type;)Ljava/lang/Object;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_IEnvironment_getRegisteredInterface );
+ // method IEnvironment.registerInterface()
+ m_method_IEnvironment_registerInterface = jni->GetMethodID(
+ (jclass) jo_IEnvironment.get(), "registerInterface",
+ "(Ljava/lang/Object;[Ljava/lang/String;Lcom/sun/star/uno/Type;)"
+ "Ljava/lang/Object;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_IEnvironment_registerInterface );
+
+ // static method JNI_proxy.get_proxy_ctor()
+ m_method_JNI_proxy_get_proxy_ctor = jni->GetStaticMethodID(
+ (jclass) jo_JNI_proxy.get(), "get_proxy_ctor",
+ "(Ljava/lang/Class;)Ljava/lang/reflect/Constructor;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_JNI_proxy_get_proxy_ctor );
+ // static method JNI_proxy.create()
+ m_method_JNI_proxy_create = jni->GetStaticMethodID(
+ (jclass) jo_JNI_proxy.get(), "create",
+ "(JLcom/sun/star/uno/IEnvironment;JJLcom/sun/star/uno/Type;Ljava/lang"
+ "/String;Ljava/lang/reflect/Constructor;)Ljava/lang/Object;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_method_JNI_proxy_create );
+ // field JNI_proxy.m_receiver_handle
+ m_field_JNI_proxy_m_receiver_handle = jni->GetFieldID(
+ (jclass) jo_JNI_proxy.get(), "m_receiver_handle", "J" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_JNI_proxy_m_receiver_handle );
+ // field JNI_proxy.m_td_handle
+ m_field_JNI_proxy_m_td_handle = jni->GetFieldID(
+ (jclass) jo_JNI_proxy.get(), "m_td_handle", "J" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_JNI_proxy_m_td_handle );
+ // field JNI_proxy.m_type
+ m_field_JNI_proxy_m_type = jni->GetFieldID(
+ (jclass) jo_JNI_proxy.get(), "m_type", "Lcom/sun/star/uno/Type;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_JNI_proxy_m_type );
+ // field JNI_proxy.m_oid
+ m_field_JNI_proxy_m_oid = jni->GetFieldID(
+ (jclass) jo_JNI_proxy.get(), "m_oid", "Ljava/lang/String;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != m_field_JNI_proxy_m_oid );
+
+ // get java env
+ OUString java_env_type_name( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_JAVA) );
+ JLocalAutoRef jo_java(
+ jni, ustring_to_jstring( jni, java_env_type_name.pData ) );
+ jvalue args[ 2 ];
+ args[ 0 ].l = jo_java.get();
+ args[ 1 ].l = 0;
+ jmethodID method_getEnvironment = jni->GetStaticMethodID(
+ (jclass) jo_UnoRuntime.get(), "getEnvironment",
+ "(Ljava/lang/String;Ljava/lang/Object;)"
+ "Lcom/sun/star/uno/IEnvironment;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != method_getEnvironment );
+ JLocalAutoRef jo_java_env(
+ jni, jni->CallStaticObjectMethodA(
+ (jclass) jo_UnoRuntime.get(), method_getEnvironment, args ) );
+
+ // get com.sun.star.uno.Any.VOID
+ jfieldID field_Any_VOID = jni->GetStaticFieldID(
+ (jclass) jo_Any.get(), "VOID", "Lcom/sun/star/uno/Any;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != field_Any_VOID );
+ JLocalAutoRef jo_Any_VOID(
+ jni, jni->GetStaticObjectField(
+ (jclass) jo_Any.get(), field_Any_VOID ) );
+ // get com.sun.star.uno.Type.UNSIGNED_SHORT
+ jfieldID field_Type_UNSIGNED_SHORT = jni->GetStaticFieldID(
+ (jclass) jo_Type.get(), "UNSIGNED_SHORT", "Lcom/sun/star/uno/Type;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != field_Type_UNSIGNED_SHORT );
+ JLocalAutoRef jo_Type_UNSIGNED_SHORT(
+ jni, jni->GetStaticObjectField(
+ (jclass) jo_Type.get(), field_Type_UNSIGNED_SHORT ) );
+ // get com.sun.star.uno.Type.UNSIGNED_LONG
+ jfieldID field_Type_UNSIGNED_LONG = jni->GetStaticFieldID(
+ (jclass) jo_Type.get(), "UNSIGNED_LONG", "Lcom/sun/star/uno/Type;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != field_Type_UNSIGNED_LONG );
+ JLocalAutoRef jo_Type_UNSIGNED_LONG(
+ jni, jni->GetStaticObjectField(
+ (jclass) jo_Type.get(), field_Type_UNSIGNED_LONG ) );
+ // get com.sun.star.uno.Type.UNSIGNED_HYPER
+ jfieldID field_Type_UNSIGNED_HYPER = jni->GetStaticFieldID(
+ (jclass) jo_Type.get(), "UNSIGNED_HYPER", "Lcom/sun/star/uno/Type;" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != field_Type_UNSIGNED_HYPER );
+ JLocalAutoRef jo_Type_UNSIGNED_HYPER(
+ jni, jni->GetStaticObjectField(
+ (jclass) jo_Type.get(), field_Type_UNSIGNED_HYPER ) );
+
+ // make global refs
+ m_class_UnoRuntime =
+ (jclass) jni->NewGlobalRef( jo_UnoRuntime.get() );
+ m_class_RuntimeException =
+ (jclass) jni->NewGlobalRef( jo_RuntimeException.get() );
+ m_class_Any =
+ (jclass) jni->NewGlobalRef( jo_Any.get() );
+ m_class_Type =
+ (jclass) jni->NewGlobalRef( jo_Type.get() );
+ m_class_TypeClass =
+ (jclass) jni->NewGlobalRef( jo_TypeClass.get() );
+ m_class_JNI_proxy =
+ (jclass) jni->NewGlobalRef( jo_JNI_proxy.get() );
+
+ m_class_Character =
+ (jclass) jni->NewGlobalRef( jo_Character.get() );
+ m_class_Boolean =
+ (jclass) jni->NewGlobalRef( jo_Boolean.get() );
+ m_class_Byte =
+ (jclass) jni->NewGlobalRef( jo_Byte.get() );
+ m_class_Short =
+ (jclass) jni->NewGlobalRef( jo_Short.get() );
+ m_class_Integer =
+ (jclass) jni->NewGlobalRef( jo_Integer.get() );
+ m_class_Long =
+ (jclass) jni->NewGlobalRef( jo_Long.get() );
+ m_class_Float =
+ (jclass) jni->NewGlobalRef( jo_Float.get() );
+ m_class_Double =
+ (jclass) jni->NewGlobalRef( jo_Double.get() );
+ m_class_String =
+ (jclass) jni->NewGlobalRef( jo_String.get() );
+ m_class_Object =
+ (jclass) jni->NewGlobalRef( jo_Object.get() );
+ m_class_Class =
+ (jclass) jni->NewGlobalRef( m_class_Class );
+
+ m_object_Any_VOID =
+ jni->NewGlobalRef( jo_Any_VOID.get() );
+ m_object_Type_UNSIGNED_SHORT =
+ jni->NewGlobalRef( jo_Type_UNSIGNED_SHORT.get() );
+ m_object_Type_UNSIGNED_LONG =
+ jni->NewGlobalRef( jo_Type_UNSIGNED_LONG.get() );
+ m_object_Type_UNSIGNED_HYPER =
+ jni->NewGlobalRef( jo_Type_UNSIGNED_HYPER.get() );
+ m_object_java_env = jni->NewGlobalRef( jo_java_env.get() );
+
+ try
+ {
+ css::uno::TypeDescription XInterface_td(
+ ::getCppuType(
+ (css::uno::Reference< css::uno::XInterface > const *)0 ) );
+ m_XInterface_type_info =
+ new JNI_interface_type_info( jni, XInterface_td.get() );
+ }
+ catch (...)
+ {
+ destruct( jni_env );
+ throw;
+ }
+}
+
+//______________________________________________________________________________
+void JNI_info::destruct( JNIEnv * jni_env )
+{
+ t_str2type::const_iterator iPos( m_type_map.begin() );
+ t_str2type::const_iterator const iEnd( m_type_map.begin() );
+ for ( ; iPos != iEnd; ++iPos )
+ {
+ iPos->second.m_info->destroy( jni_env );
+ }
+ if (0 != m_XInterface_type_info)
+ {
+ const_cast< JNI_interface_type_info * >(
+ m_XInterface_type_info )->destroy( jni_env );
+ }
+
+ // free global refs
+ jni_env->DeleteGlobalRef( m_object_java_env );
+ jni_env->DeleteGlobalRef( m_object_Any_VOID );
+ jni_env->DeleteGlobalRef( m_object_Type_UNSIGNED_SHORT );
+ jni_env->DeleteGlobalRef( m_object_Type_UNSIGNED_LONG );
+ jni_env->DeleteGlobalRef( m_object_Type_UNSIGNED_HYPER );
+
+ jni_env->DeleteGlobalRef( m_class_Class );
+ jni_env->DeleteGlobalRef( m_class_Object );
+ jni_env->DeleteGlobalRef( m_class_String );
+ jni_env->DeleteGlobalRef( m_class_Double );
+ jni_env->DeleteGlobalRef( m_class_Float );
+ jni_env->DeleteGlobalRef( m_class_Long );
+ jni_env->DeleteGlobalRef( m_class_Integer );
+ jni_env->DeleteGlobalRef( m_class_Short );
+ jni_env->DeleteGlobalRef( m_class_Byte );
+ jni_env->DeleteGlobalRef( m_class_Boolean );
+ jni_env->DeleteGlobalRef( m_class_Character );
+
+ jni_env->DeleteGlobalRef( m_class_JNI_proxy );
+ jni_env->DeleteGlobalRef( m_class_RuntimeException );
+ jni_env->DeleteGlobalRef( m_class_UnoRuntime );
+ jni_env->DeleteGlobalRef( m_class_TypeClass );
+ jni_env->DeleteGlobalRef( m_class_Type );
+ jni_env->DeleteGlobalRef( m_class_Any );
+}
+
+//______________________________________________________________________________
+JNI_info const * JNI_info::get_jni_info(
+ rtl::Reference< jvmaccess::UnoVirtualMachine > const & uno_vm )
+{
+ // !!!no JNI_info available at JNI_context!!!
+ ::jvmaccess::VirtualMachine::AttachGuard guard(
+ uno_vm->getVirtualMachine() );
+ JNIEnv * jni_env = guard.getEnvironment();
+ JNI_context jni(
+ 0, jni_env, static_cast< jobject >(uno_vm->getClassLoader()) );
+
+ jclass jo_class;
+ jmethodID jo_forName;
+ jni.getClassForName( &jo_class, &jo_forName );
+ jni.ensure_no_exception();
+ JLocalAutoRef jo_JNI_info_holder(
+ jni,
+ jni.findClass(
+ "com.sun.star.bridges.jni_uno.JNI_info_holder", jo_class,
+ jo_forName, false ) );
+ // field JNI_info_holder.m_jni_info_handle
+ jfieldID field_s_jni_info_handle =
+ jni->GetStaticFieldID(
+ (jclass) jo_JNI_info_holder.get(), "s_jni_info_handle", "J" );
+ jni.ensure_no_exception();
+ OSL_ASSERT( 0 != field_s_jni_info_handle );
+
+ JNI_info const * jni_info =
+ reinterpret_cast< JNI_info const * >(
+ jni->GetStaticLongField(
+ (jclass) jo_JNI_info_holder.get(), field_s_jni_info_handle ) );
+ if (0 == jni_info) // un-initialized?
+ {
+ JNI_info * new_info = new JNI_info(
+ jni_env, static_cast< jobject >(uno_vm->getClassLoader()), jo_class,
+ jo_forName );
+
+ ClearableMutexGuard g( Mutex::getGlobalMutex() );
+ jni_info =
+ reinterpret_cast< JNI_info const * >(
+ jni->GetStaticLongField(
+ (jclass) jo_JNI_info_holder.get(),
+ field_s_jni_info_handle ) );
+ if (0 == jni_info) // still un-initialized?
+ {
+ jni->SetStaticLongField(
+ (jclass) jo_JNI_info_holder.get(), field_s_jni_info_handle,
+ reinterpret_cast< jlong >( new_info ) );
+ jni_info = new_info;
+ }
+ else
+ {
+ g.clear();
+ new_info->destroy( jni_env );
+ }
+ }
+
+ return jni_info;
+}
+
+}
+
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+JNIEXPORT void
+JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1info_1holder_finalize__J(
+ JNIEnv * jni_env, jobject, jlong jni_info_handle )
+ SAL_THROW_EXTERN_C()
+{
+ ::jni_uno::JNI_info * jni_info =
+ reinterpret_cast< ::jni_uno::JNI_info * >( jni_info_handle );
+ jni_info->destroy( jni_env );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/jni_uno/jni_info.h b/bridges/source/jni_uno/jni_info.h
new file mode 100644
index 000000000000..1382c6f9f4d8
--- /dev/null
+++ b/bridges/source/jni_uno/jni_info.h
@@ -0,0 +1,378 @@
+/* -*- 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_JNI_INFO_H
+#define INCLUDED_JNI_INFO_H
+
+#include <hash_map>
+
+#include "jni_base.h"
+
+#include "osl/mutex.hxx"
+#include "rtl/ref.hxx"
+#include "rtl/ustring.hxx"
+#include "rtl/strbuf.hxx"
+
+#include "uno/environment.h"
+#include "typelib/typedescription.hxx"
+
+#include "com/sun/star/uno/Type.hxx"
+
+namespace jvmaccess { class UnoVirtualMachine; }
+
+namespace jni_uno
+{
+
+//------------------------------------------------------------------------------
+inline bool type_equals(
+ typelib_TypeDescriptionReference * type1,
+ typelib_TypeDescriptionReference * type2 )
+{
+ if (type1 == type2)
+ return true;
+ ::rtl::OUString const & name1 =
+ ::rtl::OUString::unacquired( &type1->pTypeName );
+ ::rtl::OUString const & name2 =
+ ::rtl::OUString::unacquired( &type2->pTypeName );
+ return ((type1->eTypeClass == type2->eTypeClass) && name1.equals( name2 ));
+}
+
+//------------------------------------------------------------------------------
+inline bool is_XInterface( typelib_TypeDescriptionReference * type )
+{
+ return ((typelib_TypeClass_INTERFACE == type->eTypeClass) &&
+ ::rtl::OUString::unacquired( &type->pTypeName ).equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") ));
+}
+
+//==============================================================================
+struct JNI_type_info
+{
+ ::com::sun::star::uno::TypeDescription m_td;
+ jclass m_class;
+
+ virtual void destroy( JNIEnv * jni_env ) = 0;
+protected:
+ inline void destruct( JNIEnv * jni_env )
+ { jni_env->DeleteGlobalRef( m_class ); }
+ virtual inline ~JNI_type_info() {}
+ explicit JNI_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td );
+};
+
+//==============================================================================
+struct JNI_interface_type_info : public JNI_type_info
+{
+ jobject m_proxy_ctor; // proxy ctor
+ jobject m_type;
+ // sorted via typelib function index
+ jmethodID * m_methods;
+
+ virtual void destroy( JNIEnv * jni_env );
+ explicit JNI_interface_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td );
+};
+
+//==============================================================================
+struct JNI_compound_type_info : public JNI_type_info
+{
+ JNI_type_info const * m_base;
+ // ctor( msg ) for exceptions
+ jmethodID m_exc_ctor;
+ // sorted via typelib member index
+ jfieldID * m_fields;
+
+ virtual void destroy( JNIEnv * jni_env );
+ explicit JNI_compound_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td );
+};
+
+//==============================================================================
+struct JNI_type_info_holder
+{
+ JNI_type_info * m_info;
+ inline JNI_type_info_holder()
+ : m_info( 0 )
+ {}
+};
+
+typedef ::std::hash_map<
+ ::rtl::OUString, JNI_type_info_holder, ::rtl::OUStringHash > t_str2type;
+
+//==============================================================================
+class JNI_info
+{
+ mutable ::osl::Mutex m_mutex;
+ mutable t_str2type m_type_map;
+
+public:
+ // These two are needed very early by find_class from within the ctor:
+ jclass m_class_Class;
+ jmethodID m_method_Class_forName;
+
+ //
+ jobject m_object_java_env;
+ jobject m_object_Any_VOID;
+ jobject m_object_Type_UNSIGNED_SHORT;
+ jobject m_object_Type_UNSIGNED_LONG;
+ jobject m_object_Type_UNSIGNED_HYPER;
+
+ //
+ jclass m_class_Object;
+ jclass m_class_Character;
+ jclass m_class_Boolean;
+ jclass m_class_Byte;
+ jclass m_class_Short;
+ jclass m_class_Integer;
+ jclass m_class_Long;
+ jclass m_class_Float;
+ jclass m_class_Double;
+ jclass m_class_String;
+
+ jclass m_class_UnoRuntime;
+ jclass m_class_RuntimeException;
+ jclass m_class_Any;
+ jclass m_class_Type;
+ jclass m_class_TypeClass;
+ jclass m_class_JNI_proxy;
+
+ //
+ jmethodID m_method_Object_toString;
+ jmethodID m_method_Class_getName;
+ jmethodID m_method_Throwable_getMessage;
+ jmethodID m_ctor_Character_with_char;
+ jmethodID m_ctor_Boolean_with_boolean;
+ jmethodID m_ctor_Byte_with_byte;
+ jmethodID m_ctor_Short_with_short;
+ jmethodID m_ctor_Integer_with_int;
+ jmethodID m_ctor_Long_with_long;
+ jmethodID m_ctor_Float_with_float;
+ jmethodID m_ctor_Double_with_double;
+ jmethodID m_method_Boolean_booleanValue;
+ jmethodID m_method_Byte_byteValue;
+ jmethodID m_method_Character_charValue;
+ jmethodID m_method_Double_doubleValue;
+ jmethodID m_method_Float_floatValue;
+ jmethodID m_method_Integer_intValue;
+ jmethodID m_method_Long_longValue;
+ jmethodID m_method_Short_shortValue;
+
+ //
+ jmethodID m_method_IEnvironment_getRegisteredInterface;
+ jmethodID m_method_IEnvironment_registerInterface;
+ jmethodID m_method_UnoRuntime_generateOid;
+ jmethodID m_method_UnoRuntime_queryInterface;
+ jmethodID m_ctor_Any_with_Type_Object;
+ jfieldID m_field_Any__type;
+ jfieldID m_field_Any__object;
+ jmethodID m_ctor_Type_with_Class;
+ jmethodID m_ctor_Type_with_Name_TypeClass;
+ jfieldID m_field_Type__typeName;
+ jmethodID m_method_TypeClass_fromInt;
+ jfieldID m_field_Enum_m_value;
+
+ //
+ jmethodID m_method_JNI_proxy_get_proxy_ctor;
+ jmethodID m_method_JNI_proxy_create;
+ jfieldID m_field_JNI_proxy_m_receiver_handle;
+ jfieldID m_field_JNI_proxy_m_td_handle;
+ jfieldID m_field_JNI_proxy_m_type;
+ jfieldID m_field_JNI_proxy_m_oid;
+
+ //
+ ::com::sun::star::uno::TypeDescription m_XInterface_queryInterface_td;
+ ::com::sun::star::uno::Type const & m_Exception_type;
+ ::com::sun::star::uno::Type const & m_RuntimeException_type;
+ ::com::sun::star::uno::Type const & m_void_type;
+ //
+ JNI_interface_type_info const * m_XInterface_type_info;
+
+ //
+ JNI_type_info const * get_type_info(
+ JNI_context const & jni,
+ typelib_TypeDescription * type ) const;
+ JNI_type_info const * get_type_info(
+ JNI_context const & jni,
+ typelib_TypeDescriptionReference * type ) const;
+ JNI_type_info const * get_type_info(
+ JNI_context const & jni,
+ ::rtl::OUString const & uno_name ) const;
+ //
+ inline static void append_sig(
+ ::rtl::OStringBuffer * buf, typelib_TypeDescriptionReference * type,
+ bool use_Object_for_type_XInterface = true, bool use_slashes = true );
+
+ // get this
+ static JNI_info const * get_jni_info(
+ rtl::Reference< jvmaccess::UnoVirtualMachine > const & uno_vm );
+ inline void destroy( JNIEnv * jni_env );
+
+private:
+ JNI_type_info const * create_type_info(
+ JNI_context const & jni, typelib_TypeDescription * td ) const;
+
+ void destruct( JNIEnv * jni_env );
+
+ JNI_info( JNIEnv * jni_env, jobject class_loader,
+ jclass classClass, jmethodID methodForName );
+ inline ~JNI_info() {}
+};
+
+//______________________________________________________________________________
+inline void JNI_info::destroy( JNIEnv * jni_env )
+{
+ destruct( jni_env );
+ delete this;
+}
+
+//______________________________________________________________________________
+inline void JNI_info::append_sig(
+ ::rtl::OStringBuffer * buf, typelib_TypeDescriptionReference * type,
+ bool use_Object_for_type_XInterface, bool use_slashes )
+{
+ switch (type->eTypeClass)
+ {
+ case typelib_TypeClass_VOID:
+ buf->append( 'V' );
+ break;
+ case typelib_TypeClass_CHAR:
+ buf->append( 'C' );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ buf->append( 'Z' );
+ break;
+ case typelib_TypeClass_BYTE:
+ buf->append( 'B' );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ buf->append( 'S' );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ buf->append( 'I' );
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ buf->append( 'J' );
+ break;
+ case typelib_TypeClass_FLOAT:
+ buf->append( 'F' );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ buf->append( 'D' );
+ break;
+ case typelib_TypeClass_STRING:
+ if ( use_slashes ) {
+ buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava/lang/String;") );
+ } else {
+ buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava.lang.String;") );
+ }
+ break;
+ case typelib_TypeClass_TYPE:
+ if ( use_slashes ) {
+ buf->append(
+ RTL_CONSTASCII_STRINGPARAM("Lcom/sun/star/uno/Type;") );
+ } else {
+ buf->append(
+ RTL_CONSTASCII_STRINGPARAM("Lcom.sun.star.uno.Type;") );
+ }
+ break;
+ case typelib_TypeClass_ANY:
+ if ( use_slashes ) {
+ buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;") );
+ } else {
+ buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava.lang.Object;") );
+ }
+ break;
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ ::rtl::OUString const & uno_name =
+ ::rtl::OUString::unacquired( &type->pTypeName );
+ buf->append( 'L' );
+ // Erase type arguments of instantiated polymorphic struct types:
+ sal_Int32 i = uno_name.indexOf( '<' );
+ if ( i < 0 ) {
+ buf->append(
+ ::rtl::OUStringToOString(
+ use_slashes ? uno_name.replace( '.', '/' ) : uno_name,
+ RTL_TEXTENCODING_JAVA_UTF8 ) );
+ } else {
+ rtl::OUString s( uno_name.copy( 0, i ) );
+ buf->append(
+ ::rtl::OUStringToOString(
+ use_slashes ? s.replace( '.', '/' ) : s,
+ RTL_TEXTENCODING_JAVA_UTF8 ) );
+ }
+ buf->append( ';' );
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ buf->append( '[' );
+ TypeDescr td( type );
+ append_sig(
+ buf, ((typelib_IndirectTypeDescription *)td.get())->pType,
+ use_Object_for_type_XInterface, use_slashes );
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ if (use_Object_for_type_XInterface && is_XInterface( type ))
+ {
+ if ( use_slashes ) {
+ buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;") );
+ } else {
+ buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava.lang.Object;") );
+ }
+ }
+ else
+ {
+ ::rtl::OUString const & uno_name =
+ ::rtl::OUString::unacquired( &type->pTypeName );
+ buf->append( 'L' );
+ buf->append(
+ ::rtl::OUStringToOString(
+ use_slashes ? uno_name.replace( '.', '/' ) : uno_name,
+ RTL_TEXTENCODING_JAVA_UTF8 ) );
+ buf->append( ';' );
+ }
+ break;
+ default:
+ throw BridgeRuntimeError(
+ OUSTR("unsupported type: ") +
+ ::rtl::OUString::unacquired( &type->pTypeName ) );
+ }
+}
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/jni_uno/jni_java2uno.cxx b/bridges/source/jni_uno/jni_java2uno.cxx
new file mode 100644
index 000000000000..fa32e879f1bd
--- /dev/null
+++ b/bridges/source/jni_uno/jni_java2uno.cxx
@@ -0,0 +1,706 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sal/alloca.h>
+
+#include "jni_bridge.h"
+
+#include <rtl/ustrbuf.hxx>
+
+#include <algorithm>
+
+
+using namespace ::rtl;
+
+namespace jni_uno
+{
+
+//______________________________________________________________________________
+jobject Bridge::map_to_java(
+ JNI_context const & jni,
+ uno_Interface * pUnoI, JNI_interface_type_info const * info ) const
+{
+ // get oid
+ rtl_uString * pOid = 0;
+ (*m_uno_env->getObjectIdentifier)( m_uno_env, &pOid, pUnoI );
+ OSL_ASSERT( 0 != pOid );
+ OUString oid( pOid, SAL_NO_ACQUIRE );
+
+ // opt getRegisteredInterface()
+ JLocalAutoRef jo_oid( jni, ustring_to_jstring( jni, oid.pData ) );
+ jvalue args[ 2 ];
+ args[ 0 ].l = jo_oid.get();
+ args[ 1 ].l = info->m_type;
+ jobject jo_iface = jni->CallObjectMethodA(
+ m_jni_info->m_object_java_env,
+ m_jni_info->m_method_IEnvironment_getRegisteredInterface, args );
+ jni.ensure_no_exception();
+
+ if (0 == jo_iface) // no registered iface
+ {
+ // register uno interface
+ (*m_uno_env->registerInterface)(
+ m_uno_env, reinterpret_cast< void ** >( &pUnoI ),
+ oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() );
+
+ // create java and register java proxy
+ jvalue args2[ 7 ];
+ acquire();
+ args2[ 0 ].j = reinterpret_cast< sal_Int64 >( this );
+ (*pUnoI->acquire)( pUnoI );
+ args2[ 1 ].l = m_jni_info->m_object_java_env;
+ args2[ 2 ].j = reinterpret_cast< sal_Int64 >( pUnoI );
+ typelib_typedescription_acquire( info->m_td.get() );
+ args2[ 3 ].j = reinterpret_cast< sal_Int64 >( info->m_td.get() );
+ args2[ 4 ].l = info->m_type;
+ args2[ 5 ].l = jo_oid.get();
+ args2[ 6 ].l = info->m_proxy_ctor;
+ jo_iface = jni->CallStaticObjectMethodA(
+ m_jni_info->m_class_JNI_proxy,
+ m_jni_info->m_method_JNI_proxy_create, args2 );
+ jni.ensure_no_exception();
+ }
+
+ OSL_ASSERT( 0 != jo_iface );
+ return jo_iface;
+}
+
+
+//______________________________________________________________________________
+void Bridge::handle_uno_exc( JNI_context const & jni, uno_Any * uno_exc ) const
+{
+ if (typelib_TypeClass_EXCEPTION == uno_exc->pType->eTypeClass)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ // append java stack trace to Message member
+ reinterpret_cast< ::com::sun::star::uno::Exception * >(
+ uno_exc->pData )->Message += jni.get_stack_trace();
+#endif
+
+#if OSL_DEBUG_LEVEL > 1
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("exception occured java->uno: [") );
+ buf.append( OUString::unacquired( &uno_exc->pType->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
+ buf.append(
+ reinterpret_cast< ::com::sun::star::uno::Exception const * >(
+ uno_exc->pData )->Message );
+ OString cstr_msg(
+ OUStringToOString(
+ buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_msg.getStr() );
+ }
+#endif
+ // signal exception
+ jvalue java_exc;
+ try
+ {
+ map_to_java(
+ jni, &java_exc, uno_exc->pData, uno_exc->pType, 0,
+ true /* in */, false /* no out */ );
+ }
+ catch (...)
+ {
+ uno_any_destruct( uno_exc, 0 );
+ throw;
+ }
+ uno_any_destruct( uno_exc, 0 );
+
+ JLocalAutoRef jo_exc( jni, java_exc.l );
+ jint res = jni->Throw( (jthrowable) jo_exc.get() );
+ if (0 != res)
+ {
+ // call toString()
+ JLocalAutoRef jo_descr(
+ jni, jni->CallObjectMethodA(
+ jo_exc.get(), m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "throwing java exception failed: ") );
+ buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ }
+ else
+ {
+ OUString message(
+ OUSTR("thrown exception is no uno exception: ") +
+ OUString::unacquired( &uno_exc->pType->pTypeName ) +
+ jni.get_stack_trace() );
+ uno_any_destruct( uno_exc, 0 );
+ throw BridgeRuntimeError( message );
+ }
+}
+
+union largest
+{
+ sal_Int64 n;
+ double d;
+ void * p;
+ uno_Any a;
+};
+
+//______________________________________________________________________________
+jobject Bridge::call_uno(
+ JNI_context const & jni,
+ uno_Interface * pUnoI, typelib_TypeDescription * member_td,
+ typelib_TypeDescriptionReference * return_type,
+ sal_Int32 nParams, typelib_MethodParameter const * pParams,
+ jobjectArray jo_args /* may be 0 */ ) const
+{
+ // return mem
+ sal_Int32 return_size;
+ switch (return_type->eTypeClass) {
+ case typelib_TypeClass_VOID:
+ return_size = 0;
+ break;
+
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ return_size = std::max(
+ TypeDescr(return_type).get()->nSize,
+ static_cast< sal_Int32 >(sizeof (largest)));
+ break;
+
+ default:
+ return_size = sizeof (largest);
+ break;
+ }
+
+#ifdef BROKEN_ALLOCA
+ char * mem = (char *) malloc(
+#else
+ char * mem = (char *) alloca(
+#endif
+ (nParams * sizeof (void *)) +
+ return_size + (nParams * sizeof (largest)) );
+ void ** uno_args = (void **) mem;
+ void * uno_ret = return_size == 0 ? 0 : (mem + (nParams * sizeof (void *)));
+ largest * uno_args_mem = (largest *)
+ (mem + (nParams * sizeof (void *)) + return_size);
+
+ OSL_ASSERT( (0 == nParams) || (nParams == jni->GetArrayLength( jo_args )) );
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & param = pParams[ nPos ];
+ typelib_TypeDescriptionReference * type = param.pTypeRef;
+
+ uno_args[ nPos ] = &uno_args_mem[ nPos ];
+ if (typelib_TypeClass_STRUCT == type->eTypeClass ||
+ typelib_TypeClass_EXCEPTION == type->eTypeClass)
+ {
+ TypeDescr td( type );
+ if (sal::static_int_cast< sal_uInt32 >(td.get()->nSize)
+ > sizeof (largest))
+#ifdef BROKEN_ALLOCA
+ uno_args[ nPos ] = malloc( td.get()->nSize );
+#else
+ uno_args[ nPos ] = alloca( td.get()->nSize );
+#endif
+ }
+
+ if (param.bIn)
+ {
+ try
+ {
+ JLocalAutoRef jo_arg(
+ jni, jni->GetObjectArrayElement( jo_args, nPos ) );
+ jni.ensure_no_exception();
+ jvalue java_arg;
+ java_arg.l = jo_arg.get();
+ map_to_uno(
+ jni, uno_args[ nPos ], java_arg, type, 0,
+ false /* no assign */, sal_False != param.bOut,
+ true /* special wrapped integral types */ );
+ }
+ catch (...)
+ {
+ // cleanup uno in args
+ for ( sal_Int32 n = 0; n < nPos; ++n )
+ {
+ typelib_MethodParameter const & p = pParams[ n ];
+ if (p.bIn)
+ {
+ uno_type_destructData(
+ uno_args[ n ], p.pTypeRef, 0 );
+ }
+#ifdef BROKEN_ALLOCA
+ if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
+ free( uno_args[ nPos ] );
+#endif
+ }
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ throw;
+ }
+ }
+ }
+
+ uno_Any uno_exc_holder;
+ uno_Any * uno_exc = &uno_exc_holder;
+ // call binary uno
+ (*pUnoI->pDispatcher)( pUnoI, member_td, uno_ret, uno_args, &uno_exc );
+
+ if (0 == uno_exc)
+ {
+ // convert out args; destruct uno args
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & param = pParams[ nPos ];
+ typelib_TypeDescriptionReference * type = param.pTypeRef;
+ if (param.bOut)
+ {
+ try
+ {
+ // get out holder array[ 1 ]
+ JLocalAutoRef jo_out_holder(
+ jni, jni->GetObjectArrayElement( jo_args, nPos ) );
+ jni.ensure_no_exception();
+ jvalue java_arg;
+ java_arg.l = jo_out_holder.get();
+ map_to_java(
+ jni, &java_arg, uno_args[ nPos ], type, 0,
+ true /* in */, true /* out holder */ );
+ }
+ catch (...)
+ {
+ // cleanup further uno args
+ for ( sal_Int32 n = nPos; n < nParams; ++n )
+ {
+ uno_type_destructData(
+ uno_args[ n ], pParams[ n ].pTypeRef, 0 );
+#ifdef BROKEN_ALLOCA
+ if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
+ free( uno_args[ nPos ] );
+#endif
+ }
+ // cleanup uno return value
+ uno_type_destructData( uno_ret, return_type, 0 );
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ throw;
+ }
+ }
+ if (typelib_TypeClass_DOUBLE < type->eTypeClass &&
+ typelib_TypeClass_ENUM != type->eTypeClass) // opt
+ {
+ uno_type_destructData( uno_args[ nPos ], type, 0 );
+#ifdef BROKEN_ALLOCA
+ if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
+ free( uno_args[ nPos ] );
+#endif
+ }
+ }
+
+ if (typelib_TypeClass_VOID != return_type->eTypeClass)
+ {
+ // convert uno return value
+ jvalue java_ret;
+ try
+ {
+ map_to_java(
+ jni, &java_ret, uno_ret, return_type, 0,
+ true /* in */, false /* no out */,
+ true /* special_wrapped_integral_types */ );
+ }
+ catch (...)
+ {
+ uno_type_destructData( uno_ret, return_type, 0 );
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ throw;
+ }
+ if (typelib_TypeClass_DOUBLE < return_type->eTypeClass &&
+ typelib_TypeClass_ENUM != return_type->eTypeClass) // opt
+ {
+ uno_type_destructData( uno_ret, return_type, 0 );
+ }
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ return java_ret.l;
+ }
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ return 0; // void return
+ }
+ else // exception occured
+ {
+ // destruct uno in args
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & param = pParams[ nPos ];
+ if (param.bIn)
+ uno_type_destructData( uno_args[ nPos ], param.pTypeRef, 0 );
+#ifdef BROKEN_ALLOCA
+ if (uno_args[ nPos ] && uno_args[ nPos ] != &uno_args_mem[ nPos ])
+ free( uno_args[ nPos ] );
+#endif
+ }
+
+ handle_uno_exc( jni, uno_exc );
+#ifdef BROKEN_ALLOCA
+ free( mem );
+#endif
+ return 0;
+ }
+}
+
+}
+
+using namespace ::jni_uno;
+
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+JNIEXPORT jobject
+JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call(
+ JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle, jstring,
+ jstring jo_method, jobjectArray jo_args /* may be 0 */ )
+ SAL_THROW_EXTERN_C()
+{
+ Bridge const * bridge = reinterpret_cast< Bridge const * >( bridge_handle );
+ JNI_info const * jni_info = bridge->m_jni_info;
+ JNI_context jni(
+ jni_info, jni_env,
+ static_cast< jobject >(
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext )->getClassLoader() ) );
+
+ OUString method_name;
+
+ try
+ {
+ method_name = jstring_to_oustring( jni, jo_method );
+#if OSL_DEBUG_LEVEL > 1
+ {
+ OUStringBuffer trace_buf( 64 );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("java->uno call: ") );
+ trace_buf.append( method_name );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on oid ") );
+ JLocalAutoRef jo_oid(
+ jni, jni->GetObjectField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
+ trace_buf.append( jstring_to_oustring( jni, (jstring) jo_oid.get() ) );
+ OString cstr_msg(
+ OUStringToOString(
+ trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_msg.getStr() );
+ }
+#endif
+
+ // special IQueryInterface.queryInterface()
+ if (method_name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("queryInterface") ))
+ {
+ // oid
+ JLocalAutoRef jo_oid(
+ jni, jni->GetObjectField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
+ // type
+ JLocalAutoRef jo_type(
+ jni, jni->GetObjectArrayElement( jo_args, 0 ) );
+ jni.ensure_no_exception();
+
+ JLocalAutoRef jo_type_name(
+ jni, jni->GetObjectField(
+ jo_type.get(), jni_info->m_field_Type__typeName ) );
+ if (! jo_type_name.is())
+ {
+ throw BridgeRuntimeError(
+ OUSTR("incomplete type object: no type name!") +
+ jni.get_stack_trace() );
+ }
+ OUString type_name(
+ jstring_to_oustring( jni, (jstring) jo_type_name.get() ) );
+ JNI_type_info const * info =
+ jni_info->get_type_info( jni, type_name );
+ if (typelib_TypeClass_INTERFACE != info->m_td.get()->eTypeClass)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("queryInterface() call demands an INTERFACE type!") );
+ }
+ JNI_interface_type_info const * iface_info =
+ static_cast< JNI_interface_type_info const * >( info );
+
+ // getRegisteredInterface() already tested in JNI_proxy:
+ // perform queryInterface call on binary uno interface
+ uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
+
+ uno_Any uno_ret;
+ void * uno_args[] = { &iface_info->m_td.get()->pWeakRef };
+ uno_Any uno_exc_holder;
+ uno_Any * uno_exc = &uno_exc_holder;
+ // call binary uno
+ (*pUnoI->pDispatcher)(
+ pUnoI, jni_info->m_XInterface_queryInterface_td.get(),
+ &uno_ret, uno_args, &uno_exc );
+ if (0 == uno_exc)
+ {
+ jobject jo_ret = 0;
+ if (typelib_TypeClass_INTERFACE == uno_ret.pType->eTypeClass)
+ {
+ uno_Interface * pUnoRet =
+ (uno_Interface *) uno_ret.pReserved;
+ if (0 != pUnoRet)
+ {
+ try
+ {
+ jo_ret =
+ bridge->map_to_java( jni, pUnoRet, iface_info );
+ }
+ catch (...)
+ {
+ uno_any_destruct( &uno_ret, 0 );
+ throw;
+ }
+ }
+ }
+ uno_any_destruct( &uno_ret, 0 );
+ return jo_ret;
+ }
+ else
+ {
+ bridge->handle_uno_exc( jni, uno_exc );
+ return 0;
+ }
+ }
+
+ typelib_InterfaceTypeDescription * td =
+ reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) );
+ uno_Interface * pUnoI =
+ reinterpret_cast< uno_Interface * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
+
+ typelib_TypeDescriptionReference ** ppAllMembers = td->ppAllMembers;
+ for ( sal_Int32 nPos = td->nAllMembers; nPos--; )
+ {
+ // try to avoid getting typedescription as long as possible,
+ // because of a Mutex.acquire() in
+ // typelib_typedescriptionreference_getDescription()
+ typelib_TypeDescriptionReference * member_type =
+ ppAllMembers[ nPos ];
+
+ // check method_name against fully qualified type_name
+ // of member_type; type_name is of the form
+ // <name> "::" <method_name> *(":@" <idx> "," <idx> ":" <name>)
+ OUString const & type_name =
+ OUString::unacquired( &member_type->pTypeName );
+ sal_Int32 offset = type_name.indexOf( ':' ) + 2;
+ OSL_ASSERT(
+ offset >= 2 && offset < type_name.getLength()
+ && type_name[offset - 1] == ':' );
+ sal_Int32 remainder = type_name.getLength() - offset;
+ if (typelib_TypeClass_INTERFACE_METHOD == member_type->eTypeClass)
+ {
+ if ((method_name.getLength() == remainder
+ || (method_name.getLength() < remainder
+ && type_name[offset + method_name.getLength()] == ':'))
+ && type_name.match(method_name, offset))
+ {
+ TypeDescr member_td( member_type );
+ typelib_InterfaceMethodTypeDescription * method_td =
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ member_td.get() );
+ return bridge->call_uno(
+ jni, pUnoI, member_td.get(),
+ method_td->pReturnTypeRef,
+ method_td->nParams, method_td->pParams,
+ jo_args );
+ }
+ }
+ else // attribute
+ {
+ OSL_ASSERT(
+ typelib_TypeClass_INTERFACE_ATTRIBUTE ==
+ member_type->eTypeClass );
+
+ if (method_name.getLength() >= 3
+ && (method_name.getLength() - 3 == remainder
+ || (method_name.getLength() - 3 < remainder
+ && type_name[
+ offset + (method_name.getLength() - 3)] == ':'))
+ && method_name[1] == 'e' && method_name[2] == 't'
+ && rtl_ustr_compare_WithLength(
+ type_name.getStr() + offset,
+ method_name.getLength() - 3,
+ method_name.getStr() + 3,
+ method_name.getLength() - 3) == 0)
+ {
+ if ('g' == method_name[ 0 ])
+ {
+ TypeDescr member_td( member_type );
+ typelib_InterfaceAttributeTypeDescription * attr_td =
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member_td.get() );
+ return bridge->call_uno(
+ jni, pUnoI, member_td.get(),
+ attr_td->pAttributeTypeRef,
+ 0, 0,
+ jo_args );
+ }
+ else if ('s' == method_name[ 0 ])
+ {
+ TypeDescr member_td( member_type );
+ typelib_InterfaceAttributeTypeDescription * attr_td =
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ member_td.get() );
+ if (! attr_td->bReadOnly)
+ {
+ typelib_MethodParameter param;
+ param.pTypeRef = attr_td->pAttributeTypeRef;
+ param.bIn = sal_True;
+ param.bOut = sal_False;
+ return bridge->call_uno(
+ jni, pUnoI, member_td.get(),
+ jni_info->m_void_type.getTypeLibType(),
+ 1, &param,
+ jo_args );
+ }
+ }
+ }
+ }
+ }
+ // the thing that should not be... no method info found!
+ OUStringBuffer buf( 64 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "calling undeclared function on interface ") );
+ buf.append( OUString::unacquired(
+ &((typelib_TypeDescription *)td)->pTypeName ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
+ buf.append( method_name );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ catch (BridgeRuntimeError & err)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("[jni_uno bridge error] "
+ "Java calling UNO method ") );
+ buf.append( method_name );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
+ buf.append( err.m_message );
+ // notify RuntimeException
+ OString cstr_msg(
+ OUStringToOString(
+ buf.makeStringAndClear(), RTL_TEXTENCODING_JAVA_UTF8 ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+ if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr())
+ != 0)
+ {
+ OSL_ASSERT( false );
+ }
+ return 0;
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ OString cstr_msg(
+ OString( RTL_CONSTASCII_STRINGPARAM(
+ "[jni_uno bridge error] "
+ "attaching current thread to java failed!") ) +
+ OUStringToOString(
+ jni.get_stack_trace(), RTL_TEXTENCODING_JAVA_UTF8 ) );
+ OSL_ENSURE( 0, cstr_msg.getStr() );
+ if (jni->ThrowNew(jni_info->m_class_RuntimeException, cstr_msg.getStr())
+ != 0)
+ {
+ OSL_ASSERT( false );
+ }
+ return 0;
+ }
+}
+
+//------------------------------------------------------------------------------
+JNIEXPORT void
+JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J(
+ JNIEnv * jni_env, jobject jo_proxy, jlong bridge_handle )
+ SAL_THROW_EXTERN_C()
+{
+ Bridge const * bridge = reinterpret_cast< Bridge const * >( bridge_handle );
+ JNI_info const * jni_info = bridge->m_jni_info;
+ JNI_context jni(
+ jni_info, jni_env,
+ static_cast< jobject >(
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext )->getClassLoader() ) );
+
+ uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) );
+ typelib_TypeDescription * td =
+ reinterpret_cast< typelib_TypeDescription * >(
+ jni->GetLongField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) );
+
+#if OSL_DEBUG_LEVEL > 1
+ {
+ JLocalAutoRef jo_oid(
+ jni, jni->GetObjectField(
+ jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) );
+ OUString oid( jstring_to_oustring( jni, (jstring) jo_oid.get() ) );
+ OString cstr_msg(
+ OUStringToOString(
+ OUSTR("freeing java uno proxy: ") + oid,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_msg.getStr() );
+ }
+#endif
+ // revoke from uno env; has already been revoked from java env
+ (*bridge->m_uno_env->revokeInterface)( bridge->m_uno_env, pUnoI );
+ // release receiver
+ (*pUnoI->release)( pUnoI );
+ // release typedescription handle
+ typelib_typedescription_release( td );
+ // release bridge handle
+ bridge->release();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/jni_uno/jni_uno2java.cxx b/bridges/source/jni_uno/jni_uno2java.cxx
new file mode 100644
index 000000000000..70e139d66aab
--- /dev/null
+++ b/bridges/source/jni_uno/jni_uno2java.cxx
@@ -0,0 +1,876 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <sal/alloca.h>
+
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+#include "rtl/ustrbuf.hxx"
+
+#include "jni_bridge.h"
+
+
+using namespace ::std;
+using namespace ::rtl;
+
+namespace
+{
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_free( uno_ExtEnvironment * env, void * proxy )
+ SAL_THROW_EXTERN_C();
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_acquire( uno_Interface * pUnoI )
+ SAL_THROW_EXTERN_C();
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_release( uno_Interface * pUnoI )
+ SAL_THROW_EXTERN_C();
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_dispatch(
+ uno_Interface * pUnoI, typelib_TypeDescription const * member_td,
+ void * uno_ret, void * uno_args[], uno_Any ** uno_exc )
+ SAL_THROW_EXTERN_C();
+}
+}
+
+namespace jni_uno
+{
+
+//______________________________________________________________________________
+void Bridge::handle_java_exc(
+ JNI_context const & jni,
+ JLocalAutoRef const & jo_exc, uno_Any * uno_exc ) const
+{
+ OSL_ASSERT( jo_exc.is() );
+ if (! jo_exc.is())
+ {
+ throw BridgeRuntimeError(
+ OUSTR("java exception occured, but no java exception available!?") +
+ jni.get_stack_trace() );
+ }
+
+ JLocalAutoRef jo_class( jni, jni->GetObjectClass( jo_exc.get() ) );
+ JLocalAutoRef jo_class_name(
+ jni, jni->CallObjectMethodA(
+ jo_class.get(), m_jni_info->m_method_Class_getName, 0 ) );
+ jni.ensure_no_exception();
+ OUString exc_name(
+ jstring_to_oustring( jni, (jstring) jo_class_name.get() ) );
+
+ ::com::sun::star::uno::TypeDescription td( exc_name.pData );
+ if (!td.is() || (typelib_TypeClass_EXCEPTION != td.get()->eTypeClass))
+ {
+ // call toString()
+ JLocalAutoRef jo_descr(
+ jni, jni->CallObjectMethodA(
+ jo_exc.get(), m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("non-UNO exception occurred: ") );
+ buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
+ buf.append( jni.get_stack_trace( jo_exc.get() ) );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+
+ auto_ptr< rtl_mem > uno_data( rtl_mem::allocate( td.get()->nSize ) );
+ jvalue val;
+ val.l = jo_exc.get();
+ map_to_uno(
+ jni, uno_data.get(), val, td.get()->pWeakRef, 0,
+ false /* no assign */, false /* no out param */ );
+
+#if OSL_DEBUG_LEVEL > 0
+ // patch Message, append stack trace
+ reinterpret_cast< ::com::sun::star::uno::Exception * >(
+ uno_data.get() )->Message += jni.get_stack_trace( jo_exc.get() );
+#endif
+
+ typelib_typedescriptionreference_acquire( td.get()->pWeakRef );
+ uno_exc->pType = td.get()->pWeakRef;
+ uno_exc->pData = uno_data.release();
+
+#if OSL_DEBUG_LEVEL > 1
+ OUStringBuffer trace_buf( 128 );
+ trace_buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("exception occured uno->java: [") );
+ trace_buf.append( exc_name );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
+ trace_buf.append(
+ reinterpret_cast< ::com::sun::star::uno::Exception const * >(
+ uno_exc->pData )->Message );
+ OString cstr_trace(
+ OUStringToOString(
+ trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_trace.getStr() );
+#endif
+}
+
+//______________________________________________________________________________
+void Bridge::call_java(
+ jobject javaI, typelib_InterfaceTypeDescription * iface_td,
+ sal_Int32 local_member_index, sal_Int32 function_pos_offset,
+ typelib_TypeDescriptionReference * return_type,
+ typelib_MethodParameter * params, sal_Int32 nParams,
+ void * uno_ret, void * uno_args [], uno_Any ** uno_exc ) const
+{
+ OSL_ASSERT( function_pos_offset == 0 || function_pos_offset == 1 );
+
+ JNI_guarded_context jni(
+ m_jni_info, reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ m_java_env->pContext ) );
+
+ // assure fully initialized iface_td:
+ ::com::sun::star::uno::TypeDescription iface_holder;
+ if (! iface_td->aBase.bComplete) {
+ iface_holder = ::com::sun::star::uno::TypeDescription(
+ reinterpret_cast<typelib_TypeDescription *>(iface_td) );
+ iface_holder.makeComplete();
+ if (! iface_holder.get()->bComplete) {
+ OUStringBuffer buf;
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("cannot make type complete: ") );
+ buf.append( OUString::unacquired(&iface_holder.get()->pTypeName) );
+ buf.append( jni.get_stack_trace() );
+ throw BridgeRuntimeError( buf.makeStringAndClear() );
+ }
+ iface_td = reinterpret_cast<typelib_InterfaceTypeDescription *>(
+ iface_holder.get() );
+ OSL_ASSERT( iface_td->aBase.eTypeClass == typelib_TypeClass_INTERFACE );
+ }
+
+ // prepare java args, save param td
+#ifdef BROKEN_ALLOCA
+ jvalue * java_args = (jvalue *) malloc( sizeof (jvalue) * nParams );
+#else
+ jvalue * java_args = (jvalue *) alloca( sizeof (jvalue) * nParams );
+#endif
+
+ sal_Int32 nPos;
+ for ( nPos = 0; nPos < nParams; ++nPos )
+ {
+ try
+ {
+ typelib_MethodParameter const & param = params[ nPos ];
+ java_args[ nPos ].l = 0; // if out: build up array[ 1 ]
+ map_to_java(
+ jni, &java_args[ nPos ],
+ uno_args[ nPos ],
+ param.pTypeRef, 0,
+ sal_False != param.bIn /* convert uno value */,
+ sal_False != param.bOut /* build up array[ 1 ] */ );
+ }
+ catch (...)
+ {
+ // cleanup
+ for ( sal_Int32 n = 0; n < nPos; ++n )
+ {
+ typelib_MethodParameter const & param = params[ n ];
+ if (param.bOut ||
+ typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
+ {
+ jni->DeleteLocalRef( java_args[ n ].l );
+ }
+ }
+#ifdef BROKEN_ALLOCA
+ free( java_args );
+#endif
+ throw;
+ }
+ }
+
+ sal_Int32 base_members = iface_td->nAllMembers - iface_td->nMembers;
+ OSL_ASSERT( base_members < iface_td->nAllMembers );
+ sal_Int32 base_members_function_pos =
+ iface_td->pMapMemberIndexToFunctionIndex[ base_members ];
+ sal_Int32 member_pos = base_members + local_member_index;
+ OSL_ENSURE(
+ member_pos < iface_td->nAllMembers, "### member pos out of range!" );
+ sal_Int32 function_pos =
+ iface_td->pMapMemberIndexToFunctionIndex[ member_pos ]
+ + function_pos_offset;
+ OSL_ENSURE(
+ function_pos >= base_members_function_pos
+ && function_pos < iface_td->nMapFunctionIndexToMemberIndex,
+ "### illegal function index!" );
+ function_pos -= base_members_function_pos;
+
+ JNI_interface_type_info const * info =
+ static_cast< JNI_interface_type_info const * >(
+ m_jni_info->get_type_info( jni, &iface_td->aBase ) );
+ jmethodID method_id = info->m_methods[ function_pos ];
+
+#if OSL_DEBUG_LEVEL > 1
+ OUStringBuffer trace_buf( 128 );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("calling ") );
+ JLocalAutoRef jo_method(
+ jni, jni->ToReflectedMethod( info->m_class, method_id, JNI_FALSE ) );
+ jni.ensure_no_exception();
+ JLocalAutoRef jo_descr(
+ jni, jni->CallObjectMethodA(
+ jo_method.get(), m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ trace_buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on ") );
+ jo_descr.reset(
+ jni->CallObjectMethodA(
+ javaI, m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ trace_buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (") );
+ JLocalAutoRef jo_class( jni, jni->GetObjectClass( javaI ) );
+ jo_descr.reset(
+ jni->CallObjectMethodA(
+ jo_class.get(), m_jni_info->m_method_Object_toString, 0 ) );
+ jni.ensure_no_exception();
+ trace_buf.append( jstring_to_oustring( jni, (jstring) jo_descr.get() ) );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(")") );
+ OString cstr_trace(
+ OUStringToOString(
+ trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_trace.getStr() );
+#endif
+
+ // complex return value
+ JLocalAutoRef java_ret( jni );
+
+ switch (return_type->eTypeClass)
+ {
+ case typelib_TypeClass_VOID:
+ jni->CallVoidMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_CHAR:
+ *(sal_Unicode *)uno_ret =
+ jni->CallCharMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ *(sal_Bool *)uno_ret =
+ jni->CallBooleanMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_BYTE:
+ *(sal_Int8 *)uno_ret =
+ jni->CallByteMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(sal_Int16 *)uno_ret =
+ jni->CallShortMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ *(sal_Int32 *)uno_ret =
+ jni->CallIntMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *(sal_Int64 *)uno_ret =
+ jni->CallLongMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_FLOAT:
+ *(float *)uno_ret =
+ jni->CallFloatMethodA( javaI, method_id, java_args );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *(double *)uno_ret =
+ jni->CallDoubleMethodA( javaI, method_id, java_args );
+ break;
+ default:
+ java_ret.reset(
+ jni->CallObjectMethodA( javaI, method_id, java_args ) );
+ break;
+ }
+
+ if (jni->ExceptionCheck())
+ {
+ JLocalAutoRef jo_exc( jni, jni->ExceptionOccurred() );
+ jni->ExceptionClear();
+
+ // release temp java local refs
+ for ( nPos = 0; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & param = params[ nPos ];
+ if (param.bOut ||
+ typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
+ {
+ jni->DeleteLocalRef( java_args[ nPos ].l );
+ }
+ }
+
+ handle_java_exc( jni, jo_exc, *uno_exc );
+ }
+ else // no exception
+ {
+ for ( nPos = 0; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & param = params[ nPos ];
+ if (param.bOut)
+ {
+ try
+ {
+ map_to_uno(
+ jni, uno_args[ nPos ],
+ java_args[ nPos ], param.pTypeRef, 0,
+ sal_False != param.bIn /* assign if inout */,
+ true /* out param */ );
+ }
+ catch (...)
+ {
+ // cleanup uno pure out
+ for ( sal_Int32 n = 0; n < nPos; ++n )
+ {
+ typelib_MethodParameter const & p = params[ n ];
+ if (! p.bIn)
+ {
+ uno_type_destructData(
+ uno_args[ n ], p.pTypeRef, 0 );
+ }
+ }
+ // cleanup java temp local refs
+ for ( ; nPos < nParams; ++nPos )
+ {
+ typelib_MethodParameter const & p = params[ nPos ];
+ if (p.bOut ||
+ typelib_TypeClass_DOUBLE <
+ p.pTypeRef->eTypeClass)
+ {
+ jni->DeleteLocalRef( java_args[ nPos ].l );
+ }
+ }
+#ifdef BROKEN_ALLOCA
+ free( java_args );
+#endif
+ throw;
+ }
+ jni->DeleteLocalRef( java_args[ nPos ].l );
+ }
+ else // pure temp in param
+ {
+ if (typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass)
+ jni->DeleteLocalRef( java_args[ nPos ].l );
+ }
+ }
+
+ // return value
+ if (typelib_TypeClass_DOUBLE < return_type->eTypeClass)
+ {
+ try
+ {
+ jvalue val;
+ val.l = java_ret.get();
+ map_to_uno(
+ jni, uno_ret, val, return_type, 0,
+ false /* no assign */, false /* no out param */ );
+ }
+ catch (...)
+ {
+ // cleanup uno pure out
+ for ( sal_Int32 i = 0; i < nParams; ++i )
+ {
+ typelib_MethodParameter const & param = params[ i ];
+ if (! param.bIn)
+ {
+ uno_type_destructData(
+ uno_args[ i ], param.pTypeRef, 0 );
+ }
+ }
+#ifdef BROKEN_ALLOCA
+ free( java_args );
+#endif
+ throw;
+ }
+ } // else: already set integral uno return value
+
+ // no exception occured
+ *uno_exc = 0;
+ }
+#ifdef BROKEN_ALLOCA
+ free( java_args );
+#endif
+}
+
+//==== a uno proxy wrapping a java interface ===================================
+struct UNO_proxy : public uno_Interface
+{
+ mutable oslInterlockedCount m_ref;
+ Bridge const * m_bridge;
+
+ // mapping information
+ jobject m_javaI;
+ jstring m_jo_oid;
+ OUString m_oid;
+ JNI_interface_type_info const * m_type_info;
+
+ inline void acquire() const;
+ inline void release() const;
+
+ // ctor
+ inline UNO_proxy(
+ JNI_context const & jni, Bridge const * bridge,
+ jobject javaI, jstring jo_oid, OUString const & oid,
+ JNI_interface_type_info const * info );
+};
+
+//______________________________________________________________________________
+inline UNO_proxy::UNO_proxy(
+ JNI_context const & jni, Bridge const * bridge,
+ jobject javaI, jstring jo_oid, OUString const & oid,
+ JNI_interface_type_info const * info )
+ : m_ref( 1 ),
+ m_oid( oid ),
+ m_type_info( info )
+{
+ JNI_info const * jni_info = bridge->m_jni_info;
+ JLocalAutoRef jo_string_array(
+ jni, jni->NewObjectArray( 1, jni_info->m_class_String, jo_oid ) );
+ jni.ensure_no_exception();
+ jvalue args[ 3 ];
+ args[ 0 ].l = javaI;
+ args[ 1 ].l = jo_string_array.get();
+ args[ 2 ].l = info->m_type;
+ jobject jo_iface = jni->CallObjectMethodA(
+ jni_info->m_object_java_env,
+ jni_info->m_method_IEnvironment_registerInterface, args );
+ jni.ensure_no_exception();
+
+ m_javaI = jni->NewGlobalRef( jo_iface );
+ m_jo_oid = (jstring) jni->NewGlobalRef( jo_oid );
+ bridge->acquire();
+ m_bridge = bridge;
+
+ // uno_Interface
+ uno_Interface::acquire = UNO_proxy_acquire;
+ uno_Interface::release = UNO_proxy_release;
+ uno_Interface::pDispatcher = UNO_proxy_dispatch;
+}
+
+//______________________________________________________________________________
+inline void UNO_proxy::acquire() const
+{
+ if (1 == osl_incrementInterlockedCount( &m_ref ))
+ {
+ // rebirth of proxy zombie
+ void * that = const_cast< UNO_proxy * >( this );
+ // register at uno env
+ (*m_bridge->m_uno_env->registerProxyInterface)(
+ m_bridge->m_uno_env, &that,
+ UNO_proxy_free, m_oid.pData,
+ (typelib_InterfaceTypeDescription *)m_type_info->m_td.get() );
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ASSERT( this == (void const * const)that );
+#endif
+ }
+}
+
+//______________________________________________________________________________
+inline void UNO_proxy::release() const
+{
+ if (0 == osl_decrementInterlockedCount( &m_ref ))
+ {
+ // revoke from uno env on last release
+ (*m_bridge->m_uno_env->revokeInterface)(
+ m_bridge->m_uno_env, const_cast< UNO_proxy * >( this ) );
+ }
+}
+
+
+//______________________________________________________________________________
+uno_Interface * Bridge::map_to_uno(
+ JNI_context const & jni,
+ jobject javaI, JNI_interface_type_info const * info ) const
+{
+ JLocalAutoRef jo_oid( jni, compute_oid( jni, javaI ) );
+ OUString oid( jstring_to_oustring( jni, (jstring) jo_oid.get() ) );
+
+ uno_Interface * pUnoI = 0;
+ (*m_uno_env->getRegisteredInterface)(
+ m_uno_env, (void **)&pUnoI,
+ oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() );
+
+ if (0 == pUnoI) // no existing interface, register new proxy
+ {
+ // refcount initially 1
+ pUnoI = new UNO_proxy(
+ jni, const_cast< Bridge * >( this ),
+ javaI, (jstring) jo_oid.get(), oid, info );
+
+ (*m_uno_env->registerProxyInterface)(
+ m_uno_env, (void **)&pUnoI,
+ UNO_proxy_free,
+ oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() );
+ }
+ return pUnoI;
+}
+
+}
+
+using namespace ::jni_uno;
+
+namespace
+{
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_free( uno_ExtEnvironment * env, void * proxy )
+ SAL_THROW_EXTERN_C()
+{
+ UNO_proxy const * that = reinterpret_cast< UNO_proxy const * >( proxy );
+ Bridge const * bridge = that->m_bridge;
+
+ if ( env != bridge->m_uno_env ) {
+ OSL_ASSERT(false);
+ }
+#if OSL_DEBUG_LEVEL > 1
+ OString cstr_msg(
+ OUStringToOString(
+ OUSTR("freeing binary uno proxy: ") + that->m_oid,
+ RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_msg.getStr() );
+#endif
+
+ try
+ {
+ JNI_guarded_context jni(
+ bridge->m_jni_info,
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext ) );
+
+ jni->DeleteGlobalRef( that->m_javaI );
+ jni->DeleteGlobalRef( that->m_jo_oid );
+ }
+ catch (BridgeRuntimeError & err)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg2(
+ OUStringToOString( err.m_message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg2.getStr() );
+#else
+ (void) err; // unused
+#endif
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ OSL_ENSURE(
+ 0,
+ "[jni_uno bridge error] attaching current thread to java failed!" );
+ }
+
+ bridge->release();
+#if OSL_DEBUG_LEVEL > 1
+ *(int *)that = 0xdeadcafe;
+#endif
+ delete that;
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_acquire( uno_Interface * pUnoI )
+ SAL_THROW_EXTERN_C()
+{
+ UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
+ that->acquire();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_release( uno_Interface * pUnoI )
+ SAL_THROW_EXTERN_C()
+{
+ UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
+ that->release();
+}
+
+//------------------------------------------------------------------------------
+void SAL_CALL UNO_proxy_dispatch(
+ uno_Interface * pUnoI, typelib_TypeDescription const * member_td,
+ void * uno_ret, void * uno_args [], uno_Any ** uno_exc )
+ SAL_THROW_EXTERN_C()
+{
+ UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI );
+ Bridge const * bridge = that->m_bridge;
+
+#if OSL_DEBUG_LEVEL > 1
+ OUStringBuffer trace_buf( 64 );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("uno->java call: ") );
+ trace_buf.append( OUString::unacquired( &member_td->pTypeName ) );
+ trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" on oid ") );
+ trace_buf.append( that->m_oid );
+ OString cstr_msg(
+ OUStringToOString(
+ trace_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( cstr_msg.getStr() );
+#endif
+
+ try
+ {
+ switch (member_td->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ typelib_InterfaceAttributeTypeDescription const * attrib_td =
+ reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription const * >(
+ member_td );
+ com::sun::star::uno::TypeDescription attrib_holder;
+ while ( attrib_td->pBaseRef != 0 ) {
+ attrib_holder = com::sun::star::uno::TypeDescription(
+ attrib_td->pBaseRef );
+ OSL_ASSERT(
+ attrib_holder.get()->eTypeClass
+ == typelib_TypeClass_INTERFACE_ATTRIBUTE );
+ attrib_td = reinterpret_cast<
+ typelib_InterfaceAttributeTypeDescription * >(
+ attrib_holder.get() );
+ }
+ typelib_InterfaceTypeDescription * iface_td = attrib_td->pInterface;
+
+ if (0 == uno_ret) // is setter method
+ {
+ typelib_MethodParameter param;
+ param.pTypeRef = attrib_td->pAttributeTypeRef;
+ param.bIn = sal_True;
+ param.bOut = sal_False;
+
+ bridge->call_java(
+ that->m_javaI, iface_td,
+ attrib_td->nIndex, 1, // get, then set method
+ bridge->m_jni_info->m_void_type.getTypeLibType(),
+ &param, 1,
+ 0, uno_args, uno_exc );
+ }
+ else // is getter method
+ {
+ bridge->call_java(
+ that->m_javaI, iface_td, attrib_td->nIndex, 0,
+ attrib_td->pAttributeTypeRef,
+ 0, 0, // no params
+ uno_ret, 0, uno_exc );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ typelib_InterfaceMethodTypeDescription const * method_td =
+ reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription const * >(
+ member_td );
+ com::sun::star::uno::TypeDescription method_holder;
+ while ( method_td->pBaseRef != 0 ) {
+ method_holder = com::sun::star::uno::TypeDescription(
+ method_td->pBaseRef );
+ OSL_ASSERT(
+ method_holder.get()->eTypeClass
+ == typelib_TypeClass_INTERFACE_METHOD );
+ method_td = reinterpret_cast<
+ typelib_InterfaceMethodTypeDescription * >(
+ method_holder.get() );
+ }
+ typelib_InterfaceTypeDescription * iface_td = method_td->pInterface;
+
+ switch ( method_td->aBase.nPosition )
+ {
+ case 0: // queryInterface()
+ {
+ TypeDescr demanded_td(
+ *reinterpret_cast< typelib_TypeDescriptionReference ** >(
+ uno_args[ 0 ] ) );
+ if (typelib_TypeClass_INTERFACE !=
+ demanded_td.get()->eTypeClass)
+ {
+ throw BridgeRuntimeError(
+ OUSTR("queryInterface() call demands "
+ "an INTERFACE type!") );
+ }
+
+ uno_Interface * pInterface = 0;
+ (*bridge->m_uno_env->getRegisteredInterface)(
+ bridge->m_uno_env,
+ (void **) &pInterface, that->m_oid.pData,
+ (typelib_InterfaceTypeDescription *)demanded_td.get() );
+
+ if (0 == pInterface)
+ {
+ JNI_info const * jni_info = bridge->m_jni_info;
+ JNI_guarded_context jni(
+ jni_info,
+ reinterpret_cast< ::jvmaccess::UnoVirtualMachine * >(
+ bridge->m_java_env->pContext ) );
+
+ JNI_interface_type_info const * info =
+ static_cast< JNI_interface_type_info const * >(
+ jni_info->get_type_info( jni, demanded_td.get() ) );
+
+ jvalue args[ 2 ];
+ args[ 0 ].l = info->m_type;
+ args[ 1 ].l = that->m_javaI;
+
+ JLocalAutoRef jo_ret(
+ jni, jni->CallStaticObjectMethodA(
+ jni_info->m_class_UnoRuntime,
+ jni_info->m_method_UnoRuntime_queryInterface,
+ args ) );
+
+ if (jni->ExceptionCheck())
+ {
+ JLocalAutoRef jo_exc( jni, jni->ExceptionOccurred() );
+ jni->ExceptionClear();
+ bridge->handle_java_exc( jni, jo_exc, *uno_exc );
+ }
+ else
+ {
+ if (jo_ret.is())
+ {
+#if OSL_DEBUG_LEVEL > 0
+ JLocalAutoRef jo_oid(
+ jni, compute_oid( jni, jo_ret.get() ) );
+ OUString oid( jstring_to_oustring(
+ jni, (jstring) jo_oid.get() ) );
+ OSL_ENSURE(
+ oid.equals( that->m_oid ),
+ "### different oids!" );
+#endif
+ // refcount initially 1
+ uno_Interface * pUnoI2 = new UNO_proxy(
+ jni, bridge, jo_ret.get(),
+ that->m_jo_oid, that->m_oid, info );
+
+ (*bridge->m_uno_env->registerProxyInterface)(
+ bridge->m_uno_env,
+ (void **) &pUnoI2,
+ UNO_proxy_free, that->m_oid.pData,
+ reinterpret_cast<
+ typelib_InterfaceTypeDescription * >(
+ info->m_td.get() ) );
+
+ uno_any_construct(
+ (uno_Any *)uno_ret, &pUnoI2,
+ demanded_td.get(), 0 );
+ (*pUnoI2->release)( pUnoI2 );
+ }
+ else // object does not support demanded interface
+ {
+ uno_any_construct(
+ reinterpret_cast< uno_Any * >( uno_ret ),
+ 0, 0, 0 );
+ }
+ // no exception occured
+ *uno_exc = 0;
+ }
+ }
+ else
+ {
+ uno_any_construct(
+ reinterpret_cast< uno_Any * >( uno_ret ),
+ &pInterface, demanded_td.get(), 0 );
+ (*pInterface->release)( pInterface );
+ *uno_exc = 0;
+ }
+ break;
+ }
+ case 1: // acquire this proxy
+ that->acquire();
+ *uno_exc = 0;
+ break;
+ case 2: // release this proxy
+ that->release();
+ *uno_exc = 0;
+ break;
+ default: // arbitrary method call
+ bridge->call_java(
+ that->m_javaI, iface_td, method_td->nIndex, 0,
+ method_td->pReturnTypeRef,
+ method_td->pParams, method_td->nParams,
+ uno_ret, uno_args, uno_exc );
+ break;
+ }
+ break;
+ }
+ default:
+ {
+ throw BridgeRuntimeError(
+ OUSTR("illegal member type description!") );
+ }
+ }
+ }
+ catch (BridgeRuntimeError & err)
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM(
+ "[jni_uno bridge error] UNO calling Java method ") );
+ if (typelib_TypeClass_INTERFACE_METHOD == member_td->eTypeClass ||
+ typelib_TypeClass_INTERFACE_ATTRIBUTE == member_td->eTypeClass)
+ {
+ buf.append( OUString::unacquired(
+ &reinterpret_cast<
+ typelib_InterfaceMemberTypeDescription const * >(
+ member_td )->pMemberName ) );
+ }
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") );
+ buf.append( err.m_message );
+ // binary identical struct
+ ::com::sun::star::uno::RuntimeException exc(
+ buf.makeStringAndClear(),
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XInterface >() );
+ ::com::sun::star::uno::Type const & exc_type = ::getCppuType( &exc );
+ uno_type_any_construct( *uno_exc, &exc, exc_type.getTypeLibType(), 0 );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg2(
+ OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( "%s", cstr_msg2.getStr() );
+#endif
+ }
+ catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ // binary identical struct
+ ::com::sun::star::uno::RuntimeException exc(
+ OUSTR("[jni_uno bridge error] attaching current thread "
+ "to java failed!"),
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XInterface >() );
+ ::com::sun::star::uno::Type const & exc_type = ::getCppuType( &exc );
+ uno_type_any_construct( *uno_exc, &exc, exc_type.getTypeLibType(), 0 );
+#if OSL_DEBUG_LEVEL > 0
+ OString cstr_msg2(
+ OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_ENSURE( 0, cstr_msg2.getStr() );
+#endif
+ }
+}
+
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/jni_uno/makefile.mk b/bridges/source/jni_uno/makefile.mk
new file mode 100644
index 000000000000..da0942cdad29
--- /dev/null
+++ b/bridges/source/jni_uno/makefile.mk
@@ -0,0 +1,85 @@
+#*************************************************************************
+#
+# 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=java_uno
+USE_DEFFILE=TRUE
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+.IF "$(SOLAR_JAVA)"==""
+nojava:
+ @echo "Not building jni-uno bridge because Java is disabled"
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+.IF "$(GUI)$(COM)" == "WNTGCC"
+.IF "$(EXCEPTIONS)" == "sjlj"
+CFLAGS += -DBROKEN_ALLOCA
+.ENDIF
+.ENDIF
+
+SLOFILES= \
+ $(SLO)$/jni_info.obj \
+ $(SLO)$/jni_data.obj \
+ $(SLO)$/jni_uno2java.obj \
+ $(SLO)$/jni_java2uno.obj \
+ $(SLO)$/jni_bridge.obj \
+ $(SLO)$/nativethreadpool.obj
+
+SHL1TARGET=$(TARGET)
+
+SHL1STDLIBS= \
+ $(JVMACCESSLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(SALHELPERLIB)
+
+SHL1VERSIONMAP=$(TARGET).map
+
+SHL1IMPLIB=i$(TARGET)
+SHL1LIBS=$(SLB)$/$(TARGET).lib
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+DEF1NAME=$(SHL1TARGET)
+SHL1RPATH=URELIB
+
+.IF "$(debug)" != ""
+.IF "$(COM)" == "MSC"
+CFLAGS += -Ob0
+.ENDIF
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/jni_uno/nativethreadpool.cxx b/bridges/source/jni_uno/nativethreadpool.cxx
new file mode 100644
index 000000000000..9c92e89c5b07
--- /dev/null
+++ b/bridges/source/jni_uno/nativethreadpool.cxx
@@ -0,0 +1,233 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "jvmaccess/virtualmachine.hxx"
+#include "rtl/byteseq.h"
+#include "rtl/byteseq.hxx"
+#include "rtl/memory.h"
+#include "rtl/ref.hxx"
+#include "sal/types.h"
+#include "uno/threadpool.h"
+
+#include "jni.h"
+
+#include <new>
+
+/* The native implementation part of
+ * jurt/com/sun/star/lib/uno/environments/remote/NativeThreadPool.java.
+ */
+
+namespace {
+
+struct Pool {
+ Pool(rtl::Reference< jvmaccess::VirtualMachine > const & theVirtualMachine,
+ jmethodID theExecute, uno_ThreadPool thePool):
+ virtualMachine(theVirtualMachine), execute(theExecute), pool(thePool) {}
+
+ rtl::Reference< jvmaccess::VirtualMachine > virtualMachine;
+ jmethodID execute;
+ uno_ThreadPool pool;
+};
+
+struct Job {
+ Job(Pool * thePool, jobject theJob): pool(thePool), job(theJob) {}
+
+ Pool * pool;
+ jobject job;
+};
+
+void throwOutOfMemory(JNIEnv * env) {
+ jclass c = env->FindClass("java/lang/OutOfMemoryError");
+ if (c != 0) {
+ env->ThrowNew(c, "");
+ }
+}
+
+}
+
+extern "C" {
+
+static void SAL_CALL executeRequest(void * data) {
+ Job * job = static_cast< Job * >(data);
+ try {
+ jvmaccess::VirtualMachine::AttachGuard guard(job->pool->virtualMachine);
+ JNIEnv * env = guard.getEnvironment();
+ // Failure of the following Job.execute Java call is ignored; if that
+ // call fails, it should be due to a java.lang.Error, which is not
+ // handled well, anyway:
+ env->CallObjectMethod(job->job, job->pool->execute);
+ env->DeleteGlobalRef(job->job);
+ delete job;
+ } catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &) {
+ //TODO: DeleteGlobalRef(job->job)
+ delete job;
+ }
+}
+
+}
+
+extern "C" JNIEXPORT jbyteArray JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_threadId(
+ JNIEnv * env, jclass) SAL_THROW_EXTERN_C()
+{
+ sal_Sequence * s = 0;
+ uno_getIdOfCurrentThread(&s); //TODO: out of memory
+ uno_releaseIdFromCurrentThread();
+ rtl::ByteSequence seq(s);
+ rtl_byte_sequence_release(s);
+ sal_Int32 n = seq.getLength();
+ jbyteArray a = env->NewByteArray(n);
+ // sal_Int32 and jsize are compatible here
+ if (a == 0) {
+ return 0;
+ }
+ void * p = env->GetPrimitiveArrayCritical(a, 0);
+ if (p == 0) {
+ return 0;
+ }
+ rtl_copyMemory(p, seq.getConstArray(), n);
+ // sal_Int8 and jbyte ought to be compatible
+ env->ReleasePrimitiveArrayCritical(a, p, 0);
+ return a;
+}
+
+extern "C" JNIEXPORT jlong JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_create(
+ JNIEnv * env, jclass) SAL_THROW_EXTERN_C()
+{
+ JavaVM * vm;
+ if (env->GetJavaVM(&vm) != JNI_OK) { //TODO: no Java exception raised?
+ jclass c = env->FindClass("java/lang/RuntimeException");
+ if (c != 0) {
+ env->ThrowNew(c, "JNI GetJavaVM failed");
+ }
+ return 0;
+ }
+ jclass c = env->FindClass("com/sun/star/lib/uno/environments/remote/Job");
+ if (c == 0) {
+ return 0;
+ }
+ jmethodID execute = env->GetMethodID(c, "execute", "()Ljava/lang/Object;");
+ if (execute == 0) {
+ return 0;
+ }
+ try {
+ return reinterpret_cast< jlong >(new Pool(
+ new jvmaccess::VirtualMachine(vm, env->GetVersion(), false, env),
+ execute, uno_threadpool_create()));
+ } catch (std::bad_alloc) {
+ throwOutOfMemory(env);
+ return 0;
+ }
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_attach(
+ JNIEnv *, jclass, jlong pool) SAL_THROW_EXTERN_C()
+{
+ uno_threadpool_attach(reinterpret_cast< Pool * >(pool)->pool);
+}
+
+extern "C" JNIEXPORT jobject JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_enter(
+ JNIEnv * env, jclass, jlong pool) SAL_THROW_EXTERN_C()
+{
+ jobject job;
+ uno_threadpool_enter(
+ reinterpret_cast< Pool * >(pool)->pool,
+ reinterpret_cast< void ** >(&job));
+ if (job == 0) {
+ return 0;
+ }
+ jobject ref = env->NewLocalRef(job);
+ env->DeleteGlobalRef(job);
+ return ref;
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_detach(
+ JNIEnv *, jclass, jlong pool) SAL_THROW_EXTERN_C()
+{
+ uno_threadpool_detach(reinterpret_cast< Pool * >(pool)->pool);
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_putJob(
+ JNIEnv * env, jclass, jlong pool, jbyteArray threadId, jobject job,
+ jboolean request, jboolean oneWay) SAL_THROW_EXTERN_C()
+{
+ void * s = env->GetPrimitiveArrayCritical(threadId, 0);
+ if (s == 0) {
+ return;
+ }
+ rtl::ByteSequence seq(
+ static_cast< sal_Int8 * >(s), env->GetArrayLength(threadId));
+ // sal_Int8 and jbyte ought to be compatible; sal_Int32 and jsize are
+ // compatible here
+ //TODO: out of memory
+ env->ReleasePrimitiveArrayCritical(threadId, s, JNI_ABORT);
+ Pool * p = reinterpret_cast< Pool * >(pool);
+ jobject ref = env->NewGlobalRef(job);
+ if (ref == 0) {
+ return;
+ }
+ Job * j = 0;
+ if (request) {
+ j = new(std::nothrow) Job(p, ref);
+ if (j == 0) {
+ env->DeleteGlobalRef(ref);
+ throwOutOfMemory(env);
+ return;
+ }
+ }
+ uno_threadpool_putJob(
+ p->pool, seq.getHandle(),
+ request ? static_cast< void * >(j) : static_cast< void * >(ref),
+ request ? executeRequest : 0, oneWay);
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_dispose(
+ JNIEnv *, jclass, jlong pool) SAL_THROW_EXTERN_C()
+{
+ uno_threadpool_dispose(reinterpret_cast< Pool * >(pool)->pool);
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_com_sun_star_lib_uno_environments_remote_NativeThreadPool_destroy(
+ JNIEnv *, jclass, jlong pool) SAL_THROW_EXTERN_C()
+{
+ Pool * p = reinterpret_cast< Pool * >(pool);
+ uno_threadpool_destroy(p->pool);
+ delete p;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/context/context.cxx b/bridges/source/remote/context/context.cxx
new file mode 100644
index 000000000000..3e0ffeac894f
--- /dev/null
+++ b/bridges/source/remote/context/context.cxx
@@ -0,0 +1,487 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <stdio.h>
+#include <string.h>
+#include <list>
+#include <hash_map>
+#include <utility>
+
+#include <osl/diagnose.h>
+#include <osl/interlck.h>
+#include <osl/mutex.hxx>
+
+#include "rtl/ustring.hxx"
+#include "rtl/instance.hxx"
+
+#include <bridges/remote/context.h>
+#include <bridges/remote/remote.h>
+#include <bridges/remote/connection.h>
+#include <bridges/remote/counter.hxx>
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::rtl;
+
+namespace {
+
+extern "C" typedef void * (SAL_CALL * MemAlloc)(sal_Size);
+
+}
+
+namespace remote_context
+{
+
+class remote_ContextImpl :
+ public remote_Context
+{
+public:
+ remote_ContextImpl( remote_Connection *pConnection,
+ rtl_uString *pIdStr,
+ rtl_uString *pDescription,
+ rtl_uString *pProtocol,
+ remote_InstanceProvider *pProvider );
+ ~remote_ContextImpl();
+
+ static void SAL_CALL thisAcquire( uno_Context * );
+ static void SAL_CALL thisRelease( uno_Context * );
+ static void * SAL_CALL thisQuery( uno_Context * , rtl_uString * );
+ static void SAL_CALL thisAddDisposingListener( remote_Context * , remote_DisposingListener * );
+ static void SAL_CALL thisRemoveDisposingListener( remote_Context *, remote_DisposingListener *);
+ static void SAL_CALL thisDispose( remote_Context *);
+public:
+ oslInterlockedCount m_nRef;
+ sal_Bool m_bDisposed;
+ list < remote_DisposingListener * > m_lstListener;
+ Mutex m_mutex;
+};
+
+
+
+
+struct equalOUString_Impl
+{
+ sal_Bool operator()(const OUString & s1, const OUString & s2) const
+ { return s1 == s2; }
+};
+
+struct hashOUString_Impl
+{
+ size_t operator()(const OUString & rName) const
+ { return rName.hashCode(); }
+};
+
+typedef hash_map
+<
+ OUString,
+ void *,
+ hashOUString_Impl,
+ equalOUString_Impl
+>
+ContextMap;
+
+#if OSL_DEBUG_LEVEL > 1
+static MyCounter thisCounter( "DEBUG : Context" );
+#endif
+
+class ContextAdmin
+{
+public:
+ // listener administration
+ void addContextListener( remote_contextListenerFunc listener , void *pObject );
+ void removeContextListener( remote_contextListenerFunc listener , void *pObject );
+
+ void fire( sal_Int32 nRemoteContextMode,
+ rtl_uString *sName,
+ rtl_uString *sDescription );
+
+ // context administration
+ uno_Context *createAndRegisterContext(
+ remote_Connection *pConnection,
+ rtl_uString *pIdStr,
+ rtl_uString *pDescription,
+ rtl_uString *pProtocol,
+ remote_InstanceProvider *pInstanceProvider );
+
+ void revokeContext( uno_Context *pRemoteContext );
+
+ uno_Context *getContext( rtl_uString *pHost );
+
+ rtl_uString ** getConnectionList(
+ sal_Int32 *pnStringCount, MemAlloc memAlloc );
+
+private:
+ ::osl::Mutex m_mutex;
+
+ ContextMap m_mapContext;
+
+ typedef std::list< std::pair< remote_contextListenerFunc, void * > > List;
+ List m_lstListener;
+};
+
+void ContextAdmin::addContextListener( remote_contextListenerFunc listener , void *pObject )
+{
+ ::osl::MutexGuard guard( m_mutex );
+
+ m_lstListener.push_back( std::make_pair( listener, pObject ) );
+}
+
+void ContextAdmin::removeContextListener( remote_contextListenerFunc listener , void *pObject )
+{
+ ::osl::MutexGuard guard( m_mutex );
+
+ for (List::iterator ii(m_lstListener.begin()); ii != m_lstListener.end();
+ ++ii)
+ {
+ if (ii->first == listener && ii->second == pObject) {
+ m_lstListener.erase( ii );
+ break;
+ }
+ }
+}
+
+void ContextAdmin::fire(
+ sal_Int32 nRemoteContextMode,
+ rtl_uString *pName,
+ rtl_uString *sDescription )
+{
+ List lst;
+ {
+ ::osl::MutexGuard guard( m_mutex );
+ lst = m_lstListener;
+ }
+ for (List::iterator i(lst.begin()); i != lst.end(); ++i) {
+ (i->first)(i->second, nRemoteContextMode, pName, sDescription);
+ }
+}
+
+uno_Context *ContextAdmin::createAndRegisterContext( remote_Connection *pConnection,
+ rtl_uString *pIdStr,
+ rtl_uString *pDescription,
+ rtl_uString *pProtocol,
+ remote_InstanceProvider *pInstanceProvider )
+{
+ ::osl::MutexGuard guard( m_mutex );
+
+ uno_Context *pContext = getContext( pIdStr );
+ if( pContext )
+ {
+ pContext->release( pContext );
+ return 0;
+ }
+
+ remote_ContextImpl *p = new remote_ContextImpl( pConnection,
+ pIdStr,
+ pDescription,
+ pProtocol,
+ pInstanceProvider );
+
+ p->aBase.acquire( (uno_Context*) p );
+
+ m_mapContext[ OUString( pIdStr) ] = (void*) p;
+
+ fire( REMOTE_CONTEXT_CREATE , pIdStr , pDescription );
+ return ( uno_Context * )p;
+}
+
+
+void ContextAdmin::revokeContext( uno_Context *pRemoteContext )
+{
+ ::osl::MutexGuard guard( m_mutex );
+
+ remote_ContextImpl *p = ( remote_ContextImpl * ) pRemoteContext;
+
+ ContextMap::iterator ii = m_mapContext.find( p->m_pName );
+ OSL_ASSERT( ii != m_mapContext.end() );
+ m_mapContext.erase( ii );
+
+ fire( REMOTE_CONTEXT_DESTROY , p->m_pName , p->m_pDescription );
+
+}
+
+uno_Context *ContextAdmin::getContext( rtl_uString *pHost )
+{
+ ::osl::MutexGuard guard( m_mutex );
+
+ ContextMap::iterator ii = m_mapContext.find( OUString( (rtl_uString*)pHost ) );
+ if( ii == m_mapContext.end() )
+ {
+ return 0;
+ }
+
+ uno_Context *p = ( uno_Context * ) (*ii).second;
+ p->acquire( p );
+ return p;
+}
+
+
+rtl_uString ** ContextAdmin::getConnectionList(
+ sal_Int32 *pnStringCount, MemAlloc memAlloc )
+{
+ ::osl::MutexGuard guard( m_mutex );
+
+ *pnStringCount = m_mapContext.size();
+
+ if (*pnStringCount == 0)
+ return NULL;
+
+ rtl_uString **ppReturn = ( rtl_uString ** )
+ memAlloc( sizeof( rtl_uString * ) * m_mapContext.size() );
+ memset( ppReturn , 0 , sizeof( rtl_uString * ) * m_mapContext.size() );
+
+ sal_Int32 i = 0;
+ for( ContextMap::iterator ii = m_mapContext.begin() ;
+ ii != m_mapContext.end();
+ ++ii, i++ )
+ {
+ rtl_uString_assign( &( ppReturn[i] ), (*ii).first.pData );
+ }
+
+ return ppReturn;
+}
+
+
+struct theContextAdmin : public rtl::Static<ContextAdmin, theContextAdmin> {};
+
+/*****************************
+ * remote_ContextImpl implementation
+ ****************************/
+
+
+
+remote_ContextImpl::remote_ContextImpl( remote_Connection *pConnection ,
+ rtl_uString *pIdStr,
+ rtl_uString *pDescription,
+ rtl_uString *pProtocol,
+ remote_InstanceProvider *pProvider ) :
+ m_nRef( 0 ),
+ m_bDisposed( sal_False )
+{
+ m_pConnection = pConnection;
+ m_pConnection->acquire( m_pConnection );
+
+ m_pInstanceProvider = pProvider;
+ if( m_pInstanceProvider )
+ {
+ m_pInstanceProvider->acquire( pProvider );
+ }
+
+ m_pName = pIdStr;
+ rtl_uString_acquire( m_pName );
+
+ m_pDescription = pDescription;
+ rtl_uString_acquire( m_pDescription );
+
+ m_pProtocol = pProtocol;
+ rtl_uString_acquire( pProtocol );
+
+ aBase.acquire = thisAcquire;
+ aBase.release = thisRelease;
+ addDisposingListener = thisAddDisposingListener;
+ removeDisposingListener = thisRemoveDisposingListener;
+ dispose = thisDispose;
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+remote_ContextImpl::~remote_ContextImpl()
+{
+ // disposed must have been called
+ OSL_ASSERT( m_bDisposed );
+
+ rtl_uString_release( m_pName );
+ rtl_uString_release( m_pDescription );
+ rtl_uString_release( m_pProtocol );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+
+}
+
+
+void remote_ContextImpl::thisAddDisposingListener( remote_Context *pRemoteC ,
+ remote_DisposingListener *pListener )
+{
+ remote_ContextImpl *pImpl = (remote_ContextImpl * ) pRemoteC;
+
+ ::osl::MutexGuard guard( pImpl->m_mutex );
+
+ pListener->acquire( pListener );
+ pImpl->m_lstListener.push_back( pListener );
+}
+
+void remote_ContextImpl::thisRemoveDisposingListener( remote_Context *pRemoteC,
+ remote_DisposingListener *pListener)
+{
+ remote_ContextImpl *pImpl = (remote_ContextImpl * ) pRemoteC;
+ MutexGuard guard( pImpl->m_mutex );
+
+ for( list< remote_DisposingListener * >::iterator ii = pImpl->m_lstListener.begin() ;
+ ii != pImpl->m_lstListener.end();
+ ++ii )
+ {
+ if( (*ii) == pListener )
+ {
+ pImpl->m_lstListener.erase( ii );
+ pListener->release( pListener );
+ break;
+ }
+ }
+}
+
+void remote_ContextImpl::thisDispose( remote_Context *pRemoteC )
+{
+ remote_ContextImpl *pImpl = ( remote_ContextImpl * )pRemoteC;
+
+ MutexGuard guard( pImpl->m_mutex );
+ if( ! pImpl->m_bDisposed )
+ {
+ pImpl->m_bDisposed = sal_True;
+ theContextAdmin::get().revokeContext( (uno_Context * ) pRemoteC );
+
+ if( pImpl->m_pInstanceProvider )
+ {
+ pImpl->m_pInstanceProvider->release( pImpl->m_pInstanceProvider );
+ pImpl->m_pInstanceProvider = 0;
+ }
+
+ pImpl->m_pConnection->release( pImpl->m_pConnection );
+ pImpl->m_pConnection = 0;
+
+ list< remote_DisposingListener * > lst = pImpl->m_lstListener;
+ pImpl->m_lstListener.clear();
+
+ for( list < remote_DisposingListener * >::iterator ii = lst.begin();
+ ii != lst.end();
+ ++ii )
+ {
+ (*ii)->disposing( (*ii) , pImpl->m_pName );
+ (*ii)->release( (*ii) );
+ }
+
+ }
+}
+
+
+
+void remote_ContextImpl::thisAcquire( uno_Context *pRemoteC )
+{
+ remote_ContextImpl *p = SAL_REINTERPRET_CAST(remote_ContextImpl * ,pRemoteC );
+ osl_incrementInterlockedCount( &(p->m_nRef) );
+}
+
+void remote_ContextImpl::thisRelease( uno_Context *pRemoteC )
+{
+ remote_ContextImpl *p = SAL_REINTERPRET_CAST( remote_ContextImpl * , pRemoteC );
+ if (! osl_decrementInterlockedCount( &(p->m_nRef) ))
+ {
+ // enshure, that this piece of code is not reentered
+ osl_incrementInterlockedCount( &(p->m_nRef) );
+
+ // dispose, if necessary
+ p->dispose( p );
+
+ // restore the counter
+ osl_decrementInterlockedCount( &(p->m_nRef) );
+
+ if( 0 == p->m_nRef )
+ {
+ delete p;
+ }
+ else
+ {
+ // reanimated, but disposed !
+ }
+ }
+}
+
+void *remote_ContextImpl::thisQuery( uno_Context * , rtl_uString * )
+{
+ return 0;
+}
+
+
+} // end namespace remote_context
+
+
+using namespace remote_context;
+
+//-----------------------
+//
+// C-Interface
+//
+//-----------------------
+extern "C" remote_Context * SAL_CALL
+remote_getContext( rtl_uString *pIdString )
+{
+ return (remote_Context *) theContextAdmin::get().getContext(pIdString);
+}
+
+
+
+extern "C" remote_Context * SAL_CALL
+remote_createContext( remote_Connection *pConnection,
+ rtl_uString *pIdStr,
+ rtl_uString *pDescription,
+ rtl_uString *pProtocol,
+ remote_InstanceProvider *pProvider )
+{
+ remote_ContextImpl *p = (remote_ContextImpl * )
+ theContextAdmin::get().createAndRegisterContext(
+ pConnection ,
+ pIdStr ,
+ pDescription,
+ pProtocol,
+ pProvider );
+
+ return (remote_Context * )p;
+}
+
+
+extern "C" void SAL_CALL
+remote_addContextListener( remote_contextListenerFunc listener, void *pObject )
+{
+ theContextAdmin::get().addContextListener( listener , pObject );
+}
+
+extern "C" void SAL_CALL
+remote_removeContextListener( remote_contextListenerFunc listener , void *pObject )
+{
+ theContextAdmin::get().removeContextListener( listener , pObject );
+}
+
+extern "C" rtl_uString ** SAL_CALL
+remote_getContextList( sal_Int32 *pnStringCount, MemAlloc memAlloc )
+{
+ return theContextAdmin::get().getConnectionList( pnStringCount , memAlloc );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/context/exports.dxp b/bridges/source/remote/context/exports.dxp
new file mode 100644
index 000000000000..dcef3c369b10
--- /dev/null
+++ b/bridges/source/remote/context/exports.dxp
@@ -0,0 +1,5 @@
+remote_getContext
+remote_createContext
+remote_getContextList
+remote_removeContextListener
+remote_addContextListener \ No newline at end of file
diff --git a/bridges/source/remote/context/makefile.mk b/bridges/source/remote/context/makefile.mk
new file mode 100644
index 000000000000..cc2a52355d25
--- /dev/null
+++ b/bridges/source/remote/context/makefile.mk
@@ -0,0 +1,65 @@
+#*************************************************************************
+#
+# 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=rmcxt
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+
+UNIXVERSIONNAMES=UDK
+
+# --- Settings -----------------------------------------------------
+.INCLUDE : settings.mk
+# ------------------------------------------------------------------
+
+UNOUCRDEP=$(SOLARUCRDIR)$/uce.rdb
+UNOUCRRDB=$(SOLARUCRDIR)$/uce.rdb
+
+SLOFILES= $(SLO)$/context.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1STDLIBS= \
+ $(SALLIB)
+
+SHL1DEPN=
+SHL1IMPLIB= i$(TARGET)
+SHL1LIBS= $(SLB)$/$(TARGET).lib
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1RPATH=URELIB
+
+SHL1VERSIONMAP= $(TARGET).map
+
+DEF1NAME= $(SHL1TARGET)
+#DEF1EXPORTFILE= exports.dxp
+
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/bridges/source/remote/context/rmcxt.map b/bridges/source/remote/context/rmcxt.map
new file mode 100755
index 000000000000..182f6495ea9d
--- /dev/null
+++ b/bridges/source/remote/context/rmcxt.map
@@ -0,0 +1,10 @@
+UDK_3_0_0 {
+ global:
+ remote_getContext;
+ remote_createContext;
+ remote_getContextList;
+ remote_removeContextListener;
+ remote_addContextListener;
+ local:
+ *;
+};
diff --git a/bridges/source/remote/idl/corba.idl b/bridges/source/remote/idl/corba.idl
new file mode 100644
index 000000000000..b71d16e2eff1
--- /dev/null
+++ b/bridges/source/remote/idl/corba.idl
@@ -0,0 +1,88 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+module com
+{
+module sun
+{
+module star
+{
+
+module corba
+{
+
+ // CosBridging module
+ typedef unsigned long ObjectSystemID;
+ typedef sequence< byte > OpaqueData;
+
+ struct OneThreadID
+ {
+ ObjectSystemID objSysID;
+ OpaqueData threadID;
+ };
+
+ typedef sequence<OneThreadID> ThreadIDs;
+
+ struct LogicalThreadID // Service context
+ {
+ ThreadIDs IDs;
+ };
+
+ struct CorbaString8
+ {
+ string theString;
+ };
+
+ struct CorbaUnion
+ {
+ long dummy;
+ };
+
+ struct ObjectKey
+ {
+ CorbaString8 sOid;
+ CorbaString8 sType;
+ };
+
+ enum TCKind
+ {
+ tk_null, tk_void,
+ tk_short, tk_long, tk_ushort, tk_ulong,
+ tk_float, tk_double, tk_boolean, tk_char,
+ tk_octet, tk_any, tk_TypeCode, tk_Principal, tk_objref,
+ tk_struct, tk_union, tk_enum, tk_string,
+ tk_sequence, tk_array, tk_alias, tk_except,
+ tk_longlong, tk_ulonglong, tk_longdouble,
+ tk_wchar, tk_wstring, tk_fixed,
+ tk_value, tk_value_box,
+ tk_native,
+ tk_abstract_interface
+ };
+};
+
+};
+};
+};
diff --git a/bridges/source/remote/static/helper.cxx b/bridges/source/remote/static/helper.cxx
new file mode 100644
index 000000000000..f0fc40106d36
--- /dev/null
+++ b/bridges/source/remote/static/helper.cxx
@@ -0,0 +1,212 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <rtl/alloc.h>
+#include <osl/diagnose.h>
+
+#include <bridges/remote/helper.hxx>
+
+#include <bridges/remote/stub.hxx>
+#include <bridges/remote/proxy.hxx>
+#include <bridges/remote/remote.hxx>
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace bridges_remote
+{
+
+void SAL_CALL remote_createStub (
+ remote_Interface **ppRemoteI,
+ rtl_uString *pOid ,
+ typelib_TypeDescriptionReference *pTypeRef,
+ uno_Environment *pEnvRemote,
+ ReleaseRemoteCallbackFunc releaseRemoteCallback )
+{
+ typelib_TypeDescription *pType = 0;
+ typelib_typedescriptionreference_getDescription( &pType, pTypeRef );
+
+ (void) pEnvRemote->pExtEnv->getRegisteredInterface(
+ pEnvRemote->pExtEnv,
+ (void **)ppRemoteI,
+ pOid,
+ (typelib_InterfaceTypeDescription* )pType );
+
+ if( *ppRemoteI )
+ {
+ if( (*ppRemoteI)->acquire == acquireRemote2RemoteStub ) {
+
+ if( releaseRemoteCallback )
+ {
+ // use the callback handler, the bridge wants to send the call immeadiatly
+ releaseRemoteCallback( *ppRemoteI , pOid, pTypeRef , pEnvRemote );
+ }
+ else
+ {
+ ((::bridges_remote::Remote2RemoteStub *)*ppRemoteI)->releaseRemote();
+ }
+ }
+ else
+ {
+ // Uno2RemoteStub
+ // no release necessary
+ }
+ }
+ else
+ {
+ remote_BridgeImpl *pImpl = ((remote_Context *)pEnvRemote->pContext)->m_pBridgeImpl;
+ *ppRemoteI =
+ new ::bridges_remote::Remote2RemoteStub(
+ pOid,
+ (typelib_InterfaceTypeDescription * ) pType,
+ pEnvRemote,
+ pImpl->m_sendRequest);
+
+ // ppRemoteI may change during registration
+ pEnvRemote->pExtEnv->registerProxyInterface(
+ pEnvRemote->pExtEnv,
+ (void **) ppRemoteI,
+ freeRemote2RemoteStub,
+ pOid,
+ (typelib_InterfaceTypeDescription * ) pType );
+ }
+
+ typelib_typedescription_release( pType );
+}
+
+void SAL_CALL remote_sendQueryInterface(
+ uno_Environment *pEnvRemote,
+ remote_Interface **ppRemoteI,
+ rtl_uString *pOid ,
+ typelib_TypeDescriptionReference *pTypeRef,
+ uno_Any **ppException
+ )
+{
+ OSL_ASSERT( ppRemoteI );
+
+ typelib_InterfaceTypeDescription *pType = 0;
+ typelib_typedescriptionreference_getDescription( (typelib_TypeDescription ** )&pType, pTypeRef );
+
+ if( *ppRemoteI )
+ {
+ (*ppRemoteI)->release( *ppRemoteI );
+ (*ppRemoteI) = 0;
+ }
+
+ remote_BridgeImpl *pImpl = ((remote_Context *)pEnvRemote->pContext)->m_pBridgeImpl;
+
+ Type type = ::getCppuType( (Reference < XInterface > *)0 );
+
+ // get type for queryInterface
+ OUString sCompleteMethodName = type.getTypeName();
+ sCompleteMethodName += OUString(RTL_CONSTASCII_USTRINGPARAM("::queryInterface"));
+
+ typelib_InterfaceMemberTypeDescription *pMemberType = 0;
+ typelib_typedescription_getByName(
+ (typelib_TypeDescription **) &pMemberType,
+ sCompleteMethodName.pData );
+
+ OSL_ASSERT( pMemberType );
+
+ uno_Any anyInterface;
+ anyInterface.pType = 0;
+ anyInterface.pData = 0;
+
+ void *pReturn = &anyInterface;
+ void *ppArgs[1];
+
+ ppArgs[0] = 0;
+ typelib_TypeDescriptionReference *pRef = 0;
+ typelib_typedescriptionreference_new( &pRef ,
+ pType->aBase.eTypeClass,
+ pType->aBase.pTypeName);
+
+ ppArgs[0] = &pRef;
+
+// uno_Any anyException;
+// uno_Any *pAnyException = &anyException;
+
+ // do the queryInterface
+ pImpl->m_sendRequest(
+ pEnvRemote,
+ (typelib_TypeDescription * ) pMemberType,
+ pOid,
+ pType,
+ pReturn,
+ ppArgs,
+ ppException );
+
+
+ // now release everything
+ typelib_typedescriptionreference_release( pRef );
+ typelib_typedescription_release( (typelib_TypeDescription * ) pMemberType );
+
+ if( *ppException )
+ {
+ *ppRemoteI = 0;
+ }
+ else
+ {
+ // set out parameter
+ if( typelib_TypeClass_INTERFACE == anyInterface.pType->eTypeClass )
+ {
+ *ppRemoteI = ( remote_Interface * ) anyInterface.pReserved;
+ }
+ typelib_typedescriptionreference_release( anyInterface.pType );
+ }
+
+ typelib_typedescription_release( (typelib_TypeDescription * ) pType );
+}
+
+
+void SAL_CALL remote_retrieveOidFromProxy(
+ remote_Interface *pRemoteI,
+ rtl_uString **ppOid )
+{
+ if( pRemoteI->acquire == acquireRemote2RemoteStub )
+ {
+ // Remote2RemoteStub
+ ::bridges_remote::Remote2RemoteStub *pStub = (::bridges_remote::Remote2RemoteStub * ) pRemoteI;
+ rtl_uString_newFromString( ppOid , pStub->m_sOid.pData );
+ }
+ else
+ {
+ // Uno2RemoteStub
+ ::bridges_remote::Uno2RemoteStub *pStub = (::bridges_remote::Uno2RemoteStub * ) pRemoteI;
+ rtl_uString_newFromString( ppOid , pStub->m_sOid.pData );
+ pRemoteI->acquire( pRemoteI );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/static/makefile.mk b/bridges/source/remote/static/makefile.mk
new file mode 100644
index 000000000000..9b3c2b795f8d
--- /dev/null
+++ b/bridges/source/remote/static/makefile.mk
@@ -0,0 +1,61 @@
+#*************************************************************************
+#
+# 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=bridges_remote_static
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/proxy.obj \
+ $(SLO)$/stub.obj \
+ $(SLO)$/remote.obj \
+ $(SLO)$/mapping.obj \
+ $(SLO)$/helper.obj \
+ $(SLO)$/remote_types.obj
+
+# Forte6 update 1 on Solaris Intel dies with internal compiler error
+# on stub.cxx if optimization is on. Switch it off for now.
+# To be reevaluated on compiler upgrade
+.IF "$(OS)$(CPU)"=="SOLARISI"
+NOOPTFILES=\
+ $(SLO)$/stub.obj
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+
diff --git a/bridges/source/remote/static/mapping.cxx b/bridges/source/remote/static/mapping.cxx
new file mode 100644
index 000000000000..3402cfe68268
--- /dev/null
+++ b/bridges/source/remote/static/mapping.cxx
@@ -0,0 +1,221 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <osl/diagnose.h>
+
+#include <bridges/remote/proxy.hxx>
+#include <bridges/remote/stub.hxx>
+#include <bridges/remote/counter.hxx>
+#include <bridges/remote/mapping.hxx>
+
+using namespace bridges_remote;
+
+extern "C" {
+
+static void SAL_CALL thisAcquire( uno_Mapping *pMap )
+{
+ RemoteMapping *p = SAL_REINTERPRET_CAST( RemoteMapping * , pMap );
+ if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) )
+ {
+ if( remoteToUno == pMap->mapInterface )
+ {
+ uno_registerMapping( &pMap ,
+ freeRemoteMapping,
+ p->pEnvRemote ,
+ p->pEnvUno ,
+ p->m_sPurpose.pData );
+ }
+ else
+ {
+ uno_registerMapping( &pMap ,
+ freeRemoteMapping,
+ p->pEnvUno ,
+ p->pEnvRemote ,
+ p->m_sPurpose.pData );
+ }
+
+ }
+}
+
+static void SAL_CALL thisRelease( uno_Mapping *pMap )
+{
+ RemoteMapping *p = SAL_REINTERPRET_CAST( RemoteMapping * , pMap );
+ if (! osl_decrementInterlockedCount( &(p->m_nRef) ))
+ {
+ uno_revokeMapping( pMap );
+ }
+}
+
+}
+
+namespace bridges_remote {
+
+void remoteToUno( uno_Mapping *pMapping, void **ppUnoI, void *pRemoteI,
+ typelib_InterfaceTypeDescription *pTypeDescr )
+{
+ remote_Mapping *pRemoteMapping = ( remote_Mapping * ) pMapping;
+
+ OSL_ASSERT( ppUnoI && pTypeDescr );
+ if (*ppUnoI)
+ {
+ ((uno_Interface *)*ppUnoI)->release( (uno_Interface *)*ppUnoI );
+ *ppUnoI = 0;
+ }
+
+ if (pRemoteI && pTypeDescr)
+ {
+ // get object id of interface to be wrapped
+ rtl_uString * pOid = 0;
+ pRemoteMapping->pEnvRemote->pExtEnv->getObjectIdentifier(
+ pRemoteMapping->pEnvRemote->pExtEnv,
+ &pOid,
+ pRemoteI );
+
+ OSL_ASSERT(pOid);
+ if( ! pOid )
+ {
+ return;
+ }
+
+ // try to get any known interface from target environment
+ pRemoteMapping->pEnvUno->pExtEnv->getRegisteredInterface(
+ pRemoteMapping->pEnvUno->pExtEnv,
+ ppUnoI,
+ pOid,
+ pTypeDescr);
+
+ if ( ! *ppUnoI) // already existing interface
+ {
+ // try to publish a new proxy; proxy may be exchanged during registration
+ *ppUnoI = new Remote2UnoProxy(
+ ( remote_Interface * ) pRemoteI,
+ pOid,
+ pTypeDescr ,
+ pRemoteMapping->pEnvUno,
+ pRemoteMapping->pEnvRemote);
+
+ pRemoteMapping->pEnvUno->pExtEnv->registerProxyInterface(
+ pRemoteMapping->pEnvUno->pExtEnv,
+ ppUnoI,
+ freeRemote2UnoProxy,
+ pOid,
+ pTypeDescr );
+
+ OSL_ASSERT( *ppUnoI );
+ }
+ rtl_uString_release( pOid );
+ }
+}
+
+void unoToRemote( uno_Mapping *pMapping, void **ppRemoteI, void *pUnoI,
+ typelib_InterfaceTypeDescription *pTypeDescr )
+{
+ remote_Mapping *pRemoteMapping = ( remote_Mapping * ) pMapping;
+ OSL_ASSERT( ppRemoteI && pTypeDescr );
+ if (*ppRemoteI)
+ {
+ ((remote_Interface *)*ppRemoteI)->release( (remote_Interface *)*ppRemoteI);
+ *ppRemoteI = 0;
+ }
+ if (pUnoI && pTypeDescr)
+ {
+ // get object id of interface to be wrapped
+ rtl_uString * pOid = 0;
+ pRemoteMapping->pEnvUno->pExtEnv->getObjectIdentifier(
+ pRemoteMapping->pEnvUno->pExtEnv,
+ &pOid,
+ pUnoI );
+
+ OSL_ASSERT( pOid );
+ if( ! pOid )
+ {
+ return;
+ }
+
+ pRemoteMapping->pEnvRemote->pExtEnv->getRegisteredInterface(
+ pRemoteMapping->pEnvRemote->pExtEnv,
+ (void**)ppRemoteI,
+ pOid,
+ pTypeDescr );
+
+ if( !*ppRemoteI )
+ {
+ // try to publish a new proxy;
+ *ppRemoteI = new Uno2RemoteStub(
+ ( uno_Interface * ) pUnoI,
+ pOid,
+ pTypeDescr,
+ pRemoteMapping->pEnvUno,
+ pRemoteMapping->pEnvRemote );
+
+ // note : ppRemoteI may change during registration
+ pRemoteMapping->pEnvRemote->pExtEnv->registerProxyInterface(
+ pRemoteMapping->pEnvRemote->pExtEnv,
+ (void**) ppRemoteI,
+ freeUno2RemoteStub,
+ pOid,
+ pTypeDescr );
+ }
+
+ rtl_uString_release( pOid );
+ }
+}
+
+void freeRemoteMapping(uno_Mapping * mapping) {
+ delete reinterpret_cast< RemoteMapping * >(mapping);
+}
+
+RemoteMapping::RemoteMapping( uno_Environment *pEnvUno_ ,
+ uno_Environment *pEnvRemote_,
+ uno_MapInterfaceFunc func,
+ const ::rtl::OUString sPurpose) :
+ m_nRef( 1 ),
+ m_sPurpose( sPurpose )
+{
+ pEnvUno = pEnvUno_;
+ pEnvRemote = pEnvRemote_;
+
+ pEnvUno->acquire( pEnvUno );
+ pEnvRemote->acquire( pEnvRemote );
+
+ aBase.mapInterface = func;
+ aBase.acquire = thisAcquire;
+ aBase.release = thisRelease;
+}
+
+RemoteMapping::~RemoteMapping( )
+{
+ pEnvUno->release( pEnvUno );
+ pEnvRemote->release( pEnvRemote );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/static/proxy.cxx b/bridges/source/remote/static/proxy.cxx
new file mode 100644
index 000000000000..db7b9a67a903
--- /dev/null
+++ b/bridges/source/remote/static/proxy.cxx
@@ -0,0 +1,341 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <sal/alloca.h>
+#include <bridges/remote/proxy.hxx>
+#include <bridges/remote/context.h>
+
+#include <uno/data.h>
+#include <uno/mapping.hxx>
+#include <uno/environment.h>
+
+#include <com/sun/star/uno/Any.hxx>
+
+#include <bridges/remote/bridgeimpl.hxx>
+
+#include "remote_types.hxx"
+
+#if OSL_DEBUG_LEVEL > 1
+#include <bridges/remote/counter.hxx>
+static MyCounter thisCounter( "DEBUG : Remote2UnoProxy");
+#endif
+
+using namespace ::bridges_remote;
+using namespace ::com::sun::star::uno;
+
+extern "C" {
+
+void SAL_CALL remote_release( void *pRemoteI )
+{
+ ((remote_Interface * )pRemoteI)->release( (remote_Interface * ) pRemoteI );
+}
+
+}
+
+namespace bridges_remote {
+
+void freeRemote2UnoProxy(uno_ExtEnvironment *, void * proxy) {
+ delete static_cast< Remote2UnoProxy * >(proxy);
+}
+
+void acquireRemote2UnoProxy( uno_Interface *pThis )
+{
+ Remote2UnoProxy *p = ( Remote2UnoProxy * ) pThis;
+ if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) )
+ {
+ p->m_pEnvUno->pExtEnv->registerProxyInterface(
+ p->m_pEnvUno->pExtEnv,
+ (void**)&pThis,
+ freeRemote2UnoProxy,
+ p->m_sOid.pData,
+ p->m_pType );
+ OSL_ASSERT( (uno_Interface *)p == pThis );
+ }
+}
+
+void releaseRemote2UnoProxy( uno_Interface *pThis )
+{
+ Remote2UnoProxy *p = ( Remote2UnoProxy * ) pThis;
+ if ( 0 == osl_decrementInterlockedCount( &(p->m_nRef) ))
+ {
+ p->m_pEnvUno->pExtEnv->revokeInterface( p->m_pEnvUno->pExtEnv, p );
+ }
+}
+
+void SAL_CALL dispatchRemote2UnoProxy(
+ uno_Interface * pUnoI,
+ typelib_TypeDescription const * pType,
+ void * pReturn,
+ void * ppArgs[],
+ uno_Any ** ppException )
+{
+ Remote2UnoProxy *p = ( Remote2UnoProxy * ) pUnoI;
+ RemoteThreadCounter counter( p->m_pEnvRemote );
+
+ typelib_InterfaceMethodTypeDescription *pMethodType = 0;
+ typelib_InterfaceAttributeTypeDescription *pAttributeType = 0;
+ typelib_TypeDescription *pReturnType = 0;
+ typelib_TypeDescription **ppArgType = 0;
+ sal_Int32 nArgCount = 0;
+ sal_Bool *pbIsIn = 0;
+ sal_Bool *pbIsOut = 0;
+ sal_Bool *pbConversionNeeded = 0;
+ sal_Bool bConversionNeededForReturn = 0;
+
+ //--------------------------------
+ // Collect all needed types !
+ //--------------------------------
+ if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pType->eTypeClass )
+ {
+ pAttributeType = ( typelib_InterfaceAttributeTypeDescription * ) pType;
+ if( pReturn )
+ {
+ TYPELIB_DANGER_GET( &pReturnType , pAttributeType->pAttributeTypeRef );
+ bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
+ }
+ else
+ {
+ nArgCount = 1;
+ ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) );
+ pbIsIn = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
+ pbIsOut = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
+ pbConversionNeeded = ( sal_Bool *) alloca( sizeof( sal_Bool ) );
+
+ pbIsIn[0] = sal_True;
+ pbIsOut[0] = sal_False;
+ ppArgType[0] = 0;
+ TYPELIB_DANGER_GET( &( ppArgType[0] ) , pAttributeType->pAttributeTypeRef );
+ pbConversionNeeded[0] = remote_relatesToInterface( ppArgType[0] );
+
+ }
+ }
+ if( typelib_TypeClass_INTERFACE_METHOD == pType->eTypeClass )
+ {
+ pMethodType = ( typelib_InterfaceMethodTypeDescription * ) pType;
+ TYPELIB_DANGER_GET( &pReturnType , pMethodType->pReturnTypeRef );
+ bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
+ nArgCount = pMethodType->nParams;
+ ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) * nArgCount );
+ pbIsIn = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
+ pbIsOut = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
+ pbConversionNeeded = ( sal_Bool *) alloca( sizeof( sal_Bool ) * nArgCount );
+ sal_Int32 i;
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ ppArgType[i] = 0;
+ TYPELIB_DANGER_GET( & (ppArgType[i]) , pMethodType->pParams[i].pTypeRef );
+ pbIsIn[i] = pMethodType->pParams[i].bIn;
+ pbIsOut[i] = pMethodType->pParams[i].bOut;
+ pbConversionNeeded[i] = remote_relatesToInterface( ppArgType[i] );
+ }
+ }
+
+ void *pRemoteReturn = 0;
+ if( pReturnType )
+ {
+ if( bConversionNeededForReturn )
+ {
+ pRemoteReturn = alloca( pReturnType->nSize );
+ }
+ else
+ {
+ pRemoteReturn = pReturn;
+ }
+ }
+
+ void ** ppRemoteArgs = 0;
+ if( nArgCount )
+ {
+ ppRemoteArgs = (void**) alloca( sizeof( void * ) * nArgCount );
+ }
+
+ sal_Int32 i;
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ if( pbConversionNeeded[i] )
+ {
+ ppRemoteArgs[i] = alloca( ppArgType[i]->nSize );
+
+ if( pbIsIn[i] ) {
+ uno_copyAndConvertData(
+ ppRemoteArgs[i],
+ ppArgs[i],
+ ppArgType[i],
+ p->m_mapUno2Remote.get() );
+ }
+ }
+ else
+ {
+ ppRemoteArgs[i] = ppArgs[i];
+ }
+ }
+
+ uno_Any any;
+ uno_Any *pAny = &any;
+
+ p->m_pRemoteI->pDispatcher( p->m_pRemoteI,
+ pType,
+ pRemoteReturn,
+ ppRemoteArgs,
+ &pAny );
+
+ if( ! pAny )
+ {
+ if( pReturn && bConversionNeededForReturn )
+ {
+ uno_copyAndConvertData(
+ pReturn ,
+ pRemoteReturn,
+ pReturnType,
+ p->m_mapRemote2Uno.get() );
+ uno_destructData( pRemoteReturn , pReturnType , remote_release );
+ }
+
+ sal_Int32 j;
+ for( j = 0 ; j < nArgCount ; j ++ )
+ {
+ if( pbConversionNeeded[j] )
+ {
+ if( pbIsIn[j] ) {
+ if( pbIsOut[j] ) {
+ uno_destructData( ppArgs[j] ,
+ ppArgType[j] ,
+ 0 );
+ uno_copyAndConvertData( ppArgs[j] ,
+ ppRemoteArgs[j],
+ ppArgType[j],
+ p->m_mapRemote2Uno.get() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( ppArgs[j] ,
+ ppRemoteArgs[j],
+ ppArgType[j],
+ p->m_mapRemote2Uno.get() );
+ }
+ uno_destructData( ppRemoteArgs[j],
+ ppArgType[j],
+ remote_release );
+ }
+ }
+ *ppException = 0;
+ }
+ else
+ {
+ // -----------------------
+ // an exception occured
+ // -----------------------
+ typelib_TypeDescription *pAnyType = 0;
+ getCppuType( (::com::sun::star::uno::Any*) 0 ).getDescription( &pAnyType );
+ uno_copyAndConvertData( *ppException ,
+ pAny ,
+ pAnyType,
+ p->m_mapRemote2Uno.get() );
+ uno_destructData( pAny , pAnyType , remote_release );
+ typelib_typedescription_release( pAnyType );
+
+ // destruct remote in parameters ( out parameters have not been constructed )
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ if( pbConversionNeeded[i] && pbIsIn[i] )
+ {
+ uno_destructData( ppRemoteArgs[i],
+ ppArgType[i],
+ remote_release );
+ }
+ }
+ }
+
+ //--------------------------
+ // release all acquired types
+ //--------------------------
+ if( pReturnType )
+ {
+ TYPELIB_DANGER_RELEASE( pReturnType );
+ }
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ TYPELIB_DANGER_RELEASE( ppArgType[ i] );
+ }
+
+}
+
+Remote2UnoProxy::Remote2UnoProxy( remote_Interface *pRemoteI,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pType,
+ uno_Environment *pEnvUno,
+ uno_Environment *pEnvRemote ) :
+ m_sOid( pOid ),
+ m_pType( pType ),
+ m_pRemoteI( pRemoteI ),
+ m_pEnvUno( pEnvUno ),
+ m_pEnvRemote( pEnvRemote ),
+ m_mapRemote2Uno( pEnvRemote, pEnvUno ),
+ m_mapUno2Remote( pEnvUno , pEnvRemote ),
+ m_nRef( 1 )
+{
+ typelib_typedescription_acquire( (typelib_TypeDescription * ) m_pType );
+ m_pEnvUno->acquire( m_pEnvUno );
+ m_pEnvRemote->acquire( m_pEnvRemote );
+
+ acquire = acquireRemote2UnoProxy;
+ release = releaseRemote2UnoProxy;
+ pDispatcher = dispatchRemote2UnoProxy;
+
+ m_pEnvRemote->pExtEnv->registerInterface(
+ m_pEnvRemote->pExtEnv,
+ (void**)&m_pRemoteI,
+ m_sOid.pData,
+ m_pType );
+ m_pRemoteI->acquire( m_pRemoteI );
+
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+Remote2UnoProxy::~Remote2UnoProxy()
+{
+ // revoke external ref (oid)
+ m_pEnvRemote->pExtEnv->revokeInterface( m_pEnvRemote->pExtEnv , m_pRemoteI );
+
+ typelib_typedescription_release( (typelib_TypeDescription * )m_pType );
+ m_pRemoteI->release( m_pRemoteI );
+ m_pEnvUno->release( m_pEnvUno );
+ m_pEnvRemote->release( m_pEnvRemote );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+}
+
+} // end namespace bridge_remote
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/static/remote.cxx b/bridges/source/remote/static/remote.cxx
new file mode 100644
index 000000000000..e94743469271
--- /dev/null
+++ b/bridges/source/remote/static/remote.cxx
@@ -0,0 +1,164 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <bridges/remote/remote.hxx>
+#include <bridges/remote/counter.hxx>
+
+#if OSL_DEBUG_LEVEL > 1
+static MyCounter thisCounter( "DEBUG : Remote2RemoteStub");
+#endif
+
+using namespace bridges_remote;
+
+extern "C" {
+
+static void SAL_CALL thisRelease( remote_Interface *pThis )
+{
+ Remote2RemoteStub *p = ( Remote2RemoteStub * ) pThis;
+ if (! osl_decrementInterlockedCount( &(p->m_nRef) ))
+ {
+ p->m_pEnvRemote->pExtEnv->revokeInterface( p->m_pEnvRemote->pExtEnv, pThis );
+
+ }
+}
+
+static void SAL_CALL thisDispatch(
+ remote_Interface * pRemoteI,
+ typelib_TypeDescription const * pMemberType,
+ void * pReturn,
+ void * pArgs[],
+ uno_Any ** ppException )
+{
+ Remote2RemoteStub *pThis = ( Remote2RemoteStub * ) pRemoteI;
+
+ pThis->m_dispatch( pThis->m_pEnvRemote,
+ pMemberType,
+ pThis->m_sOid.pData,
+ pThis->m_pType,
+ pReturn,
+ pArgs,
+ ppException );
+}
+
+}
+
+namespace bridges_remote {
+
+void acquireRemote2RemoteStub( remote_Interface *pThis )
+{
+ Remote2RemoteStub *p = ( Remote2RemoteStub * ) pThis;
+ if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) )
+ {
+ p->m_pEnvRemote->pExtEnv->registerProxyInterface(
+ p->m_pEnvRemote->pExtEnv,
+ (void**)&pThis,
+ freeRemote2RemoteStub,
+ p->m_sOid.pData,
+ p->m_pType );
+ OSL_ASSERT( (remote_Interface *)p == pThis );
+ }
+}
+
+void freeRemote2RemoteStub(uno_ExtEnvironment *, void * stub) {
+ delete static_cast< Remote2RemoteStub * >(stub);
+}
+
+Remote2RemoteStub::Remote2RemoteStub( rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pType,
+ uno_Environment *pEnvRemote,
+ requestClientSideDispatcher dispatch ) :
+ m_sOid( pOid ),
+ m_pType( (typelib_InterfaceTypeDescription * ) pType ),
+ m_nRef( 1 ),
+ m_pEnvRemote( pEnvRemote ),
+ m_dispatch( dispatch ),
+ m_nReleaseRemote( 1 )
+{
+ typelib_typedescription_acquire( ( typelib_TypeDescription * ) m_pType );
+ m_pEnvRemote->acquire( m_pEnvRemote );
+
+ acquire = acquireRemote2RemoteStub;
+ release = thisRelease;
+ pDispatcher = thisDispatch;
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+Remote2RemoteStub::~Remote2RemoteStub()
+{
+
+ // send a release via the connection !
+ sal_Bool bNeedsRelease = sal_False;
+ if( ! m_pType->aBase.bComplete )
+ {
+ // m_pType may be exchanged during complete, so it needs to be acquired
+ // (MT : Another thread may use m_pType during e.g. dispatch ! ).
+ typelib_typedescription_acquire( (typelib_TypeDescription*)m_pType );
+ bNeedsRelease = sal_True;
+ typelib_typedescription_complete( (typelib_TypeDescription **) &m_pType );
+ }
+
+ uno_Any any;
+ uno_Any *pAny = &any;
+
+ typelib_TypeDescription *pReleaseMethod = 0;
+ typelib_typedescriptionreference_getDescription(
+ &pReleaseMethod ,
+ m_pType->ppAllMembers[REMOTE_RELEASE_METHOD_INDEX] );
+ for( int i = 0 ; i < m_nReleaseRemote ; i ++ )
+ {
+ thisDispatch( this,
+ pReleaseMethod,
+ 0,
+ 0,
+ &pAny );
+ }
+ typelib_typedescription_release( pReleaseMethod );
+ if( bNeedsRelease )
+ {
+ typelib_typedescription_release( (typelib_TypeDescription * ) m_pType );
+ }
+
+ typelib_typedescription_release( (typelib_TypeDescription * ) m_pType );
+ m_pEnvRemote->release( m_pEnvRemote );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+}
+
+void Remote2RemoteStub::releaseRemote()
+{
+ osl_incrementInterlockedCount( &m_nReleaseRemote );
+}
+
+} // end namespace bridges_remote
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/static/remote_types.cxx b/bridges/source/remote/static/remote_types.cxx
new file mode 100644
index 000000000000..f47580d8da92
--- /dev/null
+++ b/bridges/source/remote/static/remote_types.cxx
@@ -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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include "remote_types.hxx"
+
+namespace bridges_remote {
+
+sal_Bool SAL_CALL remote_relatesToInterface2( typelib_TypeDescription * pTypeDescr )
+{
+ switch (pTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_SEQUENCE:
+ {
+ switch (((typelib_IndirectTypeDescription *)pTypeDescr)->pType->eTypeClass)
+ {
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType );
+ sal_Bool bRel = remote_relatesToInterface( pTD );
+ TYPELIB_DANGER_RELEASE( pTD );
+ return bRel;
+ }
+ default:
+ break;
+ }
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ // ...optimized... to avoid getDescription() calls!
+ typelib_CompoundTypeDescription * pComp = (typelib_CompoundTypeDescription *)pTypeDescr;
+ typelib_TypeDescriptionReference ** pTypes = pComp->ppTypeRefs;
+ for ( sal_Int32 nPos = pComp->nMembers; nPos--; )
+ {
+ switch (pTypes[nPos]->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE:
+ case typelib_TypeClass_UNION: // might relate to interface
+ case typelib_TypeClass_ANY: // might relate to interface
+ return sal_True;
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, pTypes[nPos] );
+ sal_Bool bRel = remote_relatesToInterface( pTD );
+ TYPELIB_DANGER_RELEASE( pTD );
+ if (bRel)
+ return sal_True;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ if (pComp->pBaseTypeDescription)
+ return remote_relatesToInterface( (typelib_TypeDescription *)pComp->pBaseTypeDescription );
+ break;
+ }
+ default:
+ OSL_ASSERT( 0 );
+ }
+ return sal_False;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/static/remote_types.hxx b/bridges/source/remote/static/remote_types.hxx
new file mode 100644
index 000000000000..9325cbc18167
--- /dev/null
+++ b/bridges/source/remote/static/remote_types.hxx
@@ -0,0 +1,92 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+#ifndef _BRIDGES_REMOTE_TYPES_HXX_
+#define _BRIDGES_REMOTE_TYPES_HXX_
+
+#include <osl/diagnose.h>
+#include <sal/types.h>
+#include <typelib/typedescription.h>
+
+namespace bridges_remote
+{
+
+inline sal_Bool SAL_CALL remote_relatesToInterface( typelib_TypeDescription *pTypeDescr );
+sal_Bool SAL_CALL remote_relatesToInterface2( typelib_TypeDescription * pTypeDescr );
+
+
+/** Determines whether given type might relate or relates to an interface,
+ i.e. values of this type are interface or may contain interface(s).<br>
+ @param pTypeDescr type description of type
+ @return true if type might relate to an interface, false otherwise
+*/
+inline sal_Bool SAL_CALL remote_relatesToInterface( typelib_TypeDescription * pTypeDescr )
+{
+ switch (pTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_SEQUENCE:
+ switch (((typelib_IndirectTypeDescription *)pTypeDescr)->pType->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE:
+ case typelib_TypeClass_UNION: // might relate to interface
+ case typelib_TypeClass_ANY: // might relate to interface
+ return sal_True;
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ return remote_relatesToInterface2( pTypeDescr );
+ default:
+ return sal_False;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ return remote_relatesToInterface2( pTypeDescr );
+ case typelib_TypeClass_UNION: // might relate to interface
+ case typelib_TypeClass_ANY: // might relate to interface
+ case typelib_TypeClass_INTERFACE:
+ return sal_True;
+ default:
+ return sal_False;
+ }
+}
+
+/** Determines whether given type is a cpp simple type, e.g. int, enum.<br>
+ @param pTypeDescr type description of type
+ @return true if type is a cpp simple type, false otherwise
+*/
+inline sal_Bool SAL_CALL remote_isSimpleType( typelib_TypeDescription * pTypeDescr )
+{
+ return (pTypeDescr->eTypeClass <= typelib_TypeClass_ENUM &&
+ pTypeDescr->eTypeClass != typelib_TypeClass_STRING &&
+ pTypeDescr->eTypeClass != typelib_TypeClass_ANY &&
+ pTypeDescr->eTypeClass != typelib_TypeClass_TYPE);
+}
+
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/static/stub.cxx b/bridges/source/remote/static/stub.cxx
new file mode 100644
index 000000000000..58796351d5bd
--- /dev/null
+++ b/bridges/source/remote/static/stub.cxx
@@ -0,0 +1,339 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <sal/alloca.h>
+#include <osl/diagnose.h>
+
+#include <uno/data.h>
+#include <uno/mapping.hxx>
+
+#include <bridges/remote/stub.hxx>
+#include <bridges/remote/proxy.hxx>
+#include <bridges/remote/context.h>
+#include <bridges/remote/bridgeimpl.hxx>
+
+#include "remote_types.hxx"
+
+#if OSL_DEBUG_LEVEL > 1
+#include <bridges/remote/counter.hxx>
+static MyCounter thisCounter( "DEBUG : Uno2RemoteStub");
+#endif
+
+using namespace ::com::sun::star::uno;
+using namespace bridges_remote;
+
+extern "C" {
+
+void SAL_CALL thisRelease( remote_Interface *pThis )
+{
+ Uno2RemoteStub *p = ( Uno2RemoteStub * ) pThis;
+ if (! osl_decrementInterlockedCount( &(p->m_nRef) ))
+ {
+ p->m_pEnvRemote->pExtEnv->revokeInterface( p->m_pEnvRemote->pExtEnv, pThis );
+ }
+}
+
+void SAL_CALL thisDispatch(
+ remote_Interface * pRemoteI,
+ typelib_TypeDescription const * pType,
+ void * pReturn,
+ void * ppArgs[],
+ uno_Any ** ppException )
+{
+ Uno2RemoteStub *p = ( Uno2RemoteStub * ) pRemoteI;
+
+ RemoteThreadCounter counter( p->m_pEnvRemote );
+
+ typelib_InterfaceMethodTypeDescription *pMethodType = 0;
+ typelib_InterfaceAttributeTypeDescription *pAttributeType = 0;
+ typelib_TypeDescription *pReturnType = 0;
+ typelib_TypeDescription **ppArgType = 0;
+ sal_Int32 nArgCount = 0;
+ sal_Bool *pbIsIn = 0;
+ sal_Bool *pbIsOut = 0;
+ sal_Bool bConversionNeededForReturn = sal_False;
+ sal_Bool *pbConversionNeeded = 0;
+
+ sal_Int32 i;
+ //--------------------------------
+ // Collect all needed types !
+ //--------------------------------
+ if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pType->eTypeClass )
+ {
+ pAttributeType = ( typelib_InterfaceAttributeTypeDescription * ) pType;
+ if( pReturn )
+ {
+ TYPELIB_DANGER_GET( &pReturnType , pAttributeType->pAttributeTypeRef );
+ bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
+ }
+ else
+ {
+ nArgCount = 1;
+ ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) );
+ pbIsIn = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
+ pbIsOut = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
+ pbConversionNeeded = ( sal_Bool * ) alloca( sizeof( sal_Bool ) );
+ pbIsIn[0] = sal_True;
+ pbIsOut[0] = sal_False;
+ ppArgType[0] = 0;
+ TYPELIB_DANGER_GET( &( ppArgType[0] ) , pAttributeType->pAttributeTypeRef );
+ pbConversionNeeded[0] = remote_relatesToInterface( ppArgType[0] );
+ }
+ }
+ if( typelib_TypeClass_INTERFACE_METHOD == pType->eTypeClass )
+ {
+ pMethodType = ( typelib_InterfaceMethodTypeDescription * ) pType;
+ TYPELIB_DANGER_GET( &pReturnType , pMethodType->pReturnTypeRef );
+ bConversionNeededForReturn = remote_relatesToInterface( pReturnType );
+ nArgCount = pMethodType->nParams;
+ ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) * nArgCount );
+ pbIsIn = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
+ pbIsOut = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
+ pbConversionNeeded = ( sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount );
+
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ ppArgType[i] = 0;
+ TYPELIB_DANGER_GET( & (ppArgType[i]) , pMethodType->pParams[i].pTypeRef );
+ pbIsIn[i] = pMethodType->pParams[i].bIn;
+ pbIsOut[i] = pMethodType->pParams[i].bOut;
+ pbConversionNeeded[i] = remote_relatesToInterface( ppArgType[i] );
+ }
+ }
+
+ // create Mapping
+
+ void *pUnoReturn = 0;
+ void **ppUnoArgs = 0;
+
+ if( pReturnType )
+ {
+ if( bConversionNeededForReturn )
+ {
+ pUnoReturn = alloca( pReturnType->nSize );
+ }
+ else
+ {
+ pUnoReturn = pReturn;
+ }
+ }
+
+ ppUnoArgs = (void **) alloca( nArgCount * sizeof( void * ) );
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ if( pbConversionNeeded[i] )
+ {
+ ppUnoArgs[i] = alloca( ppArgType[i]->nSize );
+ if( pbIsIn[i] )
+ {
+ uno_copyAndConvertData(
+ ppUnoArgs[i],
+ ppArgs[i],
+ ppArgType[i],
+ p->m_mapRemote2Uno.get()
+ );
+ }
+ }
+ else
+ {
+ ppUnoArgs[i] = ppArgs[i];
+ }
+ }
+
+ // do the call
+ uno_Any any;
+ uno_Any *pAny = &any;
+
+ p->m_pUnoI->pDispatcher( p->m_pUnoI,
+ pType,
+ pUnoReturn,
+ ppUnoArgs,
+ &pAny);
+
+ if( ! pAny )
+ {
+ // ------------------
+ // No Exception
+ // ------------------
+
+ // Map return value
+ if( pReturnType && bConversionNeededForReturn )
+ {
+ uno_copyAndConvertData(
+ pReturn ,
+ pUnoReturn,
+ pReturnType,
+ p->m_mapUno2Remote.get() );
+ uno_destructData( pUnoReturn , pReturnType, 0 );
+ }
+
+ // map arguments
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ if( pbConversionNeeded[i] )
+ {
+ if( pbIsIn[i] ) {
+ if( pbIsOut[i] ) {
+ uno_destructData(
+ ppArgs[i] ,
+ ppArgType[i] ,
+ remote_release );
+ uno_copyAndConvertData( ppArgs[i] ,
+ ppUnoArgs[i],
+ ppArgType[i],
+ p->m_mapUno2Remote.get() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( ppArgs[i] ,
+ ppUnoArgs[i],
+ ppArgType[i],
+ p->m_mapUno2Remote.get() );
+ }
+ uno_destructData( ppUnoArgs[i],
+ ppArgType[i],
+ 0 );
+ }
+ }
+ *ppException = 0;
+ }
+ else
+ {
+ // -----------------------
+ // an exception occured
+ // -----------------------
+ typelib_TypeDescription *pAnyType = 0;
+ getCppuType( (Any*) 0 ).getDescription( &pAnyType );
+ uno_copyAndConvertData( *ppException ,
+ pAny ,
+ pAnyType,
+ p->m_mapUno2Remote.get() );
+ uno_destructData( pAny , pAnyType , 0 );
+ typelib_typedescription_release( pAnyType );
+
+ // destruct uno in parameters ( out parameters have not been constructed )
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ if( pbConversionNeeded[i] && pbIsIn[i] )
+ {
+ uno_destructData( ppUnoArgs[i],
+ ppArgType[i],
+ 0 );
+ }
+ }
+ }
+
+ //--------------------------
+ // release all acquired types
+ //--------------------------
+ if( pReturnType )
+ {
+ TYPELIB_DANGER_RELEASE( pReturnType );
+ }
+ for( i = 0 ; i < nArgCount ; i ++ )
+ {
+ TYPELIB_DANGER_RELEASE( ppArgType[ i] );
+ }
+}
+
+}
+
+namespace bridges_remote {
+
+void acquireUno2RemoteStub( remote_Interface *pThis )
+{
+ Uno2RemoteStub *p = ( Uno2RemoteStub * ) pThis;
+ if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) )
+ {
+
+ p->m_pEnvRemote->pExtEnv->registerProxyInterface(
+ p->m_pEnvRemote->pExtEnv,
+ (void**)&pThis,
+ freeUno2RemoteStub,
+ p->m_sOid.pData,
+ p->m_pType );
+
+ OSL_ASSERT( (remote_Interface*) p == pThis );
+ }
+}
+
+void freeUno2RemoteStub(uno_ExtEnvironment *, void * stub) {
+ delete static_cast< Uno2RemoteStub * >(stub);
+}
+
+Uno2RemoteStub::Uno2RemoteStub( uno_Interface *pUnoI,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pType,
+ uno_Environment *pEnvUno,
+ uno_Environment *pEnvRemote ) :
+ m_sOid( pOid ),
+ m_pType( pType ),
+ m_pUnoI( pUnoI ),
+ m_nRef( 1 ),
+ m_pEnvUno( pEnvUno ),
+ m_pEnvRemote( pEnvRemote ),
+ m_mapRemote2Uno( pEnvRemote, pEnvUno ),
+ m_mapUno2Remote( pEnvUno, pEnvRemote )
+{
+ typelib_typedescription_acquire( (typelib_TypeDescription * )m_pType );
+ m_pEnvUno->acquire( m_pEnvUno );
+ m_pEnvRemote->acquire( m_pEnvRemote );
+
+ acquire = acquireUno2RemoteStub;
+ release = thisRelease;
+ pDispatcher = thisDispatch;
+
+ m_pEnvUno->pExtEnv->registerInterface( m_pEnvUno->pExtEnv,
+ (void **)&m_pUnoI,
+ m_sOid.pData,
+ m_pType );
+ m_pUnoI->acquire( m_pUnoI );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+Uno2RemoteStub::~Uno2RemoteStub()
+{
+ m_pEnvUno->pExtEnv->revokeInterface( m_pEnvUno->pExtEnv , m_pUnoI );
+
+ typelib_typedescription_release( (typelib_TypeDescription * )m_pType );
+ m_pUnoI->release( m_pUnoI );
+ m_pEnvUno->release( m_pEnvUno );
+ m_pEnvRemote->release( m_pEnvRemote );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+}
+
+} // end namespace bridges_remote
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/makefile.mk b/bridges/source/remote/urp/makefile.mk
new file mode 100644
index 000000000000..eaa3f3a6f146
--- /dev/null
+++ b/bridges/source/remote/urp/makefile.mk
@@ -0,0 +1,78 @@
+#*************************************************************************
+#
+# 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=urp_uno
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/urp_environment.obj \
+ $(SLO)$/urp_marshal.obj \
+ $(SLO)$/urp_unmarshal.obj \
+ $(SLO)$/urp_dispatch.obj \
+ $(SLO)$/urp_job.obj \
+ $(SLO)$/urp_reader.obj \
+ $(SLO)$/urp_writer.obj \
+ $(SLO)$/urp_log.obj \
+ $(SLO)$/urp_bridgeimpl.obj \
+ $(SLO)$/urp_propertyobject.obj \
+ $(SLO)$/urp_threadid.obj
+
+.IF "$(COM)"=="GCC"
+NOOPTFILES= \
+ $(SLO)$/urp_reader.obj
+.ENDIF # "$(COM)"=="GCC"
+
+SHL1TARGET= $(TARGET)
+
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1VERSIONMAP=..$/..$/bridge_exports.map
+SHL1RPATH=URELIB
+
+SHL1STDLIBS=\
+ $(SALLIB)\
+ $(CPPULIB)
+
+SHL1LIBS=\
+ $(SLB)$/$(TARGET).lib \
+ $(SLB)$/bridges_remote_static.lib
+
+DEF1NAME= $(SHL1TARGET)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/source/remote/urp/urp_bridgeimpl.cxx b/bridges/source/remote/urp/urp_bridgeimpl.cxx
new file mode 100644
index 000000000000..0e25746f0a42
--- /dev/null
+++ b/bridges/source/remote/urp/urp_bridgeimpl.cxx
@@ -0,0 +1,253 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <osl/thread.h>
+#include <bridges/remote/helper.hxx>
+
+#include <algorithm>
+
+#include "urp_bridgeimpl.hxx"
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+namespace bridges_urp
+{
+
+template < class t >
+inline t mymin( const t & val1, const t & val2 )
+{
+ return val1 < val2 ? val1 : val2;
+}
+
+/***********
+ * urp_BridgeImpl
+ ***********/
+urp_BridgeImpl::urp_BridgeImpl( sal_Int32 nCacheSize , sal_uInt32 nInitialMarshalerSize ) :
+ m_blockMarshaler( this , nInitialMarshalerSize , ::bridges_remote::remote_retrieveOidFromProxy),
+ m_nMarshaledMessages( 0 ),
+ m_oidCacheOut( (sal_uInt16)nCacheSize ),
+ m_tidCacheOut( (sal_uInt16)nCacheSize ),
+ m_typeCacheOut( (sal_uInt16)nCacheSize )
+{
+ m_pOidIn = new OUString[ nCacheSize ];
+ m_pTidIn = new ByteSequence[ nCacheSize ];
+ m_pTypeIn = new Type[ nCacheSize ];
+ m_nRemoteThreads = 0;
+}
+
+urp_BridgeImpl::~urp_BridgeImpl()
+{
+ delete [] m_pOidIn;
+ delete [] m_pTidIn;
+ delete [] m_pTypeIn;
+}
+
+
+void urp_BridgeImpl::applyProtocolChanges( const Properties &props )
+{
+ if( m_properties.nTypeCacheSize != props.nTypeCacheSize )
+ {
+ if( props.nTypeCacheSize == 0 )
+ {
+ delete [] m_pTypeIn;
+ m_pTypeIn = 0;
+ }
+ else
+ {
+ Type *pNew = new Type[props.nTypeCacheSize];
+ sal_Int32 i;
+ sal_Int32 iMin = mymin( m_properties.nTypeCacheSize , props.nTypeCacheSize );
+ for( i = 0; i < iMin ; i ++ )
+ {
+ pNew[i] = m_pTypeIn[i];
+ }
+ delete [] m_pTypeIn;
+ m_pTypeIn = pNew;
+ }
+ OSL_ASSERT( props.nTypeCacheSize <= 0xffff );
+ m_properties.nTypeCacheSize = props.nTypeCacheSize;
+ m_typeCacheOut.resize( (sal_uInt16)props.nTypeCacheSize );
+ }
+
+ if( m_properties.nOidCacheSize != props.nOidCacheSize )
+ {
+ if( 0 == props.nOidCacheSize )
+ {
+ delete [] m_pOidIn;
+ m_pOidIn = 0;
+ }
+ else
+ {
+ OUString *pNew = new OUString[props.nOidCacheSize];
+ sal_Int32 i;
+ sal_Int32 iMin = mymin( m_properties.nOidCacheSize , props.nOidCacheSize );
+ for( i = 0; i < iMin ; i ++ )
+ {
+ pNew[i] = m_pOidIn[i];
+ }
+ delete [] m_pOidIn;
+ m_pOidIn = pNew;
+ }
+ OSL_ASSERT( props.nOidCacheSize <= 0xffff );
+ m_oidCacheOut.resize( (sal_uInt16)props.nOidCacheSize );
+ m_properties.nOidCacheSize = props.nOidCacheSize;
+ }
+
+ if( m_properties.nTidCacheSize != props.nTidCacheSize )
+ {
+ if( 0 == props.nTidCacheSize )
+ {
+ delete [] m_pTidIn;
+ m_pTidIn = 0;
+ }
+ else
+ {
+ ByteSequence *pNew = new ByteSequence[props.nTidCacheSize];
+ sal_Int32 i;
+ sal_Int32 iMin = mymin( m_properties.nTidCacheSize , props.nTidCacheSize );
+ for( i = 0; i < iMin ; i ++ )
+ {
+ pNew[i] = m_pTidIn[i];
+ }
+ delete [] m_pTidIn;
+ m_pTidIn = pNew;
+ }
+ OSL_ASSERT( props.nTidCacheSize <= 0xffff );
+ m_tidCacheOut.resize( (sal_uInt16)props.nTidCacheSize );
+ m_properties.nTidCacheSize = props.nTidCacheSize;
+ }
+
+ if( m_properties.sVersion != props.sVersion )
+ {
+ m_properties.sVersion = props.sVersion;
+ }
+
+ if( m_properties.nFlushBlockSize != props.nFlushBlockSize )
+ {
+ m_properties.nFlushBlockSize = props.nFlushBlockSize;
+ }
+
+ if( m_properties.nOnewayTimeoutMUSEC != props.nOnewayTimeoutMUSEC )
+ {
+ m_properties.nOnewayTimeoutMUSEC = props.nOnewayTimeoutMUSEC;
+ }
+
+ if( props.bClearCache )
+ {
+ if( m_properties.nTypeCacheSize )
+ {
+ delete [] m_pTypeIn;
+ m_pTypeIn = new Type[m_properties.nTypeCacheSize];
+ m_typeCacheOut.clear();
+ }
+ m_lastInType = Type();
+ m_lastOutType = Type();
+
+ if( m_properties.nOidCacheSize )
+ {
+ delete [] m_pOidIn;
+ m_pOidIn = new OUString[ m_properties.nOidCacheSize];
+ m_oidCacheOut.clear();
+ }
+ m_lastOutOid = OUString();
+ m_lastInOid = OUString();
+
+ if( m_properties.nTidCacheSize )
+ {
+ delete [] m_pTidIn;
+ m_pTidIn = new ByteSequence[m_properties.nTidCacheSize];
+ m_tidCacheOut.clear();
+ }
+ m_lastInTid = ByteSequence();
+ m_lastOutTid = ByteSequence();
+ }
+
+ if( m_properties.bNegotiate != props.bNegotiate )
+ {
+ m_properties.bNegotiate = props.bNegotiate;
+ }
+
+ if( m_properties.bForceSynchronous != props.bForceSynchronous )
+ {
+ m_properties.bForceSynchronous = props.bForceSynchronous;
+ }
+
+ m_properties.bCurrentContext = props.bCurrentContext;
+}
+
+void urp_BridgeImpl::addError( char const *pError )
+{
+ OUString message = OUString(RTL_CONSTASCII_USTRINGPARAM("(tid=" ));
+ message += OUString::valueOf( (sal_Int32 ) osl_getThreadIdentifier( 0 ) );
+ message += OUString(RTL_CONSTASCII_USTRINGPARAM(") "));
+ message += OUString::createFromAscii( pError );
+ MutexGuard guard( m_errorListMutex );
+ m_lstErrors.push_back( message );
+}
+
+void urp_BridgeImpl::addError( const OUString & error )
+{
+ OUString message = OUString(RTL_CONSTASCII_USTRINGPARAM("(tid="));
+ message += OUString::valueOf( (sal_Int32 ) osl_getThreadIdentifier( 0 ) );
+ message += OUString(RTL_CONSTASCII_USTRINGPARAM(") "));
+ message += error;
+ MutexGuard guard( m_errorListMutex );
+ m_lstErrors.push_back( message );
+}
+
+void urp_BridgeImpl::dumpErrors( FILE * f)
+{
+ MutexGuard guard( m_errorListMutex );
+ for( ::std::list< OUString >::iterator ii = m_lstErrors.begin() ;
+ ii != m_lstErrors.end() ;
+ ++ii )
+ {
+ OString o = OUStringToOString( *ii , RTL_TEXTENCODING_UTF8 );
+ fprintf( f, "%s\n" , o.getStr() );
+ }
+}
+
+OUString urp_BridgeImpl::getErrorsAsString( )
+{
+ MutexGuard guard( m_errorListMutex );
+ OUString ret;
+ for( ::std::list< OUString >::iterator ii = m_lstErrors.begin() ;
+ ii != m_lstErrors.end() ;
+ ++ii )
+ {
+ ret += *ii;
+ }
+ return ret;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_bridgeimpl.hxx b/bridges/source/remote/urp/urp_bridgeimpl.hxx
new file mode 100644
index 000000000000..4e6d31d22505
--- /dev/null
+++ b/bridges/source/remote/urp/urp_bridgeimpl.hxx
@@ -0,0 +1,130 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+#ifndef _URP_BRIDGEIMPL_HXX_
+#define _URP_BRIDGEIMPL_HXX_
+
+#include <stdio.h>
+#include <osl/mutex.hxx>
+#include <osl/conditn.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/byteseq.hxx>
+
+#include <uno/threadpool.h>
+#include <bridges/remote/bridgeimpl.hxx>
+
+#include "urp_cache.hxx"
+#include "urp_marshal_decl.hxx"
+
+#include "urp_replycontainer.hxx"
+#include "urp_property.hxx"
+
+
+namespace bridges_urp
+{
+
+class PropertyObject;
+
+struct equalOUString
+{
+ sal_Int32 operator() ( const ::rtl::OUString &s1, const ::rtl::OUString &s2 ) const
+ {
+ return s1 == s2;
+ }
+};
+
+struct equalType
+{
+ sal_Int32 operator() ( const ::com::sun::star::uno::Type &t1,
+ const ::com::sun::star::uno::Type &t2 ) const
+ {
+ return t1 == t2;
+ }
+};
+
+class OWriterThread;
+class OReaderThread;
+
+struct urp_BridgeImpl :
+ public remote_BridgeImpl
+{
+ urp_BridgeImpl( sal_Int32 nCacheSize , sal_uInt32 nInitialMarshalerSize );
+ ~urp_BridgeImpl();
+
+ void applyProtocolChanges( const Properties & );
+
+ void startBlockBridge();
+ void stopBlockBridge();
+ void addError( char const *pError );
+ void addError( const ::rtl::OUString &anError );
+ void dumpErrors( FILE *f );
+ ::rtl::OUString getErrorsAsString();
+
+ ::osl::Mutex m_marshalingMutex;
+ ::osl::Mutex m_disposingMutex;
+ ::osl::Mutex m_errorListMutex;
+ Marshal m_blockMarshaler;
+ sal_Int32 m_nMarshaledMessages;
+
+ // Caches for vars, that go from local process to the remote process
+ Cache < ::rtl::OUString , equalOUString > m_oidCacheOut;
+ Cache < ::rtl::ByteSequence , EqualThreadId > m_tidCacheOut;
+ Cache < ::com::sun::star::uno::Type , equalType > m_typeCacheOut;
+
+ ::com::sun::star::uno::Type m_lastOutType;
+ ::rtl::ByteSequence m_lastOutTid;
+ ::rtl::OUString m_lastOutOid;
+
+ // Caches for vars, that come from the remote process to the local process
+ ::rtl::OUString *m_pOidIn;
+ ::rtl::ByteSequence *m_pTidIn;
+ ::com::sun::star::uno::Type *m_pTypeIn;
+
+ ::com::sun::star::uno::Type m_lastInType;
+ ::rtl::ByteSequence m_lastInTid;
+ ::rtl::OUString m_lastInOid;
+
+ urp_ClientJobContainer m_clientJobContainer;
+
+ OWriterThread *m_pWriter;
+ OReaderThread *m_pReader;
+ ::rtl::OString m_sLogFileName;
+ FILE *m_pLogFile;
+ ::osl::Condition m_initialized;
+ ::osl::Condition m_cndWaitForThreads;
+
+ struct Properties m_properties;
+ class PropertyObject *m_pPropertyObject;
+ ::std::list< ::rtl::OUString > m_lstErrors;
+ uno_ThreadPool m_hThreadPool;
+};
+
+
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_cache.h b/bridges/source/remote/urp/urp_cache.h
new file mode 100644
index 000000000000..a0150c854594
--- /dev/null
+++ b/bridges/source/remote/urp/urp_cache.h
@@ -0,0 +1,60 @@
+/* -*- 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 bridges_urp
+{
+ template < class t , class tequals >
+ class Cache
+ {
+ public:
+ inline Cache ( sal_uInt16 nMaxEntries );
+ inline ~Cache();
+
+ // puts the value t into the cache. Returns then entry,
+ // that is used for this value.
+ inline sal_uInt16 put( const t & );
+
+ // lookup, if there is an entry for this value
+ // returns 0xffff, when value cannot be found in the list
+ inline sal_uInt16 seek( const t & );
+
+ // resizes the cache, conserving overlapping values
+ inline void resize( sal_uInt16 nNewMaxEntries );
+
+ // empties the cache
+ inline void clear();
+ private:
+ t *m_pCache;
+ ::std::list< sal_uInt16 > m_lstLeastRecentlyUsed;
+ sal_uInt16 m_nMaxEntries;
+ sal_uInt16 m_nEntries;
+ };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_cache.hxx b/bridges/source/remote/urp/urp_cache.hxx
new file mode 100644
index 000000000000..5aec834199be
--- /dev/null
+++ b/bridges/source/remote/urp/urp_cache.hxx
@@ -0,0 +1,163 @@
+/* -*- 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 <stdio.h>
+#include <list>
+#include <algorithm>
+#include <rtl/ustring.hxx>
+
+#include "urp_threadid.hxx"
+#include "urp_cache.h"
+
+namespace bridges_urp
+{
+
+ template < class t , class tequals >
+ inline Cache< t , tequals >::Cache( sal_uInt16 nMaxEntries ) :
+ m_pCache( new t[nMaxEntries] ),
+ m_nMaxEntries( nMaxEntries ),
+ m_nEntries( 0 )
+ {
+
+ }
+
+ template < class t , class tequals >
+ inline Cache< t , tequals >::~Cache( )
+ {
+ delete [] m_pCache;
+ }
+
+
+ template < class t , class tequals >
+ inline sal_uInt16 Cache< t , tequals >::put( const t & value )
+ {
+ if( ! m_nMaxEntries )
+ {
+ return 0xffff;
+ }
+ sal_uInt16 nEntry = 0xffff;
+ if( m_nEntries < m_nMaxEntries )
+ {
+ // cache has still empty places
+ m_pCache[m_nEntries] = value;
+ nEntry = m_nEntries;
+ m_nEntries ++;
+
+ // add it to the cache
+ m_lstLeastRecentlyUsed.push_front( nEntry );
+ }
+ else
+ {
+ // cache is full, remove an element and insert the new one
+ nEntry = m_lstLeastRecentlyUsed.back();
+ m_lstLeastRecentlyUsed.pop_back();
+ m_lstLeastRecentlyUsed.push_front( nEntry );
+
+ m_pCache[nEntry] = value;
+ }
+ return nEntry;
+ }
+
+ template < class t , class tequals >
+ inline sal_uInt16 Cache< t , tequals >::seek( const t & value )
+ {
+ for( ::std::list< sal_uInt16 >::iterator ii = m_lstLeastRecentlyUsed.begin() ;
+ ii != m_lstLeastRecentlyUsed.end() ;
+ ++ ii )
+ {
+ if( value == m_pCache[*ii] )
+ {
+ sal_uInt16 nEntry = *ii;
+ m_lstLeastRecentlyUsed.erase( ii );
+ m_lstLeastRecentlyUsed.push_front( nEntry );
+ return nEntry;
+ }
+ }
+ return 0xffff;
+ }
+
+ // helper predicate for element removal
+ template < class t >
+ struct PredicateOverMax
+ {
+ t m_;
+ inline PredicateOverMax( const t &value ) : m_(value)
+ {}
+ sal_Int32 operator () ( const t &value ) const
+ { return value >= m_; }
+ };
+
+ template < class t, class tequals >
+ inline void Cache < t , tequals >::resize( sal_uInt16 nNewMaxEntries )
+ {
+ if( 0 == nNewMaxEntries )
+ {
+ m_lstLeastRecentlyUsed.clear();
+ delete [] m_pCache;
+ m_pCache = 0;
+ m_nMaxEntries = 0;
+ }
+ else
+ {
+ // allocate
+ t *pNew = new t[nNewMaxEntries];
+ sal_Int32 nMin = nNewMaxEntries < m_nMaxEntries ? nNewMaxEntries : m_nMaxEntries;
+
+ // copy
+ for( sal_Int32 i = 0; i < nMin ; i ++ )
+ {
+ pNew[i] = m_pCache[i];
+ }
+ // delete
+ delete [] m_pCache;
+
+ // assign
+ m_pCache = pNew;
+
+ // remove overlapping lru cache entries
+ ::std::remove_if(m_lstLeastRecentlyUsed.begin(),
+ m_lstLeastRecentlyUsed.end(),
+ PredicateOverMax< sal_Int32 > ( nMin ) );
+ }
+ m_nMaxEntries = nNewMaxEntries;
+ m_nEntries = m_nEntries < m_nMaxEntries ?
+ m_nEntries : m_nMaxEntries;
+ }
+
+ template < class t, class tequals >
+ inline void Cache < t, tequals >:: clear()
+ {
+ for( sal_Int32 i = 0; i < m_nMaxEntries ; i ++ )
+ {
+ m_pCache[i] = t();
+ }
+ m_lstLeastRecentlyUsed.clear();
+ m_nEntries = 0;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_dispatch.cxx b/bridges/source/remote/urp/urp_dispatch.cxx
new file mode 100644
index 000000000000..459900b2460a
--- /dev/null
+++ b/bridges/source/remote/urp/urp_dispatch.cxx
@@ -0,0 +1,118 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <sal/alloca.h>
+#include <osl/mutex.hxx>
+#include <osl/diagnose.h>
+
+#include <rtl/alloc.h>
+#include <rtl/ustrbuf.hxx>
+
+#include <uno/mapping.hxx>
+#include <uno/threadpool.h>
+
+#include <bridges/remote/remote.h>
+#include <bridges/remote/stub.hxx>
+#include <bridges/remote/proxy.hxx>
+#include <bridges/remote/remote.hxx>
+
+#include "urp_bridgeimpl.hxx"
+#include "urp_marshal.hxx"
+#include "urp_dispatch.hxx"
+#include "urp_job.hxx"
+#include "urp_writer.hxx"
+#include "urp_log.hxx"
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+
+namespace bridges_urp
+{
+
+void SAL_CALL urp_sendCloseConnection( uno_Environment *pEnvRemote )
+{
+ remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = (urp_BridgeImpl*) ( pContext->m_pBridgeImpl );
+
+ {
+ MutexGuard guard( pImpl->m_marshalingMutex );
+
+ // send immediately
+ if( ! pImpl->m_blockMarshaler.empty() )
+ {
+ pImpl->m_pWriter->touch( sal_True );
+ }
+
+ pImpl->m_pWriter->sendEmptyMessage();
+ }
+}
+extern "C" void SAL_CALL urp_sendRequest(
+ uno_Environment *pEnvRemote,
+ typelib_TypeDescription const * pMemberType,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pInterfaceType,
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException )
+{
+ remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = (urp_BridgeImpl*) ( pContext->m_pBridgeImpl );
+ pImpl->m_initialized.wait();
+ urp_sendRequest_internal(
+ pEnvRemote, pMemberType, pOid, pInterfaceType, pReturn, ppArgs,
+ ppException );
+}
+void SAL_CALL urp_sendRequest_internal(
+ uno_Environment *pEnvRemote,
+ typelib_TypeDescription const * pMemberType,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pInterfaceType,
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException )
+{
+ remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = (urp_BridgeImpl*) ( pContext->m_pBridgeImpl );
+
+ ClientJob job(
+ pEnvRemote, pContext, pImpl, pOid, pMemberType, pInterfaceType, pReturn,
+ ppArgs, ppException);
+
+ if( job.pack() && ! job.isOneway() )
+ {
+ job.wait();
+ }
+}
+
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_dispatch.hxx b/bridges/source/remote/urp/urp_dispatch.hxx
new file mode 100644
index 000000000000..2b44854e3350
--- /dev/null
+++ b/bridges/source/remote/urp/urp_dispatch.hxx
@@ -0,0 +1,80 @@
+/* -*- 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.hxx>
+
+#include <typelib/typedescription.h>
+
+#include <uno/any2.h>
+
+
+typedef struct _uno_Environment uno_Environment;
+struct remote_Interface;
+
+
+
+namespace bridges_urp {
+
+ const sal_uInt8 HDRFLAG_LONGHEADER = 0x80;
+ const sal_uInt8 HDRFLAG_REQUEST = 0x40;
+ const sal_uInt8 HDRFLAG_NEWTYPE = 0x20;
+ const sal_uInt8 HDRFLAG_NEWOID = 0x10;
+ const sal_uInt8 HDRFLAG_NEWTID = 0x08;
+ const sal_uInt8 HDRFLAG_LONGMETHODID = 0x04;
+ const sal_uInt8 HDRFLAG_IGNORECACHE = 0x02;
+ const sal_uInt8 HDRFLAG_MOREFLAGS = 0x01;
+ const sal_uInt8 HDRFLAG_MUSTREPLY = 0x80;
+ const sal_uInt8 HDRFLAG_SYNCHRONOUS = 0x40;
+
+ const sal_uInt8 HDRFLAG_EXCEPTION = 0x20;
+
+ void SAL_CALL urp_sendCloseConnection( uno_Environment *pEnvRemote );
+
+ extern "C" void SAL_CALL urp_sendRequest(
+ uno_Environment *pEnvRemote,
+ typelib_TypeDescription const * pMemberType,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pInterfaceType,
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException
+ );
+
+ void SAL_CALL urp_sendRequest_internal(
+ uno_Environment *pEnvRemote,
+ typelib_TypeDescription const * pMemberType,
+ rtl_uString *pOid,
+ typelib_InterfaceTypeDescription *pInterfaceType,
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException
+ );
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_environment.cxx b/bridges/source/remote/urp/urp_environment.cxx
new file mode 100644
index 000000000000..f1a61896202b
--- /dev/null
+++ b/bridges/source/remote/urp/urp_environment.cxx
@@ -0,0 +1,554 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+
+#include <osl/interlck.h>
+#include <osl/diagnose.h>
+#include <osl/conditn.h>
+#include <osl/mutex.hxx>
+#include <osl/process.h>
+
+#include <rtl/alloc.h>
+#include <rtl/uuid.h>
+#include <rtl/unload.h>
+
+#include <uno/environment.h>
+#include <uno/lbnames.h>
+#include <uno/mapping.hxx>
+#include <uno/threadpool.h>
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <bridges/remote/proxy.hxx>
+#include <bridges/remote/stub.hxx>
+#include <bridges/remote/context.h>
+#include <bridges/remote/mapping.hxx>
+#include <bridges/remote/counter.hxx>
+#include <bridges/remote/bridgeimpl.hxx>
+#include <bridges/remote/helper.hxx>
+
+#include "urp_bridgeimpl.hxx"
+#include "urp_writer.hxx"
+#include "urp_reader.hxx"
+#include "urp_dispatch.hxx"
+#include "urp_log.hxx"
+#include "urp_propertyobject.hxx"
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+
+namespace bridges_urp
+{
+rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+// static void dumpProperties( struct Properties *p )
+// {
+// fprintf( stderr , "FlushBlockSize : %d\n" , p->nFlushBlockSize );
+// fprintf( stderr , "OnewayTimeoutMUSEC : %d\n" , p->nOnewayTimeoutMUSEC );
+// fprintf( stderr , "OidCacheSize : %d\n" , p->nOidCacheSize );
+// fprintf( stderr , "TypeCacheSize : %d\n" , p->nTypeCacheSize );
+// fprintf( stderr , "TidCacheSize : %d\n" , p->nTidCacheSize );
+// OString o = OUStringToOString( p->sSupportedVersions , RTL_TEXTENCODING_ASCII_US );
+// fprintf( stderr , "SupportedVersions : %s\n" , o.pData->buffer );
+// o = OUStringToOString( p->sVersion , RTL_TEXTENCODING_ASCII_US );
+// fprintf( stderr , "Version : %s\n" , o.pData->buffer );
+// fprintf( stderr , "SupportsMultipleSynchronous : %d\n" , p->bSupportsMultipleSynchronous );
+// fprintf( stderr , "SupportsMustReply : %d\n" , p->bSupportsMustReply );
+// fprintf( stderr , "SupportsSynchronous : %d\n" , p->bSupportsSynchronous );
+// }
+
+// PropertySetterThread
+//------------------------------------
+class PropertySetterThread : public ::osl::Thread
+{
+ urp_BridgeImpl *m_pImpl;
+ ::rtl::OUString m_sProps;
+ uno_Environment *m_pEnvRemote;
+public:
+ PropertySetterThread( uno_Environment *pEnvRemote,
+ urp_BridgeImpl *pImpl,
+ const ::rtl::OUString & props )
+ : m_pImpl( pImpl )
+ , m_sProps( props )
+ , m_pEnvRemote( pEnvRemote )
+ {
+ if (m_sProps.getLength() > 0) {
+ m_sProps += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(","));
+ }
+ m_sProps += rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("CurrentContext="));
+ // hold the environment in case all references are released before this
+ // thread terminates
+ m_pEnvRemote->acquire( pEnvRemote );
+ }
+ ~PropertySetterThread()
+ {
+ m_pEnvRemote->release( m_pEnvRemote );
+ }
+
+ virtual void SAL_CALL run()
+ {
+ for (;;)
+ {
+ switch ( m_pImpl->m_pPropertyObject->localRequestChange( ) )
+ {
+ case 1:
+ sal_Bool bExceptionThrown;
+ m_pImpl->m_pPropertyObject->localCommitChange( m_sProps , &bExceptionThrown );
+ OSL_ENSURE( !bExceptionThrown, "properties were not set\n" );
+ goto done;
+ case 0:
+ OSL_TRACE( "urp-bridge : remote-counterpart won the changing-the-protocol-race\n" );
+ goto done;
+ }
+ }
+ done:
+ m_pImpl->m_initialized.set();
+ }
+ virtual void SAL_CALL onTerminated()
+ {
+ delete this;
+ }
+};
+//------------------------------------
+
+
+void test_cache()
+{
+ OUString a = OUString( RTL_CONSTASCII_USTRINGPARAM( "a" ) );
+ OUString b = OUString( RTL_CONSTASCII_USTRINGPARAM( "b" ) );
+ OUString c = OUString( RTL_CONSTASCII_USTRINGPARAM( "c" ) );
+ Cache < OUString , equalOUString > cache ( 2 );
+
+ sal_Int32 n = cache.put( a );
+ if (cache.seek( a ) != n)
+ {
+ OSL_ASSERT( false );
+ }
+ OSL_ASSERT( 0 == n );
+
+ n = cache.put( b );
+ OSL_ASSERT( 1 == n );
+
+ cache.put( c );
+
+ OSL_ASSERT( 0xffff == cache.seek( a ) );
+ OSL_ASSERT( 1 == cache.seek( b ) );
+ OSL_ASSERT( 0 == cache.seek( c ) );
+
+ OSL_ASSERT( 1 == cache.put( a ) );
+ OSL_ASSERT( 0xffff == cache.seek( b) );
+ OSL_ASSERT( 1 == cache.seek( a ) );
+ OSL_ASSERT( 0 == cache.seek( c ) );
+}
+
+/*******************
+ * Are we within thread, that calls destructors of static objects ?
+ *******************/
+sal_Bool g_bStaticDestructorsCalled = sal_False;
+struct StaticSingleton
+{
+ ~StaticSingleton()
+ {
+ ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
+ g_bStaticDestructorsCalled = sal_True;
+ }
+};
+StaticSingleton singleton;
+
+#if OSL_DEBUG_LEVEL > 1
+static MyCounter thisCounter( "Remote Environment" );
+#endif
+
+void SAL_CALL allThreadsAreGone( uno_Environment * pEnvRemote )
+{
+ remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = ( urp_BridgeImpl *) pContext->m_pBridgeImpl;
+
+ // if the current thread is not the writer thread, the writer thread
+ // object is not destroyed up to now, though it may already have run out.
+ // In both cases, it must be safe to cal pImpl->m_pWriter->getIdentifier()
+ OSL_ASSERT( pImpl->m_pWriter );
+ if( pImpl->m_pWriter->getIdentifier() == osl_getThreadIdentifier(0) )
+ {
+ // This is the writer thread. It has done some release calls,
+ // and is now the last one, that was active. Because the writer
+ // thread holds the environment weakly, there may also be a thread within
+ // the dispose of the bridge ( because the enviroment may have a refcount == 0 ).
+ // However, this thread MUST wait for the writer thread, so it is perfectly ok,
+ // not to set m_cndWaitForThreads. ( The check for m_nRemoteThreads is done
+ // after the join of the writer thread ).
+ }
+ else
+ {
+ pImpl->m_cndWaitForThreads.set();
+ }
+
+}
+
+void SAL_CALL releaseStubs( uno_Environment *pEnvRemote )
+{
+
+ ((remote_Context * ) pEnvRemote->pContext )->m_pBridgeImpl->m_bReleaseStubsCalled = sal_True;
+
+ remote_Interface **ppInterfaces = 0;
+ sal_Int32 nCount;
+ pEnvRemote->pExtEnv->getRegisteredInterfaces( pEnvRemote->pExtEnv,
+ (void***)&ppInterfaces,
+ &nCount,
+ rtl_allocateMemory );
+
+ sal_Int32 i;
+ for( i = 0 ; i < nCount ; i ++ )
+ {
+ if( ppInterfaces[i]->acquire == bridges_remote::acquireUno2RemoteStub )
+ {
+ // these are freed by the environment, so no release necessary
+ pEnvRemote->pExtEnv->revokeInterface( pEnvRemote->pExtEnv, ppInterfaces[i] );
+ }
+ else
+ {
+ ppInterfaces[i]->release( ppInterfaces[i] );
+ }
+ }
+
+ rtl_freeMemory( (void*) ppInterfaces );
+}
+
+} // end namespace bridges_urp
+
+using namespace bridges_urp;
+
+extern "C" {
+
+static void SAL_CALL RemoteEnvironment_thisDispose( uno_Environment *pEnvRemote )
+{
+ remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = ( urp_BridgeImpl *) pContext->m_pBridgeImpl;
+
+ ::osl::ClearableMutexGuard guard( pImpl->m_disposingMutex );
+ if( pContext->m_pBridgeImpl->m_bDisposed &&
+ ( ! pImpl->m_pReader ||
+ osl_getThreadIdentifier(0) ==
+ (oslThreadIdentifier) pImpl->m_pReader->getIdentifier() ) )
+ {
+ return;
+ }
+ // in case, that the static destructors already have been called, no
+ // tiding up is done.
+ bool tidyUp;
+ {
+ ::osl::MutexGuard guard2( ::osl::Mutex::getGlobalMutex() );
+ tidyUp = ! g_bStaticDestructorsCalled &&
+ ! pContext->m_pBridgeImpl->m_bDisposed;
+ }
+ if( tidyUp )
+ {
+ // TODO : not threadsafe
+ // synchronization with dispatch methods needed !
+
+ pImpl->m_bDisposed = sal_True;
+
+
+ // close the connection
+ uno_threadpool_dispose( pImpl->m_hThreadPool );
+ pImpl->m_pWriter->abortThread();
+ pContext->m_pConnection->close( pContext->m_pConnection );
+
+ if( osl_getThreadIdentifier(0) ==
+ (oslThreadIdentifier) pImpl->m_pReader->getIdentifier() )
+ {
+ // This is the reader thread. Let the thread destroy itself
+ // the reader thread object must also release the connection at this stage !
+ pImpl->m_pReader->destroyYourself();
+ pImpl->m_pReader = 0;
+ }
+ else
+ {
+ // wait for the reader thread
+ // the reader thread object must also release the connection,
+ // when terminating !!!!
+ pImpl->m_pReader->join();
+ }
+
+ // wait for the writer thread
+ pImpl->m_pWriter->join();
+
+ // now let the context go !
+ pContext->dispose( pContext );
+
+ if( 0 != pImpl->m_nRemoteThreads )
+ {
+ // Wait for all threads
+ guard.clear();
+ pImpl->m_cndWaitForThreads.wait();
+ OSL_ASSERT( ! pImpl->m_nRemoteThreads );
+ }
+ else
+ {
+ guard.clear();
+ }
+#ifdef BRIDGES_URP_PROT
+ if( pImpl->m_pLogFile )
+ {
+ fclose( pImpl->m_pLogFile );
+ pImpl->m_pLogFile = 0;
+ }
+#endif
+#if OSL_DEBUG_LEVEL > 1
+ pImpl->dumpErrors( stderr );
+#endif
+
+ // destroy the threads
+ delete pImpl->m_pWriter;
+ pImpl->m_pWriter = 0;
+
+ if( pImpl->m_pReader != 0 )
+ {
+ // This is not the reader thread, so the thread object is deleted
+ delete pImpl->m_pReader;
+ pImpl->m_pReader = 0;
+ }
+
+ bool bReleaseStubs = false;
+ {
+ ::osl::MutexGuard guard2( ::osl::Mutex::getGlobalMutex() );
+ bReleaseStubs = !g_bStaticDestructorsCalled;
+ }
+ if( bReleaseStubs )
+ {
+ releaseStubs( pEnvRemote );
+ }
+ }
+}
+
+static void SAL_CALL RemoteEnvironment_thisDisposing(
+ uno_Environment *pEnvRemote )
+{
+ remote_Context *pContext = (remote_Context * )pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = ((urp_BridgeImpl*) pContext->m_pBridgeImpl);
+
+ {
+ ::osl::ClearableMutexGuard guard( pImpl->m_disposingMutex );
+ if( ! pImpl->m_bDisposed )
+ {
+ guard.clear();
+ urp_sendCloseConnection( pEnvRemote );
+ RemoteEnvironment_thisDispose( pEnvRemote );
+ }
+ }
+ pImpl->m_pPropertyObject->thisRelease();
+ pImpl->m_pPropertyObject = 0;
+
+ uno_threadpool_destroy( pImpl->m_hThreadPool );
+
+ delete pImpl;
+ pContext->aBase.release( (uno_Context * ) pContext );
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+}
+
+static void SAL_CALL RemoteEnvironment_thisComputeObjectIdentifier(
+ uno_ExtEnvironment *, rtl_uString **, void *)
+{
+ OSL_ENSURE( 0, "RemoteEnvironment_thisComputeObjectIdentifier should never be called" );
+}
+
+static void SAL_CALL RemoteEnvironment_thisAcquireInterface(
+ uno_ExtEnvironment *, void *pInterface )
+{
+ ((remote_Interface *)pInterface)->acquire( ( remote_Interface *) pInterface );
+}
+
+static void SAL_CALL RemoteEnvironment_thisReleaseInterface(
+ uno_ExtEnvironment *, void *pInterface )
+{
+ ((remote_Interface *)pInterface)->release( ( remote_Interface *) pInterface );
+}
+
+//##################################################################################################
+void SAL_CALL uno_initEnvironment( uno_Environment * pEnvRemote )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ // set C-virtual methods
+ pEnvRemote->environmentDisposing = RemoteEnvironment_thisDisposing;
+ pEnvRemote->pExtEnv->computeObjectIdentifier = RemoteEnvironment_thisComputeObjectIdentifier;
+ pEnvRemote->pExtEnv->acquireInterface = RemoteEnvironment_thisAcquireInterface;
+ pEnvRemote->pExtEnv->releaseInterface = RemoteEnvironment_thisReleaseInterface;
+ pEnvRemote->dispose = RemoteEnvironment_thisDispose;
+
+ remote_Context *pContext = ( remote_Context * ) pEnvRemote->pContext;
+ pContext->aBase.acquire( ( uno_Context * ) pContext );
+ pContext->getRemoteInstance = ::bridges_remote::remote_sendQueryInterface;
+
+ // Initialize impl struct urp_BridgeImpl
+ urp_BridgeImpl *pImpl = new ::bridges_urp::urp_BridgeImpl( 256, 8192 );
+ pContext->m_pBridgeImpl = pImpl;
+
+ // Initialize threadpool
+ pImpl->m_hThreadPool = uno_threadpool_create();
+
+ // take the bridgepointer as id
+ pImpl->m_properties.seqBridgeID = ByteSequence( (sal_Int8*)&pEnvRemote , sizeof( pEnvRemote ) );
+
+ pImpl->m_allThreadsAreGone = allThreadsAreGone;
+ pImpl->m_sendRequest = urp_sendRequest;
+ pImpl->m_nRemoteThreads = 0;
+ pImpl->m_bDisposed = sal_False;
+ pImpl->m_bReleaseStubsCalled = sal_False;
+
+ pImpl->m_pPropertyObject = new PropertyObject( &(pImpl->m_properties ), pEnvRemote, pImpl );
+ pImpl->m_pPropertyObject->thisAcquire();
+
+ OUString sProtocolProperties;
+ if( pContext->m_pProtocol->length > 3 )
+ {
+ sProtocolProperties = OUString( pContext->m_pProtocol ).copy( 4, pContext->m_pProtocol->length-4);
+ }
+ if( sProtocolProperties.getLength() )
+ {
+ struct Properties props = pImpl->m_properties;
+ assignFromStringToStruct( sProtocolProperties , &props );
+ if( ! props.bNegotiate )
+ {
+ // no negotiation takes place, the creator of the bridge knows the parameter
+ // of the other side !
+ pImpl->applyProtocolChanges( props );
+ sProtocolProperties = OUString();
+ }
+ }
+
+#ifdef BRIDGES_URP_PROT
+ char *p = getenv( "PROT_REMOTE" );
+ pImpl->m_pLogFile = 0;
+ if( p )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ static int counter;
+ oslProcessInfo data;
+ data.Size = sizeof( data );
+ osl_getProcessInfo( 0 , osl_Process_HEAPUSAGE | osl_Process_IDENTIFIER , &data );
+ OString s(p);
+ s += "_pid";
+ s += OString::valueOf( (sal_Int32) data.Ident );
+ s += "_";
+ s += OString::valueOf( (sal_Int32) counter );
+ pImpl->m_sLogFileName = s;
+ // clear the file
+ FILE *f = fopen( s.getStr() , "w" );
+ OSL_ASSERT( f );
+ if( getenv( "PROT_REMOTE_FAST") )
+ {
+ pImpl->m_pLogFile = f;
+ }
+ else
+ {
+ fclose( f );
+ }
+ counter++;
+ }
+#endif
+
+ // start reader and writer threads
+ pImpl->m_pWriter = new ::bridges_urp::OWriterThread( pContext->m_pConnection , pImpl,
+ pEnvRemote);
+ pImpl->m_pWriter->create();
+
+ pImpl->m_pReader = new ::bridges_urp::OReaderThread( pContext->m_pConnection ,
+ pEnvRemote,
+ pImpl->m_pWriter );
+ pImpl->m_pReader->create();
+
+ PropertySetterThread *pPropsSetterThread =
+ new PropertySetterThread( pEnvRemote, pImpl , sProtocolProperties );
+ pPropsSetterThread->create();
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+
+//##################################################################################################
+void SAL_CALL uno_ext_getMapping(
+ uno_Mapping ** ppMapping,
+ uno_Environment * pFrom,
+ uno_Environment * pTo )
+{
+ OSL_ASSERT( ppMapping && pFrom && pTo );
+ if (ppMapping && pFrom && pTo)
+ {
+ if (*ppMapping)
+ ((*ppMapping)->release)( *ppMapping );
+ bridges_remote::RemoteMapping * pMapping = 0;
+
+ ::rtl::OUString sFromName = pFrom->pTypeName;
+ ::rtl::OUString sToName = pTo->pTypeName;
+ ::rtl::OUString sUno(RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO));
+ ::rtl::OUString sRemote(RTL_CONSTASCII_USTRINGPARAM("urp"));
+ if ( sFromName.equalsIgnoreAsciiCase( sRemote ) &&
+ sToName.equalsIgnoreAsciiCase( sUno ) )
+ {
+ pMapping = new bridges_remote::RemoteMapping( pTo, /* Uno */
+ pFrom, /*remote*/
+ bridges_remote::remoteToUno,
+ OUString() );
+ }
+ else if ( sFromName.equalsIgnoreAsciiCase( sUno ) &&
+ sToName.equalsIgnoreAsciiCase( sRemote ) )
+ {
+ pMapping = new bridges_remote::RemoteMapping( pFrom ,
+ pTo ,
+ bridges_remote::unoToRemote,
+ OUString() );
+ }
+
+ *ppMapping = (uno_Mapping * )pMapping;
+ OUString dummy;
+ uno_registerMapping( ppMapping ,
+ bridges_remote::freeRemoteMapping,
+ pFrom ,
+ pTo ,
+ dummy.pData );
+ }
+}
+
+sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
+{
+ return g_moduleCount.canUnload( &g_moduleCount , pTime );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_job.cxx b/bridges/source/remote/urp/urp_job.cxx
new file mode 100644
index 000000000000..8af686fa3ef3
--- /dev/null
+++ b/bridges/source/remote/urp/urp_job.cxx
@@ -0,0 +1,941 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <string.h>
+#include <stdio.h>
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+
+#include <rtl/alloc.h>
+#include <rtl/ustrbuf.hxx>
+
+#include <uno/current_context.h>
+#include <uno/current_context.hxx>
+#include <uno/threadpool.h>
+
+#include <bridges/cpp_uno/type_misc.hxx>
+#include <bridges/remote/proxy.hxx>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/XCurrentContext.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+
+#include "urp_job.hxx"
+#include "urp_bridgeimpl.hxx"
+#include "urp_writer.hxx"
+#include "urp_dispatch.hxx"
+#include "urp_log.hxx"
+#include "urp_marshal.hxx"
+#include "urp_propertyobject.hxx"
+#include "urp_reader.hxx"
+
+using namespace ::std;
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+
+using namespace bridges_urp;
+
+extern "C" {
+
+static void SAL_CALL doit(void * job) {
+ ServerMultiJob * p = static_cast< ServerMultiJob * >(job);
+ p->execute();
+ delete p;
+}
+
+}
+
+namespace bridges_urp
+{
+ static sal_Bool isDisposedExceptionDescriptionAvail( const Type &type )
+ {
+ static sal_Bool bInit;
+ static sal_Bool bReturn;
+ // we don't care for thread safety here, as both threads must come
+ // to the same result
+ if( ! bInit )
+ {
+ typelib_TypeDescription *pTD = 0;
+ typelib_typedescriptionreference_getDescription( & pTD, type.getTypeLibType() );
+ if( pTD )
+ {
+ bReturn = sal_True;
+ typelib_typedescription_release( pTD );
+ }
+ else
+ {
+ bReturn = sal_False;
+ }
+ bInit = sal_True;
+ }
+ return bReturn;
+ }
+
+ //--------------------------------------------------------------------------------------
+ static void prepareRuntimeExceptionClientSide( uno_Any **ppException , const OUString &s)
+ {
+ com::sun::star::lang::DisposedException exception( s , Reference< XInterface > () );
+ Type type = ::getCppuType( &exception );
+ if( !isDisposedExceptionDescriptionAvail( type ) )
+ {
+ // if it is not available (probably missing type library),
+ // then we are satisfied with throwing a normal runtime exception,
+ // for which cppu provides a static description
+ type = getCppuType( ( RuntimeException * ) 0 );
+ }
+ uno_type_any_construct( *ppException , &exception , type.getTypeLibType() , 0 );
+ }
+
+
+ Job::Job( uno_Environment *pEnvRemote,
+ remote_Context *pContext,
+ sal_Sequence *pTid,
+ struct urp_BridgeImpl *pBridgeImpl,
+ Unmarshal *pUnmarshal )
+ : m_pContext( pContext )
+ , m_pUnmarshal( pUnmarshal )
+ , m_pBridgeImpl( pBridgeImpl )
+ , m_pTid( pTid )
+ , m_counter( pEnvRemote )
+ {
+ if ( m_pContext )
+ {
+ m_pContext->aBase.acquire( &m_pContext->aBase );
+ }
+ if( m_pTid )
+ rtl_byte_sequence_acquire( pTid );
+ }
+
+ Job::~Job()
+ {
+ if( m_pTid )
+ rtl_byte_sequence_release( m_pTid );
+ if ( m_pContext )
+ {
+ m_pContext->aBase.release( &m_pContext->aBase );
+ }
+ }
+
+
+
+
+ //--------------------------------------------------------------------------------------
+ sal_Bool ClientJob::extract( )
+ {
+ sal_Bool bReturn = sal_True;
+ //-------------------------------
+ // Handle the reply, unpack data
+ //-------------------------------
+ if( m_bExceptionOccured )
+ {
+ bReturn = m_pUnmarshal->unpackAny( *m_ppException );
+ }
+ else
+ {
+ //---------------------------------
+ // alles ist gut
+ //---------------------------------
+ if( m_pMethodType )
+ {
+ if( m_pMethodType->pReturnTypeRef->eTypeClass != typelib_TypeClass_VOID )
+ {
+ typelib_TypeDescription *pType = 0;
+ TYPELIB_DANGER_GET( &pType , m_pMethodType->pReturnTypeRef );
+ bReturn = m_pUnmarshal->unpack( m_pReturn , pType ) && bReturn;
+ TYPELIB_DANGER_RELEASE( pType );
+ }
+
+ // out parameters
+ sal_Int32 i;
+ for( i = 0 ; i < m_pMethodType->nParams ; i ++ )
+ {
+ if( m_pMethodType->pParams[i].bOut )
+ {
+ typelib_TypeDescription *pType = 0;
+ TYPELIB_DANGER_GET( &pType , m_pMethodType->pParams[i].pTypeRef );
+ if( m_pMethodType->pParams[i].bIn )
+ {
+ uno_destructData( m_ppArgs[i] , pType , ::bridges_remote::remote_release );
+ }
+ bReturn = m_pUnmarshal->unpack( m_ppArgs[i] , pType ) && bReturn;
+ TYPELIB_DANGER_RELEASE( pType );
+ }
+ }
+ }
+ else if( m_pAttributeType && m_pReturn )
+ {
+ typelib_TypeDescription *pType = 0;
+ TYPELIB_DANGER_GET( &pType , m_pAttributeType->pAttributeTypeRef );
+ bReturn = m_pUnmarshal->unpack( m_pReturn , pType ) && bReturn;
+ TYPELIB_DANGER_RELEASE( pType );
+ }
+ else if( m_pAttributeType && m_ppArgs )
+ {
+ // nothing to do
+ }
+ else
+ {
+ OSL_ASSERT( 0 );
+ }
+ }
+ return bReturn;
+ }
+
+ //-------------------------------------------------------------------------------------------
+ void ClientJob::initiate()
+ {
+ uno_threadpool_putJob( m_pBridgeImpl->m_hThreadPool, m_pTid , this, 0, sal_False);
+ }
+
+ //--------------------------------------------------------------------------------------------
+ sal_Bool ClientJob::pack()
+ {
+ sal_Bool bSuccess = sal_True;
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+
+ if( m_pMethodType &&
+ REMOTE_RELEASE_METHOD_INDEX == m_pMethodType->aBase.nPosition &&
+ ! m_pBridgeImpl->m_bDisposed &&
+ m_pBridgeImpl->m_pWriter->getIdentifier() != ::osl::Thread::getCurrentIdentifier() )
+ {
+ // all release calls are delegated to the writer thread to avoid
+ // multiple synchron calls with the same thread id and reentrant
+ // marshaling (in case during destruction of parameters a release is
+ // invoked ).
+ m_pBridgeImpl->m_pWriter->insertReleaseRemoteCall(
+ m_pOid, m_pInterfaceType->aBase.pWeakRef );
+
+ // No waiting, please
+ return sal_False;
+ }
+ else if ( m_pMethodType &&
+ REMOTE_RELEASE_METHOD_INDEX == m_pMethodType->aBase.nPosition &&
+ m_pBridgeImpl->m_bDisposed )
+ {
+ // no exception for release calls !
+ return sal_False;
+ }
+ else if( m_pBridgeImpl->m_bDisposed )
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "URP-Bridge: disposed" ) );
+ buf.append( m_pBridgeImpl->getErrorsAsString() );
+ prepareRuntimeExceptionClientSide( m_ppException , buf.makeStringAndClear() );
+ return sal_False;
+ }
+
+ // build up the flag byte
+ sal_Bool bType = sal_False, bOid = sal_False, bTid = sal_False;
+ sal_uInt8 nFlags = 0;
+ if( m_pBridgeImpl->m_lastOutType.getTypeLibType() != m_pInterfaceType->aBase.pWeakRef &&
+ ! typelib_typedescriptionreference_equals(
+ m_pBridgeImpl->m_lastOutType.getTypeLibType(), m_pInterfaceType->aBase.pWeakRef ) )
+ {
+ //new type
+ nFlags = nFlags | HDRFLAG_NEWTYPE;
+ bType = sal_True;
+ }
+ if( m_pBridgeImpl->m_lastOutOid.pData != m_pOid &&
+ rtl_ustr_compare_WithLength( m_pBridgeImpl->m_lastOutOid.pData->buffer,
+ m_pBridgeImpl->m_lastOutOid.pData->length,
+ m_pOid->buffer,
+ m_pOid->length ) )
+ {
+ //new object id
+ nFlags = nFlags | HDRFLAG_NEWOID;
+ bOid = sal_True;
+ }
+ if( m_pBridgeImpl->m_lastOutTid.getHandle() != m_pTid &&
+ !(m_pBridgeImpl->m_lastOutTid == *(ByteSequence*) &(m_pTid) ) )
+ {
+ // new threadid
+ nFlags = nFlags | HDRFLAG_NEWTID;
+ bTid = sal_True;
+ }
+
+ if( m_bCallingConventionForced )
+ {
+ nFlags = nFlags | HDRFLAG_MOREFLAGS;
+ }
+#ifdef BRIDGES_URP_PROT
+ sal_Int32 nLogStart = m_pBridgeImpl->m_blockMarshaler.getPos();
+#endif
+ // Short request headers can only handle 14-bit method IDs, so
+ // unconditionally use a long header for method IDs that are too large:
+ if( nFlags || m_nMethodIndex >= 0xC000 )
+ {
+ // the flag byte is needed + request
+ nFlags = nFlags | HDRFLAG_LONGHEADER | HDRFLAG_REQUEST; //
+
+ // as long as we do not have customized calls, no MOREFLAGS must be set
+ if( m_nMethodIndex >= 0x100 )
+ {
+ nFlags = nFlags | HDRFLAG_LONGMETHODID;
+ }
+ m_pBridgeImpl->m_blockMarshaler.packInt8( &nFlags );
+
+ if( nFlags & HDRFLAG_MOREFLAGS )
+ {
+ sal_uInt8 nMoreFlags = 0;
+ if( ! m_bOneway )
+ {
+ nMoreFlags = HDRFLAG_SYNCHRONOUS |HDRFLAG_MUSTREPLY;
+ }
+ m_pBridgeImpl->m_blockMarshaler.packInt8( &nMoreFlags );
+ }
+ if( nFlags & HDRFLAG_LONGMETHODID )
+ {
+ sal_uInt16 nMethod = (sal_uInt16 ) m_nMethodIndex;
+ m_pBridgeImpl->m_blockMarshaler.packInt16( &nMethod );
+ }
+ else
+ {
+ sal_uInt8 nMethod = (sal_uInt8) m_nMethodIndex;
+ m_pBridgeImpl->m_blockMarshaler.packInt8( &nMethod );
+ }
+ }
+ else
+ {
+ // no flag byte needed, simply marshal the method index
+ if( m_nMethodIndex >= 64 )
+ {
+ sal_uInt16 nMethod = ( sal_uInt16 ) m_nMethodIndex;
+ nMethod = nMethod | 0x4000;
+ m_pBridgeImpl->m_blockMarshaler.packInt16( &nMethod );
+ }
+ else
+ {
+ sal_uInt8 nMethod = (sal_uInt8 ) m_nMethodIndex;
+ m_pBridgeImpl->m_blockMarshaler.packInt8( &nMethod );
+ }
+ }
+
+ // marshal type,oid,tid
+ if( bType )
+ {
+ m_pBridgeImpl->m_lastOutType = m_pInterfaceType->aBase.pWeakRef;
+ m_pBridgeImpl->m_blockMarshaler.packType( &(m_pBridgeImpl->m_lastOutType) );
+ }
+ if( bOid )
+ {
+ m_pBridgeImpl->m_lastOutOid = *(OUString *)&m_pOid;
+ m_pBridgeImpl->m_blockMarshaler.packOid( m_pBridgeImpl->m_lastOutOid );
+ }
+ if( bTid )
+ {
+ m_pBridgeImpl->m_lastOutTid = *(ByteSequence*)&(m_pTid);
+ m_pBridgeImpl->m_blockMarshaler.packTid( m_pBridgeImpl->m_lastOutTid );
+ }
+
+ if ( m_pBridgeImpl->m_properties.bCurrentContext
+ && m_nMethodIndex != REMOTE_RELEASE_METHOD_INDEX
+ && m_pContext != 0 )
+ {
+ void * pCc = 0;
+ rtl::OUString aEnvName( RTL_CONSTASCII_USTRINGPARAM( "urp" ) );
+ bSuccess = bSuccess && uno_getCurrentContext(
+ &pCc, aEnvName.pData, m_pContext );
+ typelib_TypeDescription * pType = 0;
+ TYPELIB_DANGER_GET(
+ &pType, XCurrentContext::static_type().getTypeLibType() );
+ bSuccess = bSuccess && m_pBridgeImpl->m_blockMarshaler.pack(
+ &pCc, pType );
+ TYPELIB_DANGER_RELEASE( pType );
+ if ( pCc )
+ {
+ remote_Interface * p = static_cast< remote_Interface * >( pCc );
+ p->release( p );
+ }
+ }
+
+ // marshal arguments !
+#ifdef BRIDGES_URP_PROT
+ sal_Int32 nLogHeader = m_pBridgeImpl->m_blockMarshaler.getPos();
+#endif
+ if( m_pMethodType )
+ {
+ sal_Int32 i;
+ for( i = 0 ; i < m_pMethodType->nParams ; i ++ )
+ {
+ if( m_pMethodType->pParams[i].bIn )
+ {
+ typelib_TypeDescription *pType = 0;
+ TYPELIB_DANGER_GET( &pType , m_pMethodType->pParams[i].pTypeRef );
+ if( pType )
+ {
+ bSuccess =
+ bSuccess && m_pBridgeImpl->m_blockMarshaler.pack( m_ppArgs[i] , pType );
+ TYPELIB_DANGER_RELEASE( pType );
+ }
+ else
+ {
+ bSuccess = sal_False;
+ OUStringBuffer buffer( 128 );
+ buffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "no typedescription available for type" ) );
+ buffer.append( m_pMethodType->pParams[i].pTypeRef->pTypeName );
+ m_pBridgeImpl->addError( buffer.makeStringAndClear() );
+ }
+ }
+ }
+ }
+ else if( m_pAttributeType && m_pReturn )
+ {
+ // nothing to do !
+ }
+ else if( m_pAttributeType && m_ppArgs )
+ {
+ typelib_TypeDescription *pType = 0;
+ TYPELIB_DANGER_GET( &pType , m_pAttributeType->pAttributeTypeRef );
+ if( pType )
+ {
+ bSuccess = bSuccess && m_pBridgeImpl->m_blockMarshaler.pack( m_ppArgs[0] , pType );
+ TYPELIB_DANGER_RELEASE( pType );
+ }
+ else
+ {
+ bSuccess = sal_False;
+ OUStringBuffer buffer( 128 );
+ buffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "no typedescription available for type" ) );
+ buffer.append( m_pAttributeType->pAttributeTypeRef->pTypeName );
+ m_pBridgeImpl->addError( buffer.makeStringAndClear() );
+ }
+ }
+ else
+ {
+ OSL_ASSERT( 0 );
+ }
+
+#ifdef BRIDGES_URP_PROT
+ urp_logCall( m_pBridgeImpl, m_pBridgeImpl->m_blockMarshaler.getPos() - nLogStart,
+ m_pBridgeImpl->m_blockMarshaler.getPos() - nLogHeader, ! m_bOneway,
+ m_pMethodType ? m_pMethodType->aBase.pMemberName :
+ m_pAttributeType->aBase.pMemberName );
+#endif
+
+ if( bSuccess )
+ {
+ if( ! m_bOneway )
+ {
+ uno_threadpool_attach( m_pBridgeImpl->m_hThreadPool );
+ m_pBridgeImpl->m_clientJobContainer.add( *(ByteSequence*)&(m_pTid), this );
+ }
+
+ m_pBridgeImpl->m_nMarshaledMessages ++;
+ //---------------------------
+ // Inform the writer thread, that there is some work to do
+ //---------------------------
+ m_pBridgeImpl->m_pWriter->touch( ! m_bOneway );
+
+ if( m_bOneway )
+ {
+ *m_ppException = 0;
+ }
+ }
+ else
+ {
+ // Something went wrong during packing, which means, that the caches may not be in sync
+ // anymore. So we have no other choice than to dispose the environment.
+ m_pEnvRemote->dispose( m_pEnvRemote );
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Error during marshaling " ) );
+ if( m_pMethodType )
+ {
+ buf.append( m_pMethodType->aBase.aBase.pTypeName );
+ }
+ else if( m_pAttributeType )
+ {
+ buf.append( m_pAttributeType->aBase.aBase.pTypeName );
+ }
+ buf.appendAscii( "\n" );
+ buf.append( m_pBridgeImpl->getErrorsAsString() );
+ prepareRuntimeExceptionClientSide( m_ppException , buf.makeStringAndClear() );
+ }
+ return bSuccess;
+ // release the guard
+ }
+
+ //------------------------------------------------------------------------------------
+ void ClientJob::wait()
+ {
+ //---------------------------
+ // Wait for the reply
+ //---------------------------
+ void * pDisposeReason = 0;
+
+ uno_threadpool_enter(m_pBridgeImpl->m_hThreadPool, &pDisposeReason );
+
+ if( ! pDisposeReason )
+ {
+ // thread has been disposed !
+ // avoid leak due continous calling on a disposed reference. The
+ // reply may or may not be within the container. If the reader thread
+ // got into problems during unmarshaling the reply for this request,
+ // it won't be in the container anymore, but it is eiterway safe to call
+ // the method
+ ClientJob *pJob =
+ m_pBridgeImpl->m_clientJobContainer.remove( *(ByteSequence*) &m_pTid );
+ if( pJob != this )
+ {
+ // this is not our job, it is probably one of the callstack below, so
+ // push it back
+ m_pBridgeImpl->m_clientJobContainer.add( *(ByteSequence*) &m_pTid , pJob );
+ }
+
+ OUStringBuffer sMessage( 256 );
+ sMessage.appendAscii( RTL_CONSTASCII_STRINGPARAM( "URP_Bridge : disposed\n" ) );
+ sMessage.append( m_pBridgeImpl->getErrorsAsString() );
+ prepareRuntimeExceptionClientSide( m_ppException, sMessage.makeStringAndClear() );
+ m_bExceptionOccured = sal_True;
+ }
+ else
+ {
+ OSL_ASSERT( pDisposeReason == (void*)this );
+ }
+ if( !m_bExceptionOccured )
+ {
+ *m_ppException = 0;
+ }
+ uno_threadpool_detach( m_pBridgeImpl->m_hThreadPool );
+ }
+
+ //------------------------------------------------------------------------------------
+ // ServerMultiJob
+ //------------------------------------------------------------------------------------
+ ServerMultiJob::ServerMultiJob(
+ uno_Environment *pEnvRemote,
+ remote_Context *pContext,
+ sal_Sequence *pTid,
+ struct urp_BridgeImpl *pBridgeImpl,
+ Unmarshal *pUnmarshal,
+ sal_Int32 nMaxMessages )
+ : Job( pEnvRemote, pContext, pTid, pBridgeImpl, pUnmarshal )
+ , m_pEnvRemote( pEnvRemote )
+ , m_nCalls( 0 )
+ , m_nMaxMessages( nMaxMessages )
+ , m_nCurrentMemPosition( 0 )
+ {
+ m_pEnvRemote->acquire( m_pEnvRemote );
+ m_nCurrentMemSize = MULTIJOB_STANDARD_MEMORY_SIZE + m_nMaxMessages * (
+ MULTIJOB_PER_CALL_MEMORY_SIZE + sizeof(ServerJobEntry) + sizeof(MemberTypeInfo) );
+ m_pCurrentMem = ( sal_Int8 * ) rtl_allocateMemory( m_nCurrentMemSize );
+ m_aEntries = ( ServerJobEntry * ) getHeap( m_nMaxMessages * sizeof( ServerJobEntry ) );
+ m_aTypeInfo = ( MemberTypeInfo * ) getHeap( m_nMaxMessages * sizeof( MemberTypeInfo ) );
+ }
+
+ ServerMultiJob::~ServerMultiJob()
+ {
+ sal_Int32 i;
+ for( i = 0 ; i < m_nCalls ; i ++ )
+ {
+ struct MemberTypeInfo *const pMTI = &( m_aTypeInfo[i] );
+ struct ServerJobEntry *const pSJE = &( m_aEntries[i] );
+
+ if( pSJE->m_pRemoteI )
+ pSJE->m_pRemoteI->release( pSJE->m_pRemoteI );
+
+ if( pSJE->m_pOid )
+ rtl_uString_release( pSJE->m_pOid );
+
+ if( pSJE->m_pInterfaceTypeRef )
+ typelib_typedescriptionreference_release( pSJE->m_pInterfaceTypeRef );
+
+ if( pMTI->m_pInterfaceType )
+ TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *)pMTI->m_pInterfaceType );
+
+ for( sal_Int32 iArgs = 0 ; iArgs < pMTI->m_nArgCount ; iArgs ++ )
+ {
+ if( pMTI->m_ppArgType[iArgs] )
+ TYPELIB_DANGER_RELEASE( pMTI->m_ppArgType [iArgs] );
+ }
+ if( pMTI->m_pReturnType )
+ TYPELIB_DANGER_RELEASE( pMTI->m_pReturnType );
+
+ if( pMTI->m_pMethodType )
+ typelib_typedescription_release( (typelib_TypeDescription*)pMTI->m_pMethodType );
+ if( pMTI->m_pAttributeType )
+ typelib_typedescription_release( (typelib_TypeDescription*)pMTI->m_pAttributeType );
+ }
+
+ rtl_freeMemory( m_pCurrentMem );
+ for( list< sal_Int8 *>::iterator ii = m_lstMem.begin() ; ii != m_lstMem.end() ; ++ii )
+ rtl_freeMemory( *ii );
+
+ if( m_pEnvRemote )
+ m_pEnvRemote->release( m_pEnvRemote );
+ }
+
+ //-------------------------------------------------------------------------------------
+ void ServerMultiJob::execute()
+ {
+ Reference< XCurrentContext > xOldCc;
+ bool bHasOldCc = false;
+ for( sal_Int32 i = 0; i < m_nCalls ; i ++ )
+ {
+ struct MemberTypeInfo * const pMTI = &( m_aTypeInfo[i] );
+ struct ServerJobEntry * const pSJE = &( m_aEntries[i] );
+
+ if ( pSJE->m_bHasCurrentContext )
+ {
+ if ( !bHasOldCc )
+ {
+ xOldCc = com::sun::star::uno::getCurrentContext();
+ bHasOldCc = true;
+ }
+ rtl::OUString aEnvName( RTL_CONSTASCII_USTRINGPARAM( "urp" ) );
+ if ( !uno_setCurrentContext(
+ pSJE->m_pCurrentContext, aEnvName.pData, m_pContext ) )
+ {
+ throw RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "fatal: uno_setCurrentContext failed" ) ),
+ Reference< XInterface >() );
+ }
+ if ( pSJE->m_pCurrentContext )
+ {
+ pSJE->m_pCurrentContext->release( pSJE->m_pCurrentContext );
+ }
+ }
+
+ if( ! pSJE->m_pRemoteI )
+ {
+ // -------------------
+ // Initial object ?
+ // ------------------
+ // be robust : Sending a release on a not constructed object
+ // provokes an segfault. Make sure, the call
+ // is not a release call.
+ remote_Context *pRemoteC = ((remote_Context*)m_pEnvRemote->pContext);
+
+ if( ! pMTI->m_bIsReleaseCall && pRemoteC->m_pInstanceProvider )
+ {
+ pSJE->m_pException = &(pSJE->m_exception);
+
+ pRemoteC->m_pInstanceProvider->getInstance(
+ pRemoteC->m_pInstanceProvider,
+ m_pEnvRemote,
+ &(pSJE->m_pRemoteI),
+ pSJE->m_pOid,
+ pMTI->m_pInterfaceType,
+ &(pSJE->m_pException));
+ }
+ else
+ {
+ prepareRuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "urp: No instance provider set")),i);
+ }
+ }
+
+ if( pSJE->m_pException )
+ {
+ // errors during extracting, do nothing
+ }
+ else if( ! pSJE->m_pRemoteI )
+ {
+ // May only occur during the queryInterface call on the initial object !!!
+ // construct the return value
+ uno_type_any_construct( (uno_Any*) pSJE->m_pReturn , 0 , 0 , 0 );
+ }
+ else
+ {
+ pSJE->m_pException = &(pSJE->m_exception );
+
+ if( pMTI->m_bIsReleaseCall )
+ {
+ pSJE->m_pRemoteI->release( pSJE->m_pRemoteI );
+ pSJE->m_pException = 0;
+ }
+ else
+ {
+ pSJE->m_pRemoteI->pDispatcher(
+ pSJE->m_pRemoteI,
+ pMTI->m_pMethodType ? (typelib_TypeDescription*) pMTI->m_pMethodType :
+ (typelib_TypeDescription*) pMTI->m_pAttributeType,
+ pSJE->m_pReturn,
+ pSJE->m_ppArgs,
+ &(pSJE->m_pException) );
+ }
+ }
+ if( pSJE->m_pRemoteI )
+ {
+ /**
+ Do the release here, in case of ForceSynchronous=1, calls
+ originated by the destructor of an UNO object must be sent BEFORE the
+ release returns ( otherwise we don't own the thread anymore ! )
+ */
+ pSJE->m_pRemoteI->release( pSJE->m_pRemoteI );
+ pSJE->m_pRemoteI = 0;
+ }
+
+ // now destruct parameters and marshal replies
+ // Note : when call is synchron => m_nCalls == 1
+ if( pMTI->m_bIsOneway )
+ {
+ // Oneway call, destruct in parameters
+ for( sal_Int32 j = 0 ; j < pMTI->m_pMethodType->nParams ; j ++ )
+ {
+ // usually all parameters must be in parameters, but to be robust ...
+ if( pMTI->m_pbIsIn[j] && !cppu_isSimpleType( pMTI->m_ppArgType[j] ) )
+ {
+ uno_destructData( pSJE->m_ppArgs[j] , pMTI->m_ppArgType[j] , 0 );
+ }
+ }
+
+ if( pSJE->m_pException )
+ {
+ uno_any_destruct( pSJE->m_pException, ::bridges_remote::remote_release );
+ }
+
+ }
+ else
+ {
+ // synchron, get the mutex to marshal reply and send immeadiatly
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+
+ sal_Bool bTid = sal_False;
+ sal_uInt8 nFlags = HDRFLAG_LONGHEADER;
+ ByteSequence tid = m_pTid;
+ if( !( tid == m_pBridgeImpl->m_lastOutTid ) || pSJE->m_bIgnoreCache )
+ {
+ // new threadid
+ nFlags = nFlags | HDRFLAG_NEWTID;
+ bTid = sal_True;
+ }
+
+ if( pSJE->m_pException )
+ {
+ nFlags = nFlags | HDRFLAG_EXCEPTION;
+ }
+#ifdef BRIDGES_URP_PROT
+ sal_Int32 nLogStart = m_pBridgeImpl->m_blockMarshaler.getPos();
+#endif
+ m_pBridgeImpl->m_blockMarshaler.packInt8( &nFlags );
+
+ if( bTid )
+ {
+ if( ! pSJE->m_bIgnoreCache )
+ {
+ m_pBridgeImpl->m_lastOutTid = tid;
+ }
+ m_pBridgeImpl->m_blockMarshaler.packTid( tid , pSJE->m_bIgnoreCache );
+ }
+
+#ifdef BRIDGES_URP_PROT
+ sal_Int32 nLogHeader = m_pBridgeImpl->m_blockMarshaler.getPos();
+#endif
+
+ if( pSJE->m_pException )
+ {
+ //--------------------
+ // an exception was thrown
+ //--------------------
+ m_pBridgeImpl->m_blockMarshaler.packAny( &(pSJE->m_exception) );
+ uno_any_destruct( &(pSJE->m_exception) , ::bridges_remote::remote_release );
+
+ // destroy in parameters
+ for( sal_Int32 j = 0 ; j < pMTI->m_nArgCount ; j ++ )
+ {
+ if( pMTI->m_pbIsIn[j] && ! cppu_isSimpleType( pMTI->m_ppArgType[j] ))
+ {
+ uno_destructData( pSJE->m_ppArgs[j] , pMTI->m_ppArgType[j] ,
+ ::bridges_remote::remote_release );
+ }
+ }
+ }
+ else
+ {
+ //---------------------------
+ // alles ist gut ...
+ //--------------------------
+ if( pMTI->m_pReturnType )
+ {
+ m_pBridgeImpl->m_blockMarshaler.pack(
+ pSJE->m_pReturn, pMTI->m_pReturnType );
+ if( ! cppu_isSimpleType( pMTI->m_pReturnType ) )
+ {
+ uno_destructData( pSJE->m_pReturn , pMTI->m_pReturnType ,
+ ::bridges_remote::remote_release );
+ }
+ }
+ for( sal_Int32 j = 0 ; j < pMTI->m_nArgCount ; j ++ )
+ {
+ if( pMTI->m_pbIsOut[j] )
+ {
+ m_pBridgeImpl->m_blockMarshaler.pack(
+ pSJE->m_ppArgs[j] , pMTI->m_ppArgType[j] );
+ }
+ if( ! cppu_isSimpleType( pMTI->m_ppArgType[j] ) )
+ {
+ uno_destructData( pSJE->m_ppArgs[j], pMTI->m_ppArgType[j] ,
+ ::bridges_remote::remote_release );
+ }
+ }
+ }
+
+#ifdef BRIDGES_URP_PROT
+ {
+ typelib_InterfaceMemberTypeDescription *pMemberType =
+ pMTI->m_pMethodType ?
+ (typelib_InterfaceMemberTypeDescription*)pMTI->m_pMethodType :
+ (typelib_InterfaceMemberTypeDescription*)pMTI->m_pAttributeType;
+
+ urp_logReplying( m_pBridgeImpl ,
+ m_pBridgeImpl->m_blockMarshaler.getPos() - nLogStart,
+ m_pBridgeImpl->m_blockMarshaler.getPos() - nLogHeader,
+ pMemberType->pMemberName );
+ }
+#endif
+
+ m_pBridgeImpl->m_nMarshaledMessages ++;
+ // put it on the wire
+ m_pBridgeImpl->m_pWriter->touch( sal_True );
+ } // MutexGuard marshalingMutex
+ }
+ if ( bHasOldCc )
+ {
+ if ( !com::sun::star::uno::setCurrentContext( xOldCc ) )
+ {
+ throw RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "fatal: com::sun::star::uno::setCurrentContext"
+ " failed" ) ),
+ Reference< XInterface >() );
+ }
+ }
+ }
+
+ //-------------------------------------------------------------------------------------
+ void ServerMultiJob::prepareRuntimeException( const OUString & sMessage , sal_Int32 nCall )
+ {
+ // -------------------------------
+ // Construct the DisposedException
+ // -------------------------------
+ com::sun::star::lang::DisposedException exception( sMessage , Reference< XInterface > () );
+ Type type = getCppuType( &exception );
+ if( !isDisposedExceptionDescriptionAvail( type ) )
+ {
+ // if it is not available (probably missing type library),
+ // then we are satisfied with throwing a normal runtime exception,
+ // for which cppu provides a static description
+ type = getCppuType( ( RuntimeException * ) 0 );
+ }
+
+ m_aEntries[nCall].m_pException = &(m_aEntries[nCall].m_exception);
+ uno_type_any_construct( m_aEntries[nCall].m_pException , &exception , type.getTypeLibType() , 0 );
+ }
+
+ //-------------------------------------------------------------------------------------
+ void ServerMultiJob::initiate()
+ {
+ uno_threadpool_putJob(
+ m_pBridgeImpl->m_hThreadPool,
+ m_pTid,
+ this,
+ doit,
+ m_aTypeInfo[0].m_bIsOneway );
+ }
+
+
+ //-------------------------------------------------------------------------------------
+ sal_Bool ServerMultiJob::extract()
+ {
+ sal_Bool bContinue = sal_True;
+ struct MemberTypeInfo * const pMTI = &(m_aTypeInfo[m_nCalls]);
+ struct ServerJobEntry * const pSJE = &(m_aEntries[m_nCalls]);
+
+ pSJE->m_pException = 0;
+ pSJE->m_ppArgs = 0;
+ pSJE->m_pReturn = 0;
+ pMTI->m_pReturnType = 0;
+
+ if( pMTI->m_nArgCount )
+ {
+ pMTI->m_ppArgType =
+ ( typelib_TypeDescription ** ) getHeap( sizeof(void*) * pMTI->m_nArgCount );
+ pSJE->m_ppArgs = (void**) getHeap( sizeof( void * ) * pMTI->m_nArgCount );
+ pMTI->m_pbIsIn = (sal_Bool *) getHeap( sizeof( sal_Bool ) * pMTI->m_nArgCount );
+ pMTI->m_pbIsOut = (sal_Bool *) getHeap( sizeof( sal_Bool ) * pMTI->m_nArgCount );
+ }
+ if( pMTI->m_pMethodType &&
+ pMTI->m_pMethodType->pReturnTypeRef->eTypeClass != typelib_TypeClass_VOID )
+ {
+ TYPELIB_DANGER_GET( &(pMTI->m_pReturnType), pMTI->m_pMethodType->pReturnTypeRef );
+ }
+ else if( pMTI->m_pAttributeType && ! pMTI->m_nArgCount )
+ {
+ TYPELIB_DANGER_GET( &(pMTI->m_pReturnType) , pMTI->m_pAttributeType->pAttributeTypeRef );
+ }
+
+ // normal method
+ if( pMTI->m_pMethodType )
+ {
+ for( sal_Int32 i = 0 ; i < pMTI->m_nArgCount ; i ++ )
+ {
+ pMTI->m_ppArgType[i] = 0;
+ TYPELIB_DANGER_GET( & ( pMTI->m_ppArgType[i] ) , pMTI->m_pMethodType->pParams[i].pTypeRef);
+ pMTI->m_pbIsIn[i] = pMTI->m_pMethodType->pParams[i].bIn;
+ pMTI->m_pbIsOut[i] = pMTI->m_pMethodType->pParams[i].bOut;
+
+ pSJE->m_ppArgs[i] = getHeap( pMTI->m_ppArgType[i]->nSize );
+ if( pMTI->m_pbIsIn[i] )
+ {
+ // everything needs to be constructed
+ bContinue = m_pUnmarshal->unpack(
+ pSJE->m_ppArgs[i], pMTI->m_ppArgType[i] ) && bContinue;
+ }
+ }
+ }
+ else if( pMTI->m_nArgCount )
+ {
+ // set attribut
+ pMTI->m_ppArgType[0] = 0;
+ pMTI->m_pbIsIn[0] = sal_True;
+ pMTI->m_pbIsOut[0] = sal_False;
+ TYPELIB_DANGER_GET(
+ & ( pMTI->m_ppArgType[0] ) , pMTI->m_pAttributeType->pAttributeTypeRef );
+ pSJE->m_ppArgs[0] = getHeap( pMTI->m_ppArgType[0]->nSize );
+ bContinue = m_pUnmarshal->unpack(
+ pSJE->m_ppArgs[0], pMTI->m_ppArgType[0] ) && bContinue;
+ }
+
+ if( pMTI->m_pReturnType )
+ {
+ pSJE->m_pReturn = getHeap( pMTI->m_pReturnType->nSize );
+ }
+
+ m_nCalls ++;
+ return bContinue;
+ }
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_job.hxx b/bridges/source/remote/urp/urp_job.hxx
new file mode 100644
index 000000000000..ed31e33c387b
--- /dev/null
+++ b/bridges/source/remote/urp/urp_job.hxx
@@ -0,0 +1,381 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+#ifndef _URP_JOB_HXX_
+#define _URP_JOB_HXX_
+#include <list>
+#include <typelib/typedescription.hxx>
+#include <uno/any2.h>
+#include <uno/environment.h>
+#include <uno/threadpool.h>
+#include "urp_threadid.hxx"
+#include "urp_unmarshal.hxx"
+#include "urp_bridgeimpl.hxx"
+
+
+namespace bridges_urp
+{
+const sal_Int32 MULTIJOB_STANDARD_MEMORY_SIZE = 1024;
+const sal_Int32 MULTIJOB_PER_CALL_MEMORY_SIZE = 96;
+
+class Unmarshal;
+struct urp_BridgeImpl;
+
+template < class t >
+inline t mymax( const t &t1 , const t &t2 )
+{
+ return t1 > t2 ? t1 : t2;
+}
+
+class Job
+{
+public:
+ Job( uno_Environment *pEnvRemote,
+ remote_Context *pContext,
+ sal_Sequence *pTid,
+ struct urp_BridgeImpl *pBridgeImpl,
+ Unmarshal *pUnmarshal );
+
+ Job( uno_Environment *pEnvRemote,
+ remote_Context *pContext,
+ struct urp_BridgeImpl *pBridgeImpl,
+ ::bridges_remote::RemoteThreadCounter_HoldEnvWeak value )
+ : m_pContext( pContext )
+ , m_pBridgeImpl( pBridgeImpl )
+ , m_pTid( 0 )
+ , m_counter( pEnvRemote , value )
+ {
+ if ( m_pContext )
+ {
+ m_pContext->aBase.acquire( &m_pContext->aBase );
+ }
+ }
+
+ ~Job();
+
+public:
+ remote_Context *m_pContext;
+ Unmarshal *m_pUnmarshal;
+ struct urp_BridgeImpl *m_pBridgeImpl;
+ sal_Sequence *m_pTid;
+ ::bridges_remote::RemoteThreadCounter m_counter;
+};
+
+class ClientJob : private Job
+{
+public:
+ // pContext is null for bridge-internal UrpProtocolProperties requests
+ inline ClientJob( uno_Environment *pEnvRemote, // weak !
+ remote_Context *pContext,
+ struct urp_BridgeImpl *pBridgeImpl,
+ rtl_uString *pOid, // weak
+ typelib_TypeDescription const * pMemberType, // weak
+ typelib_InterfaceTypeDescription *pInterfaceType, // weak
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException );
+
+ // ~ClientJob
+ // no release for method type and attribute type necessary, because
+ // it was acquired by the caller of urp_sendRequest. The lifetime
+ // of the ClientJob object is always shorter than the urp_sendRequest call.
+ inline ~ClientJob()
+ {
+ if( m_bReleaseForTypeDescriptionNecessary )
+ typelib_typedescription_release( (typelib_TypeDescription*) m_pInterfaceType );
+ uno_releaseIdFromCurrentThread();
+ }
+
+ sal_Bool pack();
+ void wait();
+ sal_Bool extract( );
+ void initiate();
+
+ inline void setBridgePropertyCall()
+ { m_bBridgePropertyCall = sal_True; }
+ inline sal_Bool isBridgePropertyCall()
+ { return m_bBridgePropertyCall; }
+ inline sal_Bool isOneway()
+ { return m_bOneway; }
+
+ inline void setUnmarshal( Unmarshal *p )
+ { m_pUnmarshal = p; }
+public:
+ typelib_InterfaceMethodTypeDescription *m_pMethodType;
+ typelib_InterfaceAttributeTypeDescription *m_pAttributeType;
+ sal_Bool m_bExceptionOccured;
+
+private:
+ void **m_ppArgs;
+ void *m_pReturn;
+ typelib_InterfaceTypeDescription *m_pInterfaceType;
+ sal_Bool m_bReleaseForTypeDescriptionNecessary;
+
+ uno_Any **m_ppException;
+ sal_Bool m_bOneway;
+ sal_Bool m_bBridgePropertyCall;
+ sal_uInt16 m_nMethodIndex;
+ uno_Environment *m_pEnvRemote;
+ rtl_uString *m_pOid;
+ sal_Bool m_bCallingConventionForced;
+};
+
+struct MemberTypeInfo
+{
+ typelib_InterfaceTypeDescription *m_pInterfaceType;
+ typelib_InterfaceMethodTypeDescription *m_pMethodType;
+ typelib_InterfaceAttributeTypeDescription *m_pAttributeType;
+ sal_Int32 m_nArgCount;
+ sal_Bool m_bIsReleaseCall;
+ sal_Bool *m_pbIsIn;
+ sal_Bool *m_pbIsOut;
+ sal_Bool m_bIsOneway;
+ typelib_TypeDescription *m_pReturnType;
+ typelib_TypeDescription **m_ppArgType;
+};
+
+
+struct ServerJobEntry
+{
+ rtl_uString *m_pOid;
+ remote_Interface *m_pRemoteI;
+ typelib_TypeDescriptionReference *m_pInterfaceTypeRef;
+ void **m_ppArgs;
+ void *m_pReturn;
+ uno_Any m_exception;
+ uno_Any *m_pException;
+ remote_Interface *m_pCurrentContext;
+ sal_Bool m_bHasCurrentContext;
+ sal_Bool m_bIgnoreCache;
+};
+
+class ServerMultiJob : private Job
+{
+public:
+ ServerMultiJob( uno_Environment *pEnvRemote,
+ remote_Context *pContext,
+ sal_Sequence *pTid,
+ struct urp_BridgeImpl *pBridgeImpl,
+ Unmarshal *pUnmarshal,
+ sal_Int32 nMaxMessages );
+ ~ServerMultiJob();
+public:
+ sal_Bool extract( );
+ void initiate();
+ void execute();
+
+public:
+ // setMethodType or setAttributeType MUST be called before extract
+ inline void setMethodType(
+ typelib_InterfaceMethodTypeDescription *pMethodType,
+ sal_Bool bIsReleaseCall,
+ sal_Bool bIsOneway )
+ {
+ m_aTypeInfo[m_nCalls].m_pMethodType = pMethodType;
+ m_aTypeInfo[m_nCalls].m_pAttributeType = 0;
+ m_aTypeInfo[m_nCalls].m_nArgCount = pMethodType->nParams;
+ m_aTypeInfo[m_nCalls].m_bIsReleaseCall = bIsReleaseCall;
+ m_aTypeInfo[m_nCalls].m_bIsOneway = bIsOneway;
+ }
+
+ inline void setAttributeType(
+ typelib_InterfaceAttributeTypeDescription *pAttributeType, sal_Bool bIsSetter, sal_Bool bIsOneway )
+ {
+ m_aTypeInfo[m_nCalls].m_pAttributeType = pAttributeType;
+ m_aTypeInfo[m_nCalls].m_pMethodType = 0;
+ m_aTypeInfo[m_nCalls].m_nArgCount = bIsSetter ? 1 : 0;
+ m_aTypeInfo[m_nCalls].m_bIsReleaseCall = sal_False;
+ m_aTypeInfo[m_nCalls].m_bIsOneway = bIsOneway;
+ }
+
+ inline void setType( typelib_TypeDescriptionReference *pTypeRef )
+ {
+ m_aEntries[m_nCalls].m_pInterfaceTypeRef = pTypeRef;
+ typelib_typedescriptionreference_acquire( m_aEntries[m_nCalls].m_pInterfaceTypeRef );
+ TYPELIB_DANGER_GET(
+ (typelib_TypeDescription ** )&(m_aTypeInfo[m_nCalls].m_pInterfaceType) ,
+ pTypeRef );
+ }
+ // setOid or setInterface MUST be called before extract
+ inline void setOid( rtl_uString *pOid )
+ {
+ m_aEntries[m_nCalls].m_pOid = pOid;
+ rtl_uString_acquire( m_aEntries[m_nCalls].m_pOid );
+ m_aEntries[m_nCalls].m_pRemoteI = 0;
+ }
+
+ // setOid or setInterface MUST be called
+ inline void setInterface( remote_Interface *pRemoteI )
+ {
+ m_aEntries[m_nCalls].m_pRemoteI = pRemoteI;
+ pRemoteI->acquire( pRemoteI );
+ m_aEntries[m_nCalls].m_pOid = 0;
+ }
+
+ inline void setCurrentContext(
+ bool bHasCurrentContext, remote_Interface *pCurrentContext )
+ {
+ m_aEntries[m_nCalls].m_pCurrentContext = pCurrentContext;
+ m_aEntries[m_nCalls].m_bHasCurrentContext = bHasCurrentContext;
+ }
+
+ inline void setIgnoreCache( sal_Bool bIgnoreCache )
+ {
+ m_aEntries[m_nCalls].m_bIgnoreCache = bIgnoreCache;
+ }
+
+ inline sal_Bool isFull()
+ { return m_nCalls >= m_nMaxMessages; }
+
+ inline sal_Int8 *getHeap( sal_Int32 nSizeToAlloc )
+ {
+ if( nSizeToAlloc + m_nCurrentMemPosition > m_nCurrentMemSize )
+ {
+ m_lstMem.push_back( m_pCurrentMem );
+ m_nCurrentMemSize = mymax( nSizeToAlloc , MULTIJOB_STANDARD_MEMORY_SIZE ) +
+ (m_nMaxMessages -m_nCalls)*MULTIJOB_PER_CALL_MEMORY_SIZE;
+ m_pCurrentMem = (sal_Int8*) rtl_allocateMemory( m_nCurrentMemSize );
+ m_nCurrentMemPosition = 0;
+ }
+ sal_Int8 *pHeap = m_pCurrentMem + m_nCurrentMemPosition;
+ m_nCurrentMemPosition += nSizeToAlloc;
+
+ // care for alignment
+ if( m_nCurrentMemPosition & 0x7 )
+ {
+ m_nCurrentMemPosition = ( ((sal_uInt32)m_nCurrentMemPosition) & ( 0xffffffff - 0x7 )) + 8;
+ }
+ return pHeap;
+ }
+ void prepareRuntimeException( const ::rtl::OUString &sMessage, sal_Int32 nCall );
+
+private:
+ uno_Environment *m_pEnvRemote;
+ sal_Int32 m_nCalls;
+ sal_Int32 m_nMaxMessages;
+
+ ServerJobEntry *m_aEntries;
+ MemberTypeInfo *m_aTypeInfo;
+
+ sal_Int8 *m_pCurrentMem;
+ sal_Int32 m_nCurrentMemSize;
+ sal_Int32 m_nCurrentMemPosition;
+
+ // list of memory pointers, that must be freed
+ ::std::list< sal_Int8 * > m_lstMem;
+};
+
+
+
+//---------------------------------------------------------------------------------------------
+inline ClientJob::ClientJob(
+ uno_Environment *pEnvRemote,
+ remote_Context *pContext,
+ struct urp_BridgeImpl *pBridgeImpl,
+ rtl_uString *pOid,
+ typelib_TypeDescription const * pMemberType,
+ typelib_InterfaceTypeDescription *pInterfaceType,
+ void *pReturn,
+ void *ppArgs[],
+ uno_Any **ppException )
+ : Job(
+ pEnvRemote, pContext, pBridgeImpl, ::bridges_remote::RTC_HOLDENVWEAK )
+ , m_ppArgs( ppArgs )
+ , m_pReturn( pReturn )
+ , m_pInterfaceType( pInterfaceType ) // weak
+ , m_bReleaseForTypeDescriptionNecessary( sal_False )
+ , m_ppException( ppException )
+ , m_bBridgePropertyCall( sal_False )
+ , m_pEnvRemote( pEnvRemote ) // weak
+ , m_pOid( pOid ) // weak
+ , m_bCallingConventionForced( sal_False )
+{
+ uno_getIdOfCurrentThread( &m_pTid );
+
+ if( typelib_TypeClass_INTERFACE_METHOD == pMemberType->eTypeClass )
+ {
+ m_pMethodType = ( typelib_InterfaceMethodTypeDescription * ) pMemberType;
+ m_pAttributeType = 0;
+ }
+ else if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pMemberType->eTypeClass )
+ {
+ m_pAttributeType = ( typelib_InterfaceAttributeTypeDescription * ) pMemberType;
+ m_pMethodType = 0;
+ }
+ else
+ {
+ OSL_ASSERT( ! "wrong member type" );
+ }
+
+ // calculate method index
+ if( ! m_pInterfaceType->aBase.bComplete )
+ {
+ // must be acquired because typedescription may be exchanged
+ typelib_typedescription_acquire((typelib_TypeDescription*) m_pInterfaceType );
+ m_bReleaseForTypeDescriptionNecessary = sal_True;
+ typelib_typedescription_complete( (typelib_TypeDescription ** ) &m_pInterfaceType );
+ }
+ m_nMethodIndex = (sal_uInt16) m_pInterfaceType->pMapMemberIndexToFunctionIndex[
+ ((typelib_InterfaceMemberTypeDescription*)pMemberType)->nPosition ];
+
+ if( m_pAttributeType && m_ppArgs )
+ {
+ // setter
+ m_nMethodIndex ++;
+ }
+
+ if( typelib_TypeClass_INTERFACE_METHOD == pMemberType->eTypeClass )
+ {
+// if( (( typelib_InterfaceMemberTypeDescription * ) pMemberType)->nPosition
+// == REMOTE_RELEASE_METHOD_INDEX )
+// {
+// m_bOneway = sal_True;
+// }
+// else
+ if( pBridgeImpl->m_properties.bForceSynchronous )
+ {
+ m_bOneway = sal_False;
+ if( (( typelib_InterfaceMethodTypeDescription * ) pMemberType)->bOneWay )
+ {
+ m_bCallingConventionForced = sal_True;
+ }
+ }
+ else
+ {
+ m_bOneway = (( typelib_InterfaceMethodTypeDescription * ) pMemberType)->bOneWay;
+ }
+ }
+ else
+ {
+ m_bOneway = sal_False;
+ }
+}
+
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_log.cxx b/bridges/source/remote/urp/urp_log.cxx
new file mode 100644
index 000000000000..cdaa1727e6b9
--- /dev/null
+++ b/bridges/source/remote/urp/urp_log.cxx
@@ -0,0 +1,150 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <osl/time.h>
+#include "urp_bridgeimpl.hxx"
+#include "urp_log.hxx"
+
+using namespace ::rtl;
+using namespace ::osl;
+namespace bridges_urp
+{
+#ifdef BRIDGES_URP_PROT
+ Mutex g_logFileMutex;
+
+ class FileAccess
+ {
+ public:
+ FileAccess( urp_BridgeImpl *pBridgeImpl_ ) :
+ pBridgeImpl( pBridgeImpl_ ),
+ guard( g_logFileMutex )
+ {
+ if( pBridgeImpl->m_pLogFile )
+ {
+ f = pBridgeImpl->m_pLogFile;
+ }
+ else
+ {
+ f = fopen( pBridgeImpl->m_sLogFileName.getStr() , "a" );
+ }
+ }
+ ~FileAccess()
+ {
+ if( ! pBridgeImpl->m_pLogFile )
+ {
+ fclose( f );
+ }
+ }
+ FILE *getFile()
+ {
+ return f;
+ }
+ private:
+ urp_BridgeImpl *pBridgeImpl;
+ MutexGuard guard;
+ FILE *f;
+ };
+
+ void urp_logCall( urp_BridgeImpl *pBridgeImpl, sal_Int32 nSize, sal_Int32 nUseData, sal_Bool bSynchron ,
+ const ::rtl::OUString &sMethodName )
+ {
+ if( pBridgeImpl->m_sLogFileName.getLength() && getenv( "PROT_REMOTE_ACTIVATE" ) )
+ {
+ OString sOperation = OUStringToOString( sMethodName,RTL_TEXTENCODING_ASCII_US );
+
+ FileAccess access( pBridgeImpl );
+ fprintf( access.getFile() ,
+ "%06u: calling [size=%d(usedata=%d)] [synchron=%d] [name=%s]\n" ,
+ static_cast< unsigned int > (osl_getGlobalTimer()),
+ static_cast< int > (nSize),
+ static_cast< int > (nUseData),
+ bSynchron, sOperation.pData->buffer );
+ }
+ }
+
+ void urp_logServingRequest( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nSize, sal_Int32 nUseData, sal_Bool bSynchron ,
+ const ::rtl::OUString &sMethodName )
+ {
+ if( pBridgeImpl->m_sLogFileName.getLength() && getenv( "PROT_REMOTE_ACTIVATE" ) )
+ {
+ OString sOperation = OUStringToOString( sMethodName,RTL_TEXTENCODING_ASCII_US );
+
+ FileAccess access( pBridgeImpl );
+ fprintf(
+ access.getFile(),
+ "%06u: serving request [size=%d(usedata=%d)] [synchron=%d] [name=%s]\n",
+ static_cast< unsigned int > (osl_getGlobalTimer()),
+ static_cast< int > (nSize),
+ static_cast< int > (nUseData),
+ bSynchron,
+ sOperation.pData->buffer
+ );
+ }
+ }
+
+ void urp_logGettingReply( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nSize, sal_Int32 nUseData,
+ const ::rtl::OUString &sMethodName )
+ {
+ if( pBridgeImpl->m_sLogFileName.getLength() && getenv( "PROT_REMOTE_ACTIVATE" ) )
+ {
+ OString sOperation = OUStringToOString( sMethodName,RTL_TEXTENCODING_ASCII_US );
+ FileAccess access( pBridgeImpl );
+ fprintf( access.getFile(),
+ "%06u: getting reply [size=%d(usedata=%d)][name=%s]\n" ,
+ static_cast< unsigned int > (osl_getGlobalTimer()),
+ static_cast< int > (nSize),
+ static_cast< int > (nUseData),
+ sOperation.pData->buffer);
+ }
+ }
+
+ void urp_logReplying( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nSize , sal_Int32 nUseData,
+ const ::rtl::OUString &sMethodName )
+ {
+ if( pBridgeImpl->m_sLogFileName.getLength() && getenv( "PROT_REMOTE_ACTIVATE" ) )
+ {
+ OString sOperation = OUStringToOString(sMethodName,RTL_TEXTENCODING_ASCII_US);
+
+ FileAccess access( pBridgeImpl );
+ fprintf( access.getFile(),
+ "%06u: replying [size=%d(usedata=%d)] [name=%s]\n",
+ static_cast< unsigned int > (osl_getGlobalTimer()),
+ static_cast< int > (nSize),
+ static_cast< int > (nUseData),
+ sOperation.pData->buffer);
+ }
+ }
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_log.hxx b/bridges/source/remote/urp/urp_log.hxx
new file mode 100644
index 000000000000..8eb3751932a6
--- /dev/null
+++ b/bridges/source/remote/urp/urp_log.hxx
@@ -0,0 +1,53 @@
+/* -*- 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 bridges_urp
+{
+#ifdef DBG_UTIL
+#define BRIDGES_URP_PROT
+#endif
+
+#ifdef BRIDGES_URP_PROT
+ void urp_logCall( urp_BridgeImpl *pBridgeImpl ,
+ sal_Int32 nSize, sal_Int32 nUseData, sal_Bool bSynchron ,
+ const ::rtl::OUString &sMethodName );
+
+ void urp_logServingRequest( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nSize, sal_Int32 nUseData, sal_Bool bSynchron ,
+ const ::rtl::OUString &sMethodName );
+
+ void urp_logGettingReply( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nSize, sal_Int32 nUseData,
+ const ::rtl::OUString &sMethodName );
+
+ void urp_logReplying( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nSize , sal_Int32 nUseData,
+ const ::rtl::OUString &sMethodName );
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_marshal.cxx b/bridges/source/remote/urp/urp_marshal.cxx
new file mode 100644
index 000000000000..ae23cfb87eb5
--- /dev/null
+++ b/bridges/source/remote/urp/urp_marshal.cxx
@@ -0,0 +1,238 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <string.h>
+#include <osl/diagnose.h>
+#include <rtl/alloc.h>
+
+#include <uno/any2.h>
+#include <uno/sequence2.h>
+
+#include "urp_marshal.hxx"
+
+using namespace ::rtl;
+
+using namespace ::com::sun::star::uno;
+
+namespace bridges_urp {
+
+static int g_nDetectLittleEndian = 1;
+char g_bMarshalSystemIsLittleEndian = ((char*)&g_nDetectLittleEndian)[0];
+
+Marshal::Marshal( urp_BridgeImpl *pBridgeImpl,
+ sal_Int32 nBufferSize,
+ urp_extractOidCallback callback) :
+ m_nBufferSize( nBufferSize ),
+ m_base( (sal_Int8*)rtl_allocateMemory( nBufferSize ) ),
+ m_pos( m_base + 2*sizeof( sal_Int32 ) ),
+ m_pBridgeImpl( pBridgeImpl ),
+ m_callback( callback )
+{}
+
+Marshal::~Marshal( )
+{
+ rtl_freeMemory( m_base );
+}
+
+void Marshal::packOid( const ::rtl::OUString & oid )
+{
+ sal_uInt16 nIndex;
+ if( oid.getLength() )
+ {
+ nIndex = m_pBridgeImpl->m_oidCacheOut.seek( oid );
+ if( 0xffff == nIndex )
+ {
+ nIndex = m_pBridgeImpl->m_oidCacheOut.put( oid );
+ packString( (void*)(&oid.pData) );
+ }
+ else
+ {
+ OUString dummy;
+ packString( &dummy );
+ }
+ }
+ else
+ {
+ // null reference
+ nIndex = 0xffff;
+ OUString dummy;
+ packString( &dummy );
+ }
+ packInt16( &nIndex );
+}
+
+void Marshal::packTid( const ByteSequence & threadId, sal_Bool bIgnoreCache )
+{
+
+ sal_uInt16 nIndex = 0xffff;
+ if( ! bIgnoreCache )
+ {
+ nIndex = m_pBridgeImpl->m_tidCacheOut.seek( threadId );
+ }
+
+ if( 0xffff == nIndex )
+ {
+ if( ! bIgnoreCache )
+ {
+ nIndex = m_pBridgeImpl->m_tidCacheOut.put( threadId );
+ }
+ packByteSequence( (sal_Int8*) threadId.getConstArray() ,threadId.getLength());
+ }
+ else
+ {
+ packByteSequence( 0 , 0 );
+ }
+ packInt16( &nIndex );
+}
+
+
+void Marshal::packType( void *pSource )
+{
+ typelib_TypeDescriptionReference *pRef =
+ *(typelib_TypeDescriptionReference ** ) pSource;
+
+ OSL_ASSERT( pRef );
+
+ sal_uInt8 nTypeClass = ( sal_uInt8 ) pRef->eTypeClass;
+
+ if( nTypeClass <= /* any*/ 14 )
+ {
+ packInt8( (sal_Int8*)&nTypeClass );
+ }
+ else
+ {
+ OUString sTypeName;
+ sal_uInt16 nIndex = 0xffff;
+
+ nIndex = m_pBridgeImpl->m_typeCacheOut.seek( *(Type*)&pRef );
+ if( 0xffff == nIndex )
+ {
+ // put it into the cache
+ nIndex = m_pBridgeImpl->m_typeCacheOut.put( *(Type*)&pRef );
+ sTypeName = pRef->pTypeName;
+ nTypeClass = nTypeClass | 0x80;
+ }
+ packInt8( &nTypeClass );
+ packInt16( &nIndex );
+ if( 0x80 & nTypeClass )
+ {
+ packString( &sTypeName );
+ }
+ }
+}
+
+sal_Bool Marshal::packRecursive( void *pSource , typelib_TypeDescription *pType )
+{
+ sal_Bool bSuccess = sal_True;
+ switch( pType->eTypeClass )
+ {
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_STRUCT:
+ {
+ typelib_CompoundTypeDescription * pCompType = (typelib_CompoundTypeDescription*)pType;
+
+ if (pCompType->pBaseTypeDescription)
+ {
+ bSuccess = pack( pSource , (typelib_TypeDescription*) pCompType->pBaseTypeDescription );
+ }
+
+ // then construct members
+ typelib_TypeDescriptionReference ** ppTypeRefs = pCompType->ppTypeRefs;
+ sal_Int32 * pMemberOffsets = pCompType->pMemberOffsets;
+ sal_Int32 nDescr = pCompType->nMembers;
+
+ for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos )
+ {
+ typelib_TypeDescription * pMemberType = 0;
+ TYPELIB_DANGER_GET( &pMemberType, ppTypeRefs[nPos] );
+ if( pMemberType )
+ {
+ bSuccess = bSuccess && pack( (char*)pSource + pMemberOffsets[nPos] , pMemberType );
+ TYPELIB_DANGER_RELEASE( pMemberType );
+ }
+ else
+ {
+ OUStringBuffer buf( 64 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("Couldn't get typedescription for type "));
+ buf.append( ppTypeRefs[nPos]->pTypeName );
+ m_pBridgeImpl->addError( buf.makeStringAndClear() );
+ bSuccess = sal_False;
+ }
+ }
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ typelib_IndirectTypeDescription *pIndirectType =
+ ( typelib_IndirectTypeDescription* ) pType;
+
+ const sal_Int32 nElements = (*(uno_Sequence **)pSource)->nElements;
+ char * pSourceElements = (char *)(*(uno_Sequence **)pSource)->elements;
+
+ if( typelib_TypeClass_BYTE == pIndirectType->pType->eTypeClass )
+ {
+ // Byte sequences are optimized
+ packByteSequence( (sal_Int8*)pSourceElements , nElements );
+ }
+ else
+ {
+ typelib_TypeDescription *pElementType = 0;
+ TYPELIB_DANGER_GET( &pElementType, pIndirectType->pType );
+ if( pElementType )
+ {
+ const sal_Int32 nElementSize = pElementType->nSize;
+
+ packCompressedSize( nElements );
+ for ( sal_Int32 i = 0 ; i < nElements; i++ )
+ {
+ bSuccess = bSuccess && pack( pSourceElements + (nElementSize*i) , pElementType );
+ }
+ TYPELIB_DANGER_RELEASE( pElementType );
+ }
+ else
+ {
+ bSuccess = sal_False;
+ OUStringBuffer buf( 64 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("Couldn't get typedescription for type "));
+ buf.append( pIndirectType->pType->pTypeName );
+ m_pBridgeImpl->addError( buf.makeStringAndClear() );
+ }
+ }
+ break;
+ }
+ default:
+ OSL_ASSERT( 0 );
+ }
+ return bSuccess;
+}
+
+} // end namespace bridges
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_marshal.hxx b/bridges/source/remote/urp/urp_marshal.hxx
new file mode 100644
index 000000000000..f66528d74703
--- /dev/null
+++ b/bridges/source/remote/urp/urp_marshal.hxx
@@ -0,0 +1,345 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+#ifndef _URP_MARSHAL_HXX_
+#define _URP_MARSHAL_HXX_
+#include <rtl/ustrbuf.hxx>
+#include <rtl/byteseq.hxx>
+#include <com/sun/star/uno/Type.hxx>
+#include "urp_bridgeimpl.hxx"
+#include "urp_marshal_decl.hxx"
+
+#include <string.h>
+
+struct remote_Interface;
+
+namespace bridges_urp
+{
+ // methods for accessing marshaling buffer
+ inline void Marshal::finish( sal_Int32 nMessageCount )
+ {
+ sal_Int32 nSize = getSize() - 2*sizeof( sal_Int32 );
+
+ // save the state
+ sal_Int8 *pos = m_pos;
+ m_pos = m_base;
+ packInt32( &nSize );
+ packInt32( &nMessageCount );
+
+ // reset the state
+ m_pos = pos;
+ }
+
+ inline void Marshal::restart()
+ {
+ m_pos = m_base + 2*sizeof( sal_Int32 );
+ }
+
+ inline sal_Int8 *Marshal::getBuffer()
+ {
+ return m_base;
+ }
+
+ inline sal_Bool Marshal::empty() const
+ {
+ return ( m_pos - m_base ) == 2*sizeof( sal_Int32 );
+ }
+
+ inline sal_Int32 Marshal::getSize()
+ {
+ return ((sal_Int32) (m_pos - m_base));
+ }
+
+ inline void Marshal::ensureAdditionalMem( sal_Int32 nMemToAdd )
+ {
+ sal_Int32 nDiff = m_pos - m_base;
+ if( nDiff + nMemToAdd > m_nBufferSize )
+ {
+ m_nBufferSize = m_nBufferSize * 2 > nDiff + nMemToAdd ?
+ m_nBufferSize* 2 :
+ nDiff + nMemToAdd;
+
+ m_base = ( sal_Int8 * ) rtl_reallocateMemory( m_base , m_nBufferSize );
+ m_pos = m_base + nDiff;
+ }
+ }
+
+ // marshaling methods
+ inline void Marshal::packInt8( void *pSource )
+ {
+ ensureAdditionalMem( 1 );
+ *m_pos = *((sal_Int8*) pSource );
+ m_pos++;
+ }
+
+ inline void Marshal::packInt16( void *pSource )
+ {
+ ensureAdditionalMem( 2 );
+ if( isSystemLittleEndian() )
+ {
+ m_pos[0] = ((unsigned char *)pSource)[1];
+ m_pos[1] = ((unsigned char *)pSource)[0];
+ }
+ else
+ {
+ m_pos[1] = ((unsigned char *)pSource)[1];
+ m_pos[0] = ((unsigned char *)pSource)[0];
+ }
+ m_pos +=2;
+ }
+
+ inline void Marshal::packByteSequence( sal_Int8 *pData , sal_Int32 nLength )
+ {
+ packCompressedSize( nLength );
+
+ ensureAdditionalMem( nLength );
+ memcpy( m_pos , pData , nLength );
+ m_pos += nLength;
+ }
+
+ inline void Marshal::packString( void *pSource )
+ {
+ rtl_uString *p = *( rtl_uString ** ) pSource;
+
+ // to be optimized !
+ // static buffer in marshal
+ ::rtl::OString o = ::rtl::OUStringToOString( p , RTL_TEXTENCODING_UTF8 );
+ sal_Int32 nLength = o.pData->length;
+ packCompressedSize( nLength );
+
+ ensureAdditionalMem( nLength );
+
+ memcpy( m_pos , o.pData->buffer , nLength );
+ m_pos += nLength;
+ }
+
+ inline sal_Bool Marshal::packAny( void *pSource )
+ {
+ sal_Bool bSuccess = sal_True;
+ uno_Any *pAny = (uno_Any * ) pSource;
+
+ // pack the type
+ packType( &( pAny->pType ) );
+ // pack the value
+ typelib_TypeDescription *pType = 0;
+ TYPELIB_DANGER_GET( &pType, pAny->pType );
+ if( pType )
+ {
+ pack( pAny->pData , pType );
+ TYPELIB_DANGER_RELEASE( pType );
+ }
+ else
+ {
+ rtl::OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("couldn't get typedescription for type " ) );
+ buf.append( pAny->pType->pTypeName );
+ m_pBridgeImpl->addError( buf.makeStringAndClear() );
+ bSuccess = sal_False;
+ }
+ return bSuccess;
+ }
+
+ inline void Marshal::packInt32( void *pSource )
+ {
+ ensureAdditionalMem( 4 );
+ if( isSystemLittleEndian() )
+ {
+ m_pos[0] = ((unsigned char *)pSource)[3];
+ m_pos[1] = ((unsigned char *)pSource)[2];
+ m_pos[2] = ((unsigned char *)pSource)[1];
+ m_pos[3] = ((unsigned char *)pSource)[0];
+ }
+ else {
+ m_pos[3] = ((unsigned char *)pSource)[3];
+ m_pos[2] = ((unsigned char *)pSource)[2];
+ m_pos[1] = ((unsigned char *)pSource)[1];
+ m_pos[0] = ((unsigned char *)pSource)[0];
+ }
+ m_pos +=4;
+ }
+
+ inline void Marshal::packCompressedSize( sal_Int32 nSize )
+ {
+ ensureAdditionalMem( 5 );
+
+ if( nSize < 0xff )
+ {
+ *((sal_uInt8*)m_pos) = (sal_uInt8) nSize;
+ m_pos ++;
+ }
+ else
+ {
+ *((sal_uInt8*)m_pos) = 0xff;
+ m_pos ++;
+ packInt32( &nSize );
+ }
+ }
+
+ inline sal_Bool Marshal::pack( void *pSource , typelib_TypeDescription *pType )
+ {
+ sal_Bool bSuccess = sal_True;
+ switch( pType->eTypeClass )
+ {
+ case typelib_TypeClass_BYTE:
+ {
+ packInt8( pSource );
+ break;
+ }
+ case typelib_TypeClass_BOOLEAN:
+ {
+ ensureAdditionalMem( 1 );
+ *m_pos = ( *((sal_Bool*) pSource ) ) ? 1 : 0;
+ m_pos++;
+ break;
+ }
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ {
+ packInt16( pSource );
+ break;
+ }
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_FLOAT:
+ {
+ packInt32( pSource );
+ break;
+ }
+ case typelib_TypeClass_DOUBLE:
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ {
+ ensureAdditionalMem( 8 );
+ if( isSystemLittleEndian() )
+ {
+ m_pos[0] = ((unsigned char *)pSource)[7];
+ m_pos[1] = ((unsigned char *)pSource)[6];
+ m_pos[2] = ((unsigned char *)pSource)[5];
+ m_pos[3] = ((unsigned char *)pSource)[4];
+ m_pos[4] = ((unsigned char *)pSource)[3];
+ m_pos[5] = ((unsigned char *)pSource)[2];
+ m_pos[6] = ((unsigned char *)pSource)[1];
+ m_pos[7] = ((unsigned char *)pSource)[0];
+ }
+ else
+ {
+ m_pos[7] = ((unsigned char *)pSource)[7];
+ m_pos[6] = ((unsigned char *)pSource)[6];
+ m_pos[5] = ((unsigned char *)pSource)[5];
+ m_pos[4] = ((unsigned char *)pSource)[4];
+ m_pos[3] = ((unsigned char *)pSource)[3];
+ m_pos[2] = ((unsigned char *)pSource)[2];
+ m_pos[1] = ((unsigned char *)pSource)[1];
+ m_pos[0] = ((unsigned char *)pSource)[0];
+ }
+ m_pos += 8;
+ break;
+ }
+
+ case typelib_TypeClass_STRING:
+ {
+ packString( pSource );
+ break;
+ }
+ case typelib_TypeClass_TYPE:
+ {
+ packType( pSource );
+ break;
+ }
+ case typelib_TypeClass_ANY:
+ {
+ bSuccess = packAny( pSource );
+ break;
+ }
+ case typelib_TypeClass_TYPEDEF:
+ {
+ bSuccess = sal_False;
+ m_pBridgeImpl->addError( "can't handle typedef typedescriptions" );
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ remote_Interface *pRemoteI = *( remote_Interface ** )pSource;
+
+ ::rtl::OUString sOid;
+ sal_uInt16 nIndex = 0xffff;
+ if( pRemoteI )
+ {
+ m_callback( pRemoteI , &(sOid.pData) );
+
+ nIndex = m_pBridgeImpl->m_oidCacheOut.seek( sOid );
+ if( 0xffff == nIndex )
+ {
+ nIndex = m_pBridgeImpl->m_oidCacheOut.put( sOid );
+ }
+ else
+ {
+ // cached !
+ sOid = ::rtl::OUString();
+ }
+ }
+ packString( &sOid );
+ packInt16( &nIndex );
+ break;
+ }
+ case typelib_TypeClass_VOID:
+ {
+ // do nothing
+ break;
+ }
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_SEQUENCE:
+ {
+ bSuccess = packRecursive( pSource, pType );
+ break;
+ }
+ default:
+ {
+ bSuccess = sal_False;
+ rtl::OUStringBuffer buf( 128 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "can't handle values with typeclass " ) );
+ buf.append( (sal_Int32 ) pType->eTypeClass , 10 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " (" ) );
+ buf.append( pType->pTypeName );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
+ m_pBridgeImpl->addError( buf.makeStringAndClear() );
+ break;
+ }
+ }
+ return bSuccess;
+ }
+}
+
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_marshal_decl.hxx b/bridges/source/remote/urp/urp_marshal_decl.hxx
new file mode 100644
index 000000000000..a07f6ea48f5a
--- /dev/null
+++ b/bridges/source/remote/urp/urp_marshal_decl.hxx
@@ -0,0 +1,109 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef _URP_MARSHAL_DECL_HXX_
+#define _URP_MARSHAL_DECL_HXX_
+
+#include <rtl/ustring.hxx>
+#include <rtl/byteseq.hxx>
+
+#include <com/sun/star/uno/Type.hxx>
+
+namespace bridges_urp
+{
+ struct urp_BridgeImpl;
+
+ typedef void
+ ( SAL_CALL * urp_extractOidCallback )( remote_Interface *pRemoteI, rtl_uString **ppOid );
+
+ extern char g_bMarshalSystemIsLittleEndian;
+ class Marshal
+ {
+ public:
+ Marshal( /* cache access */ struct urp_BridgeImpl *,
+ sal_Int32 m_nBufferSize,
+ urp_extractOidCallback callback = 0
+ );
+ ~Marshal( );
+
+ inline sal_Bool pack( void *pSource , typelib_TypeDescription *pType );
+
+ sal_Bool packRecursive( void *pSource, typelib_TypeDescription *pType );
+
+ void packTid( const ::rtl::ByteSequence &id, sal_Bool bIgnoreCache = sal_False );
+ void packOid( const ::rtl::OUString &oid );
+ void packType( void *pSource );
+
+ inline void packCompressedSize( sal_Int32 nSize );
+ inline void packInt8( void *pSource );
+ inline void packInt16( void *pSource );
+ inline void packInt32( void *pSource );
+ inline void packString( void *pSource );
+ inline sal_Bool packAny( void *pSource );
+ inline void packByteSequence( sal_Int8 *pBuffer , sal_Int32 nSize );
+
+ // can be called during marshaling, but not between
+ // finish and restart
+ // returns true, when nothing has been marshaled
+ inline sal_Bool empty() const;
+
+ // stops marshaling, inserts size in front of the buffer
+ // getStart and getSize can now be called
+ inline void finish( sal_Int32 nMessageCount );
+
+ // must be called after finish. After calling restart,
+ // a new marshalling session is started invalidating
+ // the previous bufer
+ inline void restart();
+
+ // is only valid, after finish has been called.
+ // valid until destructed.
+ inline sal_Int8 *getBuffer();
+
+ // is only valid, after finish has been called.
+ // valid until destructed.
+ inline sal_Int32 getSize();
+
+ inline sal_Int32 getPos()
+ { return m_pos - m_base; }
+
+ inline sal_Bool isSystemLittleEndian()
+ { return g_bMarshalSystemIsLittleEndian; }
+
+ private:
+ inline void ensureAdditionalMem( sal_Int32 nMemToAdd );
+ sal_Int32 m_nBufferSize;
+ sal_Int8 *m_base;
+ sal_Int8 *m_pos;
+ struct urp_BridgeImpl *m_pBridgeImpl;
+ urp_extractOidCallback m_callback;
+ };
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_property.hxx b/bridges/source/remote/urp/urp_property.hxx
new file mode 100644
index 000000000000..0cd5525e63ad
--- /dev/null
+++ b/bridges/source/remote/urp/urp_property.hxx
@@ -0,0 +1,94 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+#ifndef _URP_PROPERTY_HXX_
+#define _URP_PROPERTY_HXX_
+#include <bridges/remote/remote.h>
+#include <rtl/ustring.hxx>
+#include <rtl/byteseq.hxx>
+
+namespace bridges_urp
+{
+ struct Properties
+ {
+ ::rtl::ByteSequence seqBridgeID;
+ sal_Int32 nTypeCacheSize;
+ sal_Int32 nOidCacheSize;
+ sal_Int32 nTidCacheSize;
+ ::rtl::OUString sSupportedVersions;
+ ::rtl::OUString sVersion;
+ sal_Int32 nFlushBlockSize;
+ sal_Int32 nOnewayTimeoutMUSEC;
+ sal_Bool bSupportsMustReply;
+ sal_Bool bSupportsSynchronous;
+ sal_Bool bSupportsMultipleSynchronous;
+ sal_Bool bClearCache;
+ sal_Bool bNegotiate;
+ sal_Bool bForceSynchronous;
+ sal_Bool bCurrentContext;
+
+ inline Properties()
+ : nTypeCacheSize( 256 )
+ , nOidCacheSize( 256 )
+ , nTidCacheSize( 256 )
+ , sSupportedVersions( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "1.0" ) ) )
+ , sVersion( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "1.0" )))
+ , nFlushBlockSize( 4*1024 )
+ , nOnewayTimeoutMUSEC( 10000 )
+ , bSupportsMustReply( sal_False )
+ , bSupportsSynchronous( sal_False )
+ , bSupportsMultipleSynchronous( sal_False )
+ , bClearCache( sal_False )
+ , bNegotiate( sal_True )
+ , bForceSynchronous( sal_True )
+ , bCurrentContext( sal_False )
+ {}
+
+ inline Properties & SAL_CALL operator = ( const Properties &props )
+ {
+ seqBridgeID = props.seqBridgeID;
+ nTypeCacheSize = props.nTypeCacheSize;
+ nOidCacheSize = props.nOidCacheSize;
+ nTidCacheSize = props.nTidCacheSize;
+ sSupportedVersions = props.sSupportedVersions;
+ sVersion = props.sVersion;
+ nFlushBlockSize = props.nFlushBlockSize;
+ nOnewayTimeoutMUSEC = props.nOnewayTimeoutMUSEC;
+ bSupportsMustReply = props.bSupportsMustReply;
+ bSupportsSynchronous = props.bSupportsSynchronous;
+ bSupportsMultipleSynchronous = props.bSupportsMultipleSynchronous;
+ bClearCache = props.bClearCache;
+ bNegotiate = props.bNegotiate;
+ bForceSynchronous = props.bForceSynchronous;
+ bCurrentContext = props.bCurrentContext;
+ return *this;
+ }
+ };
+} // end namespace bridges_urp
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_propertyobject.cxx b/bridges/source/remote/urp/urp_propertyobject.cxx
new file mode 100644
index 000000000000..323faee2e929
--- /dev/null
+++ b/bridges/source/remote/urp/urp_propertyobject.cxx
@@ -0,0 +1,796 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <stdlib.h>
+#include <osl/diagnose.h>
+
+#include <rtl/random.h>
+
+#include <uno/data.h>
+
+#include "com/sun/star/bridge/InvalidProtocolChangeException.hpp"
+#include <com/sun/star/bridge/XProtocolProperties.hpp>
+
+#include "urp_propertyobject.hxx"
+#include "urp_dispatch.hxx"
+#include "urp_bridgeimpl.hxx"
+#include "urp_job.hxx"
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::bridge;
+using namespace ::com::sun::star::uno;
+
+using namespace bridges_urp;
+
+extern "C" {
+
+static void SAL_CALL staticAcquire( remote_Interface *pRemoteI )
+{
+ PropertyObject *pProperties = (PropertyObject *) pRemoteI;
+ pProperties->thisAcquire();
+}
+
+static void SAL_CALL staticRelease( remote_Interface *pRemoteI )
+{
+ PropertyObject *pProperties = (PropertyObject *) pRemoteI;
+ pProperties->thisRelease();
+}
+
+static void SAL_CALL staticDispatch(
+ remote_Interface * pRemoteI, typelib_TypeDescription const * pMemberType,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ PropertyObject *pProperties = (PropertyObject *) pRemoteI;
+ pProperties->thisDispatch( pMemberType, pReturn, pArgs, ppException );
+}
+
+}
+
+namespace bridges_urp
+{
+// some nice constants ....
+static const sal_Int32 METHOD_QUERY_INTERFACE = 0;
+static const sal_Int32 METHOD_GET_PROPERTIES = 3;
+static const sal_Int32 METHOD_REQUEST_CHANGE = 4;
+static const sal_Int32 METHOD_COMMIT_CHANGE = 5;
+
+static const sal_Int32 PROPERTY_BRIDGEID = 0;
+static const sal_Int32 PROPERTY_TYPECACHESIZE = 1;
+static const sal_Int32 PROPERTY_OIDCACHESIZE = 2;
+static const sal_Int32 PROPERTY_TIDCACHESIZE = 3;
+static const sal_Int32 PROPERTY_SUPPORTEDVERSIONS = 4;
+static const sal_Int32 PROPERTY_VERSION =5;
+static const sal_Int32 PROPERTY_FLUSHBLOCKSIZE = 6;
+static const sal_Int32 PROPERTY_ONEWAYTIMEOUT_MUSEC = 7;
+static const sal_Int32 PROPERTY_SUPPORTSMUSTREPLY = 8;
+static const sal_Int32 PROPERTY_SUPPERTSSYNCHRONOUS = 9;
+static const sal_Int32 PROPERTY_SUPPORTSMULTIPLESYNCHRONOUS = 10;
+static const sal_Int32 PROPERTY_CLEARCACHE = 11;
+static const sal_Int32 PROPERTY_NEGOTIATE = 12;
+static const sal_Int32 PROPERTY_FORCESYNCHRONOUS = 13;
+static const sal_Int32 PROPERTY_CURRENTCONTEXT = 14;
+
+static const sal_Int32 MAX_PROPERTIES = PROPERTY_CURRENTCONTEXT +1;
+
+const sal_Char *g_aPropertyName[] =
+{
+ "BridgeId",
+ "TypeCacheSize",
+ "OidCacheSize",
+ "TidCacheSize",
+ "SupportedVersion",
+ "Version",
+ "FlushBlockSize",
+ "OnewayTimeoutMUSEC",
+ "SupportsMustReply",
+ "SupportsSynchronous",
+ "SupportsMultipleSynchronous",
+ "ClearCache",
+ "Negotiate",
+ "ForceSynchronous",
+ "CurrentContext"
+};
+
+// nice little helper functions for conversion
+template< class t >
+void assignToIdl( ProtocolProperty *pIdl, sal_Int32 nIndex, const t &value )
+{
+ pIdl->Name = OUString::createFromAscii( g_aPropertyName[nIndex] );
+ ( *(::com::sun::star::uno::Any *)&(pIdl->Value) ) <<= value;
+}
+
+template< class t >
+void assignFromIdl( t * p, const ProtocolProperty & property )
+{
+ property.Value >>=*p;
+}
+
+static sal_Int32 getIndexFromIdl( const ProtocolProperty & property )
+{
+ sal_Int32 nResult = -1;
+ for( sal_Int32 i = 0 ; i < MAX_PROPERTIES ; i ++ )
+ {
+ if( 0 == property.Name.compareToAscii( g_aPropertyName[i] ) )
+ {
+ nResult = i;
+ break;
+ }
+ }
+ return nResult;
+}
+
+static sal_Int32 getIndexFromString( const OUString & property )
+{
+ sal_Int32 nResult = -1;
+ for( sal_Int32 i = 0 ; i < MAX_PROPERTIES ; i ++ )
+ {
+ if( 0 == property.compareToAscii( g_aPropertyName[i] ) )
+ {
+ nResult = i;
+ break;
+ }
+ }
+ return nResult;
+}
+
+static sal_Bool assignFromIdlToStruct( Properties *pProps, const ProtocolProperty &idl )
+{
+ sal_Bool bReturn = sal_True;
+
+ sal_Int32 nIndex = getIndexFromIdl( idl );
+ if( nIndex >= 0 )
+ {
+ switch( nIndex )
+ {
+ case PROPERTY_SUPPORTSMULTIPLESYNCHRONOUS:
+ assignFromIdl( &(pProps->bSupportsMultipleSynchronous) , idl );
+ break;
+ case PROPERTY_SUPPERTSSYNCHRONOUS:
+ assignFromIdl( &(pProps->bSupportsMustReply) , idl );
+ break;
+ case PROPERTY_SUPPORTSMUSTREPLY:
+ assignFromIdl( &(pProps->bSupportsSynchronous) , idl );
+ break;
+ case PROPERTY_ONEWAYTIMEOUT_MUSEC:
+ assignFromIdl( &(pProps->nOnewayTimeoutMUSEC) , idl );
+ break;
+ case PROPERTY_BRIDGEID:
+ assignFromIdl( (Sequence< sal_Int8 > * )&(pProps->seqBridgeID), idl );
+ break;
+ case PROPERTY_TYPECACHESIZE:
+ assignFromIdl( &(pProps->nTypeCacheSize) , idl );
+ break;
+ case PROPERTY_OIDCACHESIZE:
+ assignFromIdl( &(pProps->nOidCacheSize) , idl );
+ break;
+ case PROPERTY_TIDCACHESIZE:
+ assignFromIdl( &(pProps->nTidCacheSize), idl );
+ break;
+ case PROPERTY_SUPPORTEDVERSIONS:
+ assignFromIdl( &(pProps->sSupportedVersions) , idl );
+ break;
+ case PROPERTY_VERSION:
+ assignFromIdl( &(pProps->sVersion) , idl );
+ break;
+ case PROPERTY_FLUSHBLOCKSIZE:
+ assignFromIdl( &(pProps->nFlushBlockSize) ,idl );
+ break;
+ case PROPERTY_CLEARCACHE:
+ assignFromIdl( &(pProps->bClearCache) ,idl );
+ break;
+ case PROPERTY_NEGOTIATE:
+ assignFromIdl( &(pProps->bNegotiate) ,idl );
+ break;
+ case PROPERTY_FORCESYNCHRONOUS:
+ assignFromIdl( &(pProps->bForceSynchronous) ,idl );
+ break;
+ case PROPERTY_CURRENTCONTEXT:
+ pProps->bCurrentContext = true;
+ break;
+ default:
+ bReturn = sal_False;
+ }
+ }
+ else
+ {
+ bReturn = sal_False;
+ }
+ return bReturn;
+}
+
+static void extractTokens(
+ const ::rtl::OUString &sProps , ::std::list< OUString > &lst )
+{
+ sal_Int32 nNext = 0;
+ while ( sal_True )
+ {
+ sal_Int32 nStart = nNext;
+ nNext = sProps.indexOf( ',' , nNext );
+ if( -1 == nNext )
+ {
+ lst.push_back( sProps.copy( nStart, sProps.getLength() - nStart ) );
+ break;
+ }
+ lst.push_back( sProps.copy( nStart , nNext - nStart ) );
+ nNext ++;
+ }
+}
+
+
+static void assignFromStringToPropSeq( const OUString &sProps, uno_Sequence **ppPropertySeq)
+{
+ ::std::list< OUString > lst;
+ extractTokens( sProps , lst );
+
+ typelib_TypeDescription *pSequenceType = 0;
+ getCppuType( (Sequence< ProtocolProperty > *)0).getDescription( &pSequenceType );
+ uno_Sequence *pSeq = 0;
+ uno_sequence_construct( &pSeq , pSequenceType , 0, lst.size() , 0 );
+ ProtocolProperty *pElements = (ProtocolProperty * ) pSeq->elements;
+
+ sal_Int32 i = 0;
+ for( ::std::list< OUString >::iterator ii = lst.begin() ; ii != lst.end() ; ++ ii, i++ )
+ {
+ sal_Int32 nAssign = (*ii).indexOf( '=' );
+ if( -1 == nAssign )
+ {
+ OString o = OUStringToOString( *ii, RTL_TEXTENCODING_ASCII_US );
+ OSL_ENSURE( !"wrong protocol propertyt format, ignored", o.getStr() );
+ }
+ OUString sPropName = (*ii).copy( 0, nAssign );
+ OUString sValue = (*ii).copy( nAssign +1, (*ii).getLength() - nAssign -1 );
+
+ sal_Int32 nIndex = getIndexFromString( sPropName );
+ if( -1 == nIndex )
+ {
+ OString o = OUStringToOString( sPropName , RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE( !"unknown protocol property, ignored", o.getStr() );
+ }
+ switch( nIndex )
+ {
+ // voids
+ case PROPERTY_CURRENTCONTEXT:
+ pElements[i].Name = OUString::createFromAscii(
+ g_aPropertyName[nIndex] );
+ break;
+ // bools
+ case PROPERTY_CLEARCACHE:
+ case PROPERTY_NEGOTIATE:
+ case PROPERTY_FORCESYNCHRONOUS:
+ {
+ sal_Bool bClearCache = (sal_Bool ) sValue.toInt32();
+ assignToIdl( &(pElements[i]) , nIndex , bClearCache );
+ break;
+ }
+ // ints
+ case PROPERTY_TYPECACHESIZE:
+ case PROPERTY_OIDCACHESIZE:
+ case PROPERTY_TIDCACHESIZE:
+ case PROPERTY_FLUSHBLOCKSIZE:
+ case PROPERTY_ONEWAYTIMEOUT_MUSEC:
+ {
+ sal_Int32 nValue = sValue.toInt32();
+ assignToIdl( &(pElements[i]) , nIndex , nValue );
+ break;
+ }
+
+ // strings
+ case PROPERTY_VERSION:
+ assignToIdl( &(pElements[i]) , nIndex , sValue );
+ break;
+ default:
+ OString o = OUStringToOString( sPropName, RTL_TEXTENCODING_ASCII_US );
+ OSL_ENSURE( !"readonly protocol property, ignored" , o.getStr() );
+ }
+ }
+ *ppPropertySeq = pSeq;
+ typelib_typedescription_release( pSequenceType );
+}
+
+static void assignFromPropSeqToStruct( uno_Sequence *pSeq , struct Properties *pProps )
+{
+ sal_Int32 i;
+ ProtocolProperty *pElements = (ProtocolProperty *)pSeq->elements;
+ for( i = 0 ; i < pSeq->nElements ; i ++ )
+ {
+ assignFromIdlToStruct( pProps , pElements[i] );
+ }
+}
+
+void assignFromStringToStruct( const OUString & sProps , struct Properties *pProps )
+{
+ uno_Sequence *pSeq = 0;
+ assignFromStringToPropSeq( sProps , &pSeq );
+ assignFromPropSeqToStruct( pSeq , pProps );
+ uno_type_destructData( &pSeq, getCppuType( (Sequence< ProtocolProperty > *)0).getTypeLibType(),0);
+}
+
+
+//----------------------------------------------------------------------------------------------
+// PropertyObject implementation
+PropertyObject::PropertyObject(
+ struct Properties *pLocalSetting , uno_Environment *pEnvRemote, urp_BridgeImpl *pImpl )
+ : m_commitChangeCondition( osl_createCondition() )
+ , m_nRefCount( 0 )
+ , m_pBridgeImpl( pImpl )
+ , m_pLocalSetting( pLocalSetting )
+ , m_pEnvRemote( pEnvRemote )
+ , m_bRequestChangeHasBeenCalled( sal_False )
+ , m_bServerWaitingForCommit( sal_False )
+ , m_bApplyProperties( sal_False )
+{
+ acquire = staticAcquire;
+ release = staticRelease;
+ pDispatcher = staticDispatch;
+}
+
+PropertyObject::~PropertyObject()
+{
+ osl_destroyCondition( m_commitChangeCondition );
+}
+
+void SAL_CALL PropertyObject::thisDispatch(
+ typelib_TypeDescription const * pMemberType, void * pReturn, void * ppArgs[],
+ uno_Any ** ppException )
+{
+ OSL_ASSERT( pMemberType->eTypeClass == typelib_TypeClass_INTERFACE_METHOD );
+
+ typelib_InterfaceMethodTypeDescription *pMethodType =
+ ( typelib_InterfaceMethodTypeDescription * ) pMemberType;
+
+ switch( pMethodType->aBase.nPosition )
+ {
+ case METHOD_QUERY_INTERFACE:
+ OSL_ENSURE( 0 , "not implemented yet !" );
+ break;
+ case METHOD_GET_PROPERTIES:
+ {
+ implGetProperties( (uno_Sequence **) pReturn );
+ *ppException = 0;
+ break;
+ }
+ case METHOD_COMMIT_CHANGE:
+ {
+ implCommitChange( *(uno_Sequence ** ) ppArgs[0] , ppException );
+ break;
+ }
+ case METHOD_REQUEST_CHANGE:
+ {
+ *(sal_Int32 *) pReturn = implRequestChange( *(sal_Int32 *)ppArgs[0], ppException );
+ break;
+ }
+ default:
+ OSL_ENSURE( 0 , "unkown method !" );
+ }
+}
+
+void SAL_CALL PropertyObject::localGetPropertiesFromRemote( struct Properties *pR )
+{
+ OUString oid = OUString::createFromAscii( g_NameOfUrpProtocolPropertiesObject );
+
+ typelib_TypeDescription *pInterfaceType = 0;
+ getCppuType( (Reference< XProtocolProperties > *) 0 ).getDescription( &pInterfaceType );
+
+ if( !pInterfaceType->bComplete )
+ {
+ typelib_typedescription_complete( &pInterfaceType );
+ }
+
+ typelib_TypeDescription *pMethodType = 0;
+ typelib_typedescriptionreference_getDescription(
+ &pMethodType,
+ ((typelib_InterfaceTypeDescription*) pInterfaceType)->ppAllMembers[METHOD_GET_PROPERTIES] );
+
+
+ uno_Sequence *pResult = 0;
+ uno_Any exception;
+ uno_Any *pException = &exception;
+ urp_sendRequest( m_pEnvRemote,
+ pMethodType,
+ oid.pData,
+ (typelib_InterfaceTypeDescription*) pInterfaceType,
+ &pResult,
+ 0,
+ &pException );
+
+ if( pException )
+ {
+ OSL_ENSURE( 0 , "remote urp-bridge doesn't support property-object" );
+ uno_any_destruct( pException , 0 );
+ return;
+ }
+
+ ProtocolProperty *pP = (ProtocolProperty * ) pResult->elements;
+ for( sal_Int32 i = 0; i < pResult->nElements ; i ++ )
+ {
+ if( ! assignFromIdlToStruct( pR , pP[i] ) )
+ {
+ OSL_ENSURE( 0 , "unknown property !!!!" );
+ }
+ }
+
+ typelib_typedescription_release( pInterfaceType );
+ typelib_typedescription_release( pMethodType );
+}
+
+
+// implementation for call from remote
+void SAL_CALL PropertyObject::implGetProperties( uno_Sequence **ppReturnValue )
+{
+ typelib_TypeDescription *pElementType= 0;
+ getCppuType( (Sequence< ProtocolProperty > *)0).getDescription( &pElementType );
+
+ OSL_ENSURE( pElementType , "Couldn't get property type" );
+
+ *ppReturnValue = 0;
+ uno_sequence_construct( ppReturnValue , pElementType , 0, MAX_PROPERTIES , 0 );
+ ProtocolProperty *pElements = (ProtocolProperty * ) ( *ppReturnValue )->elements;
+ Properties *pP = m_pLocalSetting;
+
+ assignToIdl( &(pElements[PROPERTY_BRIDGEID]),PROPERTY_BRIDGEID, toUnoSequence(pP->seqBridgeID) );
+ assignToIdl( &(pElements[PROPERTY_TYPECACHESIZE]),PROPERTY_TYPECACHESIZE,pP->nTypeCacheSize );
+ assignToIdl( &(pElements[PROPERTY_OIDCACHESIZE]),PROPERTY_OIDCACHESIZE, pP->nOidCacheSize );
+ assignToIdl( &(pElements[PROPERTY_TIDCACHESIZE]),PROPERTY_TIDCACHESIZE, pP->nTidCacheSize );
+ assignToIdl( &(pElements[PROPERTY_SUPPORTEDVERSIONS]),PROPERTY_SUPPORTEDVERSIONS, pP->sSupportedVersions );
+ assignToIdl( &(pElements[PROPERTY_VERSION]),PROPERTY_VERSION, pP->sVersion );
+ assignToIdl( &(pElements[PROPERTY_FLUSHBLOCKSIZE]), PROPERTY_FLUSHBLOCKSIZE,pP->nFlushBlockSize );
+ assignToIdl( &(pElements[PROPERTY_ONEWAYTIMEOUT_MUSEC]), PROPERTY_ONEWAYTIMEOUT_MUSEC, pP->nOnewayTimeoutMUSEC );
+ assignToIdl( &(pElements[PROPERTY_SUPPORTSMUSTREPLY]), PROPERTY_SUPPORTSMUSTREPLY, pP->bSupportsMustReply );
+ assignToIdl( &(pElements[PROPERTY_SUPPERTSSYNCHRONOUS]), PROPERTY_SUPPERTSSYNCHRONOUS, pP->bSupportsSynchronous );
+ assignToIdl( &(pElements[PROPERTY_SUPPORTSMULTIPLESYNCHRONOUS]), PROPERTY_SUPPORTSMULTIPLESYNCHRONOUS, pP->bSupportsMultipleSynchronous );
+ assignToIdl( &(pElements[PROPERTY_CLEARCACHE]), PROPERTY_CLEARCACHE, pP->bClearCache );
+
+ typelib_typedescription_release( pElementType );
+}
+
+//----------------------------------------------------------------------------------------------
+sal_Int32 SAL_CALL PropertyObject::localRequestChange( )
+{
+ sal_Int32 nResult = 0;
+ sal_Bool bCall = sal_True;
+
+ // disallow marshaling NOW !
+ ClearableMutexGuard marshalingGuard( m_pBridgeImpl->m_marshalingMutex );
+ {
+ MutexGuard guard( m_mutex );
+ if( m_bRequestChangeHasBeenCalled || m_bServerWaitingForCommit )
+ {
+ // another transaction is already underway
+ // try again later !
+ bCall = sal_False;
+ }
+ m_bRequestChangeHasBeenCalled = sal_True;
+
+ if( bCall )
+ {
+ // calulate random number
+ rtlRandomPool pool = rtl_random_createPool ();
+ rtl_random_getBytes( pool , &m_nRandomNumberOfRequest, sizeof( m_nRandomNumberOfRequest ) );
+ rtl_random_destroyPool( pool );
+ }
+ }
+
+ if( bCall )
+ {
+ OUString oid = OUString::createFromAscii( g_NameOfUrpProtocolPropertiesObject );
+
+ // gather types for calling
+ typelib_TypeDescription *pInterfaceType = 0;
+ getCppuType( (Reference< XProtocolProperties > *) 0 ).getDescription( &pInterfaceType );
+
+ if( !pInterfaceType->bComplete )
+ {
+ typelib_typedescription_complete( &pInterfaceType );
+ }
+
+ typelib_TypeDescription *pMethodType = 0;
+ typelib_typedescriptionreference_getDescription(
+ &pMethodType,
+ ((typelib_InterfaceTypeDescription*) pInterfaceType)->ppAllMembers[METHOD_REQUEST_CHANGE] );
+
+ void *pArg1 = &m_nRandomNumberOfRequest;
+ void **ppArgs = &pArg1;
+
+ uno_Any exception;
+ uno_Any *pException = &exception;
+
+ ClientJob job( m_pEnvRemote,
+ 0,
+ m_pBridgeImpl,
+ oid.pData,
+ pMethodType,
+ (typelib_InterfaceTypeDescription*) pInterfaceType,
+ &nResult,
+ ppArgs,
+ &pException );
+
+ // put the call on the line !
+ sal_Bool bSuccess = job.pack();
+
+ // now allow writing on wire again.
+ // NOTE : this has been locked, because it is inevitable to set m_bRequestChangeHasBeenCalled
+ // and call requestChange in an atomar operation. Otherwise, implRequestChange may be called
+ // inbetween and reply, before the request is put on the wire. This certainly would
+ // be confusing for the remote counterpart !
+ marshalingGuard.clear();
+
+ // wait for the reply ...
+ if( bSuccess )
+ {
+ job.wait();
+
+ if( pException )
+ {
+ // the object is unknown on the other side.
+ uno_any_destruct( pException , 0 );
+ nResult = 0;
+ }
+ }
+ else
+ {
+ nResult = 0;
+ }
+ typelib_typedescription_release( pInterfaceType );
+ typelib_typedescription_release( pMethodType );
+ }
+
+ {
+ MutexGuard guard( m_mutex );
+ m_bRequestChangeHasBeenCalled = sal_False;
+ m_bServerWaitingForCommit = ( 0 == nResult );
+ }
+ return nResult;
+}
+
+// implementation for call from remote
+sal_Int32 SAL_CALL PropertyObject::implRequestChange( sal_Int32 nRandomNumber, uno_Any **ppException )
+{
+ sal_Int32 nResult = 0;
+ MutexGuard guard( m_mutex );
+ if( m_bRequestChangeHasBeenCalled )
+ {
+ // this side has also called requestChange, now negotiate, which side is allowed
+ // to commit the change !
+ if( m_nRandomNumberOfRequest > nRandomNumber )
+ {
+ // this side may commit !!!!
+ nResult = 0;
+ }
+ else if( m_nRandomNumberOfRequest == nRandomNumber )
+ {
+ // sorry, try again !
+ nResult = -1;
+ }
+ else if( m_nRandomNumberOfRequest < nRandomNumber )
+ {
+ // the other side may commit !
+ nResult = 1;
+ // m_bServerWaitingForCommit will be set by localRequestChange
+ }
+ }
+ else
+ {
+ // This side has NOT called requestChange, so the other side may commit
+ nResult = 1;
+ m_bServerWaitingForCommit = sal_True;
+ }
+
+ *ppException = 0;
+ return nResult;
+}
+
+
+
+void SAL_CALL PropertyObject::localCommitChange( const ::rtl::OUString &sProps , sal_Bool *pbExceptionThrown )
+{
+ // lock the bridge NOW !
+ // NOTE: it is not allowed for other threads to call, when a commit change is underway.
+ // The remote counterpart cannot if the call following the commit already uses
+ // the new properties or not.
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+
+ OUString oid = OUString::createFromAscii( g_NameOfUrpProtocolPropertiesObject );
+
+ osl_resetCondition( m_commitChangeCondition );
+
+ Properties props = *m_pLocalSetting;
+
+ typelib_TypeDescription *pInterfaceType = 0;
+ getCppuType( (Reference< XProtocolProperties > *) 0 ).getDescription( &pInterfaceType );
+
+ if( !pInterfaceType->bComplete )
+ {
+ typelib_typedescription_complete( &pInterfaceType );
+ }
+
+ typelib_TypeDescription *pMethodType = 0;
+ typelib_typedescriptionreference_getDescription(
+ &pMethodType,
+ ((typelib_InterfaceTypeDescription*) pInterfaceType)->ppAllMembers[METHOD_COMMIT_CHANGE] );
+
+// typelib_TypeDescription *pSequenceType= 0;
+
+
+ // extract name/value pairs
+ uno_Sequence *pSeq = 0;
+ assignFromStringToPropSeq( sProps, &pSeq );
+ assignFromPropSeqToStruct( pSeq , &props );
+// ::std::list< OUString > lst;
+// extractTokens( sProps , lst );
+
+// getCppuType( (Sequence< ProtocolProperty > *)0).getDescription( &pSequenceType );
+// uno_sequence_construct( &pSeq , pSequenceType , 0, lst.size() , 0 );
+// ProtocolProperty *pElements = (ProtocolProperty * ) pSeq->elements;
+
+// sal_Int32 i = 0;
+// for( ::std::list< OUString >::iterator ii = lst.begin() ; ii != lst.end() ; ++ ii, i++ )
+// {
+// sal_Int32 nAssign = (*ii).indexOf( '=' );
+// if( -1 == nAssign )
+// {
+// OString o = OUStringToOString( *ii, RTL_TEXTENCODING_ASCII_US );
+// OSL_ENSURE( !"wrong protocol propertyt format, ignored", o.getStr() );
+// }
+// OUString sPropName = (*ii).copy( 0, nAssign );
+// OUString sValue = (*ii).copy( nAssign +1, (*ii).getLength() - nAssign -1 );
+
+// sal_Int32 nIndex = getIndexFromString( sPropName );
+// if( -1 == nIndex )
+// {
+// OString o = OUStringToOString( sPropName , RTL_TEXTENCODING_ASCII_US);
+// OSL_ENSURE( !"unknown protocol property, ignored", o.getStr() );
+// }
+// switch( nIndex )
+// {
+// // bools
+// case PROPERTY_CLEARCACHE:
+// {
+// sal_Bool bClearCache = (sal_Bool ) sValue.toInt32();
+// assignToIdl( &(pElements[i]) , nIndex , bClearCache );
+// break;
+// }
+// // ints
+// case PROPERTY_TYPECACHESIZE:
+// case PROPERTY_OIDCACHESIZE:
+// case PROPERTY_TIDCACHESIZE:
+// case PROPERTY_FLUSHBLOCKSIZE:
+// case PROPERTY_ONEWAYTIMEOUT_MUSEC:
+// {
+// sal_Int32 nValue = sValue.toInt32();
+// assignToIdl( &(pElements[i]) , nIndex , nValue );
+// break;
+// }
+
+// // strings
+// case PROPERTY_VERSION:
+// assignToIdl( &(pElements[i]) , nIndex , sValue );
+// break;
+// default:
+// OString o = OUStringToOString( sPropName, RTL_TEXTENCODING_ASCII_US );
+// OSL_ENSURE( !"readonly protocol property, ignored" , o.getStr() );
+// }
+// assignFromIdlToStruct( &props, pElements[i] );
+// }
+
+ void *pArg1 = &pSeq;
+ uno_Any exception;
+ uno_Any *pException = &exception;
+
+ ClientJob job( m_pEnvRemote,
+ 0,
+ m_pBridgeImpl,
+ oid.pData,
+ pMethodType,
+ (typelib_InterfaceTypeDescription*) pInterfaceType,
+ 0,
+ &pArg1,
+ &pException );
+ job.setBridgePropertyCall();
+ if( job.pack() )
+ {
+ job.wait();
+ }
+ else
+ {
+ OSL_ASSERT( pException != NULL );
+ }
+
+ ::uno_type_destructData(
+ &pSeq, getCppuType( (Sequence< ProtocolProperty > *)0).getTypeLibType(), 0 );
+
+ *pbExceptionThrown = pException ? sal_True : sal_False;
+
+ if( pException )
+ {
+ OString o = OUStringToOString( ((com::sun::star::uno::Exception*)pException->pData)->Message,
+ RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE( !"exception thrown during calling on PropertyObject",o.getStr() );
+ uno_any_destruct( pException , 0 );
+ }
+ else
+ {
+ m_pBridgeImpl->applyProtocolChanges( props );
+ m_bServerWaitingForCommit = sal_False;
+ m_bApplyProperties = sal_False;
+ }
+
+ // let the reader thread go ...
+ osl_setCondition( m_commitChangeCondition );
+
+ typelib_typedescription_release( pMethodType );
+ typelib_typedescription_release( pInterfaceType );
+}
+
+void SAL_CALL PropertyObject::implCommitChange( uno_Sequence *pSequence, uno_Any **ppException )
+{
+ MutexGuard guard( m_mutex );
+ m_propsToBeApplied = *m_pLocalSetting;
+
+ ProtocolProperty *pP = (ProtocolProperty * ) pSequence->elements;
+ for( sal_Int32 i = 0; i < pSequence->nElements ; i ++ )
+ {
+ if( ! assignFromIdlToStruct( &m_propsToBeApplied , pP[i] ) )
+ {
+ InvalidProtocolChangeException exception;
+ Type type = getCppuType( &exception );
+ exception.Message = OUString(RTL_CONSTASCII_USTRINGPARAM("urp: unknown Property "));
+ exception.Message += pP[i].Name;
+ exception.invalidProperty = pP[i];
+ exception.reason = 1;
+
+ uno_type_any_construct( *ppException, &exception, type.getTypeLibType() , 0 );
+
+ m_bApplyProperties = sal_False;
+ m_bServerWaitingForCommit = sal_False;
+ return;
+ }
+ }
+
+ m_bApplyProperties = sal_True;
+ *ppException = 0;
+}
+
+Properties SAL_CALL PropertyObject::getCommitedChanges()
+{
+ MutexGuard guard( m_mutex );
+ OSL_ASSERT( m_bApplyProperties );
+ m_bApplyProperties = sal_False;
+ m_bServerWaitingForCommit = sal_False;
+ return m_propsToBeApplied;
+}
+
+void SAL_CALL PropertyObject::waitUntilChangesAreCommitted()
+{
+ osl_waitCondition( m_commitChangeCondition , 0 );
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_propertyobject.hxx b/bridges/source/remote/urp/urp_propertyobject.hxx
new file mode 100644
index 000000000000..d6cfbc84ff95
--- /dev/null
+++ b/bridges/source/remote/urp/urp_propertyobject.hxx
@@ -0,0 +1,107 @@
+/* -*- 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 <stdio.h>
+#include <osl/interlck.h>
+#include <osl/mutex.hxx>
+
+#include <osl/conditn.h>
+#include <rtl/string.hxx>
+#include <uno/sequence2.h>
+
+#include <bridges/remote/remote.h>
+#include "urp_property.hxx"
+
+namespace bridges_urp {
+
+struct urp_BridgeImpl;
+const sal_Char g_NameOfUrpProtocolPropertiesObject[] = "UrpProtocolProperties";
+
+// helper functions
+void assignFromStringToStruct( const ::rtl::OUString & sProps , struct Properties *pProps );
+
+class PropertyObject : public remote_Interface
+{
+private:
+ ::osl::Mutex m_mutex;
+ oslCondition m_commitChangeCondition;
+ oslInterlockedCount m_nRefCount;
+ urp_BridgeImpl *m_pBridgeImpl;
+ struct Properties *m_pLocalSetting;
+ struct Properties m_propsToBeApplied;
+
+ uno_Environment *m_pEnvRemote;
+ sal_Int32 m_nRandomNumberOfRequest;
+ sal_Bool m_bRequestChangeHasBeenCalled;
+ sal_Bool m_bServerWaitingForCommit;
+ sal_Bool m_bApplyProperties;
+
+public:
+ PropertyObject(
+ struct Properties *pLocalSetting , uno_Environment *pEnvRemote, urp_BridgeImpl *pImpl );
+ ~PropertyObject();
+
+ void SAL_CALL thisAcquire( )
+ {
+ osl_incrementInterlockedCount( &m_nRefCount );
+ }
+
+ void SAL_CALL thisRelease()
+ {
+ if( ! osl_decrementInterlockedCount( &m_nRefCount ) )
+ {
+ delete this;
+ }
+ }
+
+ void SAL_CALL thisDispatch( typelib_TypeDescription const * pMemberType,
+ void * pReturn,
+ void * pArgs[],
+ uno_Any ** ppException );
+
+public: // local
+ sal_Int32 SAL_CALL localRequestChange( );
+ void SAL_CALL localCommitChange( const ::rtl::OUString &properties, sal_Bool *pbExceptionThrown );
+ void SAL_CALL localGetPropertiesFromRemote( struct Properties * );
+
+ // returns 0, if nothing was commited.
+ inline sal_Bool SAL_CALL changesHaveBeenCommited()
+ { return m_bApplyProperties; }
+ Properties SAL_CALL getCommitedChanges();
+
+ void SAL_CALL waitUntilChangesAreCommitted();
+
+protected:
+ // these methods are called by thisDispatch
+ void SAL_CALL implGetProperties( uno_Sequence **ppReturnValue );
+ sal_Int32 SAL_CALL implRequestChange( sal_Int32 nRandomNumber, uno_Any **ppException );
+ void SAL_CALL implCommitChange( uno_Sequence *seqOfProperties, uno_Any **ppException );
+};
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_reader.cxx b/bridges/source/remote/urp/urp_reader.cxx
new file mode 100644
index 000000000000..00941c468e1b
--- /dev/null
+++ b/bridges/source/remote/urp/urp_reader.cxx
@@ -0,0 +1,835 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <string.h>
+
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+
+#include <bridges/remote/connection.h>
+#include <bridges/remote/counter.hxx>
+#include <bridges/remote/context.h>
+#include <bridges/remote/helper.hxx>
+
+#include <com/sun/star/uno/XCurrentContext.hpp>
+#include <uno/environment.h>
+
+#include "urp_reader.hxx"
+#include "urp_writer.hxx"
+#include "urp_dispatch.hxx"
+#include "urp_job.hxx"
+#include "urp_bridgeimpl.hxx"
+#include "urp_log.hxx"
+#include "urp_propertyobject.hxx"
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+
+#if OSL_DEBUG_LEVEL > 1
+static MyCounter thisCounter( "DEBUG : ReaderThread" );
+#endif
+
+namespace bridges_urp
+{
+
+ /**
+ * This callback is used to ensure, that the release call is sent for the correct type.
+ *
+ ***/
+ void SAL_CALL urp_releaseRemoteCallback (
+ remote_Interface *, rtl_uString *pOid,
+ typelib_TypeDescriptionReference *pTypeRef, uno_Environment *pEnvRemote )
+ {
+ remote_Context *pContext = (remote_Context *) pEnvRemote->pContext;
+ urp_BridgeImpl *pImpl = (urp_BridgeImpl*) ( pContext->m_pBridgeImpl );
+
+ pImpl->m_pWriter->insertReleaseRemoteCall( pOid , pTypeRef );
+ }
+
+
+ struct MessageFlags
+ {
+ sal_uInt16 nMethodId;
+ sal_Bool bRequest;
+ sal_Bool bType;
+ sal_Bool bOid;
+ sal_Bool bTid;
+ sal_Bool bException;
+ sal_Bool bMustReply;
+ sal_Bool bSynchronous;
+ sal_Bool bMoreFlags;
+ sal_Bool bIgnoreCache;
+ sal_Bool bBridgePropertyCall;
+ ///--------------------------
+ inline MessageFlags()
+ {
+ bTid = sal_False;
+ bOid = sal_False;
+ bType = sal_False;
+ bException = sal_False;
+ bMoreFlags = sal_False;
+ bIgnoreCache = sal_False;
+ bBridgePropertyCall = sal_False;
+ }
+ //---------------------------
+ }; // end struct MessageFlags
+
+inline sal_Bool OReaderThread::getMemberTypeDescription(
+ typelib_InterfaceAttributeTypeDescription **ppAttributeType,
+ typelib_InterfaceMethodTypeDescription **ppMethodType,
+ sal_Bool *pbIsSetter,
+ sal_uInt16 nMethodId ,
+ typelib_TypeDescriptionReference * pITypeRef )
+{
+ if( pITypeRef->eTypeClass != typelib_TypeClass_INTERFACE )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "interface type is not of typeclass interface (" );
+ sMessage.append( (sal_Int32) pITypeRef->eTypeClass );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+ OSL_ENSURE( 0 , "type is not an interface" );
+ return sal_False;
+ }
+
+ typelib_InterfaceTypeDescription *pInterfaceType = 0;
+ TYPELIB_DANGER_GET(
+ (typelib_TypeDescription **)&pInterfaceType , pITypeRef );
+ if( ! pInterfaceType )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "No typedescription can be retrieved for type " );
+ sMessage.append( OUString( pITypeRef->pTypeName ) );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+ OSL_ENSURE( 0 , "urp: unknown type " );
+ return sal_False;
+ }
+
+ if( ! pInterfaceType->aBase.bComplete )
+ {
+ typelib_typedescription_complete( (typelib_TypeDescription **) &pInterfaceType );
+ }
+
+ if ( nMethodId >= pInterfaceType->nMapFunctionIndexToMemberIndex )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "vtable out of range for type " );
+ sMessage.append( OUString( pITypeRef->pTypeName ) );
+ sMessage.appendAscii( " (" );
+ sMessage.append( (sal_Int32) nMethodId );
+ sMessage.appendAscii( " )" );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+
+ OSL_ENSURE( 0 , "vtable index out of range" );
+ return sal_False;
+ }
+
+ sal_Int32 nMemberIndex = pInterfaceType->pMapFunctionIndexToMemberIndex[ nMethodId ];
+
+ if( !( pInterfaceType->nAllMembers > nMemberIndex && nMemberIndex >= 0 ) )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "vtable out of range for type " );
+ sMessage.append( OUString( pITypeRef->pTypeName ) );
+ sMessage.appendAscii( " (" );
+ sMessage.append( (sal_Int32) nMethodId );
+ sMessage.appendAscii( " )" );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+
+ OSL_ENSURE( 0 , "vtable index out of range" );
+ return sal_False;
+ }
+
+ typelib_InterfaceMemberTypeDescription *pMemberType = 0;
+ typelib_typedescriptionreference_getDescription(
+ (typelib_TypeDescription **) &pMemberType,pInterfaceType->ppAllMembers[nMemberIndex]);
+
+ if(! pMemberType )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "unknown method type description for type" );
+ sMessage.append( OUString( pITypeRef->pTypeName ) );
+ sMessage.appendAscii( " (" );
+ sMessage.append( (sal_Int32) nMethodId );
+ sMessage.appendAscii( " )" );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+
+ OSL_ENSURE( 0 , "unknown method type description" );
+ return sal_False;
+ }
+
+ if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pMemberType->aBase.eTypeClass )
+ {
+ // Note: pMapMemberIndexToFunctionIndex always contains the function
+ // index of the attribute getter! setter function index is getter index
+ // + 1.
+ *ppAttributeType = (typelib_InterfaceAttributeTypeDescription *) pMemberType;
+ *pbIsSetter = ! (
+ pInterfaceType->pMapMemberIndexToFunctionIndex[nMemberIndex] == nMethodId );
+ }
+ else
+ {
+ *ppMethodType = (typelib_InterfaceMethodTypeDescription *) pMemberType;
+ }
+
+ TYPELIB_DANGER_RELEASE( (typelib_TypeDescription * )pInterfaceType );
+ return sal_True;
+}
+
+OReaderThread::OReaderThread( remote_Connection *pConnection,
+ uno_Environment *pEnvRemote,
+ OWriterThread * pWriterThread ) :
+ m_pConnection( pConnection ),
+ m_pEnvRemote( pEnvRemote ),
+ m_pWriterThread( pWriterThread ),
+ m_bDestroyMyself( sal_False ),
+ m_bContinue( sal_True ),
+ m_pBridgeImpl((struct urp_BridgeImpl*)
+ ((remote_Context *)pEnvRemote->pContext)->m_pBridgeImpl ),
+ m_unmarshal( m_pBridgeImpl, m_pEnvRemote, ::bridges_remote::remote_createStub )
+{
+ m_pEnvRemote->acquireWeak( m_pEnvRemote );
+ m_pConnection->acquire( m_pConnection );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+
+OReaderThread::~OReaderThread( )
+{
+ m_pEnvRemote->releaseWeak( m_pEnvRemote );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+}
+
+// may only be called in the callstack of this thread !!!!!
+// run() -> dispose() -> destroyYourself()
+void OReaderThread::destroyYourself()
+{
+ m_bDestroyMyself = sal_True;
+ m_pConnection->release( m_pConnection );
+ m_pConnection = 0;
+ m_bContinue = sal_False;
+}
+
+void OReaderThread::onTerminated()
+{
+ if( m_bDestroyMyself )
+ {
+ delete this;
+ }
+}
+
+
+void OReaderThread::disposeEnvironment()
+{
+ struct remote_Context *pContext =
+ ( struct remote_Context * ) m_pEnvRemote->pContext;
+ m_bContinue = sal_False;
+ if( ! pContext->m_pBridgeImpl->m_bDisposed )
+ {
+ uno_Environment *pEnvRemote = 0;
+ m_pEnvRemote->harden( &pEnvRemote , m_pEnvRemote );
+ if( pEnvRemote )
+ {
+ pEnvRemote->dispose( m_pEnvRemote );
+ pEnvRemote->release( m_pEnvRemote );
+ }
+ else
+ {
+ // environment has been disposed eitherway !
+ }
+ }
+}
+
+inline sal_Bool OReaderThread::readBlock( sal_Int32 *pnMessageCount )
+{
+ m_unmarshal.setSize( 8 );
+ if( 8 != m_pConnection->read( m_pConnection , m_unmarshal.getBuffer(), 8 ) )
+ {
+ OUString s( RTL_CONSTASCII_USTRINGPARAM( "Unexpected connection closure" ) );
+ m_pBridgeImpl->addError( s );
+ return sal_False;
+ }
+
+ sal_Int32 nSize;
+ m_unmarshal.unpackInt32( &nSize );
+ m_unmarshal.unpackInt32( pnMessageCount );
+
+ if( nSize < 0 )
+ {
+ // buffer too big
+ // no exception can be thrown, because there is no thread id, which could be
+ // used. -> terminate !
+ OUStringBuffer s;
+ s.appendAscii( "Packet-size too big (" );
+ s.append( (sal_Int64) (sal_uInt32 ) nSize );
+ s.append( sal_Unicode( ')' ) );
+ m_pBridgeImpl->addError( s.makeStringAndClear() );
+ OSL_ENSURE( 0 , "urp bridge: Packet-size too big" );
+ return sal_False;
+ }
+
+ if( 0 == nSize )
+ {
+ // normal termination !
+ return sal_False;
+ }
+
+ // allocate the necessary memory
+ if( ! m_unmarshal.setSize( nSize ) )
+ {
+ OUStringBuffer s;
+ s.appendAscii( "Packet-size too big, couln't allocate necessary memory (" );
+ s.append( (sal_Int64) (sal_uInt32 ) nSize );
+ s.append( sal_Unicode( ')' ) );
+ m_pBridgeImpl->addError( s.makeStringAndClear() );
+ OSL_ENSURE( 0 , "urp bridge: messages size too large, terminating connection" );
+ return sal_False;
+ }
+
+ sal_Int32 nRead = m_pConnection->read( m_pConnection , m_unmarshal.getBuffer() , nSize );
+
+ if( nSize != nRead )
+ {
+ OUStringBuffer s;
+ s.appendAscii( "Unexpected connection closure, inconsistent packet (" );
+ s.append( (sal_Int64) (sal_uInt32 ) nSize );
+ s.appendAscii( " asked, " );
+ s.append( (sal_Int64) (sal_uInt32 ) nRead );
+ s.appendAscii( " got )" );
+ m_pBridgeImpl->addError( s.makeStringAndClear() );
+ // couldn't get the asked amount of bytes, quit
+ // should only occur, when the environment has already been disposed
+ OSL_ENSURE( m_pBridgeImpl->m_bDisposed , "urp bridge: inconsistent packet, terminating connection." );
+ return sal_False;
+ }
+ return sal_True;
+}
+
+inline sal_Bool OReaderThread::readFlags( struct MessageFlags *pFlags )
+{
+ sal_uInt8 nBitField;
+ if( ! m_unmarshal.unpackInt8( &nBitField ) )
+ {
+ m_pBridgeImpl->addError( "Unexpected end of message header (1)" );
+ return sal_False;
+ }
+
+ if( HDRFLAG_LONGHEADER & nBitField )
+ {
+ // this is a long header, interpret the byte as bitfield
+ pFlags->bTid = (HDRFLAG_NEWTID & nBitField );
+ pFlags->bRequest = (HDRFLAG_REQUEST & nBitField);
+
+ if( pFlags->bRequest )
+ {
+ // request
+ pFlags->bType = ( HDRFLAG_NEWTYPE & nBitField );
+ pFlags->bOid = ( HDRFLAG_NEWOID & nBitField );
+ pFlags->bIgnoreCache = ( HDRFLAG_IGNORECACHE & nBitField );
+ pFlags->bMoreFlags = ( HDRFLAG_MOREFLAGS & nBitField );
+
+ if( pFlags->bMoreFlags )
+ {
+ // another byte with flags
+ sal_Int8 moreFlags;
+ if( ! m_unmarshal.unpackInt8( &moreFlags ) )
+ {
+ m_pBridgeImpl->addError( "Unexpected end of message header (2)" );
+ return sal_False;
+ }
+ pFlags->bSynchronous = ( HDRFLAG_SYNCHRONOUS & moreFlags );
+ pFlags->bMustReply = ( HDRFLAG_MUSTREPLY & moreFlags );
+ OSL_ENSURE( (pFlags->bSynchronous && pFlags->bMustReply) ||
+ (!pFlags->bSynchronous && !pFlags->bMustReply),
+ "urp-bridge : customized calls currently not supported !");
+ }
+
+ if( HDRFLAG_LONGMETHODID & nBitField )
+ {
+ // methodid as unsigned short
+ if( ! m_unmarshal.unpackInt16( &(pFlags->nMethodId )) )
+ {
+ m_pBridgeImpl->addError( "Unexpected end of message header (3)" );
+ return sal_False;
+ }
+ }
+ else
+ {
+ sal_uInt8 id;
+ if( ! m_unmarshal.unpackInt8( &id ) )
+ {
+ m_pBridgeImpl->addError( "Unexpected end of message header (4)" );
+ return sal_False;
+ }
+ pFlags->nMethodId = (sal_uInt16) id;
+ }
+ }
+ else
+ {
+ // reply
+ pFlags->bRequest = sal_False;
+ pFlags->bException = ( HDRFLAG_EXCEPTION & nBitField );
+ }
+ }
+ else
+ {
+ // short request
+ pFlags->bRequest = sal_True;
+ if( 0x40 & nBitField )
+ {
+ sal_uInt8 lower;
+ if( ! m_unmarshal.unpackInt8( &lower ) )
+ {
+ m_pBridgeImpl->addError( "Unexpected end of message header (5)" );
+ return sal_False;
+ }
+ pFlags->nMethodId = ( nBitField & 0x3f ) << 8 | lower;
+ }
+ else
+ {
+ pFlags->nMethodId = ( nBitField & 0x3f );
+ }
+ }
+ return sal_True;
+}
+
+void OReaderThread::run()
+{
+ // This vars are needed to hold oid,tid and type information, which should not be cached.
+ Type lastTypeNoCache;
+ OUString lastOidNoCache;
+ ByteSequence lastTidNoCache;
+
+ while( m_bContinue )
+ {
+ sal_Int32 nMessageCount;
+ if( ! readBlock( &nMessageCount ) )
+ {
+ disposeEnvironment();
+ break;
+ }
+
+ uno_Environment *pEnvRemote = 0;
+ m_pEnvRemote->harden( &pEnvRemote , m_pEnvRemote );
+ if( !pEnvRemote )
+ {
+ // environment has been disposed already, quit here
+ break;
+ }
+ ServerMultiJob *pMultiJob = 0;
+ remote_Interface *pLastRemoteI = 0;
+ while( ! m_unmarshal.finished() )
+ {
+#ifdef BRIDGES_URP_PROT
+ sal_uInt32 nLogStart = m_unmarshal.getPos();
+ sal_Bool bIsOneWay = sal_False;
+ OUString sMemberName;
+#endif
+ MessageFlags flags;
+
+ if( ! readFlags( &flags ) )
+ {
+ m_pBridgeImpl->addError( "incomplete message, skipping block" );
+ OSL_ENSURE ( 0 , "urp-bridge : incomplete message, skipping block" );
+ break;
+ }
+
+ // use these ** to access the ids fast ( avoid acquire/release calls )
+ sal_Sequence **ppLastTid = flags.bIgnoreCache ?
+ (sal_Sequence **) &lastTidNoCache :
+ (sal_Sequence **) &(m_pBridgeImpl->m_lastInTid);
+ rtl_uString **ppLastOid = flags.bIgnoreCache ?
+ (rtl_uString ** ) &lastOidNoCache :
+ (rtl_uString ** ) &(m_pBridgeImpl->m_lastInOid);
+ typelib_TypeDescriptionReference **ppLastType =
+ flags.bIgnoreCache ?
+ (typelib_TypeDescriptionReference ** ) &lastTypeNoCache :
+ (typelib_TypeDescriptionReference ** ) &(m_pBridgeImpl->m_lastInType);
+
+ // get new type
+ if( flags.bType )
+ {
+ typelib_TypeDescriptionReference *pTypeRef = 0;
+ if( m_unmarshal.unpackType( &pTypeRef ) )
+ {
+ // release the old type
+ typelib_typedescriptionreference_release( *ppLastType );
+ // set the new type
+ *ppLastType = pTypeRef;
+
+ // no release on pTypeRef necessary (will be released by type dtor)
+ }
+ else
+ {
+ typelib_typedescriptionreference_release( pTypeRef );
+ m_pBridgeImpl->addError( "error during unpacking (maybe cached) interface type" );
+ OSL_ENSURE( 0 , "urp-bridge : error during unpacking interface type, terminating connection" );
+ disposeEnvironment();
+ break;
+ }
+ if( m_pBridgeImpl->m_lastInType.getTypeClass() != TypeClass_INTERFACE )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "interface type is not of typeclass interface (" );
+ sMessage.append( (sal_Int32) m_pBridgeImpl->m_lastInType.getTypeClass() );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+ OSL_ENSURE( 0 , "urp-bridge : not an interface type" );
+ disposeEnvironment();
+ break;
+ }
+ }
+ if( flags.bOid )
+ {
+ rtl_uString *pOid = 0;
+ if( m_unmarshal.unpackOid( &pOid ) )
+ {
+ rtl_uString_release( *ppLastOid );
+ *ppLastOid = pOid;
+ }
+ else
+ {
+ rtl_uString_release( pOid );
+ m_pBridgeImpl->addError( "error during unpacking (maybe cached) oid" );
+ OSL_ENSURE( 0 , "urp-bridge : error during unpacking cached data, terminating connection" );
+ disposeEnvironment();
+ break;
+ }
+ }
+
+ if( flags.bTid )
+ {
+ sal_Sequence *pSeq = 0;
+ if( m_unmarshal.unpackTid( &pSeq ) )
+ {
+ rtl_byte_sequence_release( *ppLastTid );
+ *ppLastTid = pSeq;
+ }
+ else
+ {
+ rtl_byte_sequence_release( pSeq );
+
+ m_pBridgeImpl->addError( "error during unpacking (maybe cached) tid" );
+ OSL_ENSURE( 0 , "urp-bridge : error during unpacking cached data, terminating connection" );
+ disposeEnvironment();
+ break;
+ }
+ }
+
+ // do the job
+ if( flags.bRequest )
+ {
+ bool bHasCc = m_pBridgeImpl->m_properties.bCurrentContext
+ && flags.nMethodId != REMOTE_RELEASE_METHOD_INDEX
+ && !rtl::OUString( *ppLastOid ).equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ g_NameOfUrpProtocolPropertiesObject ) );
+ remote_Interface * pCc = 0;
+ if ( bHasCc )
+ {
+ typelib_TypeDescription * pType = 0;
+ TYPELIB_DANGER_GET(
+ &pType,
+ XCurrentContext::static_type().getTypeLibType() );
+ bool ok = m_unmarshal.unpack( &pCc, pType );
+ TYPELIB_DANGER_RELEASE( pType );
+ if ( !ok )
+ {
+ OSL_ENSURE(
+ false,
+ ("urp_bridge: error while unpacking current"
+ " context") );
+ disposeEnvironment();
+ break;
+ }
+ }
+
+ //--------------------------
+ // handle request
+ //--------------------------
+ // get the membertypedescription
+ typelib_InterfaceMethodTypeDescription *pMethodType = 0;
+ typelib_InterfaceAttributeTypeDescription *pAttributeType = 0;
+ sal_Bool bIsSetter = sal_False;
+
+ if( getMemberTypeDescription(
+ &pAttributeType, &pMethodType, &bIsSetter,
+ flags.nMethodId, *ppLastType ) )
+ {
+ if( ! pLastRemoteI || flags.bOid || flags.bType )
+ {
+ // a new interface must be retrieved
+
+ // retrieve the interface NOW from the environment
+ // (avoid race conditions : oneway followed by release )
+ typelib_InterfaceTypeDescription *pInterfaceType = 0;
+
+ TYPELIB_DANGER_GET(
+ (typelib_TypeDescription ** ) &pInterfaceType ,
+ *ppLastType );
+ if( !pInterfaceType )
+ {
+ OUStringBuffer sMessage;
+ sMessage.appendAscii( "Couldn't retrieve type description for type " );
+ sMessage.append( OUString( (*ppLastType)->pTypeName ) );
+ m_pBridgeImpl->addError( sMessage.makeStringAndClear() );
+ delete pMultiJob;
+ pMultiJob = 0;
+ disposeEnvironment();
+ pLastRemoteI = 0; // stubs are released during dispose eitherway
+ break;
+ }
+ pEnvRemote->pExtEnv->getRegisteredInterface(
+ pEnvRemote->pExtEnv, ( void ** ) &pLastRemoteI,
+ *ppLastOid, pInterfaceType );
+ TYPELIB_DANGER_RELEASE( (typelib_TypeDescription * )pInterfaceType );
+
+ if( !pLastRemoteI &&
+ REMOTE_RELEASE_METHOD_INDEX != flags.nMethodId &&
+ 0 == rtl_ustr_ascii_compare_WithLength(
+ (*ppLastOid)->buffer, (*ppLastOid)->length, g_NameOfUrpProtocolPropertiesObject ) )
+ {
+ // check for bridge internal propertyobject
+ pLastRemoteI = m_pBridgeImpl->m_pPropertyObject;
+ pLastRemoteI->acquire( pLastRemoteI );
+ flags.bBridgePropertyCall = sal_True;
+ }
+
+ // NOTE : Instance provider is called in the executing thread
+ // Otherwise, instance provider may block the bridge
+ }
+
+ sal_Bool bCallIsOneway = sal_False;
+ if( flags.bMoreFlags )
+ {
+ // flags override the default !
+ bCallIsOneway = ! flags.bSynchronous;
+ }
+ else if( pMethodType && pMethodType->bOneWay )
+ {
+ bCallIsOneway = sal_True;
+ }
+
+ if( pMultiJob && ! flags.bTid && bCallIsOneway && ! pMultiJob->isFull())
+ {
+ // add to the existing multijob, nothing to do here
+ }
+ else
+ {
+ // create a new multijob
+ if( pMultiJob )
+ {
+ // there exists an old one, start it first.
+ pMultiJob->initiate();
+ }
+
+ pMultiJob = new ServerMultiJob(
+ pEnvRemote,
+ static_cast< remote_Context * >(
+ pEnvRemote->pContext ),
+ *ppLastTid, m_pBridgeImpl, &m_unmarshal,
+ nMessageCount );
+ }
+
+ pMultiJob->setCurrentContext( bHasCc, pCc );
+ pMultiJob->setIgnoreCache( flags.bIgnoreCache );
+ pMultiJob->setType( *ppLastType );
+ if( pMethodType )
+ {
+ pMultiJob->setMethodType( pMethodType ,
+ REMOTE_RELEASE_METHOD_INDEX == flags.nMethodId,
+ bCallIsOneway );
+ }
+ else if( pAttributeType )
+ {
+ pMultiJob->setAttributeType( pAttributeType, bIsSetter, bCallIsOneway );
+ }
+ else
+ {
+ OSL_ASSERT( 0 );
+ }
+
+ if( pLastRemoteI )
+ pMultiJob->setInterface( pLastRemoteI );
+ else
+ pMultiJob->setOid( *ppLastOid );
+ } /* getMemberTypeDescription */
+ else
+ {
+ delete pMultiJob;
+ pMultiJob = 0;
+ pLastRemoteI = 0; // stubs are released during dispose eitherway
+ disposeEnvironment();
+ break;
+ }
+#ifdef BRIDGES_URP_PROT
+ bIsOneWay = pMethodType && pMethodType->bOneWay;
+ sMemberName = pMethodType ?
+ pMethodType->aBase.pMemberName :
+ pAttributeType->aBase.pMemberName;
+ sal_uInt32 nLogHeader = m_unmarshal.getPos();
+#endif
+ if( ! pMultiJob->extract( ) )
+ {
+ // severe error during extracting, dispose
+ delete pMultiJob;
+ pMultiJob = 0;
+ pLastRemoteI = 0; // stubs are released during dispose eitherway
+ disposeEnvironment();
+ break;
+ }
+
+#ifdef BRIDGES_URP_PROT
+ urp_logServingRequest(
+ m_pBridgeImpl, m_unmarshal.getPos() - nLogStart,
+ m_unmarshal.getPos() - nLogHeader,
+ !bIsOneWay,
+ sMemberName );
+#endif
+ if ( flags.bBridgePropertyCall )
+ {
+ // call to the bridge internal object.
+ // these calls MUST be executed within the dispatcher thread in order
+ // to synchronize properly with protocol changes
+ // NOTE : Threadid is not preserved for this call.
+
+ // lock the marshaling NOW !
+ {
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+
+ pMultiJob->execute();
+
+ if( m_pBridgeImpl->m_pPropertyObject->changesHaveBeenCommited() )
+ {
+ Properties props;
+ props = m_pBridgeImpl->m_pPropertyObject->getCommitedChanges();
+
+ // This call modified the protocol, apply the changes NOW !
+ m_pBridgeImpl->applyProtocolChanges( props );
+ }
+ }
+ delete pMultiJob;
+ pMultiJob = 0;
+ }
+ }
+ else
+ {
+ //--------------------------
+ // handle reply
+ //--------------------------
+ if( pMultiJob )
+ {
+ pMultiJob->initiate();
+ pMultiJob = 0;
+ }
+ if( pLastRemoteI )
+ {
+ pLastRemoteI->release( pLastRemoteI );
+ pLastRemoteI = 0;
+ }
+ ClientJob *pClientJob =
+ m_pBridgeImpl->m_clientJobContainer.remove( *( ByteSequence * )ppLastTid );
+
+ // Bridge MUST be already disposed, otherwise we got a wrong threadid
+ // from remote !
+ OSL_ASSERT( pClientJob || m_pBridgeImpl->m_bDisposed );
+ if( ! pClientJob )
+ {
+ OUStringBuffer error( 128 );
+ error.appendAscii( "ThreadID " );
+ OString o = byteSequence2HumanReadableString( *(ByteSequence* )ppLastTid );
+ error.appendAscii( o.getStr(), o.getLength() );
+ error.appendAscii( " unknown, so couldn't unmarshal reply" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ pLastRemoteI = 0;
+ disposeEnvironment();
+ break;
+ }
+
+ pClientJob->m_bExceptionOccured = flags.bException;
+
+ pClientJob->setUnmarshal( &m_unmarshal );
+#ifdef BRIDGES_URP_PROT
+ sMemberName = pClientJob->m_pMethodType ?
+ pClientJob->m_pMethodType->aBase.pMemberName :
+ pClientJob->m_pAttributeType->aBase.pMemberName;
+ sal_uInt32 nLogHeader = m_unmarshal.getPos();
+#endif
+ if( ! pClientJob->extract( ) )
+ {
+ // severe error during extracting, dispose
+ pLastRemoteI = 0; // stubs are released during dispose eitherway
+ disposeEnvironment();
+ break;
+ }
+#ifdef BRIDGES_URP_PROT
+ urp_logGettingReply(
+ m_pBridgeImpl, m_unmarshal.getPos() - nLogStart,
+ m_unmarshal.getPos() - nLogHeader, sMemberName );
+#endif
+ sal_Bool bBridgePropertyCallAndWaitingForReply =
+ pClientJob->isBridgePropertyCall();
+
+ pClientJob->initiate();
+
+ if( bBridgePropertyCallAndWaitingForReply )
+ {
+ // NOTE : This must be the reply for commit change. The new properties
+ // are now applied by the clientJob thread, but the reader thread
+ // must wait for it, because the next message on the wire already
+ // uses the new protocol settings.
+ // waiting for the commit change reply
+ m_pBridgeImpl->m_pPropertyObject->waitUntilChangesAreCommitted();
+ }
+ }
+ } // end while( !m_unmarshal.finished() )
+
+ if( pLastRemoteI )
+ pLastRemoteI->release( pLastRemoteI );
+
+ if( pMultiJob )
+ pMultiJob->initiate();
+
+ if( pEnvRemote )
+ pEnvRemote->release( pEnvRemote );
+ }
+
+ if( m_pConnection )
+ {
+ m_pConnection->release( m_pConnection );
+ m_pConnection = 0;
+ }
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_reader.hxx b/bridges/source/remote/urp/urp_reader.hxx
new file mode 100644
index 000000000000..aa4042ce197b
--- /dev/null
+++ b/bridges/source/remote/urp/urp_reader.hxx
@@ -0,0 +1,81 @@
+/* -*- 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 <osl/thread.hxx>
+
+#include "urp_unmarshal.hxx"
+
+struct remote_Connection;
+typedef struct _uno_Environment uno_Environment;
+
+namespace bridges_urp
+{
+
+class OWriterThread;
+struct MessageFlags;
+
+class OReaderThread :
+ public ::osl::Thread
+{
+public:
+ OReaderThread( remote_Connection *pConnection ,
+ uno_Environment *pEnvRemote,
+ OWriterThread *pWriterThread );
+ ~OReaderThread();
+
+ // may only be called in the callstack of this thread !!!!!
+ // run() -> disposeEnvironment() -> dispose() -> destroyYourself()
+ void destroyYourself();
+
+private:
+ virtual void SAL_CALL run();
+ virtual void SAL_CALL onTerminated();
+
+ inline sal_Bool readBlock( sal_Int32 *pnMessageCount );
+ inline sal_Bool readFlags( struct MessageFlags *pFlags );
+
+ void disposeEnvironment();
+
+ inline sal_Bool getMemberTypeDescription(
+ typelib_InterfaceAttributeTypeDescription **ppAttributeType,
+ typelib_InterfaceMethodTypeDescription **ppMethodType,
+ sal_Bool *pbIsSetter,
+ sal_uInt16 nMethodId ,
+ typelib_TypeDescriptionReference *pITypeRef);
+
+ remote_Connection *m_pConnection;
+ uno_Environment *m_pEnvRemote;
+ OWriterThread *m_pWriterThread;
+ sal_Bool m_bDestroyMyself;
+ sal_Bool m_bContinue;
+ urp_BridgeImpl *m_pBridgeImpl;
+ Unmarshal m_unmarshal;
+};
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_replycontainer.hxx b/bridges/source/remote/urp/urp_replycontainer.hxx
new file mode 100644
index 000000000000..c8b05ea47435
--- /dev/null
+++ b/bridges/source/remote/urp/urp_replycontainer.hxx
@@ -0,0 +1,78 @@
+/* -*- 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 <hash_map>
+#include <list>
+
+#include <osl/mutex.hxx>
+#include <osl/diagnose.h>
+
+#include "urp_threadid.hxx"
+
+namespace bridges_urp
+{
+ class ClientJob;
+ typedef ::std::hash_map< ::rtl::ByteSequence ,
+ ::std::list < ClientJob * > ,
+ HashThreadId ,
+ EqualThreadId > Id2ClientJobStackMap;
+
+ class urp_ClientJobContainer
+ {
+ public:
+ void add( const ::rtl::ByteSequence &id , ClientJob *p )
+ {
+ ::osl::MutexGuard guard( m_mutex );
+ m_map[id].push_back( p );
+ }
+
+ ClientJob *remove( const ::rtl::ByteSequence & id )
+ {
+ ::osl::MutexGuard guard( m_mutex );
+ Id2ClientJobStackMap::iterator ii = m_map.find( id );
+
+ ClientJob *p = 0;
+ if( ii != m_map.end() )
+ {
+ p = (*ii).second.back();
+ (*ii).second.pop_back();
+ if( (*ii).second.empty() )
+ {
+ m_map.erase( ii );
+ }
+ }
+
+ return p;
+ }
+
+ private:
+ ::osl::Mutex m_mutex;
+ Id2ClientJobStackMap m_map;
+ };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_threadid.cxx b/bridges/source/remote/urp/urp_threadid.cxx
new file mode 100644
index 000000000000..e603a73bab83
--- /dev/null
+++ b/bridges/source/remote/urp/urp_threadid.cxx
@@ -0,0 +1,51 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include "urp_threadid.hxx"
+
+#include <rtl/strbuf.hxx>
+
+using namespace rtl;
+
+namespace bridges_urp
+{
+ rtl::OString byteSequence2HumanReadableString( const rtl::ByteSequence &a )
+ {
+ const sal_uInt8 *p = (const sal_uInt8 * ) a.getConstArray();
+ sal_Int32 nLength = a.getLength();
+ OStringBuffer buf( a.getLength() * 2 + 2 );
+ buf.append( RTL_CONSTASCII_STRINGPARAM( "0x" ) );
+ for( sal_Int32 i = 0 ; i < nLength ; i ++ )
+ buf.append( (sal_Int32) p[i] , 16 );
+ return buf.makeStringAndClear();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_threadid.hxx b/bridges/source/remote/urp/urp_threadid.hxx
new file mode 100644
index 000000000000..e920e2c1e9c3
--- /dev/null
+++ b/bridges/source/remote/urp/urp_threadid.hxx
@@ -0,0 +1,62 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+#ifndef _URP_THREADID_HXX_
+#define _URP_THREADID_HXX_
+
+#include <sal/types.h>
+#include <rtl/byteseq.hxx>
+#include <rtl/string.hxx>
+
+namespace bridges_urp
+{
+
+ struct EqualThreadId
+ {
+ sal_Int32 operator () ( const ::rtl::ByteSequence &a , const ::rtl::ByteSequence &b ) const
+ {
+ return a == b;
+ }
+ };
+
+ struct HashThreadId
+ {
+ sal_Int32 operator () ( const ::rtl::ByteSequence &a ) const
+ {
+ if( a.getLength() >= 4 )
+ {
+ return *(sal_Int32*) a.getConstArray();
+ }
+ return 0;
+ }
+ };
+
+ rtl::OString byteSequence2HumanReadableString( const rtl::ByteSequence &a );
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_unmarshal.cxx b/bridges/source/remote/urp/urp_unmarshal.cxx
new file mode 100644
index 000000000000..5fd124017d4a
--- /dev/null
+++ b/bridges/source/remote/urp/urp_unmarshal.cxx
@@ -0,0 +1,709 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <string.h>
+
+#include <osl/diagnose.h>
+
+#include <rtl/alloc.h>
+#include <rtl/ustrbuf.hxx>
+
+#include <uno/data.h>
+#include <uno/any2.h>
+#include <uno/sequence2.h>
+
+#include <com/sun/star/uno/Any.hxx>
+
+#include "urp_unmarshal.hxx"
+#include "urp_bridgeimpl.hxx"
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace bridges_urp
+{
+static int g_nDetectLittleEndian = 1;
+char g_bSystemIsLittleEndian = ((char*)&g_nDetectLittleEndian)[0];
+
+
+Unmarshal::Unmarshal( struct urp_BridgeImpl *pBridgeImpl,
+ uno_Environment *pEnvRemote,
+ remote_createStubFunc callback ) :
+ m_nBufferSize( 4096 ),
+ m_base( (sal_Int8*) rtl_allocateMemory( m_nBufferSize ) ),
+ m_pos( m_base ),
+ m_nLength( 0 ),
+ m_callback( callback ),
+ m_pEnvRemote( pEnvRemote ),
+ m_pBridgeImpl( pBridgeImpl )
+{
+}
+
+Unmarshal::~Unmarshal()
+{
+ rtl_freeMemory( m_base );
+}
+
+// special unpacks
+sal_Bool Unmarshal::unpackTid( sal_Sequence **ppThreadId )
+{
+ sal_Int32 nSize;
+ sal_Bool bReturn = unpackCompressedSize( &nSize );
+ if( bReturn )
+ {
+ if( nSize )
+ {
+ rtl_byte_sequence_constructFromArray( ppThreadId , m_pos , nSize );
+ m_pos += nSize;
+ sal_uInt16 nIndex;
+ bReturn = unpackInt16( &nIndex );
+ if( nIndex < m_pBridgeImpl->m_properties.nTidCacheSize )
+ {
+ m_pBridgeImpl->m_pTidIn[nIndex] = *(ByteSequence * )ppThreadId;
+ }
+ else if( 0xffff != nIndex )
+ {
+ bReturn = sal_False;
+ rtl_byte_sequence_construct( ppThreadId , 0 );
+
+ OUStringBuffer error( 128 );
+ error.appendAscii( "cache index for tid " );
+ OString o = byteSequence2HumanReadableString( *(ByteSequence * ) ppThreadId );
+ error.appendAscii( o.getStr(), o.getLength() );
+ error.appendAscii( "out of range(0x");
+ error.append( (sal_Int32) nIndex ,16 );
+ error.appendAscii( ")" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+ else
+ {
+ sal_uInt16 nIndex;
+ bReturn = unpackInt16( &nIndex );
+ if( nIndex < m_pBridgeImpl->m_properties.nTidCacheSize )
+ {
+ *ppThreadId = m_pBridgeImpl->m_pTidIn[nIndex].getHandle();
+ rtl_byte_sequence_acquire( *ppThreadId );
+ }
+ else
+ {
+ bReturn = sal_False;
+ rtl_byte_sequence_construct( ppThreadId , 0 );
+ OUStringBuffer error(128);
+ error.appendAscii( "cache index for tids out of range(0x" );
+ error.append( (sal_Int32) nIndex ,16 );
+ error.appendAscii( ")" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+ }
+ else
+ {
+ m_pBridgeImpl->addError( "couldn't unpack thread id because of previous errors" );
+ }
+ return bReturn;
+}
+
+sal_Bool Unmarshal::unpackOid( rtl_uString **ppOid )
+{
+ sal_Bool bReturn = sal_True;
+ sal_uInt16 nCacheIndex = 0;
+
+ bReturn = bReturn && unpackString( ppOid );
+ bReturn = bReturn && unpackInt16( &nCacheIndex );
+
+ if( bReturn &&
+ ! ( 0xffff == nCacheIndex && 0 == (*ppOid)->length ) /* null reference */ )
+ {
+ if( (*ppOid)->length )
+ {
+ // new unknown reference
+ if( 0xffff != nCacheIndex )
+ {
+ // oid should be cached ?
+ if( nCacheIndex < m_pBridgeImpl->m_properties.nOidCacheSize )
+ {
+ m_pBridgeImpl->m_pOidIn[nCacheIndex] = *ppOid;
+ }
+ else
+ {
+ OUStringBuffer error( 128 );
+ error.appendAscii( "new oid provided (" );
+ error.append( *ppOid );
+ error.appendAscii( "), but new cache index is out of range(0x");
+ error.append( (sal_Int32) nCacheIndex ,16 );
+ error.appendAscii( ")" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+
+ bReturn = sal_False;
+ rtl_uString_new( ppOid );
+ }
+ }
+ }
+ else
+ {
+ // reference in cache !
+ if( nCacheIndex < m_pBridgeImpl->m_properties.nOidCacheSize )
+ {
+ rtl_uString_assign( ppOid , m_pBridgeImpl->m_pOidIn[nCacheIndex].pData );
+ }
+ else
+ {
+ bReturn = sal_False;
+ rtl_uString_new( ppOid );
+
+ OUStringBuffer error( 128 );
+ error.appendAscii( "cache index for oids out of range(0x");
+ error.append( (sal_Int32) nCacheIndex ,16 );
+ error.appendAscii( ")" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+ }
+
+ return bReturn;
+}
+
+sal_Bool Unmarshal::unpack( void *pDestination ,
+ typelib_TypeDescription *pTypeDescr )
+{
+ // Note: We implement unpack functionality without recursions in order
+ // to avoid stack overflows caused by rotten URP blocks.
+
+ m_aItemsToUnpack.push( UnpackItem( pDestination, pTypeDescr ) );
+
+ sal_Bool bReturn = sal_True;
+ do
+ {
+ void * pDest = m_aItemsToUnpack.top().pDest;
+ typelib_TypeDescription * pType = m_aItemsToUnpack.top().pType;
+ m_aItemsToUnpack.pop();
+
+ switch( pType->eTypeClass )
+ {
+ case typelib_TypeClass_VOID:
+ // do nothing
+ break;
+ case typelib_TypeClass_BYTE:
+ {
+ bReturn = unpackInt8( pDest );
+ break;
+ }
+ case typelib_TypeClass_BOOLEAN:
+ {
+ bReturn = ! checkOverflow( 1 );
+ if( bReturn )
+ {
+ *((sal_Bool*)pDest) = (sal_Bool ) ( *m_pos);
+ m_pos ++;
+ }
+ else
+ {
+ *((sal_Bool*)pDest) = 0;
+ }
+ break;
+ }
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ {
+ unpackInt16( pDest );
+ break;
+ }
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_FLOAT:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ {
+ bReturn = unpackInt32( pDest );
+ break;
+ }
+ case typelib_TypeClass_DOUBLE:
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ {
+ sal_Int8 * p = static_cast< sal_Int8 * >(pDest);
+ bReturn = ! checkOverflow( 8 );
+ if( bReturn )
+ {
+ if( isSystemLittleEndian() )
+ {
+ p[7] = m_pos[0];
+ p[6] = m_pos[1];
+ p[5] = m_pos[2];
+ p[4] = m_pos[3];
+ p[3] = m_pos[4];
+ p[2] = m_pos[5];
+ p[1] = m_pos[6];
+ p[0] = m_pos[7];
+ }
+ else
+ {
+ p[0] = m_pos[0];
+ p[1] = m_pos[1];
+ p[2] = m_pos[2];
+ p[3] = m_pos[3];
+ p[4] = m_pos[4];
+ p[5] = m_pos[5];
+ p[6] = m_pos[6];
+ p[7] = m_pos[7];
+ }
+ m_pos += 8;
+ }
+ else
+ {
+ // Do not trigger alignment errors:
+ p[0] = p[1] = p[2] = p[3] = p[4] = p[5] = p[6] = p[7] = 0;
+ }
+ break;
+ }
+ case typelib_TypeClass_STRING:
+ {
+ unpackString( pDest );
+ break;
+ }
+ case typelib_TypeClass_ANY:
+ {
+ uno_Any *pAny = ( uno_Any * )pDest;
+
+ pAny->pType = 0;
+ // Type is acquired with typelib_typedescription_acquire
+
+ bReturn = unpackType( &(pAny->pType) );
+
+ typelib_TypeDescription *pDataType = 0;
+ if( bReturn && pAny->pType )
+ {
+ typelib_typedescriptionreference_getDescription( &pDataType , pAny->pType );
+
+ if( pDataType )
+ {
+ switch (pDataType->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (sizeof(void *) < sizeof(sal_Int64))
+ {
+ pAny->pData = rtl_allocateMemory( sizeof(sal_Int64) );
+ }
+ else
+ {
+ pAny->pData = &pAny->pReserved;
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (sizeof(void *) < sizeof(float))
+ {
+ pAny->pData = rtl_allocateMemory( sizeof(float) );
+ }
+ else
+ {
+ pAny->pData = &pAny->pReserved;
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (sizeof(void *) < sizeof(double))
+ {
+ pAny->pData = rtl_allocateMemory( sizeof(double) );
+ }
+ else
+ {
+ pAny->pData = &pAny->pReserved;
+ }
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_UNION:
+ case typelib_TypeClass_EXCEPTION:
+ case typelib_TypeClass_ARRAY:
+ pAny->pData = rtl_allocateMemory( pDataType->nSize );
+ break;
+ case typelib_TypeClass_ANY:
+ {
+ m_pBridgeImpl->addError(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "can't unmarshal any: any in any not supported!" ) ) );
+
+ pAny->pData = 0;
+ Type type; // void
+ pAny->pType = type.getTypeLibType();
+ typelib_typedescriptionreference_acquire( pAny->pType );
+
+ bReturn = sal_False;
+ break;
+ }
+ default:
+ pAny->pData = &pAny->pReserved;
+ }
+
+ if ( bReturn )
+ {
+ m_aItemsToUnpack.push(
+ UnpackItem( pAny->pData, pDataType ) );
+ }
+ }
+ else
+ {
+ OUStringBuffer error;
+ error.appendAscii( "can't unmarshal any because typedescription for " );
+ error.append( pAny->pType->pTypeName );
+ error.appendAscii( " is missing" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+
+ if( pDataType )
+ {
+ typelib_typedescription_release( pDataType );
+ }
+ else
+ {
+ pAny->pData = 0;
+ Type type; // void
+ pAny->pType = type.getTypeLibType();
+ typelib_typedescriptionreference_acquire( pAny->pType );
+
+ bReturn = sal_False;
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE:
+ {
+ *(remote_Interface**)pDest = 0;
+
+ rtl_uString *pString = 0;
+ bReturn = unpackOid( &pString ) && bReturn;
+
+ if( bReturn && pString && pString->length )
+ {
+ m_callback( (remote_Interface**) pDest ,
+ pString,
+ pType->pWeakRef ,
+ m_pEnvRemote,
+ urp_releaseRemoteCallback );
+ }
+ if( pString )
+ {
+ rtl_uString_release( pString );
+ }
+ break;
+ }
+ case typelib_TypeClass_TYPE:
+ {
+ bReturn = unpackType( pDest );
+ break;
+ }
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ {
+ typelib_CompoundTypeDescription * pCompType =
+ (typelib_CompoundTypeDescription *)pType;
+
+ // direct members
+ typelib_TypeDescriptionReference ** ppTypeRefs = pCompType->ppTypeRefs;
+ sal_Int32 * pMemberOffsets = pCompType->pMemberOffsets;
+ sal_Int32 nDescr = pCompType->nMembers;
+
+ // at least assume 1 byte per member
+ bReturn = bReturn && ! checkOverflow( nDescr * 1 );
+ for ( sal_Int32 nPos = nDescr; nPos; --nPos )
+ {
+ typelib_TypeDescription * pMemberType = 0;
+ typelib_typedescriptionreference_getDescription(
+ &pMemberType, ppTypeRefs[ nPos - 1 ] );
+
+ m_aItemsToUnpack.push(
+ UnpackItem( (char*)pDest + pMemberOffsets[ nPos - 1 ],
+ pMemberType,
+ true /* construct even in error case */ ) );
+
+ m_aTypesToRelease.push_back( pMemberType );
+ }
+
+ // parent
+ if (pCompType->pBaseTypeDescription)
+ {
+ m_aItemsToUnpack.push(
+ UnpackItem( pDest,
+ (typelib_TypeDescription *)
+ pCompType->pBaseTypeDescription ) );
+ }
+ break;
+ }
+ case typelib_TypeClass_SEQUENCE:
+ {
+ sal_Int32 nLen;
+ bReturn = unpackCompressedSize( &nLen );
+
+ // urp protocol does not allow to use the elementsize as a guess, if enough data
+ // is available. However, at least one byte per member must be within the message
+ bReturn = bReturn && ! checkOverflow( 1 * nLen );
+ uno_Sequence *pSequence = 0;
+ if( nLen && bReturn )
+ {
+ typelib_TypeDescriptionReference * pETRef =
+ ((typelib_IndirectTypeDescription *)pType)->pType;
+
+ typelib_TypeDescription * pET = 0;
+ typelib_typedescriptionreference_getDescription( &pET , pETRef );
+
+ if( pET )
+ {
+ sal_Int32 nElementSize = pET->nSize;
+
+ pSequence = (uno_Sequence *)rtl_allocateMemory(
+ SAL_SEQUENCE_HEADER_SIZE + nElementSize * nLen );
+ pSequence->nRefCount = 1;
+ pSequence->nElements = nLen;
+
+ if( typelib_TypeClass_BYTE == pET->eTypeClass )
+ {
+ memcpy( pSequence->elements , m_pos , nLen );
+ m_pos += nLen;
+ }
+ else
+ {
+ for ( sal_Int32 i = nLen; i; --i )
+ {
+ m_aItemsToUnpack.push(
+ UnpackItem(
+ ((char*)pSequence->elements)
+ + (i - 1) * nElementSize,
+ pET ) );
+ }
+ }
+ m_aTypesToRelease.push_back( pET );
+ }
+ else
+ {
+ bReturn = sal_False;
+ uno_constructData( &pSequence , pType );
+ OUStringBuffer error;
+ error.appendAscii( "can't unmarshal sequence, because there is no typedescription for element type " );
+ error.append( pETRef->pTypeName );
+ error.appendAscii( " available" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+ else
+ {
+ uno_constructData( &pSequence , pType );
+ }
+
+ *((uno_Sequence **)pDest) = pSequence;
+ break;
+ }
+ case typelib_TypeClass_UNION:
+ case typelib_TypeClass_ARRAY:
+ case typelib_TypeClass_SERVICE:
+ case typelib_TypeClass_MODULE:
+ case typelib_TypeClass_INTERFACE_METHOD:
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ case typelib_TypeClass_UNKNOWN:
+ default:
+ {
+ ::rtl::OUStringBuffer buffer( 128 );
+ buffer.appendAscii( RTL_CONSTASCII_STRINGPARAM("Unsupported typeclass during unmarshaling ("));
+ buffer.append( ( sal_Int32 ) pType->eTypeClass , 10 );
+ buffer.appendAscii( ")" );
+ m_pBridgeImpl->addError( buffer.makeStringAndClear() );
+ bReturn = sal_False;
+ }
+ }
+
+ if ( !bReturn )
+ {
+ // construct default data for every remaining item.
+ while ( !m_aItemsToUnpack.empty() )
+ {
+ const UnpackItem & rItem = m_aItemsToUnpack.top();
+
+ if ( rItem.bMustBeConstructed )
+ uno_constructData( rItem.pDest , rItem.pType );
+
+ m_aItemsToUnpack.pop();
+ }
+ }
+ }
+ while ( !m_aItemsToUnpack.empty() );
+
+ // release pending type descriptions
+ TypeDescVector::const_iterator it = m_aTypesToRelease.begin();
+ const TypeDescVector::const_iterator end = m_aTypesToRelease.end();
+ while ( it != end )
+ {
+ typelib_typedescription_release( *it );
+ it++;
+ }
+ m_aTypesToRelease.clear();
+
+ return bReturn;
+}
+
+sal_Bool Unmarshal::unpackType( void *pDest )
+{
+ *(typelib_TypeDescriptionReference **) pDest = 0;
+
+ sal_uInt8 nTypeClass;
+ sal_Bool bReturn = unpackInt8( &nTypeClass );
+
+ typelib_TypeDescriptionReference *pTypeRef = 0;
+ if( bReturn )
+ {
+ if( nTypeClass <= 14 /* any */ )
+ {
+ pTypeRef = * typelib_static_type_getByTypeClass((typelib_TypeClass )nTypeClass);
+ typelib_typedescriptionreference_acquire( pTypeRef );
+ }
+ else
+ {
+ sal_uInt16 nCacheIndex = 0;
+ bReturn = bReturn && unpackInt16( &nCacheIndex );
+
+ if( bReturn )
+ {
+ if( nTypeClass & 0x80 )
+ {
+ // new type
+ rtl_uString *pString = 0;
+ bReturn = bReturn && unpackString( &pString );
+ if( bReturn )
+ {
+ typelib_TypeDescription *pType = 0;
+ typelib_typedescription_getByName( &pType, pString );
+ if( pType )
+ {
+ // type is known in this process
+ if( (typelib_TypeClass )(nTypeClass & 0x7f) == pType->eTypeClass )
+ {
+ //typename and typeclass match, this is as it should be
+ pTypeRef = pType->pWeakRef;
+ typelib_typedescriptionreference_acquire( pTypeRef );
+ }
+ else
+ {
+ // typename and typeclass do not match, dispose the bridge
+ // as there must be inconsistent type base between both processes
+ // or trash comes over the wire ...
+ bReturn = sal_False;
+ OUStringBuffer error( 128 );
+ error.appendAscii( "it is tried to introduce type " );
+ error.append( pString );
+ error.appendAscii( "with typeclass " );
+ error.append( (sal_Int32)( nTypeClass & 0x7f ) , 10 );
+ error.appendAscii( " , which does not match with typeclass " );
+ error.append( (sal_Int32) pType->eTypeClass ,10 );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ typelib_typedescription_release( pType );
+ pType = 0;
+ }
+ else
+ {
+ // a type by this name is not known in the process.
+ if( (nTypeClass & 0x7f) < typelib_TypeClass_UNKNOWN )
+ {
+ // typeclass is within a valid range, introduce the new
+ // type.
+ typelib_typedescriptionreference_new(
+ &pTypeRef, (typelib_TypeClass )(nTypeClass & 0x7f), pString );
+ }
+ else
+ {
+ // typeclass is out of range !
+ bReturn = sal_False;
+ OUStringBuffer error( 128 );
+ error.appendAscii( "it is tried to introduce type " );
+ error.append( pString );
+ error.appendAscii( "with an out of range typeclass " );
+ error.append( (sal_Int32)( nTypeClass & 0x7f ) , 10 );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+
+ if( bReturn && nCacheIndex != 0xffff )
+ {
+ if( nCacheIndex < m_pBridgeImpl->m_properties.nTypeCacheSize )
+ {
+ m_pBridgeImpl->m_pTypeIn[nCacheIndex] = *( Type * )&pTypeRef;
+ }
+ else
+ {
+ bReturn = sal_False;
+ OUStringBuffer error( 128 );
+ error.appendAscii( "cache index for type " );
+ error.append( pString );
+ error.appendAscii( "out of range(0x" );
+ error.append( (sal_Int32) nCacheIndex ,16 );
+ error.appendAscii( ")" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+ }
+ if( pString )
+ {
+ rtl_uString_release( pString );
+ }
+ }
+ else
+ {
+ if( nCacheIndex < m_pBridgeImpl->m_properties.nTypeCacheSize )
+ {
+ pTypeRef = m_pBridgeImpl->m_pTypeIn[nCacheIndex].getTypeLibType();
+ typelib_typedescriptionreference_acquire( pTypeRef );
+ }
+ else
+ {
+ bReturn = sal_False;
+ OUStringBuffer error;
+ error.appendAscii( "cache index for types out of range(0x" );
+ error.append( (sal_Int32) nCacheIndex ,16 );
+ error.appendAscii( ")" );
+ m_pBridgeImpl->addError( error.makeStringAndClear() );
+ }
+ }
+ }
+ }
+ }
+ if( ! pTypeRef )
+ {
+ pTypeRef = * typelib_static_type_getByTypeClass(typelib_TypeClass_VOID);
+ typelib_typedescriptionreference_acquire( pTypeRef );
+ }
+ // pTypeRef is already acquired
+ *(typelib_TypeDescriptionReference**)pDest = pTypeRef;
+ return bReturn;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_unmarshal.hxx b/bridges/source/remote/urp/urp_unmarshal.hxx
new file mode 100644
index 000000000000..04881d456cce
--- /dev/null
+++ b/bridges/source/remote/urp/urp_unmarshal.hxx
@@ -0,0 +1,281 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+#ifndef _URP_UNMARSHAL_HXX_
+#define _URP_UNMARSHAL_HXX_
+
+#include <stack>
+#include <vector>
+#include <rtl/byteseq.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <bridges/remote/context.h>
+
+#include <bridges/remote/helper.hxx>
+#include <com/sun/star/uno/Type.hxx>
+#include "urp_bridgeimpl.hxx"
+
+typedef struct _uno_Environment uno_Environment;
+struct remote_Interface;
+
+namespace bridges_urp
+{
+
+extern char g_bSystemIsLittleEndian;
+class ThreadId;
+struct urp_BridgeImpl;
+void SAL_CALL urp_releaseRemoteCallback(
+ remote_Interface *pRemoteI,rtl_uString *pOid,
+ typelib_TypeDescriptionReference *pTypeRef,
+ uno_Environment *pEnvRemote );
+
+struct UnpackItem
+{
+ void * pDest;
+ typelib_TypeDescription * pType;
+ bool bMustBeConstructed;
+
+ UnpackItem()
+ : pDest( 0 ), pType( 0 ), bMustBeConstructed( false ) {}
+ UnpackItem( void * d, typelib_TypeDescription * t, bool b = false )
+ : pDest( d ), pType( t ), bMustBeConstructed( b ) {}
+};
+
+typedef std::stack< UnpackItem > UnpackItemStack;
+typedef std::vector< typelib_TypeDescription * > TypeDescVector;
+
+class Unmarshal
+{
+public:
+ Unmarshal(
+ struct urp_BridgeImpl *,
+ uno_Environment *pEnvRemote,
+ remote_createStubFunc callback );
+ ~Unmarshal();
+
+ inline sal_Bool finished()
+ { return m_base + m_nLength == m_pos; }
+ inline sal_uInt32 getPos()
+ { return (sal_uInt32 ) (m_pos - m_base); }
+
+ inline sal_Bool setSize( sal_Int32 nSize );
+
+ sal_Bool unpack( void *pDest, typelib_TypeDescription *pType );
+ inline sal_Bool unpackCompressedSize( sal_Int32 *pData );
+ inline sal_Bool unpackInt8( void *pDest );
+ inline sal_Bool unpackString( void *pDest );
+ inline sal_Bool unpackInt16( void *pDest );
+ inline sal_Bool unpackInt32( void *pDest );
+ sal_Bool unpackType( void *pDest );
+
+ inline sal_Bool unpackAny( void *pDest );
+ sal_Bool unpackOid( rtl_uString **ppOid );
+ sal_Bool unpackTid( sal_Sequence **ppThreadId );
+
+ sal_Int8 *getBuffer()
+ { return m_base; }
+ inline sal_Bool isSystemLittleEndian()
+ { return g_bSystemIsLittleEndian; }
+
+private:
+ inline sal_Bool checkOverflow( sal_Int32 nNextMem );
+
+ UnpackItemStack m_aItemsToUnpack;
+ TypeDescVector m_aTypesToRelease;
+
+ sal_Int32 m_nBufferSize;
+ sal_Int8 *m_base;
+ sal_Int8 *m_pos;
+ sal_Int32 m_nLength;
+
+ remote_createStubFunc m_callback;
+ uno_Environment *m_pEnvRemote;
+ urp_BridgeImpl *m_pBridgeImpl;
+};
+
+inline sal_Bool Unmarshal::setSize( sal_Int32 nSize )
+{
+ if( nSize > m_nBufferSize )
+ {
+ // adjust buffer size and length.
+ sal_Int8 * base =
+ (sal_Int8*)rtl_reallocateMemory (m_base, sal_Size(nSize));
+ if (base != 0)
+ {
+ m_base = base;
+ m_nLength = m_nBufferSize = nSize;
+ }
+ }
+ else
+ {
+ // adjust buffer length, only.
+ m_nLength = nSize;
+ }
+
+ // reset buffer position, and leave.
+ m_pos = m_base;
+ return (m_nLength == nSize);
+}
+
+inline sal_Bool Unmarshal::checkOverflow( sal_Int32 nNextMem )
+{
+ sal_Bool bOverflow = nNextMem < 0 ||
+ (((sal_Int32)( m_pos - m_base )) + nNextMem ) > m_nLength;
+ if( bOverflow )
+ m_pBridgeImpl->addError( "message too short" );
+ return bOverflow;
+}
+
+
+inline sal_Bool Unmarshal::unpackInt8( void *pDest )
+{
+ sal_Bool bReturn = ! checkOverflow( 1 );
+ if( bReturn )
+ {
+ *((sal_Int8*)pDest ) = *m_pos;
+ m_pos++;
+ }
+ else
+ {
+ *((sal_Int8*)pDest ) = 0;
+ }
+ return bReturn;
+}
+
+inline sal_Bool Unmarshal::unpackInt32( void *pDest )
+{
+ sal_uInt32 *p = ( sal_uInt32 * ) pDest;
+ sal_Bool bReturn = ! checkOverflow(4);
+ if( bReturn )
+ {
+ if( isSystemLittleEndian() )
+ {
+ ((sal_Int8*) p )[3] = m_pos[0];
+ ((sal_Int8*) p )[2] = m_pos[1];
+ ((sal_Int8*) p )[1] = m_pos[2];
+ ((sal_Int8*) p )[0] = m_pos[3];
+ }
+ else
+ {
+ ((sal_Int8*) p )[3] = m_pos[3];
+ ((sal_Int8*) p )[2] = m_pos[2];
+ ((sal_Int8*) p )[1] = m_pos[1];
+ ((sal_Int8*) p )[0] = m_pos[0];
+ }
+ m_pos += 4;
+ }
+ else
+ {
+ *p = 0;
+ }
+ return bReturn;
+}
+
+inline sal_Bool Unmarshal::unpackInt16( void *pDest )
+{
+ sal_uInt16 *p = ( sal_uInt16 * ) pDest;
+
+ sal_Bool bReturn = ! checkOverflow( 2 );
+ if( bReturn )
+ {
+ if( isSystemLittleEndian() )
+ {
+ ((sal_Int8*) p )[1] = m_pos[0];
+ ((sal_Int8*) p )[0] = m_pos[1];
+ }
+ else
+ {
+ ((sal_Int8*) p )[1] = m_pos[1];
+ ((sal_Int8*) p )[0] = m_pos[0];
+ }
+ m_pos ++;
+ m_pos ++;
+ }
+ else
+ {
+ *p = 0;
+ }
+ return bReturn;
+}
+
+inline sal_Bool Unmarshal::unpackString( void *pDest )
+{
+ sal_Int32 nLength;
+ sal_Bool bReturn = unpackCompressedSize( &nLength );
+
+ bReturn = bReturn && ! checkOverflow( nLength );
+ if( bReturn )
+ {
+ *(rtl_uString **) pDest = 0;
+ rtl_string2UString( (rtl_uString**) pDest, (const sal_Char * )m_pos , nLength,
+ RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS );
+ m_pos += nLength;
+ }
+ else
+ {
+ *(rtl_uString ** ) pDest = 0;
+ rtl_uString_new( (rtl_uString **) pDest );
+ }
+ return bReturn;
+}
+
+inline sal_Bool Unmarshal::unpackCompressedSize( sal_Int32 *pData )
+{
+ sal_uInt8 n8Size;
+ sal_Bool bReturn = unpackInt8( &n8Size );
+ if( bReturn )
+ {
+ if( n8Size == 0xff )
+ {
+ unpackInt32( pData );
+ }
+ else
+ {
+ *pData = (sal_Int32 ) n8Size;
+ }
+ }
+ return bReturn;
+}
+
+inline sal_Bool Unmarshal::unpackAny( void *pDest )
+{
+ typelib_TypeDescriptionReference *pTypeRef =
+ * typelib_static_type_getByTypeClass( typelib_TypeClass_ANY );
+
+ typelib_TypeDescription * pTD = 0;
+ typelib_typedescriptionreference_getDescription( &pTD, pTypeRef );
+
+ sal_Bool bReturn = unpack( pDest, pTD );
+
+ typelib_typedescription_release( pTD );
+
+ return bReturn;
+}
+
+}
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_writer.cxx b/bridges/source/remote/urp/urp_writer.cxx
new file mode 100644
index 000000000000..58795d9f3359
--- /dev/null
+++ b/bridges/source/remote/urp/urp_writer.cxx
@@ -0,0 +1,271 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <stdio.h>
+#include <osl/time.h>
+
+#include <osl/mutex.hxx>
+#include <osl/conditn.h>
+
+#include <typelib/typedescription.h>
+
+#include <bridges/remote/connection.h>
+#include <bridges/remote/remote.hxx>
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+#include <bridges/remote/counter.hxx>
+
+#include "urp_writer.hxx"
+#include "urp_bridgeimpl.hxx"
+#include "urp_marshal.hxx"
+#include "urp_dispatch.hxx"
+
+#if OSL_DEBUG_LEVEL > 1
+static MyCounter thisCounter( "DEBUG : WriterThread" );
+#endif
+
+using namespace ::osl;
+
+namespace bridges_urp {
+
+OWriterThread::OWriterThread( remote_Connection *pConnection, urp_BridgeImpl *pBridgeImpl,
+ uno_Environment *pEnvRemote) :
+ m_bAbort( sal_False ),
+ m_bInBlockingWait( sal_False ),
+ m_bEnterBlockingWait( sal_False ),
+ m_pConnection( pConnection ),
+ m_pBridgeImpl( pBridgeImpl ),
+ m_pEnvRemote( pEnvRemote )
+
+{
+ m_oslCondition = osl_createCondition();
+ osl_resetCondition( m_oslCondition );
+ m_pConnection->acquire( m_pConnection );
+
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.acquire();
+#endif
+}
+
+OWriterThread::~OWriterThread()
+{
+ osl_destroyCondition( m_oslCondition );
+ m_pConnection->release( m_pConnection );
+#if OSL_DEBUG_LEVEL > 1
+ thisCounter.release();
+#endif
+}
+
+
+// touch is called with locked m_marshalingMutex
+void OWriterThread::touch( sal_Bool bImmediately )
+{
+ if( bImmediately || m_pBridgeImpl->m_blockMarshaler.getPos() > m_pBridgeImpl->m_properties.nFlushBlockSize )
+ {
+ write();
+ }
+ else
+ {
+ // wake the writer thread up
+ if( m_bInBlockingWait )
+ {
+ m_bInBlockingWait = sal_False;
+ osl_setCondition( m_oslCondition );
+ }
+ else
+ {
+ // ensure, that the writing thread does not enter blocking mode
+ m_bEnterBlockingWait = sal_False;
+ }
+ }
+}
+
+
+void OWriterThread::abortThread()
+{
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+
+ m_bAbort = sal_True;
+ m_bEnterBlockingWait = sal_False;
+ if( m_bInBlockingWait )
+ {
+ m_bInBlockingWait = sal_False;
+ osl_setCondition( m_oslCondition );
+ }
+}
+
+
+// must be called with locked marshaling mutex
+void OWriterThread::write()
+{
+ if( ! m_pBridgeImpl->m_blockMarshaler.empty() && ! m_bAbort )
+ {
+ m_pBridgeImpl->m_blockMarshaler.finish( m_pBridgeImpl->m_nMarshaledMessages);
+ m_pBridgeImpl->m_nMarshaledMessages = 0;
+
+ sal_Int32 nLength = m_pBridgeImpl->m_blockMarshaler.getSize();
+ sal_Int8 *pBuf = m_pBridgeImpl->m_blockMarshaler.getBuffer();
+
+ if( nLength != m_pConnection->write( m_pConnection, pBuf, nLength ))
+ {
+ m_pBridgeImpl->m_blockMarshaler.restart();
+ return;
+ }
+ m_pConnection->flush( m_pConnection );
+ m_pBridgeImpl->m_blockMarshaler.restart();
+ }
+}
+
+void OWriterThread::sendEmptyMessage()
+{
+ // must be called with locked marshaling mutex
+ sal_Int32 a[2] = {0,0};
+ m_pConnection->write( m_pConnection , (sal_Int8*) a , sizeof( sal_Int32) *2 );
+}
+
+void OWriterThread::insertReleaseRemoteCall(
+ rtl_uString *pOid,typelib_TypeDescriptionReference *pTypeRef)
+{
+ {
+ ::osl::MutexGuard guard( m_releaseCallMutex );
+
+ struct RemoteReleaseCall call;
+ call.sOid = pOid;
+ call.typeInterface = pTypeRef;
+ m_lstReleaseCalls.push_back( call );
+ }
+ {
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+ if( m_bInBlockingWait )
+ {
+ m_bInBlockingWait = sal_False;
+ osl_setCondition( m_oslCondition );
+ }
+ else
+ {
+ // ensure, that the writing thread does not enter blocking mode
+ m_bEnterBlockingWait = sal_False;
+ }
+ }
+}
+
+/* The release calls for doubled interfaces
+ *
+ *
+ ***/
+void OWriterThread::executeReleaseRemoteCalls()
+{
+ ::std::list< struct RemoteReleaseCall > lstReleaseCalls;
+ {
+ ::osl::MutexGuard guard( m_releaseCallMutex );
+ lstReleaseCalls.swap( m_lstReleaseCalls );
+ }
+
+ for( ::std::list< struct RemoteReleaseCall >::iterator ii = lstReleaseCalls.begin();
+ ii != lstReleaseCalls.end();
+ ++ ii )
+ {
+ struct RemoteReleaseCall &call = (*ii) ;
+
+ typelib_TypeDescription *pInterfaceTypeDesc = 0;
+ typelib_TypeDescription *pReleaseMethod = 0;
+
+ call.typeInterface.getDescription( &pInterfaceTypeDesc );
+ if( ! pInterfaceTypeDesc->bComplete )
+ {
+ typelib_typedescription_complete( &pInterfaceTypeDesc );
+ }
+
+ uno_Any any;
+ uno_Any *pAny = &any;
+
+ typelib_typedescriptionreference_getDescription(
+ &pReleaseMethod ,
+ ((typelib_InterfaceTypeDescription*)pInterfaceTypeDesc)->ppAllMembers[REMOTE_RELEASE_METHOD_INDEX] );
+
+ urp_sendRequest_internal(
+ m_pEnvRemote , pReleaseMethod, call.sOid.pData,
+ (typelib_InterfaceTypeDescription*) pInterfaceTypeDesc, 0, 0,
+ &pAny );
+
+ typelib_typedescription_release( pReleaseMethod );
+ typelib_typedescription_release( pInterfaceTypeDesc );
+ }
+}
+
+
+void OWriterThread::run()
+{
+ while( ! m_bAbort )
+ {
+ sal_Bool bWait;
+ {
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+ bWait = m_bEnterBlockingWait;
+ if( bWait )
+ {
+ osl_resetCondition( m_oslCondition );
+ m_bInBlockingWait = sal_True;
+ }
+ m_bEnterBlockingWait = sal_True;
+ }
+
+ // wait for some notification
+ if( bWait )
+ osl_waitCondition( m_oslCondition , 0 );
+ // (m_bInBlockingWait = sal_False was set by the activating thread)
+
+ if( m_bAbort )
+ break;
+
+ // Wait for the timeout
+ TimeValue value = { 0 , 1000 * m_pBridgeImpl->m_properties.nOnewayTimeoutMUSEC };
+ osl_resetCondition( m_oslCondition );
+ osl_waitCondition( m_oslCondition , &value );
+
+ // check if there are some release calls to be sent ....
+ executeReleaseRemoteCalls();
+
+ {
+ // write to the socket
+ MutexGuard guard( m_pBridgeImpl->m_marshalingMutex );
+ if( ! m_pBridgeImpl->m_blockMarshaler.empty() )
+ {
+ write();
+ }
+ }
+ }
+}
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/remote/urp/urp_writer.hxx b/bridges/source/remote/urp/urp_writer.hxx
new file mode 100644
index 000000000000..041f0b4d753f
--- /dev/null
+++ b/bridges/source/remote/urp/urp_writer.hxx
@@ -0,0 +1,85 @@
+/* -*- 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 <list>
+
+#include <osl/conditn.h>
+#include <osl/mutex.hxx>
+
+#include <rtl/ustring.hxx>
+
+#include <osl/thread.hxx>
+
+#include <com/sun/star/uno/Type.hxx>
+
+struct remote_Connection;
+
+namespace bridges_urp
+{
+ struct RemoteReleaseCall
+ {
+ ::rtl::OUString sOid;
+ ::com::sun::star::uno::Type typeInterface;
+ };
+
+ struct urp_BridgeImpl;
+ class OWriterThread :
+ public ::osl::Thread
+ {
+ public:
+ OWriterThread( remote_Connection *pConnection,
+ urp_BridgeImpl *m_pBridgeImpl,
+ uno_Environment *pEnvRemote);
+ ~OWriterThread( );
+
+ virtual void SAL_CALL run();
+
+ void touch( sal_Bool bImmediately );
+ void sendEmptyMessage();
+
+ void abortThread();
+
+ void SAL_CALL insertReleaseRemoteCall (
+ rtl_uString *pOid,typelib_TypeDescriptionReference *pTypeRef);
+ void SAL_CALL executeReleaseRemoteCalls();
+
+ private:
+ void write();
+ oslCondition m_oslCondition;
+ sal_Bool m_bAbort;
+ sal_Bool m_bInBlockingWait;
+ sal_Bool m_bEnterBlockingWait;
+ remote_Connection *m_pConnection;
+ urp_BridgeImpl *m_pBridgeImpl;
+ uno_Environment *m_pEnvRemote; // this is held weak only
+
+ ::osl::Mutex m_releaseCallMutex;
+ ::std::list< struct RemoteReleaseCall > m_lstReleaseCalls;
+ };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/test/com/sun/star/lib/TestBed.java b/bridges/test/com/sun/star/lib/TestBed.java
new file mode 100644
index 000000000000..2e96a724ebc3
--- /dev/null
+++ b/bridges/test/com/sun/star/lib/TestBed.java
@@ -0,0 +1,232 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.lib;
+
+import com.sun.star.bridge.XBridge;
+import com.sun.star.bridge.XBridgeFactory;
+import com.sun.star.bridge.XInstanceProvider;
+import com.sun.star.comp.helper.Bootstrap;
+import com.sun.star.connection.Acceptor;
+import com.sun.star.connection.Connector;
+import com.sun.star.connection.XAcceptor;
+import com.sun.star.connection.XConnection;
+import com.sun.star.connection.XConnector;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+
+public final class TestBed {
+ public boolean execute(XInstanceProvider provider, boolean waitForServer,
+ Class client, long wait) throws Exception {
+ // assert client.isAssignableFrom(client) && wait >= 0;
+ synchronized (lock) {
+ server = new Server(provider);
+ server.start();
+ server.waitAccepting();
+ }
+ Process p = Runtime.getRuntime().exec(new String[] {
+ "java", "-classpath", System.getProperty("java.class.path"),
+/*
+ "-Xdebug",
+ "-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n",
+*/
+ client.getName() });
+ pipe(p.getInputStream(), System.out, "CO> ");
+ pipe(p.getErrorStream(), System.err, "CE> ");
+ boolean clientDone = false;
+ if (wait <= 0) {
+ clientDone = p.waitFor() == CLIENT_DONE;
+ } else {
+ try {
+ Thread.sleep(wait);
+ } catch (InterruptedException e) {
+ p.destroy();
+ throw e;
+ }
+ try {
+ clientDone = p.exitValue() == CLIENT_DONE;
+ } catch (IllegalThreadStateException e) {
+ p.destroy();
+ }
+ }
+ boolean success = clientDone;
+ if (waitForServer) {
+ success &= server.waitDone();
+ }
+ return success;
+ }
+
+ public void serverDone(boolean success) {
+ synchronized (lock) {
+ server.done(success);
+ }
+ }
+
+ private void pipe(final InputStream in, final PrintStream out,
+ final String prefix) {
+ new Thread("Pipe: " + prefix) {
+ public void run() {
+ BufferedReader r
+ = new BufferedReader(new InputStreamReader(in));
+ try {
+ for (;;) {
+ String s = r.readLine();
+ if (s == null) {
+ break;
+ }
+ out.println(prefix + s);
+ }
+ } catch (java.io.IOException e) {
+ e.printStackTrace(System.err);
+ }
+ }
+ }.start();
+ }
+
+ public static abstract class Client {
+ protected abstract boolean run(XComponentContext context)
+ throws Throwable;
+
+ protected final String getConnectionDescription() {
+ return connectionDescription;
+ }
+
+ protected final String getProtocolDescription() {
+ return protocolDescription;
+ }
+
+ protected final XBridge getBridge(XComponentContext context)
+ throws com.sun.star.uno.Exception
+ {
+ XConnector connector = Connector.create(context);
+ XBridgeFactory factory = UnoRuntime.queryInterface(
+ XBridgeFactory.class,
+ context.getServiceManager().createInstanceWithContext(
+ "com.sun.star.bridge.BridgeFactory", context));
+ System.out.println("Client: Connecting...");
+ XConnection connection = connector.connect(connectionDescription);
+ System.out.println("Client: ...connected...");
+ XBridge bridge = factory.createBridge(
+ "", protocolDescription, connection, null);
+ System.out.println("Client: ...bridged.");
+ return bridge;
+ }
+
+ protected final void execute() {
+ int status = CLIENT_FAILED;
+ try {
+ if (run(Bootstrap.createInitialComponentContext(null))) {
+ status = CLIENT_DONE;
+ }
+ } catch (Throwable e) {
+ e.printStackTrace(System.err);
+ }
+ System.exit(status);
+ }
+ }
+
+ private static final class Server extends Thread {
+ public Server(XInstanceProvider provider) {
+ super("Server");
+ // assert provider != null;
+ this.provider = provider;
+ }
+
+ public void run() {
+ try {
+ XComponentContext context
+ = Bootstrap.createInitialComponentContext(null);
+ XAcceptor acceptor = Acceptor.create(context);
+ XBridgeFactory factory
+ = UnoRuntime.queryInterface(
+ XBridgeFactory.class,
+ context.getServiceManager().createInstanceWithContext(
+ "com.sun.star.bridge.BridgeFactory", context));
+ System.out.println("Server: Accepting...");
+ synchronized (this) {
+ state = ACCEPTING;
+ notifyAll();
+ }
+ for (;;) {
+ XConnection connection = acceptor.accept(
+ connectionDescription);
+ System.out.println("Server: ...connected...");
+ XBridge bridge = factory.createBridge(
+ "", protocolDescription, connection, provider);
+ System.out.println("Server: ...bridged.");
+ }
+ } catch (Throwable e) {
+ e.printStackTrace(System.err);
+ }
+ }
+
+ public synchronized void waitAccepting() throws InterruptedException {
+ while (state < ACCEPTING) {
+ wait();
+ }
+ }
+
+ public synchronized boolean waitDone() throws InterruptedException {
+ while (state <= ACCEPTING) {
+ wait();
+ }
+ return state == SUCCEEDED;
+ }
+
+ public synchronized void done(boolean success) {
+ state = success ? SUCCEEDED : FAILED;
+ notifyAll();
+ }
+
+ private static final int INITIAL = 0;
+ private static final int ACCEPTING = 1;
+ private static final int FAILED = 2;
+ private static final int SUCCEEDED = 3;
+
+ private final XInstanceProvider provider;
+
+ private int state = INITIAL;
+ }
+
+ private static final int TEST_SUCCEEDED = 0;
+ private static final int TEST_FAILED = 1;
+ private static final int TEST_ERROR = 2;
+
+ private static final int CLIENT_FAILED = 0;
+ private static final int CLIENT_DONE = 123;
+
+ private static final String connectionDescription
+ = "socket,host=localhost,port=12345";
+ private static final String protocolDescription = "urp";
+
+ private final Object lock = new Object();
+ private Server server = null;
+}
diff --git a/bridges/test/com/sun/star/lib/makefile.mk b/bridges/test/com/sun/star/lib/makefile.mk
new file mode 100644
index 000000000000..3af025ba8667
--- /dev/null
+++ b/bridges/test/com/sun/star/lib/makefile.mk
@@ -0,0 +1,36 @@
+#*************************************************************************
+#
+# 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 := test_com_sun_star_lib
+
+PACKAGE := com$/sun$/star$/lib
+JAVAFILES := TestBed.java
+JARFILES := juh.jar jurt.jar ridl.jar
+
+.INCLUDE: javaunittest.mk
diff --git a/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug107753_Test.java b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug107753_Test.java
new file mode 100644
index 000000000000..badc38df256e
--- /dev/null
+++ b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug107753_Test.java
@@ -0,0 +1,394 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.lib.uno.bridges.javaremote;
+
+import com.sun.star.bridge.XInstanceProvider;
+import com.sun.star.lib.TestBed;
+import com.sun.star.lib.uno.typeinfo.MethodTypeInfo;
+import com.sun.star.lib.uno.typeinfo.TypeInfo;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.uno.XInterface;
+import complexlib.ComplexTestCase;
+
+/**
+ * Test case for bug #107753#.
+ *
+ * <p>Bug #107753# "Java UNO: Proxies should implement intuitive semantics of
+ * equals and hashCode" requests that two proxies are equal iff they represent
+ * the same UNO object. This implies that if two proxies repsent the same UNO
+ * object, they must have the same hash code.</p>
+ */
+public final class Bug107753_Test extends ComplexTestCase {
+ public String getTestObjectName() {
+ return getClass().getName();
+ }
+
+ public String[] getTestMethodNames() {
+ return new String[] { "test" };
+ }
+
+ public void test() throws Exception {
+ TestBed t = new TestBed();
+ assure("test", t.execute(new Provider(t), false, Client.class, 0));
+ }
+
+ public static final class Client extends TestBed.Client {
+ public static void main(String[] args) {
+ new Client().execute();
+ }
+
+ protected boolean run(XComponentContext context) throws Throwable {
+ boolean success = true;
+ XTransport transport = UnoRuntime.queryInterface(
+ XTransport.class, getBridge(context).getInstance("Transport"));
+
+ Object obj1a = new XType1() {};
+ XType1 obj1b = UnoRuntime.queryInterface(XType1.class, obj1a);
+ success &= test("obj1a == obj1b", obj1a == obj1b);
+
+ Object obj2a = new XType2() {};
+ XType2 obj2b = UnoRuntime.queryInterface(XType2.class, obj2a);
+ success &= test("obj2a == obj2b", obj2a == obj2b);
+
+ Object obj3a = transport.getType1();
+ XType1 obj3b = UnoRuntime.queryInterface(XType1.class, obj3a);
+ success &= test(
+ "obj3a != obj3b; only meaningful as long as different proxy"
+ + " instances are used for different UNO interfaces of one UNO"
+ + " object",
+ obj3a != obj3b);
+
+ Object obj4a = transport.getType2();
+ XType2 obj4b = UnoRuntime.queryInterface(XType2.class, obj4a);
+ success &= test(
+ "obj4a != obj4b; only meaningful as long as different proxy"
+ + " instances are used for different UNO interfaces of one UNO"
+ + " object",
+ obj4a != obj4b);
+
+ success &= test("UnoRuntime.areSame(null, null)",
+ UnoRuntime.areSame(null, null));
+ success &= test("!UnoRuntime.areSame(null, obj1a)",
+ !UnoRuntime.areSame(null, obj1a));
+ success &= test("!UnoRuntime.areSame(null, obj1b)",
+ !UnoRuntime.areSame(null, obj1b));
+ success &= test("!UnoRuntime.areSame(null, obj2a)",
+ !UnoRuntime.areSame(null, obj2a));
+ success &= test("!UnoRuntime.areSame(null, obj2b)",
+ !UnoRuntime.areSame(null, obj2b));
+ success &= test("!UnoRuntime.areSame(null, obj3a)",
+ !UnoRuntime.areSame(null, obj3a));
+ success &= test("!UnoRuntime.areSame(null, obj3b)",
+ !UnoRuntime.areSame(null, obj3b));
+ success &= test("!UnoRuntime.areSame(null, obj4a)",
+ !UnoRuntime.areSame(null, obj4a));
+ success &= test("!UnoRuntime.areSame(null, obj4b)",
+ !UnoRuntime.areSame(null, obj4b));
+
+ success &= test("!obj1a.equals(null)", !obj1a.equals(null));
+ success &= test("!UnoRuntime.areSame(obj1a, null)",
+ !UnoRuntime.areSame(obj1a, null));
+ success &= test("obj1a.equals(obj1a)", obj1a.equals(obj1a));
+ success &= test("UnoRuntime.areSame(obj1a, obj1a)",
+ UnoRuntime.areSame(obj1a, obj1a));
+ success &= test("obj1a.equals(obj1b)", obj1a.equals(obj1b));
+ success &= test("UnoRuntime.areSame(obj1a, obj1b)",
+ UnoRuntime.areSame(obj1a, obj1b));
+ success &= test("!obj1a.equals(obj2a)", !obj1a.equals(obj2a));
+ success &= test("!UnoRuntime.areSame(obj1a, obj2a)",
+ !UnoRuntime.areSame(obj1a, obj2a));
+ success &= test("!obj1a.equals(obj2b)", !obj1a.equals(obj2b));
+ success &= test("!UnoRuntime.areSame(obj1a, obj2b)",
+ !UnoRuntime.areSame(obj1a, obj2b));
+ success &= test("!obj1a.equals(obj3a)", !obj1a.equals(obj3a));
+ success &= test("!UnoRuntime.areSame(obj1a, obj3a)",
+ !UnoRuntime.areSame(obj1a, obj3a));
+ success &= test("!obj1a.equals(obj3b)", !obj1a.equals(obj3b));
+ success &= test("!UnoRuntime.areSame(obj1a, obj3b)",
+ !UnoRuntime.areSame(obj1a, obj3b));
+ success &= test("!obj1a.equals(obj4a)", !obj1a.equals(obj4a));
+ success &= test("!UnoRuntime.areSame(obj1a, obj4a)",
+ !UnoRuntime.areSame(obj1a, obj4a));
+ success &= test("!obj1a.equals(obj4b)", !obj1a.equals(obj4b));
+ success &= test("!UnoRuntime.areSame(obj1a, obj4b)",
+ !UnoRuntime.areSame(obj1a, obj4b));
+
+ success &= test("!obj1b.equals(null)", !obj1b.equals(null));
+ success &= test("!UnoRuntime.areSame(obj1b, null)",
+ !UnoRuntime.areSame(obj1b, null));
+ success &= test("obj1b.equals(obj1a)", obj1b.equals(obj1a));
+ success &= test("UnoRuntime.areSame(obj1b, obj1a)",
+ UnoRuntime.areSame(obj1b, obj1a));
+ success &= test("obj1b.equals(obj1b)", obj1b.equals(obj1b));
+ success &= test("UnoRuntime.areSame(obj1b, obj1b)",
+ UnoRuntime.areSame(obj1b, obj1b));
+ success &= test("!obj1b.equals(obj2a)", !obj1b.equals(obj2a));
+ success &= test("!UnoRuntime.areSame(obj1b, obj2a)",
+ !UnoRuntime.areSame(obj1b, obj2a));
+ success &= test("!obj1b.equals(obj2b)", !obj1b.equals(obj2b));
+ success &= test("!UnoRuntime.areSame(obj1b, obj2b)",
+ !UnoRuntime.areSame(obj1b, obj2b));
+ success &= test("!obj1b.equals(obj3a)", !obj1b.equals(obj3a));
+ success &= test("!UnoRuntime.areSame(obj1b, obj3a)",
+ !UnoRuntime.areSame(obj1b, obj3a));
+ success &= test("!obj1b.equals(obj3b)", !obj1b.equals(obj3b));
+ success &= test("!UnoRuntime.areSame(obj1b, obj3b)",
+ !UnoRuntime.areSame(obj1b, obj3b));
+ success &= test("!obj1b.equals(obj4a)", !obj1b.equals(obj4a));
+ success &= test("!UnoRuntime.areSame(obj1b, obj4a)",
+ !UnoRuntime.areSame(obj1b, obj4a));
+ success &= test("!obj1b.equals(obj4b)", !obj1b.equals(obj4b));
+ success &= test("!UnoRuntime.areSame(obj1b, obj4b)",
+ !UnoRuntime.areSame(obj1b, obj4b));
+
+ success &= test("!obj2a.equals(null)", !obj2a.equals(null));
+ success &= test("!UnoRuntime.areSame(obj2a, null)",
+ !UnoRuntime.areSame(obj2a, null));
+ success &= test("!obj2a.equals(obj1a)", !obj2a.equals(obj1a));
+ success &= test("!UnoRuntime.areSame(obj2a, obj1a)",
+ !UnoRuntime.areSame(obj2a, obj1a));
+ success &= test("!obj2a.equals(obj1b)", !obj2a.equals(obj1b));
+ success &= test("!UnoRuntime.areSame(obj2a, obj1b)",
+ !UnoRuntime.areSame(obj2a, obj1b));
+ success &= test("obj2a.equals(obj2a)", obj2a.equals(obj2a));
+ success &= test("UnoRuntime.areSame(obj2a, obj2a)",
+ UnoRuntime.areSame(obj2a, obj2a));
+ success &= test("obj2a.equals(obj2b)", obj2a.equals(obj2b));
+ success &= test("UnoRuntime.areSame(obj2a, obj2b)",
+ UnoRuntime.areSame(obj2a, obj2b));
+ success &= test("!obj2a.equals(obj3a)", !obj2a.equals(obj3a));
+ success &= test("!UnoRuntime.areSame(obj2a, obj3a)",
+ !UnoRuntime.areSame(obj2a, obj3a));
+ success &= test("!obj2a.equals(obj3b)", !obj2a.equals(obj3b));
+ success &= test("!UnoRuntime.areSame(obj2a, obj3b)",
+ !UnoRuntime.areSame(obj2a, obj3b));
+ success &= test("!obj2a.equals(obj4a)", !obj2a.equals(obj4a));
+ success &= test("!UnoRuntime.areSame(obj2a, obj4a)",
+ !UnoRuntime.areSame(obj2a, obj4a));
+ success &= test("!obj2a.equals(obj4b)", !obj2a.equals(obj4b));
+ success &= test("!UnoRuntime.areSame(obj2a, obj4b)",
+ !UnoRuntime.areSame(obj2a, obj4b));
+
+ success &= test("!obj2b.equals(null)", !obj2b.equals(null));
+ success &= test("!UnoRuntime.areSame(obj2b, null)",
+ !UnoRuntime.areSame(obj2b, null));
+ success &= test("!obj2b.equals(obj1a)", !obj2b.equals(obj1a));
+ success &= test("!UnoRuntime.areSame(obj2b, obj1a)",
+ !UnoRuntime.areSame(obj2b, obj1a));
+ success &= test("!obj2b.equals(obj1b)", !obj2b.equals(obj1b));
+ success &= test("!UnoRuntime.areSame(obj2b, obj1b)",
+ !UnoRuntime.areSame(obj2b, obj1b));
+ success &= test("obj2b.equals(obj2a)", obj2b.equals(obj2a));
+ success &= test("UnoRuntime.areSame(obj2b, obj2a)",
+ UnoRuntime.areSame(obj2b, obj2a));
+ success &= test("obj2b.equals(obj2b)", obj2b.equals(obj2b));
+ success &= test("UnoRuntime.areSame(obj2b, obj2b)",
+ UnoRuntime.areSame(obj2b, obj2b));
+ success &= test("!obj2b.equals(obj3a)", !obj2b.equals(obj3a));
+ success &= test("!UnoRuntime.areSame(obj2b, obj3a)",
+ !UnoRuntime.areSame(obj2b, obj3a));
+ success &= test("!obj2b.equals(obj3b)", !obj2b.equals(obj3b));
+ success &= test("!UnoRuntime.areSame(obj2b, obj3b)",
+ !UnoRuntime.areSame(obj2b, obj3b));
+ success &= test("!obj2b.equals(obj4a)", !obj2b.equals(obj4a));
+ success &= test("!UnoRuntime.areSame(obj2b, obj4a)",
+ !UnoRuntime.areSame(obj2b, obj4a));
+ success &= test("!obj2b.equals(obj4b)", !obj2b.equals(obj4b));
+ success &= test("!UnoRuntime.areSame(obj2b, obj4b)",
+ !UnoRuntime.areSame(obj2b, obj4b));
+
+ success &= test("!obj3a.equals(null)", !obj3a.equals(null));
+ success &= test("!UnoRuntime.areSame(obj3a, null)",
+ !UnoRuntime.areSame(obj3a, null));
+ success &= test("!obj3a.equals(obj1a)", !obj3a.equals(obj1a));
+ success &= test("!UnoRuntime.areSame(obj3a, obj1a)",
+ !UnoRuntime.areSame(obj3a, obj1a));
+ success &= test("!obj3a.equals(obj1b)", !obj3a.equals(obj1b));
+ success &= test("!UnoRuntime.areSame(obj3a, obj1b)",
+ !UnoRuntime.areSame(obj3a, obj1b));
+ success &= test("!obj3a.equals(obj2a)", !obj3a.equals(obj2a));
+ success &= test("!UnoRuntime.areSame(obj3a, obj2a)",
+ !UnoRuntime.areSame(obj3a, obj2a));
+ success &= test("!obj3a.equals(obj2b)", !obj3a.equals(obj2b));
+ success &= test("!UnoRuntime.areSame(obj3a, obj2b)",
+ !UnoRuntime.areSame(obj3a, obj2b));
+ success &= test("obj3a.equals(obj3a)", obj3a.equals(obj3a));
+ success &= test("UnoRuntime.areSame(obj3a, obj3a)",
+ UnoRuntime.areSame(obj3a, obj3a));
+ success &= test("obj3a.equals(obj3b)", obj3a.equals(obj3b));
+ success &= test("UnoRuntime.areSame(obj3a, obj3b)",
+ UnoRuntime.areSame(obj3a, obj3b));
+ success &= test("!obj3a.equals(obj4a)", !obj3a.equals(obj4a));
+ success &= test("!UnoRuntime.areSame(obj3a, obj4a)",
+ !UnoRuntime.areSame(obj3a, obj4a));
+ success &= test("!obj3a.equals(obj4b)", !obj3a.equals(obj4b));
+ success &= test("!UnoRuntime.areSame(obj3a, obj4b)",
+ !UnoRuntime.areSame(obj3a, obj4b));
+
+ success &= test("!obj3b.equals(null)", !obj3b.equals(null));
+ success &= test("!UnoRuntime.areSame(obj3b, null)",
+ !UnoRuntime.areSame(obj3b, null));
+ success &= test("!obj3b.equals(obj1a)", !obj3b.equals(obj1a));
+ success &= test("!UnoRuntime.areSame(obj3b, obj1a)",
+ !UnoRuntime.areSame(obj3b, obj1a));
+ success &= test("!obj3b.equals(obj1b)", !obj3b.equals(obj1b));
+ success &= test("!UnoRuntime.areSame(obj3b, obj1b)",
+ !UnoRuntime.areSame(obj3b, obj1b));
+ success &= test("!obj3b.equals(obj2a)", !obj3b.equals(obj2a));
+ success &= test("!UnoRuntime.areSame(obj3b, obj2a)",
+ !UnoRuntime.areSame(obj3b, obj2a));
+ success &= test("!obj3b.equals(obj2b)", !obj3b.equals(obj2b));
+ success &= test("!UnoRuntime.areSame(obj3b, obj2b)",
+ !UnoRuntime.areSame(obj3b, obj2b));
+ success &= test("obj3b.equals(obj3a)", obj3b.equals(obj3a));
+ success &= test("UnoRuntime.areSame(obj3b, obj3a)",
+ UnoRuntime.areSame(obj3b, obj3a));
+ success &= test("obj3b.equals(obj3b)", obj3b.equals(obj3b));
+ success &= test("UnoRuntime.areSame(obj3b, obj3b)",
+ UnoRuntime.areSame(obj3b, obj3b));
+ success &= test("!obj3b.equals(obj4a)", !obj3b.equals(obj4a));
+ success &= test("!UnoRuntime.areSame(obj3b, obj4a)",
+ !UnoRuntime.areSame(obj3b, obj4a));
+ success &= test("!obj3b.equals(obj4b)", !obj3b.equals(obj4b));
+ success &= test("!UnoRuntime.areSame(obj3b, obj4b)",
+ !UnoRuntime.areSame(obj3b, obj4b));
+
+ success &= test("!obj4a.equals(null)", !obj4a.equals(null));
+ success &= test("!UnoRuntime.areSame(obj4a, null)",
+ !UnoRuntime.areSame(obj4a, null));
+ success &= test("!obj4a.equals(obj1a)", !obj4a.equals(obj1a));
+ success &= test("!UnoRuntime.areSame(obj4a, obj1a)",
+ !UnoRuntime.areSame(obj4a, obj1a));
+ success &= test("!obj4a.equals(obj1b)", !obj4a.equals(obj1b));
+ success &= test("!UnoRuntime.areSame(obj4a, obj1b)",
+ !UnoRuntime.areSame(obj4a, obj1b));
+ success &= test("!obj4a.equals(obj2a)", !obj4a.equals(obj2a));
+ success &= test("!UnoRuntime.areSame(obj4a, obj2a)",
+ !UnoRuntime.areSame(obj4a, obj2a));
+ success &= test("!obj4a.equals(obj2b)", !obj4a.equals(obj2b));
+ success &= test("!UnoRuntime.areSame(obj4a, obj2b)",
+ !UnoRuntime.areSame(obj4a, obj2b));
+ success &= test("!obj4a.equals(obj3a)", !obj4a.equals(obj3a));
+ success &= test("!UnoRuntime.areSame(obj4a, obj3a)",
+ !UnoRuntime.areSame(obj4a, obj3a));
+ success &= test("!obj4a.equals(obj3b)", !obj4a.equals(obj3b));
+ success &= test("!UnoRuntime.areSame(obj4a, obj3b)",
+ !UnoRuntime.areSame(obj4a, obj3b));
+ success &= test("obj4a.equals(obj4a)", obj4a.equals(obj4a));
+ success &= test("UnoRuntime.areSame(obj4a, obj4a)",
+ UnoRuntime.areSame(obj4a, obj4a));
+ success &= test("obj4a.equals(obj4b)", obj4a.equals(obj4b));
+ success &= test("UnoRuntime.areSame(obj4a, obj4b)",
+ UnoRuntime.areSame(obj4a, obj4b));
+
+ success &= test("!obj4b.equals(null)", !obj4b.equals(null));
+ success &= test("!UnoRuntime.areSame(obj4b, null)",
+ !UnoRuntime.areSame(obj4b, null));
+ success &= test("!obj4b.equals(obj1a)", !obj4b.equals(obj1a));
+ success &= test("!UnoRuntime.areSame(obj4b, obj1a)",
+ !UnoRuntime.areSame(obj4b, obj1a));
+ success &= test("!obj4b.equals(obj1b)", !obj4b.equals(obj1b));
+ success &= test("!UnoRuntime.areSame(obj4b, obj1b)",
+ !UnoRuntime.areSame(obj4b, obj1b));
+ success &= test("!obj4b.equals(obj2a)", !obj4b.equals(obj2a));
+ success &= test("!UnoRuntime.areSame(obj4b, obj2a)",
+ !UnoRuntime.areSame(obj4b, obj2a));
+ success &= test("!obj4b.equals(obj2b)", !obj4b.equals(obj2b));
+ success &= test("!UnoRuntime.areSame(obj4b, obj2b)",
+ !UnoRuntime.areSame(obj4b, obj2b));
+ success &= test("!obj4b.equals(obj3a)", !obj4b.equals(obj3a));
+ success &= test("!UnoRuntime.areSame(obj4b, obj3a)",
+ !UnoRuntime.areSame(obj4b, obj3a));
+ success &= test("!obj4b.equals(obj3b)", !obj4b.equals(obj3b));
+ success &= test("!UnoRuntime.areSame(obj4b, obj3b)",
+ !UnoRuntime.areSame(obj4b, obj3b));
+ success &= test("obj4b.equals(obj4a)", obj4b.equals(obj4a));
+ success &= test("UnoRuntime.areSame(obj4b, obj4a)",
+ UnoRuntime.areSame(obj4b, obj4a));
+ success &= test("obj4b.equals(obj4b)", obj4b.equals(obj4b));
+ success &= test("UnoRuntime.areSame(obj4b, obj4b)",
+ UnoRuntime.areSame(obj4b, obj4b));
+
+ success &= test("obj1a.hashCode() == obj1b.hashCode()",
+ obj1a.hashCode() == obj1b.hashCode());
+ success &= test("obj2a.hashCode() == obj2b.hashCode()",
+ obj2a.hashCode() == obj2b.hashCode());
+ success &= test("obj3a.hashCode() == obj3b.hashCode()",
+ obj3a.hashCode() == obj3b.hashCode());
+ success &= test("obj4a.hashCode() == obj4b.hashCode()",
+ obj4a.hashCode() == obj4b.hashCode());
+
+ return success;
+ }
+
+ private static boolean test(String message, boolean condition) {
+ if (!condition) {
+ System.err.println("Failed: " + message);
+ }
+ return condition;
+ }
+ }
+
+ private static final class Provider implements XInstanceProvider {
+ public Provider(TestBed testBed) {
+ this.testBed = testBed;
+ }
+
+ public Object getInstance(String instanceName) {
+ return new XTransport() {
+ public Object getType1() {
+ return new XType1() {};
+ }
+
+ public Object getType2() {
+ return new XType2() {};
+ }
+ };
+ }
+
+ private final TestBed testBed;
+ }
+
+ public interface XTransport extends XInterface {
+ Object getType1();
+
+ Object getType2();
+
+ TypeInfo[] UNOTYPEINFO = { new MethodTypeInfo("getType1", 0, 0),
+ new MethodTypeInfo("getType2", 1, 0) };
+ }
+
+ public interface XType1 extends XInterface {
+ TypeInfo[] UNOTYPEINFO = null;
+ }
+
+ public interface XType2 extends XInterface {
+ TypeInfo[] UNOTYPEINFO = null;
+ }
+}
diff --git a/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug108825_Test.java b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug108825_Test.java
new file mode 100644
index 000000000000..9c7b84a960b3
--- /dev/null
+++ b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug108825_Test.java
@@ -0,0 +1,163 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.lib.uno.bridges.javaremote;
+
+import com.sun.star.bridge.XInstanceProvider;
+import com.sun.star.lib.TestBed;
+import com.sun.star.lib.uno.typeinfo.MethodTypeInfo;
+import com.sun.star.lib.uno.typeinfo.TypeInfo;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.uno.XInterface;
+import complexlib.ComplexTestCase;
+
+/**
+ * Test case for bug #108825#.
+ *
+ * <p>Bug #108825# "Java UNO Remote Bridge: Mapped-out Objects Not Held" shows
+ * that local objects that are mapped out via a remote bridge, but not held
+ * locally, might be garbage collected while there are still remote references
+ * to them. This test is not guaranteed to always work reliably, see comment in
+ * the code.</p>
+ */
+public final class Bug108825_Test extends ComplexTestCase {
+ public String getTestObjectName() {
+ return getClass().getName();
+ }
+
+ public String[] getTestMethodNames() {
+ return new String[] { "test" };
+ }
+
+ public void test() throws Exception {
+ TestBed t = new TestBed();
+ assure("test", t.execute(new Provider(t), true, Client.class, 0));
+ }
+
+ public static final class Client extends TestBed.Client {
+ public static void main(String[] args) {
+ new Client().execute();
+ }
+
+ protected boolean run(XComponentContext context) throws Throwable {
+ XTest test = UnoRuntime.queryInterface(
+ XTest.class, getBridge(context).getInstance("Test"));
+ // Send the XObject that is held on the server side amidst two
+ // dummies that are not held on the server side; then wait for the
+ // dummies to be garbage collected, hoping that the XObject, if it
+ // is erroneously not held on the client side, will be garbage
+ // collected, too. Obviously, this is not guaranteed to always work
+ // (the VM might chose not to garbage collect the dummies, hanging
+ // the test forever; or the VM might chose to garbage collect the
+ // dummies but not the XObject, making the test pass erroneously).
+ test.offer(new Dummy(), new XObject() { public void call() {} },
+ new Dummy());
+ System.out.println("Client waiting for garbage collection...");
+ for (;;) {
+ synchronized (lock) {
+ if (finalizedCount == 2) {
+ break;
+ }
+ }
+ test.remoteGc();
+ gc();
+ }
+ System.out.println("Client garbage collection done.");
+ test.notification();
+ return true;
+ }
+
+ private final class Dummy implements XDummy {
+ protected void finalize() {
+ synchronized (lock) {
+ ++finalizedCount;
+ }
+ }
+ }
+
+ private final Object lock = new Object();
+ private int finalizedCount = 0;
+ }
+
+ // Make it as likely as possible that the VM reclaims all garbage:
+ private static void gc() {
+ System.gc();
+ System.runFinalization();
+ byte[] garbage = new byte[1024 * 1024];
+ }
+
+ private static final class Provider implements XInstanceProvider {
+ public Provider(TestBed testBed) {
+ this.testBed = testBed;
+ }
+
+ public Object getInstance(String instanceName) {
+ return new XTest() {
+ public void offer(XDummy dummy1, XObject obj, XDummy dummy2)
+ {
+ this.obj = obj;
+ }
+
+ public void remoteGc() {
+ gc();
+ }
+
+ public void notification() {
+ obj.call();
+ testBed.serverDone(true);
+ }
+
+ private XObject obj;
+ };
+ }
+
+ private final TestBed testBed;
+ }
+
+ public interface XDummy extends XInterface {
+ TypeInfo[] UNOTYPEINFO = null;
+ }
+
+ public interface XObject extends XInterface {
+ void call();
+
+ TypeInfo[] UNOTYPEINFO = { new MethodTypeInfo("call", 0, 0) };
+ }
+
+ public interface XTest extends XInterface {
+ void offer(XDummy dummy1, XObject obj, XDummy dummy2);
+
+ void remoteGc();
+
+ void notification();
+
+ TypeInfo[] UNOTYPEINFO = { new MethodTypeInfo("offer", 0, 0),
+ new MethodTypeInfo("remoteGc", 1, 0),
+ new MethodTypeInfo("notification", 2, 0) };
+ }
+}
diff --git a/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug110892_Test.java b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug110892_Test.java
new file mode 100644
index 000000000000..322f8051ed60
--- /dev/null
+++ b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug110892_Test.java
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.lib.uno.bridges.javaremote;
+
+import com.sun.star.bridge.XInstanceProvider;
+import com.sun.star.lib.TestBed;
+import com.sun.star.lib.uno.typeinfo.MethodTypeInfo;
+import com.sun.star.lib.uno.typeinfo.TypeInfo;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.uno.XInterface;
+import complexlib.ComplexTestCase;
+import util.WaitUnreachable;
+
+/**
+ * Test case for bug #110892#.
+ *
+ * <p>Bug #110892# "Java URP bridge holds objects indefinitely" applies to cases
+ * where an object is sent from server to client, then recursively back from
+ * client to server. In such a case, the client should not increment its
+ * internal reference count for the object, as the server will never send back a
+ * corresponding release message.</p>
+ *
+ * <p>This test has to detect whether the spawned client process fails to
+ * garbage-collect an object, which can not be done reliably. As an
+ * approximation, it waits for 10 sec and considers the process failing if it
+ * has not garbage-collected the object by then.</p>
+ */
+public final class Bug110892_Test extends ComplexTestCase {
+ public String[] getTestMethodNames() {
+ return new String[] { "test" };
+ }
+
+ public void test() throws Exception {
+ assure("test",
+ new TestBed().execute(new Provider(), false, Client.class,
+ 10000));
+ }
+
+ public static final class Client extends TestBed.Client {
+ public static void main(String[] args) {
+ new Client().execute();
+ }
+
+ protected boolean run(XComponentContext context) throws Throwable {
+ XTest test = UnoRuntime.queryInterface(
+ XTest.class, getBridge(context).getInstance("Test"));
+ test.start(new ClientObject());
+ synchronized (lock) {
+ unreachable.waitUnreachable();
+ }
+ return true;
+ }
+
+ private final class ClientObject implements XClientObject {
+ public void call(XServerObject server, XInterface object) {
+ synchronized (lock) {
+ unreachable = new WaitUnreachable(object);
+ }
+ server.call(object);
+ }
+ }
+
+ private final Object lock = new Object();
+ private WaitUnreachable unreachable = null;
+ }
+
+ private static final class Provider implements XInstanceProvider {
+ public Object getInstance(String instanceName) {
+ return new XTest() {
+ public void start(XClientObject client) {
+ client.call(
+ new XServerObject() {
+ public void call(XInterface object) {}
+ },
+ new XInterface() {});
+ }
+ };
+ }
+ }
+
+ public interface XClientObject extends XInterface {
+ void call(XServerObject server, XInterface object);
+
+ TypeInfo[] UNOTYPEINFO = { new MethodTypeInfo("call", 0, 0) };
+ }
+
+ public interface XServerObject extends XInterface {
+ void call(XInterface object);
+
+ TypeInfo[] UNOTYPEINFO = { new MethodTypeInfo("call", 0, 0) };
+ }
+
+ public interface XTest extends XInterface {
+ void start(XClientObject client);
+
+ TypeInfo[] UNOTYPEINFO = { new MethodTypeInfo("start", 0, 0) };
+ }
+}
diff --git a/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug111153_Test.java b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug111153_Test.java
new file mode 100644
index 000000000000..351481cb4680
--- /dev/null
+++ b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug111153_Test.java
@@ -0,0 +1,103 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.lib.uno.bridges.javaremote;
+
+import com.sun.star.bridge.XInstanceProvider;
+import com.sun.star.lib.TestBed;
+import com.sun.star.lib.uno.typeinfo.MethodTypeInfo;
+import com.sun.star.lib.uno.typeinfo.TypeInfo;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.uno.XInterface;
+import complexlib.ComplexTestCase;
+
+/**
+ * Test case for bug #111153#.
+ *
+ * <P>Bug #111153# "jni_uno bridge sometimes fails to map objects
+ * correctly" describes that mapping a local object out with type XDerived and
+ * then mapping it back in with type XBase produces a proxy, instead of
+ * short-cutting to the local object.</P>
+ */
+public final class Bug111153_Test extends ComplexTestCase {
+ public String[] getTestMethodNames() {
+ return new String[] { "test" };
+ }
+
+ public void test() throws Exception {
+ assure("test", new TestBed().execute(new Provider(), false,
+ Client.class, 0));
+ }
+
+ public static final class Client extends TestBed.Client {
+ public static void main(String[] args) {
+ new Client().execute();
+ }
+
+ protected boolean run(XComponentContext context) throws Throwable {
+ XTransport t = UnoRuntime.queryInterface(
+ XTransport.class, getBridge(context).getInstance("Transport"));
+ XDerived d = new XDerived() {};
+ t.setDerived(d);
+ return t.getBase() == d;
+ }
+ }
+
+ private static final class Provider implements XInstanceProvider {
+ public Object getInstance(String instanceName) {
+ return new XTransport() {
+ public synchronized void setDerived(XDerived derived) {
+ this.derived = derived;
+ }
+
+ public synchronized XBase getBase() {
+ return this.derived;
+ }
+
+ private XDerived derived = null;
+ };
+ }
+ }
+
+ public interface XBase extends XInterface {
+ TypeInfo[] UNOTYPEINFO = null;
+ }
+
+ public interface XDerived extends XBase {
+ TypeInfo[] UNOTYPEINFO = null;
+ }
+
+ public interface XTransport extends XInterface {
+ void setDerived(XDerived derived);
+
+ XBase getBase();
+
+ TypeInfo[] UNOTYPEINFO = { new MethodTypeInfo("setDerived", 0, 0),
+ new MethodTypeInfo("getBase", 1, 0) };
+ }
+}
diff --git a/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug114133_Test.java b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug114133_Test.java
new file mode 100644
index 000000000000..0049b966be1c
--- /dev/null
+++ b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug114133_Test.java
@@ -0,0 +1,76 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.lib.uno.bridges.javaremote;
+
+import com.sun.star.bridge.XInstanceProvider;
+import com.sun.star.lib.TestBed;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.uno.XInterface;
+import complexlib.ComplexTestCase;
+import util.WaitUnreachable;
+
+/**
+ * Test case for bug #114133#.
+ *
+ * <p>Bug #114133# "Java UNO: UnoRuntime.getBride and disposed bridges." The
+ * client calls UnoRuntime.getBridge to get a bridge to the server, uses the
+ * bridge, waits until it terminates itself (when all bridged objects have been
+ * garbage-collected), then calls UnoRuntime.getBridge again. This must return
+ * a fresh, unterminated bridge.</p>
+ */
+public final class Bug114133_Test extends ComplexTestCase {
+ public String[] getTestMethodNames() {
+ return new String[] { "test" };
+ }
+
+ public void test() throws Exception {
+ assure(
+ "test",
+ new TestBed().execute(new Provider(), false, Client.class, 0));
+ }
+
+ public static final class Client extends TestBed.Client {
+ public static void main(String[] args) {
+ new Client().execute();
+ }
+
+ protected boolean run(XComponentContext context) throws Throwable {
+ new WaitUnreachable(getBridge(context).getInstance("Test")).
+ waitUnreachable();
+ new WaitUnreachable(getBridge(context).getInstance("Test")).
+ waitUnreachable();
+ return true;
+ }
+ }
+
+ private static final class Provider implements XInstanceProvider {
+ public Object getInstance(String instanceName) {
+ return new XInterface() {};
+ }
+ }
+}
diff --git a/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug51323_Test.java b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug51323_Test.java
new file mode 100644
index 000000000000..bb13c55ee1ad
--- /dev/null
+++ b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug51323_Test.java
@@ -0,0 +1,84 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.lib.uno.bridges.javaremote;
+
+import com.sun.star.bridge.XBridgeFactory;
+import com.sun.star.bridge.XInstanceProvider;
+import com.sun.star.connection.Connector;
+import com.sun.star.connection.XConnection;
+import com.sun.star.lib.TestBed;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.uno.XInterface;
+import complexlib.ComplexTestCase;
+import util.WaitUnreachable;
+
+/**
+ * Test case for bug #i51323#.
+ *
+ * <p>Bug #i51323# "jurt: BridgeFactory.createBridge creates bridge names."
+ * Make sure that multiple calls to BridgeFactory.getBridge with empty names
+ * create different bridges.</p>
+ */
+public final class Bug51323_Test extends ComplexTestCase {
+ public String[] getTestMethodNames() {
+ return new String[] { "test" };
+ }
+
+ public void test() throws Exception {
+ assure(
+ "test",
+ new TestBed().execute(new Provider(), false, Client.class, 0));
+ }
+
+ public static final class Client extends TestBed.Client {
+ public static void main(String[] args) {
+ new Client().execute();
+ }
+
+ protected boolean run(XComponentContext context) throws Throwable {
+ XConnection connection =
+ Connector.create(context).connect(getConnectionDescription());
+ XBridgeFactory factory = UnoRuntime.queryInterface(
+ XBridgeFactory.class,
+ context.getServiceManager().createInstanceWithContext(
+ "com.sun.star.bridge.BridgeFactory", context));
+ return !UnoRuntime.areSame(
+ factory.createBridge(
+ "", getProtocolDescription(), connection, null),
+ factory.createBridge(
+ "", getProtocolDescription(), connection, null));
+ }
+ }
+
+ private static final class Provider implements XInstanceProvider {
+ public Object getInstance(String instanceName) {
+ return new XInterface() {};
+ }
+ }
+}
diff --git a/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug92174_Test.java b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug92174_Test.java
new file mode 100644
index 000000000000..9c425a61fb2b
--- /dev/null
+++ b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug92174_Test.java
@@ -0,0 +1,99 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.lib.uno.bridges.javaremote;
+
+import com.sun.star.bridge.XInstanceProvider;
+import com.sun.star.lib.TestBed;
+import com.sun.star.lib.uno.typeinfo.MethodTypeInfo;
+import com.sun.star.lib.uno.typeinfo.TypeInfo;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.uno.XInterface;
+import complexlib.ComplexTestCase;
+
+public final class Bug92174_Test extends ComplexTestCase {
+ public String[] getTestMethodNames() {
+ return new String[] { "test" };
+ }
+
+ public void test() throws Exception {
+ assure("test",
+ new TestBed().execute(new Provider(), false, Client.class, 0));
+ }
+
+ public static final class Client extends TestBed.Client {
+ public static void main(String[] args) {
+ new Client().execute();
+ }
+
+ protected boolean run(XComponentContext context) throws Throwable {
+ XTransport t = UnoRuntime.queryInterface(
+ XTransport.class, getBridge(context).getInstance("Transport"));
+ t.setDerived(new XDerived() {
+ public void fn() {}
+ });
+ t.getBase().fn();
+ return true;
+ }
+ }
+
+ private static final class Provider implements XInstanceProvider {
+ public Object getInstance(String instanceName) {
+ return new XTransport() {
+ public XBase getBase() {
+ return derived;
+ }
+
+ public synchronized void setDerived(XDerived derived) {
+ this.derived = derived;
+ }
+
+ private XDerived derived = null;
+ };
+ }
+ }
+
+ public interface XBase extends XInterface {
+ void fn();
+
+ TypeInfo[] UNOTYPEINFO = { new MethodTypeInfo("fn", 0, 0) };
+ }
+
+ public interface XDerived extends XBase {
+ TypeInfo[] UNOTYPEINFO = null;
+ }
+
+ public interface XTransport extends XInterface {
+ XBase getBase();
+
+ void setDerived(XDerived derived);
+
+ TypeInfo[] UNOTYPEINFO = { new MethodTypeInfo("getBase", 0, 0),
+ new MethodTypeInfo("setDerived", 1, 0) };
+ }
+}
diff --git a/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug97697_Test.java b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug97697_Test.java
new file mode 100644
index 000000000000..34d98532688b
--- /dev/null
+++ b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug97697_Test.java
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.lib.uno.bridges.javaremote;
+
+import com.sun.star.bridge.XInstanceProvider;
+import com.sun.star.lang.DisposedException;
+import com.sun.star.lib.TestBed;
+import com.sun.star.lib.uno.typeinfo.MethodTypeInfo;
+import com.sun.star.lib.uno.typeinfo.TypeInfo;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.uno.XInterface;
+import complexlib.ComplexTestCase;
+
+/**
+ * Test case for bug #97697#.
+ *
+ * <p>Bug #97697# "GPF in java-uno bridge in bugdoc scenario" shows that sending
+ * a plain <code>Object</code> as an <code>Any</code> over the URP bridge lead
+ * to a <code>StackOverflowError</code> on the writer thread, which was silently
+ * discarded (and the bridge was not disposed).</p>
+ *
+ * <p>This test has to detect whether the spawned client process indeed hangs,
+ * which can not be done reliably. As an approximation, it waits for 10 sec and
+ * considers the process hanging if it has not completed by then.</p>
+ */
+public final class Bug97697_Test extends ComplexTestCase {
+ public String getTestObjectName() {
+ return getClass().getName();
+ }
+
+ public String[] getTestMethodNames() {
+ return new String[] { "test" };
+ }
+
+ public void test() throws Exception {
+ TestBed t = new TestBed();
+ assure("test", t.execute(new Provider(t), true, Client.class, 10000));
+ }
+
+ public static final class Client extends TestBed.Client {
+ public static void main(String[] args) {
+ new Client().execute();
+ }
+
+ protected boolean run(XComponentContext context) throws Throwable {
+ XTransport transport = UnoRuntime.queryInterface(
+ XTransport.class, getBridge(context).getInstance("Transport"));
+ try {
+ transport.getAny();
+ } catch (DisposedException e) {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ private static final class Provider implements XInstanceProvider {
+ public Provider(TestBed testBed) {
+ this.testBed = testBed;
+ }
+
+ public Object getInstance(String instanceName) {
+ return new XTransport() {
+ public Object getAny() {
+ testBed.serverDone(true);
+ return new Object();
+ }
+ };
+ }
+
+ private final TestBed testBed;
+ }
+
+ public interface XTransport extends XInterface {
+ Object getAny();
+
+ TypeInfo[] UNOTYPEINFO = { new MethodTypeInfo("getAny", 0, 0) };
+ }
+}
diff --git a/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug98508_Test.idl b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug98508_Test.idl
new file mode 100644
index 000000000000..491f82cc0a83
--- /dev/null
+++ b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug98508_Test.idl
@@ -0,0 +1,37 @@
+/*************************************************************************
+ *
+ * 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 "com/sun/star/uno/XInterface.idl"
+
+module com { module sun { module star { module lib { module uno {
+module bridges { module javaremote {
+
+struct Test98508Struct<T> { T member; };
+
+interface Test98508Interface { Test98508Struct<long> get(); };
+
+}; }; }; }; }; }; };
diff --git a/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug98508_Test.java b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug98508_Test.java
new file mode 100644
index 000000000000..82804cf22e67
--- /dev/null
+++ b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/Bug98508_Test.java
@@ -0,0 +1,104 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.lib.uno.bridges.javaremote;
+
+import com.sun.star.bridge.XInstanceProvider;
+import com.sun.star.lang.DisposedException;
+import com.sun.star.lib.TestBed;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import complexlib.ComplexTestCase;
+
+/**
+ * Test case for bug #98508#.
+ *
+ * <p>Bug #98508# "JAVA UNO bridge is not disposed when Exception occures during
+ * sendReply()" states that the server returning <code>null</code> instead of a
+ * valid <code>String</code> from <code>XServiceName.getServiceName</code>
+ * causes an exception when sending the reply, but this exception did not cause
+ * the bridge to be disposed, it rather caused both client and server to
+ * hang.</p>
+ *
+ * <p>Since null instead of a <code>String</code> no longer causes an exception
+ * in the bridge, this test has been redesigned to send a value of a wrong
+ * instantiated polymorphic struct type instead.</p>
+ *
+ * <p>This test has to detect whether the spawned client process indeed hangs,
+ * which can not be done reliably. As an approximation, it waits for 10 sec and
+ * considers the process hanging if it has not completed by then.</p>
+ */
+public final class Bug98508_Test extends ComplexTestCase {
+ public String getTestObjectName() {
+ return getClass().getName();
+ }
+
+ public String[] getTestMethodNames() {
+ return new String[] { "test" };
+ }
+
+ public void test() throws Exception {
+ TestBed t = new TestBed();
+ assure("test", t.execute(new Provider(t), true, Client.class, 10000));
+ }
+
+ public static final class Client extends TestBed.Client {
+ public static void main(String[] args) {
+ new Client().execute();
+ }
+
+ protected boolean run(XComponentContext context) throws Throwable {
+ Test98508Interface ifc
+ = UnoRuntime.queryInterface(
+ Test98508Interface.class,
+ getBridge(context).getInstance(""));
+ try {
+ ifc.get();
+ } catch (DisposedException e) {
+ return true;
+ }
+ return false;
+ }
+ }
+
+ private static final class Provider implements XInstanceProvider {
+ public Provider(TestBed testBed) {
+ this.testBed = testBed;
+ }
+
+ public Object getInstance(String instanceName) {
+ return new Test98508Interface() {
+ public Test98508Struct get() {
+ testBed.serverDone(true);
+ return new Test98508Struct(Boolean.FALSE);
+ }
+ };
+ }
+
+ private final TestBed testBed;
+ }
+}
diff --git a/bridges/test/com/sun/star/lib/uno/bridges/java_remote/MethodIdTest.java b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/MethodIdTest.java
new file mode 100755
index 000000000000..39c8a0639b8f
--- /dev/null
+++ b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/MethodIdTest.java
@@ -0,0 +1,473 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.lib.uno.bridges.javaremote;
+
+import com.sun.star.bridge.XInstanceProvider;
+import com.sun.star.lib.TestBed;
+import com.sun.star.lib.uno.typeinfo.MethodTypeInfo;
+import com.sun.star.lib.uno.typeinfo.TypeInfo;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.uno.XInterface;
+import complexlib.ComplexTestCase;
+
+/**
+ * Test case for bug #111153#.
+ *
+ * <P>Bug #111153# "jni_uno bridge sometimes fails to map objects
+ * correctly" describes that mapping a local object out with type XDerived and
+ * then mapping it back in with type XBase produces a proxy, instead of
+ * short-cutting to the local object.</P>
+ */
+public final class MethodIdTest extends ComplexTestCase {
+ public String[] getTestMethodNames() {
+ return new String[] { "test" };
+ }
+
+ public void test() throws Exception {
+ assure(
+ "test",
+ new TestBed().execute(new Provider(), false, Client.class, 0));
+ }
+
+ public static final class Client extends TestBed.Client {
+ public static void main(String[] args) {
+ new Client().execute();
+ }
+
+ protected boolean run(XComponentContext context) throws Throwable {
+ XTest t = UnoRuntime.queryInterface(
+ XTest.class, getBridge(context).getInstance("Test"));
+ return t.f129() == 129;
+ }
+ }
+
+ private static final class Provider implements XInstanceProvider {
+ public Object getInstance(String instanceName) {
+ return new XTest() {
+ public int f0() { return 0; }
+ public int f1() { return 1; }
+ public int f2() { return 2; }
+ public int f3() { return 3; }
+ public int f4() { return 4; }
+ public int f5() { return 5; }
+ public int f6() { return 6; }
+ public int f7() { return 7; }
+ public int f8() { return 8; }
+ public int f9() { return 9; }
+ public int f10() { return 10; }
+ public int f11() { return 11; }
+ public int f12() { return 12; }
+ public int f13() { return 13; }
+ public int f14() { return 14; }
+ public int f15() { return 15; }
+ public int f16() { return 16; }
+ public int f17() { return 17; }
+ public int f18() { return 18; }
+ public int f19() { return 19; }
+ public int f20() { return 20; }
+ public int f21() { return 21; }
+ public int f22() { return 22; }
+ public int f23() { return 23; }
+ public int f24() { return 24; }
+ public int f25() { return 25; }
+ public int f26() { return 26; }
+ public int f27() { return 27; }
+ public int f28() { return 28; }
+ public int f29() { return 29; }
+ public int f30() { return 30; }
+ public int f31() { return 31; }
+ public int f32() { return 32; }
+ public int f33() { return 33; }
+ public int f34() { return 34; }
+ public int f35() { return 35; }
+ public int f36() { return 36; }
+ public int f37() { return 37; }
+ public int f38() { return 38; }
+ public int f39() { return 39; }
+ public int f40() { return 40; }
+ public int f41() { return 41; }
+ public int f42() { return 42; }
+ public int f43() { return 43; }
+ public int f44() { return 44; }
+ public int f45() { return 45; }
+ public int f46() { return 46; }
+ public int f47() { return 47; }
+ public int f48() { return 48; }
+ public int f49() { return 49; }
+ public int f50() { return 50; }
+ public int f51() { return 51; }
+ public int f52() { return 52; }
+ public int f53() { return 53; }
+ public int f54() { return 54; }
+ public int f55() { return 55; }
+ public int f56() { return 56; }
+ public int f57() { return 57; }
+ public int f58() { return 58; }
+ public int f59() { return 59; }
+ public int f60() { return 60; }
+ public int f61() { return 61; }
+ public int f62() { return 62; }
+ public int f63() { return 63; }
+ public int f64() { return 64; }
+ public int f65() { return 65; }
+ public int f66() { return 66; }
+ public int f67() { return 67; }
+ public int f68() { return 68; }
+ public int f69() { return 69; }
+ public int f70() { return 70; }
+ public int f71() { return 71; }
+ public int f72() { return 72; }
+ public int f73() { return 73; }
+ public int f74() { return 74; }
+ public int f75() { return 75; }
+ public int f76() { return 76; }
+ public int f77() { return 77; }
+ public int f78() { return 78; }
+ public int f79() { return 79; }
+ public int f80() { return 80; }
+ public int f81() { return 81; }
+ public int f82() { return 82; }
+ public int f83() { return 83; }
+ public int f84() { return 84; }
+ public int f85() { return 85; }
+ public int f86() { return 86; }
+ public int f87() { return 87; }
+ public int f88() { return 88; }
+ public int f89() { return 89; }
+ public int f90() { return 90; }
+ public int f91() { return 91; }
+ public int f92() { return 92; }
+ public int f93() { return 93; }
+ public int f94() { return 94; }
+ public int f95() { return 95; }
+ public int f96() { return 96; }
+ public int f97() { return 97; }
+ public int f98() { return 98; }
+ public int f99() { return 99; }
+ public int f100() { return 100; }
+ public int f101() { return 101; }
+ public int f102() { return 102; }
+ public int f103() { return 103; }
+ public int f104() { return 104; }
+ public int f105() { return 105; }
+ public int f106() { return 106; }
+ public int f107() { return 107; }
+ public int f108() { return 108; }
+ public int f109() { return 109; }
+ public int f110() { return 110; }
+ public int f111() { return 111; }
+ public int f112() { return 112; }
+ public int f113() { return 113; }
+ public int f114() { return 114; }
+ public int f115() { return 115; }
+ public int f116() { return 116; }
+ public int f117() { return 117; }
+ public int f118() { return 118; }
+ public int f119() { return 119; }
+ public int f120() { return 120; }
+ public int f121() { return 121; }
+ public int f122() { return 122; }
+ public int f123() { return 123; }
+ public int f124() { return 124; }
+ public int f125() { return 125; }
+ public int f126() { return 126; }
+ public int f127() { return 127; }
+ public int f128() { return 128; }
+ public int f129() { return 129; }
+ public int f130() { return 130; }
+ };
+ }
+ }
+
+ public interface XTest extends XInterface {
+ int f0();
+ int f1();
+ int f2();
+ int f3();
+ int f4();
+ int f5();
+ int f6();
+ int f7();
+ int f8();
+ int f9();
+ int f10();
+ int f11();
+ int f12();
+ int f13();
+ int f14();
+ int f15();
+ int f16();
+ int f17();
+ int f18();
+ int f19();
+ int f20();
+ int f21();
+ int f22();
+ int f23();
+ int f24();
+ int f25();
+ int f26();
+ int f27();
+ int f28();
+ int f29();
+ int f30();
+ int f31();
+ int f32();
+ int f33();
+ int f34();
+ int f35();
+ int f36();
+ int f37();
+ int f38();
+ int f39();
+ int f40();
+ int f41();
+ int f42();
+ int f43();
+ int f44();
+ int f45();
+ int f46();
+ int f47();
+ int f48();
+ int f49();
+ int f50();
+ int f51();
+ int f52();
+ int f53();
+ int f54();
+ int f55();
+ int f56();
+ int f57();
+ int f58();
+ int f59();
+ int f60();
+ int f61();
+ int f62();
+ int f63();
+ int f64();
+ int f65();
+ int f66();
+ int f67();
+ int f68();
+ int f69();
+ int f70();
+ int f71();
+ int f72();
+ int f73();
+ int f74();
+ int f75();
+ int f76();
+ int f77();
+ int f78();
+ int f79();
+ int f80();
+ int f81();
+ int f82();
+ int f83();
+ int f84();
+ int f85();
+ int f86();
+ int f87();
+ int f88();
+ int f89();
+ int f90();
+ int f91();
+ int f92();
+ int f93();
+ int f94();
+ int f95();
+ int f96();
+ int f97();
+ int f98();
+ int f99();
+ int f100();
+ int f101();
+ int f102();
+ int f103();
+ int f104();
+ int f105();
+ int f106();
+ int f107();
+ int f108();
+ int f109();
+ int f110();
+ int f111();
+ int f112();
+ int f113();
+ int f114();
+ int f115();
+ int f116();
+ int f117();
+ int f118();
+ int f119();
+ int f120();
+ int f121();
+ int f122();
+ int f123();
+ int f124();
+ int f125();
+ int f126();
+ int f127();
+ int f128();
+ int f129();
+ int f130();
+
+ TypeInfo[] UNOTYPEINFO = { new MethodTypeInfo("f0", 0, 0),
+ new MethodTypeInfo("f1", 1, 0),
+ new MethodTypeInfo("f2", 2, 0),
+ new MethodTypeInfo("f3", 3, 0),
+ new MethodTypeInfo("f4", 4, 0),
+ new MethodTypeInfo("f5", 5, 0),
+ new MethodTypeInfo("f6", 6, 0),
+ new MethodTypeInfo("f7", 7, 0),
+ new MethodTypeInfo("f8", 8, 0),
+ new MethodTypeInfo("f9", 9, 0),
+ new MethodTypeInfo("f10", 10, 0),
+ new MethodTypeInfo("f11", 11, 0),
+ new MethodTypeInfo("f12", 12, 0),
+ new MethodTypeInfo("f13", 13, 0),
+ new MethodTypeInfo("f14", 14, 0),
+ new MethodTypeInfo("f15", 15, 0),
+ new MethodTypeInfo("f16", 16, 0),
+ new MethodTypeInfo("f17", 17, 0),
+ new MethodTypeInfo("f18", 18, 0),
+ new MethodTypeInfo("f19", 19, 0),
+ new MethodTypeInfo("f20", 20, 0),
+ new MethodTypeInfo("f21", 21, 0),
+ new MethodTypeInfo("f22", 22, 0),
+ new MethodTypeInfo("f23", 23, 0),
+ new MethodTypeInfo("f24", 24, 0),
+ new MethodTypeInfo("f25", 25, 0),
+ new MethodTypeInfo("f26", 26, 0),
+ new MethodTypeInfo("f27", 27, 0),
+ new MethodTypeInfo("f28", 28, 0),
+ new MethodTypeInfo("f29", 29, 0),
+ new MethodTypeInfo("f30", 30, 0),
+ new MethodTypeInfo("f31", 31, 0),
+ new MethodTypeInfo("f32", 32, 0),
+ new MethodTypeInfo("f33", 33, 0),
+ new MethodTypeInfo("f34", 34, 0),
+ new MethodTypeInfo("f35", 35, 0),
+ new MethodTypeInfo("f36", 36, 0),
+ new MethodTypeInfo("f37", 37, 0),
+ new MethodTypeInfo("f38", 38, 0),
+ new MethodTypeInfo("f39", 39, 0),
+ new MethodTypeInfo("f40", 40, 0),
+ new MethodTypeInfo("f41", 41, 0),
+ new MethodTypeInfo("f42", 42, 0),
+ new MethodTypeInfo("f43", 43, 0),
+ new MethodTypeInfo("f44", 44, 0),
+ new MethodTypeInfo("f45", 45, 0),
+ new MethodTypeInfo("f46", 46, 0),
+ new MethodTypeInfo("f47", 47, 0),
+ new MethodTypeInfo("f48", 48, 0),
+ new MethodTypeInfo("f49", 49, 0),
+ new MethodTypeInfo("f50", 50, 0),
+ new MethodTypeInfo("f51", 51, 0),
+ new MethodTypeInfo("f52", 52, 0),
+ new MethodTypeInfo("f53", 53, 0),
+ new MethodTypeInfo("f54", 54, 0),
+ new MethodTypeInfo("f55", 55, 0),
+ new MethodTypeInfo("f56", 56, 0),
+ new MethodTypeInfo("f57", 57, 0),
+ new MethodTypeInfo("f58", 58, 0),
+ new MethodTypeInfo("f59", 59, 0),
+ new MethodTypeInfo("f60", 60, 0),
+ new MethodTypeInfo("f61", 61, 0),
+ new MethodTypeInfo("f62", 62, 0),
+ new MethodTypeInfo("f63", 63, 0),
+ new MethodTypeInfo("f64", 64, 0),
+ new MethodTypeInfo("f65", 65, 0),
+ new MethodTypeInfo("f66", 66, 0),
+ new MethodTypeInfo("f67", 67, 0),
+ new MethodTypeInfo("f68", 68, 0),
+ new MethodTypeInfo("f69", 69, 0),
+ new MethodTypeInfo("f70", 70, 0),
+ new MethodTypeInfo("f71", 71, 0),
+ new MethodTypeInfo("f72", 72, 0),
+ new MethodTypeInfo("f73", 73, 0),
+ new MethodTypeInfo("f74", 74, 0),
+ new MethodTypeInfo("f75", 75, 0),
+ new MethodTypeInfo("f76", 76, 0),
+ new MethodTypeInfo("f77", 77, 0),
+ new MethodTypeInfo("f78", 78, 0),
+ new MethodTypeInfo("f79", 79, 0),
+ new MethodTypeInfo("f80", 80, 0),
+ new MethodTypeInfo("f81", 81, 0),
+ new MethodTypeInfo("f82", 82, 0),
+ new MethodTypeInfo("f83", 83, 0),
+ new MethodTypeInfo("f84", 84, 0),
+ new MethodTypeInfo("f85", 85, 0),
+ new MethodTypeInfo("f86", 86, 0),
+ new MethodTypeInfo("f87", 87, 0),
+ new MethodTypeInfo("f88", 88, 0),
+ new MethodTypeInfo("f89", 89, 0),
+ new MethodTypeInfo("f90", 90, 0),
+ new MethodTypeInfo("f91", 91, 0),
+ new MethodTypeInfo("f92", 92, 0),
+ new MethodTypeInfo("f93", 93, 0),
+ new MethodTypeInfo("f94", 94, 0),
+ new MethodTypeInfo("f95", 95, 0),
+ new MethodTypeInfo("f96", 96, 0),
+ new MethodTypeInfo("f97", 97, 0),
+ new MethodTypeInfo("f98", 98, 0),
+ new MethodTypeInfo("f99", 99, 0),
+ new MethodTypeInfo("f100", 100, 0),
+ new MethodTypeInfo("f101", 101, 0),
+ new MethodTypeInfo("f102", 102, 0),
+ new MethodTypeInfo("f103", 103, 0),
+ new MethodTypeInfo("f104", 104, 0),
+ new MethodTypeInfo("f105", 105, 0),
+ new MethodTypeInfo("f106", 106, 0),
+ new MethodTypeInfo("f107", 107, 0),
+ new MethodTypeInfo("f108", 108, 0),
+ new MethodTypeInfo("f109", 109, 0),
+ new MethodTypeInfo("f110", 110, 0),
+ new MethodTypeInfo("f111", 111, 0),
+ new MethodTypeInfo("f112", 112, 0),
+ new MethodTypeInfo("f113", 113, 0),
+ new MethodTypeInfo("f114", 114, 0),
+ new MethodTypeInfo("f115", 115, 0),
+ new MethodTypeInfo("f116", 116, 0),
+ new MethodTypeInfo("f117", 117, 0),
+ new MethodTypeInfo("f118", 118, 0),
+ new MethodTypeInfo("f119", 119, 0),
+ new MethodTypeInfo("f120", 120, 0),
+ new MethodTypeInfo("f121", 121, 0),
+ new MethodTypeInfo("f122", 122, 0),
+ new MethodTypeInfo("f123", 123, 0),
+ new MethodTypeInfo("f124", 124, 0),
+ new MethodTypeInfo("f125", 125, 0),
+ new MethodTypeInfo("f126", 126, 0),
+ new MethodTypeInfo("f127", 127, 0),
+ new MethodTypeInfo("f128", 128, 0),
+ new MethodTypeInfo("f129", 129, 0),
+ new MethodTypeInfo("f130", 130, 0) };
+ }
+}
diff --git a/bridges/test/com/sun/star/lib/uno/bridges/java_remote/PolyStructTest.idl b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/PolyStructTest.idl
new file mode 100644
index 000000000000..68330567d405
--- /dev/null
+++ b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/PolyStructTest.idl
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * 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 "com/sun/star/uno/XInterface.idl"
+
+module com { module sun { module star { module lib { module uno {
+module bridges { module javaremote {
+
+enum TestEnum { VALUE1 = 100, VALUE2 = -100 };
+
+struct TestPolyStruct<T> { T member; };
+
+interface TestTransport {
+ TestPolyStruct<boolean> transportBoolean([in] TestPolyStruct<boolean> arg);
+ TestPolyStruct<byte> transportByte([in] TestPolyStruct<byte> arg);
+ TestPolyStruct<short> transportShort([in] TestPolyStruct<short> arg);
+ TestPolyStruct<long> transportLong([in] TestPolyStruct<long> arg);
+ TestPolyStruct<hyper> transportHyper([in] TestPolyStruct<hyper> arg);
+ TestPolyStruct<float> transportFloat([in] TestPolyStruct<float> arg);
+ TestPolyStruct<double> transportDouble([in] TestPolyStruct<double> arg);
+ TestPolyStruct<char> transportChar([in] TestPolyStruct<char> arg);
+ TestPolyStruct<string> transportString([in] TestPolyStruct<string> arg);
+ TestPolyStruct<type> transportType([in] TestPolyStruct<type> arg);
+ TestPolyStruct<any> transportAny([in] TestPolyStruct<any> arg);
+ TestPolyStruct<TestEnum> transportEnum([in] TestPolyStruct<TestEnum> arg);
+};
+
+}; }; }; }; }; }; };
diff --git a/bridges/test/com/sun/star/lib/uno/bridges/java_remote/PolyStructTest.java b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/PolyStructTest.java
new file mode 100644
index 000000000000..ebf1ed57bc2c
--- /dev/null
+++ b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/PolyStructTest.java
@@ -0,0 +1,260 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.lib.uno.bridges.javaremote;
+
+import com.sun.star.bridge.XInstanceProvider;
+import com.sun.star.lib.TestBed;
+import com.sun.star.lib.uno.typeinfo.MemberTypeInfo;
+import com.sun.star.lib.uno.typeinfo.MethodTypeInfo;
+import com.sun.star.lib.uno.typeinfo.ParameterTypeInfo;
+import com.sun.star.lib.uno.typeinfo.TypeInfo;
+import com.sun.star.uno.Any;
+import com.sun.star.uno.Type;
+import com.sun.star.uno.TypeClass;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.uno.XInterface;
+import complexlib.ComplexTestCase;
+
+public final class PolyStructTest extends ComplexTestCase {
+ public String[] getTestMethodNames() {
+ return new String[] { "test" };
+ }
+
+ public void test() throws Exception {
+ assure(
+ "test",
+ new TestBed().execute(new Provider(), false, Client.class, 0));
+ }
+
+ public static final class Client extends TestBed.Client {
+ public static void main(String[] args) {
+ new Client().execute();
+ }
+
+ protected boolean run(XComponentContext context) throws Throwable {
+ TestTransport t = UnoRuntime.queryInterface(
+ TestTransport.class, getBridge(context).getInstance(""));
+
+ assertEquals(
+ Boolean.FALSE, t.transportBoolean(new TestPolyStruct()).member);
+ assertEquals(
+ Boolean.FALSE,
+ t.transportBoolean(new TestPolyStruct(Boolean.FALSE)).member);
+ assertEquals(
+ Boolean.TRUE,
+ t.transportBoolean(new TestPolyStruct(Boolean.TRUE)).member);
+
+ assertEquals(
+ new Byte((byte) 0),
+ t.transportByte(new TestPolyStruct()).member);
+ assertEquals(
+ new Byte(Byte.MIN_VALUE),
+ t.transportByte(
+ new TestPolyStruct(new Byte(Byte.MIN_VALUE))).member);
+ assertEquals(
+ new Byte(Byte.MAX_VALUE),
+ t.transportByte(
+ new TestPolyStruct(new Byte(Byte.MAX_VALUE))).member);
+
+ assertEquals(
+ new Short((short) 0),
+ t.transportShort(new TestPolyStruct()).member);
+ assertEquals(
+ new Short(Short.MIN_VALUE),
+ t.transportShort(
+ new TestPolyStruct(new Short(Short.MIN_VALUE))).member);
+ assertEquals(
+ new Short(Short.MAX_VALUE),
+ t.transportShort(
+ new TestPolyStruct(new Short(Short.MAX_VALUE))).member);
+
+ assertEquals(
+ new Integer(0), t.transportLong(new TestPolyStruct()).member);
+ assertEquals(
+ new Integer(Integer.MIN_VALUE),
+ t.transportLong(
+ new TestPolyStruct(new Integer(Integer.MIN_VALUE))).member);
+ assertEquals(
+ new Integer(Integer.MAX_VALUE),
+ t.transportLong(
+ new TestPolyStruct(new Integer(Integer.MAX_VALUE))).member);
+
+ assertEquals(
+ new Long(0L), t.transportHyper(new TestPolyStruct()).member);
+ assertEquals(
+ new Long(Long.MIN_VALUE),
+ t.transportHyper(
+ new TestPolyStruct(new Long(Long.MIN_VALUE))).member);
+ assertEquals(
+ new Long(Long.MAX_VALUE),
+ t.transportHyper(
+ new TestPolyStruct(new Long(Long.MAX_VALUE))).member);
+
+ assertEquals(
+ new Float(0.0f), t.transportFloat(new TestPolyStruct()).member);
+ assertEquals(
+ new Float(Float.MIN_VALUE),
+ t.transportFloat(
+ new TestPolyStruct(new Float(Float.MIN_VALUE))).member);
+ assertEquals(
+ new Float(Float.MAX_VALUE),
+ t.transportFloat(
+ new TestPolyStruct(new Float(Float.MAX_VALUE))).member);
+
+ assertEquals(
+ new Double(0.0),
+ t.transportDouble(new TestPolyStruct()).member);
+ assertEquals(
+ new Double(Double.MIN_VALUE),
+ t.transportDouble(
+ new TestPolyStruct(new Double(Double.MIN_VALUE))).member);
+ assertEquals(
+ new Double(Double.MAX_VALUE),
+ t.transportDouble(
+ new TestPolyStruct(new Double(Double.MAX_VALUE))).member);
+
+ assertEquals(
+ new Character(Character.MIN_VALUE),
+ t.transportChar(new TestPolyStruct()).member);
+ assertEquals(
+ new Character(Character.MIN_VALUE),
+ t.transportChar(
+ new TestPolyStruct(
+ new Character(Character.MIN_VALUE))).member);
+ assertEquals(
+ new Character(Character.MAX_VALUE),
+ t.transportChar(
+ new TestPolyStruct(
+ new Character(Character.MAX_VALUE))).member);
+
+ assertEquals("", t.transportString(new TestPolyStruct()).member);
+ assertEquals(
+ "ABC", t.transportString(new TestPolyStruct("ABC")).member);
+
+ assertEquals(
+ Type.VOID, t.transportType(new TestPolyStruct()).member);
+ assertEquals(
+ new Type(
+ "[]com.sun.star.lib.uno.bridges.javaremote.TestPolyStruct"
+ + "<long>"),
+ t.transportType(
+ new TestPolyStruct(
+ new Type(
+ "[]com.sun.star.lib.uno.bridges.javaremote."
+ + "TestPolyStruct<long>"))).member);
+
+ assertEquals(null, t.transportAny(new TestPolyStruct()).member);
+ assertEquals(
+ Any.VOID, t.transportAny(new TestPolyStruct(Any.VOID)).member);
+ assertEquals(null, t.transportAny(new TestPolyStruct(null)).member);
+ assertEquals(
+ new Any(Type.UNSIGNED_LONG, new Integer(5)),
+ t.transportAny(
+ new TestPolyStruct(
+ new Any(Type.UNSIGNED_LONG, new Integer(5)))).member);
+
+ assertEquals(
+ TestEnum.VALUE1, t.transportEnum(new TestPolyStruct()).member);
+ assertEquals(
+ TestEnum.VALUE1,
+ t.transportEnum(new TestPolyStruct(TestEnum.VALUE1)).member);
+ assertEquals(
+ TestEnum.VALUE2,
+ t.transportEnum(new TestPolyStruct(TestEnum.VALUE2)).member);
+
+ return success;
+ }
+
+ private void assertEquals(Object expected, Object actual) {
+ if (!(expected == null ? actual == null : expected.equals(actual)))
+ {
+ new RuntimeException(
+ "failed; expected " + expected + ", got " + actual).
+ printStackTrace();
+ success = false;
+ }
+ }
+
+ private boolean success = true;
+ }
+
+ private static final class Provider implements XInstanceProvider {
+ public Object getInstance(String instanceName) {
+ return new TestTransport() {
+ public TestPolyStruct transportBoolean(TestPolyStruct s) {
+ return s;
+ }
+
+ public TestPolyStruct transportByte(TestPolyStruct s) {
+ return s;
+ }
+
+ public TestPolyStruct transportShort(TestPolyStruct s) {
+ return s;
+ }
+
+ public TestPolyStruct transportLong(TestPolyStruct s) {
+ return s;
+ }
+
+ public TestPolyStruct transportHyper(TestPolyStruct s) {
+ return s;
+ }
+
+ public TestPolyStruct transportFloat(TestPolyStruct s) {
+ return s;
+ }
+
+ public TestPolyStruct transportDouble(TestPolyStruct s) {
+ return s;
+ }
+
+ public TestPolyStruct transportChar(TestPolyStruct s) {
+ return s;
+ }
+
+ public TestPolyStruct transportString(TestPolyStruct s) {
+ return s;
+ }
+
+ public TestPolyStruct transportType(TestPolyStruct s) {
+ return s;
+ }
+
+ public TestPolyStruct transportAny(TestPolyStruct s) {
+ return s;
+ }
+
+ public TestPolyStruct transportEnum(TestPolyStruct s) {
+ return s;
+ }
+ };
+ }
+ }
+}
diff --git a/bridges/test/com/sun/star/lib/uno/bridges/java_remote/StopMessageDispatcherTest.java b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/StopMessageDispatcherTest.java
new file mode 100644
index 000000000000..2456d681563d
--- /dev/null
+++ b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/StopMessageDispatcherTest.java
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package com.sun.star.lib.uno.bridges.javaremote;
+
+import com.sun.star.bridge.XInstanceProvider;
+import com.sun.star.lang.DisposedException;
+import com.sun.star.lib.TestBed;
+import com.sun.star.lib.uno.typeinfo.MethodTypeInfo;
+import com.sun.star.lib.uno.typeinfo.TypeInfo;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.uno.XInterface;
+import complexlib.ComplexTestCase;
+
+/* This test has to detect whether the spawned client process hangs, which can
+ * not be done reliably. As an approximation, it waits for 10 sec and considers
+ * the process hanging if it has not terminated by then.
+ */
+public final class StopMessageDispatcherTest extends ComplexTestCase {
+ public StopMessageDispatcherTest() {}
+
+ public String[] getTestMethodNames() {
+ return new String[] { "test" };
+ }
+
+ public void test() throws Exception {
+ assure(
+ "test",
+ new TestBed().execute(new Provider(), false, Client.class, 10000));
+ }
+
+ public static final class Client extends TestBed.Client {
+ public static void main(String[] args) {
+ new Client().execute();
+ }
+
+ protected boolean run(XComponentContext context) throws Throwable {
+ XTest test = UnoRuntime.queryInterface(
+ XTest.class, getBridge(context).getInstance("Test"));
+ Thread[] threads = new Thread[101];
+ int n = Thread.enumerate(threads);
+ if (n > 100) {
+ System.err.println("ERROR: too many threads");
+ return false;
+ }
+ boolean stopped = false;
+ for (int i = 0; i < n; ++i) {
+ if (threads[i].getName().equals("MessageDispatcher")) {
+ threads[i].stop();
+ stopped = true;
+ break;
+ }
+ }
+ if (!stopped) {
+ System.err.println("ERROR: thread not found");
+ return false;
+ }
+ try {
+ test.call();
+ System.err.println("ERROR: no DisposedException");
+ return false;
+ } catch (DisposedException e) {
+ return true;
+ }
+ }
+
+ private Client() {}
+ }
+
+ private static final class Provider implements XInstanceProvider {
+ public Object getInstance(String instanceName) {
+ return new XTest() {
+ public void call() {}
+ };
+ }
+ }
+
+ public interface XTest extends XInterface {
+ void call();
+
+ TypeInfo[] UNOTYPEINFO = { new MethodTypeInfo("call", 0, 0) };
+ }
+}
diff --git a/bridges/test/com/sun/star/lib/uno/bridges/java_remote/makefile.mk b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/makefile.mk
new file mode 100644
index 000000000000..e532a012c615
--- /dev/null
+++ b/bridges/test/com/sun/star/lib/uno/bridges/java_remote/makefile.mk
@@ -0,0 +1,51 @@
+#*************************************************************************
+#
+# 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 := test_com_sun_star_lib_uno_bridges_javaremote
+
+PACKAGE := com$/sun$/star$/lib$/uno$/bridges$/javaremote
+JAVATESTFILES := \
+ Bug51323_Test.java \
+ Bug92174_Test.java \
+ Bug97697_Test.java \
+ Bug98508_Test.java \
+ Bug107753_Test.java \
+ Bug108825_Test.java \
+ Bug110892_Test.java \
+ Bug111153_Test.java \
+ Bug114133_Test.java \
+ MethodIdTest.java \
+ PolyStructTest.java \
+ StopMessageDispatcherTest.java
+IDLTESTFILES := \
+ Bug98508_Test.idl \
+ PolyStructTest.idl
+JARFILES := juh.jar jurt.jar ridl.jar
+
+.INCLUDE: javaunittest.mk
diff --git a/bridges/test/inter_libs_exc/inter.cxx b/bridges/test/inter_libs_exc/inter.cxx
new file mode 100644
index 000000000000..56966388f09e
--- /dev/null
+++ b/bridges/test/inter_libs_exc/inter.cxx
@@ -0,0 +1,69 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include "share.h"
+
+#include <rtl/string.hxx>
+#include <osl/module.hxx>
+
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+extern "C" int main( int argc, char const * argv [] )
+{
+#ifdef SAL_W32
+#define SAL_DLLPREFIX ""
+#endif
+ Module mod_starter(
+ OUSTR(SAL_DLLPREFIX"starter"SAL_DLLEXTENSION),
+ SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL );
+ Module mod_thrower(
+ OUSTR(SAL_DLLPREFIX"thrower"SAL_DLLEXTENSION),
+ SAL_LOADMODULE_LAZY | SAL_LOADMODULE_GLOBAL );
+
+ typedef t_throws_exc (SAL_CALL * t_get_thrower)();
+ t_get_thrower get_thrower = (t_get_thrower)mod_thrower.getSymbol( OUSTR("get_thrower") );
+ t_throws_exc thrower = (*get_thrower)();
+
+ typedef void (SAL_CALL * t_starter)( t_throws_exc );
+ t_starter start = (t_starter)mod_starter.getSymbol( OUSTR("start") );
+
+ (*start)( thrower );
+
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/test/inter_libs_exc/makefile.mk b/bridges/test/inter_libs_exc/makefile.mk
new file mode 100644
index 000000000000..7f9ff0512e24
--- /dev/null
+++ b/bridges/test/inter_libs_exc/makefile.mk
@@ -0,0 +1,80 @@
+#*************************************************************************
+#
+# 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=inter
+LIBTARGET=NO
+TARGETTYPE=CUI
+ENABLE_EXCEPTIONS=TRUE
+USE_DEFFILE=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+UNOUCRDEP=$(SOLARBINDIR)$/udkapi.rdb
+UNOUCRRDB=$(SOLARBINDIR)$/udkapi.rdb
+
+# output directory (one dir for each project)
+UNOUCROUT=$(OUT)$/inc$/$(TARGET)
+
+# adding to inludeoath
+INCPRE+=$(UNOUCROUT)
+
+UNOTYPESTYPES := \
+ com.sun.star.lang.IllegalArgumentException \
+ com.sun.star.uno.DeploymentException
+
+SLOFILES=$(SLO)$/starter.obj $(SLO)$/thrower.obj
+
+SHL1TARGET=starter
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1IMPLIB=i$(SHL1TARGET)
+SHL1OBJS=$(SLO)$/starter.obj
+DEF1NAME=$(SHL1TARGET)
+SHL1STDLIBS+= $(CPPULIB) $(SALLIB)
+SHL1VERSIONMAP=$(SHL1TARGET).map
+
+SHL2TARGET=thrower
+SHL2DEF=$(MISC)$/$(SHL2TARGET).def
+SHL2IMPLIB=i$(SHL2TARGET)
+SHL2OBJS=$(SLO)$/thrower.obj
+DEF2NAME=$(SHL2TARGET)
+SHL2STDLIBS+= $(CPPULIB) $(SALLIB)
+SHL2VERSIONMAP=$(SHL2TARGET).map
+
+OBJFILES=$(OBJ)$/inter.obj
+APP1TARGET=inter
+APP1OBJS=$(OBJ)$/inter.obj
+APP1STDLIBS+=\
+ $(SALLIB)
+
+.INCLUDE : target.mk
+
diff --git a/bridges/test/inter_libs_exc/share.h b/bridges/test/inter_libs_exc/share.h
new file mode 100644
index 000000000000..be06619abf76
--- /dev/null
+++ b/bridges/test/inter_libs_exc/share.h
@@ -0,0 +1,10 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/uno/DeploymentException.hpp>
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+typedef void (SAL_CALL * t_throws_exc)();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/test/inter_libs_exc/starter.cxx b/bridges/test/inter_libs_exc/starter.cxx
new file mode 100644
index 000000000000..e19e83990979
--- /dev/null
+++ b/bridges/test/inter_libs_exc/starter.cxx
@@ -0,0 +1,68 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include "share.h"
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+static void some_more( t_throws_exc p )
+{
+ (*p)();
+}
+
+extern "C" void SAL_CALL start( t_throws_exc p )
+{
+ try
+ {
+ some_more( p );
+ }
+ catch (lang::IllegalArgumentException & exc)
+ {
+ OString msg( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
+ printf( "starter.cxx: caught IllegalArgumentException: %s\n", msg.getStr() );
+ }
+ catch (Exception & exc)
+ {
+ OString msg( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
+ printf( "starter.cxx: caught some UNO exc: %s\n", msg.getStr() );
+ }
+ catch (...)
+ {
+ printf( "starter.cxx: caught something\n" );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/test/inter_libs_exc/starter.map b/bridges/test/inter_libs_exc/starter.map
new file mode 100644
index 000000000000..69bf77c0a34b
--- /dev/null
+++ b/bridges/test/inter_libs_exc/starter.map
@@ -0,0 +1,7 @@
+UDK_3_0_0 {
+ global:
+ start;
+ local:
+ *;
+};
+
diff --git a/bridges/test/inter_libs_exc/thrower.cxx b/bridges/test/inter_libs_exc/thrower.cxx
new file mode 100644
index 000000000000..d490e5d7b084
--- /dev/null
+++ b/bridges/test/inter_libs_exc/thrower.cxx
@@ -0,0 +1,51 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "share.h"
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+static void SAL_CALL throws_exc()
+{
+ throw lang::IllegalArgumentException(
+ OUSTR("bla"), Reference< XInterface >(), 0 );
+}
+
+extern "C" t_throws_exc SAL_CALL get_thrower()
+{
+ return throws_exc;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/test/inter_libs_exc/thrower.map b/bridges/test/inter_libs_exc/thrower.map
new file mode 100644
index 000000000000..163d434e0121
--- /dev/null
+++ b/bridges/test/inter_libs_exc/thrower.map
@@ -0,0 +1,7 @@
+UDK_3_0_0 {
+ global:
+ get_thrower;
+ local:
+ *;
+};
+
diff --git a/bridges/test/java_uno/acquire/TestAcquire.java b/bridges/test/java_uno/acquire/TestAcquire.java
new file mode 100644
index 000000000000..0314e6bfcf9d
--- /dev/null
+++ b/bridges/test/java_uno/acquire/TestAcquire.java
@@ -0,0 +1,304 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package test.javauno.acquire;
+
+import com.sun.star.bridge.UnoUrlResolver;
+import com.sun.star.bridge.XBridgeFactory;
+import com.sun.star.bridge.XInstanceProvider;
+import com.sun.star.comp.helper.Bootstrap;
+import com.sun.star.connection.Acceptor;
+import com.sun.star.connection.XAcceptor;
+import com.sun.star.connection.XConnection;
+import com.sun.star.lib.uno.helper.UnoUrl;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.uno.XInterface;
+import util.WaitUnreachable;
+
+public final class TestAcquire {
+ public static void main(String[] arguments) throws Exception {
+ // - arguments[0] must be "client" or "server"
+ // - arguments[1] must be the UNO URL to connect to (client) or accept
+ // on (server)
+ XComponentContext context
+ = Bootstrap.createInitialComponentContext(null);
+ if (arguments[0].equals("client")) {
+ execClient(context, arguments[1]);
+ } else {
+ execServer(context, arguments[1]);
+ }
+ }
+
+ private static void assertNotNull(Object obj) {
+ if (obj == null) {
+ throw new RuntimeException("assertNotNull failed");
+ }
+ }
+
+ private static void receive(Object obj) {
+ assertNotNull(obj);
+ WaitUnreachable.ensureFinalization(obj);
+ }
+
+ private static void execClient(XComponentContext context, String url)
+ throws Exception
+ {
+ XTest test = UnoRuntime.queryInterface(
+ XTest.class, UnoUrlResolver.create(context).resolve(url));
+
+ WaitUnreachable u;
+
+ u = new WaitUnreachable(new XInterface() {});
+ test.setInterfaceToInterface((XInterface) u.get());
+ receive(test.getInterfaceFromInterface());
+ test.clearInterface();
+ u.waitUnreachable();
+ u = new WaitUnreachable(new XBase() {});
+ test.setInterfaceToInterface((XBase) u.get());
+ receive(test.getInterfaceFromInterface());
+ test.clearInterface();
+ u.waitUnreachable();
+ u = new WaitUnreachable(new XDerived() {});
+ test.setInterfaceToInterface((XDerived) u.get());
+ receive(test.getInterfaceFromInterface());
+ test.clearInterface();
+ u.waitUnreachable();
+
+ u = new WaitUnreachable(new XBase() {});
+ test.setBaseToInterface((XBase) u.get());
+ receive(test.getInterfaceFromInterface());
+ test.clearInterface();
+ u.waitUnreachable();
+ u = new WaitUnreachable(new XDerived() {});
+ test.setBaseToInterface((XDerived) u.get());
+ receive(test.getInterfaceFromInterface());
+ test.clearInterface();
+ u.waitUnreachable();
+
+ u = new WaitUnreachable(new XDerived() {});
+ test.setDerivedToInterface((XDerived) u.get());
+ receive(test.getInterfaceFromInterface());
+ test.clearInterface();
+ u.waitUnreachable();
+
+ u = new WaitUnreachable(new XBase() {});
+ test.setBaseToBase((XBase) u.get());
+ receive(test.getInterfaceFromBase());
+ receive(test.getBaseFromBase());
+ test.clearBase();
+ u.waitUnreachable();
+ u = new WaitUnreachable(new XDerived() {});
+ test.setBaseToBase((XDerived) u.get());
+ receive(test.getInterfaceFromBase());
+ receive(test.getBaseFromBase());
+ test.clearBase();
+ u.waitUnreachable();
+
+ u = new WaitUnreachable(new XDerived() {});
+ test.setDerivedToBase((XDerived) u.get());
+ receive(test.getInterfaceFromBase());
+ receive(test.getBaseFromBase());
+ test.clearBase();
+ u.waitUnreachable();
+
+ u = new WaitUnreachable(new XDerived() {});
+ test.setDerivedToDerived((XDerived) u.get());
+ receive(test.getInterfaceFromDerived());
+ receive(test.getBaseFromDerived());
+ receive(test.getDerivedFromDerived());
+ test.clearDerived();
+ u.waitUnreachable();
+
+ u = new WaitUnreachable(new XInterface() {});
+ receive(test.roundTripInterfaceToInterface((XInterface) u.get()));
+ u.waitUnreachable();
+ u = new WaitUnreachable(new XBase() {});
+ receive(test.roundTripInterfaceToInterface((XBase) u.get()));
+ u.waitUnreachable();
+ u = new WaitUnreachable(new XDerived() {});
+ receive(test.roundTripInterfaceToInterface((XDerived) u.get()));
+ u.waitUnreachable();
+
+ u = new WaitUnreachable(new XBase() {});
+ receive(test.roundTripBaseToInterface((XBase) u.get()));
+ u.waitUnreachable();
+ u = new WaitUnreachable(new XDerived() {});
+ receive(test.roundTripBaseToInterface((XDerived) u.get()));
+ u.waitUnreachable();
+
+ u = new WaitUnreachable(new XDerived() {});
+ receive(test.roundTripDerivedToInterface((XDerived) u.get()));
+ u.waitUnreachable();
+
+ u = new WaitUnreachable(new XBase() {});
+ receive(test.roundTripBaseToBase((XBase) u.get()));
+ u.waitUnreachable();
+ u = new WaitUnreachable(new XDerived() {});
+ receive(test.roundTripBaseToBase((XDerived) u.get()));
+ u.waitUnreachable();
+
+ u = new WaitUnreachable(new XDerived() {});
+ receive(test.roundTripDerivedToBase((XDerived) u.get()));
+ u.waitUnreachable();
+
+ u = new WaitUnreachable(new XDerived() {});
+ receive(test.roundTripDerivedToDerived((XDerived) u.get()));
+ u.waitUnreachable();
+
+ u = new WaitUnreachable(test);
+ test = null;
+ u.waitUnreachable();
+ System.out.println(
+ "Client and server both cleanly terminate now: Success");
+ }
+
+ private static void execServer(XComponentContext context, String url)
+ throws Exception
+ {
+ XAcceptor acceptor = Acceptor.create(context);
+ XBridgeFactory factory = UnoRuntime.queryInterface(
+ XBridgeFactory.class,
+ context.getServiceManager().createInstanceWithContext(
+ "com.sun.star.bridge.BridgeFactory", context));
+ UnoUrl unoUrl = UnoUrl.parseUnoUrl(url);
+ System.out.println("Server: Accepting...");
+ XConnection connection = acceptor.accept(
+ unoUrl.getConnectionAndParametersAsString());
+ System.out.println("Server: ...connected...");
+ factory.createBridge(
+ "", unoUrl.getProtocolAndParametersAsString(), connection,
+ new Provider());
+ System.out.println("Server: ...bridged.");
+ }
+
+ private static final class Provider implements XInstanceProvider {
+ public Object getInstance(String instanceName) {
+ return new XTest() {
+ public void setInterfaceToInterface(Object obj) {
+ iface = obj;
+ }
+
+ public void setBaseToInterface(XBase obj) {
+ iface = obj;
+ }
+
+ public void setDerivedToInterface(XDerived obj) {
+ iface = obj;
+ }
+
+ public Object getInterfaceFromInterface() {
+ return iface;
+ }
+
+ public void clearInterface() {
+ WaitUnreachable u = new WaitUnreachable(iface);
+ iface = null;
+ u.waitUnreachable();
+ }
+
+ public void setBaseToBase(XBase obj) {
+ base = obj;
+ }
+
+ public void setDerivedToBase(XDerived obj) {
+ base = obj;
+ }
+
+ public Object getInterfaceFromBase() {
+ return base;
+ }
+
+ public XBase getBaseFromBase() {
+ return base;
+ }
+
+ public void clearBase() {
+ WaitUnreachable u = new WaitUnreachable(base);
+ base = null;
+ u.waitUnreachable();
+ }
+
+ public void setDerivedToDerived(XDerived obj) {
+ derived = obj;
+ }
+
+ public Object getInterfaceFromDerived() {
+ return derived;
+ }
+
+ public XBase getBaseFromDerived() {
+ return derived;
+ }
+
+ public XDerived getDerivedFromDerived() {
+ return derived;
+ }
+
+ public void clearDerived() {
+ WaitUnreachable u = new WaitUnreachable(derived);
+ derived = null;
+ u.waitUnreachable();
+ }
+
+ public Object roundTripInterfaceToInterface(Object obj) {
+ WaitUnreachable.ensureFinalization(obj);
+ return obj;
+ }
+
+ public Object roundTripBaseToInterface(XBase obj) {
+ WaitUnreachable.ensureFinalization(obj);
+ return obj;
+ }
+
+ public Object roundTripDerivedToInterface(XDerived obj) {
+ WaitUnreachable.ensureFinalization(obj);
+ return obj;
+ }
+
+ public XBase roundTripBaseToBase(XBase obj) {
+ WaitUnreachable.ensureFinalization(obj);
+ return obj;
+ }
+
+ public XBase roundTripDerivedToBase(XDerived obj) {
+ WaitUnreachable.ensureFinalization(obj);
+ return obj;
+ }
+
+ public XDerived roundTripDerivedToDerived(XDerived obj) {
+ WaitUnreachable.ensureFinalization(obj);
+ return obj;
+ }
+
+ private Object iface;
+ private XBase base;
+ private XDerived derived;
+ };
+ }
+ }
+}
diff --git a/bridges/test/java_uno/acquire/makefile.mk b/bridges/test/java_uno/acquire/makefile.mk
new file mode 100644
index 000000000000..def12dd53c49
--- /dev/null
+++ b/bridges/test/java_uno/acquire/makefile.mk
@@ -0,0 +1,117 @@
+#*************************************************************************
+#
+# 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 := test_javauno_acquire
+PACKAGE := test$/javauno$/acquire
+
+ENABLE_EXCEPTIONS := TRUE
+
+.INCLUDE: settings.mk
+
+DLLPRE = # no leading "lib" on .so files
+INCPRE += $(MISC)$/$(TARGET)$/inc
+
+SLOFILES = $(SLO)$/testacquire.obj
+
+SHL1TARGET = testacquire.uno
+SHL1OBJS = $(SLOFILES)
+SHL1STDLIBS = $(CPPULIB) $(CPPUHELPERLIB) $(SALLIB)
+SHL1VERSIONMAP = $(SOLARENV)/src/component.map
+SHL1IMPLIB = itestacquire
+
+JAVAFILES = TestAcquire.java
+JARFILES = OOoRunner.jar juh.jar jurt.jar ridl.jar
+
+.INCLUDE: target.mk
+
+ALLTAR: \
+ $(BIN)$/testacquire-java-client \
+ $(BIN)$/testacquire-java-server \
+ $(BIN)$/testacquire-native-client \
+ $(BIN)$/testacquire-native-server
+
+.IF "$(GUI)" == "WNT"
+GIVE_EXEC_RIGHTS = @echo
+.ELSE # GUI, WNT
+GIVE_EXEC_RIGHTS = chmod +x
+.ENDIF # GUI, WNT
+
+EXEC_CLASSPATH_TMP = $(foreach,i,$(JARFILES) $(SOLARBINDIR)$/$i)
+EXEC_CLASSPATH = \
+ $(strip $(subst,!,$(PATH_SEPERATOR) $(EXEC_CLASSPATH_TMP:s/ /!/)))
+
+$(BIN)$/$(TARGET).rdb: types.idl
+ - rm $@
+ - $(MKDIR) $(MISC)$/$(TARGET)
+ - $(MKDIR) $(MISC)$/$(TARGET)$/inc
+ $(IDLC) -I$(SOLARIDLDIR) -O$(MISC)$/$(TARGET) $<
+ $(REGMERGE) $@ /UCR $(MISC)$/$(TARGET)$/types.urd
+ $(CPPUMAKER) -BUCR -C -O$(MISC)$/$(TARGET)$/inc $@ -X$(SOLARBINDIR)$/types.rdb
+ $(JAVAMAKER) -BUCR -nD -O$(CLASSDIR) $@ -X$(SOLARBINDIR)$/types.rdb
+ $(REGMERGE) $@ / $(SOLARBINDIR)$/types.rdb
+ $(REGCOMP) -register -r $@ -c acceptor.uno$(DLLPOST) \
+ -c bridgefac.uno$(DLLPOST) -c connector.uno$(DLLPOST) \
+ -c remotebridge.uno$(DLLPOST) -c uuresolver.uno$(DLLPOST)
+
+$(SLOFILES) $(JAVACLASSFILES): $(BIN)$/$(TARGET).rdb
+
+# Use "127.0.0.1" instead of "localhost", see #i32281#:
+TEST_JAVAUNO_ACQUIRE_UNO_URL := \
+ \"'uno:socket,host=127.0.0.1,port=2002;urp;test'\"
+
+$(BIN)$/testacquire-java-client:
+ echo java -classpath \
+ ..$/class$/test$(PATH_SEPERATOR)..$/class$(PATH_SEPERATOR)\
+..$/class$/java_uno.jar$(PATH_SEPERATOR)$(EXEC_CLASSPATH) \
+ test.javauno.acquire.TestAcquire client \
+ $(TEST_JAVAUNO_ACQUIRE_UNO_URL) > $@
+ $(GIVE_EXEC_RIGHTS) $@
+
+$(BIN)$/testacquire-java-server:
+ echo java -classpath \
+ ..$/class$/test$(PATH_SEPERATOR)..$/class$(PATH_SEPERATOR)\
+..$/class$/java_uno.jar$(PATH_SEPERATOR)$(EXEC_CLASSPATH) \
+ test.javauno.acquire.TestAcquire server \
+ $(TEST_JAVAUNO_ACQUIRE_UNO_URL) > $@
+ $(GIVE_EXEC_RIGHTS) $@
+
+$(BIN)$/testacquire-native-client:
+ echo '$(AUGMENT_LIBRARY_PATH)' uno \
+ -c com.sun.star.test.bridges.testacquire.impl \
+ -l ../lib/$(SHL1TARGETN:f) -ro $(TARGET).rdb -- \
+ $(TEST_JAVAUNO_ACQUIRE_UNO_URL) > $@
+ $(GIVE_EXEC_RIGHTS) $@
+
+$(BIN)$/testacquire-native-server:
+ echo '$(AUGMENT_LIBRARY_PATH)' uno \
+ -c com.sun.star.test.bridges.testacquire.impl \
+ -l ../lib/$(SHL1TARGETN:f) -ro $(TARGET).rdb \
+ -u $(TEST_JAVAUNO_ACQUIRE_UNO_URL) --singleaccept > $@
+ $(GIVE_EXEC_RIGHTS) $@
diff --git a/bridges/test/java_uno/acquire/readme.txt b/bridges/test/java_uno/acquire/readme.txt
new file mode 100644
index 000000000000..40bdf645c295
--- /dev/null
+++ b/bridges/test/java_uno/acquire/readme.txt
@@ -0,0 +1,21 @@
+Test scenarios:
+
+> cd .../bridges/<outdir>/bin
+> ./testacquire-java-server &
+> sleep 3 # wait for server to accept connection
+> ./testacquire-java-client
+
+> cd .../bridges/<outdir>/bin
+> ./testacquire-java-server &
+> sleep 3 # wait for server to accept connection
+> ./testacquire-native-client
+
+> cd .../bridges/<outdir>/bin
+> ./testacquire-native-server &
+> sleep 3 # wait for server to accept connection
+> ./testacquire-java-client
+
+> cd .../bridges/<outdir>/bin
+> ./testacquire-native-server &
+> sleep 3 # wait for server to accept connection
+> ./testacquire-native-client
diff --git a/bridges/test/java_uno/acquire/testacquire.cxx b/bridges/test/java_uno/acquire/testacquire.cxx
new file mode 100644
index 000000000000..95a4a0241d20
--- /dev/null
+++ b/bridges/test/java_uno/acquire/testacquire.cxx
@@ -0,0 +1,577 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "com/sun/star/bridge/UnoUrlResolver.hpp"
+#include "com/sun/star/bridge/XUnoUrlResolver.hpp"
+#include "com/sun/star/lang/XMain.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XSingleComponentFactory.hpp"
+#include "com/sun/star/registry/InvalidRegistryException.hpp"
+#include "com/sun/star/registry/XRegistryKey.hpp"
+#include "com/sun/star/uno/Any.hxx"
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/Type.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implbase3.hxx"
+#include "cppuhelper/weak.hxx"
+#include "osl/conditn.hxx"
+#include "osl/interlck.h"
+#include "rtl/string.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "test/javauno/acquire/XBase.hpp"
+#include "test/javauno/acquire/XDerived.hpp"
+#include "test/javauno/acquire/XTest.hpp"
+#include "uno/environment.h"
+#include "uno/lbnames.h"
+
+#include <iostream>
+#include <cstdlib>
+
+namespace css = com::sun::star;
+
+namespace {
+
+class WaitCondition {
+public:
+ WaitCondition() {}
+
+ ~WaitCondition();
+
+ osl::Condition & get() { return m_condition; }
+
+private:
+ WaitCondition(WaitCondition &); // not implemented
+ void operator =(WaitCondition); // not implemented
+
+ osl::Condition m_condition;
+};
+
+}
+
+WaitCondition::~WaitCondition() {
+ std::cout << "waiting for condition\n";
+ if (m_condition.wait() != osl::Condition::result_ok) {
+ throw "osl::Condition::wait failed";
+ }
+}
+
+namespace {
+
+class Interface: public css::uno::XInterface {
+public:
+ explicit Interface(osl::Condition & condition):
+ m_condition(condition), m_refCount(0) {}
+
+ virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const & type)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL acquire() throw ()
+ { osl_incrementInterlockedCount(&m_refCount); }
+
+ virtual void SAL_CALL release() throw ();
+
+protected:
+ virtual ~Interface() { m_condition.set(); }
+
+private:
+ Interface(Interface &); // not implemented
+ void operator =(Interface); // not implemented
+
+ osl::Condition & m_condition;
+ oslInterlockedCount m_refCount;
+};
+
+}
+
+css::uno::Any Interface::queryInterface(css::uno::Type const & type)
+ throw (css::uno::RuntimeException)
+{
+ return type.getTypeName().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
+ "com.sun.star.uno.XInterface"))
+ ? css::uno::makeAny(css::uno::Reference< css::uno::XInterface >(this))
+ : css::uno::Any();
+}
+
+void Interface::release() throw () {
+ if (osl_decrementInterlockedCount(&m_refCount) == 0) {
+ delete this;
+ }
+}
+
+namespace {
+
+class Base: public Interface, public test::javauno::acquire::XBase {
+public:
+ explicit Base(osl::Condition & condition): Interface(condition) {}
+
+ virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const & type)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL acquire() throw () { Interface::acquire(); }
+
+ virtual void SAL_CALL release() throw () { Interface::release(); }
+
+protected:
+ virtual ~Base() {}
+};
+
+}
+
+css::uno::Any Base::queryInterface(css::uno::Type const & type)
+ throw (css::uno::RuntimeException)
+{
+ return type.getTypeName().equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
+ "test.javauno.acquire.XBase"))
+ ? css::uno::makeAny(
+ css::uno::Reference< test::javauno::acquire::XBase >(this))
+ : Interface::queryInterface(type);
+}
+
+namespace {
+
+class Derived: public Base, public test::javauno::acquire::XDerived {
+public:
+ explicit Derived(osl::Condition & condition): Base(condition) {}
+
+ virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const & type)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL acquire() throw () { Base::acquire(); }
+
+ virtual void SAL_CALL release() throw () { Base::release(); }
+
+private:
+ virtual ~Derived() {}
+};
+
+}
+
+css::uno::Any Derived::queryInterface(css::uno::Type const & type)
+ throw (css::uno::RuntimeException)
+{
+ return (type.getTypeName().equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("test.javauno.acquire.XDerived")))
+ ? css::uno::makeAny(
+ css::uno::Reference< test::javauno::acquire::XDerived >(this))
+ : Interface::queryInterface(type);
+}
+
+namespace {
+
+class Service: public cppu::WeakImplHelper3<
+ css::lang::XServiceInfo, css::lang::XMain, test::javauno::acquire::XTest >
+{
+public:
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException)
+ { return getImplementationName_static(); }
+
+ virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException)
+ { return getSupportedServiceNames_static(); }
+
+ virtual sal_Int32 SAL_CALL
+ run(css::uno::Sequence< rtl::OUString > const & arguments)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL setInterfaceToInterface(
+ css::uno::Reference< css::uno::XInterface > const & obj)
+ throw (css::uno::RuntimeException)
+ { m_interface = obj; }
+
+ virtual void SAL_CALL setBaseToInterface(
+ css::uno::Reference< test::javauno::acquire::XBase > const & obj)
+ throw (css::uno::RuntimeException)
+ { m_interface = obj; }
+
+ virtual void SAL_CALL setDerivedToInterface(
+ css::uno::Reference< test::javauno::acquire::XDerived > const & obj)
+ throw (css::uno::RuntimeException)
+ { m_interface = obj; }
+
+ virtual css::uno::Reference< css::uno::XInterface >
+ SAL_CALL getInterfaceFromInterface() throw (css::uno::RuntimeException)
+ { return m_interface; }
+
+ virtual void SAL_CALL clearInterface() throw (css::uno::RuntimeException)
+ { m_interface.clear(); }
+
+ virtual void SAL_CALL setBaseToBase(
+ css::uno::Reference< test::javauno::acquire::XBase > const & obj)
+ throw (css::uno::RuntimeException)
+ { m_base = obj; }
+
+ virtual void SAL_CALL setDerivedToBase(
+ css::uno::Reference< test::javauno::acquire::XDerived > const & obj)
+ throw (css::uno::RuntimeException)
+ { m_base = obj.get(); }
+
+ virtual css::uno::Reference< css::uno::XInterface >
+ SAL_CALL getInterfaceFromBase() throw (css::uno::RuntimeException)
+ { return m_base; }
+
+ virtual css::uno::Reference< test::javauno::acquire::XBase >
+ SAL_CALL getBaseFromBase() throw (css::uno::RuntimeException)
+ { return m_base; }
+
+ virtual void SAL_CALL clearBase() throw (css::uno::RuntimeException)
+ { m_base.clear(); }
+
+ virtual void SAL_CALL setDerivedToDerived(
+ css::uno::Reference< test::javauno::acquire::XDerived > const & obj)
+ throw (css::uno::RuntimeException)
+ { m_derived = obj; }
+
+ virtual css::uno::Reference< css::uno::XInterface >
+ SAL_CALL getInterfaceFromDerived() throw (css::uno::RuntimeException)
+ { return m_derived; }
+
+ virtual css::uno::Reference< test::javauno::acquire::XBase >
+ SAL_CALL getBaseFromDerived() throw (css::uno::RuntimeException)
+ { return m_derived.get(); }
+
+ virtual css::uno::Reference< test::javauno::acquire::XDerived >
+ SAL_CALL getDerivedFromDerived() throw (css::uno::RuntimeException)
+ { return m_derived; }
+
+ virtual void SAL_CALL clearDerived() throw (css::uno::RuntimeException)
+ { m_derived.clear(); }
+
+ virtual css::uno::Reference< css::uno::XInterface >
+ SAL_CALL roundTripInterfaceToInterface(
+ css::uno::Reference< css::uno::XInterface > const & obj)
+ throw (css::uno::RuntimeException)
+ { return obj; }
+
+ virtual css::uno::Reference< css::uno::XInterface >
+ SAL_CALL roundTripBaseToInterface(
+ css::uno::Reference< test::javauno::acquire::XBase > const & obj)
+ throw (css::uno::RuntimeException)
+ { return obj; }
+
+ virtual css::uno::Reference< css::uno::XInterface >
+ SAL_CALL roundTripDerivedToInterface(
+ css::uno::Reference< test::javauno::acquire::XDerived > const & obj)
+ throw (css::uno::RuntimeException)
+ { return obj; }
+
+ virtual css::uno::Reference< test::javauno::acquire::XBase >
+ SAL_CALL roundTripBaseToBase(
+ css::uno::Reference< test::javauno::acquire::XBase > const & obj)
+ throw (css::uno::RuntimeException)
+ { return obj; }
+
+ virtual css::uno::Reference< test::javauno::acquire::XBase >
+ SAL_CALL roundTripDerivedToBase(
+ css::uno::Reference< test::javauno::acquire::XDerived > const & obj)
+ throw (css::uno::RuntimeException)
+ { return obj.get(); }
+
+ virtual css::uno::Reference< test::javauno::acquire::XDerived >
+ SAL_CALL roundTripDerivedToDerived(
+ css::uno::Reference< test::javauno::acquire::XDerived > const & obj)
+ throw (css::uno::RuntimeException)
+ { return obj; }
+
+ static rtl::OUString getImplementationName_static();
+
+ static css::uno::Sequence< rtl::OUString >
+ getSupportedServiceNames_static();
+
+ static css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance(
+ css::uno::Reference< css::uno::XComponentContext > const & context)
+ throw (css::uno::Exception);
+
+private:
+ explicit Service(
+ css::uno::Reference< css::uno::XComponentContext > const & context):
+ m_context(context) {}
+
+ css::uno::Reference< css::uno::XComponentContext > m_context;
+ css::uno::Reference< css::uno::XInterface > m_interface;
+ css::uno::Reference< test::javauno::acquire::XBase > m_base;
+ css::uno::Reference< test::javauno::acquire::XDerived > m_derived;
+};
+
+}
+
+sal_Bool Service::supportsService(rtl::OUString const & serviceName)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Sequence< rtl::OUString > names(
+ getSupportedServiceNames_static());
+ for (sal_Int32 i = 0; i< names.getLength(); ++i) {
+ if (names[i] == serviceName) {
+ return true;
+ }
+ }
+ return false;
+}
+
+namespace {
+
+template< typename T > void assertNotNull(css::uno::Reference< T > const & ref)
+{
+ if (!ref.is()) {
+ std::cerr << "assertNotNull failed\n";
+ std::abort();
+ }
+}
+
+}
+
+sal_Int32 Service::run(css::uno::Sequence< rtl::OUString > const & arguments)
+ throw (css::uno::RuntimeException)
+{
+ // - arguments[0] must be the UNO URL to connect to:
+ css::uno::Reference< XTest > test(
+ css::bridge::UnoUrlResolver::create(m_context)->resolve(arguments[0]),
+ css::uno::UNO_QUERY_THROW);
+
+ {
+ WaitCondition c;
+ test->setInterfaceToInterface(new Interface(c.get()));
+ assertNotNull(test->getInterfaceFromInterface());
+ test->clearInterface();
+ }
+ {
+ WaitCondition c;
+ test->setInterfaceToInterface(
+ static_cast< Interface * >(new Base(c.get())));
+ assertNotNull(test->getInterfaceFromInterface());
+ test->clearInterface();
+ }
+ {
+ WaitCondition c;
+ test->setInterfaceToInterface(
+ static_cast< Interface * >(new Derived(c.get())));
+ assertNotNull(test->getInterfaceFromInterface());
+ test->clearInterface();
+ }
+
+ {
+ WaitCondition c;
+ test->setBaseToInterface(new Base(c.get()));
+ assertNotNull(test->getInterfaceFromInterface());
+ test->clearInterface();
+ }
+ {
+ WaitCondition c;
+ test->setBaseToInterface(static_cast< Base * >(new Derived(c.get())));
+ assertNotNull(test->getInterfaceFromInterface());
+ test->clearInterface();
+ }
+
+ {
+ WaitCondition c;
+ test->setDerivedToInterface(new Derived(c.get()));
+ assertNotNull(test->getInterfaceFromInterface());
+ test->clearInterface();
+ }
+
+ {
+ WaitCondition c;
+ test->setBaseToBase(new Base(c.get()));
+ assertNotNull(test->getInterfaceFromBase());
+ assertNotNull(test->getBaseFromBase());
+ test->clearBase();
+ }
+ {
+ WaitCondition c;
+ test->setBaseToBase(static_cast< Base * >(new Derived(c.get())));
+ assertNotNull(test->getInterfaceFromBase());
+ assertNotNull(test->getBaseFromBase());
+ test->clearBase();
+ }
+
+ {
+ WaitCondition c;
+ test->setDerivedToBase(new Derived(c.get()));
+ assertNotNull(test->getInterfaceFromBase());
+ assertNotNull(test->getBaseFromBase());
+ test->clearBase();
+ }
+
+ {
+ WaitCondition c;
+ test->setDerivedToDerived(new Derived(c.get()));
+ assertNotNull(test->getInterfaceFromDerived());
+ assertNotNull(test->getBaseFromDerived());
+ assertNotNull(test->getDerivedFromDerived());
+ test->clearDerived();
+ }
+
+ {
+ WaitCondition c;
+ assertNotNull(
+ test->roundTripInterfaceToInterface(new Interface(c.get())));
+ }
+ {
+ WaitCondition c;
+ assertNotNull(test->roundTripInterfaceToInterface(
+ static_cast< Interface * >(new Base(c.get()))));
+ }
+ {
+ WaitCondition c;
+ assertNotNull(test->roundTripInterfaceToInterface(
+ static_cast< Interface * >(new Derived(c.get()))));
+ }
+
+ {
+ WaitCondition c;
+ assertNotNull(test->roundTripBaseToInterface(new Base(c.get())));
+ }
+ {
+ WaitCondition c;
+ assertNotNull(test->roundTripBaseToInterface(
+ static_cast< Base * >(new Derived(c.get()))));
+ }
+
+ {
+ WaitCondition c;
+ assertNotNull(test->roundTripDerivedToInterface(new Derived(c.get())));
+ }
+
+ {
+ WaitCondition c;
+ assertNotNull(test->roundTripBaseToBase(new Base(c.get())));
+ }
+ {
+ WaitCondition c;
+ assertNotNull(test->roundTripBaseToBase(
+ static_cast< Base * >(new Derived(c.get()))));
+ }
+
+ {
+ WaitCondition c;
+ assertNotNull(test->roundTripDerivedToBase(new Derived(c.get())));
+ }
+
+ {
+ WaitCondition c;
+ assertNotNull(test->roundTripDerivedToDerived(new Derived(c.get())));
+ }
+
+ std::cout << "Client and server both cleanly terminate now: Success\n";
+ return 0;
+}
+
+rtl::OUString Service::getImplementationName_static() {
+ return rtl::OUString::createFromAscii(
+ "com.sun.star.test.bridges.testacquire.impl");
+}
+
+css::uno::Sequence< rtl::OUString > Service::getSupportedServiceNames_static() {
+ css::uno::Sequence< rtl::OUString > names(1);
+ names[0] = rtl::OUString::createFromAscii(
+ "com.sun.star.test.bridges.testacquire");
+ return names;
+}
+
+css::uno::Reference< css::uno::XInterface > Service::createInstance(
+ css::uno::Reference< css::uno::XComponentContext > const & context)
+ throw (css::uno::Exception)
+{
+ return static_cast< cppu::OWeakObject * >(new Service(context));
+}
+
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ char const ** envTypeName, uno_Environment **)
+{
+ if (envTypeName != 0) {
+ *envTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+ }
+}
+
+extern "C" void * SAL_CALL component_getFactory(char const * implName,
+ void * serviceManager, void *) {
+ void * p = 0;
+ if (serviceManager != 0) {
+ css::uno::Reference< css::lang::XSingleComponentFactory > f;
+ if (Service::getImplementationName_static().equalsAscii(implName)) {
+ f = cppu::createSingleComponentFactory(
+ &Service::createInstance,
+ Service::getImplementationName_static(),
+ Service::getSupportedServiceNames_static());
+ }
+ if (f.is()) {
+ f->acquire();
+ p = f.get();
+ }
+ }
+ return p;
+}
+
+namespace {
+
+bool writeInfo(void * registryKey, rtl::OUString const & implementationName,
+ css::uno::Sequence< rtl::OUString > const & serviceNames) {
+ rtl::OUString keyName(rtl::OUString::createFromAscii("/"));
+ keyName += implementationName;
+ keyName += rtl::OUString::createFromAscii("/UNO/SERVICES");
+ css::uno::Reference< css::registry::XRegistryKey > key;
+ try {
+ key = static_cast< css::registry::XRegistryKey * >(registryKey)->
+ createKey(keyName);
+ } catch (css::registry::InvalidRegistryException &) {}
+ if (!key.is()) {
+ return false;
+ }
+ bool success = true;
+ for (sal_Int32 i = 0; i < serviceNames.getLength(); ++i) {
+ try {
+ key->createKey(serviceNames[i]);
+ } catch (css::registry::InvalidRegistryException &) {
+ success = false;
+ break;
+ }
+ }
+ return success;
+}
+
+}
+
+extern "C" sal_Bool SAL_CALL component_writeInfo(void *, void * registryKey) {
+ return registryKey
+ && writeInfo(registryKey, Service::getImplementationName_static(),
+ Service::getSupportedServiceNames_static());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/test/java_uno/acquire/types.idl b/bridges/test/java_uno/acquire/types.idl
new file mode 100644
index 000000000000..6dd2964777bd
--- /dev/null
+++ b/bridges/test/java_uno/acquire/types.idl
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * 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 "com/sun/star/uno/XInterface.idl"
+
+module test { module javauno { module acquire {
+
+interface XBase: com::sun::star::uno::XInterface {};
+
+interface XDerived: XBase {};
+
+interface XTest: com::sun::star::uno::XInterface
+{
+ void setInterfaceToInterface([in] com::sun::star::uno::XInterface obj);
+ void setBaseToInterface([in] XBase obj);
+ void setDerivedToInterface([in] XDerived obj);
+ com::sun::star::uno::XInterface getInterfaceFromInterface();
+ void clearInterface();
+
+ void setBaseToBase([in] XBase obj);
+ void setDerivedToBase([in] XDerived obj);
+ com::sun::star::uno::XInterface getInterfaceFromBase();
+ XBase getBaseFromBase();
+ void clearBase();
+
+ void setDerivedToDerived([in] XDerived obj);
+ com::sun::star::uno::XInterface getInterfaceFromDerived();
+ XBase getBaseFromDerived();
+ XDerived getDerivedFromDerived();
+ void clearDerived();
+
+ com::sun::star::uno::XInterface roundTripInterfaceToInterface(
+ [in] com::sun::star::uno::XInterface obj);
+ com::sun::star::uno::XInterface roundTripBaseToInterface([in] XBase obj);
+ com::sun::star::uno::XInterface roundTripDerivedToInterface(
+ [in] XDerived obj);
+
+ XBase roundTripBaseToBase([in] XBase obj);
+ XBase roundTripDerivedToBase([in] XDerived obj);
+
+ XDerived roundTripDerivedToDerived([in] XDerived obj);
+};
+
+}; }; };
diff --git a/bridges/test/java_uno/any/TestAny.java b/bridges/test/java_uno/any/TestAny.java
new file mode 100644
index 000000000000..43e8bf542479
--- /dev/null
+++ b/bridges/test/java_uno/any/TestAny.java
@@ -0,0 +1,2267 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package test.java_uno.anytest;
+
+import com.sun.star.uno.Any;
+import com.sun.star.uno.Enum;
+import com.sun.star.uno.Type;
+import com.sun.star.uno.TypeClass;
+import com.sun.star.uno.XInterface;
+import java.lang.reflect.Array;
+
+final class TestAny {
+ public static boolean test(XTransport transport, boolean createTypes) {
+ boolean success = true;
+
+ // Sanity check for com.sun.star.uno.Type:
+ success &= testType(void.class, TypeClass.VOID, "void");
+ success &= testType(boolean.class, TypeClass.BOOLEAN, "boolean");
+ success &= testType(byte.class, TypeClass.BYTE, "byte");
+ success &= testType(short.class, TypeClass.SHORT, "short");
+ success &= testType(int.class, TypeClass.LONG, "long");
+ success &= testType(long.class, TypeClass.HYPER, "hyper");
+ success &= testType(float.class, TypeClass.FLOAT, "float");
+ success &= testType(double.class, TypeClass.DOUBLE, "double");
+ success &= testType(char.class, TypeClass.CHAR, "char");
+ success &= testType(String.class, TypeClass.STRING, "string");
+ success &= testType(Type.class, TypeClass.TYPE, "type");
+ success &= testType(Any.class, TypeClass.ANY, "any");
+ success &= testType(boolean[].class, TypeClass.SEQUENCE, "[]boolean");
+ success &= testType(byte[].class, TypeClass.SEQUENCE, "[]byte");
+ success &= testType(short[].class, TypeClass.SEQUENCE, "[]short");
+ success &= testType(int[].class, TypeClass.SEQUENCE, "[]long");
+ success &= testType(long[].class, TypeClass.SEQUENCE, "[]hyper");
+ success &= testType(float[].class, TypeClass.SEQUENCE, "[]float");
+ success &= testType(double[].class, TypeClass.SEQUENCE, "[]double");
+ success &= testType(char[].class, TypeClass.SEQUENCE, "[]char");
+ success &= testType(String[].class, TypeClass.SEQUENCE, "[]string");
+ success &= testType(Type[].class, TypeClass.SEQUENCE, "[]type");
+ success &= testType(Any[].class, TypeClass.SEQUENCE, "[]any");
+ success &= testType(Enum1[].class, TypeClass.SEQUENCE,
+ "[]" + Enum1.class.getName());
+ success &= testType(BaseStruct[].class, TypeClass.SEQUENCE,
+ "[]" + BaseStruct.class.getName());
+ success &= testType(DerivedStruct[].class, TypeClass.SEQUENCE,
+ "[]" + DerivedStruct.class.getName());
+ success &= testType(XInterface[].class, TypeClass.SEQUENCE,
+ "[]" + XInterface.class.getName());
+ success &= testType(BaseInterface[].class, TypeClass.SEQUENCE,
+ "[]" + BaseInterface.class.getName());
+ success &= testType(DerivedInterface[].class, TypeClass.SEQUENCE,
+ "[]" + DerivedInterface.class.getName());
+ success &= testType(boolean[][].class, TypeClass.SEQUENCE,
+ "[][]boolean");
+ success &= testType(byte[][].class, TypeClass.SEQUENCE, "[][]byte");
+ success &= testType(short[][].class, TypeClass.SEQUENCE, "[][]short");
+ success &= testType(int[][].class, TypeClass.SEQUENCE, "[][]long");
+ success &= testType(long[][].class, TypeClass.SEQUENCE, "[][]hyper");
+ success &= testType(float[][].class, TypeClass.SEQUENCE, "[][]float");
+ success &= testType(double[][].class, TypeClass.SEQUENCE, "[][]double");
+ success &= testType(char[][].class, TypeClass.SEQUENCE, "[][]char");
+ success &= testType(String[][].class, TypeClass.SEQUENCE, "[][]string");
+ success &= testType(Type[][].class, TypeClass.SEQUENCE, "[][]type");
+ success &= testType(Any[][].class, TypeClass.SEQUENCE, "[][]any");
+ success &= testType(Enum1[][].class, TypeClass.SEQUENCE,
+ "[][]" + Enum1.class.getName());
+ success &= testType(BaseStruct[][].class, TypeClass.SEQUENCE,
+ "[][]" + BaseStruct.class.getName());
+ success &= testType(DerivedStruct[][].class, TypeClass.SEQUENCE,
+ "[][]" + DerivedStruct.class.getName());
+ success &= testType(XInterface[][].class, TypeClass.SEQUENCE,
+ "[][]" + XInterface.class.getName());
+ success &= testType(BaseInterface[][].class, TypeClass.SEQUENCE,
+ "[][]" + BaseInterface.class.getName());
+ success &= testType(DerivedInterface[][].class, TypeClass.SEQUENCE,
+ "[][]" + DerivedInterface.class.getName());
+ success &= testType(Enum1.class, TypeClass.ENUM, Enum1.class.getName());
+ success &= testType(BaseStruct.class, TypeClass.STRUCT,
+ BaseStruct.class.getName());
+ success &= testType(DerivedStruct.class, TypeClass.STRUCT,
+ DerivedStruct.class.getName());
+ success &= testType(com.sun.star.uno.Exception.class,
+ TypeClass.EXCEPTION,
+ com.sun.star.uno.Exception.class.getName());
+ success &= testType(com.sun.star.uno.RuntimeException.class,
+ TypeClass.EXCEPTION,
+ com.sun.star.uno.RuntimeException.class.getName());
+ success &= testType(XInterface.class, TypeClass.INTERFACE,
+ XInterface.class.getName());
+ success &= testType(BaseInterface.class, TypeClass.INTERFACE,
+ BaseInterface.class.getName());
+ success &= testType(DerivedInterface.class, TypeClass.INTERFACE,
+ DerivedInterface.class.getName());
+
+ // VOID:
+ success &= testMapAny(transport, Any.VOID, new CompareBoxed());
+
+ // BOOLEAN:
+ success &= testMapAny(transport, Boolean.FALSE, new CompareBoxed());
+ success &= testMapAny(transport, Boolean.TRUE, new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(Type.BOOLEAN, Boolean.FALSE),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.BOOLEAN, Boolean.TRUE),
+ new CompareUnboxed());
+
+ // BYTE:
+ success &= testMapAny(transport, new Byte((byte) -128),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Byte((byte) 0),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Byte((byte) 127),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(Type.BYTE, new Byte((byte) -128)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.BYTE, new Byte((byte) 0)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.BYTE, new Byte((byte) 127)),
+ new CompareUnboxed());
+
+ // SHORT:
+ success &= testMapAny(transport, new Short((short) -32768),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Short((short) 0),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Short((short) 32767),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(Type.SHORT,
+ new Short((short) -32768)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.SHORT, new Short((short) 0)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.SHORT, new Short((short) 32767)),
+ new CompareUnboxed());
+
+ // UNSIGNED SHORT:
+ success &= testMapAny(transport,
+ new Any(Type.UNSIGNED_SHORT,
+ new Short((short) 0)),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(Type.UNSIGNED_SHORT,
+ new Short((short) -32768)),
+ new CompareBoxed());
+
+ // LONG:
+ success &= testMapAny(transport, new Integer(-2147483648),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Integer(0),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Integer(2147483647),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(Type.LONG, new Integer(-2147483648)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.LONG, new Integer(0)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.LONG, new Integer(2147483647)),
+ new CompareUnboxed());
+
+ // UNSIGNED LONG:
+ success &= testMapAny(transport,
+ new Any(Type.UNSIGNED_LONG, new Integer(0)),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(Type.UNSIGNED_LONG,
+ new Integer(-2147483648)),
+ new CompareBoxed());
+
+ // HYPER:
+ success &= testMapAny(transport, new Long(-9223372036854775808L),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Long(0L), new CompareBoxed());
+ success &= testMapAny(transport, new Long(9223372036854775807L),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(Type.HYPER,
+ new Long(-9223372036854775808L)),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new Any(Type.HYPER, new Long(0L)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.HYPER,
+ new Long(9223372036854775807L)),
+ new CompareUnboxed());
+
+ // UNSIGNED HYPER:
+ success &= testMapAny(transport,
+ new Any(Type.UNSIGNED_HYPER, new Long(0L)),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(Type.UNSIGNED_HYPER,
+ new Long(-9223372036854775808L)),
+ new CompareBoxed());
+
+ // FLOAT:
+ success &= testMapAny(transport, new Float(Float.NEGATIVE_INFINITY),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Float(Float.MIN_VALUE),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Float(-0.0f),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Float(0.0f),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Float(Float.MAX_VALUE),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Float(Float.POSITIVE_INFINITY),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Float(Float.NaN),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(Type.FLOAT,
+ new Float(Float.NEGATIVE_INFINITY)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.FLOAT,
+ new Float(Float.MIN_VALUE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.FLOAT, new Float(-0.0f)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.FLOAT, new Float(0.0f)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.FLOAT,
+ new Float(Float.MAX_VALUE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.FLOAT,
+ new Float(Float.POSITIVE_INFINITY)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.FLOAT, new Float(Float.NaN)),
+ new CompareUnboxed());
+
+ // DOUBLE:
+ success &= testMapAny(transport,
+ new Double(Double.NEGATIVE_INFINITY),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Double(Double.MIN_VALUE),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Double(-0.0f),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Double(0.0f),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Double(Double.MAX_VALUE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Double(Double.POSITIVE_INFINITY),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Double(Double.NaN),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(Type.DOUBLE,
+ new Double(Double.NEGATIVE_INFINITY)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.DOUBLE,
+ new Double(Double.MIN_VALUE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.DOUBLE, new Double(-0.0)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.DOUBLE, new Double(0.0)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.DOUBLE,
+ new Double(Double.MAX_VALUE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.DOUBLE,
+ new Double(Double.POSITIVE_INFINITY)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.DOUBLE, new Double(Double.NaN)),
+ new CompareUnboxed());
+
+ // CHAR:
+ success &= testMapAny(transport, new Character('\u0000'),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Character('\uDBFF'),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Character('\uFFFD'),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(Type.CHAR, new Character('\u0000')),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.CHAR, new Character('\uDBFF')),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.CHAR, new Character('\uFFFD')),
+ new CompareUnboxed());
+
+ // STRING:
+ success &= testMapAny(transport, "", new CompareBoxed());
+ success &= testMapAny(transport, "\uD800\uDC00",
+ new CompareBoxed());
+ success &= testMapAny(transport, "Test", new CompareBoxed());
+ success &= testMapAny(transport, new Any(Type.STRING, ""),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.STRING, "\uD800\uDC00"),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new Any(Type.STRING, "Test"),
+ new CompareUnboxed());
+
+ // TYPE:
+ success &= testMapAny(transport, Type.VOID, new CompareBoxed());
+ success &= testMapAny(transport, Type.BOOLEAN, new CompareBoxed());
+ success &= testMapAny(transport, Type.BYTE, new CompareBoxed());
+ success &= testMapAny(transport, Type.SHORT, new CompareBoxed());
+ success &= testMapAny(transport, Type.UNSIGNED_SHORT,
+ new CompareBoxed());
+ success &= testMapAny(transport, Type.LONG, new CompareBoxed());
+ success &= testMapAny(transport, Type.UNSIGNED_LONG,
+ new CompareBoxed());
+ success &= testMapAny(transport, Type.HYPER, new CompareBoxed());
+ success &= testMapAny(transport, Type.UNSIGNED_HYPER,
+ new CompareBoxed());
+ success &= testMapAny(transport, Type.FLOAT, new CompareBoxed());
+ success &= testMapAny(transport, Type.DOUBLE, new CompareBoxed());
+ success &= testMapAny(transport, Type.CHAR, new CompareBoxed());
+ success &= testMapAny(transport, Type.STRING, new CompareBoxed());
+ success &= testMapAny(transport, Type.TYPE, new CompareBoxed());
+ success &= testMapAny(transport, Type.ANY, new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[]boolean", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[]byte", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[]short", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[]unsigned short",
+ TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[]long", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[]unsigned long",
+ TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[]hyper", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[]unsigned hyper",
+ TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[]float", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[]double", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[]char", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[]string", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[]type", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[]any", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ if (createTypes) {
+ success &= testMapAny(transport,
+ new Type("[]" + Enum1.class.getName(),
+ TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[]" + BaseStruct.class.getName(),
+ TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[]" + DerivedStruct.class.getName(),
+ TypeClass.SEQUENCE),
+ new CompareBoxed());
+ }
+ success &= testMapAny(transport,
+ new Type("[]" + XInterface.class.getName(),
+ TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[]" + BaseInterface.class.getName(),
+ TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[]"
+ + DerivedInterface.class.getName(),
+ TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[][]boolean", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[][]byte", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[][]short", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[][]unsigned short",
+ TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[][]long", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[][]unsigned long",
+ TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[][]hyper", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[][]unsigned hyper",
+ TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[][]float", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[][]double", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[][]char", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[][]string", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[][]type", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[][]any", TypeClass.SEQUENCE),
+ new CompareBoxed());
+ if (createTypes) {
+ success &= testMapAny(transport,
+ new Type("[][]" + Enum1.class.getName(),
+ TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[][]" + BaseStruct.class.getName(),
+ TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[][]"
+ + DerivedStruct.class.getName(),
+ TypeClass.SEQUENCE),
+ new CompareBoxed());
+ }
+ success &= testMapAny(transport,
+ new Type("[][]" + XInterface.class.getName(),
+ TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[][]"
+ + BaseInterface.class.getName(),
+ TypeClass.SEQUENCE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type("[][]"
+ + DerivedInterface.class.getName(),
+ TypeClass.SEQUENCE),
+ new CompareBoxed());
+ if (createTypes) {
+ success &= testMapAny(transport, new Type(Enum1.class.getName(),
+ TypeClass.ENUM),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type(BaseStruct.class.getName(),
+ TypeClass.STRUCT),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type(DerivedStruct.class.getName(),
+ TypeClass.STRUCT),
+ new CompareBoxed());
+ }
+ success &= testMapAny(transport,
+ new Type(
+ com.sun.star.uno.Exception.class.
+ getName(),
+ TypeClass.EXCEPTION),
+ new CompareBoxed());
+ if (createTypes) {
+ success &= testMapAny(transport,
+ new Type(BaseException.class.getName(),
+ TypeClass.EXCEPTION),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type(DerivedException.class.getName(),
+ TypeClass.EXCEPTION),
+ new CompareBoxed());
+ }
+ success &= testMapAny(transport,
+ new Type(
+ com.sun.star.uno.RuntimeException.class.
+ getName(),
+ TypeClass.EXCEPTION),
+ new CompareBoxed());
+ if (createTypes) {
+ success &= testMapAny(transport,
+ new Type(
+ BaseRuntimeException.class.getName(),
+ TypeClass.EXCEPTION),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type(
+ DerivedRuntimeException.class.
+ getName(),
+ TypeClass.EXCEPTION),
+ new CompareBoxed());
+ }
+ success &= testMapAny(transport,
+ new Type(XInterface.class.getName(),
+ TypeClass.INTERFACE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type(BaseInterface.class.getName(),
+ TypeClass.INTERFACE),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type(DerivedInterface.class.getName(),
+ TypeClass.INTERFACE),
+ new CompareBoxed());
+ success &= testMapAny(transport, new Any(Type.TYPE, Type.VOID),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new Any(Type.TYPE, Type.BOOLEAN),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new Any(Type.TYPE, Type.BYTE),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new Any(Type.TYPE, Type.SHORT),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE, Type.UNSIGNED_SHORT),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new Any(Type.TYPE, Type.LONG),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE, Type.UNSIGNED_LONG),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new Any(Type.TYPE, Type.HYPER),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE, Type.UNSIGNED_HYPER),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new Any(Type.TYPE, Type.FLOAT),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new Any(Type.TYPE, Type.DOUBLE),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new Any(Type.TYPE, Type.CHAR),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new Any(Type.TYPE, Type.STRING),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new Any(Type.TYPE, Type.TYPE),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new Any(Type.TYPE, Type.ANY),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[]boolean",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[]byte",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[]short",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[]unsigned short",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[]long",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[]unsigned long",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[]hyper",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[]unsigned hyper",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[]float",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[]double",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[]char",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[]string",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[]type",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[]any",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ if (createTypes) {
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[]" + Enum1.class.getName(),
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[]"
+ + BaseStruct.class.getName(),
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type(
+ "[]"
+ + DerivedStruct.class.getName(),
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ }
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[]"
+ + XInterface.class.getName(),
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type(
+ "[]"
+ + BaseInterface.class.getName(),
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(
+ Type.TYPE,
+ new Type(
+ "[]"
+ + DerivedInterface.class.getName(),
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[][]boolean",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[][]byte",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[][]short",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[][]unsigned short",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[][]long",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[][]unsigned long",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[][]hyper",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[][]unsigned hyper",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[][]float",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[][]double",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[][]char",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[][]string",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[][]type",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[][]any",
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ if (createTypes) {
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[][]"
+ + Enum1.class.getName(),
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[][]"
+ + BaseStruct.class.getName(),
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type(
+ "[][]"
+ + DerivedStruct.class.getName(),
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ }
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type("[][]"
+ + XInterface.class.getName(),
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type(
+ "[][]"
+ + BaseInterface.class.getName(),
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(
+ Type.TYPE,
+ new Type(
+ "[][]"
+ + DerivedInterface.class.getName(),
+ TypeClass.SEQUENCE)),
+ new CompareUnboxed());
+ if (createTypes) {
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type(Enum1.class.getName(),
+ TypeClass.ENUM)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type(BaseStruct.class.getName(),
+ TypeClass.STRUCT)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type(
+ DerivedStruct.class.getName(),
+ TypeClass.STRUCT)),
+ new CompareUnboxed());
+ }
+ success &= testMapAny(transport,
+ new Any(
+ Type.TYPE,
+ new Type(
+ com.sun.star.uno.Exception.class.
+ getName(),
+ TypeClass.EXCEPTION)),
+ new CompareUnboxed());
+ if (createTypes) {
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type(
+ BaseException.class.getName(),
+ TypeClass.EXCEPTION)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(
+ Type.TYPE,
+ new Type(
+ DerivedException.class.getName(),
+ TypeClass.EXCEPTION)),
+ new CompareUnboxed());
+ }
+ success &= testMapAny(transport,
+ new Any(
+ Type.TYPE,
+ new Type(
+ com.sun.star.uno.RuntimeException.
+ class.getName(),
+ TypeClass.EXCEPTION)),
+ new CompareUnboxed());
+ if (createTypes) {
+ success &= testMapAny(transport,
+ new Any(
+ Type.TYPE,
+ new Type(
+ BaseRuntimeException.class.
+ getName(),
+ TypeClass.EXCEPTION)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(
+ Type.TYPE,
+ new Type(
+ DerivedRuntimeException.class.
+ getName(),
+ TypeClass.EXCEPTION)),
+ new CompareUnboxed());
+ }
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type(XInterface.class.getName(),
+ TypeClass.INTERFACE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type(
+ BaseInterface.class.getName(),
+ TypeClass.INTERFACE)),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(Type.TYPE,
+ new Type(
+ DerivedInterface.class.getName(),
+ TypeClass.INTERFACE)),
+ new CompareUnboxed());
+
+ // Sequence Types:
+ success &= testMapAny(transport, new boolean[] {},
+ new CompareBoxed());
+ success &= testMapAny(transport, new boolean[] { false, true },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(boolean[].class),
+ new boolean[] {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(boolean[].class),
+ new boolean[] { false, true }),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new byte[] {},
+ new CompareBoxed());
+ success &= testMapAny(transport, new byte[] { -128, 0, 127 },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(byte[].class),
+ new byte[] {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(byte[].class),
+ new byte[] { -128, 0, 127 }),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new short[] {},
+ new CompareBoxed());
+ success &= testMapAny(transport, new short[] { -32768, 0, 32767 },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(short[].class),
+ new short[] {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(short[].class),
+ new short[] { -32768, 0, 32767 }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type("[]unsigned short",
+ TypeClass.SEQUENCE),
+ new short[] {}),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type("[]unsigned short",
+ TypeClass.SEQUENCE),
+ new short[] { 0, -32768 }),
+ new CompareBoxed());
+ success &= testMapAny(transport, new int[] {},
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new int[] { -2147483648, 0, 2147483647 },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(int[].class),
+ new int[] {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(int[].class),
+ new int[] { -2147483648, 0,
+ 2147483647 }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type("[]unsigned long",
+ TypeClass.SEQUENCE),
+ new int[] {}),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type("[]unsigned long",
+ TypeClass.SEQUENCE),
+ new int[] { 0, -2147483648 }),
+ new CompareBoxed());
+ success &= testMapAny(transport, new long[] {},
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new long[] { -9223372036854775808L, 0L,
+ 9223372036854775807L },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(long[].class),
+ new long[] {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(long[].class),
+ new long[] { -9223372036854775808L,
+ 0L,
+ 9223372036854775807L }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type("[]unsigned hyper",
+ TypeClass.SEQUENCE),
+ new long[] {}),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type("[]unsigned hyper",
+ TypeClass.SEQUENCE),
+ new long[] { 0L,
+ -9223372036854775808L }),
+ new CompareBoxed());
+ success &= testMapAny(transport, new float[] {},
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new float[] { Float.NEGATIVE_INFINITY,
+ Float.MIN_VALUE, -0.0f, 0.0f,
+ Float.MAX_VALUE,
+ Float.POSITIVE_INFINITY,
+ Float.NaN },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(float[].class),
+ new float[] {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(float[].class),
+ new float[] { Float.NEGATIVE_INFINITY,
+ Float.MIN_VALUE, -0.0f,
+ 0.0f, Float.MAX_VALUE,
+ Float.POSITIVE_INFINITY,
+ Float.NaN }),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new double[] {},
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new double[] { Double.NEGATIVE_INFINITY,
+ Double.MIN_VALUE, -0.0, 0.0,
+ Double.MAX_VALUE,
+ Double.POSITIVE_INFINITY,
+ Double.NaN },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(double[].class),
+ new double[] {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(double[].class),
+ new double[] {
+ Double.NEGATIVE_INFINITY,
+ Double.MIN_VALUE, -0.0, 0.0,
+ Double.MAX_VALUE,
+ Double.POSITIVE_INFINITY,
+ Double.NaN }),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new char[] {},
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new char[] { '\u0000', '\uDBFF', '\uFFFD' },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(char[].class),
+ new char[] {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(
+ new Type(char[].class),
+ new char[] { '\u0000', '\uDBFF',
+ '\uFFFD' }),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new String[] {},
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new String[] { "", "\uD800\uDC00", "Test" },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(String[].class),
+ new String[] {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(String[].class),
+ new String[] { "", "\uD800\uDC00",
+ "Test" }),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new Type[] {}, new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type[] {
+ Type.VOID,
+ new Type(DerivedInterface.class.getName(),
+ TypeClass.INTERFACE) },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(Type[].class),
+ new Type[] {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(
+ new Type(Type[].class),
+ new Type[] {
+ Type.VOID,
+ new Type(
+ DerivedInterface.class.getName(),
+ TypeClass.INTERFACE) }),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new Object[] {},
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Object[] { Any.VOID, Boolean.FALSE },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Object[] {
+ Boolean.FALSE,
+ new Any(Type.BOOLEAN, Boolean.TRUE) },
+ new CompareBoxed(true));
+ success &= testMapAny(transport,
+ new Any(new Type(Any[].class),
+ new Object[] {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(Any[].class),
+ new Object[] { Any.VOID,
+ Boolean.FALSE }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(Any[].class),
+ new Object[] {
+ Boolean.FALSE,
+ new Any(Type.BOOLEAN,
+ Boolean.TRUE) }),
+ new CompareUnboxed(true));
+ success &= testMapAny(transport, new Any[] {},
+ new CompareSpecific(new Object[] {}));
+ success &= testMapAny(transport,
+ new Any[] { Any.VOID,
+ new Any(Type.BOOLEAN,
+ Boolean.TRUE) },
+ new CompareSpecific(
+ new Object[] { Any.VOID, Boolean.TRUE }));
+ success &= testMapAny(transport,
+ new Any(new Type(Any[].class), new Any[] {}),
+ new CompareSpecific(new Object[] {}));
+ success &= testMapAny(transport,
+ new Any(new Type(Any[].class),
+ new Any[] { Any.VOID,
+ new Any(Type.BOOLEAN,
+ Boolean.TRUE) }),
+ new CompareSpecific(
+ new Object[] { Any.VOID, Boolean.TRUE }));
+ success &= testMapAny(transport,
+ new Any(new Type(Any[].class),
+ new Boolean[] {}),
+ new CompareSpecific(new Object[] {}));
+ success &= testMapAny(transport,
+ new Any(new Type(Any[].class),
+ new Boolean[] { Boolean.FALSE }),
+ new CompareSpecific(
+ new Object[] { Boolean.FALSE }));
+ if (createTypes) {
+ success &= testMapAny(transport, new Enum1[] {},
+ new CompareBoxed());
+ success &= testMapAny(transport, new Enum1[] { new Enum1(),
+ new Enum2() },
+ new CompareSpecific(
+ new Enum1[] { new Enum1(),
+ new Enum1() }));
+ success &= testMapAny(transport,
+ new Any(new Type(Enum1[].class),
+ new Enum1[] {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(Enum1[].class),
+ new Enum1[] { new Enum1(),
+ new Enum2() }),
+ new CompareSpecific(
+ new Enum1[] { new Enum1(),
+ new Enum1() }));
+ success &= testMapAny(transport,
+ new Any(new Type(Enum1[].class),
+ new Enum2[] {}),
+ new CompareSpecific(new Enum1[] {}));
+ success &= testMapAny(transport,
+ new Any(new Type(Enum1[].class),
+ new Enum2[] { new Enum2() }),
+ new CompareSpecific(
+ new Enum1[] { new Enum1() }));
+ success &= testMapAny(transport, new BaseStruct[] {},
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new BaseStruct[] { new BaseStruct(),
+ new DerivedStruct() },
+ new CompareSpecific(
+ new BaseStruct[] { new BaseStruct(),
+ new BaseStruct() }));
+ success &= testMapAny(transport,
+ new Any(new Type(BaseStruct[].class),
+ new BaseStruct[] {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(BaseStruct[].class),
+ new BaseStruct[] {
+ new BaseStruct(),
+ new DerivedStruct() }),
+ new CompareSpecific(
+ new BaseStruct[] { new BaseStruct(),
+ new BaseStruct() }));
+ success &= testMapAny(transport,
+ new Any(new Type(BaseStruct[].class),
+ new DerivedStruct[] {}),
+ new CompareSpecific(new BaseStruct[] {}));
+ success &= testMapAny(transport,
+ new Any(new Type(BaseStruct[].class),
+ new DerivedStruct[] {
+ new DerivedStruct() }),
+ new CompareSpecific(
+ new BaseStruct[] { new BaseStruct() }));
+ success &= testMapAny(transport, new DerivedStruct[] {},
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new DerivedStruct[] { new DerivedStruct() },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(DerivedStruct[].class),
+ new DerivedStruct[] {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(DerivedStruct[].class),
+ new DerivedStruct[] {
+ new DerivedStruct() }),
+ new CompareUnboxed());
+ }
+ success &= testMapAny(transport, new XInterface[] {},
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new XInterface[] {
+ null, new XInterface() {},
+ new BaseInterface() {},
+ new DerivedInterface() {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface[].class),
+ new XInterface[] {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface[].class),
+ new XInterface[] {
+ null, new XInterface() {},
+ new BaseInterface() {},
+ new DerivedInterface() {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface[].class),
+ new Object[] {}),
+ new CompareSpecific(new XInterface[] {}));
+ {
+ XInterface if1 = new XInterface() {};
+ XInterface if2 = new BaseInterface() {};
+ XInterface if3 = new DerivedInterface() {};
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface[].class),
+ new Object[] { null, if1, if2,
+ if3 }),
+ new CompareSpecific(
+ new XInterface[] { null, if1, if2,
+ if3 }));
+ }
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface[].class),
+ new BaseInterface[] {}),
+ new CompareSpecific(new XInterface[] {}));
+ {
+ BaseInterface if1 = new BaseInterface() {};
+ BaseInterface if2 = new DerivedInterface() {};
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface[].class),
+ new BaseInterface[] { null, if1,
+ if2 }),
+ new CompareSpecific(
+ new XInterface[] { null, if1, if2 }));
+ }
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface[].class),
+ new DerivedInterface[] {}),
+ new CompareSpecific(new XInterface[] {}));
+ {
+ DerivedInterface if1 = new DerivedInterface() {};
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface[].class),
+ new DerivedInterface[] { null,
+ if1 }),
+ new CompareSpecific(
+ new XInterface[] { null, if1 }));
+ }
+ success &= testMapAny(transport, new BaseInterface[] {},
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new BaseInterface[] {
+ null, new BaseInterface() {},
+ new DerivedInterface() {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(BaseInterface[].class),
+ new BaseInterface[] {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(BaseInterface[].class),
+ new BaseInterface[] {
+ null, new BaseInterface() {},
+ new DerivedInterface() {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(BaseInterface[].class),
+ new DerivedInterface[] {}),
+ new CompareSpecific(new BaseInterface[] {}));
+ {
+ DerivedInterface if1 = new DerivedInterface() {};
+ success &= testMapAny(transport,
+ new Any(new Type(BaseInterface[].class),
+ new DerivedInterface[] { null,
+ if1 }),
+ new CompareSpecific(
+ new BaseInterface[] { null, if1 }));
+ }
+ success &= testMapAny(transport, new DerivedInterface[] {},
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new DerivedInterface[] {
+ null, new DerivedInterface() {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(DerivedInterface[].class),
+ new DerivedInterface[] {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(DerivedInterface[].class),
+ new DerivedInterface[] {
+ null,
+ new DerivedInterface() {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new boolean[][] { new boolean[] {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new boolean[][] {
+ new boolean[] { false, true } },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(boolean[][].class),
+ new boolean[][] { new boolean[] {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(boolean[][].class),
+ new boolean[][] {
+ new boolean[] { false, true } }),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new byte[][] { new byte[] {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new byte[][] { new byte[] { -128, 0, 127 } },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(byte[][].class),
+ new byte[][] { new byte[] {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(byte[][].class),
+ new byte[][] {
+ new byte[] { -128, 0, 127 } }),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new short[][] { new short[] {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new short[][] {
+ new short[] { -32768, 0, 32767 } },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(short[][].class),
+ new short[][] { new short[] {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(short[][].class),
+ new short[][] {
+ new short[] { -32768, 0,
+ 32767 } }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type("[][]unsigned short",
+ TypeClass.SEQUENCE),
+ new short[][] { new short[] {} }),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type("[][]unsigned short",
+ TypeClass.SEQUENCE),
+ new short[][] {
+ new short[] { 0, -32768 } }),
+ new CompareBoxed());
+ success &= testMapAny(transport, new int[][] { new int[] {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new int[][] { new int[] { -2147483648, 0,
+ 2147483647 } },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(int[][].class),
+ new int[][] { new int[] {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(int[][].class),
+ new int[][] {
+ new int[] { -2147483648, 0,
+ 2147483647 } }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type("[][]unsigned long",
+ TypeClass.SEQUENCE),
+ new int[][] { new int[] {} }),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type("[][]unsigned long",
+ TypeClass.SEQUENCE),
+ new int[][] {
+ new int[] { 0, -2147483648 } }),
+ new CompareBoxed());
+ success &= testMapAny(transport, new long[][] { new long[] {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new long[][] {
+ new long[] { -9223372036854775808L, 0L,
+ 9223372036854775807L } },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(long[][].class),
+ new long[][] { new long[] {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(long[][].class),
+ new long[][] {
+ new long[] {
+ -9223372036854775808L, 0L,
+ 9223372036854775807L } }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type("[][]unsigned hyper",
+ TypeClass.SEQUENCE),
+ new long[][] { new long[] {} }),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type("[][]unsigned hyper",
+ TypeClass.SEQUENCE),
+ new long[][] {
+ new long[] {
+ 0L,
+ -9223372036854775808L } }),
+ new CompareBoxed());
+ success &= testMapAny(transport, new float[][] { new float[] {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new float[][] {
+ new float[] { Float.NEGATIVE_INFINITY,
+ Float.MIN_VALUE, -0.0f,
+ 0.0f, Float.MAX_VALUE,
+ Float.POSITIVE_INFINITY,
+ Float.NaN } },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(float[][].class),
+ new float[][] { new float[] {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(float[][].class),
+ new float[][] {
+ new float[] {
+ Float.NEGATIVE_INFINITY,
+ Float.MIN_VALUE, -0.0f, 0.0f,
+ Float.MAX_VALUE,
+ Float.POSITIVE_INFINITY,
+ Float.NaN } }),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new double[][] { new double[] {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new double[][] {
+ new double[] { Double.NEGATIVE_INFINITY,
+ Double.MIN_VALUE, -0.0,
+ 0.0, Double.MAX_VALUE,
+ Double.POSITIVE_INFINITY,
+ Double.NaN } },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(double[][].class),
+ new double[][] { new double[] {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(double[][].class),
+ new double[][] {
+ new double[] {
+ Double.NEGATIVE_INFINITY,
+ Double.MIN_VALUE, -0.0, 0.0,
+ Double.MAX_VALUE,
+ Double.POSITIVE_INFINITY,
+ Double.NaN } }),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new char[][] { new char[] {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new char[][] {
+ new char[] { '\u0000', '\uDBFF',
+ '\uFFFD' } },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(char[][].class),
+ new char[][] { new char[] {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(
+ new Type(char[][].class),
+ new char[][] {
+ new char[] { '\u0000', '\uDBFF',
+ '\uFFFD' } }),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new String[][] { new String[] {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new String[][] {
+ new String[] { "", "\uD800\uDC00",
+ "Test" } },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(String[][].class),
+ new String[][] { new String[] {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(String[][].class),
+ new String[][] {
+ new String[] { "", "\uD800\uDC00",
+ "Test" } }),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new Type[][] { new Type[] {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Type[][] {
+ new Type[] {
+ Type.VOID,
+ new Type(
+ DerivedInterface.class.getName(),
+ TypeClass.INTERFACE) } },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(Type[][].class),
+ new Type[][] { new Type[] {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(
+ new Type(Type[][].class),
+ new Type[][] {
+ new Type[] {
+ Type.VOID,
+ new Type(
+ DerivedInterface.class.
+ getName(),
+ TypeClass.INTERFACE) } }),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new Object[][] { new Object[] {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Object[][] {
+ new Object[] { Any.VOID,
+ Boolean.FALSE } },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Object[][] {
+ new Object[] {
+ Boolean.FALSE,
+ new Any(Type.BOOLEAN,
+ Boolean.TRUE) } },
+ new CompareBoxed(true));
+ success &= testMapAny(transport,
+ new Any(new Type(Any[][].class),
+ new Object[][] { new Object[] {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(Any[][].class),
+ new Object[][] {
+ new Object[] { Any.VOID,
+ Boolean.FALSE } }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(Any[][].class),
+ new Object[][] {
+ new Object[] {
+ Boolean.FALSE,
+ new Any(Type.BOOLEAN,
+ Boolean.TRUE) } }),
+ new CompareUnboxed(true));
+ success &= testMapAny(transport, new Any[][] { new Any[] {} },
+ new CompareSpecific(
+ new Object[][] { new Object[] {} }));
+ success &= testMapAny(transport,
+ new Any[][] {
+ new Any[] { Any.VOID,
+ new Any(Type.BOOLEAN,
+ Boolean.TRUE) } },
+ new CompareSpecific(
+ new Object[][] {
+ new Object[] { Any.VOID,
+ Boolean.TRUE } }));
+ success &= testMapAny(transport,
+ new Any(new Type(Any[][].class),
+ new Any[][] { new Any[] {} }),
+ new CompareSpecific(
+ new Object[][] { new Object[] {} }));
+ success &= testMapAny(transport,
+ new Any(new Type(Any[][].class),
+ new Any[][] {
+ new Any[] {
+ Any.VOID,
+ new Any(Type.BOOLEAN,
+ Boolean.TRUE) } }),
+ new CompareSpecific(
+ new Object[][] {
+ new Object[] { Any.VOID,
+ Boolean.TRUE } }));
+ success &= testMapAny(transport,
+ new Any(new Type(Any[][].class),
+ new Boolean[][] { new Boolean[] {} }),
+ new CompareSpecific(
+ new Object[][] { new Object[] {} }));
+ success &= testMapAny(transport,
+ new Any(new Type(Any[][].class),
+ new Boolean[][] {
+ new Boolean[] {
+ Boolean.FALSE } }),
+ new CompareSpecific(
+ new Object[][] {
+ new Object[] { Boolean.FALSE } }));
+ if (createTypes) {
+ success &= testMapAny(transport, new Enum1[][] { new Enum1[] {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Enum1[][] {
+ new Enum1[] { new Enum1(),
+ new Enum2() } },
+ new CompareSpecific(
+ new Enum1[][] {
+ new Enum1[] { new Enum1(),
+ new Enum1() } }));
+ success &= testMapAny(transport,
+ new Any(new Type(Enum1[][].class),
+ new Enum1[][] { new Enum1[] {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(Enum1[][].class),
+ new Enum1[][] {
+ new Enum1[] { new Enum1(),
+ new Enum2() } }),
+ new CompareSpecific(
+ new Enum1[][] {
+ new Enum1[] { new Enum1(),
+ new Enum1() } }));
+ success &= testMapAny(transport,
+ new Any(new Type(Enum1[][].class),
+ new Enum2[][] { new Enum2[] {} }),
+ new CompareSpecific(
+ new Enum1[][] { new Enum1[] {} }));
+ success &= testMapAny(transport,
+ new Any(new Type(Enum1[][].class),
+ new Enum2[][] {
+ new Enum2[] { new Enum2() } }),
+ new CompareSpecific(
+ new Enum1[][] {
+ new Enum1[] { new Enum1() } }));
+ success &= testMapAny(transport,
+ new BaseStruct[][] { new BaseStruct[] {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new BaseStruct[][] {
+ new BaseStruct[] {
+ new BaseStruct(),
+ new DerivedStruct() } },
+ new CompareSpecific(
+ new BaseStruct[][] {
+ new BaseStruct[] {
+ new BaseStruct(),
+ new BaseStruct() } }));
+ success &= testMapAny(transport,
+ new Any(new Type(BaseStruct[][].class),
+ new BaseStruct[][] {
+ new BaseStruct[] {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(BaseStruct[][].class),
+ new BaseStruct[][] {
+ new BaseStruct[] {
+ new BaseStruct(),
+ new DerivedStruct() } }),
+ new CompareSpecific(
+ new BaseStruct[][] {
+ new BaseStruct[] {
+ new BaseStruct(),
+ new BaseStruct() } }));
+ success &= testMapAny(transport,
+ new Any(new Type(BaseStruct[][].class),
+ new DerivedStruct[][] {
+ new DerivedStruct[] {} }),
+ new CompareSpecific(
+ new BaseStruct[][] {
+ new BaseStruct[] {} }));
+ success &= testMapAny(transport,
+ new Any(new Type(BaseStruct[][].class),
+ new DerivedStruct[][] {
+ new DerivedStruct[] {
+ new DerivedStruct() } }),
+ new CompareSpecific(
+ new BaseStruct[][] {
+ new BaseStruct[] {
+ new BaseStruct() } }));
+ success &= testMapAny(transport,
+ new DerivedStruct[][] {
+ new DerivedStruct[] {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new DerivedStruct[][] {
+ new DerivedStruct[] {
+ new DerivedStruct() } },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(DerivedStruct[][].class),
+ new DerivedStruct[][] {
+ new DerivedStruct[] {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(DerivedStruct[][].class),
+ new DerivedStruct[][] {
+ new DerivedStruct[] {
+ new DerivedStruct() } }),
+ new CompareUnboxed());
+ }
+ success &= testMapAny(transport,
+ new XInterface[][] { new XInterface[] {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new XInterface[][] {
+ new XInterface[] {
+ null, new XInterface() {},
+ new BaseInterface() {},
+ new DerivedInterface() {} } },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface[][].class),
+ new XInterface[][] {
+ new XInterface[] {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(
+ new Type(XInterface[][].class),
+ new XInterface[][] {
+ new XInterface[] {
+ null, new XInterface() {},
+ new BaseInterface() {},
+ new DerivedInterface() {} } }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface[][].class),
+ new Object[][] { new Object[] {} }),
+ new CompareSpecific(
+ new XInterface[][] {
+ new XInterface[] {} }));
+ {
+ XInterface if1 = new XInterface() {};
+ XInterface if2 = new BaseInterface() {};
+ XInterface if3 = new DerivedInterface() {};
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface[][].class),
+ new Object[][] {
+ new Object[] { null, if1, if2,
+ if3 } }),
+ new CompareSpecific(
+ new XInterface[][] {
+ new XInterface[] { null, if1, if2,
+ if3 } }));
+ }
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface[][].class),
+ new BaseInterface[][] {
+ new BaseInterface[] {} }),
+ new CompareSpecific(
+ new XInterface[][] {
+ new XInterface[] {} }));
+ {
+ BaseInterface if1 = new BaseInterface() {};
+ BaseInterface if2 = new DerivedInterface() {};
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface[][].class),
+ new BaseInterface[][] {
+ new BaseInterface[] {
+ null, if1, if2 } }),
+ new CompareSpecific(
+ new XInterface[][] {
+ new XInterface[] {
+ null, if1, if2 } }));
+ }
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface[][].class),
+ new DerivedInterface[][] {
+ new DerivedInterface[] {} }),
+ new CompareSpecific(
+ new XInterface[][] {
+ new XInterface[] {} }));
+ {
+ DerivedInterface if1 = new DerivedInterface() {};
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface[][].class),
+ new DerivedInterface[][] {
+ new DerivedInterface[] {
+ null, if1 } }),
+ new CompareSpecific(
+ new XInterface[][] {
+ new XInterface[] {
+ null, if1 } }));
+ }
+ success &= testMapAny(transport,
+ new BaseInterface[][] {
+ new BaseInterface[] {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new BaseInterface[][] {
+ new BaseInterface[] {
+ null, new BaseInterface() {},
+ new DerivedInterface() {} } },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(BaseInterface[][].class),
+ new BaseInterface[][] {
+ new BaseInterface[] {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(
+ new Type(BaseInterface[][].class),
+ new BaseInterface[][] {
+ new BaseInterface[] {
+ null, new BaseInterface() {},
+ new DerivedInterface() {} } }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(BaseInterface[][].class),
+ new DerivedInterface[][] {
+ new DerivedInterface[] {} }),
+ new CompareSpecific(
+ new BaseInterface[][] {
+ new BaseInterface[] {} }));
+ {
+ DerivedInterface if1 = new DerivedInterface() {};
+ success &= testMapAny(transport,
+ new Any(new Type(BaseInterface[][].class),
+ new DerivedInterface[][] {
+ new DerivedInterface[] {
+ null, if1 } }),
+ new CompareSpecific(
+ new BaseInterface[][] {
+ new BaseInterface[] {
+ null, if1 } }));
+ }
+ success &= testMapAny(transport,
+ new DerivedInterface[][] {
+ new DerivedInterface[] {} },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new DerivedInterface[][] {
+ new DerivedInterface[] {
+ null, new DerivedInterface() {} } },
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(DerivedInterface[][].class),
+ new DerivedInterface[][] {
+ new DerivedInterface[] {} }),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(
+ new Type(DerivedInterface[][].class),
+ new DerivedInterface[][] {
+ new DerivedInterface[] {
+ null,
+ new DerivedInterface() {} } }),
+ new CompareUnboxed());
+
+ // Enum Types:
+ if (createTypes) {
+ success &= testMapAny(transport, new Enum1(), new CompareBoxed());
+ success &= testMapAny(transport, new Any(new Type(Enum1.class),
+ new Enum1()),
+ new CompareUnboxed());
+ success &= testMapAny(transport, new Any(new Type(Enum1.class),
+ new Enum2()),
+ new CompareSpecific(new Enum1()));
+ }
+
+ // Struct Types:
+ if (createTypes) {
+ success &= testMapAny(transport, new BaseStruct(),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(BaseStruct.class),
+ new BaseStruct()),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(BaseStruct.class),
+ new DerivedStruct()),
+ new CompareSpecific(new BaseStruct()));
+ success &= testMapAny(transport, new DerivedStruct(),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(DerivedStruct.class),
+ new DerivedStruct()),
+ new CompareUnboxed());
+ }
+
+ // Exception Types:
+ success &= testMapAny(transport, new com.sun.star.uno.Exception(),
+ new CompareClass(
+ com.sun.star.uno.Exception.class));
+ success &= testMapAny(transport,
+ new Any(new Type(
+ com.sun.star.uno.Exception.class),
+ new com.sun.star.uno.Exception()),
+ new CompareClass(
+ com.sun.star.uno.Exception.class));
+ success &= testMapAny(transport,
+ new Any(new Type(
+ com.sun.star.uno.Exception.class),
+ new BaseException()),
+ new CompareClass(
+ com.sun.star.uno.Exception.class));
+ success &= testMapAny(transport,
+ new Any(new Type(
+ com.sun.star.uno.Exception.class),
+ new DerivedException()),
+ new CompareClass(
+ com.sun.star.uno.Exception.class));
+ if (createTypes) {
+ success &= testMapAny(transport, new BaseException(),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(BaseException.class),
+ new BaseException()),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(BaseException.class),
+ new DerivedException()),
+ new CompareSpecific(new BaseException()));
+ success &= testMapAny(transport, new DerivedException(),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(DerivedException.class),
+ new DerivedException()),
+ new CompareUnboxed());
+ }
+ success &= testMapAny(transport,
+ new com.sun.star.uno.RuntimeException(),
+ new CompareClass(
+ com.sun.star.uno.RuntimeException.class));
+ success &= testMapAny(transport,
+ new Any(
+ new Type(
+ com.sun.star.uno.RuntimeException.
+ class),
+ new com.sun.star.uno.RuntimeException()),
+ new CompareClass(
+ com.sun.star.uno.RuntimeException.class));
+ success &= testMapAny(transport,
+ new Any(
+ new Type(
+ com.sun.star.uno.RuntimeException.
+ class),
+ new BaseRuntimeException()),
+ new CompareClass(
+ com.sun.star.uno.RuntimeException.class));
+ success &= testMapAny(transport,
+ new Any(
+ new Type(
+ com.sun.star.uno.RuntimeException.
+ class),
+ new DerivedRuntimeException()),
+ new CompareClass(
+ com.sun.star.uno.RuntimeException.class));
+ if (createTypes) {
+ success &= testMapAny(transport, new BaseRuntimeException(),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(
+ BaseRuntimeException.class),
+ new BaseRuntimeException()),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(
+ BaseRuntimeException.class),
+ new DerivedRuntimeException()),
+ new CompareSpecific(
+ new BaseRuntimeException()));
+ success &= testMapAny(transport, new DerivedRuntimeException(),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(
+ DerivedRuntimeException.class),
+ new DerivedRuntimeException()),
+ new CompareUnboxed());
+ }
+
+ // Interface Types:
+ success &= testMapAny(transport, null, new CompareBoxed());
+ success &= testMapAny(transport, new XInterface() {},
+ new CompareBoxed());
+ success &= testMapAny(transport, new BaseInterface() {},
+ new CompareBoxed());
+ success &= testMapAny(transport, new DerivedInterface() {},
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface.class), null),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface.class),
+ new XInterface() {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface.class),
+ new BaseInterface() {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(XInterface.class),
+ new DerivedInterface() {}),
+ new CompareUnboxed());
+ success &= testMapAny(transport,
+ new Any(new Type(BaseInterface.class), null),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(BaseInterface.class),
+ new BaseInterface() {}),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(BaseInterface.class),
+ new DerivedInterface() {}),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(DerivedInterface.class),
+ null),
+ new CompareBoxed());
+ success &= testMapAny(transport,
+ new Any(new Type(DerivedInterface.class),
+ new DerivedInterface() {}),
+ new CompareBoxed());
+
+ // Misc:
+ try {
+ transport.mapAny(new Object());
+ System.out.println("BAD mapAny(Object), no exception");
+ success = false;
+ } catch (StackOverflowError e) {
+ System.out.println("BAD mapAny(Object): " + e);
+ success = false;
+ } catch (RuntimeException e) {}
+
+ return success;
+ }
+
+ private TestAny() {} // do not instantiate
+
+ private static boolean testType(Class zclass, TypeClass tclass,
+ String tname) {
+ Type t1 = new Type(zclass);
+ Type t2 = new Type(tname, tclass);
+ boolean ok = true;
+ if (t1.getTypeClass() != tclass) {
+ ok = false;
+ System.out.println("BAD Type(" + zclass + ").getTypeClass() = "
+ + t1.getTypeClass() + " != " + tclass);
+ }
+ if (!t1.getTypeName().equals(tname)) {
+ ok = false;
+ System.out.println("BAD Type(" + zclass + ").getTypeName() = "
+ + t1.getTypeName() + " != " + tname);
+ }
+ if (!t1.equals(t2)) {
+ ok = false;
+ System.out.println("BAD Type(" + zclass + ") != Type(" + tname
+ + ", " + tclass + ")");
+ }
+ return ok;
+ }
+
+ private static boolean testMapAny(XTransport transport, Object any,
+ Compare compare) {
+ Object any2 = transport.mapAny(any);
+ boolean eq = compare.equal(any, any2);
+ if (!eq) {
+ System.out.println("BAD mapAny(" + any + ") -> " + any2);
+ }
+ return eq;
+ }
+
+ private static abstract class Compare {
+ public abstract boolean equal(Object o1, Object o2);
+ }
+
+ private static final class CompareBoxed extends Compare {
+ public CompareBoxed() {
+ this(false);
+ }
+
+ public CompareBoxed(boolean unboxInner) {
+ this.unboxInner = unboxInner;
+ }
+
+ public boolean equal(Object o1, Object o2) {
+ if (o1 instanceof Any) {
+ return o2 instanceof Any
+ && ((Any) o1).getType().equals(((Any) o2).getType())
+ && equalValues(((Any) o1).getObject(),
+ ((Any) o2).getObject());
+ } else {
+ return equalValues(o1, o2);
+ }
+ }
+
+ private boolean equalValues(Object o1, Object o2) {
+ if (o1 == null) {
+ return o2 == null;
+ } else if (o1.getClass().isArray()) {
+ if (!(o2 != null && o1.getClass() == o2.getClass()
+ && Array.getLength(o1) == Array.getLength(o2))) {
+ return false;
+ }
+ for (int i = 0; i < Array.getLength(o1); ++i) {
+ Object oo1 = Array.get(o1, i);
+ if (unboxInner && oo1 instanceof Any) {
+ oo1 = ((Any) oo1).getObject();
+ }
+ if (!equal(oo1, Array.get(o2, i))) {
+ return false;
+ }
+ }
+ return true;
+ } else {
+ return o1.equals(o2);
+ }
+ }
+
+ private final boolean unboxInner;
+ }
+
+ private static final class CompareUnboxed extends Compare {
+ public CompareUnboxed() {
+ this(false);
+ }
+
+ public CompareUnboxed(boolean unboxInner) {
+ this.unboxInner = unboxInner;
+ }
+
+ public boolean equal(Object o1, Object o2) {
+ return new CompareBoxed(unboxInner).equal(((Any) o1).getObject(),
+ o2);
+ }
+
+ private final boolean unboxInner;
+ }
+
+ private static final class CompareSpecific extends Compare {
+ public CompareSpecific(Object specific) {
+ this.specific = specific;
+ }
+
+ public boolean equal(Object o1, Object o2) {
+ return new CompareBoxed().equal(specific, o2);
+ }
+
+ private final Object specific;
+ }
+
+ private static final class CompareClass extends Compare {
+ public CompareClass(Class clazz) {
+ this.clazz = clazz;
+ }
+
+ public boolean equal(Object o1, Object o2) {
+ return o2 != null && o2.getClass() == clazz;
+ }
+
+ private final Class clazz;
+ }
+
+ public static class Enum1 extends Enum {
+ public Enum1() {
+ super(0);
+ }
+
+ public static Enum1 fromInt(int value) {
+ return new Enum1();
+ }
+
+ public boolean equals(Object obj) {
+ return obj != null && obj.getClass() == Enum1.class;
+ }
+ }
+
+ public static class Enum2 extends Enum1 {
+ public boolean equals(Object obj) {
+ return obj != null && obj.getClass() == Enum2.class;
+ }
+ }
+
+ public static class BaseStruct {
+ public boolean equals(Object obj) {
+ return obj != null && obj.getClass() == BaseStruct.class;
+ }
+ }
+
+ public static class DerivedStruct extends BaseStruct {
+ public boolean equals(Object obj) {
+ return obj != null && obj.getClass() == DerivedStruct.class;
+ }
+ }
+
+ public static class BaseException extends com.sun.star.uno.Exception {
+ public BaseException() {}
+
+ public BaseException(String message) {
+ super(message);
+ }
+
+ public boolean equals(Object obj) {
+ return obj != null && obj.getClass() == BaseException.class;
+ }
+ }
+
+ public static class DerivedException extends BaseException {
+ public DerivedException() {}
+
+ public DerivedException(String message) {
+ super(message);
+ }
+
+ public boolean equals(Object obj) {
+ return obj != null && obj.getClass() == DerivedException.class;
+ }
+ }
+
+ public static class BaseRuntimeException
+ extends com.sun.star.uno.RuntimeException
+ {
+ public BaseRuntimeException() {}
+
+ public BaseRuntimeException(String message) {
+ super(message);
+ }
+
+ public boolean equals(Object obj) {
+ return obj != null
+ && obj.getClass() == BaseRuntimeException.class;
+ }
+ }
+
+ public static class DerivedRuntimeException extends BaseRuntimeException
+ {
+ public DerivedRuntimeException() {}
+
+ public DerivedRuntimeException(String message) {
+ super(message);
+ }
+
+ public boolean equals(Object obj) {
+ return obj != null
+ && obj.getClass() == DerivedRuntimeException.class;
+ }
+ }
+}
diff --git a/bridges/test/java_uno/any/TestJni.java b/bridges/test/java_uno/any/TestJni.java
new file mode 100644
index 000000000000..1242c38e86b0
--- /dev/null
+++ b/bridges/test/java_uno/any/TestJni.java
@@ -0,0 +1,48 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package test.java_uno.anytest;
+
+public class TestJni
+{
+ static { System.loadLibrary( "test_javauno_any" ); }
+ private static native XTransport create_jni_transport(ClassLoader loader);
+
+ public static void main( String args [] )
+ {
+ if (TestAny.test(
+ create_jni_transport(TestJni.class.getClassLoader()), false ))
+ {
+ System.out.println( "jni any test succeeded." );
+ }
+ else
+ {
+ System.err.println( "jni any test failed!" );
+ System.exit( 1 );
+ }
+ }
+}
diff --git a/bridges/test/java_uno/any/TestRemote.java b/bridges/test/java_uno/any/TestRemote.java
new file mode 100644
index 000000000000..4d038559660f
--- /dev/null
+++ b/bridges/test/java_uno/any/TestRemote.java
@@ -0,0 +1,64 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package test.java_uno.anytest;
+
+import com.sun.star.bridge.XInstanceProvider;
+import com.sun.star.lib.TestBed;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+
+public final class TestRemote {
+ public static void main(String[] args) throws Exception {
+ boolean success = new TestBed().execute(
+ new Provider(), false, Client.class, 0);
+ System.out.println("success? " + success);
+ System.exit(success ? 0 : 1);
+ }
+
+ public static final class Client extends TestBed.Client {
+ public static void main(String[] args) {
+ new Client().execute();
+ }
+
+ protected boolean run(XComponentContext context) throws Throwable {
+ XTransport transport = UnoRuntime.queryInterface(
+ XTransport.class, getBridge(context).getInstance("Transport"));
+ return TestAny.test(transport, true);
+ }
+ }
+
+ private static final class Provider implements XInstanceProvider {
+ public Object getInstance(String instanceName) {
+ return new XTransport() {
+ public Object mapAny(Object any) {
+ return any;
+ }
+ };
+ }
+ }
+}
diff --git a/bridges/test/java_uno/any/makefile.mk b/bridges/test/java_uno/any/makefile.mk
new file mode 100644
index 000000000000..888fae21d3d2
--- /dev/null
+++ b/bridges/test/java_uno/any/makefile.mk
@@ -0,0 +1,127 @@
+#*************************************************************************
+#
+# 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 = test_javauno_any
+
+PACKAGE = test$/java_uno$/anytest
+
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE: settings.mk
+
+.IF "$(GUI)" == "WNT"
+GIVE_EXEC_RIGHTS = @echo
+.ELSE
+GIVE_EXEC_RIGHTS = chmod +x
+.ENDIF
+
+JAVAFILES = \
+ $(subst,$(CLASSDIR)$/$(PACKAGE)$/, $(subst,.class,.java $(JAVACLASSFILES)))
+
+# Make sure TestBed.class is found under $(CLASSDIR)$/test:
+.IF "$(XCLASSPATH)" == ""
+XCLASSPATH := $(CLASSDIR)$/test
+.ELSE
+XCLASSPATH !:= $(XCLASSPATH)$(PATH_SEPERATOR)$(CLASSDIR)$/test
+.ENDIF
+
+EXEC_CLASSPATH_TMP = \
+ $(foreach,i,$(JARFILES) $(SOLARBINDIR)$/$i)$(PATH_SEPERATOR)$(XCLASSPATH)
+EXEC_CLASSPATH = \
+ $(strip $(subst,!,$(PATH_SEPERATOR) $(EXEC_CLASSPATH_TMP:s/ /!/)))
+
+JARFILES = juh.jar jurt.jar ridl.jar
+JAVACLASSFILES = \
+ $(CLASSDIR)$/$(PACKAGE)$/TestAny.class \
+ $(CLASSDIR)$/$(PACKAGE)$/TestRemote.class \
+ $(CLASSDIR)$/$(PACKAGE)$/TestJni.class
+
+#--------------------------------------------------
+
+USE_DEFFILE = TRUE
+ENABLE_EXCEPTIONS = TRUE
+INCPRE += $(OUT)$/inc$/test
+
+.IF "$(debug)" != ""
+.IF "$(COM)" == "MSC"
+CFLAGS += -Ob0
+.ENDIF
+.ENDIF
+
+SLOFILES= \
+ $(SLO)$/transport.obj
+
+SHL1TARGET=$(TARGET)
+
+SHL1STDLIBS= \
+ $(CPPUHELPERLIB) \
+ $(SALHELPERLIB) \
+ $(JVMACCESSLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+SHL1VERSIONMAP=$(TARGET).map
+SHL1IMPLIB=i$(TARGET)
+SHL1LIBS=$(SLB)$/$(TARGET).lib
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+DEF1NAME=$(SHL1TARGET)
+
+.INCLUDE: target.mk
+
+#--------------------------------------------------
+
+$(SLOFILES) : $(MISC)$/gen_files.flag
+$(JAVACLASSFILES) : $(MISC)$/gen_files.flag
+
+ALLTAR : \
+ $(OUT)$/bin$/TestRemote \
+ $(OUT)$/bin$/TestJni
+
+$(OUT)$/bin$/TestRemote : $(JAVACLASSFILES)
+ -rm -f $@
+ echo java -classpath ..$/class$/test$(PATH_SEPERATOR)..$/class$(PATH_SEPERATOR)$(EXEC_CLASSPATH) \
+ test.java_uno.anytest.TestRemote > $@
+ $(GIVE_EXEC_RIGHTS) $@
+
+$(OUT)$/bin$/TestJni : $(JAVACLASSFILES)
+ -rm -f $@
+ echo '$(AUGMENT_LIBRARY_PATH)' java -classpath \
+ .$(PATH_SEPERATOR)..$/class$(PATH_SEPERATOR)$(EXEC_CLASSPATH) \
+ -Djava.library.path=..$/lib test.java_uno.anytest.TestJni >> $@
+ $(GIVE_EXEC_RIGHTS) $@
+
+$(BIN)$/test_java_uno_anytest.rdb : types.idl
+ $(IDLC) -I$(PRJ) -I$(SOLARIDLDIR) -O$(BIN) $?
+ $(REGMERGE) $@ /UCR $(BIN)$/{$(?:f:s/.idl/.urd/)}
+
+$(MISC)$/gen_files.flag : $(BIN)$/test_java_uno_anytest.rdb
+ $(CPPUMAKER) -C -BUCR -O $(OUT)$/inc$/test -X $(SOLARBINDIR)$/udkapi.rdb $?
+ $(CPPUMAKER) -C -BUCR -O $(OUT)$/inc$/test -T com.sun.star.uno.XInterface $(SOLARBINDIR)$/udkapi.rdb
+ $(JAVAMAKER) -nD -BUCR -O $(CLASSDIR) -X $(SOLARBINDIR)$/udkapi.rdb $?
+ $(TOUCH) $@
diff --git a/bridges/test/java_uno/any/test_javauno_any.map b/bridges/test/java_uno/any/test_javauno_any.map
new file mode 100644
index 000000000000..c50f7b162db7
--- /dev/null
+++ b/bridges/test/java_uno/any/test_javauno_any.map
@@ -0,0 +1,6 @@
+UDK_3_0_0 {
+ global:
+ Java_test_java_1uno_anytest_TestJni_create_1jni_1transport;
+ local:
+ *;
+};
diff --git a/bridges/test/java_uno/any/transport.cxx b/bridges/test/java_uno/any/transport.cxx
new file mode 100644
index 000000000000..4211a96f8149
--- /dev/null
+++ b/bridges/test/java_uno/any/transport.cxx
@@ -0,0 +1,111 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "jni.h"
+
+#include "uno/mapping.hxx"
+#include "uno/environment.hxx"
+#include "jvmaccess/virtualmachine.hxx"
+#include "jvmaccess/unovirtualmachine.hxx"
+#include "cppuhelper/implbase1.hxx"
+
+#include "test/java_uno/anytest/XTransport.hpp"
+#include "test/java_uno/anytest/DerivedInterface.hpp"
+
+
+using namespace ::com::sun::star::uno;
+using ::test::java_uno::anytest::XTransport;
+using ::rtl::OUString;
+
+namespace
+{
+//==================================================================================================
+class Transport : public ::cppu::WeakImplHelper1< XTransport >
+{
+public:
+ virtual Any SAL_CALL mapAny( Any const & any )
+ throw (RuntimeException);
+};
+//__________________________________________________________________________________________________
+Any Transport::mapAny( Any const & any )
+ throw (RuntimeException)
+{
+ return any;
+}
+}
+
+//##################################################################################################
+extern "C" JNIEXPORT jobject JNICALL Java_test_java_1uno_anytest_TestJni_create_1jni_1transport(
+ JNIEnv * jni_env, jclass, jobject loader )
+ SAL_THROW_EXTERN_C()
+{
+ // publish some idl types
+ ::getCppuType( (Reference< XTransport > const *)0 );
+ ::getCppuType( (Reference< ::test::java_uno::anytest::DerivedInterface > const *)0 );
+
+ Reference< XTransport > xRet( new Transport() );
+
+ // get java vm
+ JavaVM * java_vm;
+ OSL_VERIFY( 0 == jni_env->GetJavaVM( &java_vm ) );
+ // create jvmaccess vm
+ ::rtl::Reference< ::jvmaccess::UnoVirtualMachine > vm;
+ try {
+ vm = new ::jvmaccess::UnoVirtualMachine(
+ new ::jvmaccess::VirtualMachine(
+ java_vm, JNI_VERSION_1_2, false, jni_env ),
+ loader );
+ } catch ( ::jvmaccess::UnoVirtualMachine::CreationException & ) {
+ OSL_ASSERT( false );
+ throw;
+ }
+ // create uno envs
+ OUString java_name( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_JAVA) );
+ OUString cpp_name( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) );
+ Environment java_env, cpp_env;
+ uno_getEnvironment( (uno_Environment **)&java_env, java_name.pData, vm.get() );
+ OSL_ASSERT( java_env.is() );
+ uno_getEnvironment( (uno_Environment **)&cpp_env, cpp_name.pData, 0 );
+ OSL_ASSERT( cpp_env.is() );
+
+ // map interface
+ Mapping mapping( cpp_env.get(), java_env.get() );
+ OSL_ASSERT( mapping.is() );
+ jobject jo_global = (jobject)mapping.mapInterface( xRet.get(), ::getCppuType( &xRet ) );
+ OSL_ASSERT( 0 != jo_global );
+
+ // return
+ jobject jo_ret = jni_env->NewLocalRef( jo_global );
+ jni_env->DeleteGlobalRef( jo_global );
+ return jo_ret;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/test/java_uno/any/types.idl b/bridges/test/java_uno/any/types.idl
new file mode 100644
index 000000000000..a7d7df5487e6
--- /dev/null
+++ b/bridges/test/java_uno/any/types.idl
@@ -0,0 +1,42 @@
+/*************************************************************************
+ *
+ * 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 <com/sun/star/uno/XInterface.idl>
+
+
+module test { module java_uno { module anytest {
+
+interface XTransport : com::sun::star::uno::XInterface
+{
+ any mapAny([in] any a);
+};
+
+interface BaseInterface : com::sun::star::uno::XInterface {};
+
+interface DerivedInterface : BaseInterface {};
+
+}; }; };
diff --git a/bridges/test/java_uno/equals/TestEquals.java b/bridges/test/java_uno/equals/TestEquals.java
new file mode 100644
index 000000000000..5f3ee34a1c1d
--- /dev/null
+++ b/bridges/test/java_uno/equals/TestEquals.java
@@ -0,0 +1,1304 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package test.java_uno.equals;
+
+import com.sun.star.bridge.XBridge;
+import com.sun.star.bridge.XBridgeFactory;
+import com.sun.star.bridge.XInstanceProvider;
+import com.sun.star.comp.helper.Bootstrap;
+import com.sun.star.connection.Acceptor;
+import com.sun.star.connection.XAcceptor;
+import com.sun.star.connection.XConnection;
+import com.sun.star.lang.XMultiComponentFactory;
+import com.sun.star.lang.XSingleComponentFactory;
+import com.sun.star.lib.TestBed;
+import com.sun.star.lib.uno.typeinfo.MethodTypeInfo;
+import com.sun.star.lib.uno.typeinfo.TypeInfo;
+import com.sun.star.loader.XImplementationLoader;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+import com.sun.star.uno.XInterface;
+import java.io.File;
+import java.net.MalformedURLException;
+import java.util.HashMap;
+import java.util.Hashtable;
+
+// In this test scenario, the Java server (see implementation of method
+// notifyAccepting) has a remote bridge to the Java client and a local JNI
+// bridge to a C++ com.sun.star.test.bridges.testequals.impl service. The C++
+// service and the Java client are also connected via a remote bridge.
+//
+// The Java server gets two objects (INSTANCE1, INSTANCE2), once directly from
+// the Java client via the remote bridge (proxies test1A, test2A), and once
+// through the C++ service via the JNI bridge (proxies test1B, test2B).
+// Exhaustive tests on the proxies' equals and hashCode methods are done.
+
+public final class TestEquals {
+ // args[0] must be a file system path to a types.rdb,
+ // args[1] must be a file system path to a services.rdb
+ public static void main(String[] args) throws Exception {
+ TestBed t = new TestBed();
+ boolean success = t.execute(
+ new Provider(t, toFileUrl(args[0]), toFileUrl(args[1])), true,
+ Client.class, 0);
+ System.out.println("success? " + success);
+ System.exit(success ? 0 : 1);
+ }
+
+ private static String toFileUrl(String path) throws MalformedURLException {
+ String url = new File(path).toURL().toString();
+ String prefix = "file:/";
+ if (url.startsWith(prefix)
+ && (url.length() == prefix.length()
+ || url.charAt(prefix.length()) != '/')) {
+ url = url.substring(0, prefix.length()) + "//"
+ + url.substring(prefix.length());
+ }
+ return url;
+ }
+
+ public static final class Client extends TestBed.Client {
+ public static void main(String[] args) {
+ new Client().execute();
+ }
+
+ protected boolean run(XComponentContext context) throws Throwable {
+ XTestFrame f = UnoRuntime.queryInterface(
+ XTestFrame.class, getBridge(context).getInstance("TestFrame"));
+ XAcceptor acceptor = Acceptor.create(context);
+ XBridgeFactory factory = UnoRuntime.queryInterface(
+ XBridgeFactory.class,
+ context.getServiceManager().createInstanceWithContext(
+ "com.sun.star.bridge.BridgeFactory", context));
+ System.out.println("Client, 2nd connection: Accepting...");
+ XInstanceProvider prov = new Provider();
+ f.notifyAccepting(new Done(), prov.getInstance(INSTANCE1),
+ prov.getInstance(INSTANCE2));
+ XConnection connection = acceptor.accept(CONNECTION_DESCRIPTION);
+ System.out.println("Client, 2nd connection: ...connected...");
+ XBridge bridge2 = factory.createBridge(
+ "", PROTOCOL_DESCRIPTION, connection, prov);
+ System.out.println("Client, 2nd connection: ...bridged.");
+ synchronized (lock) {
+ while (!done) {
+ lock.wait();
+ }
+ }
+ return true;
+ }
+
+ private static final class Provider implements XInstanceProvider {
+ public Object getInstance(String instanceName) {
+ synchronized (map) {
+ Object o = map.get(instanceName);
+ if (o == null) {
+ o = new XDerived() {};
+ map.put(instanceName, o);
+ }
+ return o;
+ }
+ }
+
+ private final HashMap map = new HashMap();
+ }
+
+ private final class Done implements XDone {
+ public void notifyDone() {
+ synchronized (lock) {
+ done = true;
+ lock.notifyAll();
+ }
+ }
+ }
+
+ private final Object lock = new Object();
+ private boolean done = false;
+ }
+
+ private static final class Provider implements XInstanceProvider {
+ public Provider(TestBed testBed, String unoTypes, String unoServices) {
+ this.testBed = testBed;
+ this.unoTypes = unoTypes;
+ this.unoServices = unoServices;
+ }
+
+ public Object getInstance(String instanceName) {
+ return new XTestFrame() {
+ public void notifyAccepting(
+ final XDone done, final Object object1,
+ final Object object2)
+ {
+ new Thread() {
+ public void run() {
+ try {
+ Object test1Aa = object1;
+ XBase test1Ab = UnoRuntime.queryInterface(
+ XBase.class, test1Aa);
+ XDerived test1Ac =
+ UnoRuntime.queryInterface(
+ XDerived.class, test1Aa);
+ Object test2Aa = object2;
+ XBase test2Ab = UnoRuntime.queryInterface(
+ XBase.class, test2Aa);
+ XDerived test2Ac =
+ UnoRuntime.queryInterface(
+ XDerived.class, test2Aa);
+
+ Hashtable params = new Hashtable();
+ params.put("UNO_TYPES", unoTypes);
+ params.put("UNO_SERVICES", unoServices);
+ XComponentContext context = Bootstrap.
+ defaultBootstrap_InitialComponentContext(
+ null, params);
+ XMultiComponentFactory factory
+ = context.getServiceManager();
+ XImplementationLoader loader =
+ UnoRuntime.queryInterface(
+ XImplementationLoader.class,
+ factory.createInstanceWithContext(
+ "com.sun.star.loader."
+ + "SharedLibrary",
+ context));
+ XSingleComponentFactory factory2 =
+ UnoRuntime.queryInterface(
+ XSingleComponentFactory.class,
+ loader.activate(
+ "com.sun.star.test.bridges."
+ + "testequals.impl",
+ "", "../lib/testequals.uno",
+ null));
+ XTestInterface test =
+ UnoRuntime.queryInterface(
+ XTestInterface.class,
+ factory2.createInstanceWithContext(
+ context));
+ // allow client to start accepting:
+ Thread.sleep(3000);
+ test.connect(
+ CONNECTION_DESCRIPTION,
+ PROTOCOL_DESCRIPTION);
+
+ Object test1Ba = test.get(INSTANCE1);
+ XBase test1Bb = UnoRuntime.queryInterface(
+ XBase.class, test1Ba);
+ XDerived test1Bc =
+ UnoRuntime.queryInterface(
+ XDerived.class, test1Ba);
+ Object test2Ba = test.get(INSTANCE2);
+ XBase test2Bb = UnoRuntime.queryInterface(
+ XBase.class, test2Ba);
+ XDerived test2Bc =
+ UnoRuntime.queryInterface(
+ XDerived.class, test2Ba);
+
+ boolean success = true;
+
+ success &= test(
+ "UnoRumtime.areSame(null, null)",
+ UnoRuntime.areSame(null, null));
+ success &= test(
+ "!UnoRumtime.areSame(null, test1Aa)",
+ !UnoRuntime.areSame(null, test1Aa));
+ success &= test(
+ "!UnoRumtime.areSame(null, test1Ab)",
+ !UnoRuntime.areSame(null, test1Ab));
+ success &= test(
+ "!UnoRumtime.areSame(null, test1Ac)",
+ !UnoRuntime.areSame(null, test1Ac));
+ success &= test(
+ "!UnoRumtime.areSame(null, test1Ba)",
+ !UnoRuntime.areSame(null, test1Ba));
+ success &= test(
+ "!UnoRumtime.areSame(null, test1Bb)",
+ !UnoRuntime.areSame(null, test1Bb));
+ success &= test(
+ "!UnoRumtime.areSame(null, test1Bc)",
+ !UnoRuntime.areSame(null, test1Bc));
+ success &= test(
+ "!UnoRumtime.areSame(null, test2Aa)",
+ !UnoRuntime.areSame(null, test2Aa));
+ success &= test(
+ "!UnoRumtime.areSame(null, test2Ab)",
+ !UnoRuntime.areSame(null, test2Ab));
+ success &= test(
+ "!UnoRumtime.areSame(null, test2Ac)",
+ !UnoRuntime.areSame(null, test2Ac));
+ success &= test(
+ "!UnoRumtime.areSame(null, test2Ba)",
+ !UnoRuntime.areSame(null, test2Ba));
+ success &= test(
+ "!UnoRumtime.areSame(null, test2Bb)",
+ !UnoRuntime.areSame(null, test2Bb));
+ success &= test(
+ "!UnoRumtime.areSame(null, test2Bc)",
+ !UnoRuntime.areSame(null, test2Bc));
+
+ success &= test(
+ "!test1Aa.equals(null)",
+ !test1Aa.equals(null));
+ success &= test(
+ "!UnoRuntime.areSame(test1Aa, null)",
+ !UnoRuntime.areSame(test1Aa, null));
+ success &= test(
+ "test1Aa.equals(test1Aa)",
+ test1Aa.equals(test1Aa));
+ success &= test(
+ "UnoRuntime.areSame(test1Aa, test1Aa)",
+ UnoRuntime.areSame(test1Aa, test1Aa));
+ success &= test(
+ "test1Aa.equals(test1Ab)",
+ test1Aa.equals(test1Ab));
+ success &= test(
+ "UnoRuntime.areSame(test1Aa, test1Ab)",
+ UnoRuntime.areSame(test1Aa, test1Ab));
+ success &= test(
+ "test1Aa.equals(test1Ac)",
+ test1Aa.equals(test1Ac));
+ success &= test(
+ "UnoRuntime.areSame(test1Aa, test1Ac)",
+ UnoRuntime.areSame(test1Aa, test1Ac));
+ success &= test(
+ "test1Aa.equals(test1Ba)",
+ test1Aa.equals(test1Ba));
+ success &= test(
+ "UnoRuntime.areSame(test1Aa, test1Ba)",
+ UnoRuntime.areSame(test1Aa, test1Ba));
+ success &= test(
+ "test1Aa.equals(test1Bb)",
+ test1Aa.equals(test1Bb));
+ success &= test(
+ "UnoRuntime.areSame(test1Aa, test1Bb)",
+ UnoRuntime.areSame(test1Aa, test1Bb));
+ success &= test(
+ "test1Aa.equals(test1Bc)",
+ test1Aa.equals(test1Bc));
+ success &= test(
+ "UnoRuntime.areSame(test1Aa, test1Bc)",
+ UnoRuntime.areSame(test1Aa, test1Bc));
+ success &= test(
+ "!test1Aa.equals(test2Aa)",
+ !test1Aa.equals(test2Aa));
+ success &= test(
+ "!UnoRuntime.areSame(test1Aa, test2Aa)",
+ !UnoRuntime.areSame(test1Aa, test2Aa));
+ success &= test(
+ "!test1Aa.equals(test2Ab)",
+ !test1Aa.equals(test2Ab));
+ success &= test(
+ "!UnoRuntime.areSame(test1Aa, test2Ab)",
+ !UnoRuntime.areSame(test1Aa, test2Ab));
+ success &= test(
+ "!test1Aa.equals(test2Ac)",
+ !test1Aa.equals(test2Ac));
+ success &= test(
+ "!UnoRuntime.areSame(test1Aa, test2Ac)",
+ !UnoRuntime.areSame(test1Aa, test2Ac));
+ success &= test(
+ "!test1Aa.equals(test2Ba)",
+ !test1Aa.equals(test2Ba));
+ success &= test(
+ "!UnoRuntime.areSame(test1Aa, test2Ba)",
+ !UnoRuntime.areSame(test1Aa, test2Ba));
+ success &= test(
+ "!test1Aa.equals(test2Bb)",
+ !test1Aa.equals(test2Bb));
+ success &= test(
+ "!UnoRuntime.areSame(test1Aa, test2Bb)",
+ !UnoRuntime.areSame(test1Aa, test2Bb));
+ success &= test(
+ "!test1Aa.equals(test2Bc)",
+ !test1Aa.equals(test2Bc));
+ success &= test(
+ "!UnoRuntime.areSame(test1Aa, test2Bc)",
+ !UnoRuntime.areSame(test1Aa, test2Bc));
+
+ success &= test(
+ "!test1Ab.equals(null)",
+ !test1Ab.equals(null));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ab, null)",
+ !UnoRuntime.areSame(test1Ab, null));
+ success &= test(
+ "test1Ab.equals(test1Aa)",
+ test1Ab.equals(test1Aa));
+ success &= test(
+ "UnoRuntime.areSame(test1Ab, test1Aa)",
+ UnoRuntime.areSame(test1Ab, test1Aa));
+ success &= test(
+ "test1Ab.equals(test1Ab)",
+ test1Ab.equals(test1Ab));
+ success &= test(
+ "UnoRuntime.areSame(test1Ab, test1Ab)",
+ UnoRuntime.areSame(test1Ab, test1Ab));
+ success &= test(
+ "test1Ab.equals(test1Ac)",
+ test1Ab.equals(test1Ac));
+ success &= test(
+ "UnoRuntime.areSame(test1Ab, test1Ac)",
+ UnoRuntime.areSame(test1Ab, test1Ac));
+ success &= test(
+ "test1Ab.equals(test1Ba)",
+ test1Ab.equals(test1Ba));
+ success &= test(
+ "UnoRuntime.areSame(test1Ab, test1Ba)",
+ UnoRuntime.areSame(test1Ab, test1Ba));
+ success &= test(
+ "test1Ab.equals(test1Bb)",
+ test1Ab.equals(test1Bb));
+ success &= test(
+ "UnoRuntime.areSame(test1Ab, test1Bb)",
+ UnoRuntime.areSame(test1Ab, test1Bb));
+ success &= test(
+ "test1Ab.equals(test1Bc)",
+ test1Ab.equals(test1Bc));
+ success &= test(
+ "UnoRuntime.areSame(test1Ab, test1Bc)",
+ UnoRuntime.areSame(test1Ab, test1Bc));
+ success &= test(
+ "!test1Ab.equals(test2Aa)",
+ !test1Ab.equals(test2Aa));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ab, test2Aa)",
+ !UnoRuntime.areSame(test1Ab, test2Aa));
+ success &= test(
+ "!test1Ab.equals(test2Ab)",
+ !test1Ab.equals(test2Ab));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ab, test2Ab)",
+ !UnoRuntime.areSame(test1Ab, test2Ab));
+ success &= test(
+ "!test1Ab.equals(test2Ac)",
+ !test1Ab.equals(test2Ac));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ab, test2Ac)",
+ !UnoRuntime.areSame(test1Ab, test2Ac));
+ success &= test(
+ "!test1Ab.equals(test2Ba)",
+ !test1Ab.equals(test2Ba));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ab, test2Ba)",
+ !UnoRuntime.areSame(test1Ab, test2Ba));
+ success &= test(
+ "!test1Ab.equals(test2Bb)",
+ !test1Ab.equals(test2Bb));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ab, test2Bb)",
+ !UnoRuntime.areSame(test1Ab, test2Bb));
+ success &= test(
+ "!test1Ab.equals(test2Bc)",
+ !test1Ab.equals(test2Bc));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ab, test2Bc)",
+ !UnoRuntime.areSame(test1Ab, test2Bc));
+
+ success &= test(
+ "!test1Ac.equals(null)",
+ !test1Ac.equals(null));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ac, null)",
+ !UnoRuntime.areSame(test1Ac, null));
+ success &= test(
+ "test1Ac.equals(test1Aa)",
+ test1Ac.equals(test1Aa));
+ success &= test(
+ "UnoRuntime.areSame(test1Ac, test1Aa)",
+ UnoRuntime.areSame(test1Ac, test1Aa));
+ success &= test(
+ "test1Ac.equals(test1Ab)",
+ test1Ac.equals(test1Ab));
+ success &= test(
+ "UnoRuntime.areSame(test1Ac, test1Ab)",
+ UnoRuntime.areSame(test1Ac, test1Ab));
+ success &= test(
+ "test1Ac.equals(test1Ac)",
+ test1Ac.equals(test1Ac));
+ success &= test(
+ "UnoRuntime.areSame(test1Ac, test1Ac)",
+ UnoRuntime.areSame(test1Ac, test1Ac));
+ success &= test(
+ "test1Ac.equals(test1Ba)",
+ test1Ac.equals(test1Ba));
+ success &= test(
+ "UnoRuntime.areSame(test1Ac, test1Ba)",
+ UnoRuntime.areSame(test1Ac, test1Ba));
+ success &= test(
+ "test1Ac.equals(test1Bb)",
+ test1Ac.equals(test1Bb));
+ success &= test(
+ "UnoRuntime.areSame(test1Ac, test1Bb)",
+ UnoRuntime.areSame(test1Ac, test1Bb));
+ success &= test(
+ "test1Ac.equals(test1Bc)",
+ test1Ac.equals(test1Bc));
+ success &= test(
+ "UnoRuntime.areSame(test1Ac, test1Bc)",
+ UnoRuntime.areSame(test1Ac, test1Bc));
+ success &= test(
+ "!test1Ac.equals(test2Aa)",
+ !test1Ac.equals(test2Aa));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ac, test2Aa)",
+ !UnoRuntime.areSame(test1Ac, test2Aa));
+ success &= test(
+ "!test1Ac.equals(test2Ab)",
+ !test1Ac.equals(test2Ab));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ac, test2Ab)",
+ !UnoRuntime.areSame(test1Ac, test2Ab));
+ success &= test(
+ "!test1Ac.equals(test2Ac)",
+ !test1Ac.equals(test2Ac));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ac, test2Ac)",
+ !UnoRuntime.areSame(test1Ac, test2Ac));
+ success &= test(
+ "!test1Ac.equals(test2Ba)",
+ !test1Ac.equals(test2Ba));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ac, test2Ba)",
+ !UnoRuntime.areSame(test1Ac, test2Ba));
+ success &= test(
+ "!test1Ac.equals(test2Bb)",
+ !test1Ac.equals(test2Bb));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ac, test2Bb)",
+ !UnoRuntime.areSame(test1Ac, test2Bb));
+ success &= test(
+ "!test1Ac.equals(test2Bc)",
+ !test1Ac.equals(test2Bc));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ac, test2Bc)",
+ !UnoRuntime.areSame(test1Ac, test2Bc));
+
+ success &= test(
+ "!test1Ba.equals(null)",
+ !test1Ba.equals(null));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ba, null)",
+ !UnoRuntime.areSame(test1Ba, null));
+ success &= test(
+ "test1Ba.equals(test1Aa)",
+ test1Ba.equals(test1Aa));
+ success &= test(
+ "UnoRuntime.areSame(test1Ba, test1Aa)",
+ UnoRuntime.areSame(test1Ba, test1Aa));
+ success &= test(
+ "test1Ba.equals(test1Ab)",
+ test1Ba.equals(test1Ab));
+ success &= test(
+ "UnoRuntime.areSame(test1Ba, test1Ab)",
+ UnoRuntime.areSame(test1Ba, test1Ab));
+ success &= test(
+ "test1Ba.equals(test1Ac)",
+ test1Ba.equals(test1Ac));
+ success &= test(
+ "UnoRuntime.areSame(test1Ba, test1Ac)",
+ UnoRuntime.areSame(test1Ba, test1Ac));
+ success &= test(
+ "test1Ba.equals(test1Ba)",
+ test1Ba.equals(test1Ba));
+ success &= test(
+ "UnoRuntime.areSame(test1Ba, test1Ba)",
+ UnoRuntime.areSame(test1Ba, test1Ba));
+ success &= test(
+ "test1Ba.equals(test1Bb)",
+ test1Ba.equals(test1Bb));
+ success &= test(
+ "UnoRuntime.areSame(test1Ba, test1Bb)",
+ UnoRuntime.areSame(test1Ba, test1Bb));
+ success &= test(
+ "test1Ba.equals(test1Bc)",
+ test1Ba.equals(test1Bc));
+ success &= test(
+ "UnoRuntime.areSame(test1Ba, test1Bc)",
+ UnoRuntime.areSame(test1Ba, test1Bc));
+ success &= test(
+ "!test1Ba.equals(test2Aa)",
+ !test1Ba.equals(test2Aa));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ba, test2Aa)",
+ !UnoRuntime.areSame(test1Ba, test2Aa));
+ success &= test(
+ "!test1Ba.equals(test2Ab)",
+ !test1Ba.equals(test2Ab));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ba, test2Ab)",
+ !UnoRuntime.areSame(test1Ba, test2Ab));
+ success &= test(
+ "!test1Ba.equals(test2Ac)",
+ !test1Ba.equals(test2Ac));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ba, test2Ac)",
+ !UnoRuntime.areSame(test1Ba, test2Ac));
+ success &= test(
+ "!test1Ba.equals(test2Ba)",
+ !test1Ba.equals(test2Ba));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ba, test2Ba)",
+ !UnoRuntime.areSame(test1Ba, test2Ba));
+ success &= test(
+ "!test1Ba.equals(test2Bb)",
+ !test1Ba.equals(test2Bb));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ba, test2Bb)",
+ !UnoRuntime.areSame(test1Ba, test2Bb));
+ success &= test(
+ "!test1Ba.equals(test2Bc)",
+ !test1Ba.equals(test2Bc));
+ success &= test(
+ "!UnoRuntime.areSame(test1Ba, test2Bc)",
+ !UnoRuntime.areSame(test1Ba, test2Bc));
+
+ success &= test(
+ "!test1Bb.equals(null)",
+ !test1Bb.equals(null));
+ success &= test(
+ "!UnoRuntime.areSame(test1Bb, null)",
+ !UnoRuntime.areSame(test1Bb, null));
+ success &= test(
+ "test1Bb.equals(test1Aa)",
+ test1Bb.equals(test1Aa));
+ success &= test(
+ "UnoRuntime.areSame(test1Bb, test1Aa)",
+ UnoRuntime.areSame(test1Bb, test1Aa));
+ success &= test(
+ "test1Bb.equals(test1Ab)",
+ test1Bb.equals(test1Ab));
+ success &= test(
+ "UnoRuntime.areSame(test1Bb, test1Ab)",
+ UnoRuntime.areSame(test1Bb, test1Ab));
+ success &= test(
+ "test1Bb.equals(test1Ac)",
+ test1Bb.equals(test1Ac));
+ success &= test(
+ "UnoRuntime.areSame(test1Bb, test1Ac)",
+ UnoRuntime.areSame(test1Bb, test1Ac));
+ success &= test(
+ "test1Bb.equals(test1Ba)",
+ test1Bb.equals(test1Ba));
+ success &= test(
+ "UnoRuntime.areSame(test1Bb, test1Ba)",
+ UnoRuntime.areSame(test1Bb, test1Ba));
+ success &= test(
+ "test1Bb.equals(test1Bb)",
+ test1Bb.equals(test1Bb));
+ success &= test(
+ "UnoRuntime.areSame(test1Bb, test1Bb)",
+ UnoRuntime.areSame(test1Bb, test1Bb));
+ success &= test(
+ "test1Bb.equals(test1Bc)",
+ test1Bb.equals(test1Bc));
+ success &= test(
+ "UnoRuntime.areSame(test1Bb, test1Bc)",
+ UnoRuntime.areSame(test1Bb, test1Bc));
+ success &= test(
+ "!test1Bb.equals(test2Aa)",
+ !test1Bb.equals(test2Aa));
+ success &= test(
+ "!UnoRuntime.areSame(test1Bb, test2Aa)",
+ !UnoRuntime.areSame(test1Bb, test2Aa));
+ success &= test(
+ "!test1Bb.equals(test2Ab)",
+ !test1Bb.equals(test2Ab));
+ success &= test(
+ "!UnoRuntime.areSame(test1Bb, test2Ab)",
+ !UnoRuntime.areSame(test1Bb, test2Ab));
+ success &= test(
+ "!test1Bb.equals(test2Ac)",
+ !test1Bb.equals(test2Ac));
+ success &= test(
+ "!UnoRuntime.areSame(test1Bb, test2Ac)",
+ !UnoRuntime.areSame(test1Bb, test2Ac));
+ success &= test(
+ "!test1Bb.equals(test2Ba)",
+ !test1Bb.equals(test2Ba));
+ success &= test(
+ "!UnoRuntime.areSame(test1Bb, test2Ba)",
+ !UnoRuntime.areSame(test1Bb, test2Ba));
+ success &= test(
+ "!test1Bb.equals(test2Bb)",
+ !test1Bb.equals(test2Bb));
+ success &= test(
+ "!UnoRuntime.areSame(test1Bb, test2Bb)",
+ !UnoRuntime.areSame(test1Bb, test2Bb));
+ success &= test(
+ "!test1Bb.equals(test2Bc)",
+ !test1Bb.equals(test2Bc));
+ success &= test(
+ "!UnoRuntime.areSame(test1Bb, test2Bc)",
+ !UnoRuntime.areSame(test1Bb, test2Bc));
+
+ success &= test(
+ "!test1Bc.equals(null)",
+ !test1Bc.equals(null));
+ success &= test(
+ "!UnoRuntime.areSame(test1Bc, null)",
+ !UnoRuntime.areSame(test1Bc, null));
+ success &= test(
+ "test1Bc.equals(test1Aa)",
+ test1Bc.equals(test1Aa));
+ success &= test(
+ "UnoRuntime.areSame(test1Bc, test1Aa)",
+ UnoRuntime.areSame(test1Bc, test1Aa));
+ success &= test(
+ "test1Bc.equals(test1Ab)",
+ test1Bc.equals(test1Ab));
+ success &= test(
+ "UnoRuntime.areSame(test1Bc, test1Ab)",
+ UnoRuntime.areSame(test1Bc, test1Ab));
+ success &= test(
+ "test1Bc.equals(test1Ac)",
+ test1Bc.equals(test1Ac));
+ success &= test(
+ "UnoRuntime.areSame(test1Bc, test1Ac)",
+ UnoRuntime.areSame(test1Bc, test1Ac));
+ success &= test(
+ "test1Bc.equals(test1Ba)",
+ test1Bc.equals(test1Ba));
+ success &= test(
+ "UnoRuntime.areSame(test1Bc, test1Ba)",
+ UnoRuntime.areSame(test1Bc, test1Ba));
+ success &= test(
+ "test1Bc.equals(test1Bb)",
+ test1Bc.equals(test1Bb));
+ success &= test(
+ "UnoRuntime.areSame(test1Bc, test1Bb)",
+ UnoRuntime.areSame(test1Bc, test1Bb));
+ success &= test(
+ "test1Bc.equals(test1Bc)",
+ test1Bc.equals(test1Bc));
+ success &= test(
+ "UnoRuntime.areSame(test1Bc, test1Bc)",
+ UnoRuntime.areSame(test1Bc, test1Bc));
+ success &= test(
+ "!test1Bc.equals(test2Aa)",
+ !test1Bc.equals(test2Aa));
+ success &= test(
+ "!UnoRuntime.areSame(test1Bc, test2Aa)",
+ !UnoRuntime.areSame(test1Bc, test2Aa));
+ success &= test(
+ "!test1Bc.equals(test2Ab)",
+ !test1Bc.equals(test2Ab));
+ success &= test(
+ "!UnoRuntime.areSame(test1Bc, test2Ab)",
+ !UnoRuntime.areSame(test1Bc, test2Ab));
+ success &= test(
+ "!test1Bc.equals(test2Ac)",
+ !test1Bc.equals(test2Ac));
+ success &= test(
+ "!UnoRuntime.areSame(test1Bc, test2Ac)",
+ !UnoRuntime.areSame(test1Bc, test2Ac));
+ success &= test(
+ "!test1Bc.equals(test2Ba)",
+ !test1Bc.equals(test2Ba));
+ success &= test(
+ "!UnoRuntime.areSame(test1Bc, test2Ba)",
+ !UnoRuntime.areSame(test1Bc, test2Ba));
+ success &= test(
+ "!test1Bc.equals(test2Bb)",
+ !test1Bc.equals(test2Bb));
+ success &= test(
+ "!UnoRuntime.areSame(test1Bc, test2Bb)",
+ !UnoRuntime.areSame(test1Bc, test2Bb));
+ success &= test(
+ "!test1Bc.equals(test2Bc)",
+ !test1Bc.equals(test2Bc));
+ success &= test(
+ "!UnoRuntime.areSame(test1Bc, test2Bc)",
+ !UnoRuntime.areSame(test1Bc, test2Bc));
+
+ success &= test(
+ "!test2Aa.equals(null)",
+ !test2Aa.equals(null));
+ success &= test(
+ "!UnoRuntime.areSame(test2Aa, null)",
+ !UnoRuntime.areSame(test2Aa, null));
+ success &= test(
+ "!test2Aa.equals(test1Aa)",
+ !test2Aa.equals(test1Aa));
+ success &= test(
+ "!UnoRuntime.areSame(test2Aa, test1Aa)",
+ !UnoRuntime.areSame(test2Aa, test1Aa));
+ success &= test(
+ "!test2Aa.equals(test1Ab)",
+ !test2Aa.equals(test1Ab));
+ success &= test(
+ "!UnoRuntime.areSame(test2Aa, test1Ab)",
+ !UnoRuntime.areSame(test2Aa, test1Ab));
+ success &= test(
+ "!test2Aa.equals(test1Ac)",
+ !test2Aa.equals(test1Ac));
+ success &= test(
+ "!UnoRuntime.areSame(test2Aa, test1Ac)",
+ !UnoRuntime.areSame(test2Aa, test1Ac));
+ success &= test(
+ "!test2Aa.equals(test1Ba)",
+ !test2Aa.equals(test1Ba));
+ success &= test(
+ "!UnoRuntime.areSame(test2Aa, test1Ba)",
+ !UnoRuntime.areSame(test2Aa, test1Ba));
+ success &= test(
+ "!test2Aa.equals(test1Bb)",
+ !test2Aa.equals(test1Bb));
+ success &= test(
+ "!UnoRuntime.areSame(test2Aa, test1Bb)",
+ !UnoRuntime.areSame(test2Aa, test1Bb));
+ success &= test(
+ "!test2Aa.equals(test1Bc)",
+ !test2Aa.equals(test1Bc));
+ success &= test(
+ "!UnoRuntime.areSame(test2Aa, test1Bc)",
+ !UnoRuntime.areSame(test2Aa, test1Bc));
+ success &= test(
+ "test2Aa.equals(test2Aa)",
+ test2Aa.equals(test2Aa));
+ success &= test(
+ "UnoRuntime.areSame(test2Aa, test2Aa)",
+ UnoRuntime.areSame(test2Aa, test2Aa));
+ success &= test(
+ "test2Aa.equals(test2Ab)",
+ test2Aa.equals(test2Ab));
+ success &= test(
+ "UnoRuntime.areSame(test2Aa, test2Ab)",
+ UnoRuntime.areSame(test2Aa, test2Ab));
+ success &= test(
+ "test2Aa.equals(test2Ac)",
+ test2Aa.equals(test2Ac));
+ success &= test(
+ "UnoRuntime.areSame(test2Aa, test2Ac)",
+ UnoRuntime.areSame(test2Aa, test2Ac));
+ success &= test(
+ "test2Aa.equals(test2Ba)",
+ test2Aa.equals(test2Ba));
+ success &= test(
+ "UnoRuntime.areSame(test2Aa, test2Ba)",
+ UnoRuntime.areSame(test2Aa, test2Ba));
+ success &= test(
+ "test2Aa.equals(test2Bb)",
+ test2Aa.equals(test2Bb));
+ success &= test(
+ "UnoRuntime.areSame(test2Aa, test2Bb)",
+ UnoRuntime.areSame(test2Aa, test2Bb));
+ success &= test(
+ "test2Aa.equals(test2Bc)",
+ test2Aa.equals(test2Bc));
+ success &= test(
+ "UnoRuntime.areSame(test2Aa, test2Bc)",
+ UnoRuntime.areSame(test2Aa, test2Bc));
+
+ success &= test(
+ "!test2Ab.equals(null)",
+ !test2Ab.equals(null));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ab, null)",
+ !UnoRuntime.areSame(test2Ab, null));
+ success &= test(
+ "!test2Ab.equals(test1Aa)",
+ !test2Ab.equals(test1Aa));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ab, test1Aa)",
+ !UnoRuntime.areSame(test2Ab, test1Aa));
+ success &= test(
+ "!test2Ab.equals(test1Ab)",
+ !test2Ab.equals(test1Ab));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ab, test1Ab)",
+ !UnoRuntime.areSame(test2Ab, test1Ab));
+ success &= test(
+ "!test2Ab.equals(test1Ac)",
+ !test2Ab.equals(test1Ac));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ab, test1Ac)",
+ !UnoRuntime.areSame(test2Ab, test1Ac));
+ success &= test(
+ "!test2Ab.equals(test1Ba)",
+ !test2Ab.equals(test1Ba));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ab, test1Ba)",
+ !UnoRuntime.areSame(test2Ab, test1Ba));
+ success &= test(
+ "!test2Ab.equals(test1Bb)",
+ !test2Ab.equals(test1Bb));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ab, test1Bb)",
+ !UnoRuntime.areSame(test2Ab, test1Bb));
+ success &= test(
+ "!test2Ab.equals(test1Bc)",
+ !test2Ab.equals(test1Bc));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ab, test1Bc)",
+ !UnoRuntime.areSame(test2Ab, test1Bc));
+ success &= test(
+ "test2Ab.equals(test2Aa)",
+ test2Ab.equals(test2Aa));
+ success &= test(
+ "UnoRuntime.areSame(test2Ab, test2Aa)",
+ UnoRuntime.areSame(test2Ab, test2Aa));
+ success &= test(
+ "test2Ab.equals(test2Ab)",
+ test2Ab.equals(test2Ab));
+ success &= test(
+ "UnoRuntime.areSame(test2Ab, test2Ab)",
+ UnoRuntime.areSame(test2Ab, test2Ab));
+ success &= test(
+ "test2Ab.equals(test2Ac)",
+ test2Ab.equals(test2Ac));
+ success &= test(
+ "UnoRuntime.areSame(test2Ab, test2Ac)",
+ UnoRuntime.areSame(test2Ab, test2Ac));
+ success &= test(
+ "test2Ab.equals(test2Ba)",
+ test2Ab.equals(test2Ba));
+ success &= test(
+ "UnoRuntime.areSame(test2Ab, test2Ba)",
+ UnoRuntime.areSame(test2Ab, test2Ba));
+ success &= test(
+ "test2Ab.equals(test2Bb)",
+ test2Ab.equals(test2Bb));
+ success &= test(
+ "UnoRuntime.areSame(test2Ab, test2Bb)",
+ UnoRuntime.areSame(test2Ab, test2Bb));
+ success &= test(
+ "test2Ab.equals(test2Bc)",
+ test2Ab.equals(test2Bc));
+ success &= test(
+ "UnoRuntime.areSame(test2Ab, test2Bc)",
+ UnoRuntime.areSame(test2Ab, test2Bc));
+
+ success &= test(
+ "!test2Ac.equals(null)",
+ !test2Ac.equals(null));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ac, null)",
+ !UnoRuntime.areSame(test2Ac, null));
+ success &= test(
+ "!test2Ac.equals(test1Aa)",
+ !test2Ac.equals(test1Aa));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ac, test1Aa)",
+ !UnoRuntime.areSame(test2Ac, test1Aa));
+ success &= test(
+ "!test2Ac.equals(test1Ab)",
+ !test2Ac.equals(test1Ab));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ac, test1Ab)",
+ !UnoRuntime.areSame(test2Ac, test1Ab));
+ success &= test(
+ "!test2Ac.equals(test1Ac)",
+ !test2Ac.equals(test1Ac));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ac, test1Ac)",
+ !UnoRuntime.areSame(test2Ac, test1Ac));
+ success &= test(
+ "!test2Ac.equals(test1Ba)",
+ !test2Ac.equals(test1Ba));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ac, test1Ba)",
+ !UnoRuntime.areSame(test2Ac, test1Ba));
+ success &= test(
+ "!test2Ac.equals(test1Bb)",
+ !test2Ac.equals(test1Bb));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ac, test1Bb)",
+ !UnoRuntime.areSame(test2Ac, test1Bb));
+ success &= test(
+ "!test2Ac.equals(test1Bc)",
+ !test2Ac.equals(test1Bc));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ac, test1Bc)",
+ !UnoRuntime.areSame(test2Ac, test1Bc));
+ success &= test(
+ "test2Ac.equals(test2Aa)",
+ test2Ac.equals(test2Aa));
+ success &= test(
+ "UnoRuntime.areSame(test2Ac, test2Aa)",
+ UnoRuntime.areSame(test2Ac, test2Aa));
+ success &= test(
+ "test2Ac.equals(test2Ab)",
+ test2Ac.equals(test2Ab));
+ success &= test(
+ "UnoRuntime.areSame(test2Ac, test2Ab)",
+ UnoRuntime.areSame(test2Ac, test2Ab));
+ success &= test(
+ "test2Ac.equals(test2Ac)",
+ test2Ac.equals(test2Ac));
+ success &= test(
+ "UnoRuntime.areSame(test2Ac, test2Ac)",
+ UnoRuntime.areSame(test2Ac, test2Ac));
+ success &= test(
+ "test2Ac.equals(test2Ba)",
+ test2Ac.equals(test2Ba));
+ success &= test(
+ "UnoRuntime.areSame(test2Ac, test2Ba)",
+ UnoRuntime.areSame(test2Ac, test2Ba));
+ success &= test(
+ "test2Ac.equals(test2Bb)",
+ test2Ac.equals(test2Bb));
+ success &= test(
+ "UnoRuntime.areSame(test2Ac, test2Bb)",
+ UnoRuntime.areSame(test2Ac, test2Bb));
+ success &= test(
+ "test2Ac.equals(test2Bc)",
+ test2Ac.equals(test2Bc));
+ success &= test(
+ "UnoRuntime.areSame(test2Ac, test2Bc)",
+ UnoRuntime.areSame(test2Ac, test2Bc));
+
+ success &= test(
+ "!test2Ba.equals(null)",
+ !test2Ba.equals(null));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ba, null)",
+ !UnoRuntime.areSame(test2Ba, null));
+ success &= test(
+ "!test2Ba.equals(test1Aa)",
+ !test2Ba.equals(test1Aa));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ba, test1Aa)",
+ !UnoRuntime.areSame(test2Ba, test1Aa));
+ success &= test(
+ "!test2Ba.equals(test1Ab)",
+ !test2Ba.equals(test1Ab));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ba, test1Ab)",
+ !UnoRuntime.areSame(test2Ba, test1Ab));
+ success &= test(
+ "!test2Ba.equals(test1Ac)",
+ !test2Ba.equals(test1Ac));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ba, test1Ac)",
+ !UnoRuntime.areSame(test2Ba, test1Ac));
+ success &= test(
+ "!test2Ba.equals(test1Ba)",
+ !test2Ba.equals(test1Ba));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ba, test1Ba)",
+ !UnoRuntime.areSame(test2Ba, test1Ba));
+ success &= test(
+ "!test2Ba.equals(test1Bb)",
+ !test2Ba.equals(test1Bb));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ba, test1Bb)",
+ !UnoRuntime.areSame(test2Ba, test1Bb));
+ success &= test(
+ "!test2Ba.equals(test1Bc)",
+ !test2Ba.equals(test1Bc));
+ success &= test(
+ "!UnoRuntime.areSame(test2Ba, test1Bc)",
+ !UnoRuntime.areSame(test2Ba, test1Bc));
+ success &= test(
+ "test2Ba.equals(test2Aa)",
+ test2Ba.equals(test2Aa));
+ success &= test(
+ "UnoRuntime.areSame(test2Ba, test2Aa)",
+ UnoRuntime.areSame(test2Ba, test2Aa));
+ success &= test(
+ "test2Ba.equals(test2Ab)",
+ test2Ba.equals(test2Ab));
+ success &= test(
+ "UnoRuntime.areSame(test2Ba, test2Ab)",
+ UnoRuntime.areSame(test2Ba, test2Ab));
+ success &= test(
+ "test2Ba.equals(test2Ac)",
+ test2Ba.equals(test2Ac));
+ success &= test(
+ "UnoRuntime.areSame(test2Ba, test2Ac)",
+ UnoRuntime.areSame(test2Ba, test2Ac));
+ success &= test(
+ "test2Ba.equals(test2Ba)",
+ test2Ba.equals(test2Ba));
+ success &= test(
+ "UnoRuntime.areSame(test2Ba, test2Ba)",
+ UnoRuntime.areSame(test2Ba, test2Ba));
+ success &= test(
+ "test2Ba.equals(test2Bb)",
+ test2Ba.equals(test2Bb));
+ success &= test(
+ "UnoRuntime.areSame(test2Ba, test2Bb)",
+ UnoRuntime.areSame(test2Ba, test2Bb));
+ success &= test(
+ "test2Ba.equals(test2Bc)",
+ test2Ba.equals(test2Bc));
+ success &= test(
+ "UnoRuntime.areSame(test2Ba, test2Bc)",
+ UnoRuntime.areSame(test2Ba, test2Bc));
+
+ success &= test(
+ "!test2Bb.equals(null)",
+ !test2Bb.equals(null));
+ success &= test(
+ "!UnoRuntime.areSame(test2Bb, null)",
+ !UnoRuntime.areSame(test2Bb, null));
+ success &= test(
+ "!test2Bb.equals(test1Aa)",
+ !test2Bb.equals(test1Aa));
+ success &= test(
+ "!UnoRuntime.areSame(test2Bb, test1Aa)",
+ !UnoRuntime.areSame(test2Bb, test1Aa));
+ success &= test(
+ "!test2Bb.equals(test1Ab)",
+ !test2Bb.equals(test1Ab));
+ success &= test(
+ "!UnoRuntime.areSame(test2Bb, test1Ab)",
+ !UnoRuntime.areSame(test2Bb, test1Ab));
+ success &= test(
+ "!test2Bb.equals(test1Ac)",
+ !test2Bb.equals(test1Ac));
+ success &= test(
+ "!UnoRuntime.areSame(test2Bb, test1Ac)",
+ !UnoRuntime.areSame(test2Bb, test1Ac));
+ success &= test(
+ "!test2Bb.equals(test1Ba)",
+ !test2Bb.equals(test1Ba));
+ success &= test(
+ "!UnoRuntime.areSame(test2Bb, test1Ba)",
+ !UnoRuntime.areSame(test2Bb, test1Ba));
+ success &= test(
+ "!test2Bb.equals(test1Bb)",
+ !test2Bb.equals(test1Bb));
+ success &= test(
+ "!UnoRuntime.areSame(test2Bb, test1Bb)",
+ !UnoRuntime.areSame(test2Bb, test1Bb));
+ success &= test(
+ "!test2Bb.equals(test1Bc)",
+ !test2Bb.equals(test1Bc));
+ success &= test(
+ "!UnoRuntime.areSame(test2Bb, test1Bc)",
+ !UnoRuntime.areSame(test2Bb, test1Bc));
+ success &= test(
+ "test2Bb.equals(test2Aa)",
+ test2Bb.equals(test2Aa));
+ success &= test(
+ "UnoRuntime.areSame(test2Bb, test2Aa)",
+ UnoRuntime.areSame(test2Bb, test2Aa));
+ success &= test(
+ "test2Bb.equals(test2Ab)",
+ test2Bb.equals(test2Ab));
+ success &= test(
+ "UnoRuntime.areSame(test2Bb, test2Ab)",
+ UnoRuntime.areSame(test2Bb, test2Ab));
+ success &= test(
+ "test2Bb.equals(test2Ac)",
+ test2Bb.equals(test2Ac));
+ success &= test(
+ "UnoRuntime.areSame(test2Bb, test2Ac)",
+ UnoRuntime.areSame(test2Bb, test2Ac));
+ success &= test(
+ "test2Bb.equals(test2Ba)",
+ test2Bb.equals(test2Ba));
+ success &= test(
+ "UnoRuntime.areSame(test2Bb, test2Ba)",
+ UnoRuntime.areSame(test2Bb, test2Ba));
+ success &= test(
+ "test2Bb.equals(test2Bb)",
+ test2Bb.equals(test2Bb));
+ success &= test(
+ "UnoRuntime.areSame(test2Bb, test2Bb)",
+ UnoRuntime.areSame(test2Bb, test2Bb));
+ success &= test(
+ "test2Bb.equals(test2Bc)",
+ test2Bb.equals(test2Bc));
+ success &= test(
+ "UnoRuntime.areSame(test2Bb, test2Bc)",
+ UnoRuntime.areSame(test2Bb, test2Bc));
+
+ success &= test(
+ "!test2Bc.equals(null)",
+ !test2Bc.equals(null));
+ success &= test(
+ "!UnoRuntime.areSame(test2Bc, null)",
+ !UnoRuntime.areSame(test2Bc, null));
+ success &= test(
+ "!test2Bc.equals(test1Aa)",
+ !test2Bc.equals(test1Aa));
+ success &= test(
+ "!UnoRuntime.areSame(test2Bc, test1Aa)",
+ !UnoRuntime.areSame(test2Bc, test1Aa));
+ success &= test(
+ "!test2Bc.equals(test1Ab)",
+ !test2Bc.equals(test1Ab));
+ success &= test(
+ "!UnoRuntime.areSame(test2Bc, test1Ab)",
+ !UnoRuntime.areSame(test2Bc, test1Ab));
+ success &= test(
+ "!test2Bc.equals(test1Ac)",
+ !test2Bc.equals(test1Ac));
+ success &= test(
+ "!UnoRuntime.areSame(test2Bc, test1Ac)",
+ !UnoRuntime.areSame(test2Bc, test1Ac));
+ success &= test(
+ "!test2Bc.equals(test1Ba)",
+ !test2Bc.equals(test1Ba));
+ success &= test(
+ "!UnoRuntime.areSame(test2Bc, test1Ba)",
+ !UnoRuntime.areSame(test2Bc, test1Ba));
+ success &= test(
+ "!test2Bc.equals(test1Bb)",
+ !test2Bc.equals(test1Bb));
+ success &= test(
+ "!UnoRuntime.areSame(test2Bc, test1Bb)",
+ !UnoRuntime.areSame(test2Bc, test1Bb));
+ success &= test(
+ "!test2Bc.equals(test1Bc)",
+ !test2Bc.equals(test1Bc));
+ success &= test(
+ "!UnoRuntime.areSame(test2Bc, test1Bc)",
+ !UnoRuntime.areSame(test2Bc, test1Bc));
+ success &= test(
+ "test2Bc.equals(test2Aa)",
+ test2Bc.equals(test2Aa));
+ success &= test(
+ "UnoRuntime.areSame(test2Bc, test2Aa)",
+ UnoRuntime.areSame(test2Bc, test2Aa));
+ success &= test(
+ "test2Bc.equals(test2Ab)",
+ test2Bc.equals(test2Ab));
+ success &= test(
+ "UnoRuntime.areSame(test2Bc, test2Ab)",
+ UnoRuntime.areSame(test2Bc, test2Ab));
+ success &= test(
+ "test2Bc.equals(test2Ac)",
+ test2Bc.equals(test2Ac));
+ success &= test(
+ "UnoRuntime.areSame(test2Bc, test2Ac)",
+ UnoRuntime.areSame(test2Bc, test2Ac));
+ success &= test(
+ "test2Bc.equals(test2Ba)",
+ test2Bc.equals(test2Ba));
+ success &= test(
+ "UnoRuntime.areSame(test2Bc, test2Ba)",
+ UnoRuntime.areSame(test2Bc, test2Ba));
+ success &= test(
+ "test2Bc.equals(test2Bb)",
+ test2Bc.equals(test2Bb));
+ success &= test(
+ "UnoRuntime.areSame(test2Bc, test2Bb)",
+ UnoRuntime.areSame(test2Bc, test2Bb));
+ success &= test(
+ "test2Bc.equals(test2Bc)",
+ test2Bc.equals(test2Bc));
+ success &= test(
+ "UnoRuntime.areSame(test2Bc, test2Bc)",
+ UnoRuntime.areSame(test2Bc, test2Bc));
+
+ success &= test(
+ "test1Aa.hashCode() == test1Ab.hashCode()",
+ test1Aa.hashCode()
+ == test1Ab.hashCode());
+ success &= test(
+ "test1Aa.hashCode()"
+ + " == test1Ac.hashCode()",
+ test1Aa.hashCode()
+ == test1Ac.hashCode());
+ success &= test(
+ "test1Aa.hashCode()"
+ + " == test1Ba.hashCode()",
+ test1Aa.hashCode()
+ == test1Ba.hashCode());
+ success &= test(
+ "test1Aa.hashCode()"
+ + " == test1Bb.hashCode()",
+ test1Aa.hashCode()
+ == test1Bb.hashCode());
+ success &= test(
+ "test1Aa.hashCode()"
+ + " == test1Bc.hashCode()",
+ test1Aa.hashCode()
+ == test1Bc.hashCode());
+ success &= test(
+ "test2Aa.hashCode()"
+ + " == test2Ab.hashCode()",
+ test2Aa.hashCode()
+ == test2Ab.hashCode());
+ success &= test(
+ "test2Aa.hashCode()"
+ + " == test2Ac.hashCode()",
+ test2Aa.hashCode()
+ == test2Ac.hashCode());
+ success &= test(
+ "test2Aa.hashCode()"
+ + " == test2Ba.hashCode()",
+ test2Aa.hashCode()
+ == test2Ba.hashCode());
+ success &= test(
+ "test2Aa.hashCode()"
+ + " == test2Bb.hashCode()",
+ test2Aa.hashCode()
+ == test2Bb.hashCode());
+ success &= test(
+ "test2Aa.hashCode()"
+ + " == test2Bc.hashCode()",
+ test2Aa.hashCode()
+ == test2Bc.hashCode());
+
+ done.notifyDone();
+ testBed.serverDone(success);
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ }
+ };
+
+ private /*static*/ boolean test(
+ String message, boolean condition)
+ {
+ if (!condition) {
+ System.err.println("Failed: " + message);
+ }
+ return condition;
+ }
+ }.start();
+ }
+ };
+ }
+
+ private final TestBed testBed;
+ private final String unoTypes;
+ private final String unoServices;
+ }
+
+ public interface XDone extends XInterface {
+ void notifyDone();
+
+ TypeInfo[] UNOTYPEINFO = { new MethodTypeInfo("notifyDone", 0, 0) };
+ }
+
+ public interface XTestFrame extends XInterface {
+ void notifyAccepting(XDone done, Object object1, Object object2);
+
+ TypeInfo[] UNOTYPEINFO = {
+ new MethodTypeInfo("notifyAccepting", 0, TypeInfo.ONEWAY) };
+ }
+
+ // Use "127.0.0.1" instead of "localhost", see #i32281#:
+ private static final String CONNECTION_DESCRIPTION
+ = "socket,host=127.0.0.1,port=12346";
+ private static final String PROTOCOL_DESCRIPTION = "urp";
+
+ private static final String INSTANCE1 = "instance1";
+ private static final String INSTANCE2 = "instance2";
+}
diff --git a/bridges/test/java_uno/equals/makefile.mk b/bridges/test/java_uno/equals/makefile.mk
new file mode 100644
index 000000000000..9ac266f80ff5
--- /dev/null
+++ b/bridges/test/java_uno/equals/makefile.mk
@@ -0,0 +1,96 @@
+#*************************************************************************
+#
+# 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 = test_javauno_equals
+PACKAGE = test$/java_uno$/equals
+
+ENABLE_EXCEPTIONS = TRUE
+
+.INCLUDE: settings.mk
+
+# Make sure TestBed.class is found under $(CLASSDIR)$/test:
+.IF "$(XCLASSPATH)" == ""
+XCLASSPATH := $(CLASSDIR)$/test
+.ELSE
+XCLASSPATH !:= $(XCLASSPATH)$(PATH_SEPERATOR)$(CLASSDIR)$/test
+.ENDIF
+
+DLLPRE = # no leading "lib" on .so files
+INCPRE += $(MISC)$/$(TARGET)$/inc
+
+SLOFILES = $(SLO)$/testequals.obj
+
+SHL1TARGET = testequals.uno
+SHL1OBJS = $(SLOFILES)
+SHL1STDLIBS = $(CPPULIB) $(CPPUHELPERLIB) $(SALLIB)
+SHL1VERSIONMAP = $(SOLARENV)/src/component.map
+SHL1IMPLIB = itestequals
+
+JAVAFILES = TestEquals.java
+JARFILES = juh.jar jurt.jar ridl.jar
+
+.INCLUDE: target.mk
+
+ALLTAR: $(BIN)$/testequals
+
+.IF "$(GUI)" == "WNT"
+GIVE_EXEC_RIGHTS = @echo
+.ELSE # GUI, WNT
+GIVE_EXEC_RIGHTS = chmod +x
+.ENDIF # GUI, WNT
+
+EXEC_CLASSPATH_TMP = $(foreach,i,$(JARFILES) $(SOLARBINDIR)$/$i)
+EXEC_CLASSPATH = \
+ $(strip $(subst,!,$(PATH_SEPERATOR) $(EXEC_CLASSPATH_TMP:s/ /!/)))
+
+$(MISC)$/$(TARGET).rdb: types.idl
+ - rm $@
+ - $(MKDIR) $(MISC)$/$(TARGET)
+ - $(MKDIR) $(MISC)$/$(TARGET)$/inc
+ $(IDLC) -I$(SOLARIDLDIR) -O$(MISC)$/$(TARGET) $<
+ $(REGMERGE) $(MISC)$/$(TARGET).rdb /UCR $(MISC)$/$(TARGET)$/types.urd
+ $(CPPUMAKER) -BUCR -C -O$(MISC)$/$(TARGET)$/inc $@ -X$(SOLARBINDIR)$/types.rdb
+ $(JAVAMAKER) -BUCR -nD -O$(CLASSDIR) $@ -X$(SOLARBINDIR)$/types.rdb
+
+$(SLOFILES) $(JAVACLASSFILES): $(MISC)$/$(TARGET).rdb
+
+$(BIN)$/testequals: $(BIN)$/testequals_services.rdb
+ echo '$(AUGMENT_LIBRARY_PATH)' java -classpath \
+ ..$/class$/test$(PATH_SEPERATOR)..$/class$(PATH_SEPERATOR)\
+..$/class$/java_uno.jar$(PATH_SEPERATOR)$(EXEC_CLASSPATH) \
+ test.java_uno.equals.TestEquals $(SOLARBINDIR)$/types.rdb \
+ testequals_services.rdb > $@
+ $(GIVE_EXEC_RIGHTS) $@
+
+$(BIN)$/testequals_services.rdb:
+ - rm $@
+ $(REGCOMP) -register -r $@ -c bridgefac.uno
+ $(REGCOMP) -register -r $@ -c connector.uno
+ $(REGCOMP) -register -r $@ -c remotebridge.uno
diff --git a/bridges/test/java_uno/equals/testequals.cxx b/bridges/test/java_uno/equals/testequals.cxx
new file mode 100644
index 000000000000..ff38371bc6ca
--- /dev/null
+++ b/bridges/test/java_uno/equals/testequals.cxx
@@ -0,0 +1,235 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "com/sun/star/bridge/XBridge.hpp"
+#include "com/sun/star/bridge/XBridgeFactory.hpp"
+#include "com/sun/star/connection/Connector.hpp"
+#include "com/sun/star/connection/XConnection.hpp"
+#include "com/sun/star/connection/XConnector.hpp"
+#include "com/sun/star/lang/XMultiComponentFactory.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/lang/XSingleComponentFactory.hpp"
+#include "com/sun/star/registry/InvalidRegistryException.hpp"
+#include "com/sun/star/registry/XRegistryKey.hpp"
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/weak.hxx"
+#include "rtl/string.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "test/java_uno/equals/XBase.hpp"
+#include "test/java_uno/equals/XDerived.hpp"
+#include "test/java_uno/equals/XTestInterface.hpp"
+#include "uno/environment.h"
+#include "uno/lbnames.h"
+
+namespace css = com::sun::star;
+
+namespace {
+
+class Service: public cppu::WeakImplHelper2<
+ css::lang::XServiceInfo, test::java_uno::equals::XTestInterface >
+{
+public:
+ virtual inline rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException)
+ { return rtl::OUString::createFromAscii(getImplementationName_static()); }
+
+ virtual sal_Bool SAL_CALL supportsService(
+ rtl::OUString const & rServiceName) throw (css::uno::RuntimeException);
+
+ virtual inline css::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException)
+ { return getSupportedServiceNames_static(); }
+
+ virtual void SAL_CALL connect(rtl::OUString const & rConnection,
+ rtl::OUString const & rProtocol)
+ throw (css::uno::Exception);
+
+ virtual css::uno::Reference< css::uno::XInterface > SAL_CALL get(
+ rtl::OUString const & rName) throw (css::uno::RuntimeException);
+
+ static inline sal_Char const * getImplementationName_static()
+ { return "com.sun.star.test.bridges.testequals.impl"; }
+
+ static css::uno::Sequence< rtl::OUString >
+ getSupportedServiceNames_static();
+
+ static css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance(
+ css::uno::Reference< css::uno::XComponentContext > const & rContext)
+ throw (css::uno::Exception);
+
+private:
+ explicit inline Service(
+ css::uno::Reference< css::uno::XComponentContext > const & rContext):
+ m_xContext(rContext) {}
+
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ css::uno::Reference< css::bridge::XBridge > m_xBridge;
+};
+
+}
+
+sal_Bool Service::supportsService(rtl::OUString const & rServiceName)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Sequence< rtl::OUString > aNames(
+ getSupportedServiceNames_static());
+ for (sal_Int32 i = 0; i< aNames.getLength(); ++i)
+ if (aNames[i] == rServiceName)
+ return true;
+ return false;
+}
+
+void Service::connect(rtl::OUString const & rConnection,
+ rtl::OUString const & rProtocol)
+ throw (css::uno::Exception)
+{
+ css::uno::Reference< css::connection::XConnection > xConnection(
+ css::connection::Connector::create(m_xContext)->connect(rConnection));
+ css::uno::Reference< css::bridge::XBridgeFactory > xBridgeFactory(
+ m_xContext->getServiceManager()->createInstanceWithContext(
+ rtl::OUString::createFromAscii("com.sun.star.bridge.BridgeFactory"),
+ m_xContext),
+ css::uno::UNO_QUERY);
+ m_xBridge = xBridgeFactory->createBridge(rtl::OUString(), rProtocol,
+ xConnection, 0);
+}
+
+css::uno::Reference< css::uno::XInterface >
+Service::get(rtl::OUString const & rName) throw (css::uno::RuntimeException)
+{
+ return m_xBridge->getInstance(rName);
+}
+
+css::uno::Sequence< rtl::OUString > Service::getSupportedServiceNames_static()
+{
+ css::uno::Sequence< rtl::OUString > aNames(1);
+ aNames[0] = rtl::OUString::createFromAscii(
+ "com.sun.star.test.bridges.testequals");
+ return aNames;
+}
+
+css::uno::Reference< css::uno::XInterface > Service::createInstance(
+ css::uno::Reference< css::uno::XComponentContext > const & rContext)
+ throw (css::uno::Exception)
+{
+ // Make types known:
+ getCppuType(
+ static_cast<
+ css::uno::Reference< test::java_uno::equals::XBase > const * >(0));
+ getCppuType(
+ static_cast<
+ css::uno::Reference< test::java_uno::equals::XDerived > const * >(0));
+ getCppuType(
+ static_cast<
+ css::uno::Reference< test::java_uno::equals::XTestInterface > const * >(
+ 0));
+
+ return static_cast< cppu::OWeakObject * >(new Service(rContext));
+}
+
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ sal_Char const ** pEnvTypeName, uno_Environment **)
+{
+ *pEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+extern "C" void * SAL_CALL component_getFactory(sal_Char const * pImplName,
+ void * pServiceManager, void *)
+{
+ void * pFactory = 0;
+ if (pServiceManager)
+ if (rtl_str_compare(pImplName, Service::getImplementationName_static())
+ == 0)
+ {
+ css::uno::Reference< css::lang::XSingleComponentFactory >
+ xFactory(cppu::createSingleComponentFactory(
+ &Service::createInstance,
+ rtl::OUString::createFromAscii(
+ Service::getImplementationName_static()),
+ Service::getSupportedServiceNames_static()));
+ if (xFactory.is())
+ {
+ xFactory->acquire();
+ pFactory = xFactory.get();
+ }
+ }
+ return pFactory;
+}
+
+namespace {
+
+bool writeInfo(void * pRegistryKey, sal_Char const * pImplementationName,
+ css::uno::Sequence< rtl::OUString > const & rServiceNames)
+{
+ rtl::OUString aKeyName(rtl::OUString::createFromAscii("/"));
+ aKeyName += rtl::OUString::createFromAscii(pImplementationName);
+ aKeyName += rtl::OUString::createFromAscii("/UNO/SERVICES");
+ css::uno::Reference< css::registry::XRegistryKey > xKey;
+ try
+ {
+ xKey = static_cast< css::registry::XRegistryKey * >(pRegistryKey)->
+ createKey(aKeyName);
+ }
+ catch (css::registry::InvalidRegistryException &) {}
+ if (!xKey.is())
+ return false;
+ bool bSuccess = true;
+ for (sal_Int32 i = 0; i < rServiceNames.getLength(); ++i)
+ try
+ {
+ xKey->createKey(rServiceNames[i]);
+ }
+ catch (css::registry::InvalidRegistryException &)
+ {
+ bSuccess = false;
+ break;
+ }
+ return bSuccess;
+}
+
+}
+
+extern "C" sal_Bool SAL_CALL component_writeInfo(void *, void * pRegistryKey)
+{
+ return pRegistryKey
+ && writeInfo(pRegistryKey, Service::getImplementationName_static(),
+ Service::getSupportedServiceNames_static());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/test/java_uno/equals/types.idl b/bridges/test/java_uno/equals/types.idl
new file mode 100644
index 000000000000..c8ddc2f072fe
--- /dev/null
+++ b/bridges/test/java_uno/equals/types.idl
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * 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 "com/sun/star/uno/Exception.idl"
+#include "com/sun/star/uno/XInterface.idl"
+
+// UNO interfaces used between Java and native (C++) environments.
+
+module test { module java_uno { module equals {
+
+interface XBase: com::sun::star::uno::XInterface {};
+
+interface XDerived: XBase {};
+
+interface XTestInterface: com::sun::star::uno::XInterface
+{
+ void connect([in] string connection, [in] string protocol)
+ raises (com::sun::star::uno::Exception);
+
+ com::sun::star::uno::XInterface get([in] string name);
+};
+
+}; }; };
diff --git a/bridges/test/java_uno/nativethreadpool/Relay.java b/bridges/test/java_uno/nativethreadpool/Relay.java
new file mode 100644
index 000000000000..50e198a2d819
--- /dev/null
+++ b/bridges/test/java_uno/nativethreadpool/Relay.java
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package test.javauno.nativethreadpool;
+
+import com.sun.star.bridge.BridgeExistsException;
+import com.sun.star.bridge.XBridgeFactory;
+import com.sun.star.bridge.XInstanceProvider;
+import com.sun.star.comp.helper.Bootstrap;
+import com.sun.star.comp.loader.FactoryHelper;
+import com.sun.star.connection.AlreadyAcceptingException;
+import com.sun.star.connection.ConnectionSetupException;
+import com.sun.star.connection.Acceptor;
+import com.sun.star.connection.XAcceptor;
+import com.sun.star.connection.XConnection;
+import com.sun.star.lang.WrappedTargetRuntimeException;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XSingleServiceFactory;
+import com.sun.star.registry.XRegistryKey;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XComponentContext;
+
+public final class Relay implements XRelay, XSource {
+ public void start(XSource source) {
+ this.source = source;
+ XComponentContext context;
+ try {
+ context = Bootstrap.createInitialComponentContext(null);
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (com.sun.star.uno.Exception e) {
+ throw new WrappedTargetRuntimeException(e.toString(), this, e);
+ } catch (Exception e) {
+ throw new com.sun.star.uno.RuntimeException(e.toString(), this);
+ }
+ final XAcceptor acceptor = Acceptor.create(context);
+ final XBridgeFactory factory;
+ try {
+ factory = UnoRuntime.queryInterface(
+ XBridgeFactory.class,
+ context.getServiceManager().createInstanceWithContext(
+ "com.sun.star.bridge.BridgeFactory", context));
+ } catch (com.sun.star.uno.Exception e) {
+ throw new WrappedTargetRuntimeException(e.toString(), this, e);
+ }
+ new Thread() {
+ public void run() {
+ try {
+ // Use "127.0.0.1" instead of "localhost", see #i32281#:
+ factory.createBridge(
+ "", "urp",
+ acceptor.accept("socket,host=127.0.0.1,port=3831"),
+ new XInstanceProvider() {
+ public Object getInstance(String instanceName) {
+ return Relay.this;
+ }
+ });
+ } catch (AlreadyAcceptingException e) {
+ e.printStackTrace(System.err);
+ } catch (ConnectionSetupException e) {
+ e.printStackTrace(System.err);
+ } catch (BridgeExistsException e) {
+ e.printStackTrace(System.err);
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ e.printStackTrace(System.err);
+ }
+ }
+ }.start();
+ try {
+ Thread.sleep(3000); // wait for new thread to accept connection
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new com.sun.star.uno.RuntimeException(e.toString(), this);
+ }
+ }
+
+ public int get() {
+ return source.get();
+ }
+
+ public static XSingleServiceFactory __getServiceFactory(
+ String implName, XMultiServiceFactory multiFactory, XRegistryKey regKey)
+ {
+ return implName.equals(implementationName)
+ ? FactoryHelper.getServiceFactory(
+ Relay.class, serviceName, multiFactory, regKey)
+ : null;
+ }
+
+ public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) {
+ return FactoryHelper.writeRegistryServiceInfo(
+ implementationName, serviceName, regKey);
+ }
+
+ private static final String implementationName
+ = "test.javauno.nativethreadpool.comp.Relay";
+ private static final String serviceName
+ = "test.javauno.nativethreadpool.Relay";
+
+ private XSource source;
+}
diff --git a/bridges/test/java_uno/nativethreadpool/makefile.mk b/bridges/test/java_uno/nativethreadpool/makefile.mk
new file mode 100644
index 000000000000..d4926e07307b
--- /dev/null
+++ b/bridges/test/java_uno/nativethreadpool/makefile.mk
@@ -0,0 +1,121 @@
+#*************************************************************************
+#
+# 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 := test_javauno_nativethreadpool
+PACKAGE := test$/javauno$/nativethreadpool
+
+ENABLE_EXCEPTIONS := TRUE
+
+#TODO:
+.IF "$(OS)" == "LINUX"
+JVM_LIB_URL := file:///net/grande.germany/develop6/update/dev/Linux_JDK_1.4.1_03/jre/lib/i386/client/libjvm.so
+.ELSE
+ERROR -- missing platform
+.ENDIF
+
+.INCLUDE: settings.mk
+
+DLLPRE = # no leading "lib" on .so files
+INCPRE += $(MISC)$/$(TARGET)$/inc
+
+SHL1TARGET = $(TARGET)_client.uno
+SHL1OBJS = $(SLO)$/testnativethreadpoolclient.obj
+SHL1STDLIBS = $(CPPULIB) $(CPPUHELPERLIB) $(SALLIB)
+SHL1VERSIONMAP = version.map
+SHL1IMPLIB = i$(TARGET)_client
+
+SHL2TARGET = $(TARGET)_server.uno
+SHL2OBJS = $(SLO)$/testnativethreadpoolserver.obj
+SHL2STDLIBS = $(CPPULIB) $(CPPUHELPERLIB) $(SALLIB)
+SHL2VERSIONMAP = version.map
+SHL2IMPLIB = i$(TARGET)_server
+
+SLOFILES = $(SHL1OBJS) $(SHL2OBJS)
+
+JAVAFILES = Relay.java
+JARFILES = java_uno.jar juh.jar jurt.jar ridl.jar
+
+.INCLUDE: target.mk
+
+ALLTAR: test
+
+EXEC_CLASSPATH_TMP = $(foreach,i,$(JARFILES) $(SOLARBINDIR)$/$i)
+EXEC_CLASSPATH = \
+ $(strip $(subst,!,$(PATH_SEPERATOR) $(EXEC_CLASSPATH_TMP:s/ /!/)))
+
+$(MISC)$/$(TARGET)$/types.rdb: types.idl
+ - rm $@
+ - $(MKDIR) $(MISC)$/$(TARGET)
+ - $(MKDIR) $(MISC)$/$(TARGET)$/inc
+ $(IDLC) -I$(SOLARIDLDIR) -O$(MISC)$/$(TARGET) $<
+ $(REGMERGE) $@ /UCR $(MISC)$/$(TARGET)$/types.urd
+ $(CPPUMAKER) -BUCR -C -O$(MISC)$/$(TARGET)$/inc $@ -X$(SOLARBINDIR)$/types.rdb
+ $(JAVAMAKER) -BUCR -nD -O$(CLASSDIR) $@ -X$(SOLARBINDIR)$/types.rdb
+
+$(SLOFILES) $(JAVACLASSFILES): $(MISC)$/$(TARGET)$/types.rdb
+
+$(BIN)$/$(TARGET).uno.jar: $(JAVACLASSFILES) relay.manifest
+ jar cfm $@ relay.manifest -C $(CLASSDIR) test/javauno/nativethreadpool
+
+$(BIN)$/$(TARGET).rdb .ERRREMOVE: $(MISC)$/$(TARGET)$/types.rdb \
+ $(BIN)$/$(TARGET).uno.jar
+ cp $(MISC)$/$(TARGET)$/types.rdb $@
+ $(REGMERGE) $@ / $(SOLARBINDIR)$/types.rdb
+ $(REGCOMP) -register -r $@ -c acceptor.uno$(DLLPOST) \
+ -c bridgefac.uno$(DLLPOST) -c connector.uno$(DLLPOST) \
+ -c remotebridge.uno$(DLLPOST) -c uuresolver.uno$(DLLPOST) \
+ -c javaloader.uno$(DLLPOST) -c javavm.uno$(DLLPOST) \
+ -c stocservices.uno$(DLLPOST)
+ cp $(SOLARBINDIR)$/types.rdb $(MISC)$/$(TARGET)$/bootstrap.rdb
+ $(REGCOMP) -register -r $(MISC)$/$(TARGET)$/bootstrap.rdb \
+ -c javaloader.uno$(DLLPOST) -c javavm.uno$(DLLPOST) \
+ -c stocservices.uno$(DLLPOST)
+.IF "$(GUI)" == "WNT"
+ ERROR -- missing platform
+.ELSE # GUI, WNT
+ + export OO_JAVA_PROPERTIES='RuntimeLib=$(JVM_LIB_URL)' && \
+ $(REGCOMP) -register -r $@ -c file://$(PWD)/$(BIN)$/$(TARGET).uno.jar \
+ -br $(MISC)$/$(TARGET)$/bootstrap.rdb -classpath $(EXEC_CLASSPATH) \
+ -env:URE_INTERNAL_JAVA_DIR=file://$(SOLARBINDIR)
+.ENDIF # GUI, WNT
+
+test .PHONY: $(SHL1TARGETN) $(BIN)$/$(TARGET).uno.jar $(BIN)$/$(TARGET).rdb
+.IF "$(GUI)" == "WNT"
+ ERROR -- missing platform
+.ELSE # GUI, WNT
+ $(AUGMENT_LIBRARY_PATH) uno -c test.javauno.nativethreadpool.server \
+ -l $(SHL2TARGETN) -ro $(BIN)$/$(TARGET).rdb \
+ -u 'uno:socket,host=localhost,port=3830;urp;test' --singleaccept &
+ + $(AUGMENT_LIBRARY_PATH) OO_JAVA_PROPERTIES='RuntimeLib=$(JVM_LIB_URL)' \
+ CLASSPATH=$(EXEC_CLASSPATH)$(PATH_SEPERATOR)$(BIN)$/$(TARGET).uno.jar \
+ uno -c test.javauno.nativethreadpool.client -l $(SHL1TARGETN) \
+ -ro $(BIN)$/$(TARGET).rdb \
+ -env:URE_INTERNAL_JAVA_DIR=file://$(SOLARBINDIR)
+.ENDIF # GUI, WNT
diff --git a/bridges/test/java_uno/nativethreadpool/readme b/bridges/test/java_uno/nativethreadpool/readme
new file mode 100644
index 000000000000..c137ed162372
--- /dev/null
+++ b/bridges/test/java_uno/nativethreadpool/readme
@@ -0,0 +1,39 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+Test that a Java URP bridge started in a native process uses the same thread
+pool as a C++ URP bridge. This test currently only works on Linux Intel.
+
+There are two processes involved. The client starts as a native process. It
+first loads a Java component (Relay) via the in-process JNI bridge, which in
+turn starts to accept incomming URP connections. The native part of the client
+then connects to the server, retrieves a thread-local token from it, and checks
+the token for correctness. The server simply waits for a connection from the
+native part of the client, creates a connection to the Java part of the client,
+and routes all requests from the native part of the client to the Java part of
+the client. The Java part of the client in turn uses the in-process JNI bridge
+to obtain the thread-local token.
diff --git a/bridges/test/java_uno/nativethreadpool/relay.manifest b/bridges/test/java_uno/nativethreadpool/relay.manifest
new file mode 100644
index 000000000000..6cd1d9dbd611
--- /dev/null
+++ b/bridges/test/java_uno/nativethreadpool/relay.manifest
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+RegistrationClassName: test.javauno.nativethreadpool.Relay
diff --git a/bridges/test/java_uno/nativethreadpool/testnativethreadpoolclient.cxx b/bridges/test/java_uno/nativethreadpool/testnativethreadpoolclient.cxx
new file mode 100644
index 000000000000..425b93a271e4
--- /dev/null
+++ b/bridges/test/java_uno/nativethreadpool/testnativethreadpoolclient.cxx
@@ -0,0 +1,187 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "test/javauno/nativethreadpool/XRelay.hpp"
+#include "test/javauno/nativethreadpool/XSource.hpp"
+
+#include "com/sun/star/bridge/UnoUrlResolver.hpp"
+#include "com/sun/star/bridge/XUnoUrlResolver.hpp"
+#include "com/sun/star/connection/ConnectionSetupException.hpp"
+#include "com/sun/star/connection/NoConnectException.hpp"
+#include "com/sun/star/lang/IllegalArgumentException.hpp"
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/lang/XMain.hpp"
+#include "com/sun/star/lang/XMultiComponentFactory.hpp"
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "cppuhelper/weak.hxx"
+#include "osl/thread.hxx"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "uno/lbnames.h"
+
+#include <iostream>
+
+namespace css = com::sun::star;
+
+namespace {
+
+class Client: public cppu::WeakImplHelper2<
+ css::lang::XMain, test::javauno::nativethreadpool::XSource >
+{
+public:
+ explicit Client(
+ css::uno::Reference< css::uno::XComponentContext > const & theContext):
+ context(theContext) {}
+
+private:
+ virtual ~Client() {}
+
+ virtual sal_Int32 SAL_CALL run(css::uno::Sequence< rtl::OUString > const &)
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL get() throw (css::uno::RuntimeException);
+
+ css::uno::Reference< css::uno::XComponentContext > context;
+ osl::ThreadData data;
+};
+
+sal_Int32 Client::run(css::uno::Sequence< rtl::OUString > const &)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Reference< css::lang::XMultiComponentFactory > factory(
+ context->getServiceManager());
+ if (!factory.is()) {
+ throw new css::uno::RuntimeException(
+ rtl::OUString::createFromAscii(
+ "no component context service manager"),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ css::uno::Reference< test::javauno::nativethreadpool::XRelay > relay;
+ try {
+ relay = css::uno::Reference< test::javauno::nativethreadpool::XRelay >(
+ factory->createInstanceWithContext(
+ rtl::OUString::createFromAscii(
+ "test.javauno.nativethreadpool.Relay"),
+ context),
+ css::uno::UNO_QUERY_THROW);
+ } catch (css::uno::RuntimeException &) {
+ throw;
+ } catch (css::uno::Exception & e) {
+ throw css::lang::WrappedTargetRuntimeException(
+ rtl::OUString::createFromAscii(
+ "creating test.javauno.nativethreadpool.Relay service"),
+ static_cast< cppu::OWeakObject * >(this), css::uno::makeAny(e));
+ }
+ relay->start(this);
+ if (!data.setData(reinterpret_cast< void * >(12345))) {
+ throw new css::uno::RuntimeException(
+ rtl::OUString::createFromAscii("osl::ThreadData::setData failed"),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ css::uno::Reference< test::javauno::nativethreadpool::XSource > source;
+ try {
+ source
+ = css::uno::Reference< test::javauno::nativethreadpool::XSource >(
+ css::bridge::UnoUrlResolver::create(context)->resolve(
+ rtl::OUString::createFromAscii(
+ "uno:socket,host=localhost,port=3830;urp;test")),
+ css::uno::UNO_QUERY_THROW);
+ } catch (css::connection::NoConnectException & e) {
+ throw css::lang::WrappedTargetRuntimeException(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.uno.UnoUrlResolver.resolve"),
+ static_cast< cppu::OWeakObject * >(this), css::uno::makeAny(e));
+ } catch (css::connection::ConnectionSetupException & e) {
+ throw css::lang::WrappedTargetRuntimeException(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.uno.UnoUrlResolver.resolve"),
+ static_cast< cppu::OWeakObject * >(this), css::uno::makeAny(e));
+ } catch (css::lang::IllegalArgumentException & e) {
+ throw css::lang::WrappedTargetRuntimeException(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.uno.UnoUrlResolver.resolve"),
+ static_cast< cppu::OWeakObject * >(this), css::uno::makeAny(e));
+ }
+ bool success = source->get() == 12345;
+ std::cout << "success? " << (success ? "yes" : "no") << '\n';
+ return success ? 0 : 1;
+}
+
+sal_Int32 Client::get() throw (css::uno::RuntimeException) {
+ return reinterpret_cast< sal_Int32 >(data.getData());
+}
+
+css::uno::Reference< css::uno::XInterface > SAL_CALL create(
+ css::uno::Reference< css::uno::XComponentContext > const & context)
+ SAL_THROW((css::uno::Exception))
+{
+ return static_cast< cppu::OWeakObject * >(new Client(context));
+}
+
+rtl::OUString SAL_CALL getImplementationName() {
+ return rtl::OUString::createFromAscii(
+ "test.javauno.nativethreadpool.client");
+}
+
+css::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames() {
+ return css::uno::Sequence< rtl::OUString >();
+}
+
+cppu::ImplementationEntry entries[] = {
+ { &create, &getImplementationName, &getSupportedServiceNames,
+ &cppu::createSingleComponentFactory, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+}
+
+extern "C" void * SAL_CALL component_getFactory(
+ char const * implName, void * serviceManager, void * registryKey)
+{
+ return cppu::component_getFactoryHelper(
+ implName, serviceManager, registryKey, entries);
+}
+
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ char const ** envTypeName, uno_Environment **)
+{
+ *envTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/test/java_uno/nativethreadpool/testnativethreadpoolserver.cxx b/bridges/test/java_uno/nativethreadpool/testnativethreadpoolserver.cxx
new file mode 100644
index 000000000000..c055faa1aa29
--- /dev/null
+++ b/bridges/test/java_uno/nativethreadpool/testnativethreadpoolserver.cxx
@@ -0,0 +1,149 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include "test/javauno/nativethreadpool/XSource.hpp"
+
+#include "com/sun/star/bridge/UnoUrlResolver.hpp"
+#include "com/sun/star/bridge/XUnoUrlResolver.hpp"
+#include "com/sun/star/connection/ConnectionSetupException.hpp"
+#include "com/sun/star/connection/NoConnectException.hpp"
+#include "com/sun/star/lang/IllegalArgumentException.hpp"
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/lang/XMultiComponentFactory.hpp"
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "cppuhelper/weak.hxx"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+#include "uno/lbnames.h"
+
+namespace css = com::sun::star;
+
+namespace {
+
+class Server:
+ public cppu::WeakImplHelper1< test::javauno::nativethreadpool::XSource >
+{
+public:
+ explicit Server(
+ css::uno::Reference< css::uno::XComponentContext > const & theContext):
+ context(theContext) {}
+
+private:
+ virtual ~Server() {}
+
+ virtual sal_Int32 SAL_CALL get() throw (css::uno::RuntimeException);
+
+ css::uno::Reference< css::uno::XComponentContext > context;
+};
+
+sal_Int32 Server::get() throw (css::uno::RuntimeException) {
+ css::uno::Reference< css::lang::XMultiComponentFactory > factory(
+ context->getServiceManager());
+ if (!factory.is()) {
+ throw new css::uno::RuntimeException(
+ rtl::OUString::createFromAscii(
+ "no component context service manager"),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ css::uno::Reference< test::javauno::nativethreadpool::XSource > source;
+ try {
+ // Use "127.0.0.1" instead of "localhost", see #i32281#:
+ source
+ = css::uno::Reference< test::javauno::nativethreadpool::XSource >(
+ css::bridge::UnoUrlResolver::create(context)->resolve(
+ rtl::OUString::createFromAscii(
+ "uno:socket,host=127.0.0.1,port=3831;urp;test")),
+ css::uno::UNO_QUERY_THROW);
+ } catch (css::connection::NoConnectException & e) {
+ throw css::lang::WrappedTargetRuntimeException(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.uno.UnoUrlResolver.resolve"),
+ static_cast< cppu::OWeakObject * >(this), css::uno::makeAny(e));
+ } catch (css::connection::ConnectionSetupException & e) {
+ throw css::lang::WrappedTargetRuntimeException(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.uno.UnoUrlResolver.resolve"),
+ static_cast< cppu::OWeakObject * >(this), css::uno::makeAny(e));
+ } catch (css::lang::IllegalArgumentException & e) {
+ throw css::lang::WrappedTargetRuntimeException(
+ rtl::OUString::createFromAscii(
+ "com.sun.star.uno.UnoUrlResolver.resolve"),
+ static_cast< cppu::OWeakObject * >(this), css::uno::makeAny(e));
+ }
+ return source->get();
+}
+
+css::uno::Reference< css::uno::XInterface > SAL_CALL create(
+ css::uno::Reference< css::uno::XComponentContext > const & context)
+ SAL_THROW((css::uno::Exception))
+{
+ return static_cast< cppu::OWeakObject * >(new Server(context));
+}
+
+rtl::OUString SAL_CALL getImplementationName() {
+ return rtl::OUString::createFromAscii(
+ "test.javauno.nativethreadpool.server");
+}
+
+css::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames() {
+ return css::uno::Sequence< rtl::OUString >();
+}
+
+cppu::ImplementationEntry entries[] = {
+ { &create, &getImplementationName, &getSupportedServiceNames,
+ &cppu::createSingleComponentFactory, 0, 0 },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+}
+
+extern "C" void * SAL_CALL component_getFactory(
+ char const * implName, void * serviceManager, void * registryKey)
+{
+ return cppu::component_getFactoryHelper(
+ implName, serviceManager, registryKey, entries);
+}
+
+extern "C" void SAL_CALL component_getImplementationEnvironment(
+ char const ** envTypeName, uno_Environment **)
+{
+ *envTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/test/java_uno/nativethreadpool/types.idl b/bridges/test/java_uno/nativethreadpool/types.idl
new file mode 100644
index 000000000000..36ca44af37e0
--- /dev/null
+++ b/bridges/test/java_uno/nativethreadpool/types.idl
@@ -0,0 +1,40 @@
+/*************************************************************************
+ *
+ * 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 "com/sun/star/uno/XInterface.idl"
+
+module test { module javauno { module nativethreadpool {
+
+interface XSource: com::sun::star::uno::XInterface {
+ long get();
+};
+
+interface XRelay: com::sun::star::uno::XInterface {
+ void start([in] XSource source);
+};
+
+}; }; };
diff --git a/bridges/test/java_uno/nativethreadpool/version.map b/bridges/test/java_uno/nativethreadpool/version.map
new file mode 100644
index 000000000000..b560ad15b99f
--- /dev/null
+++ b/bridges/test/java_uno/nativethreadpool/version.map
@@ -0,0 +1,35 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+UDK_3_0_0 {
+ global:
+ component_getFactory;
+ component_getImplementationEnvironment;
+
+ local:
+ *;
+};
diff --git a/bridges/test/makefile.mk b/bridges/test/makefile.mk
new file mode 100644
index 000000000000..1c8c6f8cf10d
--- /dev/null
+++ b/bridges/test/makefile.mk
@@ -0,0 +1,175 @@
+#*************************************************************************
+#
+# 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=test
+LIBTARGET=NO
+TARGETTYPE=CUI
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+ALLIDLFILES = test_bridge.idl
+CPPUMAKERFLAGS += -C
+
+
+UNOUCRDEP=$(SOLARBINDIR)$/udkapi.rdb $(BIN)$/test.rdb
+UNOUCRRDB=$(SOLARBINDIR)$/udkapi.rdb $(BIN)$/test.rdb
+
+# output directory (one dir for each project)
+UNOUCROUT=$(OUT)$/inc
+
+# adding to inludeoath
+INCPRE+=$(UNOUCROUT)
+CFLAGS += -I..$/source$/remote$/urp
+
+UNOTYPES = \
+ com.sun.star.uno.XWeak\
+ com.sun.star.uno.XNamingService\
+ com.sun.star.uno.XAggregation \
+ com.sun.star.uno.TypeClass\
+ com.sun.star.io.XInputStream\
+ com.sun.star.io.XOutputStream\
+ com.sun.star.lang.XInitialization \
+ com.sun.star.lang.XSingleServiceFactory \
+ com.sun.star.lang.XMultiServiceFactory \
+ com.sun.star.lang.XTypeProvider \
+ com.sun.star.registry.XSimpleRegistry \
+ com.sun.star.loader.XImplementationLoader \
+ com.sun.star.registry.XImplementationRegistration \
+ com.sun.star.corba.giop.TargetAddress \
+ com.sun.star.corba.giop.TargetAddressGroup \
+ com.sun.star.lang.XComponent \
+ com.sun.star.bridge.XBridgeFactory\
+ com.sun.star.connection.XAcceptor\
+ com.sun.star.connection.XConnector\
+ com.sun.star.beans.Property\
+ com.sun.star.corba.giop.RequestHeader_1_2\
+ com.sun.star.container.XSet\
+ com.sun.star.lang.XServiceInfo\
+ test.XTestFactory \
+ com.sun.star.test.performance.XPerformanceTest \
+ com.sun.star.lang.XMain \
+ com.sun.star.lang.XMultiComponentFactory \
+ com.sun.star.lang.XSingleComponentFactory
+
+JARFILES = jurt.jar unoil.jar
+
+OBJFILES= \
+ $(OBJ)$/testserver.obj \
+ $(OBJ)$/testclient.obj \
+ $(OBJ)$/testcomp.obj \
+ $(OBJ)$/testsameprocess.obj
+
+
+APP2TARGET= testserver
+APP2OBJS= $(OBJ)$/testserver.obj \
+ $(OBJ)$/testcomp.obj
+
+.IF "$(OS)" == "LINUX"
+APP2STDLIBS+= -lstdc++
+.ENDIF
+
+APP2STDLIBS+= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB)
+
+APP3TARGET= testclient
+APP3OBJS= $(OBJ)$/testclient.obj \
+ $(OBJ)$/testcomp.obj
+
+.IF "$(OS)" == "LINUX"
+APP3STDLIBS+= -lstdc++
+.ENDIF
+
+APP3STDLIBS+= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB)
+
+#----------------------------------
+
+APP4TARGET= testsameprocess
+APP4OBJS= $(OBJ)$/testsameprocess.obj \
+ $(OBJ)$/testcomp.obj
+
+.IF "$(OS)" == "LINUX"
+APP4STDLIBS+= -lstdc++
+.ENDIF
+
+APP4STDLIBS+= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB)
+
+APP4DEF= $(MISC)$/$(APP4TARGET).def
+
+#----------------------------------
+
+# APP5TARGET= testoffice
+# APP5OBJS= $(OBJ)$/testoffice.obj \
+# $(OBJ)$/testcomp.obj
+
+# .IF "$(OS)" == "LINUX"
+# APP5STDLIBS+= -lstdc++
+# .ENDIF
+
+# APP5STDLIBS+= \
+# $(CPPULIB) \
+# $(CPPUHELPERLIB)\
+# $(SALLIB)
+
+# APP5DEF= $(MISC)$/$(APP5TARGET).def
+
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+ALLTAR : $(BIN)$/test.rdb \
+ $(BIN)$/server.rdb \
+ $(BIN)$/client.rdb
+
+$(BIN)$/test.rdb: $(ALLIDLFILES)
+ $(IDLC) -I$(PRJ) -I$(SOLARIDLDIR) -O$(BIN) $?
+ $(REGMERGE) $@ /UCR $(BIN)$/{$(?:f:s/.idl/.urd/)}
+ touch $@
+
+$(BIN)$/client.rdb: $(BIN)$/test.rdb
+ rm -f $(BIN)$/client.rdb
+ $(REGMERGE) $@ / $(BIN)$/test.rdb $(SOLARBINDIR)$/udkapi.rdb
+
+$(BIN)$/server.rdb: $(BIN)$/test.rdb
+ rm -f $(BIN)$/client.rdb
+ $(REGMERGE) $@ / $(BIN)$/test.rdb $(SOLARBINDIR)$/udkapi.rdb
+
diff --git a/bridges/test/performance/makefile.mk b/bridges/test/performance/makefile.mk
new file mode 100644
index 000000000000..44f7ae3d4414
--- /dev/null
+++ b/bridges/test/performance/makefile.mk
@@ -0,0 +1,61 @@
+#*************************************************************************
+#
+# 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=test
+LIBTARGET=NO
+TARGETTYPE=CUI
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# --- Files --------------------------------------------------------
+
+OBJFILES= $(OBJ)$/testperformance.obj
+
+#----------------------------------
+
+APP1TARGET= testperformance
+APP1OBJS= $(OBJ)$/testperformance.obj
+
+.IF "$(OS)" == "LINUX"
+APP1STDLIBS+= -lstdc++
+.ENDIF
+
+APP1STDLIBS+= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB)
+
+APP1DEF= $(MISC)$/$(APP1TARGET).def
+
+.INCLUDE : target.mk
+
diff --git a/bridges/test/performance/testperformance.cxx b/bridges/test/performance/testperformance.cxx
new file mode 100644
index 000000000000..d692144a3f37
--- /dev/null
+++ b/bridges/test/performance/testperformance.cxx
@@ -0,0 +1,193 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+
+#include <stdio.h>
+#include <math.h>
+
+#include <osl/interlck.h>
+#include <osl/mutex.hxx>
+#include <osl/semaphor.h>
+
+#include <rtl/string.hxx>
+#include <rtl/byteseq.hxx>
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+#ifdef SAL_W32
+#include <windows.h>
+#else
+#include <sys/times.h>
+#endif
+#ifndef ULONG_MAX
+#define ULONG_MAX 0xffffffff
+#endif
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+
+static inline sal_uInt32 getSystemTicks()
+{
+#ifdef SAL_W32
+ return (sal_uInt32)GetTickCount();
+#else // only UNX supported for now
+ static sal_uInt32 nImplTicksPerSecond = 0;
+ static double dImplTicksPerSecond;
+ static double dImplTicksULONGMAX;
+
+ struct tms aTms;
+ sal_uInt32 nTicks = (sal_uInt32)times( &aTms );
+
+ if ( !nImplTicksPerSecond )
+ {
+ nImplTicksPerSecond = CLK_TCK;
+ dImplTicksPerSecond = nImplTicksPerSecond;
+ dImplTicksULONGMAX = (double)(sal_uInt32)ULONG_MAX;
+ }
+
+ double fTicks = nTicks;
+ fTicks *= 1000;
+ fTicks /= dImplTicksPerSecond;
+ fTicks = fmod (fTicks, dImplTicksULONGMAX);
+
+ return (sal_uInt32)fTicks;
+#endif
+}
+
+class MyTimer
+{
+public:
+ MyTimer( const OString &descString ) :
+ nStart( getSystemTicks() ),
+ m_descString( descString )
+ {
+ }
+ ~MyTimer( )
+ {
+ printf( "%f s : %s\n", (getSystemTicks() -nStart) / 1000., m_descString.getStr() );
+ }
+private:
+ sal_uInt32 nStart;
+ OString m_descString;
+};
+
+void main()
+{
+ // interlocked count
+ {
+ MyTimer timer( "performance - 1000*10000 interlocked count" );
+ oslInterlockedCount count;
+ for( int i = 0 ; i < 1000*10000 ; i ++ )
+ {
+ osl_incrementInterlockedCount( &count );
+ }
+ }
+ {
+ OString myDummyString( "blubber" );
+ MyTimer timer( "performance - 1000*10000 acquiring/releasing a refcounted string(without destruction)" );
+ for( int i = 0 ; i < 1000*10000 ; i ++ )
+ {
+ OString myNextDummyString = myDummyString ;
+ }
+ }
+
+ printf( "--------------------\n" );
+ {
+ Mutex mutex;
+ MyTimer timer( "performance - 1000*10000 acquiring/releasing an osl::Mutex" );
+ for( int i = 0 ; i < 1000*10000 ; i ++ )
+ {
+ MutexGuard guard( mutex );
+ }
+ }
+
+ {
+ oslSemaphore sema = osl_createSemaphore(1);
+ MyTimer timer( "performance - 1000*10000 acquiring/releasing an osl::Semaphore" );
+ for( int i = 0 ; i < 1000*10000 ; i ++ )
+ {
+ osl_acquireSemaphore( sema );
+ osl_releaseSemaphore( sema );
+ }
+ }
+
+ printf( "--------------------\n" );
+ {
+ MyTimer timer( "performance - 1000*10000 rtl::ByteSequence(500)" );
+ for( int i = 0 ; i < 1000*1000 ; i ++ )
+ {
+ ByteSequence seq(500);
+ }
+ }
+
+ {
+ MyTimer timer( "performance - 1000*1000 rtl::ByteSequence(500,BYTESEQ_NODEFAULT)" );
+ for( int i = 0 ; i < 1000*1000 ; i ++ )
+ {
+ ByteSequence seq(500, BYTESEQ_NODEFAULT);
+ }
+ }
+ {
+ MyTimer timer( "performance - 1000*1000 com::sun::star::uno::Sequence< sal_Int8 > (500)" );
+ for( int i = 0 ; i < 1000*1000 ; i ++ )
+ {
+ Sequence< sal_Int8> seq(500);
+ }
+ }
+ {
+ MyTimer timer( "performance - 1000*1000 rtl_freeMemory( rtl_allocateMemory( 512 ) )" );
+ for( int i = 0 ; i < 1000*1000 ; i ++ )
+ {
+ rtl_freeMemory( rtl_allocateMemory( 512 ) );
+ }
+ }
+
+ printf( "--------------------\n" );
+ {
+ MyTimer timer( "performance - 1000*1000 byte string construction/destruction" );
+ for( int i = 0 ; i < 1000*1000 ; i ++ )
+ {
+ OString textEnc( "this is a test string" );
+ }
+ }
+
+ {
+ MyTimer timer( "performance - 1000*1000 unicode string construction/destruction" );
+ for( int i = 0 ; i < 1000*1000 ; i ++ )
+ {
+ OUString textEnc( RTL_CONSTASCII_USTRINGPARAM( "this is a test string" ) );
+ }
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/test/test_bridge.idl b/bridges/test/test_bridge.idl
new file mode 100644
index 000000000000..ce38594ecd88
--- /dev/null
+++ b/bridges/test/test_bridge.idl
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * 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 <com/sun/star/uno/XInterface.idl>
+#include <com/sun/star/uno/Exception.idl>
+
+module test
+{
+
+struct TestTypes
+{
+ boolean Bool;
+ char Char;
+ byte Byte;
+ short Short;
+ unsigned short UShort;
+ long Long;
+ unsigned long ULong;
+ hyper Hyper;
+ unsigned hyper UHyper;
+ float Float;
+ double Double;
+// test::TestEnum Enum;
+ string String;
+ com::sun::star::uno::XInterface Interface;
+ any Any;
+};
+
+exception TestBridgeException : com::sun::star::uno::Exception
+{
+
+};
+
+interface XCallMe : com::sun::star::uno::XInterface
+{
+ void call( [in] string s , [in] long nToDo ) raises( TestBridgeException );
+ [oneway] void callOneway( [in] string s , [in] long nToDo );
+ [attribute] string sAttribute;
+ void callAgain( [in] XCallMe callAgain, [in] long nToCall );
+ TestTypes transport( [in] TestTypes types );
+ [oneway] void drawLine( [in] long x1 , [in] long y1, [in] long x2, [in] long y2 );
+};
+
+interface XInterfaceTest : com::sun::star::uno::XInterface
+{
+ void setIn( [in] XCallMe callback );
+ void setInOut( [inout] XCallMe callback );
+ void getOut( [out] XCallMe callback );
+ XCallMe get();
+};
+
+interface XTestFactory : com::sun::star::uno::XInterface
+{
+ XCallMe createCallMe();
+ XInterfaceTest createInterfaceTest();
+};
+
+
+};
diff --git a/bridges/test/testclient.cxx b/bridges/test/testclient.cxx
new file mode 100644
index 000000000000..be5223fb5873
--- /dev/null
+++ b/bridges/test/testclient.cxx
@@ -0,0 +1,249 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <string.h>
+
+#include <osl/time.h>
+
+#include <osl/mutex.hxx>
+#include <osl/module.h>
+#include <osl/thread.h>
+#include <osl/conditn.h>
+#include <osl/diagnose.h>
+
+#include <uno/mapping.hxx>
+
+#include <cppuhelper/servicefactory.hxx>
+
+#include <com/sun/star/connection/XConnector.hpp>
+
+#include <com/sun/star/bridge/XBridgeFactory.hpp>
+
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/XMain.hpp>
+
+#include <com/sun/star/test/performance/XPerformanceTest.hpp>
+
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/factory.hxx>
+
+#include <test/XTestFactory.hpp>
+
+
+using namespace ::test;
+using namespace ::rtl;
+using namespace ::cppu;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::bridge;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::connection;
+using namespace ::com::sun::star::test::performance;
+
+#include "testcomp.h"
+
+
+void doPerformanceTest( const Reference < XPerformanceTest > & /* xBench */)
+{
+ printf( "not implemented\n" );
+// sal_Int32 i,nLoop = 2000;
+// sal_Int32 tStart, tEnd , tEnd2;
+// //------------------------------------
+// // oneway calls
+// i = nLoop;
+// tStart = GetTickCount();
+// while (i--)
+// xBench->async();
+// tEnd = GetTickCount();
+// xBench->sync();
+// tEnd2 = GetTickCount();
+// printf( "%d %d %d\n" , nLoop, tEnd - tStart , tEnd2 -tStart );
+// // synchron calls
+// i = nLoop;
+// tStart = GetTickCount();
+// while (i--)
+// xBench->sync();
+// tEnd = GetTickCount();
+// printf( "%d %d \n" , nLoop, tEnd - tStart );
+
+}
+
+void testLatency( const Reference < XConnection > &r , sal_Bool /* bReply */)
+{
+ sal_Int32 nLoop = 10000;
+ TimeValue aStartTime, aEndTime;
+ osl_getSystemTime( &aStartTime );
+
+ sal_Int32 i;
+ for( i = 0 ; i < nLoop ; i++ )
+ {
+ Sequence< sal_Int8 > s1( 200 );
+ r->write( s1 );
+ r->read( s1 , 12 );
+ r->read( s1 , 48 );
+ }
+ osl_getSystemTime( &aEndTime );
+
+ double fStart = (double)aStartTime.Seconds + ((double)aStartTime.Nanosec / 1000000000.0);
+ double fEnd = (double)aEndTime.Seconds + ((double)aEndTime.Nanosec / 1000000000.0);
+
+ printf( "System latency per call : %g\n" , (( fEnd-fStart )/2.) / ((double)(nLoop)) );
+}
+
+int main( int argc, char *argv[] )
+{
+ if( argc < 2 )
+ {
+ printf(
+ "usage : testclient [-r] connectionstring\n"
+ " -r reverse call me test (server calls client)"
+ );
+ return 0;
+ }
+
+ OUString sConnectionString;
+ OUString sProtocol;
+ sal_Bool bLatency = sal_False;
+ sal_Bool bReverse = sal_False;
+
+ parseCommandLine( argv , &sConnectionString , &sProtocol , &bLatency , &bReverse );
+
+ {
+ Reference< XMultiServiceFactory > rSMgr = createRegistryServiceFactory(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("client.rdb")) );
+
+
+ Reference < XConnector > rConnector(
+ createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Connector")),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("connector.uno" SAL_DLLEXTENSION)),
+ rSMgr ),
+ UNO_QUERY );
+
+
+ try
+ {
+ Reference < XConnection > rConnection =
+ rConnector->connect( sConnectionString );
+
+ printf( "%s\n" , OUStringToOString( rConnection->getDescription(),
+ RTL_TEXTENCODING_ASCII_US ).pData->buffer );
+
+
+ if( bLatency )
+ {
+ testLatency( rConnection , sal_False );
+ testLatency( rConnection , sal_True );
+ }
+ else
+ {
+ // just ensure that it is registered
+ createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.Bridge.iiop")),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("remotebridge.uno" SAL_DLLEXTENSION)),
+ rSMgr );
+
+ Reference < XBridgeFactory > rFactory(
+ createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.BridgeFactory")),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("bridgefac.uno" SAL_DLLEXTENSION)),
+ rSMgr ),
+ UNO_QUERY );
+
+ if( rFactory.is() )
+ {
+
+ Reference < XBridge > rBridge = rFactory->createBridge(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("bla blub")),
+ sProtocol,
+ rConnection,
+ new OInstanceProvider );
+ {
+ // test the factory
+ Reference < XBridge > rBridge2 = rFactory->getBridge( OUString( RTL_CONSTASCII_USTRINGPARAM("bla blub")) );
+ OSL_ASSERT( rBridge2.is() );
+ OSL_ASSERT( rBridge2->getDescription() == rBridge->getDescription( ) );
+ OSL_ASSERT( rBridge2->getName() == rBridge->getName() );
+ OSL_ASSERT( rBridge2 == rBridge );
+ }
+
+
+ Reference < XInterface > rInitialObject = rBridge->getInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("bridges-testobject")) );
+
+ if( rInitialObject.is() )
+ {
+ printf( "got the remote object\n" );
+ if( ! bReverse )
+ {
+ // Reference < XComponent > rPerfTest( rInitialObject , UNO_QUERY );
+// if( rPerfTest.is() )
+// {
+// // doPerformanceTest( rPerfTest );
+// }
+// else
+// {
+ testRemote( rInitialObject );
+// }
+ }
+ }
+// Reference < XComponent > rComp( rBridge , UNO_QUERY );
+// rComp->dispose();
+
+ rInitialObject = Reference < XInterface > ();
+ printf( "Waiting...\n" );
+ TimeValue value={bReverse ?1000 :2,0};
+ osl_waitThread( &value );
+ printf( "Closing...\n" );
+ }
+
+ Reference < XBridge > rBridge = rFactory->getBridge( OUString( RTL_CONSTASCII_USTRINGPARAM("bla blub")) );
+// OSL_ASSERT( ! rBridge.is() );
+ }
+
+ }
+ catch( DisposedException & e )
+ {
+ OString o = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US );
+ printf( "A remote object reference became invalid\n%s\n" , o.pData->buffer );
+ }
+ catch( Exception &e )
+ {
+ OString o = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US );
+ printf( "Login failed, got an Exception !\n%s\n" , o.pData->buffer );
+ }
+
+
+ Reference < XComponent > rComp( rSMgr , UNO_QUERY );
+ rComp->dispose();
+ }
+ printf( "Closed\n" );
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/test/testclient.java b/bridges/test/testclient.java
new file mode 100644
index 000000000000..f2963f685b9f
--- /dev/null
+++ b/bridges/test/testclient.java
@@ -0,0 +1,156 @@
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.IBridge;
+import com.sun.star.connection.XConnector;
+import com.sun.star.connection.XConnection;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.bridge.XInstanceProvider;
+
+import test.XCallMe;
+import test.XTestFactory;
+
+
+class MyInstanceProvider implements XInstanceProvider
+{
+ public Object getInstance( String sName )
+ {
+ System.out.println( "getInstance called" );
+ return new MyTestFactory();
+ }
+
+}
+
+
+class MyTestFactory implements XTestFactory
+{
+ public XCallMe createCallMe( ) throws com.sun.star.uno.RuntimeException
+ {
+ return new MyCallMe();
+ }
+
+ public test.XInterfaceTest createInterfaceTest( ) throws com.sun.star.uno.RuntimeException
+ {
+ return null;
+ }
+
+}
+class MyCallMe implements XCallMe
+{
+ public String getsAttribute() throws com.sun.star.uno.RuntimeException
+ {
+ return "";
+ }
+ public void setsAttribute( String _sattribute ) throws com.sun.star.uno.RuntimeException
+ {
+ }
+
+ // Methods
+ public void call( /*IN*/String s, /*IN*/int nToDo ) throws test.TestBridgeException, com.sun.star.uno.RuntimeException
+ {
+
+ }
+ public void callOneway( /*IN*/String s, /*IN*/int nToDo ) throws com.sun.star.uno.RuntimeException
+ {
+ System.out.println( "entering callOneway" );
+// this.wait( 5 );
+ try {
+ Thread.currentThread().sleep( 4000 );
+ }
+ catch ( java.lang.Exception e )
+ {
+ System.out.println( e );
+ }
+ System.out.println( "leaving callOneway" );
+ }
+ public void callAgain( /*IN*/XCallMe callAgain, /*IN*/int nToCall ) throws com.sun.star.uno.RuntimeException
+ {
+
+ }
+ public test.TestTypes transport( /*IN*/test.TestTypes types ) throws com.sun.star.uno.RuntimeException
+ {
+ return new test.TestTypes();
+ }
+
+}
+
+public class testclient
+{
+ static void main( String[] args )
+ {
+ try {
+
+ com.sun.star.comp.servicemanager.ServiceManager smgr =
+ new com.sun.star.comp.servicemanager.ServiceManager();
+ smgr.addFactories( new String[] { "com.sun.star.comp.connections.Connector" });
+
+ Object x = smgr.createInstance("com.sun.star.connection.Connector");
+ if( x == null )
+ {
+ System.out.println( "couldn't create connector\n" );
+ return;
+ }
+
+
+ XConnector xConnector =
+ UnoRuntime.queryInterface( XConnector.class , x );
+
+ XConnection xConnection = xConnector.connect(args[0]);
+
+ if( null != xConnection )
+ {
+ System.out.println( "after connect" );
+ String rootOid = "OfficeDaemon.Factory";
+ com.sun.star.uno.IBridge bridge = (IBridge ) UnoRuntime.getBridgeByName(
+ "java",
+ null,
+ "remote",
+ null,
+ new Object[]{"iiop", xConnection, new MyInstanceProvider()});
+
+ System.out.println( "after building bridge" );
+// Object rInitialObject = m_bridge.mapInterfaceFrom(rootOid, XInterface.class);
+// XTestFactory rFactory =
+// UnoRuntime.queryInterface(XTestFactory.class,rInitialObject );
+
+// XCallMe callMerFactory->
+ Thread.currentThread().sleep( 100000 );
+ }
+ }
+ catch( com.sun.star.uno.Exception e)
+ {
+ System.out.println( "Exception thrown" );
+ }
+ catch( java.lang.Exception e)
+ {
+ System.out.println( "java.lang.Exception thrown" );
+ }
+
+ System.out.println( "exiting" );
+ }
+}
diff --git a/bridges/test/testcomp.cxx b/bridges/test/testcomp.cxx
new file mode 100644
index 000000000000..8ec0fc251491
--- /dev/null
+++ b/bridges/test/testcomp.cxx
@@ -0,0 +1,801 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <string.h>
+#include <stdlib.h>
+#include <osl/time.h>
+
+#include <uno/threadpool.h>
+
+#include <osl/mutex.hxx>
+#include <osl/diagnose.h>
+
+#include <test/XTestFactory.hpp>
+#include <cppuhelper/servicefactory.hxx>
+
+#include <com/sun/star/bridge/XInstanceProvider.hpp>
+
+#include <com/sun/star/registry/XImplementationRegistration.hpp>
+
+#include <com/sun/star/test/performance/XPerformanceTest.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+#include <cppuhelper/weak.hxx>
+
+using namespace ::test;
+using namespace ::rtl;
+using namespace ::test;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::bridge;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::test::performance;
+
+#include "testcomp.h"
+
+
+void parseCommandLine( char *argv[] ,
+ ::rtl::OUString *pConnection , ::rtl::OUString *pProtocol ,
+ sal_Bool *pbLatency , sal_Bool *pbReverse)
+{
+ sal_Int32 nArgIndex = 1;
+ if( ! strcmp( argv[1] , "-r" ) )
+ {
+ nArgIndex = 2;
+ *pbReverse = sal_True;
+ }
+ else if( ! strcmp( argv[1] , "-latency" ) )
+ {
+ *pbLatency = sal_True;
+ nArgIndex = 2;
+ }
+
+ OUString sTemp = OUString::createFromAscii( argv[nArgIndex] );
+ sal_Int32 nIndex = sTemp.indexOf( ';' );
+ if( -1 == nIndex )
+ {
+ *pConnection = sTemp;
+ *pProtocol = OUString( RTL_CONSTASCII_USTRINGPARAM( "iiop" ) );
+ }
+ else
+ {
+ *pConnection = sTemp.copy( 0 , nIndex );
+ *pProtocol = sTemp.copy( nIndex+1, sTemp.getLength() - (nIndex+1) );
+ }
+}
+
+Any OInstanceProvider::queryInterface( const Type & aType ) throw ( RuntimeException )
+{
+ Any a = ::cppu::queryInterface( aType ,
+ SAL_STATIC_CAST( XInstanceProvider * , this ) );
+ if( a.hasValue() )
+ {
+ return a;
+ }
+ return OWeakObject::queryInterface( aType );
+}
+
+::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+ OInstanceProvider::getInstance( const ::rtl::OUString& sObjectName )
+ throw(::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ // Tries to get the PerformanceTestObject
+ if( sObjectName == OUString( RTL_CONSTASCII_USTRINGPARAM( "TestRemoteObject" ) ) )
+ {
+ return m_rSMgr->createInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.test.performance.PerformanceTestObject") ) );
+ }
+ return Reference < XInterface > ( (::cppu::OWeakObject * ) new OTestFactory() );
+}
+
+class ServiceImpl
+ : public XServiceInfo
+ , public XPerformanceTest
+{
+ OUString _aDummyString;
+ Any _aDummyAny;
+ Sequence< Reference< XInterface > > _aDummySequence;
+ ComplexTypes _aDummyStruct;
+ RuntimeException _aDummyRE;
+
+ sal_Int32 _nRef;
+
+public:
+ ServiceImpl()
+ : _nRef( 0 )
+ {}
+ ServiceImpl( const Reference< XMultiServiceFactory > & /* xMgr */)
+ : _nRef( 0 )
+ {}
+
+ // XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw(::com::sun::star::uno::RuntimeException)
+ {
+ // execution time remains appr. constant any time
+ Any aRet;
+ if (aType == ::getCppuType( (const Reference< XInterface > *)0 ))
+ {
+ void * p = (XInterface *)(XPerformanceTest *)this;
+ aRet.setValue( &p, ::getCppuType( (const Reference< XInterface > *)0 ) );
+ }
+ if (aType == ::getCppuType( (const Reference< XPerformanceTest > *)0 ))
+ {
+ void * p = (XPerformanceTest *)this;
+ aRet.setValue( &p, ::getCppuType( (const Reference< XPerformanceTest > *)0 ) );
+ }
+ if (! aRet.hasValue())
+ {
+ void * p = (XPerformanceTest *)this;
+ Any aDummy( &p, ::getCppuType( (const Reference< XPerformanceTest > *)0 ) );
+ }
+ return aRet;
+ }
+ virtual void SAL_CALL acquire() throw()
+ { osl_incrementInterlockedCount( &_nRef ); }
+ virtual void SAL_CALL release() throw()
+ { if (! osl_decrementInterlockedCount( &_nRef )) delete this; }
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw (RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw (RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException);
+
+ // Attributes
+ virtual sal_Int32 SAL_CALL getLong_attr() throw(::com::sun::star::uno::RuntimeException)
+ { return 0; }
+ virtual void SAL_CALL setLong_attr( sal_Int32 /* _attributelong */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual sal_Int64 SAL_CALL getHyper_attr() throw(::com::sun::star::uno::RuntimeException)
+ { return 0; }
+ virtual void SAL_CALL setHyper_attr( sal_Int64 /* _attributehyper */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual float SAL_CALL getFloat_attr() throw(::com::sun::star::uno::RuntimeException)
+ { return 0.0; }
+ virtual void SAL_CALL setFloat_attr( float /* _attributefloat */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual double SAL_CALL getDouble_attr() throw(::com::sun::star::uno::RuntimeException)
+ { return 0.0; }
+ virtual void SAL_CALL setDouble_attr( double /* _attributedouble */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual OUString SAL_CALL getString_attr() throw(::com::sun::star::uno::RuntimeException)
+ { return _aDummyString; }
+ virtual void SAL_CALL setString_attr( const ::rtl::OUString& /* _attributestring */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual Reference< XInterface > SAL_CALL getInterface_attr() throw(::com::sun::star::uno::RuntimeException)
+ { return Reference< XInterface >(); }
+ virtual void SAL_CALL setInterface_attr( const Reference< XInterface >& /* _attributeinterface */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual Any SAL_CALL getAny_attr() throw(::com::sun::star::uno::RuntimeException)
+ { return _aDummyAny; }
+ virtual void SAL_CALL setAny_attr( const Any& /* _attributeany */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual Sequence< Reference< XInterface > > SAL_CALL getSequence_attr() throw(::com::sun::star::uno::RuntimeException)
+ { return _aDummySequence; }
+ virtual void SAL_CALL setSequence_attr( const Sequence< Reference< XInterface > >& /* _attributesequence */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual ComplexTypes SAL_CALL getStruct_attr() throw(::com::sun::star::uno::RuntimeException)
+ { return _aDummyStruct; }
+ virtual void SAL_CALL setStruct_attr( const ::com::sun::star::test::performance::ComplexTypes& /* _attributestruct */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+
+ // Methods
+ virtual sal_Int32 SAL_CALL getLong() throw(::com::sun::star::uno::RuntimeException)
+ { return 0; }
+ virtual void SAL_CALL setLong( sal_Int32 /* _long */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual sal_Int64 SAL_CALL getHyper() throw(::com::sun::star::uno::RuntimeException)
+ { return 0; }
+ virtual void SAL_CALL setHyper( sal_Int64 /* _hyper */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual float SAL_CALL getFloat() throw(::com::sun::star::uno::RuntimeException)
+ { return 0; }
+ virtual void SAL_CALL setFloat( float /* _float */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual double SAL_CALL getDouble() throw(::com::sun::star::uno::RuntimeException)
+ { return 0; }
+ virtual void SAL_CALL setDouble( double /* _double */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual OUString SAL_CALL getString() throw(::com::sun::star::uno::RuntimeException)
+ { return _aDummyString; }
+ virtual void SAL_CALL setString( const ::rtl::OUString& /* _string */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual Reference< XInterface > SAL_CALL getInterface() throw(::com::sun::star::uno::RuntimeException)
+ { return Reference< XInterface >(); }
+ virtual void SAL_CALL setInterface( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& /* _interface */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual Any SAL_CALL getAny() throw(::com::sun::star::uno::RuntimeException)
+ { return _aDummyAny; }
+ virtual void SAL_CALL setAny( const ::com::sun::star::uno::Any& /* _any */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual Sequence< Reference< XInterface > > SAL_CALL getSequence() throw(::com::sun::star::uno::RuntimeException)
+ { return _aDummySequence; }
+ virtual void SAL_CALL setSequence( const Sequence< Reference< XInterface > >& /*_sequence */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual ComplexTypes SAL_CALL getStruct() throw(::com::sun::star::uno::RuntimeException)
+ { return _aDummyStruct; }
+ virtual void SAL_CALL setStruct( const ::com::sun::star::test::performance::ComplexTypes& /* c */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+
+ virtual void SAL_CALL async() throw(::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL sync() throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual ComplexTypes SAL_CALL complex_in( const ::com::sun::star::test::performance::ComplexTypes& aVal ) throw(::com::sun::star::uno::RuntimeException)
+ { return aVal; }
+ virtual ComplexTypes SAL_CALL complex_inout( ::com::sun::star::test::performance::ComplexTypes& aVal ) throw(::com::sun::star::uno::RuntimeException)
+ { return aVal; }
+ virtual void SAL_CALL complex_oneway( const ::com::sun::star::test::performance::ComplexTypes& /* aVal */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual void SAL_CALL complex_noreturn( const ::com::sun::star::test::performance::ComplexTypes& /* aVal */) throw(::com::sun::star::uno::RuntimeException)
+ {}
+ virtual Reference< XPerformanceTest > SAL_CALL createObject() throw(::com::sun::star::uno::RuntimeException)
+ { return new ServiceImpl(); }
+ virtual void SAL_CALL raiseRuntimeException( ) throw(::com::sun::star::uno::RuntimeException)
+ { throw _aDummyRE; }
+};
+
+
+void ServiceImpl::async() throw(::com::sun::star::uno::RuntimeException)
+{}
+
+// XServiceInfo
+//__________________________________________________________________________________________________
+OUString ServiceImpl::getImplementationName()
+ throw (RuntimeException)
+{
+ return OUString( );
+}
+//__________________________________________________________________________________________________
+sal_Bool ServiceImpl::supportsService( const OUString & /* rServiceName */)
+ throw (RuntimeException)
+{
+ return sal_False;
+}
+//__________________________________________________________________________________________________
+Sequence< OUString > ServiceImpl::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ return Sequence< OUString > ();
+}
+
+/******************
+ * OCallMe
+ *
+ *****************/
+
+Any OCallMe::queryInterface( const Type & aType ) throw ( RuntimeException )
+{
+ Any a = ::cppu::queryInterface( aType,
+ SAL_STATIC_CAST( XCallMe * , this ) );
+
+ if( a.hasValue() )
+ {
+ return a;
+ }
+
+ return OWeakObject::queryInterface( aType );
+}
+
+void OCallMe::call( const ::rtl::OUString& s, sal_Int32 nToDo )
+ throw( RuntimeException, ::test::TestBridgeException)
+{
+ if( nToDo < 0 )
+ {
+ throw TestBridgeException();
+ }
+
+ OUString sDummy;
+ if( ! nToDo ) {
+ OString o = OUStringToOString( s,RTL_TEXTENCODING_ASCII_US);
+ printf( "%s\n" , o.pData->buffer );
+ }
+ for( sal_Int32 i = 0 ; i < nToDo ; i ++ )
+ {
+ sDummy += s;
+ }
+}
+
+void SAL_CALL OCallMe::drawLine( sal_Int32 /* x1 */, sal_Int32 /* y1 */, sal_Int32 /* x2 */, sal_Int32 /* y2 */)
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ // do nothings
+}
+
+void OCallMe::callOneway( const ::rtl::OUString& /* s */, sal_Int32 nToDo )
+ throw(RuntimeException)
+{
+ OUString sDummy;
+ m_nLastToDos = nToDo;
+
+
+ if( nToDo )
+ {
+ printf( "+" );
+ fflush( stdout );
+
+ TimeValue val = { nToDo , 0 };
+ osl_waitThread( &val );
+ printf( "-\n" );
+ }
+
+}
+
+::test::TestTypes SAL_CALL OCallMe::transport( const ::test::TestTypes& types )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return types;
+}
+
+::rtl::OUString OCallMe::getsAttribute() throw(RuntimeException)
+{
+ return m_sAttribute;
+}
+void OCallMe::setsAttribute( const ::rtl::OUString& _sattribute )
+ throw(RuntimeException)
+{
+ m_sAttribute = _sattribute;
+}
+void OCallMe::callAgain( const Reference< ::test::XCallMe >& callAgainArg,
+ sal_Int32 nToCall ) throw(RuntimeException)
+{
+ ::osl::MutexGuard guard( m_mutex );
+ if( nToCall %2 )
+ {
+ printf( "Deadlocktest pong %" SAL_PRIdINT32 "\n", nToCall );
+ }
+ else
+ {
+ printf( "Deadlocktest ping %" SAL_PRIdINT32 "\n", nToCall );
+ }
+ if( nToCall )
+ {
+ callAgainArg->callAgain( Reference< XCallMe > ( (XCallMe *) this ) , nToCall -1 );
+ }
+}
+
+/********************
+ * OInterfaceTest
+ *
+ *******************/
+Any OInterfaceTest::queryInterface( const Type & aType ) throw ( RuntimeException )
+{
+ Any a = ::cppu::queryInterface( aType,
+ SAL_STATIC_CAST( XInterfaceTest * , this ) );
+ if( a.hasValue() )
+ {
+ return a;
+ }
+ return OWeakObject::queryInterface( aType );
+}
+
+
+void OInterfaceTest::setIn(
+ const Reference< ::test::XCallMe >& callback )
+ throw(RuntimeException)
+{
+ m_rCallMe = callback;
+ call();
+}
+
+void OInterfaceTest::setInOut( Reference< ::test::XCallMe >& callback )
+ throw(RuntimeException)
+{
+ Reference< XCallMe > r = m_rCallMe;
+ m_rCallMe = callback;
+ callback = r;
+ call();
+}
+
+
+void OInterfaceTest::getOut( Reference< ::test::XCallMe >& callback )
+ throw(RuntimeException)
+{
+ callback = m_rCallMe;
+}
+
+Reference< ::test::XCallMe > OInterfaceTest::get( )
+ throw(RuntimeException)
+{
+ call();
+ return m_rCallMe;
+}
+
+void OInterfaceTest::call()
+{
+ if( m_rCallMe.is() )
+ {
+ m_rCallMe->call( OUString( RTL_CONSTASCII_USTRINGPARAM("This is my String during a callback!")) , 5);
+ }
+}
+
+
+Any OTestFactory::queryInterface( const Type & aType ) throw ( RuntimeException )
+{
+ Any a = ::cppu::queryInterface( aType,
+ SAL_STATIC_CAST( XTestFactory * , this ) );
+
+ if( a.hasValue() )
+ {
+ return a;
+ }
+
+ return OWeakObject::queryInterface( aType );
+}
+
+Reference< ::test::XCallMe > OTestFactory::createCallMe( )
+ throw(RuntimeException)
+{
+ return Reference< XCallMe > ( (XCallMe * ) new OCallMe() );
+}
+
+Reference< ::test::XInterfaceTest > SAL_CALL OTestFactory::createInterfaceTest( )
+ throw(RuntimeException)
+{
+ return Reference < XInterfaceTest > ( (XInterfaceTest * ) new OInterfaceTest() );
+}
+
+
+
+
+// class OInstanceProvider :
+// public ::cppu::OWeakObject,
+// public XInstanceProvider
+// {
+// public:
+// OInstanceProvider( ){}
+// ~OInstanceProvider(){ printf( "instance provider dies\n" );}
+// public:
+// // XInterface
+// Any SAL_CALL queryInterface( const Type & aType);
+// void SAL_CALL acquire() { OWeakObject::acquire(); }
+// void SAL_CALL release() { OWeakObject::release(); }
+
+// public:
+// virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
+// getInstance( const ::rtl::OUString& sObjectName )
+// throw( ::com::sun::star::container::NoSuchElementException,
+// ::com::sun::star::uno::RuntimeException);
+// };
+
+
+
+
+
+
+
+
+double getCallsPerSec( const Reference < XCallMe > &rCall , int nLoops, int nToDo )
+{
+ TimeValue aStartTime, aEndTime;
+ osl_getSystemTime( &aStartTime );
+ for( sal_Int32 i = 0; i < nLoops; i ++ )
+ {
+ rCall->call( OUString( RTL_CONSTASCII_USTRINGPARAM("Performance test string")) , nToDo );
+ }
+ osl_getSystemTime( &aEndTime );
+
+ double fStart = (double)aStartTime.Seconds + ((double)aStartTime.Nanosec / 1000000000.0);
+ double fEnd = (double)aEndTime.Seconds + ((double)aEndTime.Nanosec / 1000000000.0);
+ return fEnd-fStart;
+}
+
+double getCallsPerSecOneway( const Reference < XCallMe > &rCall ,
+ int nLoops,
+ int nToDo,
+ double *pdAfterExecution
+ )
+{
+ TimeValue aStartTime, aEndTime, aAfterExecution;
+ osl_getSystemTime( &aStartTime );
+ for( sal_Int32 i = 0; i < nLoops; i ++ )
+ {
+// rCall->callOneway( OUString( RTL_CONSTASCII_USTRINGPARAM("Performance test string" )), 0 );
+ rCall->drawLine( 0 , 0 , 500 , 123 );
+ }
+ osl_getSystemTime( &aEndTime );
+
+ rCall->call( OUString( RTL_CONSTASCII_USTRINGPARAM("Performance test string")) , nToDo );
+ osl_getSystemTime( &aAfterExecution );
+
+ double fStart = (double)aStartTime.Seconds + ((double)aStartTime.Nanosec / 1000000000.0);
+ double fEnd = (double)aEndTime.Seconds + ((double)aEndTime.Nanosec / 1000000000.0);
+ *pdAfterExecution = (double)aAfterExecution.Seconds +
+ ((double)aAfterExecution.Nanosec / 1000000000.0) - fStart;
+ return fEnd-fStart;
+}
+
+void testOnewayPerformanceOnTwoInterfaces(
+ const Reference < XCallMe > &rRemote1, const Reference < XCallMe > &rRemote2 )
+{
+ printf( "Doing oneway performance test on two interfaces ...\n" );
+ const sal_Int32 nLoops = 10000;
+ TimeValue aStartTime, aEndTime;
+ osl_getSystemTime( &aStartTime );
+ for( sal_Int32 i = 0; i < nLoops ; i ++ )
+ {
+ rRemote1->drawLine( 0 , 0 , 500 , 123 );
+ rRemote2->drawLine( 0 , 0 , 500 , 123 );
+ }
+ osl_getSystemTime( &aEndTime );
+ double fStart = (double)aStartTime.Seconds + ((double)aStartTime.Nanosec / 1000000000.0);
+ double fEnd = (double)aEndTime.Seconds + ((double)aEndTime.Nanosec / 1000000000.0);
+
+ printf( "Overhead per Call [ms] %g\n" , ((fEnd-fStart)/((double)nLoops/1000 ))/2. );
+}
+
+void testPerformance( const Reference < XCallMe > &rRemote,
+ const Reference < XCallMe > &rLocal )
+{
+ OUString aTestString;
+
+ sal_Int32 nDoSomething = 1;
+ sal_Int32 nCalls = 80000;
+ double dRemote, dLocal,dAfterExecution;
+
+ printf( "performance test oneway...\n" );
+ dLocal = getCallsPerSecOneway( rLocal , nCalls , nDoSomething , &dAfterExecution);
+ dRemote = getCallsPerSecOneway( rRemote , nCalls , nDoSomething , &dAfterExecution);
+ printf( "Local=%g s,"
+ "Remote : %g s\n" , dLocal, dRemote );
+ if( dLocal > 0. )
+ {
+ printf( "Remote/Local : %g\n", dRemote/dLocal );
+ }
+
+ printf( "Overhead per Call [ms] %g\n" , (dRemote - dLocal)/((double)nCalls/1000 ) );
+ printf( "Overhead per Call after completion [ms] %g\n" , (dAfterExecution - dLocal)/((double)nCalls/1000 ) );
+
+ nCalls = 2000;
+
+ printf( "Doing performance test ...\n" );
+ dRemote = getCallsPerSec( rRemote , nCalls , nDoSomething );
+ dLocal = getCallsPerSec( rLocal , nCalls , nDoSomething );
+ printf( "Local=%g s,\n"
+ "Remote=%g s\n" , dLocal, dRemote );
+ if( dLocal > 0. )
+ {
+ printf( "Remote/Local : %g\n", dRemote/dLocal );
+ }
+ printf( "Overhead per synchron Call [ms] %g\n" , ((dRemote - dLocal)/((double)nCalls/1000 )) );
+}
+
+void testException( const Reference < XCallMe > &r )
+{
+ try {
+ r->call( OUString( RTL_CONSTASCII_USTRINGPARAM("dummy")) , -1 );
+ OSL_ASSERT( ! "no exception flown !" );
+ }
+ catch( TestBridgeException & e )
+ {
+ // Exception flew successfully !
+ }
+ catch( Exception & e )
+ {
+ OSL_ASSERT( ! "only base class of exception could be catched!" );
+ }
+ catch(...)
+ {
+ OSL_ASSERT(! "wrong unknown exception !" );
+ }
+}
+
+void testSequenceOfCalls( const Reference< XCallMe > & rRCallMe )
+{
+ printf( "Testing sequence of calls\n" );
+ for( sal_Int32 i = 0 ; i < 800 ; i ++ )
+ {
+ rRCallMe->callOneway( OUString( RTL_CONSTASCII_USTRINGPARAM("hifuj" )), 0 );
+ }
+}
+
+void testAllTypes( const Reference < XCallMe > & rRCallMe )
+{
+ printf( "Testing all types\n" );
+
+ for( sal_Int32 i = 0; i < 32 ; i ++ )
+ {
+
+ TestTypes types;
+ types.Bool = sal_True;
+ types.Char = L'i';
+ types.Byte = -12;
+ types.Short = -32000;
+ types.UShort = (sal_uInt16 ) (1 << i);
+ types.Long = -123;
+ types.ULong = 1 << i;
+ types.Hyper = 50;
+ types.UHyper = 1 << i*2;
+ types.Float = (float)123.239;
+ types.Double = 1279.12490012;
+ types.String = OUString( RTL_CONSTASCII_USTRINGPARAM("abcdefghijklmnopqrstuvwxyz"));
+ types.Interface = Reference< XInterface >( rRCallMe , UNO_QUERY);
+ types.Any <<= types.Double;
+
+ TestTypes retTypes = rRCallMe->transport( types );
+
+ OSL_ASSERT( ( types.Bool && retTypes.Bool ) || ( ! types.Bool && ! retTypes.Bool ) );
+ OSL_ASSERT( types.Char == retTypes.Char );
+ OSL_ASSERT( types.Byte == retTypes.Byte );
+ OSL_ASSERT( types.Short == retTypes.Short );
+ OSL_ASSERT( types.UShort == retTypes.UShort );
+ OSL_ASSERT( types.Long == retTypes.Long );
+ OSL_ASSERT( types.ULong == retTypes.ULong );
+ OSL_ASSERT( types.Hyper == retTypes.Hyper );
+ OSL_ASSERT( types.UHyper == retTypes.UHyper );
+ OSL_ASSERT( types.Float == retTypes.Float );
+ OSL_ASSERT( types.Double == retTypes.Double );
+ OSL_ASSERT( types.String == retTypes.String );
+ OSL_ASSERT( types.Interface == retTypes.Interface );
+ OSL_ASSERT( types.Any == retTypes.Any );
+ }
+
+}
+
+void testRemote( const Reference< XInterface > &rRemote )
+{
+ char a;
+ getCppuType( (sal_Int8*)&a );
+
+ Reference< XTestFactory > rRFact( rRemote , UNO_QUERY );
+ if( ! rRFact.is() )
+ {
+ printf( "remote object doesn't support XTestFactory\n" );
+ return;
+ }
+ OSL_ASSERT( rRFact.is() );
+ Reference< XCallMe > rLCallMe = (XCallMe * ) new OCallMe();
+ Reference< XCallMe > rRCallMe = rRFact->createCallMe();
+
+ testAllTypes( rLCallMe );
+ testAllTypes( rRCallMe );
+
+ printf( "Testing exception local ...\n" );
+ testException( rLCallMe );
+ printf( "Testing exception remote ...\n" );
+ testException( rRCallMe );
+
+ //--------------------
+ // Test attributes
+ //----------------------
+ OUString ow = OUString::createFromAscii( "dum didel dum dideldei" );
+ rLCallMe->setsAttribute( ow );
+ OSL_ASSERT( rLCallMe->getsAttribute() == ow );
+
+ rRCallMe->setsAttribute( ow );
+ OSL_ASSERT( rRCallMe->getsAttribute() == ow );
+
+ //-------------------
+ // Performance test
+ //-------------------
+ testPerformance( rRCallMe , rLCallMe );
+ testOnewayPerformanceOnTwoInterfaces( rRFact->createCallMe(), rRCallMe );
+
+ //----------------
+ // Test sequence
+ //----------------
+ testSequenceOfCalls( rRCallMe );
+
+
+ // test triple to check if transporting the same interface multiple
+ // times causes any problems
+ Reference< XInterfaceTest > rRTest = rRFact->createInterfaceTest();
+ Reference< XInterfaceTest > rRTest2 = rRFact->createInterfaceTest();
+ Reference< XInterfaceTest > rRTest3 = rRFact->createInterfaceTest();
+
+ rRTest->setIn( rRCallMe );
+ rRTest2->setIn( rRCallMe );
+ rRTest3->setIn( rRCallMe );
+
+ OSL_ASSERT( rRTest->get() == rRCallMe );
+ OSL_ASSERT( rRTest2->get() == rRCallMe );
+ OSL_ASSERT( rRTest3->get() == rRCallMe );
+
+ rRTest->setIn( rLCallMe );
+ rRTest2->setIn( rLCallMe );
+ rRTest3->setIn( rLCallMe );
+
+ {
+ Reference< XCallMe > rLCallMe1 = (XCallMe * ) new OCallMe();
+ Reference< XCallMe > rLCallMe2 = (XCallMe * ) new OCallMe();
+ Reference< XCallMe > rLCallMe3 = (XCallMe * ) new OCallMe();
+ rRTest->setIn( rLCallMe1 );
+ rRTest2->setIn( rLCallMe2 );
+ rRTest3->setIn( rLCallMe3 );
+ OSL_ASSERT( rRTest->get() == rLCallMe1 );
+ OSL_ASSERT( rRTest2->get() == rLCallMe2 );
+ OSL_ASSERT( rRTest3->get() == rLCallMe3 );
+
+ rRTest->setIn( rLCallMe );
+ rRTest2->setIn( rLCallMe );
+ rRTest3->setIn( rLCallMe );
+
+ OSL_ASSERT( rRTest->get() == rLCallMe );
+ OSL_ASSERT( rRTest2->get() == rLCallMe );
+ OSL_ASSERT( rRTest3->get() == rLCallMe );
+ }
+
+ Reference < XCallMe > r = rRCallMe;
+ rRTest->setInOut( r );
+ OSL_ASSERT( r == rLCallMe );
+ OSL_ASSERT( ! ( r == rRCallMe ) );
+
+ // test empty references
+ rRTest->setIn( Reference < XCallMe > () );
+
+ //--------------------------------
+ // test thread deadlocking
+ //--------------------------------
+ rLCallMe->callAgain( rRCallMe, 20 );
+
+}
+
+
+
+
+
+
+Reference <XInterface > createComponent( const ::rtl::OUString &sService ,
+ const ::rtl::OUString &sDllName,
+ const Reference < XMultiServiceFactory > &rSMgr )
+{
+ Reference< XInterface > rInterface;
+ rInterface = rSMgr->createInstance( sService );
+
+ if( ! rInterface.is() )
+ {
+ // erst registrieren
+ Reference < XImplementationRegistration > rReg (
+ rSMgr->createInstance(
+ OUString::createFromAscii( "com.sun.star.registry.ImplementationRegistration" )),
+ UNO_QUERY );
+
+ OSL_ASSERT( rReg.is() );
+ OUString aDllName = sDllName;
+
+ try
+ {
+ rReg->registerImplementation(
+ OUString::createFromAscii( "com.sun.star.loader.SharedLibrary" ),
+ aDllName,
+ Reference< XSimpleRegistry > () );
+ rInterface = rSMgr->createInstance( sService );
+ }
+ catch( Exception & )
+ {
+ printf( "couldn't register dll %s\n" ,
+ OUStringToOString( aDllName, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ }
+ }
+ return rInterface;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/test/testcomp.h b/bridges/test/testcomp.h
new file mode 100644
index 000000000000..ad96c7262433
--- /dev/null
+++ b/bridges/test/testcomp.h
@@ -0,0 +1,157 @@
+/* -*- 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 <stdio.h>
+
+#include <com/sun/star/bridge/XInstanceProvider.hpp>
+#include <osl/thread.hxx>
+
+
+void parseCommandLine( char *argv[] ,
+ ::rtl::OUString *pProtocol , ::rtl::OUString *pConnection ,
+ sal_Bool *pbLatency , sal_Bool *pbReverse);
+
+
+Reference< XInterface > createComponent(
+ const ::rtl::OUString &sServiceName,
+ const ::rtl::OUString &sDllName,
+ const Reference < XMultiServiceFactory > & rSMgr );
+
+class OInterfaceTest :
+ public ::cppu::OWeakObject,
+ public XInterfaceTest
+{
+public:
+ OInterfaceTest() {}
+ ~OInterfaceTest() {}
+
+public:
+ // XInterface
+ Any SAL_CALL queryInterface( const com::sun::star::uno::Type & aType) throw ( ::com::sun::star::uno::RuntimeException );
+ void SAL_CALL acquire() throw() { OWeakObject::acquire(); }
+ void SAL_CALL release() throw() { OWeakObject::release(); }
+
+public:
+ virtual void SAL_CALL setIn( const ::com::sun::star::uno::Reference< ::test::XCallMe >& callback ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setInOut( ::com::sun::star::uno::Reference< ::test::XCallMe >& callback ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL getOut( ::com::sun::star::uno::Reference< ::test::XCallMe >& callback ) throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::test::XCallMe > SAL_CALL get( ) throw(::com::sun::star::uno::RuntimeException);
+private:
+ void call();
+
+private:
+ Reference < XCallMe > m_rCallMe;
+};
+
+
+class OCallMe :
+ public ::cppu::OWeakObject,
+ public XCallMe
+{
+public:
+ OCallMe() : m_nLastToDos(-1) {}
+ ~OCallMe() {}
+
+public:
+ // XInterface
+ Any SAL_CALL queryInterface( const com::sun::star::uno::Type & aType) throw ( ::com::sun::star::uno::RuntimeException );
+ void SAL_CALL acquire()throw() { OWeakObject::acquire(); }
+ void SAL_CALL release()throw() { OWeakObject::release(); }
+public:
+ // XCallMe
+ virtual void SAL_CALL call( const ::rtl::OUString& s, sal_Int32 nToDo )
+ throw(::com::sun::star::uno::RuntimeException,
+ ::test::TestBridgeException);
+ virtual void SAL_CALL callOneway( const ::rtl::OUString& s, sal_Int32 nToDo )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL drawLine( sal_Int32 x1, sal_Int32 y1 , sal_Int32 x2 , sal_Int32 y2 )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL getsAttribute() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setsAttribute( const ::rtl::OUString& _sattribute ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL callAgain( const ::com::sun::star::uno::Reference< ::test::XCallMe >& callAgain,
+ sal_Int32 nToCall ) throw(::com::sun::star::uno::RuntimeException);
+
+ virtual ::test::TestTypes SAL_CALL transport( const ::test::TestTypes& types )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ ::osl::Mutex m_mutex;
+ ::rtl::OUString m_sAttribute;
+ sal_Int32 m_nLastToDos;
+};
+
+class OTestFactory :
+ public ::cppu::OWeakObject,
+ public XTestFactory
+{
+public:
+ OTestFactory() {}
+ ~OTestFactory() {}
+
+public:
+ // XInterface
+ Any SAL_CALL queryInterface( const com::sun::star::uno::Type & aType ) throw ( ::com::sun::star::uno::RuntimeException );
+ void SAL_CALL acquire() throw() { OWeakObject::acquire(); }
+ void SAL_CALL release() throw() { OWeakObject::release(); }
+public:
+ virtual ::com::sun::star::uno::Reference< ::test::XCallMe > SAL_CALL createCallMe( )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::test::XInterfaceTest > SAL_CALL createInterfaceTest( )
+ throw(::com::sun::star::uno::RuntimeException);
+
+};
+
+
+class OInstanceProvider :
+ public ::cppu::OWeakObject,
+ public XInstanceProvider
+{
+public:
+ OInstanceProvider( ){}
+ OInstanceProvider( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & r ) :
+ m_rSMgr( r )
+ {}
+ ~OInstanceProvider(){ printf( "instance provider dies\n" );}
+public:
+ // XInterface
+ Any SAL_CALL queryInterface( const Type & aType)throw ( ::com::sun::star::uno::RuntimeException );
+ void SAL_CALL acquire()throw() { OWeakObject::acquire(); }
+ void SAL_CALL release() throw() { OWeakObject::release(); }
+
+public:
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
+ getInstance( const ::rtl::OUString& sObjectName )
+ throw( ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException);
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_rSMgr;
+};
+
+void testRemote( const Reference< XInterface > &rRemote );
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/test/testoffice.cxx b/bridges/test/testoffice.cxx
new file mode 100644
index 000000000000..0d87089b6921
--- /dev/null
+++ b/bridges/test/testoffice.cxx
@@ -0,0 +1,282 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <osl/time.h>
+
+#include <osl/mutex.hxx>
+#include <osl/thread.h>
+
+#include <cppuhelper/servicefactory.hxx>
+
+#include <com/sun/star/connection/XConnector.hpp>
+
+#include <com/sun/star/bridge/XBridgeFactory.hpp>
+
+#include <com/sun/star/uno/XNamingService.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+
+#include <com/sun/star/text/XTextDocument.hpp>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+#include <com/sun/star/lang/XComponent.hpp>
+
+#include <com/sun/star/frame/XComponentLoader.hpp>
+
+#include <cppuhelper/weak.hxx>
+
+#include <test/XTestFactory.hpp>
+
+using namespace ::test;
+using namespace ::rtl;
+using namespace ::cppu;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::bridge;
+using namespace ::com::sun::star::registry;
+using namespace ::com::sun::star::connection;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::text;
+
+#include "testcomp.h"
+
+#ifdef SAL_W32
+#include <conio.h>
+#endif
+
+
+void mygetchar()
+{
+#ifdef SAL_W32
+ _getch();
+#else
+ getchar();
+#endif
+}
+
+
+void testPipe( const Reference < XMultiServiceFactory > & rSmgr )
+{
+ Reference < XOutputStream > rOut(
+ rSmgr->createInstance( OUString::createFromAscii( "com.sun.star.io.Pipe" ) ),
+ UNO_QUERY );
+
+ OSL_ASSERT( rOut.is() );
+
+ {
+ Sequence < sal_Int8 > seq( 10 );
+ seq.getArray()[0] = 42;
+ rOut->writeBytes( seq );
+ }
+
+
+ {
+ Sequence < sal_Int8 > seq;
+ Reference < XInputStream > rIn( rOut , UNO_QUERY );
+ if( ! ( rIn->available() == 10) )
+ printf( "wrong bytes available\n" );
+ if( ! ( rIn->readBytes( seq , 10 ) == 10 ) )
+ printf( "wrong bytes read\n" );
+ if( ! ( 42 == seq.getArray()[0] ) )
+ printf( "wrong element in sequence\n" );
+
+// OSL_ASSERT( 0 );
+ }
+}
+#include<stdio.h>
+#include<string.h>
+
+void testWriter( const Reference < XComponent > & rCmp )
+{
+
+ Reference< XTextDocument > rTextDoc( rCmp , UNO_QUERY );
+
+ Reference< XText > rText = rTextDoc->getText();
+ Reference< XTextCursor > rCursor = rText->createTextCursor();
+ Reference< XTextRange > rRange ( rCursor , UNO_QUERY );
+
+ char pcText[1024];
+ pcText[0] = 0;
+ printf( "pleast type any text\n" );
+ while( sal_True )
+ {
+ scanf( "%s" , pcText );
+
+ if( !strcmp( pcText , "end" ) )
+ {
+ break;
+ }
+
+ if ( strlen( pcText ) < sizeof(pcText)-1 )
+ strcat( pcText , " " ); // #100211# - checked
+
+ rText->insertString( rRange , OUString::createFromAscii( pcText ) , sal_False );
+ }
+}
+
+void testDocument( const Reference < XMultiServiceFactory > & rSmgr )
+{
+ Reference < XComponentLoader > rLoader(
+ rSmgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop" ))),
+ UNO_QUERY );
+
+ OSL_ASSERT( rLoader.is() );
+
+ sal_Char *urls[] = {
+ "private:factory/swriter",
+ "private:factory/scalc",
+ "private:factory/sdraw",
+ "http://www.heise.de",
+ "file://h|/remote_interfaces.sdw"
+ };
+
+ sal_Char *docu[]= {
+ "a new writer document ...\n",
+ "a new calc document ...\n",
+ "a new draw document ...\n",
+ "www.heise.de\n",
+ "the remote_interfaces.sdw doc\n"
+ };
+
+ sal_Int32 i;
+ for( i = 0 ; i < 1 ; i ++ )
+ {
+ printf( "press any key to open %s\n" , docu[i] );
+ mygetchar();
+
+ Reference< XComponent > rComponent =
+ rLoader->loadComponentFromURL(
+ OUString::createFromAscii( urls[i] ) ,
+ OUString( RTL_CONSTASCII_USTRINGPARAM("_blank")),
+ 0 ,
+ Sequence < ::com::sun::star::beans::PropertyValue >() );
+
+ testWriter( rComponent );
+ printf( "press any key to close the document\n" );
+ mygetchar();
+ rComponent->dispose();
+ }
+
+}
+
+void doSomething( const Reference < XInterface > &r )
+{
+ Reference < XNamingService > rName( r, UNO_QUERY );
+ if( rName.is() )
+ {
+ printf( "got the remote naming service !\n" );
+ Reference < XInterface > rXsmgr = rName->getRegisteredObject(
+ OUString::createFromAscii( "StarOffice.ServiceManager" ) );
+
+ Reference < XMultiServiceFactory > rSmgr( rXsmgr , UNO_QUERY );
+ if( rSmgr.is() )
+ {
+ printf( "got the remote service manager !\n" );
+ testPipe( rSmgr );
+ testDocument( rSmgr );
+ }
+ }
+}
+
+
+int main( int argc, char *argv[] )
+{
+ if( argc < 2 )
+ {
+ printf( "usage : testclient host:port" );
+ return 0;
+ }
+
+ OUString sConnectionString;
+ OUString sProtocol;
+ sal_Bool bLatency = sal_False;
+ sal_Bool bReverse = sal_False;
+ parseCommandLine( argv , &sConnectionString , &sProtocol , &bLatency , &bReverse );
+ {
+ Reference< XMultiServiceFactory > rSMgr = createRegistryServiceFactory(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "client.rdb" ) ) );
+
+ // just ensure that it is registered
+
+ Reference < XConnector > rConnector(
+ createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Connector")),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("connector.uno" SAL_DLLEXTENSION)),
+ rSMgr ),
+ UNO_QUERY );
+
+ createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.Bridge.iiop")),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("remotebridge.uno" SAL_DLLEXTENSION)),
+ rSMgr );
+
+ Reference < XBridgeFactory > rFactory(
+ createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.BridgeFactory")),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("bridgefac.uno" SAL_DLLEXTENSION)),
+ rSMgr ),
+ UNO_QUERY );
+
+ try
+ {
+ if( rFactory.is() && rConnector.is() )
+ {
+ Reference < XConnection > rConnection =
+ rConnector->connect( sConnectionString );
+
+ Reference < XBridge > rBridge = rFactory->createBridge(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("bla blub")),
+ sProtocol,
+ rConnection,
+ Reference < XInstanceProvider > () );
+
+ Reference < XInterface > rInitialObject
+ = rBridge->getInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("NamingService")) );
+
+ if( rInitialObject.is() )
+ {
+ printf( "got the remote object\n" );
+ doSomething( rInitialObject );
+ }
+ TimeValue value={2,0};
+ osl_waitThread( &value );
+ }
+ }
+ catch (... ) {
+ printf( "Exception thrown\n" );
+ }
+
+ Reference < XComponent > rComp( rSMgr , UNO_QUERY );
+ rComp->dispose();
+ }
+ //_getch();
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/test/testsameprocess.cxx b/bridges/test/testsameprocess.cxx
new file mode 100644
index 000000000000..35003986e386
--- /dev/null
+++ b/bridges/test/testsameprocess.cxx
@@ -0,0 +1,218 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <osl/time.h>
+
+#include <osl/mutex.hxx>
+#include <osl/thread.hxx>
+
+#include <cppuhelper/servicefactory.hxx>
+
+#include <com/sun/star/bridge/XBridgeFactory.hpp>
+#include <com/sun/star/connection/XAcceptor.hpp>
+#include <com/sun/star/connection/XConnector.hpp>
+
+#include <com/sun/star/lang/XComponent.hpp>
+
+#include <cppuhelper/weak.hxx>
+
+#include <test/XTestFactory.hpp>
+
+
+using namespace ::test;
+using namespace ::rtl;
+using namespace ::cppu;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::bridge;
+using namespace ::com::sun::star::connection;
+
+#ifdef SAL_W32
+#include <conio.h>
+#endif
+
+#include "testcomp.h"
+#include "osl/mutex.h"
+
+/*********
+ *
+ ********/
+
+class MyThread :
+ public Thread
+{
+public:
+ MyThread( const Reference< XAcceptor > &r ,
+ const Reference< XBridgeFactory > &rFactory,
+ const OUString &sConnectionDescription) :
+ m_rAcceptor( r ),
+ m_rBridgeFactory ( rFactory ),
+ m_sConnectionDescription( sConnectionDescription )
+ {}
+ virtual void SAL_CALL run();
+
+private:
+ Reference < XAcceptor > m_rAcceptor;
+ Reference < XBridgeFactory > m_rBridgeFactory;
+ OUString m_sConnectionDescription;
+};
+
+
+
+void MyThread::run()
+{
+
+ while ( sal_True )
+ {
+ try
+ {
+ Reference < XConnection > rConnection =
+ m_rAcceptor->accept( m_sConnectionDescription );
+
+ if( ! rConnection.is() )
+ {
+ break;
+ }
+
+ Reference < XBridge > rBridge =
+ m_rBridgeFactory->createBridge(
+ OUString() ,
+ OUString( RTL_CONSTASCII_USTRINGPARAM("iiop")) ,
+ rConnection ,
+ (XInstanceProvider * ) new OInstanceProvider );
+
+
+ }
+ catch ( ... )
+ {
+ printf( "Exception was thrown by acceptor thread\n" );
+ break;
+ }
+ }
+}
+
+
+int main( int argc, char *argv[] )
+{
+ if( argc < 2 )
+ {
+ printf( "usage : testsamprocess host:port\n" );
+ return 0;
+ }
+
+ {
+ Reference< XMultiServiceFactory > rSMgr = createRegistryServiceFactory(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "client.rdb" ) ) );
+
+ Reference < XConnector > rConnector(
+ createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Connector")),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("connector.uno" SAL_DLLEXTENSION)),
+ rSMgr ),
+ UNO_QUERY );
+
+ Reference < XAcceptor > rAcceptor(
+ createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Acceptor")),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("acceptor.uno" SAL_DLLEXTENSION)),
+ rSMgr ),
+ UNO_QUERY );
+
+ // just ensure that it is registered
+// createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.Bridge.iiop")),
+// OUString( RTL_CONSTASCII_USTRINGPARAM("iiopbrdg" SAL_DLLEXTENSION)),
+// rSMgr );
+
+ Reference < XBridgeFactory > rFactory(
+ createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.BridgeFactory")),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("bridgefac.uno" SAL_DLLEXTENSION)),
+ rSMgr ),
+ UNO_QUERY );
+
+
+ MyThread threadAcceptor( rAcceptor , rFactory , OUString::createFromAscii( argv[1] ) );
+
+ threadAcceptor.create();
+ TimeValue value={2,0};
+ osl_waitThread( &value );
+
+ try
+ {
+ Reference < XConnection > rConnection =
+ rConnector->connect( OUString::createFromAscii( argv[1] ) );
+
+ printf( "%s\n" , OUStringToOString( rConnection->getDescription(),
+ RTL_TEXTENCODING_ASCII_US ).pData->buffer );
+
+ if( rFactory.is() )
+ {
+
+ Reference < XBridge > rBridge = rFactory->createBridge(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("bla blub")),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("iiop")),
+ rConnection,
+ Reference < XInstanceProvider > () );
+
+ Reference < XInterface > rInitialObject
+ = rBridge->getInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("bla")) );
+
+ if( rInitialObject.is() )
+ {
+ printf( "got the remote object\n" );
+ testRemote( rInitialObject );
+ }
+ printf( "Closing...\n" );
+ TimeValue timeValue={2,0};
+ osl_waitThread( &timeValue );
+ }
+
+ Reference < XBridge > rBridge = rFactory->getBridge(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("bla blub")) );
+ OSL_ASSERT( ! rBridge.is() );
+
+ }
+ catch( Exception & )
+ {
+ printf( "Login failed, got an Exception !\n" );
+ }
+
+ rAcceptor->stopAccepting();
+ threadAcceptor.join();
+
+ Reference < XComponent > rComp( rFactory , UNO_QUERY );
+ rComp->dispose();
+
+
+ rComp = Reference < XComponent > ( rSMgr , UNO_QUERY );
+ rComp->dispose();
+ }
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/test/testserver.cxx b/bridges/test/testserver.cxx
new file mode 100644
index 000000000000..1e9b70cf13d3
--- /dev/null
+++ b/bridges/test/testserver.cxx
@@ -0,0 +1,256 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_bridges.hxx"
+#include <string.h>
+#include <osl/time.h>
+
+#include <osl/mutex.hxx>
+#include <osl/conditn.h>
+
+#include <osl/thread.hxx>
+
+#include <cppuhelper/servicefactory.hxx>
+#include <cppuhelper/implbase1.hxx>
+
+#include <com/sun/star/connection/XAcceptor.hpp>
+#include <com/sun/star/connection/XConnection.hpp>
+
+#include <com/sun/star/bridge/XInstanceProvider.hpp>
+#include <com/sun/star/bridge/XBridgeFactory.hpp>
+
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+
+
+#include <test/XTestFactory.hpp>
+
+#include <cppuhelper/weak.hxx>
+
+using namespace ::test;
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::cppu;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::bridge;
+using namespace ::com::sun::star::connection;
+#include "testcomp.h"
+#ifdef SAL_W32
+#include <conio.h>
+#endif
+
+/*********
+ *
+ ********/
+
+
+
+class MyThread :
+ public Thread
+{
+public:
+ MyThread( const Reference< XAcceptor > &r ,
+ const Reference< XBridgeFactory > &rFactory,
+ const Reference< XMultiServiceFactory > &rSMgr,
+ const OUString &sConnectionDescription,
+ const OUString &sProtocol,
+ sal_Bool bReverse,
+ sal_Bool bLatency ) :
+ m_rAcceptor( r ),
+ m_rBridgeFactory ( rFactory ),
+ m_rSMgr( rSMgr ),
+ m_sConnectionDescription( sConnectionDescription ),
+ m_sProtocol( sProtocol ),
+ m_bReverse( bReverse ),
+ m_bLatency( bLatency )
+ {}
+ virtual void SAL_CALL run();
+
+ void latencyTest( const Reference< XConnection > &r );
+
+private:
+ Reference < XAcceptor > m_rAcceptor;
+ Reference < XBridgeFactory > m_rBridgeFactory;
+ Reference < XMultiServiceFactory > m_rSMgr;
+ OUString m_sConnectionDescription;
+ OUString m_sProtocol;
+ sal_Bool m_bReverse;
+ sal_Bool m_bLatency;
+};
+
+
+void MyThread::latencyTest( const Reference< XConnection > &r )
+{
+ Sequence < sal_Int8 > s;
+ while( 12 == r->read( s , 12 ) )
+ {
+ r->read( s , 188 );
+ s = Sequence < sal_Int8 >(60);
+ r->write( s );
+ }
+}
+
+void MyThread::run()
+{
+
+ while ( sal_True )
+ {
+ try
+ {
+ Reference < XConnection > rConnection =
+ m_rAcceptor->accept( m_sConnectionDescription );
+
+ if( ! rConnection.is() )
+ {
+ break;
+ }
+ if( m_bLatency )
+ {
+ latencyTest( rConnection );
+ }
+ else
+ {
+
+ Reference < XBridge > rBridge =
+ m_rBridgeFactory->createBridge(
+ OUString() ,
+ m_sProtocol,
+ rConnection ,
+ (XInstanceProvider * ) new OInstanceProvider(m_rSMgr) );
+
+
+ if( m_bReverse )
+ {
+ printf( "doing reverse callme test (test is ok, when on each line a +- appears\n" );
+ Reference < XInterface > r = rBridge->getInstance(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("blubber" )));
+ Reference < XTestFactory > rFactory( r , UNO_QUERY );
+ Reference < XCallMe > rCallMe = rFactory->createCallMe();
+
+ for( sal_Int32 i = 0 ; i < 1 ; i ++ )
+ {
+ rCallMe->callOneway(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("my test string")) , 2 );
+ }
+ printf( "all oneway are send\n" );
+ rCallMe->call( OUString::createFromAscii( "reverse call me test finished" ) , 0 );
+ printf( "revers callme test finished\n" );
+ }
+ }
+ }
+ catch ( Exception & e )
+ {
+ printf( "Exception was thrown by acceptor \n" );
+ OString o = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US );
+ printf( "%s\n" , o.getStr() );
+ break;
+ }
+ catch ( ... )
+ {
+ printf( "Exception was thrown by acceptor thread\n" );
+ break;
+ }
+ }
+}
+
+
+int main( int argc, char *argv[] )
+{
+// testserver();
+
+ if( argc < 2 )
+ {
+ printf( "usage : testserver [-r] connectionstring\n"
+ " -r does a reverse test (server calls client)\n" );
+ return 0;
+ }
+
+ OUString sConnectionString;
+ OUString sProtocol;
+ sal_Bool bReverse = sal_False;
+ sal_Bool bLatency = sal_False;
+
+ parseCommandLine( argv , &sConnectionString , &sProtocol , &bLatency , &bReverse );
+
+ {
+ Reference< XMultiServiceFactory > rSMgr = createRegistryServiceFactory(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "server.rdb" ) ) );
+
+ Reference < XBridgeFactory > rBridgeFactory ( createComponent(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.BridgeFactory")),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("bridgefac.uno" SAL_DLLEXTENSION )),
+ rSMgr ),
+ UNO_QUERY );
+
+
+ createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.Bridge.iiop")),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("remotebridge.uno" SAL_DLLEXTENSION)),
+ rSMgr );
+
+
+ Reference < XAcceptor > rAcceptor(
+ createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Acceptor")),
+ OUString( RTL_CONSTASCII_USTRINGPARAM("acceptor.uno" SAL_DLLEXTENSION)),
+ rSMgr ) ,
+ UNO_QUERY );
+
+ MyThread thread( rAcceptor ,
+ rBridgeFactory,
+ rSMgr,
+ sConnectionString,
+ sProtocol,
+ bReverse,
+ bLatency);
+ thread.create();
+
+#ifdef SAL_W32
+ _getch();
+#elif SOLARIS
+ getchar();
+#elif LINUX
+ TimeValue value={360,0};
+ osl_waitThread( &value );
+#endif
+ printf( "Closing...\n" );
+
+ rAcceptor->stopAccepting();
+ thread.join();
+
+ printf( "Closed\n" );
+
+ Reference < XComponent > rComp2( rBridgeFactory , UNO_QUERY );
+ rComp2->dispose();
+ Reference < XComponent > rComp( rSMgr, UNO_QUERY );
+ rComp->dispose();
+ }
+ return 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/unotypes/makefile.mk b/bridges/unotypes/makefile.mk
new file mode 100644
index 000000000000..d775638ac4af
--- /dev/null
+++ b/bridges/unotypes/makefile.mk
@@ -0,0 +1,63 @@
+#*************************************************************************
+#
+# 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=unotypes
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+#-------------------------------------------------------------------
+
+CPPUMAKERFLAGS += -C
+UNOUCRDEP=$(SOLARBINDIR)$/udkapi.rdb
+UNOUCRRDB=$(SOLARBINDIR)$/udkapi.rdb
+UNOUCROUT=$(OUT)$/inc
+
+UNOTYPES = \
+ com.sun.star.bridge.XProtocolProperties \
+ com.sun.star.corba.giop.MessageHeader_1_2 \
+ com.sun.star.corba.giop.MsgType_1_1 \
+ com.sun.star.corba.iop.ServiceContextList \
+ com.sun.star.corba.iop.ProfileIdGroup \
+ com.sun.star.corba.iiop.ProfileBody_1_1 \
+ com.sun.star.corba.LogicalThreadID \
+ com.sun.star.corba.iop.ServiceIdGroup \
+ com.sun.star.corba.giop.ReplyHeader_1_2 \
+ com.sun.star.corba.giop.RequestHeader_1_2 \
+ com.sun.star.corba.TCKind \
+ com.sun.star.corba.ObjectKey \
+ com.sun.star.uno.XInterface \
+ com.sun.star.lang.DisposedException \
+ com.sun.star.uno.TypeClass
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/bridges/version.mk b/bridges/version.mk
new file mode 100644
index 000000000000..57c4c7f2a306
--- /dev/null
+++ b/bridges/version.mk
@@ -0,0 +1,40 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+# target
+RMCXT_TARGET=rmcxt
+
+# the major
+RMCXT_MAJOR=2
+# the minor
+RMCXT_MINOR=0
+# the micro
+RMCXT_MICRO=0
+
+# this is a c++ compatible library
+RMCXT_CPP=0
+