Ice 3.7 C++11 API Reference
InputStream.h
Go to the documentation of this file.
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>
19 #include <Ice/StreamHelpers.h>
20 #include <Ice/FactoryTable.h>
21 
22 namespace Ice
23 {
24 
25 class UserException;
26 
28 template<typename T> inline void
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 }
44 
49 class ICE_API InputStream : public IceInternal::Buffer
50 {
51 public:
52 
53  typedef size_t size_type;
54 
60  typedef void (*PatchFunc)(void* addr, const ValuePtr& v);
61 
69 
77  InputStream(const std::vector<Byte>& bytes);
78 
86  InputStream(const std::pair<const Byte*, const Byte*>& bytes);
87 
89  InputStream(IceInternal::Buffer&, bool = false);
91 
96  InputStream(const CommunicatorPtr& communicator);
97 
103  InputStream(const CommunicatorPtr& communicator, const std::vector<Byte>& bytes);
104 
110  InputStream(const CommunicatorPtr& communicator, const std::pair<const Byte*, const Byte*>& bytes);
111 
113  InputStream(const CommunicatorPtr& communicator, IceInternal::Buffer&, bool = false);
115 
123  InputStream(const EncodingVersion& version);
124 
133  InputStream(const EncodingVersion& version, const std::vector<Byte>& bytes);
134 
143  InputStream(const EncodingVersion& version, const std::pair<const Byte*, const Byte*>& bytes);
144 
146  InputStream(const EncodingVersion&, IceInternal::Buffer&, bool = false);
148 
154  InputStream(const CommunicatorPtr& communicator, const EncodingVersion& version);
155 
162  InputStream(const CommunicatorPtr& communicator, const EncodingVersion& version, const std::vector<Byte>& bytes);
163 
170  InputStream(const CommunicatorPtr& communicator, const EncodingVersion& version,
171  const std::pair<const Byte*, const Byte*>& bytes);
172 
174  InputStream(const CommunicatorPtr&, const EncodingVersion&, IceInternal::Buffer&, bool = false);
176 
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 
200  void initialize(const CommunicatorPtr& communicator);
201 
208  void initialize(const CommunicatorPtr& communicator, const EncodingVersion& version);
209 
213  void clear();
214 
216  //
217  // Must return Instance*, because we don't hold an InstancePtr for
218  // optimization reasons (see comments below).
219  //
220  IceInternal::Instance* instance() const { return _instance; } // Inlined for performance reasons.
222 
230  void setValueFactoryManager(const ValueFactoryManagerPtr& vfm);
231 
239  void setLogger(const LoggerPtr& logger);
240 
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 
261  void setCollectObjects(bool b);
262 #endif
263 
272  void setSliceValues(bool b);
273 
280  void setTraceSlicing(bool b);
281 
287  void setClassGraphDepthMax(size_t n);
288 
293  void* getClosure() const;
294 
300  void* setClosure(void* p);
301 
307  void swap(InputStream& other);
308 
310  void resetEncapsulation();
312 
318  void resize(Container::size_type sz)
319  {
320  b.resize(sz);
321  i = b.end();
322  }
323 
327  void startValue()
328  {
329  assert(_currentEncaps && _currentEncaps->decoder);
330  _currentEncaps->decoder->startInstance(ValueSlice);
331  }
332 
340  SlicedDataPtr endValue(bool preserve)
341  {
342  assert(_currentEncaps && _currentEncaps->decoder);
343  return _currentEncaps->decoder->endInstance(preserve);
344  }
345 
350  {
351  assert(_currentEncaps && _currentEncaps->decoder);
352  _currentEncaps->decoder->startInstance(ExceptionSlice);
353  }
354 
362  SlicedDataPtr endException(bool preserve)
363  {
364  assert(_currentEncaps && _currentEncaps->decoder);
365  return _currentEncaps->decoder->endInstance(preserve);
366  }
367 
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 = static_cast<size_t>(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 
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 
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 += static_cast<size_t>(sz) - sizeof(Ice::Int) - 2;
488  }
489  return encoding;
490  }
491 
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 += static_cast<size_t>(sz) - sizeof(Int) - 2;
515  return encoding;
516  }
517 
524  {
525  return _currentEncaps ? _currentEncaps->encoding : _encoding;
526  }
527 
534 
541 
547  std::string startSlice()
548  {
549  assert(_currentEncaps && _currentEncaps->decoder);
550  return _currentEncaps->decoder->startSlice();
551  }
552 
556  void endSlice()
557  {
558  assert(_currentEncaps && _currentEncaps->decoder);
559  _currentEncaps->decoder->endSlice();
560  }
561 
565  void skipSlice()
566  {
567  assert(_currentEncaps && _currentEncaps->decoder);
568  _currentEncaps->decoder->skipSlice();
569  }
570 
577 
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 
610  Int readAndCheckSeqSize(int minSize);
611 
618  void readBlob(std::vector<Byte>& bytes, Int sz);
619 
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 
647  template<typename T> void read(T& v)
648  {
649  StreamHelper<T, StreamableTraits<T>::helper>::read(this, v);
650  }
651 
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 
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 
704  template<typename T> void readAll(T& v)
705  {
706  read(v);
707  }
708 
712  template<typename T, typename... Te> void readAll(T& v, Te&... ve)
713  {
714  read(v);
715  readAll(ve...);
716  }
717 
721  template<typename T>
722  void readAll(std::initializer_list<int> tags, IceUtil::Optional<T>& v)
723  {
724  read(*(tags.begin() + tags.size() - 1), v);
725  }
726 
730  template<typename T, typename... Te>
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 
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 
764  void read(Byte& v)
765  {
766  if(i >= b.end())
767  {
768  throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
769  }
770  v = *i++;
771  }
772 
777  void read(std::vector<Byte>& v);
778 
784  void read(std::pair<const Byte*, const Byte*>& v);
785 
786 #ifndef ICE_CPP11_MAPPING
787 
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 
804  void read(bool& v)
805  {
806  if(i >= b.end())
807  {
808  throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
809  }
810  v = (0 != *i++);
811  }
812 
817  void read(std::vector<bool>& v);
818 
819 #ifdef ICE_CPP11_MAPPING
820 
825  void read(std::pair<const bool*, const bool*>& v);
826 #else
827 
833  void read(std::pair<const bool*, const bool*>& v, ::IceUtil::ScopedArray<bool>& arr);
834 #endif
835 
840  void read(Short& v);
841 
846  void read(std::vector<Short>& v);
847 
848 #ifdef ICE_CPP11_MAPPING
849 
853  void read(std::pair<const short*, const short*>& v);
854 #else
855 
860  void read(std::pair<const Short*, const Short*>& v, ::IceUtil::ScopedArray<Short>& arr);
861 #endif
862 
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 
894  void read(std::vector<Int>& v);
895 
896 #ifdef ICE_CPP11_MAPPING
897 
901  void read(std::pair<const int*, const int*>& v);
902 #else
903 
908  void read(std::pair<const Int*, const Int*>& v, ::IceUtil::ScopedArray<Int>& arr);
909 #endif
910 
915  void read(Long& v);
916 
921  void read(std::vector<Long>& v);
922 
923 #ifdef ICE_CPP11_MAPPING
924 
928  void read(std::pair<const long long*, const long long*>& v);
929 #else
930 
935  void read(std::pair<const Long*, const Long*>& v, ::IceUtil::ScopedArray<Long>& arr);
936 #endif
937 
942  void read(Float& v);
943 
948  void read(std::vector<Float>& v);
949 
950 #ifdef ICE_CPP11_MAPPING
951 
955  void read(std::pair<const float*, const float*>& v);
956 #else
957 
962  void read(std::pair<const Float*, const Float*>& v, ::IceUtil::ScopedArray<Float>& arr);
963 #endif
964 
969  void read(Double& v);
970 
975  void read(std::vector<Double>& v);
976 
977 #ifdef ICE_CPP11_MAPPING
978 
982  void read(std::pair<const double*, const double*>& v);
983 #else
984 
989  void read(std::pair<const Double*, const Double*>& v, ::IceUtil::ScopedArray<Double>& arr);
990 #endif
991 
998  void read(std::string& v, bool convert = true);
999 
1000 #ifdef ICE_CPP11_MAPPING
1001 
1008  void read(const char*& vdata, size_t& vsize, bool convert = true);
1009 #else
1010  // For custom strings, convert = false
1016  void read(const char*& vdata, size_t& vsize);
1017 
1018  // For custom strings, convert = true
1025  void read(const char*& vdata, size_t& vsize, std::string& holder);
1026 #endif
1027 
1034  void read(std::vector<std::string>& v, bool convert = true);
1035 
1040  void read(std::wstring& v);
1041 
1046  void read(std::vector<std::wstring>& v);
1047 
1048 #ifdef ICE_CPP11_MAPPING
1049 
1053  std::shared_ptr<ObjectPrx> readProxy();
1054 
1059  template<typename T, typename ::std::enable_if<::std::is_base_of<ObjectPrx, T>::value>::type* = nullptr>
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 
1078  void read(ObjectPrx& v);
1079 
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 
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>
1096  void read(::std::shared_ptr<T>& v)
1097  {
1098  read(&patchHandle<T>, &v);
1099  }
1100 #else // C++98 mapping
1101  template<typename T> void read(IceInternal::Handle<T>& v)
1102  {
1103  read(&patchHandle<T>, &v);
1104  }
1105 #endif
1106 
1112  void read(PatchFunc patchFunc, void* patchAddr)
1113  {
1114  initEncaps();
1115  _currentEncaps->decoder->read(patchFunc, patchAddr);
1116  }
1117 
1123  Int readEnum(Int maxValue);
1124 
1133 
1138  void skipOptional(OptionalFormat format);
1139 
1144 
1149  void skip(size_type size)
1150  {
1151  if(i + size > b.end())
1152  {
1153  throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
1154  }
1155  i += size;
1156  }
1157 
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 
1176  {
1177  return static_cast<size_t>(i - b.begin());
1178  }
1179 
1184  void pos(size_type p)
1185  {
1186  i = b.begin() + p;
1187  }
1188 
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);
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 
1252  virtual bool readOptional(Int, OptionalFormat)
1253  {
1254  return false;
1255  }
1256 
1257  virtual void readPendingValues()
1258  {
1259  }
1260 
1261  protected:
1262 
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;
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 
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 
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  {
1382  InstanceData(InstanceData* p) : previous(p), next(0)
1383  {
1384  if(previous)
1385  {
1386  previous->next = this;
1387  }
1388  }
1389 
1390  ~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 
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 
1438  Encaps() : start(0), decoder(0), previous(0)
1439  {
1440  // Inlined for performance reasons.
1441  }
1442  ~Encaps()
1443  {
1444  // Inlined for performance reasons.
1445  delete decoder;
1446  }
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
Ice::InputStream::InputStream
InputStream(const CommunicatorPtr &communicator, const EncodingVersion &version, const std::pair< const Byte *, const Byte * > &bytes)
Constructs a stream using the given communicator and encoding version.
Ice::Short
short Short
The mapping for the Slice short type.
Definition: Config.h:52
Ice::InputStream::endEncapsulation
void endEncapsulation()
Ends the current encapsulation.
Definition: InputStream.h:415
Ice::InputStream::read
void read(Long &v)
Reads a long from the stream.
CommunicatorF.h
Ice::InputStream::startSlice
std::string startSlice()
Reads the start of a value or exception slice.
Definition: InputStream.h:547
Ice::InputStream::read
void read(std::pair< const short *, const short * > &v)
Reads a sequence of boolean values from the stream.
Ice::InputStream::setValueFactoryManager
void setValueFactoryManager(const ValueFactoryManagerPtr &vfm)
Sets the value factory manager to use when unmarshaling value instances.
Ice::InputStream::skipSlice
void skipSlice()
Skips over a value or exception slice.
Definition: InputStream.h:565
Ice::InputStream::read
void read(std::vector< Short > &v)
Reads a sequence of shorts from the stream.
Ice::InputStream::readBlob
void readBlob(std::vector< Byte > &bytes, Int sz)
Reads a blob of bytes from the stream.
Ice::InputStream
Interface for input streams used to extract Slice types from a sequence of bytes.
Definition: InputStream.h:50
Ice::InputStream::InputStream
InputStream(const EncodingVersion &version, const std::pair< const Byte *, const Byte * > &bytes)
Constructs a stream using the given encoding version but without a communicator.
Ice::InputStream::initialize
void initialize(const CommunicatorPtr &communicator)
Initializes the stream to use the communicator's default encoding version.
Ice::InputStream::read
void read(Int &v)
Reads an int from the stream.
Definition: InputStream.h:867
Ice::Double
double Double
The mapping for the Slice double type.
Definition: Config.h:65
Ice::InputStream::InputStream
InputStream(const CommunicatorPtr &communicator, const EncodingVersion &version)
Constructs a stream using the given communicator and encoding version.
Ice::InputStream::size_type
size_t size_type
Definition: InputStream.h:53
Ice::SliceInfoSeq
::std::vector< SliceInfoPtr > SliceInfoSeq
The slices of unknown types.
Definition: SlicedDataF.h:16
IceUtil::None
constexpr std::experimental::Ice::nullopt_t None
For compatibility with the Ice C++98 mapping, do not use in new code:
Definition: Optional.h:1104
Ice::InputStream::read
void read(std::pair< const double *, const double * > &v)
Reads a sequence of doubles from the stream.
Ice::InputStream::read
void read(std::wstring &v)
Reads a wide string from the stream.
Ice::InputStream::read
void read(std::vector< Float > &v)
Reads a sequence of floats from the stream.
Ice::InputStream::pos
void pos(size_type p)
Sets a new position for the stream.
Definition: InputStream.h:1184
Ice::InputStream::read
void read(std::vector< bool > &v)
Reads a sequence of boolean values from the stream.
StreamHelpers.h
InstanceF.h
Ice::InputStream::endValue
SlicedDataPtr endValue(bool preserve)
Marks the end of a class instance.
Definition: InputStream.h:340
IceUtil::Optional
std::experimental::Ice::optional< T > Optional
For compatibility with the Ice C++98 mapping, do not use in new code:
Definition: Optional.h:1100
Ice::InputStream::setClosure
void * setClosure(void *p)
Associates closure data with this stream.
Ice::Float
float Float
The mapping for the Slice float type.
Definition: Config.h:63
Ice::InputStream::InputStream
InputStream(const std::pair< const Byte *, const Byte * > &bytes)
Constructs a stream using the latest encoding version but without a communicator.
Ice::InputStream::read
void read(std::pair< const T *, const T * > &v)
Extracts a sequence of data values from the stream.
Definition: InputStream.h:684
Ice::InputStream::readBlob
void readBlob(const Byte *&v, Container::size_type sz)
Reads a blob of bytes from the stream.
Definition: InputStream.h:626
Ice::InputStream::setCompactIdResolver
void setCompactIdResolver(std::function< std::string(int)> r)
Sets the compact ID resolver to use when unmarshaling value and exception instances.
Ice::InputStream::read
void read(std::pair< const int *, const int * > &v)
Reads a sequence of ints from the stream.
Ice::InputStream::InputStream
InputStream(const CommunicatorPtr &communicator, const std::vector< Byte > &bytes)
Constructs a stream using the communicator's default encoding version.
Ice::InputStream::InputStream
InputStream(const CommunicatorPtr &communicator, const EncodingVersion &version, const std::vector< Byte > &bytes)
Constructs a stream using the given communicator and encoding version.
Ice::InputStream::read
void read(Float &v)
Reads a float from the stream.
Ice::InputStream::endSlice
void endSlice()
Indicates that the end of a value or exception slice has been reached.
Definition: InputStream.h:556
Ice::InputStream::InputStream
InputStream(const EncodingVersion &version)
Constructs a stream using the given encoding version but without a communicator.
Ice::InputStream::~InputStream
~InputStream()
Definition: InputStream.h:177
Ice::InputStream::skipOptionals
void skipOptionals()
Skips all remaining optional values.
Ice::InputStream::readSize
Int readSize()
Extracts a size from the stream.
Definition: InputStream.h:583
ICE_API
#define ICE_API
Definition: Config.h:197
Ice::InputStream::read
void read(Short &v)
Reads a short from the stream.
Ice::EncodingVersion
A version structure for the encoding version.
Definition: Version.h:82
Ice::initialize
CommunicatorPtr initialize(int &argc, const char *argv[], const InitializationData &initData=InitializationData(), int version=30710)
Initializes a new communicator.
Ice::InputStream::readAndCheckSeqSize
Int readAndCheckSeqSize(int minSize)
Reads and validates a sequence size.
ValueFactory.h
Protocol.h
Ice::Byte
unsigned char Byte
The mapping for the Slice byte type.
Definition: Config.h:50
Ice::InputStream::InputStream
InputStream(const CommunicatorPtr &communicator)
Constructs a stream using the communicator's default encoding version.
Ice::InputStream::skipEmptyEncapsulation
EncodingVersion skipEmptyEncapsulation()
Skips an empty encapsulation.
Definition: InputStream.h:460
Ice::InputStream::read
void read(std::pair< const bool *, const bool * > &v)
Reads a sequence of boolean values from the stream.
Ice::InputStream::readEnum
Int readEnum(Int maxValue)
Reads an enumerator from the stream.
ICE_NULLPTR
#define ICE_NULLPTR
Definition: Config.h:362
Ice::InputStream::setTraceSlicing
void setTraceSlicing(bool b)
Indicates whether to log messages when instances of Slice classes are sliced.
Ice::InputStream::readOptional
bool readOptional(Int tag, OptionalFormat expectedFormat)
Determine if an optional value is available for reading.
Definition: InputStream.h:747
Ice::InputStream::read
void read(std::vector< Int > &v)
Reads a sequence of ints from the stream.
Ice::InputStream::startEncapsulation
const EncodingVersion & startEncapsulation()
Reads the start of an encapsulation.
Definition: InputStream.h:373
Ice::InputStream::startException
void startException()
Marks the start of a user exception.
Definition: InputStream.h:349
Ice::InputStream::EncapsDecoder::PatchEntry::patchAddr
void * patchAddr
Definition: InputStream.h:1282
Ice::InputStream::resize
void resize(Container::size_type sz)
Resizes the stream to a new size.
Definition: InputStream.h:318
Ice::InputStream::read
void read(::std::shared_ptr< T > &v)
Reads a typed proxy from the stream.
Definition: InputStream.h:1060
ICE_IN
#define ICE_IN(...)
Definition: Config.h:370
Ice::InputStream::readEncapsulation
EncodingVersion readEncapsulation(const Byte *&v, Int &sz)
Returns a blob of bytes representing an encapsulation.
Definition: InputStream.h:499
Ice::InputStream::throwException
void throwException(UserExceptionFactory factory=nullptr)
Extracts a user exception from the stream and throws it.
Ice::InputStream::readPendingValues
void readPendingValues()
Indicates that unmarshaling is complete, except for any class instances.
Ice::InputStream::skipSize
void skipSize()
Reads a size at the current position and skips that number of bytes.
Definition: InputStream.h:1161
ProxyF.h
Ice::InputStream::read
void read(const char *&vdata, size_t &vsize, bool convert=true)
Reads a string from the stream.
Ice::InputStream::InputStream
InputStream(const EncodingVersion &version, const std::vector< Byte > &bytes)
Constructs a stream using the given encoding version but without a communicator.
Ice::InputStream::EncapsDecoder::PatchEntry::classGraphDepth
size_t classGraphDepth
Definition: InputStream.h:1283
Ice::InputStream::clear
void clear()
Releases any data retained by encapsulations.
SlicedDataF.h
IceUtil::noncopyable
Definition: Config.h:313
Buffer.h
Ice::InputStream::getClosure
void * getClosure() const
Obtains the closure data associated with this stream.
Ice::InputStream::read
void read(std::vector< std::string > &v, bool convert=true)
Reads a sequence of strings from the stream.
Ice::InputStream::read
void read(Double &v)
Reads a double from the stream.
Object.h
Ice::InputStream::read
void read(std::pair< const long long *, const long long * > &v)
Reads a sequence of longs from the stream.
Ice::InputStream::read
void read(T &v)
Reads a data value from the stream.
Definition: InputStream.h:647
Ice::InputStream::InputStream
InputStream()
Constructs a stream using the latest encoding version but without a communicator.
Ice::InputStream::setClassGraphDepthMax
void setClassGraphDepthMax(size_t n)
Sets an upper limit on the depth of a class graph.
Ice::InputStream::read
void read(std::pair< const Byte *, const Byte * > &v)
Reads a sequence of bytes from the stream.
Ice::InputStream::getEncoding
const EncodingVersion & getEncoding() const
Determines the current encoding version.
Definition: InputStream.h:523
FactoryTable.h
Ice::InputStream::read
void read(Int tag, IceUtil::Optional< T > &v)
Reads an optional data value from the stream.
Definition: InputStream.h:657
Ice::InputStream::swap
void swap(InputStream &other)
Swaps the contents of one stream with another.
Ice::InputStream::read
void read(std::string &v, bool convert=true)
Reads a string from the stream.
Ice::InputStream::InputStream
InputStream(const CommunicatorPtr &communicator, const std::pair< const Byte *, const Byte * > &bytes)
Constructs a stream using the communicator's default encoding version.
Ice::Long
long long int Long
The mapping for the Slice long type.
Definition: Config.h:57
Ice
Definition: BuiltinSequences.h:56
Ice::InputStream::InputStream
InputStream(const std::vector< Byte > &bytes)
Constructs a stream using the latest encoding version but without a communicator.
Ice::InputStream::EncapsDecoder::PatchEntry
Definition: InputStream.h:1280
Ice::InputStream::readAll
void readAll(std::initializer_list< int > tags, IceUtil::Optional< T > &v, IceUtil::Optional< Te > &... ve)
Reads a list of optional data values.
Definition: InputStream.h:731
Ice::InputStream::read
void read(PatchFunc patchFunc, void *patchAddr)
Reads a value (instance of a Slice class) from the stream.
Definition: InputStream.h:1112
Ice::InputStream::setLogger
void setLogger(const LoggerPtr &logger)
Sets the logger to use when logging trace messages.
IceUtil::Handle
Definition: Handle.h:143
Ice::ObjectPrx
Base class of all object proxies.
Definition: Proxy.h:317
Ice::InputStream::readAll
void readAll(T &v)
Reads a list of mandatory data values.
Definition: InputStream.h:704
Ice::Encoding_1_0
const EncodingVersion Encoding_1_0
Identifies encoding version 1.0.
Ice::InputStream::initialize
void initialize(const CommunicatorPtr &communicator, const EncodingVersion &version)
Initializes the stream to use the given communicator and encoding version.
Ice::InputStream::readProxy
std::shared_ptr< ObjectPrx > readProxy()
Reads a proxy from the stream.
Ice::InputStream::endException
SlicedDataPtr endException(bool preserve)
Marks the end of a user exception.
Definition: InputStream.h:362
UserExceptionFactory.h
Ice::InputStream::skip
void skip(size_type size)
Advances the current stream position by the given number of bytes.
Definition: InputStream.h:1149
Ice::InputStream::read
void read(std::vector< Byte > &v)
Reads a sequence of bytes from the stream.
Ice::InputStream::startValue
void startValue()
Marks the start of a class instance.
Definition: InputStream.h:327
Ice::InputStream::pos
size_type pos()
Obtains the current position of the stream.
Definition: InputStream.h:1175
Ice::InputStream::getEncapsulationSize
Int getEncapsulationSize()
Determines the size of the current encapsulation, excluding the encapsulation header.
Ice::InputStream::EncapsDecoder::PatchEntry::patchFunc
PatchFunc patchFunc
Definition: InputStream.h:1281
Ice::InputStream::setSliceValues
void setSliceValues(bool b)
Indicates whether to slice instances of Slice classes to a known Slice type when a more derived type ...
Ice::CompactIdResolverPtr
IceUtil::Handle< CompactIdResolver > CompactIdResolverPtr
Definition: FactoryTable.h:31
Ice::UserExceptionFactory
std::function< void(const std::string &)> UserExceptionFactory
Creates and throws a user exception.
Definition: UserExceptionFactory.h:18
ValueF.h
Ice::InputStream::readAll
void readAll(T &v, Te &... ve)
Reads a list of mandatory data values.
Definition: InputStream.h:712
LoggerF.h
Ice::InputStream::skipEncapsulation
EncodingVersion skipEncapsulation()
Skips over an encapsulation.
Ice::Int
int Int
The mapping for the Slice int type.
Definition: Config.h:54
Ice::InputStream::skipOptional
void skipOptional(OptionalFormat format)
Skips one optional value with the given format.
Ice::InputStream::readAll
void readAll(std::initializer_list< int > tags, IceUtil::Optional< T > &v)
Reads a list of optional data values.
Definition: InputStream.h:722
Ice::InputStream::read
void read(std::vector< Long > &v)
Reads a sequence of longs from the stream.
ICE_DELEGATE
#define ICE_DELEGATE(T)
Definition: Config.h:369
Ice::InputStream::read
void read(std::pair< const float *, const float * > &v)
Reads a sequence of floats from the stream.
Ice::InputStream::read
void read(std::vector< std::wstring > &v)
Reads a sequence of wide strings from the stream.
Ice::InputStream::read
void read(std::vector< Double > &v)
Reads a sequence of doubles from the stream.
Ice::InputStream::read
void read(bool &v)
Reads a bool from the stream.
Definition: InputStream.h:804
Ice::InputStream::read
void read(Byte &v)
Reads a byte from the stream.
Definition: InputStream.h:764