xref: /aoo41x/main/binaryurp/source/marshal.cxx (revision 0848378b)
137adc4f0SAndrew Rist /**************************************************************
237adc4f0SAndrew Rist  *
337adc4f0SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
437adc4f0SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
537adc4f0SAndrew Rist  * distributed with this work for additional information
637adc4f0SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
737adc4f0SAndrew Rist  * to you under the Apache License, Version 2.0 (the
837adc4f0SAndrew Rist  * "License"); you may not use this file except in compliance
937adc4f0SAndrew Rist  * with the License.  You may obtain a copy of the License at
1037adc4f0SAndrew Rist  *
1137adc4f0SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1237adc4f0SAndrew Rist  *
1337adc4f0SAndrew Rist  * Unless required by applicable law or agreed to in writing,
1437adc4f0SAndrew Rist  * software distributed under the License is distributed on an
1537adc4f0SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1637adc4f0SAndrew Rist  * KIND, either express or implied.  See the License for the
1737adc4f0SAndrew Rist  * specific language governing permissions and limitations
1837adc4f0SAndrew Rist  * under the License.
1937adc4f0SAndrew Rist  *
2037adc4f0SAndrew Rist  *************************************************************/
2137adc4f0SAndrew Rist 
2237adc4f0SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "sal/config.h"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include <vector>
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include "boost/noncopyable.hpp"
29cdf0e10cSrcweir #include "com/sun/star/uno/Reference.hxx"
30cdf0e10cSrcweir #include "com/sun/star/uno/RuntimeException.hpp"
31cdf0e10cSrcweir #include "com/sun/star/uno/Sequence.hxx"
32cdf0e10cSrcweir #include "com/sun/star/uno/XInterface.hpp"
33cdf0e10cSrcweir #include "cppu/unotype.hxx"
34cdf0e10cSrcweir #include "osl/diagnose.h"
35cdf0e10cSrcweir #include "rtl/byteseq.hxx"
36cdf0e10cSrcweir #include "rtl/string.hxx"
37cdf0e10cSrcweir #include "rtl/textcvt.h"
38cdf0e10cSrcweir #include "rtl/textenc.h"
39cdf0e10cSrcweir #include "rtl/ustring.h"
40cdf0e10cSrcweir #include "rtl/ustring.hxx"
41cdf0e10cSrcweir #include "sal/types.h"
42cdf0e10cSrcweir #include "typelib/typeclass.h"
43cdf0e10cSrcweir #include "typelib/typedescription.h"
44cdf0e10cSrcweir #include "typelib/typedescription.hxx"
45cdf0e10cSrcweir #include "uno/dispatcher.hxx"
46cdf0e10cSrcweir 
47cdf0e10cSrcweir #include "binaryany.hxx"
48cdf0e10cSrcweir #include "bridge.hxx"
49cdf0e10cSrcweir #include "cache.hxx"
50cdf0e10cSrcweir #include "lessoperators.hxx"
51cdf0e10cSrcweir #include "marshal.hxx"
52cdf0e10cSrcweir 
53cdf0e10cSrcweir namespace binaryurp {
54cdf0e10cSrcweir 
55cdf0e10cSrcweir namespace {
56cdf0e10cSrcweir 
57cdf0e10cSrcweir namespace css = com::sun::star;
58cdf0e10cSrcweir 
write64(std::vector<unsigned char> * buffer,sal_uInt64 value)59cdf0e10cSrcweir void write64(std::vector< unsigned char > * buffer, sal_uInt64 value) {
60cdf0e10cSrcweir     Marshal::write8(buffer, value >> 56);
61cdf0e10cSrcweir     Marshal::write8(buffer, (value >> 48) & 0xFF);
62cdf0e10cSrcweir     Marshal::write8(buffer, (value >> 40) & 0xFF);
63cdf0e10cSrcweir     Marshal::write8(buffer, (value >> 32) & 0xFF);
64cdf0e10cSrcweir     Marshal::write8(buffer, (value >> 24) & 0xFF);
65cdf0e10cSrcweir     Marshal::write8(buffer, (value >> 16) & 0xFF);
66cdf0e10cSrcweir     Marshal::write8(buffer, (value >> 8) & 0xFF);
67cdf0e10cSrcweir     Marshal::write8(buffer, value & 0xFF);
68cdf0e10cSrcweir }
69cdf0e10cSrcweir 
writeCompressed(std::vector<unsigned char> * buffer,sal_uInt32 value)70cdf0e10cSrcweir void writeCompressed(std::vector< unsigned char > * buffer, sal_uInt32 value) {
71cdf0e10cSrcweir     if (value < 0xFF) {
72cdf0e10cSrcweir         Marshal::write8(buffer, static_cast< sal_uInt8 >(value));
73cdf0e10cSrcweir     } else {
74cdf0e10cSrcweir         Marshal::write8(buffer, 0xFF);
75cdf0e10cSrcweir         Marshal::write32(buffer, value);
76cdf0e10cSrcweir     }
77cdf0e10cSrcweir }
78cdf0e10cSrcweir 
writeString(std::vector<unsigned char> * buffer,rtl::OUString const & value)79cdf0e10cSrcweir void writeString(
80cdf0e10cSrcweir     std::vector< unsigned char > * buffer, rtl::OUString const & value)
81cdf0e10cSrcweir {
82cdf0e10cSrcweir     OSL_ASSERT(buffer != 0);
83cdf0e10cSrcweir     rtl::OString v;
84cdf0e10cSrcweir     if (!value.convertToString(
85cdf0e10cSrcweir             &v, RTL_TEXTENCODING_UTF8,
86cdf0e10cSrcweir             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
87cdf0e10cSrcweir              RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
88cdf0e10cSrcweir     {
89cdf0e10cSrcweir         throw css::uno::RuntimeException(
90cdf0e10cSrcweir             rtl::OUString(
91cdf0e10cSrcweir                 RTL_CONSTASCII_USTRINGPARAM(
92cdf0e10cSrcweir                     "UNO string contains invalid UTF-16 sequence")),
93cdf0e10cSrcweir             css::uno::Reference< css::uno::XInterface >());
94cdf0e10cSrcweir     }
95cdf0e10cSrcweir     writeCompressed(buffer, static_cast< sal_uInt32 >(v.getLength()));
96cdf0e10cSrcweir     buffer->insert(buffer->end(), v.getStr(), v.getStr() + v.getLength());
97cdf0e10cSrcweir }
98cdf0e10cSrcweir 
99cdf0e10cSrcweir }
100cdf0e10cSrcweir 
Marshal(rtl::Reference<Bridge> const & bridge,WriterState & state)101cdf0e10cSrcweir Marshal::Marshal(rtl::Reference< Bridge > const & bridge, WriterState & state):
102cdf0e10cSrcweir     bridge_(bridge), state_(state)
103cdf0e10cSrcweir {
104cdf0e10cSrcweir     OSL_ASSERT(bridge.is());
105cdf0e10cSrcweir }
106cdf0e10cSrcweir 
~Marshal()107cdf0e10cSrcweir Marshal::~Marshal() {}
108cdf0e10cSrcweir 
write8(std::vector<unsigned char> * buffer,sal_uInt8 value)109cdf0e10cSrcweir void Marshal::write8(std::vector< unsigned char > * buffer, sal_uInt8 value) {
110cdf0e10cSrcweir     OSL_ASSERT(buffer != 0);
111cdf0e10cSrcweir     buffer->push_back(value);
112cdf0e10cSrcweir }
113cdf0e10cSrcweir 
write16(std::vector<unsigned char> * buffer,sal_uInt16 value)114cdf0e10cSrcweir void Marshal::write16(std::vector< unsigned char > * buffer, sal_uInt16 value) {
115cdf0e10cSrcweir     write8(buffer, value >> 8);
116cdf0e10cSrcweir     write8(buffer, value & 0xFF);
117cdf0e10cSrcweir }
118cdf0e10cSrcweir 
write32(std::vector<unsigned char> * buffer,sal_uInt32 value)119cdf0e10cSrcweir void Marshal::write32(std::vector< unsigned char > * buffer, sal_uInt32 value) {
120cdf0e10cSrcweir     write8(buffer, value >> 24);
121cdf0e10cSrcweir     write8(buffer, (value >> 16) & 0xFF);
122cdf0e10cSrcweir     write8(buffer, (value >> 8) & 0xFF);
123cdf0e10cSrcweir     write8(buffer, value & 0xFF);
124cdf0e10cSrcweir }
125cdf0e10cSrcweir 
writeValue(std::vector<unsigned char> * buffer,css::uno::TypeDescription const & type,BinaryAny const & value)126cdf0e10cSrcweir void Marshal::writeValue(
127cdf0e10cSrcweir     std::vector< unsigned char > * buffer,
128cdf0e10cSrcweir     css::uno::TypeDescription const & type, BinaryAny const & value)
129cdf0e10cSrcweir {
130cdf0e10cSrcweir     OSL_ASSERT(
131cdf0e10cSrcweir         type.is() &&
132cdf0e10cSrcweir         (type.get()->eTypeClass == typelib_TypeClass_ANY ||
133cdf0e10cSrcweir          value.getType().equals(type)));
134cdf0e10cSrcweir     writeValue(buffer, type, value.getValue(type));
135cdf0e10cSrcweir }
136cdf0e10cSrcweir 
writeType(std::vector<unsigned char> * buffer,css::uno::TypeDescription const & value)137cdf0e10cSrcweir void Marshal::writeType(
138cdf0e10cSrcweir     std::vector< unsigned char > * buffer,
139cdf0e10cSrcweir     css::uno::TypeDescription const & value)
140cdf0e10cSrcweir {
141cdf0e10cSrcweir     value.makeComplete();
142cdf0e10cSrcweir     OSL_ASSERT(value.is());
143cdf0e10cSrcweir     typelib_TypeClass tc = value.get()->eTypeClass;
144cdf0e10cSrcweir     if (tc <= typelib_TypeClass_ANY) {
145cdf0e10cSrcweir         write8(buffer, static_cast< sal_uInt8 >(tc));
146cdf0e10cSrcweir     } else {
147cdf0e10cSrcweir         bool found;
148cdf0e10cSrcweir         sal_uInt16 idx = state_.typeCache.add(value, &found);
149cdf0e10cSrcweir         if (found) {
150cdf0e10cSrcweir             write8(buffer, static_cast< sal_uInt8 >(tc));
151cdf0e10cSrcweir             write16(buffer, idx);
152cdf0e10cSrcweir         } else {
153cdf0e10cSrcweir             write8(buffer, static_cast< sal_uInt8 >(tc) | 0x80);
154cdf0e10cSrcweir             write16(buffer, idx);
155cdf0e10cSrcweir             writeString(buffer, rtl::OUString(value.get()->pTypeName));
156cdf0e10cSrcweir         }
157cdf0e10cSrcweir     }
158cdf0e10cSrcweir }
159cdf0e10cSrcweir 
writeOid(std::vector<unsigned char> * buffer,rtl::OUString const & oid)160cdf0e10cSrcweir void Marshal::writeOid(
161cdf0e10cSrcweir     std::vector< unsigned char > * buffer, rtl::OUString const & oid)
162cdf0e10cSrcweir {
163cdf0e10cSrcweir     bool found;
164cdf0e10cSrcweir     sal_uInt16 idx;
165*0848378bSHerbert Dürr     if ( oid.isEmpty() ) {
166cdf0e10cSrcweir         found = true;
167cdf0e10cSrcweir         idx = cache::ignore;
168cdf0e10cSrcweir     } else {
169cdf0e10cSrcweir         idx = state_.oidCache.add(oid, &found);
170cdf0e10cSrcweir     }
171cdf0e10cSrcweir     if (found) {
172cdf0e10cSrcweir         write8(buffer, 0);
173cdf0e10cSrcweir     } else {
174cdf0e10cSrcweir         writeString(buffer, oid);
175cdf0e10cSrcweir     }
176cdf0e10cSrcweir     write16(buffer, idx);
177cdf0e10cSrcweir }
178cdf0e10cSrcweir 
writeTid(std::vector<unsigned char> * buffer,rtl::ByteSequence const & tid)179cdf0e10cSrcweir void Marshal::writeTid(
180cdf0e10cSrcweir     std::vector< unsigned char > * buffer, rtl::ByteSequence const & tid)
181cdf0e10cSrcweir {
182cdf0e10cSrcweir     bool found;
183cdf0e10cSrcweir     sal_uInt16 idx = state_.tidCache.add(tid, &found);
184cdf0e10cSrcweir     if (found) {
185cdf0e10cSrcweir         write8(buffer, 0);
186cdf0e10cSrcweir     } else {
187cdf0e10cSrcweir         sal_Sequence * p = tid.getHandle();
188cdf0e10cSrcweir         writeValue(
189cdf0e10cSrcweir             buffer,
190cdf0e10cSrcweir             css::uno::TypeDescription(
191cdf0e10cSrcweir                 cppu::UnoType< css::uno::Sequence< sal_Int8 > >::get()), &p);
192cdf0e10cSrcweir     }
193cdf0e10cSrcweir     write16(buffer, idx);
194cdf0e10cSrcweir }
195cdf0e10cSrcweir 
writeValue(std::vector<unsigned char> * buffer,css::uno::TypeDescription const & type,void const * value)196cdf0e10cSrcweir void Marshal::writeValue(
197cdf0e10cSrcweir     std::vector< unsigned char > * buffer,
198cdf0e10cSrcweir     css::uno::TypeDescription const & type, void const * value)
199cdf0e10cSrcweir {
200cdf0e10cSrcweir     OSL_ASSERT(buffer != 0 && type.is());
201cdf0e10cSrcweir     type.makeComplete();
202cdf0e10cSrcweir     switch (type.get()->eTypeClass) {
203cdf0e10cSrcweir     case typelib_TypeClass_VOID:
204cdf0e10cSrcweir         break;
205cdf0e10cSrcweir     case typelib_TypeClass_BOOLEAN:
206cdf0e10cSrcweir         OSL_ASSERT(*static_cast< sal_uInt8 const * >(value) <= 1);
207cdf0e10cSrcweir         // fall through
208cdf0e10cSrcweir     case typelib_TypeClass_BYTE:
209cdf0e10cSrcweir         write8(buffer, *static_cast< sal_uInt8 const * >(value));
210cdf0e10cSrcweir         break;
211cdf0e10cSrcweir     case typelib_TypeClass_SHORT:
212cdf0e10cSrcweir     case typelib_TypeClass_UNSIGNED_SHORT:
213cdf0e10cSrcweir     case typelib_TypeClass_CHAR:
214cdf0e10cSrcweir         write16(buffer, *static_cast< sal_uInt16 const * >(value));
215cdf0e10cSrcweir         break;
216cdf0e10cSrcweir     case typelib_TypeClass_LONG:
217cdf0e10cSrcweir     case typelib_TypeClass_UNSIGNED_LONG:
218cdf0e10cSrcweir     case typelib_TypeClass_FLOAT:
219cdf0e10cSrcweir     case typelib_TypeClass_ENUM:
220cdf0e10cSrcweir         write32(buffer, *static_cast< sal_uInt32 const * >(value));
221cdf0e10cSrcweir         break;
222cdf0e10cSrcweir     case typelib_TypeClass_HYPER:
223cdf0e10cSrcweir     case typelib_TypeClass_UNSIGNED_HYPER:
224cdf0e10cSrcweir     case typelib_TypeClass_DOUBLE:
225cdf0e10cSrcweir         write64(buffer, *static_cast< sal_uInt64 const * >(value));
226cdf0e10cSrcweir         break;
227cdf0e10cSrcweir     case typelib_TypeClass_STRING:
228cdf0e10cSrcweir         writeString(
229cdf0e10cSrcweir             buffer,
230cdf0e10cSrcweir             rtl::OUString(*static_cast< rtl_uString * const * >(value)));
231cdf0e10cSrcweir         break;
232cdf0e10cSrcweir     case typelib_TypeClass_TYPE:
233cdf0e10cSrcweir         writeType(
234cdf0e10cSrcweir             buffer,
235cdf0e10cSrcweir             css::uno::TypeDescription(
236cdf0e10cSrcweir                 *static_cast< typelib_TypeDescriptionReference * const * >(
237cdf0e10cSrcweir                     value)));
238cdf0e10cSrcweir         break;
239cdf0e10cSrcweir     case typelib_TypeClass_ANY:
240cdf0e10cSrcweir         {
241cdf0e10cSrcweir             uno_Any const * p = static_cast< uno_Any const * >(value);
242cdf0e10cSrcweir             css::uno::TypeDescription t(p->pType);
243cdf0e10cSrcweir             writeType(buffer, t);
244cdf0e10cSrcweir             writeValue(buffer, t, p->pData);
245cdf0e10cSrcweir             break;
246cdf0e10cSrcweir         }
247cdf0e10cSrcweir     case typelib_TypeClass_SEQUENCE:
248cdf0e10cSrcweir         {
249cdf0e10cSrcweir             sal_Sequence * p = *static_cast< sal_Sequence * const * >(value);
250cdf0e10cSrcweir             writeCompressed(buffer, static_cast< sal_uInt32 >(p->nElements));
251cdf0e10cSrcweir             css::uno::TypeDescription ctd(
252cdf0e10cSrcweir                 reinterpret_cast< typelib_IndirectTypeDescription * >(
253cdf0e10cSrcweir                     type.get())->
254cdf0e10cSrcweir                 pType);
255cdf0e10cSrcweir             OSL_ASSERT(ctd.is());
256cdf0e10cSrcweir             if (ctd.get()->eTypeClass == typelib_TypeClass_BYTE) {
257cdf0e10cSrcweir                 buffer->insert(
258cdf0e10cSrcweir                     buffer->end(), p->elements, p->elements + p->nElements);
259cdf0e10cSrcweir             } else {
260cdf0e10cSrcweir                 for (sal_Int32 i = 0; i != p->nElements; ++i) {
261cdf0e10cSrcweir                     writeValue(buffer, ctd, p->elements + i * ctd.get()->nSize);
262cdf0e10cSrcweir                 }
263cdf0e10cSrcweir             }
264cdf0e10cSrcweir             break;
265cdf0e10cSrcweir         }
266cdf0e10cSrcweir     case typelib_TypeClass_STRUCT:
267cdf0e10cSrcweir     case typelib_TypeClass_EXCEPTION:
268cdf0e10cSrcweir         writeMemberValues(buffer, type, value);
269cdf0e10cSrcweir         break;
270cdf0e10cSrcweir     case typelib_TypeClass_INTERFACE:
271cdf0e10cSrcweir         writeOid(
272cdf0e10cSrcweir             buffer,
273cdf0e10cSrcweir             bridge_->registerOutgoingInterface(
274cdf0e10cSrcweir                 css::uno::UnoInterfaceReference(
275cdf0e10cSrcweir                     *static_cast< uno_Interface * const * >(value)),
276cdf0e10cSrcweir                 type));
277cdf0e10cSrcweir         break;
278cdf0e10cSrcweir     default:
279cdf0e10cSrcweir         OSL_ASSERT(false); // this cannot happen
280cdf0e10cSrcweir         break;
281cdf0e10cSrcweir     }
282cdf0e10cSrcweir }
283cdf0e10cSrcweir 
writeMemberValues(std::vector<unsigned char> * buffer,css::uno::TypeDescription const & type,void const * aggregateValue)284cdf0e10cSrcweir void Marshal::writeMemberValues(
285cdf0e10cSrcweir     std::vector< unsigned char > * buffer,
286cdf0e10cSrcweir     css::uno::TypeDescription const & type, void const * aggregateValue)
287cdf0e10cSrcweir {
288cdf0e10cSrcweir     OSL_ASSERT(
289cdf0e10cSrcweir         type.is() &&
290cdf0e10cSrcweir         (type.get()->eTypeClass == typelib_TypeClass_STRUCT ||
291cdf0e10cSrcweir          type.get()->eTypeClass == typelib_TypeClass_EXCEPTION) &&
292cdf0e10cSrcweir         aggregateValue != 0);
293cdf0e10cSrcweir     type.makeComplete();
294cdf0e10cSrcweir     typelib_CompoundTypeDescription * ctd =
295cdf0e10cSrcweir         reinterpret_cast< typelib_CompoundTypeDescription * >(type.get());
296cdf0e10cSrcweir     if (ctd->pBaseTypeDescription != 0) {
297cdf0e10cSrcweir         writeMemberValues(
298cdf0e10cSrcweir             buffer,
299cdf0e10cSrcweir             css::uno::TypeDescription(&ctd->pBaseTypeDescription->aBase),
300cdf0e10cSrcweir             aggregateValue);
301cdf0e10cSrcweir     }
302cdf0e10cSrcweir     for (sal_Int32 i = 0; i != ctd->nMembers; ++i) {
303cdf0e10cSrcweir         writeValue(
304cdf0e10cSrcweir             buffer, css::uno::TypeDescription(ctd->ppTypeRefs[i]),
305cdf0e10cSrcweir             (static_cast< char const * >(aggregateValue) +
306cdf0e10cSrcweir              ctd->pMemberOffsets[i]));
307cdf0e10cSrcweir     }
308cdf0e10cSrcweir }
309cdf0e10cSrcweir 
310cdf0e10cSrcweir }
311