1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: urp_marshal.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_bridges.hxx"
34 #include <osl/diagnose.h>
35 #include <rtl/alloc.h>
38 #include <uno/sequence2.h>
40 #include "urp_marshal.hxx"
42 using namespace ::rtl
;
44 using namespace ::com::sun::star::uno
;
46 namespace bridges_urp
{
48 static int g_nDetectLittleEndian
= 1;
49 char g_bMarshalSystemIsLittleEndian
= ((char*)&g_nDetectLittleEndian
)[0];
51 Marshal::Marshal( urp_BridgeImpl
*pBridgeImpl
,
52 sal_Int32 nBufferSize
,
53 urp_extractOidCallback callback
) :
54 m_nBufferSize( nBufferSize
),
55 m_base( (sal_Int8
*)rtl_allocateMemory( nBufferSize
) ),
56 m_pos( m_base
+ 2*sizeof( sal_Int32
) ),
57 m_pBridgeImpl( pBridgeImpl
),
58 m_callback( callback
)
63 rtl_freeMemory( m_base
);
66 void Marshal::packOid( const ::rtl::OUString
& oid
)
71 nIndex
= m_pBridgeImpl
->m_oidCacheOut
.seek( oid
);
72 if( 0xffff == nIndex
)
74 nIndex
= m_pBridgeImpl
->m_oidCacheOut
.put( oid
);
75 packString( (void*)(&oid
.pData
) );
93 void Marshal::packTid( const ByteSequence
& threadId
, sal_Bool bIgnoreCache
)
96 sal_uInt16 nIndex
= 0xffff;
99 nIndex
= m_pBridgeImpl
->m_tidCacheOut
.seek( threadId
);
102 if( 0xffff == nIndex
)
106 nIndex
= m_pBridgeImpl
->m_tidCacheOut
.put( threadId
);
108 packByteSequence( (sal_Int8
*) threadId
.getConstArray() ,threadId
.getLength());
112 packByteSequence( 0 , 0 );
114 packInt16( &nIndex
);
118 void Marshal::packType( void *pSource
)
120 typelib_TypeDescriptionReference
*pRef
=
121 *(typelib_TypeDescriptionReference
** ) pSource
;
125 sal_uInt8 nTypeClass
= ( sal_uInt8
) pRef
->eTypeClass
;
127 if( nTypeClass
<= /* any*/ 14 )
129 packInt8( (sal_Int8
*)&nTypeClass
);
134 sal_uInt16 nIndex
= 0xffff;
136 nIndex
= m_pBridgeImpl
->m_typeCacheOut
.seek( *(Type
*)&pRef
);
137 if( 0xffff == nIndex
)
139 // put it into the cache
140 nIndex
= m_pBridgeImpl
->m_typeCacheOut
.put( *(Type
*)&pRef
);
141 sTypeName
= pRef
->pTypeName
;
142 nTypeClass
= nTypeClass
| 0x80;
144 packInt8( &nTypeClass
);
145 packInt16( &nIndex
);
146 if( 0x80 & nTypeClass
)
148 packString( &sTypeName
);
153 sal_Bool
Marshal::packRecursive( void *pSource
, typelib_TypeDescription
*pType
)
155 sal_Bool bSuccess
= sal_True
;
156 switch( pType
->eTypeClass
)
158 case typelib_TypeClass_EXCEPTION
:
159 case typelib_TypeClass_STRUCT
:
161 typelib_CompoundTypeDescription
* pCompType
= (typelib_CompoundTypeDescription
*)pType
;
163 if (pCompType
->pBaseTypeDescription
)
165 bSuccess
= pack( pSource
, (typelib_TypeDescription
*) pCompType
->pBaseTypeDescription
);
168 // then construct members
169 typelib_TypeDescriptionReference
** ppTypeRefs
= pCompType
->ppTypeRefs
;
170 sal_Int32
* pMemberOffsets
= pCompType
->pMemberOffsets
;
171 sal_Int32 nDescr
= pCompType
->nMembers
;
173 for ( sal_Int32 nPos
= 0; nPos
< nDescr
; ++nPos
)
175 typelib_TypeDescription
* pMemberType
= 0;
176 TYPELIB_DANGER_GET( &pMemberType
, ppTypeRefs
[nPos
] );
179 bSuccess
= bSuccess
&& pack( (char*)pSource
+ pMemberOffsets
[nPos
] , pMemberType
);
180 TYPELIB_DANGER_RELEASE( pMemberType
);
184 OUStringBuffer
buf( 64 );
185 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("Couldn't get typedescription for type "));
186 buf
.append( ppTypeRefs
[nPos
]->pTypeName
);
187 m_pBridgeImpl
->addError( buf
.makeStringAndClear() );
188 bSuccess
= sal_False
;
193 case typelib_TypeClass_SEQUENCE
:
195 typelib_IndirectTypeDescription
*pIndirectType
=
196 ( typelib_IndirectTypeDescription
* ) pType
;
198 const sal_Int32 nElements
= (*(uno_Sequence
**)pSource
)->nElements
;
199 char * pSourceElements
= (char *)(*(uno_Sequence
**)pSource
)->elements
;
201 if( typelib_TypeClass_BYTE
== pIndirectType
->pType
->eTypeClass
)
203 // Byte sequences are optimized
204 packByteSequence( (sal_Int8
*)pSourceElements
, nElements
);
208 typelib_TypeDescription
*pElementType
= 0;
209 TYPELIB_DANGER_GET( &pElementType
, pIndirectType
->pType
);
212 const sal_Int32 nElementSize
= pElementType
->nSize
;
214 packCompressedSize( nElements
);
215 for ( sal_Int32 i
= 0 ; i
< nElements
; i
++ )
217 bSuccess
= bSuccess
&& pack( pSourceElements
+ (nElementSize
*i
) , pElementType
);
219 TYPELIB_DANGER_RELEASE( pElementType
);
223 bSuccess
= sal_False
;
224 OUStringBuffer
buf( 64 );
225 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("Couldn't get typedescription for type "));
226 buf
.append( pIndirectType
->pType
->pTypeName
);
227 m_pBridgeImpl
->addError( buf
.makeStringAndClear() );
238 } // end namespace bridges