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.hxx,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 ************************************************************************/
30 #ifndef _URP_MARSHAL_HXX_
31 #define _URP_MARSHAL_HXX_
32 #include <rtl/ustrbuf.hxx>
33 #include <rtl/byteseq.hxx>
34 #include <com/sun/star/uno/Type.hxx>
35 #include "urp_bridgeimpl.hxx"
36 #include "urp_marshal_decl.hxx"
40 struct remote_Interface
;
44 // methods for accessing marshaling buffer
45 inline void Marshal::finish( sal_Int32 nMessageCount
)
47 sal_Int32 nSize
= getSize() - 2*sizeof( sal_Int32
);
50 sal_Int8
*pos
= m_pos
;
53 packInt32( &nMessageCount
);
59 inline void Marshal::restart()
61 m_pos
= m_base
+ 2*sizeof( sal_Int32
);
64 inline sal_Int8
*Marshal::getBuffer()
69 inline sal_Bool
Marshal::empty() const
71 return ( m_pos
- m_base
) == 2*sizeof( sal_Int32
);
74 inline sal_Int32
Marshal::getSize()
76 return ((sal_Int32
) (m_pos
- m_base
));
79 inline void Marshal::ensureAdditionalMem( sal_Int32 nMemToAdd
)
81 sal_Int32 nDiff
= m_pos
- m_base
;
82 if( nDiff
+ nMemToAdd
> m_nBufferSize
)
84 m_nBufferSize
= m_nBufferSize
* 2 > nDiff
+ nMemToAdd
?
88 m_base
= ( sal_Int8
* ) rtl_reallocateMemory( m_base
, m_nBufferSize
);
89 m_pos
= m_base
+ nDiff
;
94 inline void Marshal::packInt8( void *pSource
)
96 ensureAdditionalMem( 1 );
97 *m_pos
= *((sal_Int8
*) pSource
);
101 inline void Marshal::packInt16( void *pSource
)
103 ensureAdditionalMem( 2 );
104 if( isSystemLittleEndian() )
106 m_pos
[0] = ((unsigned char *)pSource
)[1];
107 m_pos
[1] = ((unsigned char *)pSource
)[0];
111 m_pos
[1] = ((unsigned char *)pSource
)[1];
112 m_pos
[0] = ((unsigned char *)pSource
)[0];
117 inline void Marshal::packByteSequence( sal_Int8
*pData
, sal_Int32 nLength
)
119 packCompressedSize( nLength
);
121 ensureAdditionalMem( nLength
);
122 memcpy( m_pos
, pData
, nLength
);
126 inline void Marshal::packString( void *pSource
)
128 rtl_uString
*p
= *( rtl_uString
** ) pSource
;
131 // static buffer in marshal
132 ::rtl::OString o
= ::rtl::OUStringToOString( p
, RTL_TEXTENCODING_UTF8
);
133 sal_Int32 nLength
= o
.pData
->length
;
134 packCompressedSize( nLength
);
136 ensureAdditionalMem( nLength
);
138 memcpy( m_pos
, o
.pData
->buffer
, nLength
);
142 inline sal_Bool
Marshal::packAny( void *pSource
)
144 sal_Bool bSuccess
= sal_True
;
145 uno_Any
*pAny
= (uno_Any
* ) pSource
;
148 packType( &( pAny
->pType
) );
150 typelib_TypeDescription
*pType
= 0;
151 TYPELIB_DANGER_GET( &pType
, pAny
->pType
);
154 pack( pAny
->pData
, pType
);
155 TYPELIB_DANGER_RELEASE( pType
);
159 rtl::OUStringBuffer
buf( 128 );
160 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("couldn't get typedescription for type " ) );
161 buf
.append( pAny
->pType
->pTypeName
);
162 m_pBridgeImpl
->addError( buf
.makeStringAndClear() );
163 bSuccess
= sal_False
;
168 inline void Marshal::packInt32( void *pSource
)
170 ensureAdditionalMem( 4 );
171 if( isSystemLittleEndian() )
173 m_pos
[0] = ((unsigned char *)pSource
)[3];
174 m_pos
[1] = ((unsigned char *)pSource
)[2];
175 m_pos
[2] = ((unsigned char *)pSource
)[1];
176 m_pos
[3] = ((unsigned char *)pSource
)[0];
179 m_pos
[3] = ((unsigned char *)pSource
)[3];
180 m_pos
[2] = ((unsigned char *)pSource
)[2];
181 m_pos
[1] = ((unsigned char *)pSource
)[1];
182 m_pos
[0] = ((unsigned char *)pSource
)[0];
187 inline void Marshal::packCompressedSize( sal_Int32 nSize
)
189 ensureAdditionalMem( 5 );
193 *((sal_uInt8
*)m_pos
) = (sal_uInt8
) nSize
;
198 *((sal_uInt8
*)m_pos
) = 0xff;
204 inline sal_Bool
Marshal::pack( void *pSource
, typelib_TypeDescription
*pType
)
206 sal_Bool bSuccess
= sal_True
;
207 switch( pType
->eTypeClass
)
209 case typelib_TypeClass_BYTE
:
214 case typelib_TypeClass_BOOLEAN
:
216 ensureAdditionalMem( 1 );
217 *m_pos
= ( *((sal_Bool
*) pSource
) ) ? 1 : 0;
222 case typelib_TypeClass_CHAR
:
223 case typelib_TypeClass_SHORT
:
224 case typelib_TypeClass_UNSIGNED_SHORT
:
226 packInt16( pSource
);
229 case typelib_TypeClass_ENUM
:
230 case typelib_TypeClass_LONG
:
231 case typelib_TypeClass_UNSIGNED_LONG
:
232 case typelib_TypeClass_FLOAT
:
234 packInt32( pSource
);
237 case typelib_TypeClass_DOUBLE
:
238 case typelib_TypeClass_HYPER
:
239 case typelib_TypeClass_UNSIGNED_HYPER
:
241 ensureAdditionalMem( 8 );
242 if( isSystemLittleEndian() )
244 m_pos
[0] = ((unsigned char *)pSource
)[7];
245 m_pos
[1] = ((unsigned char *)pSource
)[6];
246 m_pos
[2] = ((unsigned char *)pSource
)[5];
247 m_pos
[3] = ((unsigned char *)pSource
)[4];
248 m_pos
[4] = ((unsigned char *)pSource
)[3];
249 m_pos
[5] = ((unsigned char *)pSource
)[2];
250 m_pos
[6] = ((unsigned char *)pSource
)[1];
251 m_pos
[7] = ((unsigned char *)pSource
)[0];
255 m_pos
[7] = ((unsigned char *)pSource
)[7];
256 m_pos
[6] = ((unsigned char *)pSource
)[6];
257 m_pos
[5] = ((unsigned char *)pSource
)[5];
258 m_pos
[4] = ((unsigned char *)pSource
)[4];
259 m_pos
[3] = ((unsigned char *)pSource
)[3];
260 m_pos
[2] = ((unsigned char *)pSource
)[2];
261 m_pos
[1] = ((unsigned char *)pSource
)[1];
262 m_pos
[0] = ((unsigned char *)pSource
)[0];
268 case typelib_TypeClass_STRING
:
270 packString( pSource
);
273 case typelib_TypeClass_TYPE
:
278 case typelib_TypeClass_ANY
:
280 bSuccess
= packAny( pSource
);
283 case typelib_TypeClass_TYPEDEF
:
285 bSuccess
= sal_False
;
286 m_pBridgeImpl
->addError( "can't handle typedef typedescriptions" );
289 case typelib_TypeClass_INTERFACE
:
291 remote_Interface
*pRemoteI
= *( remote_Interface
** )pSource
;
293 ::rtl::OUString sOid
;
294 sal_uInt16 nIndex
= 0xffff;
297 m_callback( pRemoteI
, &(sOid
.pData
) );
299 nIndex
= m_pBridgeImpl
->m_oidCacheOut
.seek( sOid
);
300 if( 0xffff == nIndex
)
302 nIndex
= m_pBridgeImpl
->m_oidCacheOut
.put( sOid
);
307 sOid
= ::rtl::OUString();
311 packInt16( &nIndex
);
314 case typelib_TypeClass_VOID
:
319 case typelib_TypeClass_EXCEPTION
:
320 case typelib_TypeClass_STRUCT
:
321 case typelib_TypeClass_SEQUENCE
:
323 bSuccess
= packRecursive( pSource
, pType
);
328 bSuccess
= sal_False
;
329 rtl::OUStringBuffer
buf( 128 );
330 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM( "can't handle values with typeclass " ) );
331 buf
.append( (sal_Int32
) pType
->eTypeClass
, 10 );
332 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM( " (" ) );
333 buf
.append( pType
->pTypeName
);
334 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
335 m_pBridgeImpl
->addError( buf
.makeStringAndClear() );