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