Update ooo320-m1
[ooovba.git] / bridges / source / remote / urp / urp_marshal.cxx
blob704d47c0a44044a1e314739b950fba7eb6f13997
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: urp_marshal.cxx,v $
10 * $Revision: 1.7 $
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"
33 #include <string.h>
34 #include <osl/diagnose.h>
35 #include <rtl/alloc.h>
37 #include <uno/any2.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 )
61 Marshal::~Marshal( )
63 rtl_freeMemory( m_base );
66 void Marshal::packOid( const ::rtl::OUString & oid )
68 sal_uInt16 nIndex;
69 if( oid.getLength() )
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) );
77 else
79 OUString dummy;
80 packString( &dummy );
83 else
85 // null reference
86 nIndex = 0xffff;
87 OUString dummy;
88 packString( &dummy );
90 packInt16( &nIndex );
93 void Marshal::packTid( const ByteSequence & threadId, sal_Bool bIgnoreCache )
96 sal_uInt16 nIndex = 0xffff;
97 if( ! bIgnoreCache )
99 nIndex = m_pBridgeImpl->m_tidCacheOut.seek( threadId );
102 if( 0xffff == nIndex )
104 if( ! bIgnoreCache )
106 nIndex = m_pBridgeImpl->m_tidCacheOut.put( threadId );
108 packByteSequence( (sal_Int8*) threadId.getConstArray() ,threadId.getLength());
110 else
112 packByteSequence( 0 , 0 );
114 packInt16( &nIndex );
118 void Marshal::packType( void *pSource )
120 typelib_TypeDescriptionReference *pRef =
121 *(typelib_TypeDescriptionReference ** ) pSource;
123 OSL_ASSERT( pRef );
125 sal_uInt8 nTypeClass = ( sal_uInt8 ) pRef->eTypeClass;
127 if( nTypeClass <= /* any*/ 14 )
129 packInt8( (sal_Int8*)&nTypeClass );
131 else
133 OUString sTypeName;
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] );
177 if( pMemberType )
179 bSuccess = bSuccess && pack( (char*)pSource + pMemberOffsets[nPos] , pMemberType );
180 TYPELIB_DANGER_RELEASE( pMemberType );
182 else
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;
191 break;
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 );
206 else
208 typelib_TypeDescription *pElementType = 0;
209 TYPELIB_DANGER_GET( &pElementType, pIndirectType->pType );
210 if( pElementType )
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 );
221 else
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() );
230 break;
232 default:
233 OSL_ASSERT( 0 );
235 return bSuccess;
238 } // end namespace bridges