1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4
5 #ifndef ICE_INPUT_STREAM_H
6 #define ICE_INPUT_STREAM_H
7
8 #include <Ice/CommunicatorF.h>
9 #include <Ice/InstanceF.h>
10 #include <Ice/Object.h>
11 #include <Ice/ValueF.h>
12 #include <Ice/ProxyF.h>
13 #include <Ice/LoggerF.h>
14 #include <Ice/ValueFactory.h>
15 #include <Ice/Buffer.h>
16 #include <Ice/Protocol.h>
17 #include <Ice/SlicedDataF.h>
18 #include <Ice/UserExceptionFactory.h>
19 #include <Ice/StreamHelpers.h>
20 #include <Ice/FactoryTable.h>
21
22 namespace Ice
23 {
24
25 class UserException;
26
27 /// \cond INTERNAL
28 template<typename T> inline void
patchHandle(void * addr,const ValuePtr & v)29 patchHandle(void* addr, const ValuePtr& v)
30 {
31 #ifdef ICE_CPP11_MAPPING
32 ::std::shared_ptr<T>* handle = static_cast<::std::shared_ptr<T>*>(addr);
33 *handle = ::std::dynamic_pointer_cast<T>(v);
34 if(v && !(*handle))
35 {
36 IceInternal::Ex::throwUOE(T::ice_staticId(), v);
37 }
38 #else
39 IceInternal::Handle<T>* p = static_cast<IceInternal::Handle<T>*>(addr);
40 _icePatchObjectPtr(*p, v); // Generated _icePatchObjectPtr function, necessary for forward declarations.
41 #endif
42 }
43 /// \endcond
44
45 /**
46 * Interface for input streams used to extract Slice types from a sequence of bytes.
47 * \headerfile Ice/Ice.h
48 */
49 class ICE_API InputStream : public IceInternal::Buffer
50 {
51 public:
52
53 typedef size_t size_type;
54
55 /**
56 * Signature for a patch function, used to receive an unmarshaled value.
57 * @param addr The target address.
58 * @param v The unmarshaled value.
59 */
60 typedef void (*PatchFunc)(void* addr, const ValuePtr& v);
61
62 /**
63 * Constructs a stream using the latest encoding version but without a communicator.
64 * This stream will not be able to unmarshal a proxy. For other unmarshaling tasks,
65 * you can provide Helpers for objects that are normally provided by a communicator.
66 * You can supply a communicator later by calling initialize().
67 */
68 InputStream();
69
70 /**
71 * Constructs a stream using the latest encoding version but without a communicator.
72 * This stream will not be able to unmarshal a proxy. For other unmarshaling tasks,
73 * you can provide Helpers for objects that are normally provided by a communicator.
74 * You can supply a communicator later by calling initialize().
75 * @param bytes The encoded data.
76 */
77 InputStream(const std::vector<Byte>& bytes);
78
79 /**
80 * Constructs a stream using the latest encoding version but without a communicator.
81 * This stream will not be able to unmarshal a proxy. For other unmarshaling tasks,
82 * you can provide Helpers for objects that are normally provided by a communicator.
83 * You can supply a communicator later by calling initialize().
84 * @param bytes The encoded data.
85 */
86 InputStream(const std::pair<const Byte*, const Byte*>& bytes);
87
88 /// \cond INTERNAL
89 InputStream(IceInternal::Buffer&, bool = false);
90 /// \endcond
91
92 /**
93 * Constructs a stream using the communicator's default encoding version.
94 * @param communicator The communicator to use for unmarshaling tasks.
95 */
96 InputStream(const CommunicatorPtr& communicator);
97
98 /**
99 * Constructs a stream using the communicator's default encoding version.
100 * @param communicator The communicator to use for unmarshaling tasks.
101 * @param bytes The encoded data.
102 */
103 InputStream(const CommunicatorPtr& communicator, const std::vector<Byte>& bytes);
104
105 /**
106 * Constructs a stream using the communicator's default encoding version.
107 * @param communicator The communicator to use for unmarshaling tasks.
108 * @param bytes The encoded data.
109 */
110 InputStream(const CommunicatorPtr& communicator, const std::pair<const Byte*, const Byte*>& bytes);
111
112 /// \cond INTERNAL
113 InputStream(const CommunicatorPtr& communicator, IceInternal::Buffer&, bool = false);
114 /// \endcond
115
116 /**
117 * Constructs a stream using the given encoding version but without a communicator.
118 * This stream will not be able to unmarshal a proxy. For other unmarshaling tasks,
119 * you can provide Helpers for objects that are normally provided by a communicator.
120 * You can supply a communicator later by calling initialize().
121 * @param version The encoding version used to encode the data to be unmarshaled.
122 */
123 InputStream(const EncodingVersion& version);
124
125 /**
126 * Constructs a stream using the given encoding version but without a communicator.
127 * This stream will not be able to unmarshal a proxy. For other unmarshaling tasks,
128 * you can provide Helpers for objects that are normally provided by a communicator.
129 * You can supply a communicator later by calling initialize().
130 * @param version The encoding version used to encode the data to be unmarshaled.
131 * @param bytes The encoded data.
132 */
133 InputStream(const EncodingVersion& version, const std::vector<Byte>& bytes);
134
135 /**
136 * Constructs a stream using the given encoding version but without a communicator.
137 * This stream will not be able to unmarshal a proxy. For other unmarshaling tasks,
138 * you can provide Helpers for objects that are normally provided by a communicator.
139 * You can supply a communicator later by calling initialize().
140 * @param version The encoding version used to encode the data to be unmarshaled.
141 * @param bytes The encoded data.
142 */
143 InputStream(const EncodingVersion& version, const std::pair<const Byte*, const Byte*>& bytes);
144
145 /// \cond INTERNAL
146 InputStream(const EncodingVersion&, IceInternal::Buffer&, bool = false);
147 /// \endcond
148
149 /**
150 * Constructs a stream using the given communicator and encoding version.
151 * @param communicator The communicator to use for unmarshaling tasks.
152 * @param version The encoding version used to encode the data to be unmarshaled.
153 */
154 InputStream(const CommunicatorPtr& communicator, const EncodingVersion& version);
155
156 /**
157 * Constructs a stream using the given communicator and encoding version.
158 * @param communicator The communicator to use for unmarshaling tasks.
159 * @param version The encoding version used to encode the data to be unmarshaled.
160 * @param bytes The encoded data.
161 */
162 InputStream(const CommunicatorPtr& communicator, const EncodingVersion& version, const std::vector<Byte>& bytes);
163
164 /**
165 * Constructs a stream using the given communicator and encoding version.
166 * @param communicator The communicator to use for unmarshaling tasks.
167 * @param version The encoding version used to encode the data to be unmarshaled.
168 * @param bytes The encoded data.
169 */
170 InputStream(const CommunicatorPtr& communicator, const EncodingVersion& version,
171 const std::pair<const Byte*, const Byte*>& bytes);
172
173 /// \cond INTERNAL
174 InputStream(const CommunicatorPtr&, const EncodingVersion&, IceInternal::Buffer&, bool = false);
175 /// \endcond
176
~InputStream()177 ~InputStream()
178 {
179 // Inlined for performance reasons.
180
181 if(_currentEncaps != &_preAllocatedEncaps)
182 {
183 clear(); // Not inlined.
184 }
185
186 #ifdef ICE_CPP11_MAPPING
187
188 for(auto d: _deleters)
189 {
190 d();
191 }
192 #endif
193 }
194
195 /**
196 * Initializes the stream to use the communicator's default encoding version.
197 * Use initialize() if you originally constructed the stream without a communicator.
198 * @param communicator The communicator to use for unmarshaling tasks.
199 */
200 void initialize(const CommunicatorPtr& communicator);
201
202 /**
203 * Initializes the stream to use the given communicator and encoding version.
204 * Use initialize() if you originally constructed the stream without a communicator.
205 * @param communicator The communicator to use for unmarshaling tasks.
206 * @param version The encoding version used to encode the data to be unmarshaled.
207 */
208 void initialize(const CommunicatorPtr& communicator, const EncodingVersion& version);
209
210 /**
211 * Releases any data retained by encapsulations.
212 */
213 void clear();
214
215 /// \cond INTERNAL
216 //
217 // Must return Instance*, because we don't hold an InstancePtr for
218 // optimization reasons (see comments below).
219 //
instance()220 IceInternal::Instance* instance() const { return _instance; } // Inlined for performance reasons.
221 /// \endcond
222
223 /**
224 * Sets the value factory manager to use when unmarshaling value instances. If the stream
225 * was initialized with a communicator, the communicator's value factory manager will
226 * be used by default.
227 *
228 * @param vfm The value factory manager.
229 */
230 void setValueFactoryManager(const ValueFactoryManagerPtr& vfm);
231
232 /**
233 * Sets the logger to use when logging trace messages. If the stream
234 * was initialized with a communicator, the communicator's logger will
235 * be used by default.
236 *
237 * @param logger The logger to use for logging trace messages.
238 */
239 void setLogger(const LoggerPtr& logger);
240
241 /**
242 * Sets the compact ID resolver to use when unmarshaling value and exception
243 * instances. If the stream was initialized with a communicator, the communicator's
244 * resolver will be used by default.
245 *
246 * @param r The compact ID resolver.
247 */
248 #ifdef ICE_CPP11_MAPPING
249 void setCompactIdResolver(std::function<std::string(int)> r);
250 #else
251 void setCompactIdResolver(const CompactIdResolverPtr& r);
252 #endif
253
254 #ifndef ICE_CPP11_MAPPING
255 /**
256 * Indicates whether to mark instances of Slice classes as collectable. If the stream is
257 * initialized with a communicator, this setting defaults to the value of the
258 * Ice.CollectObjects property, otherwise the setting defaults to false.
259 * @param b True to mark instances as collectable, false otherwise.
260 */
261 void setCollectObjects(bool b);
262 #endif
263
264 /**
265 * Indicates whether to slice instances of Slice classes to a known Slice type when a more
266 * derived type is unknown. An instance is "sliced" when no static information is available
267 * for a Slice type ID and no factory can be found for that type, resulting in the creation
268 * of an instance of a less-derived type. If slicing is disabled in this situation, the
269 * stream raises the exception NoValueFactoryException. The default behavior is to allow slicing.
270 * @param b True to enable slicing, false otherwise.
271 */
272 void setSliceValues(bool b);
273
274 /**
275 * Indicates whether to log messages when instances of Slice classes are sliced. If the stream
276 * is initialized with a communicator, this setting defaults to the value of the Ice.Trace.Slicing
277 * property, otherwise the setting defaults to false.
278 * @param b True to enable logging, false otherwise.
279 */
280 void setTraceSlicing(bool b);
281
282 /**
283 * Sets an upper limit on the depth of a class graph. If this limit is exceeded during
284 * unmarshaling, the stream raises MarshalException.
285 * @param n The maximum depth.
286 */
287 void setClassGraphDepthMax(size_t n);
288
289 /**
290 * Obtains the closure data associated with this stream.
291 * @return The data as a void pointer.
292 */
293 void* getClosure() const;
294
295 /**
296 * Associates closure data with this stream.
297 * @param p The data as a void pointer.
298 * @return The previous closure data, or nil.
299 */
300 void* setClosure(void* p);
301
302 /**
303 * Swaps the contents of one stream with another.
304 *
305 * @param other The other stream.
306 */
307 void swap(InputStream& other);
308
309 /// \cond INTERNAL
310 void resetEncapsulation();
311 /// \endcond
312
313 /**
314 * Resizes the stream to a new size.
315 *
316 * @param sz The new size.
317 */
resize(Container::size_type sz)318 void resize(Container::size_type sz)
319 {
320 b.resize(sz);
321 i = b.end();
322 }
323
324 /**
325 * Marks the start of a class instance.
326 */
startValue()327 void startValue()
328 {
329 assert(_currentEncaps && _currentEncaps->decoder);
330 _currentEncaps->decoder->startInstance(ValueSlice);
331 }
332
333 /**
334 * Marks the end of a class instance.
335 *
336 * @param preserve Pass true and the stream will preserve the unknown slices of the instance, or false
337 * to discard the unknown slices.
338 * @return An object that encapsulates the unknown slice data.
339 */
endValue(bool preserve)340 SlicedDataPtr endValue(bool preserve)
341 {
342 assert(_currentEncaps && _currentEncaps->decoder);
343 return _currentEncaps->decoder->endInstance(preserve);
344 }
345
346 /**
347 * Marks the start of a user exception.
348 */
startException()349 void startException()
350 {
351 assert(_currentEncaps && _currentEncaps->decoder);
352 _currentEncaps->decoder->startInstance(ExceptionSlice);
353 }
354
355 /**
356 * Marks the end of a user exception.
357 *
358 * @param preserve Pass true and the stream will preserve the unknown slices of the exception, or false
359 * to discard the unknown slices.
360 * @return An object that encapsulates the unknown slice data.
361 */
endException(bool preserve)362 SlicedDataPtr endException(bool preserve)
363 {
364 assert(_currentEncaps && _currentEncaps->decoder);
365 return _currentEncaps->decoder->endInstance(preserve);
366 }
367
368 /**
369 * Reads the start of an encapsulation.
370 *
371 * @return The encoding version used by the encapsulation.
372 */
startEncapsulation()373 const EncodingVersion& startEncapsulation()
374 {
375 Encaps* oldEncaps = _currentEncaps;
376 if(!oldEncaps) // First allocated encaps?
377 {
378 _currentEncaps = &_preAllocatedEncaps;
379 }
380 else
381 {
382 _currentEncaps = new Encaps();
383 _currentEncaps->previous = oldEncaps;
384 }
385 _currentEncaps->start = i - b.begin();
386
387 //
388 // I don't use readSize() and writeSize() for encapsulations,
389 // because when creating an encapsulation, I must know in advance
390 // how many bytes the size information will require in the data
391 // stream. If I use an Int, it is always 4 bytes. For
392 // readSize()/writeSize(), it could be 1 or 5 bytes.
393 //
394 Int sz;
395 read(sz);
396 if(sz < 6)
397 {
398 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
399 }
400 if(i - sizeof(Int) + sz > b.end())
401 {
402 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
403 }
404 _currentEncaps->sz = sz;
405
406 read(_currentEncaps->encoding);
407 IceInternal::checkSupportedEncoding(_currentEncaps->encoding); // Make sure the encoding is supported
408
409 return _currentEncaps->encoding;
410 }
411
412 /**
413 * Ends the current encapsulation.
414 */
endEncapsulation()415 void endEncapsulation()
416 {
417 assert(_currentEncaps);
418
419 if(_currentEncaps->encoding != Encoding_1_0)
420 {
421 skipOptionals();
422 if(i != b.begin() + _currentEncaps->start + _currentEncaps->sz)
423 {
424 throwEncapsulationException(__FILE__, __LINE__);
425 }
426 }
427 else if(i != b.begin() + _currentEncaps->start + _currentEncaps->sz)
428 {
429 if(i + 1 != b.begin() + _currentEncaps->start + _currentEncaps->sz)
430 {
431 throwEncapsulationException(__FILE__, __LINE__);
432 }
433
434 //
435 // Ice version < 3.3 had a bug where user exceptions with
436 // class members could be encoded with a trailing byte
437 // when dispatched with AMD. So we tolerate an extra byte
438 // in the encapsulation.
439 //
440 ++i;
441 }
442
443 Encaps* oldEncaps = _currentEncaps;
444 _currentEncaps = _currentEncaps->previous;
445 if(oldEncaps == &_preAllocatedEncaps)
446 {
447 oldEncaps->reset();
448 }
449 else
450 {
451 delete oldEncaps;
452 }
453 }
454
455 /**
456 * Skips an empty encapsulation.
457 *
458 * @return The encapsulation's encoding version.
459 */
skipEmptyEncapsulation()460 EncodingVersion skipEmptyEncapsulation()
461 {
462 Ice::Int sz;
463 read(sz);
464 if(sz < 6)
465 {
466 throwEncapsulationException(__FILE__, __LINE__);
467 }
468 if(i - sizeof(Ice::Int) + sz > b.end())
469 {
470 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
471 }
472 Ice::EncodingVersion encoding;
473 read(encoding);
474 IceInternal::checkSupportedEncoding(encoding); // Make sure the encoding is supported
475
476 if(encoding == Ice::Encoding_1_0)
477 {
478 if(sz != static_cast<Ice::Int>(sizeof(Ice::Int)) + 2)
479 {
480 throwEncapsulationException(__FILE__, __LINE__);
481 }
482 }
483 else
484 {
485 // Skip the optional content of the encapsulation if we are expecting an
486 // empty encapsulation.
487 i += sz - sizeof(Ice::Int) - 2;
488 }
489 return encoding;
490 }
491
492 /**
493 * Returns a blob of bytes representing an encapsulation.
494 *
495 * @param v A pointer into the internal marshaling buffer representing the start of the encoded encapsulation.
496 * @param sz The number of bytes in the encapsulation.
497 * @return encoding The encapsulation's encoding version.
498 */
readEncapsulation(const Byte * & v,Int & sz)499 EncodingVersion readEncapsulation(const Byte*& v, Int& sz)
500 {
501 EncodingVersion encoding;
502 v = i;
503 read(sz);
504 if(sz < 6)
505 {
506 throwEncapsulationException(__FILE__, __LINE__);
507 }
508 if(i - sizeof(Int) + sz > b.end())
509 {
510 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
511 }
512
513 read(encoding);
514 i += sz - sizeof(Int) - 2;
515 return encoding;
516 }
517
518 /**
519 * Determines the current encoding version.
520 *
521 * @return The encoding version.
522 */
getEncoding()523 const EncodingVersion& getEncoding() const
524 {
525 return _currentEncaps ? _currentEncaps->encoding : _encoding;
526 }
527
528 /**
529 * Determines the size of the current encapsulation, excluding the encapsulation header.
530 *
531 * @return The size of the encapsulated data.
532 */
533 Int getEncapsulationSize();
534
535 /**
536 * Skips over an encapsulation.
537 *
538 * @return The encoding version of the skipped encapsulation.
539 */
540 EncodingVersion skipEncapsulation();
541
542 /**
543 * Reads the start of a value or exception slice.
544 *
545 * @return The Slice type ID for this slice.
546 */
startSlice()547 std::string startSlice()
548 {
549 assert(_currentEncaps && _currentEncaps->decoder);
550 return _currentEncaps->decoder->startSlice();
551 }
552
553 /**
554 * Indicates that the end of a value or exception slice has been reached.
555 */
endSlice()556 void endSlice()
557 {
558 assert(_currentEncaps && _currentEncaps->decoder);
559 _currentEncaps->decoder->endSlice();
560 }
561
562 /**
563 * Skips over a value or exception slice.
564 */
skipSlice()565 void skipSlice()
566 {
567 assert(_currentEncaps && _currentEncaps->decoder);
568 _currentEncaps->decoder->skipSlice();
569 }
570
571 /**
572 * Indicates that unmarshaling is complete, except for any class instances. The application must call this method
573 * only if the stream actually contains class instances. Calling readPendingValues triggers the
574 * patch callbacks to inform the application that unmarshaling of an instance is complete.
575 */
576 void readPendingValues();
577
578 /**
579 * Extracts a size from the stream.
580 *
581 * @return The extracted size.
582 */
readSize()583 Int readSize() // Inlined for performance reasons.
584 {
585 Byte byte;
586 read(byte);
587 unsigned char val = static_cast<unsigned char>(byte);
588 if(val == 255)
589 {
590 Int v;
591 read(v);
592 if(v < 0)
593 {
594 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
595 }
596 return v;
597 }
598 else
599 {
600 return static_cast<Int>(static_cast<unsigned char>(byte));
601 }
602 }
603
604 /**
605 * Reads and validates a sequence size.
606 *
607 * @param minSize The minimum size required by the sequence type.
608 * @return The extracted size.
609 */
610 Int readAndCheckSeqSize(int minSize);
611
612 /**
613 * Reads a blob of bytes from the stream.
614 *
615 * @param bytes The vector to hold a copy of the bytes from the marshaling buffer.
616 * @param sz The number of bytes to read.
617 */
618 void readBlob(std::vector<Byte>& bytes, Int sz);
619
620 /**
621 * Reads a blob of bytes from the stream.
622 *
623 * @param v A pointer into the internal marshaling buffer representing the start of the blob.
624 * @param sz The number of bytes to read.
625 */
readBlob(const Byte * & v,Container::size_type sz)626 void readBlob(const Byte*& v, Container::size_type sz)
627 {
628 if(sz > 0)
629 {
630 v = i;
631 if(static_cast<Container::size_type>(b.end() - i) < sz)
632 {
633 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
634 }
635 i += sz;
636 }
637 else
638 {
639 v = i;
640 }
641 }
642
643 /**
644 * Reads a data value from the stream.
645 * @param v Holds the extracted data.
646 */
read(T & v)647 template<typename T> void read(T& v)
648 {
649 StreamHelper<T, StreamableTraits<T>::helper>::read(this, v);
650 }
651
652 /**
653 * Reads an optional data value from the stream.
654 * @param tag The tag ID.
655 * @param v Holds the extracted data (if any).
656 */
read(Int tag,IceUtil::Optional<T> & v)657 template<typename T> void read(Int tag, IceUtil::Optional<T>& v)
658 {
659 if(readOptional(tag, StreamOptionalHelper<T,
660 StreamableTraits<T>::helper,
661 StreamableTraits<T>::fixedLength>::optionalFormat))
662 {
663 #ifdef ICE_CPP11_MAPPING
664 v.emplace();
665 #else
666 v.__setIsSet();
667 #endif
668 StreamOptionalHelper<T,
669 StreamableTraits<T>::helper,
670 StreamableTraits<T>::fixedLength>::read(this, *v);
671 }
672 else
673 {
674 v = IceUtil::None;
675 }
676 }
677
678 #ifdef ICE_CPP11_MAPPING
679
680 /**
681 * Extracts a sequence of data values from the stream.
682 * @param v A pair of pointers representing the beginning and end of the sequence elements.
683 */
read(std::pair<const T *,const T * > & v)684 template<typename T> void read(std::pair<const T*, const T*>& v)
685 {
686 auto holder = new std::vector<T>;
687 _deleters.push_back([holder] { delete holder; });
688 read(*holder);
689 if(holder->size() > 0)
690 {
691 v.first = holder->data();
692 v.second = holder->data() + holder->size();
693 }
694 else
695 {
696 v.first = 0;
697 v.second = 0;
698 }
699 }
700
701 /**
702 * Reads a list of mandatory data values.
703 */
readAll(T & v)704 template<typename T> void readAll(T& v)
705 {
706 read(v);
707 }
708
709 /**
710 * Reads a list of mandatory data values.
711 */
readAll(T & v,Te &...ve)712 template<typename T, typename... Te> void readAll(T& v, Te&... ve)
713 {
714 read(v);
715 readAll(ve...);
716 }
717
718 /**
719 * Reads a list of optional data values.
720 */
721 template<typename T>
readAll(std::initializer_list<int> tags,IceUtil::Optional<T> & v)722 void readAll(std::initializer_list<int> tags, IceUtil::Optional<T>& v)
723 {
724 read(*(tags.begin() + tags.size() - 1), v);
725 }
726
727 /**
728 * Reads a list of optional data values.
729 */
730 template<typename T, typename... Te>
readAll(std::initializer_list<int> tags,IceUtil::Optional<T> & v,IceUtil::Optional<Te> &...ve)731 void readAll(std::initializer_list<int> tags, IceUtil::Optional<T>& v, IceUtil::Optional<Te>&... ve)
732 {
733 size_t index = tags.size() - sizeof...(ve) - 1;
734 read(*(tags.begin() + index), v);
735 readAll(tags, ve...);
736 }
737
738 #endif
739
740 /**
741 * Determine if an optional value is available for reading.
742 *
743 * @param tag The tag associated with the value.
744 * @param expectedFormat The optional format for the value.
745 * @return True if the value is present, false otherwise.
746 */
readOptional(Int tag,OptionalFormat expectedFormat)747 bool readOptional(Int tag, OptionalFormat expectedFormat)
748 {
749 assert(_currentEncaps);
750 if(_currentEncaps->decoder)
751 {
752 return _currentEncaps->decoder->readOptional(tag, expectedFormat);
753 }
754 else
755 {
756 return readOptImpl(tag, expectedFormat);
757 }
758 }
759
760 /**
761 * Reads a byte from the stream.
762 * @param v The extracted byte.
763 */
read(Byte & v)764 void read(Byte& v)
765 {
766 if(i >= b.end())
767 {
768 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
769 }
770 v = *i++;
771 }
772
773 /**
774 * Reads a sequence of bytes from the stream.
775 * @param v A vector to hold a copy of the bytes.
776 */
777 void read(std::vector<Byte>& v);
778
779 /**
780 * Reads a sequence of bytes from the stream.
781 * @param v A pair of pointers into the internal marshaling buffer representing the start and end of the
782 * sequence elements.
783 */
784 void read(std::pair<const Byte*, const Byte*>& v);
785
786 #ifndef ICE_CPP11_MAPPING
787 /**
788 * Reads a sequence of bytes from the stream.
789 * @param v A pair of pointers into the internal marshaling buffer representing the start and end of the
790 * sequence elements.
791 * @param arr A scoped array.
792 */
read(std::pair<const Byte *,const Byte * > & v,::IceUtil::ScopedArray<Byte> & arr)793 void read(std::pair<const Byte*, const Byte*>& v, ::IceUtil::ScopedArray<Byte>& arr)
794 {
795 arr.reset();
796 read(v);
797 }
798 #endif
799
800 /**
801 * Reads a bool from the stream.
802 * @param v The extracted bool.
803 */
read(bool & v)804 void read(bool& v)
805 {
806 if(i >= b.end())
807 {
808 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
809 }
810 v = (0 != *i++);
811 }
812
813 /**
814 * Reads a sequence of boolean values from the stream.
815 * @param v A vector to hold a copy of the boolean values.
816 */
817 void read(std::vector<bool>& v);
818
819 #ifdef ICE_CPP11_MAPPING
820 /**
821 * Reads a sequence of boolean values from the stream.
822 * @param v A pair of pointers into the internal marshaling buffer representing the start and end of the
823 * sequence elements.
824 */
825 void read(std::pair<const bool*, const bool*>& v);
826 #else
827 /**
828 * Reads a sequence of boolean values from the stream.
829 * @param v A pair of pointers into the internal marshaling buffer representing the start and end of the
830 * sequence elements.
831 * @param arr A scoped array.
832 */
833 void read(std::pair<const bool*, const bool*>& v, ::IceUtil::ScopedArray<bool>& arr);
834 #endif
835
836 /**
837 * Reads a short from the stream.
838 * @param v The extracted short.
839 */
840 void read(Short& v);
841
842 /**
843 * Reads a sequence of shorts from the stream.
844 * @param v A vector to hold a copy of the short values.
845 */
846 void read(std::vector<Short>& v);
847
848 #ifdef ICE_CPP11_MAPPING
849 /**
850 * Reads a sequence of boolean values from the stream.
851 * @param v A pair of pointers representing the start and end of the sequence elements.
852 */
853 void read(std::pair<const short*, const short*>& v);
854 #else
855 /**
856 * Reads a sequence of shorts from the stream.
857 * @param v A pair of pointers representing the start and end of the sequence elements.
858 * @param arr A scoped array.
859 */
860 void read(std::pair<const Short*, const Short*>& v, ::IceUtil::ScopedArray<Short>& arr);
861 #endif
862
863 /**
864 * Reads an int from the stream.
865 * @param v The extracted int.
866 */
read(Int & v)867 void read(Int& v) // Inlined for performance reasons.
868 {
869 if(b.end() - i < static_cast<int>(sizeof(Int)))
870 {
871 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
872 }
873 const Byte* src = &(*i);
874 i += sizeof(Int);
875 #ifdef ICE_BIG_ENDIAN
876 Byte* dest = reinterpret_cast<Byte*>(&v) + sizeof(Int) - 1;
877 *dest-- = *src++;
878 *dest-- = *src++;
879 *dest-- = *src++;
880 *dest = *src;
881 #else
882 Byte* dest = reinterpret_cast<Byte*>(&v);
883 *dest++ = *src++;
884 *dest++ = *src++;
885 *dest++ = *src++;
886 *dest = *src;
887 #endif
888 }
889
890 /**
891 * Reads a sequence of ints from the stream.
892 * @param v A vector to hold a copy of the int values.
893 */
894 void read(std::vector<Int>& v);
895
896 #ifdef ICE_CPP11_MAPPING
897 /**
898 * Reads a sequence of ints from the stream.
899 * @param v A pair of pointers representing the start and end of the sequence elements.
900 */
901 void read(std::pair<const int*, const int*>& v);
902 #else
903 /**
904 * Reads a sequence of ints from the stream.
905 * @param v A pair of pointers representing the start and end of the sequence elements.
906 * @param arr A scoped array.
907 */
908 void read(std::pair<const Int*, const Int*>& v, ::IceUtil::ScopedArray<Int>& arr);
909 #endif
910
911 /**
912 * Reads a long from the stream.
913 * @param v The extracted long.
914 */
915 void read(Long& v);
916
917 /**
918 * Reads a sequence of longs from the stream.
919 * @param v A vector to hold a copy of the long values.
920 */
921 void read(std::vector<Long>& v);
922
923 #ifdef ICE_CPP11_MAPPING
924 /**
925 * Reads a sequence of longs from the stream.
926 * @param v A pair of pointers representing the start and end of the sequence elements.
927 */
928 void read(std::pair<const long long*, const long long*>& v);
929 #else
930 /**
931 * Reads a sequence of longs from the stream.
932 * @param v A pair of pointers representing the start and end of the sequence elements.
933 * @param arr A scoped array.
934 */
935 void read(std::pair<const Long*, const Long*>& v, ::IceUtil::ScopedArray<Long>& arr);
936 #endif
937
938 /**
939 * Reads a float from the stream.
940 * @param v The extracted float.
941 */
942 void read(Float& v);
943
944 /**
945 * Reads a sequence of floats from the stream.
946 * @param v A vector to hold a copy of the float values.
947 */
948 void read(std::vector<Float>& v);
949
950 #ifdef ICE_CPP11_MAPPING
951 /**
952 * Reads a sequence of floats from the stream.
953 * @param v A pair of pointers representing the start and end of the sequence elements.
954 */
955 void read(std::pair<const float*, const float*>& v);
956 #else
957 /**
958 * Reads a sequence of floats from the stream.
959 * @param v A pair of pointers representing the start and end of the sequence elements.
960 * @param arr A scoped array.
961 */
962 void read(std::pair<const Float*, const Float*>& v, ::IceUtil::ScopedArray<Float>& arr);
963 #endif
964
965 /**
966 * Reads a double from the stream.
967 * @param v The extracted double.
968 */
969 void read(Double& v);
970
971 /**
972 * Reads a sequence of doubles from the stream.
973 * @param v A vector to hold a copy of the double values.
974 */
975 void read(std::vector<Double>& v);
976
977 #ifdef ICE_CPP11_MAPPING
978 /**
979 * Reads a sequence of doubles from the stream.
980 * @param v A pair of pointers representing the start and end of the sequence elements.
981 */
982 void read(std::pair<const double*, const double*>& v);
983 #else
984 /**
985 * Reads a sequence of doubles from the stream.
986 * @param v A pair of pointers representing the start and end of the sequence elements.
987 * @param arr A scoped array.
988 */
989 void read(std::pair<const Double*, const Double*>& v, ::IceUtil::ScopedArray<Double>& arr);
990 #endif
991
992 /**
993 * Reads a string from the stream.
994 * @param v The extracted string.
995 * @param convert Determines whether the string is processed by the string converter, if one
996 * is installed. The default behavior is to convert strings.
997 */
998 void read(std::string& v, bool convert = true);
999
1000 #ifdef ICE_CPP11_MAPPING
1001 /**
1002 * Reads a string from the stream.
1003 * @param vdata A pointer to the beginning of the string.
1004 * @param vsize The number of bytes in the string.
1005 * @param convert Determines whether the string is processed by the string converter, if one
1006 * is installed. The default behavior is to convert strings.
1007 */
1008 void read(const char*& vdata, size_t& vsize, bool convert = true);
1009 #else
1010 // For custom strings, convert = false
1011 /**
1012 * Reads a string from the stream. String conversion is disabled.
1013 * @param vdata A pointer to the beginning of the string.
1014 * @param vsize The number of bytes in the string.
1015 */
1016 void read(const char*& vdata, size_t& vsize);
1017
1018 // For custom strings, convert = true
1019 /**
1020 * Reads a string from the stream. String conversion is enabled.
1021 * @param vdata A pointer to the beginning of the string.
1022 * @param vsize The number of bytes in the string.
1023 * @param holder Holds the string contents.
1024 */
1025 void read(const char*& vdata, size_t& vsize, std::string& holder);
1026 #endif
1027
1028 /**
1029 * Reads a sequence of strings from the stream.
1030 * @param v The extracted string sequence.
1031 * @param convert Determines whether strings are processed by the string converter, if one
1032 * is installed. The default behavior is to convert the strings.
1033 */
1034 void read(std::vector<std::string>& v, bool convert = true);
1035
1036 /**
1037 * Reads a wide string from the stream.
1038 * @param v The extracted string.
1039 */
1040 void read(std::wstring& v);
1041
1042 /**
1043 * Reads a sequence of wide strings from the stream.
1044 * @param v The extracted sequence.
1045 */
1046 void read(std::vector<std::wstring>& v);
1047
1048 #ifdef ICE_CPP11_MAPPING
1049 /**
1050 * Reads a proxy from the stream.
1051 * @return The proxy as the base ObjectPrx type.
1052 */
1053 std::shared_ptr<ObjectPrx> readProxy();
1054
1055 /**
1056 * Reads a typed proxy from the stream.
1057 * @param v The proxy as a user-defined type.
1058 */
1059 template<typename T, typename ::std::enable_if<::std::is_base_of<ObjectPrx, T>::value>::type* = nullptr>
read(::std::shared_ptr<T> & v)1060 void read(::std::shared_ptr<T>& v)
1061 {
1062 ::std::shared_ptr<ObjectPrx> proxy(readProxy());
1063 if(!proxy)
1064 {
1065 v = 0;
1066 }
1067 else
1068 {
1069 v = ::IceInternal::createProxy<T>();
1070 v->_copyFrom(proxy);
1071 }
1072 }
1073 #else
1074 /**
1075 * Reads a proxy from the stream.
1076 * @param v The proxy as the base ObjectPrx type.
1077 */
1078 void read(ObjectPrx& v);
1079
1080 /**
1081 * Reads a typed proxy from the stream.
1082 * @param v The proxy as a user-defined type.
1083 */
read(IceInternal::ProxyHandle<T> & v)1084 template<typename T> void read(IceInternal::ProxyHandle<T>& v)
1085 {
1086 _readProxy(this, v); // Generated _readProxy method, necessary for forward declarations.
1087 }
1088 #endif
1089
1090 /**
1091 * Reads a value (instance of a Slice class) from the stream.
1092 * @param v The instance.
1093 */
1094 #ifdef ICE_CPP11_MAPPING // C++11 mapping
1095 template<typename T, typename ::std::enable_if<::std::is_base_of<Value, T>::value>::type* = nullptr>
read(::std::shared_ptr<T> & v)1096 void read(::std::shared_ptr<T>& v)
1097 {
1098 read(&patchHandle<T>, &v);
1099 }
1100 #else // C++98 mapping
read(IceInternal::Handle<T> & v)1101 template<typename T> void read(IceInternal::Handle<T>& v)
1102 {
1103 read(&patchHandle<T>, &v);
1104 }
1105 #endif
1106
1107 /**
1108 * Reads a value (instance of a Slice class) from the stream.
1109 * @param patchFunc The patch callback function.
1110 * @param patchAddr Closure data passed to the callback.
1111 */
read(PatchFunc patchFunc,void * patchAddr)1112 void read(PatchFunc patchFunc, void* patchAddr)
1113 {
1114 initEncaps();
1115 _currentEncaps->decoder->read(patchFunc, patchAddr);
1116 }
1117
1118 /**
1119 * Reads an enumerator from the stream.
1120 * @param maxValue The maximum enumerator value in the definition.
1121 * @return The enumerator value.
1122 */
1123 Int readEnum(Int maxValue);
1124
1125 /**
1126 * Extracts a user exception from the stream and throws it.
1127 * @param factory If provided, this factory is given the first opportunity to instantiate
1128 * the exception. If not provided, or if the factory does not throw an exception when invoked,
1129 * the stream will attempt to instantiate the exception using static type information.
1130 * @throws UserException The user exception that was unmarshaled.
1131 */
1132 void throwException(ICE_IN(ICE_DELEGATE(UserExceptionFactory)) factory = ICE_NULLPTR);
1133
1134 /**
1135 * Skips one optional value with the given format.
1136 * @param format The expected format of the optional, if present.
1137 */
1138 void skipOptional(OptionalFormat format);
1139
1140 /**
1141 * Skips all remaining optional values.
1142 */
1143 void skipOptionals();
1144
1145 /**
1146 * Advances the current stream position by the given number of bytes.
1147 * @param size The number of bytes to skip.
1148 */
skip(size_type size)1149 void skip(size_type size)
1150 {
1151 if(i + size > b.end())
1152 {
1153 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
1154 }
1155 i += size;
1156 }
1157
1158 /**
1159 * Reads a size at the current position and skips that number of bytes.
1160 */
skipSize()1161 void skipSize()
1162 {
1163 Byte bt;
1164 read(bt);
1165 if(static_cast<unsigned char>(bt) == 255)
1166 {
1167 skip(4);
1168 }
1169 }
1170
1171 /**
1172 * Obtains the current position of the stream.
1173 * @return The current position.
1174 */
pos()1175 size_type pos()
1176 {
1177 return i - b.begin();
1178 }
1179
1180 /**
1181 * Sets a new position for the stream.
1182 * @param p The new position.
1183 */
pos(size_type p)1184 void pos(size_type p)
1185 {
1186 i = b.begin() + p;
1187 }
1188
1189 /// \cond INTERNAL
1190 InputStream(IceInternal::Instance*, const EncodingVersion&);
1191 InputStream(IceInternal::Instance*, const EncodingVersion&, IceInternal::Buffer&, bool = false);
1192
1193 void initialize(IceInternal::Instance*, const EncodingVersion&);
1194
1195 bool readOptImpl(Int, OptionalFormat);
1196 /// \endcond
1197
1198 private:
1199
1200 void initialize(const EncodingVersion&);
1201
1202 //
1203 // String
1204 //
1205 bool readConverted(std::string&, Int);
1206
1207 //
1208 // We can't throw these exception from inline functions from within
1209 // this file, because we cannot include the header with the
1210 // exceptions. Doing so would screw up the whole include file
1211 // ordering.
1212 //
1213 void throwUnmarshalOutOfBoundsException(const char*, int);
1214 void throwEncapsulationException(const char*, int);
1215
1216 std::string resolveCompactId(int) const;
1217
1218 void postUnmarshal(const ValuePtr&) const;
1219
1220 class Encaps;
1221 enum SliceType { NoSlice, ValueSlice, ExceptionSlice };
1222
1223 void traceSkipSlice(const std::string&, SliceType) const;
1224
1225 ValueFactoryManagerPtr valueFactoryManager() const;
1226
1227 LoggerPtr logger() const;
1228
1229 #ifdef ICE_CPP11_MAPPING
1230 std::function<std::string(int)> compactIdResolver() const;
1231 #else
1232 CompactIdResolverPtr compactIdResolver() const;
1233 #endif
1234
1235 typedef std::vector<ValuePtr> ValueList;
1236
1237 class ICE_API EncapsDecoder : private ::IceUtil::noncopyable
1238 {
1239 public:
1240
1241 virtual ~EncapsDecoder();
1242
1243 virtual void read(PatchFunc, void*) = 0;
1244 virtual void throwException(ICE_IN(ICE_DELEGATE(UserExceptionFactory))) = 0;
1245
1246 virtual void startInstance(SliceType) = 0;
1247 virtual SlicedDataPtr endInstance(bool) = 0;
1248 virtual const std::string& startSlice() = 0;
1249 virtual void endSlice() = 0;
1250 virtual void skipSlice() = 0;
1251
readOptional(Int,OptionalFormat)1252 virtual bool readOptional(Int, OptionalFormat)
1253 {
1254 return false;
1255 }
1256
readPendingValues()1257 virtual void readPendingValues()
1258 {
1259 }
1260
1261 protected:
1262
EncapsDecoder(InputStream * stream,Encaps * encaps,bool sliceValues,size_t classGraphDepthMax,const Ice::ValueFactoryManagerPtr & f)1263 EncapsDecoder(InputStream* stream, Encaps* encaps, bool sliceValues, size_t classGraphDepthMax,
1264 const Ice::ValueFactoryManagerPtr& f) :
1265 _stream(stream), _encaps(encaps), _sliceValues(sliceValues), _classGraphDepthMax(classGraphDepthMax),
1266 _classGraphDepth(0), _valueFactoryManager(f), _typeIdIndex(0)
1267 {
1268 }
1269
1270 std::string readTypeId(bool);
1271 ValuePtr newInstance(const std::string&);
1272
1273 void addPatchEntry(Int, PatchFunc, void*);
1274 void unmarshal(Int, const ValuePtr&);
1275
1276 typedef std::map<Int, ValuePtr> IndexToPtrMap;
1277 typedef std::map<Int, std::string> TypeIdMap;
1278
1279 struct PatchEntry
1280 {
1281 PatchFunc patchFunc;
1282 void* patchAddr;
1283 size_t classGraphDepth;
1284 };
1285 typedef std::vector<PatchEntry> PatchList;
1286 typedef std::map<Int, PatchList> PatchMap;
1287
1288 InputStream* _stream;
1289 Encaps* _encaps;
1290 const bool _sliceValues;
1291 const size_t _classGraphDepthMax;
1292 size_t _classGraphDepth;
1293 Ice::ValueFactoryManagerPtr _valueFactoryManager;
1294
1295 // Encapsulation attributes for object un-marshalling
1296 PatchMap _patchMap;
1297
1298 private:
1299
1300 // Encapsulation attributes for object un-marshalling
1301 IndexToPtrMap _unmarshaledMap;
1302 TypeIdMap _typeIdMap;
1303 Int _typeIdIndex;
1304 ValueList _valueList;
1305 };
1306
1307 class ICE_API EncapsDecoder10 : public EncapsDecoder
1308 {
1309 public:
1310
EncapsDecoder10(InputStream * stream,Encaps * encaps,bool sliceValues,size_t classGraphDepthMax,const Ice::ValueFactoryManagerPtr & f)1311 EncapsDecoder10(InputStream* stream, Encaps* encaps, bool sliceValues, size_t classGraphDepthMax,
1312 const Ice::ValueFactoryManagerPtr& f) :
1313 EncapsDecoder(stream, encaps, sliceValues, classGraphDepthMax, f),
1314 _sliceType(NoSlice)
1315 {
1316 }
1317
1318 virtual void read(PatchFunc, void*);
1319 virtual void throwException(ICE_IN(ICE_DELEGATE(UserExceptionFactory)));
1320
1321 virtual void startInstance(SliceType);
1322 virtual SlicedDataPtr endInstance(bool);
1323 virtual const std::string& startSlice();
1324 virtual void endSlice();
1325 virtual void skipSlice();
1326
1327 virtual void readPendingValues();
1328
1329 private:
1330
1331 void readInstance();
1332
1333 // Instance attributes
1334 SliceType _sliceType;
1335 bool _skipFirstSlice;
1336
1337 // Slice attributes
1338 Int _sliceSize;
1339 std::string _typeId;
1340 };
1341
1342 class ICE_API EncapsDecoder11 : public EncapsDecoder
1343 {
1344 public:
1345
EncapsDecoder11(InputStream * stream,Encaps * encaps,bool sliceValues,size_t classGraphDepthMax,const Ice::ValueFactoryManagerPtr & f)1346 EncapsDecoder11(InputStream* stream, Encaps* encaps, bool sliceValues, size_t classGraphDepthMax,
1347 const Ice::ValueFactoryManagerPtr& f) :
1348 EncapsDecoder(stream, encaps, sliceValues, classGraphDepthMax, f),
1349 _preAllocatedInstanceData(0), _current(0), _valueIdIndex(1)
1350 {
1351 }
1352
1353 virtual void read(PatchFunc, void*);
1354 virtual void throwException(ICE_IN(ICE_DELEGATE(UserExceptionFactory)));
1355
1356 virtual void startInstance(SliceType);
1357 virtual SlicedDataPtr endInstance(bool);
1358 virtual const std::string& startSlice();
1359 virtual void endSlice();
1360 virtual void skipSlice();
1361
1362 virtual bool readOptional(Int, OptionalFormat);
1363
1364 private:
1365
1366 Int readInstance(Int, PatchFunc, void*);
1367 SlicedDataPtr readSlicedData();
1368
1369 struct IndirectPatchEntry
1370 {
1371 Int index;
1372 PatchFunc patchFunc;
1373 void* patchAddr;
1374 };
1375 typedef std::vector<IndirectPatchEntry> IndirectPatchList;
1376
1377 typedef std::vector<Int> IndexList;
1378 typedef std::vector<IndexList> IndexListList;
1379
1380 struct InstanceData
1381 {
InstanceDataInstanceData1382 InstanceData(InstanceData* p) : previous(p), next(0)
1383 {
1384 if(previous)
1385 {
1386 previous->next = this;
1387 }
1388 }
1389
~InstanceDataInstanceData1390 ~InstanceData()
1391 {
1392 if(next)
1393 {
1394 delete next;
1395 }
1396 }
1397
1398 // Instance attributes
1399 SliceType sliceType;
1400 bool skipFirstSlice;
1401 SliceInfoSeq slices; // Preserved slices.
1402 IndexListList indirectionTables;
1403
1404 // Slice attributes
1405 Byte sliceFlags;
1406 Int sliceSize;
1407 std::string typeId;
1408 int compactId;
1409 IndirectPatchList indirectPatchList;
1410
1411 InstanceData* previous;
1412 InstanceData* next;
1413 };
1414 InstanceData _preAllocatedInstanceData;
1415 InstanceData* _current;
1416
push(SliceType sliceType)1417 void push(SliceType sliceType)
1418 {
1419 if(!_current)
1420 {
1421 _current = &_preAllocatedInstanceData;
1422 }
1423 else
1424 {
1425 _current = _current->next ? _current->next : new InstanceData(_current);
1426 }
1427 _current->sliceType = sliceType;
1428 _current->skipFirstSlice = false;
1429 }
1430
1431 Int _valueIdIndex; // The ID of the next value to unmarshal.
1432 };
1433
1434 class Encaps : private ::IceUtil::noncopyable
1435 {
1436 public:
1437
Encaps()1438 Encaps() : start(0), decoder(0), previous(0)
1439 {
1440 // Inlined for performance reasons.
1441 }
~Encaps()1442 ~Encaps()
1443 {
1444 // Inlined for performance reasons.
1445 delete decoder;
1446 }
reset()1447 void reset()
1448 {
1449 // Inlined for performance reasons.
1450 delete decoder;
1451 decoder = 0;
1452
1453 previous = 0;
1454 }
1455
1456 Container::size_type start;
1457 Int sz;
1458 EncodingVersion encoding;
1459
1460 EncapsDecoder* decoder;
1461
1462 Encaps* previous;
1463 };
1464
1465 //
1466 // Optimization. The instance may not be deleted while a
1467 // stack-allocated stream still holds it.
1468 //
1469 IceInternal::Instance* _instance;
1470
1471 //
1472 // The encoding version to use when there's no encapsulation to
1473 // read from. This is for example used to read message headers.
1474 //
1475 EncodingVersion _encoding;
1476
1477 Encaps* _currentEncaps;
1478
1479 void initEncaps();
1480
1481 Encaps _preAllocatedEncaps;
1482
1483 #ifndef ICE_CPP11_MAPPING
1484 bool _collectObjects;
1485 #endif
1486
1487 bool _traceSlicing;
1488
1489 size_t _classGraphDepthMax;
1490
1491 void* _closure;
1492
1493 bool _sliceValues;
1494
1495 int _startSeq;
1496 int _minSeqSize;
1497
1498 ValueFactoryManagerPtr _valueFactoryManager;
1499 LoggerPtr _logger;
1500 #ifdef ICE_CPP11_MAPPING
1501 std::function<std::string(int)> _compactIdResolver;
1502 #else
1503 CompactIdResolverPtr _compactIdResolver;
1504 #endif
1505
1506 #ifdef ICE_CPP11_MAPPING
1507 std::vector<std::function<void()>> _deleters;
1508 #endif
1509
1510 };
1511
1512 } // End namespace Ice
1513
1514 #endif
1515