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