1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4
5 #include <IceUtil/DisableWarnings.h>
6 #include <Ice/InputStream.h>
7 #include <Ice/DefaultsAndOverrides.h>
8 #include <Ice/Instance.h>
9 #include <Ice/Object.h>
10 #include <Ice/Proxy.h>
11 #include <Ice/ProxyFactory.h>
12 #include <Ice/ValueFactory.h>
13 #include <Ice/UserExceptionFactory.h>
14 #include <Ice/LocalException.h>
15 #include <Ice/Protocol.h>
16 #include <Ice/FactoryTableInit.h>
17 #include <Ice/TraceUtil.h>
18 #include <Ice/TraceLevels.h>
19 #include <Ice/LoggerUtil.h>
20 #include <Ice/SlicedData.h>
21 #include <Ice/StringConverter.h>
22 #include <iterator>
23
24 #ifndef ICE_UNALIGNED
25 # if defined(__i386) || defined(_M_IX86) || defined(__x86_64) || defined(_M_X64)
26 # define ICE_UNALIGNED
27 # endif
28 #endif
29
30 using namespace std;
31 using namespace Ice;
32 using namespace IceInternal;
33
InputStream()34 Ice::InputStream::InputStream()
35 {
36 initialize(currentEncoding);
37 }
38
InputStream(const vector<Byte> & v)39 Ice::InputStream::InputStream(const vector<Byte>& v) :
40 Buffer(v)
41 {
42 initialize(currentEncoding);
43 }
44
InputStream(const pair<const Byte *,const Byte * > & p)45 Ice::InputStream::InputStream(const pair<const Byte*, const Byte*>& p) :
46 Buffer(p.first, p.second)
47 {
48 initialize(currentEncoding);
49 }
50
InputStream(Buffer & buf,bool adopt)51 Ice::InputStream::InputStream(Buffer& buf, bool adopt) :
52 Buffer(buf, adopt)
53 {
54 initialize(currentEncoding);
55 }
56
InputStream(const CommunicatorPtr & communicator)57 Ice::InputStream::InputStream(const CommunicatorPtr& communicator)
58 {
59 initialize(communicator);
60 }
61
InputStream(const CommunicatorPtr & communicator,const vector<Byte> & v)62 Ice::InputStream::InputStream(const CommunicatorPtr& communicator, const vector<Byte>& v) :
63 Buffer(v)
64 {
65 initialize(communicator);
66 }
67
InputStream(const CommunicatorPtr & communicator,const pair<const Byte *,const Byte * > & p)68 Ice::InputStream::InputStream(const CommunicatorPtr& communicator, const pair<const Byte*, const Byte*>& p) :
69 Buffer(p.first, p.second)
70 {
71 initialize(communicator);
72 }
73
InputStream(const CommunicatorPtr & communicator,Buffer & buf,bool adopt)74 Ice::InputStream::InputStream(const CommunicatorPtr& communicator, Buffer& buf, bool adopt) :
75 Buffer(buf, adopt)
76 {
77 initialize(communicator);
78 }
79
InputStream(const EncodingVersion & encoding)80 Ice::InputStream::InputStream(const EncodingVersion& encoding)
81 {
82 initialize(encoding);
83 }
84
InputStream(const EncodingVersion & encoding,const vector<Byte> & v)85 Ice::InputStream::InputStream(const EncodingVersion& encoding, const vector<Byte>& v) :
86 Buffer(v)
87 {
88 initialize(encoding);
89 }
90
InputStream(const EncodingVersion & encoding,const pair<const Byte *,const Byte * > & p)91 Ice::InputStream::InputStream(const EncodingVersion& encoding, const pair<const Byte*, const Byte*>& p) :
92 Buffer(p.first, p.second)
93 {
94 initialize(encoding);
95 }
96
InputStream(const EncodingVersion & encoding,Buffer & buf,bool adopt)97 Ice::InputStream::InputStream(const EncodingVersion& encoding, Buffer& buf, bool adopt) :
98 Buffer(buf, adopt)
99 {
100 initialize(encoding);
101 }
102
InputStream(const CommunicatorPtr & communicator,const EncodingVersion & encoding)103 Ice::InputStream::InputStream(const CommunicatorPtr& communicator, const EncodingVersion& encoding)
104 {
105 initialize(communicator, encoding);
106 }
107
InputStream(const CommunicatorPtr & communicator,const EncodingVersion & encoding,const vector<Byte> & v)108 Ice::InputStream::InputStream(const CommunicatorPtr& communicator, const EncodingVersion& encoding,
109 const vector<Byte>& v) :
110 Buffer(v)
111 {
112 initialize(communicator, encoding);
113 }
114
InputStream(const CommunicatorPtr & communicator,const EncodingVersion & encoding,const pair<const Byte *,const Byte * > & p)115 Ice::InputStream::InputStream(const CommunicatorPtr& communicator, const EncodingVersion& encoding,
116 const pair<const Byte*, const Byte*>& p) :
117 Buffer(p.first, p.second)
118 {
119 initialize(communicator, encoding);
120 }
121
InputStream(const CommunicatorPtr & communicator,const EncodingVersion & encoding,Buffer & buf,bool adopt)122 Ice::InputStream::InputStream(const CommunicatorPtr& communicator, const EncodingVersion& encoding,
123 Buffer& buf, bool adopt) :
124 Buffer(buf, adopt)
125 {
126 initialize(communicator, encoding);
127 }
128
InputStream(Instance * instance,const EncodingVersion & encoding)129 Ice::InputStream::InputStream(Instance* instance, const EncodingVersion& encoding)
130 {
131 initialize(instance, encoding);
132 }
133
InputStream(Instance * instance,const EncodingVersion & encoding,Buffer & buf,bool adopt)134 Ice::InputStream::InputStream(Instance* instance, const EncodingVersion& encoding, Buffer& buf, bool adopt) :
135 Buffer(buf, adopt)
136 {
137 initialize(instance, encoding);
138 }
139
140 void
initialize(const CommunicatorPtr & communicator)141 Ice::InputStream::initialize(const CommunicatorPtr& communicator)
142 {
143 Instance* instance = getInstance(communicator).get();
144 initialize(instance, instance->defaultsAndOverrides()->defaultEncoding);
145 }
146
147 void
initialize(const CommunicatorPtr & communicator,const EncodingVersion & encoding)148 Ice::InputStream::initialize(const CommunicatorPtr& communicator, const EncodingVersion& encoding)
149 {
150 initialize(getInstance(communicator).get(), encoding);
151 }
152
153 void
initialize(Instance * instance,const EncodingVersion & encoding)154 Ice::InputStream::initialize(Instance* instance, const EncodingVersion& encoding)
155 {
156 initialize(encoding);
157
158 _instance = instance;
159
160 #ifndef ICE_CPP11_MAPPING
161 _collectObjects = _instance->collectObjects();
162 #endif
163 _traceSlicing = _instance->traceLevels()->slicing > 0;
164 _classGraphDepthMax = _instance->classGraphDepthMax();
165 }
166
167 void
initialize(const EncodingVersion & encoding)168 Ice::InputStream::initialize(const EncodingVersion& encoding)
169 {
170 _instance = 0;
171 _encoding = encoding;
172 _currentEncaps = 0;
173 #ifndef ICE_CPP11_MAPPING
174 _collectObjects = false;
175 #endif
176 _traceSlicing = false;
177 _classGraphDepthMax = 0x7fffffff;
178 _closure = 0;
179 _sliceValues = true;
180 _startSeq = -1;
181 _minSeqSize = 0;
182 }
183
184 void
clear()185 Ice::InputStream::clear()
186 {
187 while(_currentEncaps && _currentEncaps != &_preAllocatedEncaps)
188 {
189 Encaps* oldEncaps = _currentEncaps;
190 _currentEncaps = _currentEncaps->previous;
191 delete oldEncaps;
192 }
193
194 _startSeq = -1;
195 _sliceValues = true;
196 }
197
198 void
setValueFactoryManager(const ValueFactoryManagerPtr & vfm)199 Ice::InputStream::setValueFactoryManager(const ValueFactoryManagerPtr& vfm)
200 {
201 _valueFactoryManager = vfm;
202 }
203
204 void
setLogger(const LoggerPtr & logger)205 Ice::InputStream::setLogger(const LoggerPtr& logger)
206 {
207 _logger = logger;
208 }
209
210 void
211 #ifdef ICE_CPP11_MAPPING
setCompactIdResolver(std::function<std::string (int)> r)212 Ice::InputStream::setCompactIdResolver(std::function<std::string(int)> r)
213 #else
214 Ice::InputStream::setCompactIdResolver(const CompactIdResolverPtr& r)
215 #endif
216 {
217 _compactIdResolver = r;
218 }
219
220 #ifndef ICE_CPP11_MAPPING
221 void
setCollectObjects(bool on)222 Ice::InputStream::setCollectObjects(bool on)
223 {
224 _collectObjects = on;
225 }
226 #endif
227
228 void
setSliceValues(bool on)229 Ice::InputStream::setSliceValues(bool on)
230 {
231 _sliceValues = on;
232 }
233
234 void
setTraceSlicing(bool on)235 Ice::InputStream::setTraceSlicing(bool on)
236 {
237 _traceSlicing = on;
238 }
239
240 void
setClassGraphDepthMax(size_t classGraphDepthMax)241 Ice::InputStream::setClassGraphDepthMax(size_t classGraphDepthMax)
242 {
243 if(classGraphDepthMax < 1)
244 {
245 _classGraphDepthMax = 0x7fffffff;
246 }
247 else
248 {
249 _classGraphDepthMax = classGraphDepthMax;
250 }
251 }
252
253 void*
getClosure() const254 Ice::InputStream::getClosure() const
255 {
256 return _closure;
257 }
258
259 void*
setClosure(void * p)260 Ice::InputStream::setClosure(void* p)
261 {
262 void* prev = _closure;
263 _closure = p;
264 return prev;
265 }
266
267 void
swap(InputStream & other)268 Ice::InputStream::swap(InputStream& other)
269 {
270 swapBuffer(other);
271
272 std::swap(_instance, other._instance);
273 std::swap(_encoding, other._encoding);
274 #ifndef ICE_CPP11_MAPPING
275 std::swap(_collectObjects, other._collectObjects);
276 #endif
277 std::swap(_traceSlicing, other._traceSlicing);
278 std::swap(_classGraphDepthMax, other._classGraphDepthMax);
279 std::swap(_closure, other._closure);
280 std::swap(_sliceValues, other._sliceValues);
281
282 //
283 // Swap is never called for streams that have encapsulations being read. However,
284 // encapsulations might still be set in case unmarshaling failed. We just
285 // reset the encapsulations if there are still some set.
286 //
287 resetEncapsulation();
288 other.resetEncapsulation();
289
290 std::swap(_startSeq, other._startSeq);
291 std::swap(_minSeqSize, other._minSeqSize);
292
293 std::swap(_valueFactoryManager, other._valueFactoryManager);
294 std::swap(_logger, other._logger);
295 std::swap(_compactIdResolver, other._compactIdResolver);
296 }
297
298 void
resetEncapsulation()299 Ice::InputStream::resetEncapsulation()
300 {
301 while(_currentEncaps && _currentEncaps != &_preAllocatedEncaps)
302 {
303 Encaps* oldEncaps = _currentEncaps;
304 _currentEncaps = _currentEncaps->previous;
305 delete oldEncaps;
306 }
307
308 _preAllocatedEncaps.reset();
309 }
310
311 Int
getEncapsulationSize()312 Ice::InputStream::getEncapsulationSize()
313 {
314 assert(_currentEncaps);
315 return _currentEncaps->sz - static_cast<Int>(sizeof(Int)) - 2;
316 }
317
318 EncodingVersion
skipEncapsulation()319 Ice::InputStream::skipEncapsulation()
320 {
321 Int sz;
322 read(sz);
323 if(sz < 6)
324 {
325 throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
326 }
327 if(i - sizeof(Int) + sz > b.end())
328 {
329 throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
330 }
331 EncodingVersion encoding;
332 read(encoding.major);
333 read(encoding.minor);
334 i += sz - sizeof(Int) - 2;
335 return encoding;
336 }
337
338 void
readPendingValues()339 Ice::InputStream::readPendingValues()
340 {
341 if(_currentEncaps && _currentEncaps->decoder)
342 {
343 _currentEncaps->decoder->readPendingValues();
344 }
345 else if(getEncoding() == Ice::Encoding_1_0)
346 {
347 //
348 // If using the 1.0 encoding and no instances were read, we
349 // still read an empty sequence of pending instances if
350 // requested (i.e.: if this is called).
351 //
352 // This is required by the 1.0 encoding, even if no instances
353 // are written we do marshal an empty sequence if marshaled
354 // data types use classes.
355 //
356 skipSize();
357 }
358 }
359
360 Int
readAndCheckSeqSize(int minSize)361 Ice::InputStream::readAndCheckSeqSize(int minSize)
362 {
363 Int sz = readSize();
364
365 if(sz == 0)
366 {
367 return sz;
368 }
369
370 //
371 // The _startSeq variable points to the start of the sequence for which
372 // we expect to read at least _minSeqSize bytes from the stream.
373 //
374 // If not initialized or if we already read more data than _minSeqSize,
375 // we reset _startSeq and _minSeqSize for this sequence (possibly a
376 // top-level sequence or enclosed sequence it doesn't really matter).
377 //
378 // Otherwise, we are reading an enclosed sequence and we have to bump
379 // _minSeqSize by the minimum size that this sequence will require on
380 // the stream.
381 //
382 // The goal of this check is to ensure that when we start un-marshalling
383 // a new sequence, we check the minimal size of this new sequence against
384 // the estimated remaining buffer size. This estimatation is based on
385 // the minimum size of the enclosing sequences, it's _minSeqSize.
386 //
387 if(_startSeq == -1 || i > (b.begin() + _startSeq + _minSeqSize))
388 {
389 _startSeq = static_cast<int>(i - b.begin());
390 _minSeqSize = sz * minSize;
391 }
392 else
393 {
394 _minSeqSize += sz * minSize;
395 }
396
397 //
398 // If there isn't enough data to read on the stream for the sequence (and
399 // possibly enclosed sequences), something is wrong with the marshalled
400 // data: it's claiming having more data that what is possible to read.
401 //
402 if(_startSeq + _minSeqSize > static_cast<int>(b.size()))
403 {
404 throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
405 }
406
407 return sz;
408 }
409
410 void
readBlob(vector<Byte> & v,Int sz)411 Ice::InputStream::readBlob(vector<Byte>& v, Int sz)
412 {
413 if(sz > 0)
414 {
415 if(b.end() - i < sz)
416 {
417 throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
418 }
419 vector<Byte>(i, i + sz).swap(v);
420 i += sz;
421 }
422 else
423 {
424 v.clear();
425 }
426 }
427
428 void
read(std::vector<Ice::Byte> & v)429 Ice::InputStream::read(std::vector<Ice::Byte>& v)
430 {
431 std::pair<const Ice::Byte*, const Ice::Byte*> p;
432 read(p);
433 if(p.first != p.second)
434 {
435 v.resize(static_cast<Ice::Int>(p.second - p.first));
436 copy(p.first, p.second, v.begin());
437 }
438 else
439 {
440 v.clear();
441 }
442 }
443
444 void
read(pair<const Byte *,const Byte * > & v)445 Ice::InputStream::read(pair<const Byte*, const Byte*>& v)
446 {
447 Int sz = readAndCheckSeqSize(1);
448 if(sz > 0)
449 {
450 v.first = i;
451 v.second = i + sz;
452 i += sz;
453 }
454 else
455 {
456 v.first = v.second = i;
457 }
458 }
459
460 void
read(vector<bool> & v)461 Ice::InputStream::read(vector<bool>& v)
462 {
463 Int sz = readAndCheckSeqSize(1);
464 if(sz > 0)
465 {
466 v.resize(sz);
467 copy(i, i + sz, v.begin());
468 i += sz;
469 }
470 else
471 {
472 v.clear();
473 }
474 }
475
476 namespace
477 {
478
479 template<size_t boolSize>
480 struct ReadBoolHelper
481 {
read__anon97c5d62e0111::ReadBoolHelper482 static bool* read(pair<const bool*, const bool*>& v, Int sz, InputStream::Container::iterator& i)
483 {
484 bool* array = new bool[sz];
485 for(int idx = 0; idx < sz; ++idx)
486 {
487 array[idx] = static_cast<bool>(*(i + idx));
488 }
489 v.first = array;
490 v.second = array + sz;
491 return array;
492 }
493 };
494
495 template<>
496 struct ReadBoolHelper<1>
497 {
read__anon97c5d62e0111::ReadBoolHelper498 static bool* read(pair<const bool*, const bool*>& v, Int sz, InputStream::Container::iterator& i)
499 {
500 v.first = reinterpret_cast<bool*>(i);
501 v.second = reinterpret_cast<bool*>(i) + sz;
502 return 0;
503 }
504 };
505
506 }
507
508 #ifdef ICE_CPP11_MAPPING
509 void
read(pair<const bool *,const bool * > & v)510 Ice::InputStream::read(pair<const bool*, const bool*>& v)
511 {
512 Int sz = readAndCheckSeqSize(1);
513 if(sz > 0)
514 {
515 auto boolArray = ReadBoolHelper<sizeof(bool)>::read(v, sz, i);
516 if(boolArray)
517 {
518 _deleters.push_back([boolArray] { delete[] boolArray; });
519 }
520 i += sz;
521 }
522 else
523 {
524 v.first = v.second = reinterpret_cast<bool*>(i);
525 }
526 }
527
528 #else
529 void
read(pair<const bool *,const bool * > & v,IceUtil::ScopedArray<bool> & result)530 Ice::InputStream::read(pair<const bool*, const bool*>& v, IceUtil::ScopedArray<bool>& result)
531 {
532 Int sz = readAndCheckSeqSize(1);
533 if(sz > 0)
534 {
535 result.reset(ReadBoolHelper<sizeof(bool)>::read(v, sz, i));
536 i += sz;
537 }
538 else
539 {
540 result.reset();
541 v.first = v.second = reinterpret_cast<bool*>(i);
542 }
543 }
544 #endif
545
546 void
read(Short & v)547 Ice::InputStream::read(Short& v)
548 {
549 if(b.end() - i < static_cast<int>(sizeof(Short)))
550 {
551 throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
552 }
553 const Byte* src = &(*i);
554 i += sizeof(Short);
555 #ifdef ICE_BIG_ENDIAN
556 Byte* dest = reinterpret_cast<Byte*>(&v) + sizeof(Short) - 1;
557 *dest-- = *src++;
558 *dest = *src;
559 #else
560 Byte* dest = reinterpret_cast<Byte*>(&v);
561 *dest++ = *src++;
562 *dest = *src;
563 #endif
564 }
565
566 void
read(vector<Short> & v)567 Ice::InputStream::read(vector<Short>& v)
568 {
569 Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Short)));
570 if(sz > 0)
571 {
572 Container::iterator begin = i;
573 i += sz * static_cast<int>(sizeof(Short));
574 v.resize(sz);
575 #ifdef ICE_BIG_ENDIAN
576 const Byte* src = &(*begin);
577 Byte* dest = reinterpret_cast<Byte*>(&v[0]) + sizeof(Short) - 1;
578 for(int j = 0 ; j < sz ; ++j)
579 {
580 *dest-- = *src++;
581 *dest-- = *src++;
582 dest += 2 * sizeof(Short);
583 }
584 #else
585 copy(begin, i, reinterpret_cast<Byte*>(&v[0]));
586 #endif
587 }
588 else
589 {
590 v.clear();
591 }
592 }
593
594 #ifdef ICE_CPP11_MAPPING
595 void
read(pair<const short *,const short * > & v)596 Ice::InputStream::read(pair<const short*, const short*>& v)
597 #else
598 void
599 Ice::InputStream::read(pair<const Short*, const Short*>& v, IceUtil::ScopedArray<Short>& result)
600 #endif
601 {
602 Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Short)));
603 if(sz > 0)
604 {
605 #ifdef ICE_UNALIGNED
606 v.first = reinterpret_cast<Short*>(i);
607 i += sz * static_cast<int>(sizeof(Short));
608 v.second = reinterpret_cast<Short*>(i);
609 #else
610 # ifdef ICE_CPP11_MAPPING
611 auto result = new short[sz];
612 _deleters.push_back([result] { delete[] result; });
613 v.first = result;
614 v.second = result + sz;
615 # else
616 result.reset(new Short[sz]);
617 v.first = result.get();
618 v.second = result.get() + sz;
619 # endif
620
621 Container::iterator begin = i;
622 i += sz * static_cast<int>(sizeof(Short));
623 # ifdef ICE_BIG_ENDIAN
624 const Byte* src = &(*begin);
625 Byte* dest = reinterpret_cast<Byte*>(&result[0]) + sizeof(Short) - 1;
626 for(int j = 0 ; j < sz ; ++j)
627 {
628 *dest-- = *src++;
629 *dest-- = *src++;
630 dest += 2 * sizeof(Short);
631 }
632 # else
633 copy(begin, i, reinterpret_cast<Byte*>(&result[0]));
634 # endif
635 #endif
636 }
637 else
638 {
639 #ifndef ICE_CPP11_MAPPING
640 result.reset();
641 #endif
642 v.first = v.second = 0;
643 }
644 }
645
646 void
read(vector<Int> & v)647 Ice::InputStream::read(vector<Int>& v)
648 {
649 Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Int)));
650 if(sz > 0)
651 {
652 Container::iterator begin = i;
653 i += sz * static_cast<int>(sizeof(Int));
654 v.resize(sz);
655 #ifdef ICE_BIG_ENDIAN
656 const Byte* src = &(*begin);
657 Byte* dest = reinterpret_cast<Byte*>(&v[0]) + sizeof(Int) - 1;
658 for(int j = 0 ; j < sz ; ++j)
659 {
660 *dest-- = *src++;
661 *dest-- = *src++;
662 *dest-- = *src++;
663 *dest-- = *src++;
664 dest += 2 * sizeof(Int);
665 }
666 #else
667 copy(begin, i, reinterpret_cast<Byte*>(&v[0]));
668 #endif
669 }
670 else
671 {
672 v.clear();
673 }
674 }
675
676 #ifdef ICE_CPP11_MAPPING
677 void
read(pair<const Int *,const Int * > & v)678 Ice::InputStream::read(pair<const Int*, const Int*>& v)
679 #else
680 void
681 Ice::InputStream::read(pair<const Int*, const Int*>& v, ::IceUtil::ScopedArray<Int>& result)
682 #endif
683 {
684 Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Int)));
685 if(sz > 0)
686 {
687 #ifdef ICE_UNALIGNED
688 v.first = reinterpret_cast<Int*>(i);
689 i += sz * static_cast<int>(sizeof(Int));
690 v.second = reinterpret_cast<Int*>(i);
691 #else
692
693 # ifdef ICE_CPP11_MAPPING
694 auto result = new int[sz];
695 _deleters.push_back([result] { delete[] result; });
696 v.first = result;
697 v.second = result + sz;
698 # else
699 result.reset(new Int[sz]);
700 v.first = result.get();
701 v.second = result.get() + sz;
702 # endif
703
704 Container::iterator begin = i;
705 i += sz * static_cast<int>(sizeof(Int));
706 # ifdef ICE_BIG_ENDIAN
707 const Byte* src = &(*begin);
708 Byte* dest = reinterpret_cast<Byte*>(&result[0]) + sizeof(Int) - 1;
709 for(int j = 0 ; j < sz ; ++j)
710 {
711 *dest-- = *src++;
712 *dest-- = *src++;
713 *dest-- = *src++;
714 *dest-- = *src++;
715 dest += 2 * sizeof(Int);
716 }
717 # else
718 copy(begin, i, reinterpret_cast<Byte*>(&result[0]));
719 # endif
720 #endif
721 }
722 else
723 {
724 #ifndef ICE_CPP11_MAPPING
725 result.reset();
726 #endif
727 v.first = v.second = 0;
728 }
729 }
730
731 void
read(Long & v)732 Ice::InputStream::read(Long& v)
733 {
734 if(b.end() - i < static_cast<int>(sizeof(Long)))
735 {
736 throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
737 }
738 const Byte* src = &(*i);
739 i += sizeof(Long);
740 #ifdef ICE_BIG_ENDIAN
741 Byte* dest = reinterpret_cast<Byte*>(&v) + sizeof(Long) - 1;
742 *dest-- = *src++;
743 *dest-- = *src++;
744 *dest-- = *src++;
745 *dest-- = *src++;
746 *dest-- = *src++;
747 *dest-- = *src++;
748 *dest-- = *src++;
749 *dest = *src;
750 #else
751 Byte* dest = reinterpret_cast<Byte*>(&v);
752 *dest++ = *src++;
753 *dest++ = *src++;
754 *dest++ = *src++;
755 *dest++ = *src++;
756 *dest++ = *src++;
757 *dest++ = *src++;
758 *dest++ = *src++;
759 *dest = *src;
760 #endif
761 }
762
763 void
read(vector<Long> & v)764 Ice::InputStream::read(vector<Long>& v)
765 {
766 Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Long)));
767 if(sz > 0)
768 {
769 Container::iterator begin = i;
770 i += sz * static_cast<int>(sizeof(Long));
771 v.resize(sz);
772 #ifdef ICE_BIG_ENDIAN
773 const Byte* src = &(*begin);
774 Byte* dest = reinterpret_cast<Byte*>(&v[0]) + sizeof(Long) - 1;
775 for(int j = 0 ; j < sz ; ++j)
776 {
777 *dest-- = *src++;
778 *dest-- = *src++;
779 *dest-- = *src++;
780 *dest-- = *src++;
781 *dest-- = *src++;
782 *dest-- = *src++;
783 *dest-- = *src++;
784 *dest-- = *src++;
785 dest += 2 * sizeof(Long);
786 }
787 #else
788 copy(begin, i, reinterpret_cast<Byte*>(&v[0]));
789 #endif
790 }
791 else
792 {
793 v.clear();
794 }
795 }
796
797 #ifdef ICE_CPP11_MAPPING
798 void
read(pair<const Long *,const Long * > & v)799 Ice::InputStream::read(pair<const Long*, const Long*>& v)
800 #else
801 void
802 Ice::InputStream::read(pair<const Long*, const Long*>& v, IceUtil::ScopedArray<Long>& result)
803 #endif
804 {
805 Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Long)));
806 if(sz > 0)
807 {
808 #ifdef ICE_UNALIGNED
809 v.first = reinterpret_cast<Long*>(i);
810 i += sz * static_cast<int>(sizeof(Long));
811 v.second = reinterpret_cast<Long*>(i);
812 #else
813
814 # ifdef ICE_CPP11_MAPPING
815 auto result = new long long[sz];
816 _deleters.push_back([result] { delete[] result; });
817 v.first = result;
818 v.second = result + sz;
819 # else
820 result.reset(new Long[sz]);
821 v.first = result.get();
822 v.second = result.get() + sz;
823 # endif
824
825 Container::iterator begin = i;
826 i += sz * static_cast<int>(sizeof(Long));
827 # ifdef ICE_BIG_ENDIAN
828 const Byte* src = &(*begin);
829 Byte* dest = reinterpret_cast<Byte*>(&result[0]) + sizeof(Long) - 1;
830 for(int j = 0 ; j < sz ; ++j)
831 {
832 *dest-- = *src++;
833 *dest-- = *src++;
834 *dest-- = *src++;
835 *dest-- = *src++;
836 *dest-- = *src++;
837 *dest-- = *src++;
838 *dest-- = *src++;
839 *dest-- = *src++;
840 dest += 2 * sizeof(Long);
841 }
842 # else
843 copy(begin, i, reinterpret_cast<Byte*>(&result[0]));
844 # endif
845 #endif
846 }
847 else
848 {
849 #ifndef ICE_CPP11_MAPPING
850 result.reset();
851 #endif
852 v.first = v.second = 0;
853 }
854 }
855
856 void
read(Float & v)857 Ice::InputStream::read(Float& v)
858 {
859 if(b.end() - i < static_cast<int>(sizeof(Float)))
860 {
861 throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
862 }
863 const Byte* src = &(*i);
864 i += sizeof(Float);
865 #ifdef ICE_BIG_ENDIAN
866 Byte* dest = reinterpret_cast<Byte*>(&v) + sizeof(Float) - 1;
867 *dest-- = *src++;
868 *dest-- = *src++;
869 *dest-- = *src++;
870 *dest = *src;
871 #else
872 Byte* dest = reinterpret_cast<Byte*>(&v);
873 *dest++ = *src++;
874 *dest++ = *src++;
875 *dest++ = *src++;
876 *dest = *src;
877 #endif
878 }
879
880 void
read(vector<Float> & v)881 Ice::InputStream::read(vector<Float>& v)
882 {
883 Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Float)));
884 if(sz > 0)
885 {
886 Container::iterator begin = i;
887 i += sz * static_cast<int>(sizeof(Float));
888 v.resize(sz);
889 #ifdef ICE_BIG_ENDIAN
890 const Byte* src = &(*begin);
891 Byte* dest = reinterpret_cast<Byte*>(&v[0]) + sizeof(Float) - 1;
892 for(int j = 0 ; j < sz ; ++j)
893 {
894 *dest-- = *src++;
895 *dest-- = *src++;
896 *dest-- = *src++;
897 *dest-- = *src++;
898 dest += 2 * sizeof(Float);
899 }
900 #else
901 copy(begin, i, reinterpret_cast<Byte*>(&v[0]));
902 #endif
903 }
904 else
905 {
906 v.clear();
907 }
908 }
909
910 #ifdef ICE_CPP11_MAPPING
911 void
read(pair<const Float *,const Float * > & v)912 Ice::InputStream::read(pair<const Float*, const Float*>& v)
913 #else
914 void
915 Ice::InputStream::read(pair<const Float*, const Float*>& v, IceUtil::ScopedArray<Float>& result)
916 #endif
917 {
918 Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Float)));
919 if(sz > 0)
920 {
921 #ifdef ICE_UNALIGNED
922 v.first = reinterpret_cast<Float*>(i);
923 i += sz * static_cast<int>(sizeof(Float));
924 v.second = reinterpret_cast<Float*>(i);
925 #else
926
927 # ifdef ICE_CPP11_MAPPING
928 auto result = new float[sz];
929 _deleters.push_back([result] { delete[] result; });
930 v.first = result;
931 v.second = result + sz;
932 # else
933 result.reset(new Float[sz]);
934 v.first = result.get();
935 v.second = result.get() + sz;
936 # endif
937
938 Container::iterator begin = i;
939 i += sz * static_cast<int>(sizeof(Float));
940 # ifdef ICE_BIG_ENDIAN
941 const Byte* src = &(*begin);
942 Byte* dest = reinterpret_cast<Byte*>(&result[0]) + sizeof(Float) - 1;
943 for(int j = 0 ; j < sz ; ++j)
944 {
945 *dest-- = *src++;
946 *dest-- = *src++;
947 *dest-- = *src++;
948 *dest-- = *src++;
949 dest += 2 * sizeof(Float);
950 }
951 # else
952 copy(begin, i, reinterpret_cast<Byte*>(&result[0]));
953 # endif
954 #endif
955 }
956 else
957 {
958 #ifndef ICE_CPP11_MAPPING
959 result.reset();
960 #endif
961 v.first = v.second = 0;
962 }
963 }
964
965 void
read(Double & v)966 Ice::InputStream::read(Double& v)
967 {
968 if(b.end() - i < static_cast<int>(sizeof(Double)))
969 {
970 throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
971 }
972 const Byte* src = &(*i);
973 i += sizeof(Double);
974 #ifdef ICE_BIG_ENDIAN
975 Byte* dest = reinterpret_cast<Byte*>(&v) + sizeof(Double) - 1;
976 *dest-- = *src++;
977 *dest-- = *src++;
978 *dest-- = *src++;
979 *dest-- = *src++;
980 *dest-- = *src++;
981 *dest-- = *src++;
982 *dest-- = *src++;
983 *dest = *src;
984 #else
985 Byte* dest = reinterpret_cast<Byte*>(&v);
986 *dest++ = *src++;
987 *dest++ = *src++;
988 *dest++ = *src++;
989 *dest++ = *src++;
990 *dest++ = *src++;
991 *dest++ = *src++;
992 *dest++ = *src++;
993 *dest = *src;
994 #endif
995 }
996
997 void
read(vector<Double> & v)998 Ice::InputStream::read(vector<Double>& v)
999 {
1000 Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Double)));
1001 if(sz > 0)
1002 {
1003 Container::iterator begin = i;
1004 i += sz * static_cast<int>(sizeof(Double));
1005 v.resize(sz);
1006 #ifdef ICE_BIG_ENDIAN
1007 const Byte* src = &(*begin);
1008 Byte* dest = reinterpret_cast<Byte*>(&v[0]) + sizeof(Double) - 1;
1009 for(int j = 0 ; j < sz ; ++j)
1010 {
1011 *dest-- = *src++;
1012 *dest-- = *src++;
1013 *dest-- = *src++;
1014 *dest-- = *src++;
1015 *dest-- = *src++;
1016 *dest-- = *src++;
1017 *dest-- = *src++;
1018 *dest-- = *src++;
1019 dest += 2 * sizeof(Double);
1020 }
1021 #else
1022 copy(begin, i, reinterpret_cast<Byte*>(&v[0]));
1023 #endif
1024 }
1025 else
1026 {
1027 v.clear();
1028 }
1029 }
1030
1031 #ifdef ICE_CPP11_MAPPING
1032 void
read(pair<const Double *,const Double * > & v)1033 Ice::InputStream::read(pair<const Double*, const Double*>& v)
1034 #else
1035 void
1036 Ice::InputStream::read(pair<const Double*, const Double*>& v, IceUtil::ScopedArray<Double>& result)
1037 #endif
1038 {
1039 Int sz = readAndCheckSeqSize(static_cast<int>(sizeof(Double)));
1040 if(sz > 0)
1041 {
1042 #ifdef ICE_UNALIGNED
1043 v.first = reinterpret_cast<Double*>(i);
1044 i += sz * static_cast<int>(sizeof(Double));
1045 v.second = reinterpret_cast<Double*>(i);
1046 #else
1047
1048 # ifdef ICE_CPP11_MAPPING
1049 auto result = new double[sz];
1050 _deleters.push_back([result] { delete[] result; });
1051 v.first = result;
1052 v.second = result + sz;
1053 # else
1054 result.reset(new Double[sz]);
1055 v.first = result.get();
1056 v.second = result.get() + sz;
1057 # endif
1058
1059 Container::iterator begin = i;
1060 i += sz * static_cast<int>(sizeof(Double));
1061 # ifdef ICE_BIG_ENDIAN
1062 const Byte* src = &(*begin);
1063 Byte* dest = reinterpret_cast<Byte*>(&result[0]) + sizeof(Double) - 1;
1064 for(int j = 0 ; j < sz ; ++j)
1065 {
1066 *dest-- = *src++;
1067 *dest-- = *src++;
1068 *dest-- = *src++;
1069 *dest-- = *src++;
1070 *dest-- = *src++;
1071 *dest-- = *src++;
1072 *dest-- = *src++;
1073 *dest-- = *src++;
1074 dest += 2 * sizeof(Double);
1075 }
1076 # else
1077 copy(begin, i, reinterpret_cast<Byte*>(&result[0]));
1078 # endif
1079 #endif
1080 }
1081 else
1082 {
1083 #ifndef ICE_CPP11_MAPPING
1084 result.reset();
1085 #endif
1086 v.first = v.second = 0;
1087 }
1088 }
1089
1090 void
read(std::string & v,bool convert)1091 Ice::InputStream::read(std::string& v, bool convert)
1092 {
1093 Int sz = readSize();
1094 if(sz > 0)
1095 {
1096 if(b.end() - i < sz)
1097 {
1098 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
1099 }
1100
1101 if(!convert || !readConverted(v, sz))
1102 {
1103 string(reinterpret_cast<const char*>(&*i), reinterpret_cast<const char*>(&*i) + sz).swap(v);
1104 }
1105 i += sz;
1106 }
1107 else
1108 {
1109 v.clear();
1110 }
1111 }
1112
1113 #ifdef ICE_CPP11_MAPPING
1114 void
read(const char * & vdata,size_t & vsize,bool convert)1115 Ice::InputStream::read(const char*& vdata, size_t& vsize, bool convert)
1116 {
1117 int sz = readSize();
1118 if(sz > 0)
1119 {
1120 if(b.end() - i < sz)
1121 {
1122 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
1123 }
1124
1125 if(convert == false)
1126 {
1127 vdata = reinterpret_cast<const char*>(&*i);
1128 vsize = static_cast<size_t>(sz);
1129 i += sz;
1130 }
1131 else
1132 {
1133 string converted;
1134 if(readConverted(converted, sz))
1135 {
1136 if(converted.size() <= static_cast<size_t>(sz))
1137 {
1138 //
1139 // Write converted string directly into buffer
1140 //
1141 std::memcpy(i, converted.data(), converted.size());
1142 vdata = reinterpret_cast<const char*>(&*i);
1143 vsize = converted.size();
1144 }
1145 else
1146 {
1147 auto holder = new string(std::move(converted));
1148 _deleters.push_back([holder] { delete holder; });
1149 vdata = holder->data();
1150 vsize = holder->size();
1151 }
1152 }
1153 else
1154 {
1155 vdata = reinterpret_cast<const char*>(&*i);
1156 vsize = static_cast<size_t>(sz);
1157 }
1158 i += sz;
1159 }
1160 }
1161 else
1162 {
1163 vdata = 0;
1164 vsize = 0;
1165 }
1166 }
1167
1168 #else
1169
1170 void
read(const char * & vdata,size_t & vsize)1171 Ice::InputStream::read(const char*& vdata, size_t& vsize)
1172 {
1173 Int sz = readSize();
1174 if(sz > 0)
1175 {
1176 if(b.end() - i < sz)
1177 {
1178 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
1179 }
1180
1181 vdata = reinterpret_cast<const char*>(&*i);
1182 vsize = static_cast<size_t>(sz);
1183 i += sz;
1184 }
1185 else
1186 {
1187 vdata = 0;
1188 vsize = 0;
1189 }
1190 }
1191
1192 void
read(const char * & vdata,size_t & vsize,string & holder)1193 Ice::InputStream::read(const char*& vdata, size_t& vsize, string& holder)
1194 {
1195 Int sz = readSize();
1196 if(sz > 0)
1197 {
1198 if(b.end() - i < sz)
1199 {
1200 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
1201 }
1202
1203 if(readConverted(holder, sz))
1204 {
1205 vdata = holder.data();
1206 vsize = holder.size();
1207 }
1208 else
1209 {
1210 vdata = reinterpret_cast<const char*>(&*i);
1211 vsize = static_cast<size_t>(sz);
1212 }
1213 i += sz;
1214 }
1215 else
1216 {
1217 holder.clear();
1218 vdata = 0;
1219 vsize = 0;
1220 }
1221 }
1222 #endif
1223
1224 bool
readConverted(string & v,int sz)1225 Ice::InputStream::readConverted(string& v, int sz)
1226 {
1227 try
1228 {
1229 bool converted = false;
1230
1231 //
1232 // NOTE: When using an _instance, we get a const& on the string reference to
1233 // not have to increment unecessarily its reference count.
1234 //
1235
1236 if(_instance)
1237 {
1238 const StringConverterPtr& stringConverter = _instance->getStringConverter();
1239 if(stringConverter)
1240 {
1241 stringConverter->fromUTF8(i, i + sz, v);
1242 converted = true;
1243 }
1244 }
1245 else
1246 {
1247 StringConverterPtr stringConverter = getProcessStringConverter();
1248 if(stringConverter)
1249 {
1250 stringConverter->fromUTF8(i, i + sz, v);
1251 converted = true;
1252 }
1253 }
1254
1255 return converted;
1256 }
1257 catch(const IllegalConversionException& ex)
1258 {
1259 throw StringConversionException(__FILE__, __LINE__, ex.reason());
1260 }
1261 }
1262
1263 void
read(vector<string> & v,bool convert)1264 Ice::InputStream::read(vector<string>& v, bool convert)
1265 {
1266 Int sz = readAndCheckSeqSize(1);
1267 if(sz > 0)
1268 {
1269 v.resize(sz);
1270 for(int j = 0; j < sz; ++j)
1271 {
1272 read(v[j], convert);
1273 }
1274 }
1275 else
1276 {
1277 v.clear();
1278 }
1279 }
1280
1281 void
read(wstring & v)1282 Ice::InputStream::read(wstring& v)
1283 {
1284 Int sz = readSize();
1285 if(sz > 0)
1286 {
1287 if(b.end() - i < sz)
1288 {
1289 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
1290 }
1291
1292 try
1293 {
1294 if(_instance)
1295 {
1296 const WstringConverterPtr& wstringConverter = _instance->getWstringConverter();
1297 wstringConverter->fromUTF8(i, i + sz, v);
1298 }
1299 else
1300 {
1301 WstringConverterPtr wstringConverter = getProcessWstringConverter();
1302 wstringConverter->fromUTF8(i, i + sz, v);
1303 }
1304
1305 i += sz;
1306 }
1307 catch(const IllegalConversionException& ex)
1308 {
1309 throw StringConversionException(__FILE__, __LINE__, ex.reason());
1310 }
1311 }
1312 else
1313 {
1314 v.clear();
1315 }
1316 }
1317
1318 void
read(vector<wstring> & v)1319 Ice::InputStream::read(vector<wstring>& v)
1320 {
1321 Int sz = readAndCheckSeqSize(1);
1322 if(sz > 0)
1323 {
1324 v.resize(sz);
1325 for(int j = 0; j < sz; ++j)
1326 {
1327 read(v[j]);
1328 }
1329 }
1330 else
1331 {
1332 v.clear();
1333 }
1334 }
1335
1336 #ifdef ICE_CPP11_MAPPING
1337 shared_ptr<ObjectPrx>
readProxy()1338 Ice::InputStream::readProxy()
1339 {
1340 if(!_instance)
1341 {
1342 throw MarshalException(__FILE__, __LINE__, "cannot unmarshal a proxy without a communicator");
1343 }
1344
1345 return _instance->proxyFactory()->streamToProxy(this);
1346 }
1347 #else
1348 void
read(ObjectPrx & v)1349 Ice::InputStream::read(ObjectPrx& v)
1350 {
1351 if(!_instance)
1352 {
1353 throw MarshalException(__FILE__, __LINE__, "cannot unmarshal a proxy without a communicator");
1354 }
1355
1356 v = _instance->proxyFactory()->streamToProxy(this);
1357 }
1358 #endif
1359
1360 Int
readEnum(Int maxValue)1361 Ice::InputStream::readEnum(Int maxValue)
1362 {
1363 if(getEncoding() == Encoding_1_0)
1364 {
1365 if(maxValue < 127)
1366 {
1367 Byte value;
1368 read(value);
1369 return value;
1370 }
1371 else if(maxValue < 32767)
1372 {
1373 Short value;
1374 read(value);
1375 return value;
1376 }
1377 else
1378 {
1379 Int value;
1380 read(value);
1381 return value;
1382 }
1383 }
1384 else
1385 {
1386 return readSize();
1387 }
1388 }
1389
1390 void
throwException(ICE_IN (ICE_DELEGATE (UserExceptionFactory))factory)1391 Ice::InputStream::throwException(ICE_IN(ICE_DELEGATE(UserExceptionFactory)) factory)
1392 {
1393 initEncaps();
1394 _currentEncaps->decoder->throwException(factory);
1395 }
1396
1397 bool
readOptImpl(Int readTag,OptionalFormat expectedFormat)1398 Ice::InputStream::readOptImpl(Int readTag, OptionalFormat expectedFormat)
1399 {
1400 if(getEncoding() == Encoding_1_0)
1401 {
1402 return false; // Optional members aren't supported with the 1.0 encoding.
1403 }
1404
1405 while(true)
1406 {
1407 if(i >= b.begin() + _currentEncaps->start + _currentEncaps->sz)
1408 {
1409 return false; // End of encapsulation also indicates end of optionals.
1410 }
1411
1412 Byte v;
1413 read(v);
1414 if(v == OPTIONAL_END_MARKER)
1415 {
1416 --i; // Rewind
1417 return false;
1418 }
1419
1420 OptionalFormat format = static_cast<OptionalFormat>(v & 0x07); // First 3 bits.
1421 Int tag = static_cast<Int>(v >> 3);
1422 if(tag == 30)
1423 {
1424 tag = readSize();
1425 }
1426
1427 if(tag > readTag)
1428 {
1429 i -= tag < 30 ? 1 : (tag < 255 ? 2 : 6); // Rewind
1430 return false; // No optional data members with the requested tag.
1431 }
1432 else if(tag < readTag)
1433 {
1434 skipOptional(format); // Skip optional data members
1435 }
1436 else
1437 {
1438 if(format != expectedFormat)
1439 {
1440 ostringstream os;
1441 os << "invalid optional data member `" << tag << "': unexpected format";
1442 throw MarshalException(__FILE__, __LINE__, os.str());
1443 }
1444 return true;
1445 }
1446 }
1447 return true; // Keep the compiler happy.
1448 }
1449
1450 void
skipOptional(OptionalFormat type)1451 Ice::InputStream::skipOptional(OptionalFormat type)
1452 {
1453 switch(type)
1454 {
1455 case ICE_SCOPED_ENUM(OptionalFormat, F1):
1456 {
1457 skip(1);
1458 break;
1459 }
1460 case ICE_SCOPED_ENUM(OptionalFormat, F2):
1461 {
1462 skip(2);
1463 break;
1464 }
1465 case ICE_SCOPED_ENUM(OptionalFormat, F4):
1466 {
1467 skip(4);
1468 break;
1469 }
1470 case ICE_SCOPED_ENUM(OptionalFormat, F8):
1471 {
1472 skip(8);
1473 break;
1474 }
1475 case ICE_SCOPED_ENUM(OptionalFormat, Size):
1476 {
1477 skipSize();
1478 break;
1479 }
1480 case ICE_SCOPED_ENUM(OptionalFormat, VSize):
1481 {
1482 skip(readSize());
1483 break;
1484 }
1485 case ICE_SCOPED_ENUM(OptionalFormat, FSize):
1486 {
1487 Int sz;
1488 read(sz);
1489 if(sz < 0)
1490 {
1491 throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
1492 }
1493 skip(sz);
1494 break;
1495 }
1496 case ICE_SCOPED_ENUM(OptionalFormat, Class):
1497 {
1498 read(0, 0);
1499 break;
1500 }
1501 }
1502 }
1503
1504 void
skipOptionals()1505 Ice::InputStream::skipOptionals()
1506 {
1507 //
1508 // Skip remaining un-read optional members.
1509 //
1510 while(true)
1511 {
1512 if(i >= b.begin() + _currentEncaps->start + _currentEncaps->sz)
1513 {
1514 return; // End of encapsulation also indicates end of optionals.
1515 }
1516
1517 Byte v;
1518 read(v);
1519 if(v == OPTIONAL_END_MARKER)
1520 {
1521 return;
1522 }
1523
1524 OptionalFormat format = static_cast<OptionalFormat>(v & 0x07); // Read first 3 bits.
1525 if(static_cast<Int>(v >> 3) == 30)
1526 {
1527 skipSize();
1528 }
1529 skipOptional(format);
1530 }
1531 }
1532
1533 void
throwUnmarshalOutOfBoundsException(const char * file,int line)1534 Ice::InputStream::throwUnmarshalOutOfBoundsException(const char* file, int line)
1535 {
1536 throw UnmarshalOutOfBoundsException(file, line);
1537 }
1538
1539 void
throwEncapsulationException(const char * file,int line)1540 Ice::InputStream::throwEncapsulationException(const char* file, int line)
1541 {
1542 throw EncapsulationException(file, line);
1543 }
1544
1545 string
resolveCompactId(int id) const1546 Ice::InputStream::resolveCompactId(int id) const
1547 {
1548 string type;
1549
1550 #ifdef ICE_CPP11_MAPPING
1551 function<string(int)> resolver = compactIdResolver();
1552 #else
1553 CompactIdResolverPtr resolver = compactIdResolver();
1554 #endif
1555
1556 if(resolver)
1557 {
1558 try
1559 {
1560 #ifdef ICE_CPP11_MAPPING
1561 type = resolver(id);
1562 #else
1563 type = resolver->resolve(id);
1564 #endif
1565 }
1566 catch(const LocalException&)
1567 {
1568 throw;
1569 }
1570 catch(const std::exception& ex)
1571 {
1572 ostringstream ostr;
1573 ostr << "exception in CompactIdResolver for ID " << id;
1574 string msg = ostr.str();
1575 string what = ex.what();
1576 if(!what.empty())
1577 {
1578 msg += ":\n" + what;
1579 }
1580 throw MarshalException(__FILE__, __LINE__, msg);
1581 }
1582 catch(...)
1583 {
1584 ostringstream ostr;
1585 ostr << "unknown exception in CompactIdResolver for ID " << id;
1586 throw MarshalException(__FILE__, __LINE__, ostr.str());
1587 }
1588 }
1589
1590 return type;
1591 }
1592
1593 void
postUnmarshal(const ValuePtr & v) const1594 Ice::InputStream::postUnmarshal(const ValuePtr& v) const
1595 {
1596 try
1597 {
1598 #ifndef ICE_CPP11_MAPPING
1599 if(_collectObjects)
1600 {
1601 v->ice_collectable(true);
1602 }
1603 #endif
1604 v->ice_postUnmarshal();
1605 }
1606 catch(const std::exception& ex)
1607 {
1608 if(logger())
1609 {
1610 Warning out(logger());
1611 out << "std::exception raised by ice_postUnmarshal:\n" << ex;
1612 }
1613 }
1614 catch(...)
1615 {
1616 if(logger())
1617 {
1618 Warning out(logger());
1619 out << "unknown exception raised by ice_postUnmarshal";
1620 }
1621 }
1622 }
1623
1624 void
traceSkipSlice(const string & typeId,SliceType sliceType) const1625 Ice::InputStream::traceSkipSlice(const string& typeId, SliceType sliceType) const
1626 {
1627 if(_traceSlicing && logger())
1628 {
1629 traceSlicing(sliceType == ExceptionSlice ? "exception" : "object", typeId, "Slicing", logger());
1630 }
1631 }
1632
1633 ValueFactoryManagerPtr
valueFactoryManager() const1634 Ice::InputStream::valueFactoryManager() const
1635 {
1636 if(_valueFactoryManager)
1637 {
1638 return _valueFactoryManager;
1639 }
1640 else if(_instance)
1641 {
1642 return _instance->initializationData().valueFactoryManager;
1643 }
1644
1645 return 0;
1646 }
1647
1648 LoggerPtr
logger() const1649 Ice::InputStream::logger() const
1650 {
1651 if(_logger)
1652 {
1653 return _logger;
1654 }
1655 else if(_instance)
1656 {
1657 return _instance->initializationData().logger;
1658 }
1659
1660 return 0;
1661 }
1662
1663 #ifdef ICE_CPP11_MAPPING
1664 function<string(int)>
compactIdResolver() const1665 Ice::InputStream::compactIdResolver() const
1666 {
1667 if(_compactIdResolver)
1668 {
1669 return _compactIdResolver;
1670 }
1671 else if(_instance)
1672 {
1673 return _instance->initializationData().compactIdResolver;
1674 }
1675
1676 return nullptr;
1677 }
1678 #else
1679 CompactIdResolverPtr
compactIdResolver() const1680 Ice::InputStream::compactIdResolver() const
1681 {
1682 if(_compactIdResolver)
1683 {
1684 return _compactIdResolver;
1685 }
1686 else if(_instance)
1687 {
1688 return _instance->initializationData().compactIdResolver;
1689 }
1690
1691 return 0;
1692 }
1693 #endif
1694
1695 void
initEncaps()1696 Ice::InputStream::initEncaps()
1697 {
1698 if(!_currentEncaps) // Lazy initialization.
1699 {
1700 _currentEncaps = &_preAllocatedEncaps;
1701 _currentEncaps->encoding = _encoding;
1702 _currentEncaps->sz = static_cast<Ice::Int>(b.size());
1703 }
1704
1705 if(!_currentEncaps->decoder) // Lazy initialization.
1706 {
1707 ValueFactoryManagerPtr vfm = valueFactoryManager();
1708 if(_currentEncaps->encoding == Encoding_1_0)
1709 {
1710 _currentEncaps->decoder = new EncapsDecoder10(this, _currentEncaps, _sliceValues, _classGraphDepthMax, vfm);
1711 }
1712 else
1713 {
1714 _currentEncaps->decoder = new EncapsDecoder11(this, _currentEncaps, _sliceValues, _classGraphDepthMax, vfm);
1715 }
1716 }
1717 }
1718
~EncapsDecoder()1719 Ice::InputStream::EncapsDecoder::~EncapsDecoder()
1720 {
1721 // Out of line to avoid weak vtable
1722 }
1723
1724 string
readTypeId(bool isIndex)1725 Ice::InputStream::EncapsDecoder::readTypeId(bool isIndex)
1726 {
1727 if(isIndex)
1728 {
1729 Int index = _stream->readSize();
1730 TypeIdMap::const_iterator k = _typeIdMap.find(index);
1731 if(k == _typeIdMap.end())
1732 {
1733 throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
1734 }
1735 return k->second;
1736 }
1737 else
1738 {
1739 string typeId;
1740 _stream->read(typeId, false);
1741 _typeIdMap.insert(make_pair(++_typeIdIndex, typeId));
1742 return typeId;
1743 }
1744 }
1745
1746 Ice::ValuePtr
newInstance(const string & typeId)1747 Ice::InputStream::EncapsDecoder::newInstance(const string& typeId)
1748 {
1749 Ice::ValuePtr v;
1750
1751 //
1752 // Try to find a factory registered for the specific type.
1753 //
1754 #ifdef ICE_CPP11_MAPPING
1755 function<ValuePtr(const string&)> userFactory;
1756 if(_valueFactoryManager)
1757 {
1758 userFactory = _valueFactoryManager->find(typeId);
1759 if(userFactory)
1760 {
1761 v = userFactory(typeId);
1762 }
1763 }
1764 #else
1765 ValueFactoryPtr userFactory;
1766 if(_valueFactoryManager)
1767 {
1768 userFactory = _valueFactoryManager->find(typeId);
1769 if(userFactory)
1770 {
1771 v = userFactory->create(typeId);
1772 }
1773 }
1774 #endif
1775 //
1776 // If that fails, invoke the default factory if one has been registered.
1777 //
1778 if(!v && _valueFactoryManager)
1779 {
1780 userFactory = _valueFactoryManager->find("");
1781 if(userFactory)
1782 {
1783 #ifdef ICE_CPP11_MAPPING
1784 v = userFactory(typeId);
1785 #else
1786 v = userFactory->create(typeId);
1787 #endif
1788 }
1789 }
1790
1791 //
1792 // Last chance: check the table of static factories (i.e.,
1793 // automatically generated factories for concrete classes).
1794 //
1795 if(!v)
1796 {
1797 #ifdef ICE_CPP11_MAPPING
1798 function<ValuePtr(const string&)> of = IceInternal::factoryTable->getValueFactory(typeId);
1799 if(of)
1800 {
1801 v = of(typeId);
1802 assert(v);
1803 }
1804 #else
1805 ValueFactoryPtr of = IceInternal::factoryTable->getValueFactory(typeId);
1806 if(of)
1807 {
1808 v = of->create(typeId);
1809 assert(v);
1810 }
1811 #endif
1812 }
1813 return v;
1814 }
1815
1816 void
addPatchEntry(Int index,PatchFunc patchFunc,void * patchAddr)1817 Ice::InputStream::EncapsDecoder::addPatchEntry(Int index, PatchFunc patchFunc, void* patchAddr)
1818 {
1819 assert(index > 0);
1820
1821 //
1822 // Check if we already unmarshaled the object. If that's the case,
1823 // just patch the object smart pointer and we're done.
1824 //
1825 IndexToPtrMap::iterator p = _unmarshaledMap.find(index);
1826 if(p != _unmarshaledMap.end())
1827 {
1828 (*patchFunc)(patchAddr, p->second);
1829 return;
1830 }
1831
1832 //
1833 // Add a patch entry if the object isn't unmarshaled yet, the
1834 // smart pointer will be patched when the instance is
1835 // unmarshaled.
1836 //
1837
1838 PatchMap::iterator q = _patchMap.find(index);
1839 if(q == _patchMap.end())
1840 {
1841 //
1842 // We have no outstanding instances to be patched for this
1843 // index, so make a new entry in the patch map.
1844 //
1845 q = _patchMap.insert(make_pair(index, PatchList())).first;
1846 }
1847
1848 //
1849 // Append a patch entry for this instance.
1850 //
1851 PatchEntry e;
1852 e.patchFunc = patchFunc;
1853 e.patchAddr = patchAddr;
1854 e.classGraphDepth = _classGraphDepth;
1855 q->second.push_back(e);
1856 }
1857
1858 void
unmarshal(Int index,const Ice::ValuePtr & v)1859 Ice::InputStream::EncapsDecoder::unmarshal(Int index, const Ice::ValuePtr& v)
1860 {
1861 //
1862 // Add the object to the map of unmarshaled instances, this must
1863 // be done before reading the instances (for circular references).
1864 //
1865 _unmarshaledMap.insert(make_pair(index, v));
1866
1867 //
1868 // Read the object.
1869 //
1870 v->_iceRead(_stream);
1871
1872 //
1873 // Patch all instances now that the object is unmarshaled.
1874 //
1875 PatchMap::iterator patchPos = _patchMap.find(index);
1876 if(patchPos != _patchMap.end())
1877 {
1878 assert(patchPos->second.size() > 0);
1879
1880 //
1881 // Patch all pointers that refer to the instance.
1882 //
1883 for(PatchList::iterator k = patchPos->second.begin(); k != patchPos->second.end(); ++k)
1884 {
1885 (*k->patchFunc)(k->patchAddr, v);
1886 }
1887
1888 //
1889 // Clear out the patch map for that index -- there is nothing left
1890 // to patch for that index for the time being.
1891 //
1892 _patchMap.erase(patchPos);
1893 }
1894
1895 if(_valueList.empty() && _patchMap.empty())
1896 {
1897 _stream->postUnmarshal(v);
1898 }
1899 else
1900 {
1901 _valueList.push_back(v);
1902
1903 if(_patchMap.empty())
1904 {
1905 //
1906 // Iterate over the value list and invoke ice_postUnmarshal on
1907 // each value. We must do this after all values have been
1908 // unmarshaled in order to ensure that any value data members
1909 // have been properly patched.
1910 //
1911 for(ValueList::iterator p = _valueList.begin(); p != _valueList.end(); ++p)
1912 {
1913 _stream->postUnmarshal(*p);
1914 }
1915 _valueList.clear();
1916 }
1917 }
1918 }
1919
1920 void
read(PatchFunc patchFunc,void * patchAddr)1921 Ice::InputStream::EncapsDecoder10::read(PatchFunc patchFunc, void* patchAddr)
1922 {
1923 assert(patchFunc && patchAddr);
1924
1925 //
1926 // Object references are encoded as a negative integer in 1.0.
1927 //
1928 Int index;
1929 _stream->read(index);
1930 if(index > 0)
1931 {
1932 throw MarshalException(__FILE__, __LINE__, "invalid object id");
1933 }
1934 index = -index;
1935
1936 if(index == 0)
1937 {
1938 //
1939 // Calling the patch function for null instances is necessary for correct functioning of Ice for
1940 // Python and Ruby.
1941 //
1942 ValuePtr nil;
1943 patchFunc(patchAddr, nil);
1944 }
1945 else
1946 {
1947 addPatchEntry(index, patchFunc, patchAddr);
1948 }
1949 }
1950
1951 void
throwException(ICE_IN (ICE_DELEGATE (UserExceptionFactory))factory)1952 Ice::InputStream::EncapsDecoder10::throwException(ICE_IN(ICE_DELEGATE(UserExceptionFactory)) factory)
1953 {
1954 assert(_sliceType == NoSlice);
1955
1956 //
1957 // User exception with the 1.0 encoding start with a boolean flag
1958 // that indicates whether or not the exception has classes.
1959 //
1960 // This allows reading the pending values even if some part of
1961 // the exception was sliced.
1962 //
1963 bool usesClasses;
1964 _stream->read(usesClasses);
1965
1966 _sliceType = ExceptionSlice;
1967 _skipFirstSlice = false;
1968
1969 //
1970 // Read the first slice header.
1971 //
1972 startSlice();
1973 const string mostDerivedId = _typeId;
1974 ICE_DELEGATE(UserExceptionFactory) exceptionFactory = factory;
1975 while(true)
1976 {
1977 //
1978 // Look for a statically-generated factory for this ID.
1979 //
1980 if(!exceptionFactory)
1981 {
1982 exceptionFactory = factoryTable->getExceptionFactory(_typeId);
1983 }
1984
1985 //
1986 // We found a factory, we get out of this loop.
1987 //
1988 if(exceptionFactory)
1989 {
1990 //
1991 // Got factory -- ask the factory to instantiate the
1992 // exception, initialize the exception members, and throw
1993 // the exception.
1994 //
1995 try
1996 {
1997 #ifdef ICE_CPP11_MAPPING
1998 exceptionFactory(_typeId);
1999 #else
2000 exceptionFactory->createAndThrow(_typeId);
2001 #endif
2002 }
2003 catch(UserException& ex)
2004 {
2005 ex._read(_stream);
2006 if(usesClasses)
2007 {
2008 readPendingValues();
2009 }
2010 throw;
2011
2012 // Never reached.
2013 }
2014 }
2015
2016 //
2017 // Slice off what we don't understand.
2018 //
2019 skipSlice();
2020 try
2021 {
2022 startSlice();
2023 }
2024 catch(UnmarshalOutOfBoundsException& ex)
2025 {
2026 //
2027 // An oversight in the 1.0 encoding means there is no marker to indicate
2028 // the last slice of an exception. As a result, we just try to read the
2029 // next type ID, which raises UnmarshalOutOfBoundsException when the
2030 // input buffer underflows.
2031 //
2032 // Set the reason member to a more helpful message.
2033 //
2034 ex.reason = "unknown exception type `" + mostDerivedId + "'";
2035 throw;
2036 }
2037 }
2038 }
2039
2040 void
2041 #ifndef NDEBUG
startInstance(SliceType sliceType)2042 Ice::InputStream::EncapsDecoder10::startInstance(SliceType sliceType)
2043 #else
2044 Ice::InputStream::EncapsDecoder10::startInstance(SliceType)
2045 #endif
2046 {
2047 assert(_sliceType == sliceType);
2048 _skipFirstSlice = true;
2049 }
2050
2051 SlicedDataPtr
endInstance(bool)2052 Ice::InputStream::EncapsDecoder10::endInstance(bool)
2053 {
2054 //
2055 // Read the Ice::Value slice.
2056 //
2057 if(_sliceType == ValueSlice)
2058 {
2059 startSlice();
2060 Int sz = _stream->readSize(); // For compatibility with the old AFM.
2061 if(sz != 0)
2062 {
2063 throw MarshalException(__FILE__, __LINE__, "invalid Object slice");
2064 }
2065 endSlice();
2066 }
2067 _sliceType = NoSlice;
2068 return 0;
2069 }
2070
2071 const std::string&
startSlice()2072 Ice::InputStream::EncapsDecoder10::startSlice()
2073 {
2074 //
2075 // If first slice, don't read the header, it was already read in
2076 // readInstance or throwException to find the factory.
2077 //
2078 if(_skipFirstSlice)
2079 {
2080 _skipFirstSlice = false;
2081 return _typeId;
2082 }
2083
2084 //
2085 // For values, first read the type ID boolean which indicates
2086 // whether or not the type ID is encoded as a string or as an
2087 // index. For exceptions, the type ID is always encoded as a
2088 // string.
2089 //
2090 if(_sliceType == ValueSlice)
2091 {
2092 bool isIndex;
2093 _stream->read(isIndex);
2094 _typeId = readTypeId(isIndex);
2095 }
2096 else
2097 {
2098 _stream->read(_typeId, false);
2099 }
2100
2101 _stream->read(_sliceSize);
2102 if(_sliceSize < 4)
2103 {
2104 throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
2105 }
2106 return _typeId;
2107 }
2108
2109 void
endSlice()2110 Ice::InputStream::EncapsDecoder10::endSlice()
2111 {
2112 }
2113
2114 void
skipSlice()2115 Ice::InputStream::EncapsDecoder10::skipSlice()
2116 {
2117 _stream->traceSkipSlice(_typeId, _sliceType);
2118 assert(_sliceSize >= 4);
2119 _stream->skip(_sliceSize - sizeof(Int));
2120 }
2121
2122 void
readPendingValues()2123 Ice::InputStream::EncapsDecoder10::readPendingValues()
2124 {
2125 Int num;
2126 do
2127 {
2128 num = _stream->readSize();
2129 for(Int k = num; k > 0; --k)
2130 {
2131 readInstance();
2132 }
2133 }
2134 while(num);
2135
2136 if(!_patchMap.empty())
2137 {
2138 //
2139 // If any entries remain in the patch map, the sender has sent an index for an object, but failed
2140 // to supply the object.
2141 //
2142 throw MarshalException(__FILE__, __LINE__, "index for class received, but no instance");
2143 }
2144 }
2145
2146 void
readInstance()2147 Ice::InputStream::EncapsDecoder10::readInstance()
2148 {
2149 Int index;
2150 _stream->read(index);
2151
2152 if(index <= 0)
2153 {
2154 throw MarshalException(__FILE__, __LINE__, "invalid object id");
2155 }
2156
2157 _sliceType = ValueSlice;
2158 _skipFirstSlice = false;
2159
2160 //
2161 // Read the first slice header.
2162 //
2163 startSlice();
2164 const string mostDerivedId = _typeId;
2165 ValuePtr v;
2166 while(true)
2167 {
2168 //
2169 // For the 1.0 encoding, the type ID for the base Object class
2170 // marks the last slice.
2171 //
2172 if(_typeId == Object::ice_staticId())
2173 {
2174 throw NoValueFactoryException(__FILE__, __LINE__, "", mostDerivedId);
2175 }
2176
2177 v = newInstance(_typeId);
2178
2179 //
2180 // We found a factory, we get out of this loop.
2181 //
2182 if(v)
2183 {
2184 break;
2185 }
2186
2187 //
2188 // If value slicing is disabled, stop unmarshaling.
2189 //
2190 if(!_sliceValues)
2191 {
2192 throw NoValueFactoryException(__FILE__, __LINE__, "no value factory found and value slicing is disabled",
2193 _typeId);
2194 }
2195
2196 //
2197 // Slice off what we don't understand.
2198 //
2199 skipSlice();
2200 startSlice(); // Read next Slice header for next iteration.
2201 }
2202
2203 //
2204 // Compute the biggest class graph depth of this object. To compute this,
2205 // we get the class graph depth of each ancestor from the patch map and
2206 // keep the biggest one.
2207 //
2208 _classGraphDepth = 0;
2209 PatchMap::iterator patchPos = _patchMap.find(index);
2210 if(patchPos != _patchMap.end())
2211 {
2212 assert(patchPos->second.size() > 0);
2213 for(PatchList::iterator k = patchPos->second.begin(); k != patchPos->second.end(); ++k)
2214 {
2215 if(k->classGraphDepth > _classGraphDepth)
2216 {
2217 _classGraphDepth = k->classGraphDepth;
2218 }
2219 }
2220 }
2221
2222 if(++_classGraphDepth > _classGraphDepthMax)
2223 {
2224 throw MarshalException(__FILE__, __LINE__, "maximum class graph depth reached");
2225 }
2226
2227 //
2228 // Unmarshal the instance and add it to the map of unmarshaled instances.
2229 //
2230 unmarshal(index, v);
2231 }
2232
2233 void
read(PatchFunc patchFunc,void * patchAddr)2234 Ice::InputStream::EncapsDecoder11::read(PatchFunc patchFunc, void* patchAddr)
2235 {
2236 Int index = _stream->readSize();
2237 if(index < 0)
2238 {
2239 throw MarshalException(__FILE__, __LINE__, "invalid object id");
2240 }
2241 else if(index == 0)
2242 {
2243 //
2244 // Calling the patch function for null instances is necessary for correct functioning of Ice for
2245 // Python and Ruby.
2246 //
2247 if(patchFunc)
2248 {
2249 ValuePtr nil;
2250 patchFunc(patchAddr, nil);
2251 }
2252 }
2253 else if(_current && _current->sliceFlags & FLAG_HAS_INDIRECTION_TABLE)
2254 {
2255 //
2256 // When reading an object within a slice and there's an
2257 // indirect object table, always read an indirect reference
2258 // that points to an object from the indirect object table
2259 // marshaled at the end of the Slice.
2260 //
2261 // Maintain a list of indirect references. Note that the
2262 // indirect index starts at 1, so we decrement it by one to
2263 // derive an index into the indirection table that we'll read
2264 // at the end of the slice.
2265 //
2266 if(patchFunc)
2267 {
2268 IndirectPatchEntry e;
2269 e.index = index - 1;
2270 e.patchFunc = patchFunc;
2271 e.patchAddr = patchAddr;
2272 _current->indirectPatchList.push_back(e);
2273 }
2274 }
2275 else
2276 {
2277 readInstance(index, patchFunc, patchAddr);
2278 }
2279 }
2280
2281 void
throwException(ICE_IN (ICE_DELEGATE (UserExceptionFactory))factory)2282 Ice::InputStream::EncapsDecoder11::throwException(ICE_IN(ICE_DELEGATE(UserExceptionFactory)) factory)
2283 {
2284 assert(!_current);
2285
2286 push(ExceptionSlice);
2287
2288 //
2289 // Read the first slice header.
2290 //
2291 startSlice();
2292 const string mostDerivedId = _current->typeId;
2293 ICE_DELEGATE(UserExceptionFactory) exceptionFactory = factory;
2294 while(true)
2295 {
2296 //
2297 // Look for a statically-generated factory for this ID.
2298 //
2299 if(!exceptionFactory)
2300 {
2301 exceptionFactory = factoryTable->getExceptionFactory(_current->typeId);
2302 }
2303
2304 //
2305 // We found a factory, we get out of this loop.
2306 //
2307 if(exceptionFactory)
2308 {
2309 //
2310 // Got factory -- ask the factory to instantiate the
2311 // exception, initialize the exception members, and throw
2312 // the exception.
2313 //
2314 try
2315 {
2316 #ifdef ICE_CPP11_MAPPING
2317 exceptionFactory(_current->typeId);
2318 #else
2319 exceptionFactory->createAndThrow(_current->typeId);
2320 #endif
2321 }
2322 catch(UserException& ex)
2323 {
2324 ex._read(_stream);
2325 throw;
2326
2327 // Never reached.
2328 }
2329 }
2330
2331 //
2332 // Slice off what we don't understand.
2333 //
2334 skipSlice();
2335
2336 //
2337 // If this is the last slice, raise an exception and stop un-marshalling.
2338 //
2339 if(_current->sliceFlags & FLAG_IS_LAST_SLICE)
2340 {
2341 throw UnknownUserException(__FILE__, __LINE__, mostDerivedId);
2342 }
2343
2344 startSlice();
2345 }
2346 }
2347
2348 void
2349 #ifndef NDEBUG
startInstance(SliceType sliceType)2350 Ice::InputStream::EncapsDecoder11::startInstance(SliceType sliceType)
2351 #else
2352 Ice::InputStream::EncapsDecoder11::startInstance(SliceType)
2353 #endif
2354 {
2355 assert(_current->sliceType == sliceType);
2356 _current->skipFirstSlice = true;
2357 }
2358
2359 SlicedDataPtr
endInstance(bool preserve)2360 Ice::InputStream::EncapsDecoder11::endInstance(bool preserve)
2361 {
2362 SlicedDataPtr slicedData;
2363 if(preserve)
2364 {
2365 slicedData = readSlicedData();
2366 }
2367 _current->slices.clear();
2368 _current->indirectionTables.clear();
2369 _current = _current->previous;
2370 return slicedData;
2371 }
2372
2373 const std::string&
startSlice()2374 Ice::InputStream::EncapsDecoder11::startSlice()
2375 {
2376 //
2377 // If first slice, don't read the header, it was already read in
2378 // readInstance or throwException to find the factory.
2379 //
2380 if(_current->skipFirstSlice)
2381 {
2382 _current->skipFirstSlice = false;
2383 return _current->typeId;
2384 }
2385
2386 _stream->read(_current->sliceFlags);
2387
2388 //
2389 // Read the type ID, for value slices the type ID is encoded as a
2390 // string or as an index, for exceptions it's always encoded as a
2391 // string.
2392 //
2393 if(_current->sliceType == ValueSlice)
2394 {
2395 if((_current->sliceFlags & FLAG_HAS_TYPE_ID_COMPACT) == FLAG_HAS_TYPE_ID_COMPACT) // Must be checked first!
2396 {
2397 _current->typeId.clear();
2398 _current->compactId = _stream->readSize();
2399 }
2400 else if(_current->sliceFlags & (FLAG_HAS_TYPE_ID_STRING | FLAG_HAS_TYPE_ID_INDEX))
2401 {
2402 _current->typeId = readTypeId(_current->sliceFlags & FLAG_HAS_TYPE_ID_INDEX);
2403 _current->compactId = -1;
2404 }
2405 else
2406 {
2407 // Only the most derived slice encodes the type ID for the compact format.
2408 _current->typeId.clear();
2409 _current->compactId = -1;
2410 }
2411 }
2412 else
2413 {
2414 _stream->read(_current->typeId, false);
2415 }
2416
2417 //
2418 // Read the slice size if necessary.
2419 //
2420 if(_current->sliceFlags & FLAG_HAS_SLICE_SIZE)
2421 {
2422 _stream->read(_current->sliceSize);
2423 if(_current->sliceSize < 4)
2424 {
2425 throw UnmarshalOutOfBoundsException(__FILE__, __LINE__);
2426 }
2427 }
2428 else
2429 {
2430 _current->sliceSize = 0;
2431 }
2432
2433 return _current->typeId;
2434 }
2435
2436 void
endSlice()2437 Ice::InputStream::EncapsDecoder11::endSlice()
2438 {
2439 if(_current->sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS)
2440 {
2441 _stream->skipOptionals();
2442 }
2443
2444 //
2445 // Read the indirect object table if one is present.
2446 //
2447 if(_current->sliceFlags & FLAG_HAS_INDIRECTION_TABLE)
2448 {
2449 IndexList indirectionTable(_stream->readAndCheckSeqSize(1));
2450 for(IndexList::iterator p = indirectionTable.begin(); p != indirectionTable.end(); ++p)
2451 {
2452 *p = readInstance(_stream->readSize(), 0, 0);
2453 }
2454
2455 //
2456 // Sanity checks. If there are optional members, it's possible
2457 // that not all object references were read if they are from
2458 // unknown optional data members.
2459 //
2460 if(indirectionTable.empty())
2461 {
2462 throw MarshalException(__FILE__, __LINE__, "empty indirection table");
2463 }
2464 if(_current->indirectPatchList.empty() && !(_current->sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS))
2465 {
2466 throw MarshalException(__FILE__, __LINE__, "no references to indirection table");
2467 }
2468
2469 //
2470 // Convert indirect references into direct references.
2471 //
2472 IndirectPatchList::iterator p;
2473 for(p = _current->indirectPatchList.begin(); p != _current->indirectPatchList.end(); ++p)
2474 {
2475 assert(p->index >= 0);
2476 if(p->index >= static_cast<Int>(indirectionTable.size()))
2477 {
2478 throw MarshalException(__FILE__, __LINE__, "indirection out of range");
2479 }
2480 addPatchEntry(indirectionTable[p->index], p->patchFunc, p->patchAddr);
2481 }
2482 _current->indirectPatchList.clear();
2483 }
2484 }
2485
2486 void
skipSlice()2487 Ice::InputStream::EncapsDecoder11::skipSlice()
2488 {
2489 _stream->traceSkipSlice(_current->typeId, _current->sliceType);
2490
2491 Container::iterator start = _stream->i;
2492
2493 if(_current->sliceFlags & FLAG_HAS_SLICE_SIZE)
2494 {
2495 assert(_current->sliceSize >= 4);
2496 _stream->skip(_current->sliceSize - sizeof(Int));
2497 }
2498 else
2499 {
2500 if(_current->sliceType == ValueSlice)
2501 {
2502 throw NoValueFactoryException(__FILE__, __LINE__,
2503 "no value factory found and compact format prevents "
2504 "slicing (the sender should use the sliced format instead)",
2505 _current->typeId);
2506 }
2507 else
2508 {
2509 throw UnknownUserException(__FILE__, __LINE__, _current->typeId);
2510 }
2511 }
2512
2513 //
2514 // Preserve this slice.
2515 //
2516 SliceInfoPtr info = ICE_MAKE_SHARED(SliceInfo);
2517 info->typeId = _current->typeId;
2518 info->compactId = _current->compactId;
2519 info->hasOptionalMembers = _current->sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS;
2520 info->isLastSlice = _current->sliceFlags & FLAG_IS_LAST_SLICE;
2521 if(info->hasOptionalMembers)
2522 {
2523 //
2524 // Don't include the optional member end marker. It will be re-written by
2525 // endSlice when the sliced data is re-written.
2526 //
2527 vector<Byte>(start, _stream->i - 1).swap(info->bytes);
2528 }
2529 else
2530 {
2531 vector<Byte>(start, _stream->i).swap(info->bytes);
2532 }
2533
2534 _current->indirectionTables.push_back(IndexList());
2535
2536 //
2537 // Read the indirect object table. We read the instances or their
2538 // IDs if the instance is a reference to an already un-marhsaled
2539 // object.
2540 //
2541 // The SliceInfo object sequence is initialized only if
2542 // readSlicedData is called.
2543 //
2544 if(_current->sliceFlags & FLAG_HAS_INDIRECTION_TABLE)
2545 {
2546 IndexList& table = _current->indirectionTables.back();
2547 table.resize(_stream->readAndCheckSeqSize(1));
2548 for(IndexList::iterator p = table.begin(); p != table.end(); ++p)
2549 {
2550 *p = readInstance(_stream->readSize(), 0, 0);
2551 }
2552 }
2553
2554 _current->slices.push_back(info);
2555 }
2556
2557 bool
readOptional(Ice::Int readTag,Ice::OptionalFormat expectedFormat)2558 Ice::InputStream::EncapsDecoder11::readOptional(Ice::Int readTag, Ice::OptionalFormat expectedFormat)
2559 {
2560 if(!_current)
2561 {
2562 return _stream->readOptImpl(readTag, expectedFormat);
2563 }
2564 else if(_current->sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS)
2565 {
2566 return _stream->readOptImpl(readTag, expectedFormat);
2567 }
2568 return false;
2569 }
2570
2571 Int
readInstance(Int index,PatchFunc patchFunc,void * patchAddr)2572 Ice::InputStream::EncapsDecoder11::readInstance(Int index, PatchFunc patchFunc, void* patchAddr)
2573 {
2574 assert(index > 0);
2575
2576 if(index > 1)
2577 {
2578 if(patchFunc)
2579 {
2580 addPatchEntry(index, patchFunc, patchAddr);
2581 }
2582 return index;
2583 }
2584
2585 push(ValueSlice);
2586
2587 //
2588 // Get the object ID before we start reading slices. If some
2589 // slices are skiped, the indirect object table are still read and
2590 // might read other instances.
2591 //
2592 index = ++_valueIdIndex;
2593
2594 //
2595 // Read the first slice header.
2596 //
2597 startSlice();
2598 const string mostDerivedId = _current->typeId;
2599 Ice::ValuePtr v;
2600 while(true)
2601 {
2602 if(_current->compactId >= 0)
2603 {
2604 //
2605 // Translate a compact (numeric) type ID into a string type ID.
2606 //
2607 _current->typeId = _stream->resolveCompactId(_current->compactId);
2608 if(_current->typeId.empty())
2609 {
2610 _current->typeId = IceInternal::factoryTable->getTypeId(_current->compactId);
2611 }
2612 }
2613
2614 if(!_current->typeId.empty())
2615 {
2616 v = newInstance(_current->typeId);
2617
2618 //
2619 // We found a factory, we get out of this loop.
2620 //
2621 if(v)
2622 {
2623 break;
2624 }
2625 }
2626
2627 //
2628 // If value slicing is disabled, stop unmarshaling.
2629 //
2630 if(!_sliceValues)
2631 {
2632 throw NoValueFactoryException(__FILE__, __LINE__, "no value factory found and value slicing is disabled",
2633 _current->typeId);
2634 }
2635
2636 //
2637 // Slice off what we don't understand.
2638 //
2639 skipSlice();
2640
2641 //
2642 // If this is the last slice, keep the object as an opaque UnknownSlicedValue.
2643 //
2644 if(_current->sliceFlags & FLAG_IS_LAST_SLICE)
2645 {
2646 //
2647 // Provide a factory with an opportunity to supply the object.
2648 // We pass the "::Ice::Object" ID to indicate that this is the
2649 // last chance to preserve the object.
2650 //
2651 v = newInstance(Object::ice_staticId());
2652 if(!v)
2653 {
2654 v = ICE_MAKE_SHARED(UnknownSlicedValue, mostDerivedId);
2655 }
2656
2657 break;
2658 }
2659
2660 startSlice(); // Read next Slice header for next iteration.
2661 }
2662
2663 if(++_classGraphDepth > _classGraphDepthMax)
2664 {
2665 throw MarshalException(__FILE__, __LINE__, "maximum class graph depth reached");
2666 }
2667
2668 //
2669 // Unmarshal the object.
2670 //
2671 unmarshal(index, v);
2672
2673 --_classGraphDepth;
2674
2675 if(!_current && !_patchMap.empty())
2676 {
2677 //
2678 // If any entries remain in the patch map, the sender has sent an index for an object, but failed
2679 // to supply the object.
2680 //
2681 throw MarshalException(__FILE__, __LINE__, "index for class received, but no instance");
2682 }
2683
2684 if(patchFunc)
2685 {
2686 patchFunc(patchAddr, v);
2687 }
2688 return index;
2689 }
2690
2691 SlicedDataPtr
readSlicedData()2692 Ice::InputStream::EncapsDecoder11::readSlicedData()
2693 {
2694 if(_current->slices.empty()) // No preserved slices.
2695 {
2696 return 0;
2697 }
2698
2699 //
2700 // The indirectionTables member holds the indirection table for
2701 // each slice in slices.
2702 //
2703 assert(_current->slices.size() == _current->indirectionTables.size());
2704 for(SliceInfoSeq::size_type n = 0; n < _current->slices.size(); ++n)
2705 {
2706 //
2707 // We use the "instances" list in SliceInfo to hold references
2708 // to the target instances. Note that the instances might not have
2709 // been read yet in the case of a circular reference to an
2710 // enclosing instance.
2711 //
2712 const IndexList& table = _current->indirectionTables[n];
2713 vector<ValuePtr>& instances = _current->slices[n]->instances;
2714 instances.resize(table.size());
2715 IndexList::size_type j = 0;
2716 for(IndexList::const_iterator p = table.begin(); p != table.end(); ++p)
2717 {
2718 #ifdef ICE_CPP11_MAPPING
2719 addPatchEntry(*p, &patchHandle<Value>, &instances[j++]);
2720 #else
2721 addPatchEntry(*p, &patchHandle<Object>, &instances[j++]);
2722 #endif
2723 }
2724 }
2725 return ICE_MAKE_SHARED(SlicedData, _current->slices);
2726 }
2727