xref: /aoo41x/main/binaryurp/source/marshal.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir *
3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir *
5*cdf0e10cSrcweir * Copyright 2000, 2011 Oracle and/or its affiliates.
6*cdf0e10cSrcweir *
7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir *
9*cdf0e10cSrcweir * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir *
11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir *
15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir *
21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir *
26*cdf0e10cSrcweir ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #include "sal/config.h"
29*cdf0e10cSrcweir 
30*cdf0e10cSrcweir #include <vector>
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir #include "boost/noncopyable.hpp"
33*cdf0e10cSrcweir #include "com/sun/star/uno/Reference.hxx"
34*cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp"
35*cdf0e10cSrcweir #include "com/sun/star/uno/Sequence.hxx"
36*cdf0e10cSrcweir #include "com/sun/star/uno/XInterface.hpp"
37*cdf0e10cSrcweir #include "cppu/unotype.hxx"
38*cdf0e10cSrcweir #include "osl/diagnose.h"
39*cdf0e10cSrcweir #include "rtl/byteseq.hxx"
40*cdf0e10cSrcweir #include "rtl/string.hxx"
41*cdf0e10cSrcweir #include "rtl/textcvt.h"
42*cdf0e10cSrcweir #include "rtl/textenc.h"
43*cdf0e10cSrcweir #include "rtl/ustring.h"
44*cdf0e10cSrcweir #include "rtl/ustring.hxx"
45*cdf0e10cSrcweir #include "sal/types.h"
46*cdf0e10cSrcweir #include "typelib/typeclass.h"
47*cdf0e10cSrcweir #include "typelib/typedescription.h"
48*cdf0e10cSrcweir #include "typelib/typedescription.hxx"
49*cdf0e10cSrcweir #include "uno/dispatcher.hxx"
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir #include "binaryany.hxx"
52*cdf0e10cSrcweir #include "bridge.hxx"
53*cdf0e10cSrcweir #include "cache.hxx"
54*cdf0e10cSrcweir #include "lessoperators.hxx"
55*cdf0e10cSrcweir #include "marshal.hxx"
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir namespace binaryurp {
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir namespace {
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir namespace css = com::sun::star;
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir void write64(std::vector< unsigned char > * buffer, sal_uInt64 value) {
64*cdf0e10cSrcweir     Marshal::write8(buffer, value >> 56);
65*cdf0e10cSrcweir     Marshal::write8(buffer, (value >> 48) & 0xFF);
66*cdf0e10cSrcweir     Marshal::write8(buffer, (value >> 40) & 0xFF);
67*cdf0e10cSrcweir     Marshal::write8(buffer, (value >> 32) & 0xFF);
68*cdf0e10cSrcweir     Marshal::write8(buffer, (value >> 24) & 0xFF);
69*cdf0e10cSrcweir     Marshal::write8(buffer, (value >> 16) & 0xFF);
70*cdf0e10cSrcweir     Marshal::write8(buffer, (value >> 8) & 0xFF);
71*cdf0e10cSrcweir     Marshal::write8(buffer, value & 0xFF);
72*cdf0e10cSrcweir }
73*cdf0e10cSrcweir 
74*cdf0e10cSrcweir void writeCompressed(std::vector< unsigned char > * buffer, sal_uInt32 value) {
75*cdf0e10cSrcweir     if (value < 0xFF) {
76*cdf0e10cSrcweir         Marshal::write8(buffer, static_cast< sal_uInt8 >(value));
77*cdf0e10cSrcweir     } else {
78*cdf0e10cSrcweir         Marshal::write8(buffer, 0xFF);
79*cdf0e10cSrcweir         Marshal::write32(buffer, value);
80*cdf0e10cSrcweir     }
81*cdf0e10cSrcweir }
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir void writeString(
84*cdf0e10cSrcweir     std::vector< unsigned char > * buffer, rtl::OUString const & value)
85*cdf0e10cSrcweir {
86*cdf0e10cSrcweir     OSL_ASSERT(buffer != 0);
87*cdf0e10cSrcweir     rtl::OString v;
88*cdf0e10cSrcweir     if (!value.convertToString(
89*cdf0e10cSrcweir             &v, RTL_TEXTENCODING_UTF8,
90*cdf0e10cSrcweir             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
91*cdf0e10cSrcweir              RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
92*cdf0e10cSrcweir     {
93*cdf0e10cSrcweir         throw css::uno::RuntimeException(
94*cdf0e10cSrcweir             rtl::OUString(
95*cdf0e10cSrcweir                 RTL_CONSTASCII_USTRINGPARAM(
96*cdf0e10cSrcweir                     "UNO string contains invalid UTF-16 sequence")),
97*cdf0e10cSrcweir             css::uno::Reference< css::uno::XInterface >());
98*cdf0e10cSrcweir     }
99*cdf0e10cSrcweir     writeCompressed(buffer, static_cast< sal_uInt32 >(v.getLength()));
100*cdf0e10cSrcweir     buffer->insert(buffer->end(), v.getStr(), v.getStr() + v.getLength());
101*cdf0e10cSrcweir }
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir }
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir Marshal::Marshal(rtl::Reference< Bridge > const & bridge, WriterState & state):
106*cdf0e10cSrcweir     bridge_(bridge), state_(state)
107*cdf0e10cSrcweir {
108*cdf0e10cSrcweir     OSL_ASSERT(bridge.is());
109*cdf0e10cSrcweir }
110*cdf0e10cSrcweir 
111*cdf0e10cSrcweir Marshal::~Marshal() {}
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir void Marshal::write8(std::vector< unsigned char > * buffer, sal_uInt8 value) {
114*cdf0e10cSrcweir     OSL_ASSERT(buffer != 0);
115*cdf0e10cSrcweir     buffer->push_back(value);
116*cdf0e10cSrcweir }
117*cdf0e10cSrcweir 
118*cdf0e10cSrcweir void Marshal::write16(std::vector< unsigned char > * buffer, sal_uInt16 value) {
119*cdf0e10cSrcweir     write8(buffer, value >> 8);
120*cdf0e10cSrcweir     write8(buffer, value & 0xFF);
121*cdf0e10cSrcweir }
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir void Marshal::write32(std::vector< unsigned char > * buffer, sal_uInt32 value) {
124*cdf0e10cSrcweir     write8(buffer, value >> 24);
125*cdf0e10cSrcweir     write8(buffer, (value >> 16) & 0xFF);
126*cdf0e10cSrcweir     write8(buffer, (value >> 8) & 0xFF);
127*cdf0e10cSrcweir     write8(buffer, value & 0xFF);
128*cdf0e10cSrcweir }
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir void Marshal::writeValue(
131*cdf0e10cSrcweir     std::vector< unsigned char > * buffer,
132*cdf0e10cSrcweir     css::uno::TypeDescription const & type, BinaryAny const & value)
133*cdf0e10cSrcweir {
134*cdf0e10cSrcweir     OSL_ASSERT(
135*cdf0e10cSrcweir         type.is() &&
136*cdf0e10cSrcweir         (type.get()->eTypeClass == typelib_TypeClass_ANY ||
137*cdf0e10cSrcweir          value.getType().equals(type)));
138*cdf0e10cSrcweir     writeValue(buffer, type, value.getValue(type));
139*cdf0e10cSrcweir }
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir void Marshal::writeType(
142*cdf0e10cSrcweir     std::vector< unsigned char > * buffer,
143*cdf0e10cSrcweir     css::uno::TypeDescription const & value)
144*cdf0e10cSrcweir {
145*cdf0e10cSrcweir     value.makeComplete();
146*cdf0e10cSrcweir     OSL_ASSERT(value.is());
147*cdf0e10cSrcweir     typelib_TypeClass tc = value.get()->eTypeClass;
148*cdf0e10cSrcweir     if (tc <= typelib_TypeClass_ANY) {
149*cdf0e10cSrcweir         write8(buffer, static_cast< sal_uInt8 >(tc));
150*cdf0e10cSrcweir     } else {
151*cdf0e10cSrcweir         bool found;
152*cdf0e10cSrcweir         sal_uInt16 idx = state_.typeCache.add(value, &found);
153*cdf0e10cSrcweir         if (found) {
154*cdf0e10cSrcweir             write8(buffer, static_cast< sal_uInt8 >(tc));
155*cdf0e10cSrcweir             write16(buffer, idx);
156*cdf0e10cSrcweir         } else {
157*cdf0e10cSrcweir             write8(buffer, static_cast< sal_uInt8 >(tc) | 0x80);
158*cdf0e10cSrcweir             write16(buffer, idx);
159*cdf0e10cSrcweir             writeString(buffer, rtl::OUString(value.get()->pTypeName));
160*cdf0e10cSrcweir         }
161*cdf0e10cSrcweir     }
162*cdf0e10cSrcweir }
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir void Marshal::writeOid(
165*cdf0e10cSrcweir     std::vector< unsigned char > * buffer, rtl::OUString const & oid)
166*cdf0e10cSrcweir {
167*cdf0e10cSrcweir     bool found;
168*cdf0e10cSrcweir     sal_uInt16 idx;
169*cdf0e10cSrcweir     if (oid.getLength() == 0) {
170*cdf0e10cSrcweir         found = true;
171*cdf0e10cSrcweir         idx = cache::ignore;
172*cdf0e10cSrcweir     } else {
173*cdf0e10cSrcweir         idx = state_.oidCache.add(oid, &found);
174*cdf0e10cSrcweir     }
175*cdf0e10cSrcweir     if (found) {
176*cdf0e10cSrcweir         write8(buffer, 0);
177*cdf0e10cSrcweir     } else {
178*cdf0e10cSrcweir         writeString(buffer, oid);
179*cdf0e10cSrcweir     }
180*cdf0e10cSrcweir     write16(buffer, idx);
181*cdf0e10cSrcweir }
182*cdf0e10cSrcweir 
183*cdf0e10cSrcweir void Marshal::writeTid(
184*cdf0e10cSrcweir     std::vector< unsigned char > * buffer, rtl::ByteSequence const & tid)
185*cdf0e10cSrcweir {
186*cdf0e10cSrcweir     bool found;
187*cdf0e10cSrcweir     sal_uInt16 idx = state_.tidCache.add(tid, &found);
188*cdf0e10cSrcweir     if (found) {
189*cdf0e10cSrcweir         write8(buffer, 0);
190*cdf0e10cSrcweir     } else {
191*cdf0e10cSrcweir         sal_Sequence * p = tid.getHandle();
192*cdf0e10cSrcweir         writeValue(
193*cdf0e10cSrcweir             buffer,
194*cdf0e10cSrcweir             css::uno::TypeDescription(
195*cdf0e10cSrcweir                 cppu::UnoType< css::uno::Sequence< sal_Int8 > >::get()), &p);
196*cdf0e10cSrcweir     }
197*cdf0e10cSrcweir     write16(buffer, idx);
198*cdf0e10cSrcweir }
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir void Marshal::writeValue(
201*cdf0e10cSrcweir     std::vector< unsigned char > * buffer,
202*cdf0e10cSrcweir     css::uno::TypeDescription const & type, void const * value)
203*cdf0e10cSrcweir {
204*cdf0e10cSrcweir     OSL_ASSERT(buffer != 0 && type.is());
205*cdf0e10cSrcweir     type.makeComplete();
206*cdf0e10cSrcweir     switch (type.get()->eTypeClass) {
207*cdf0e10cSrcweir     case typelib_TypeClass_VOID:
208*cdf0e10cSrcweir         break;
209*cdf0e10cSrcweir     case typelib_TypeClass_BOOLEAN:
210*cdf0e10cSrcweir         OSL_ASSERT(*static_cast< sal_uInt8 const * >(value) <= 1);
211*cdf0e10cSrcweir         // fall through
212*cdf0e10cSrcweir     case typelib_TypeClass_BYTE:
213*cdf0e10cSrcweir         write8(buffer, *static_cast< sal_uInt8 const * >(value));
214*cdf0e10cSrcweir         break;
215*cdf0e10cSrcweir     case typelib_TypeClass_SHORT:
216*cdf0e10cSrcweir     case typelib_TypeClass_UNSIGNED_SHORT:
217*cdf0e10cSrcweir     case typelib_TypeClass_CHAR:
218*cdf0e10cSrcweir         write16(buffer, *static_cast< sal_uInt16 const * >(value));
219*cdf0e10cSrcweir         break;
220*cdf0e10cSrcweir     case typelib_TypeClass_LONG:
221*cdf0e10cSrcweir     case typelib_TypeClass_UNSIGNED_LONG:
222*cdf0e10cSrcweir     case typelib_TypeClass_FLOAT:
223*cdf0e10cSrcweir     case typelib_TypeClass_ENUM:
224*cdf0e10cSrcweir         write32(buffer, *static_cast< sal_uInt32 const * >(value));
225*cdf0e10cSrcweir         break;
226*cdf0e10cSrcweir     case typelib_TypeClass_HYPER:
227*cdf0e10cSrcweir     case typelib_TypeClass_UNSIGNED_HYPER:
228*cdf0e10cSrcweir     case typelib_TypeClass_DOUBLE:
229*cdf0e10cSrcweir         write64(buffer, *static_cast< sal_uInt64 const * >(value));
230*cdf0e10cSrcweir         break;
231*cdf0e10cSrcweir     case typelib_TypeClass_STRING:
232*cdf0e10cSrcweir         writeString(
233*cdf0e10cSrcweir             buffer,
234*cdf0e10cSrcweir             rtl::OUString(*static_cast< rtl_uString * const * >(value)));
235*cdf0e10cSrcweir         break;
236*cdf0e10cSrcweir     case typelib_TypeClass_TYPE:
237*cdf0e10cSrcweir         writeType(
238*cdf0e10cSrcweir             buffer,
239*cdf0e10cSrcweir             css::uno::TypeDescription(
240*cdf0e10cSrcweir                 *static_cast< typelib_TypeDescriptionReference * const * >(
241*cdf0e10cSrcweir                     value)));
242*cdf0e10cSrcweir         break;
243*cdf0e10cSrcweir     case typelib_TypeClass_ANY:
244*cdf0e10cSrcweir         {
245*cdf0e10cSrcweir             uno_Any const * p = static_cast< uno_Any const * >(value);
246*cdf0e10cSrcweir             css::uno::TypeDescription t(p->pType);
247*cdf0e10cSrcweir             writeType(buffer, t);
248*cdf0e10cSrcweir             writeValue(buffer, t, p->pData);
249*cdf0e10cSrcweir             break;
250*cdf0e10cSrcweir         }
251*cdf0e10cSrcweir     case typelib_TypeClass_SEQUENCE:
252*cdf0e10cSrcweir         {
253*cdf0e10cSrcweir             sal_Sequence * p = *static_cast< sal_Sequence * const * >(value);
254*cdf0e10cSrcweir             writeCompressed(buffer, static_cast< sal_uInt32 >(p->nElements));
255*cdf0e10cSrcweir             css::uno::TypeDescription ctd(
256*cdf0e10cSrcweir                 reinterpret_cast< typelib_IndirectTypeDescription * >(
257*cdf0e10cSrcweir                     type.get())->
258*cdf0e10cSrcweir                 pType);
259*cdf0e10cSrcweir             OSL_ASSERT(ctd.is());
260*cdf0e10cSrcweir             if (ctd.get()->eTypeClass == typelib_TypeClass_BYTE) {
261*cdf0e10cSrcweir                 buffer->insert(
262*cdf0e10cSrcweir                     buffer->end(), p->elements, p->elements + p->nElements);
263*cdf0e10cSrcweir             } else {
264*cdf0e10cSrcweir                 for (sal_Int32 i = 0; i != p->nElements; ++i) {
265*cdf0e10cSrcweir                     writeValue(buffer, ctd, p->elements + i * ctd.get()->nSize);
266*cdf0e10cSrcweir                 }
267*cdf0e10cSrcweir             }
268*cdf0e10cSrcweir             break;
269*cdf0e10cSrcweir         }
270*cdf0e10cSrcweir     case typelib_TypeClass_STRUCT:
271*cdf0e10cSrcweir     case typelib_TypeClass_EXCEPTION:
272*cdf0e10cSrcweir         writeMemberValues(buffer, type, value);
273*cdf0e10cSrcweir         break;
274*cdf0e10cSrcweir     case typelib_TypeClass_INTERFACE:
275*cdf0e10cSrcweir         writeOid(
276*cdf0e10cSrcweir             buffer,
277*cdf0e10cSrcweir             bridge_->registerOutgoingInterface(
278*cdf0e10cSrcweir                 css::uno::UnoInterfaceReference(
279*cdf0e10cSrcweir                     *static_cast< uno_Interface * const * >(value)),
280*cdf0e10cSrcweir                 type));
281*cdf0e10cSrcweir         break;
282*cdf0e10cSrcweir     default:
283*cdf0e10cSrcweir         OSL_ASSERT(false); // this cannot happen
284*cdf0e10cSrcweir         break;
285*cdf0e10cSrcweir     }
286*cdf0e10cSrcweir }
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir void Marshal::writeMemberValues(
289*cdf0e10cSrcweir     std::vector< unsigned char > * buffer,
290*cdf0e10cSrcweir     css::uno::TypeDescription const & type, void const * aggregateValue)
291*cdf0e10cSrcweir {
292*cdf0e10cSrcweir     OSL_ASSERT(
293*cdf0e10cSrcweir         type.is() &&
294*cdf0e10cSrcweir         (type.get()->eTypeClass == typelib_TypeClass_STRUCT ||
295*cdf0e10cSrcweir          type.get()->eTypeClass == typelib_TypeClass_EXCEPTION) &&
296*cdf0e10cSrcweir         aggregateValue != 0);
297*cdf0e10cSrcweir     type.makeComplete();
298*cdf0e10cSrcweir     typelib_CompoundTypeDescription * ctd =
299*cdf0e10cSrcweir         reinterpret_cast< typelib_CompoundTypeDescription * >(type.get());
300*cdf0e10cSrcweir     if (ctd->pBaseTypeDescription != 0) {
301*cdf0e10cSrcweir         writeMemberValues(
302*cdf0e10cSrcweir             buffer,
303*cdf0e10cSrcweir             css::uno::TypeDescription(&ctd->pBaseTypeDescription->aBase),
304*cdf0e10cSrcweir             aggregateValue);
305*cdf0e10cSrcweir     }
306*cdf0e10cSrcweir     for (sal_Int32 i = 0; i != ctd->nMembers; ++i) {
307*cdf0e10cSrcweir         writeValue(
308*cdf0e10cSrcweir             buffer, css::uno::TypeDescription(ctd->ppTypeRefs[i]),
309*cdf0e10cSrcweir             (static_cast< char const * >(aggregateValue) +
310*cdf0e10cSrcweir              ctd->pMemberOffsets[i]));
311*cdf0e10cSrcweir     }
312*cdf0e10cSrcweir }
313*cdf0e10cSrcweir 
314*cdf0e10cSrcweir }
315