56 using PatchFunc = std::function<void(
void* addr,
const ValuePtr& v)>;
64 const std::vector<std::byte>& bytes,
70 std::pair<const std::byte*, const std::byte*> bytes,
81 const std::vector<std::byte>& bytes,
88 std::pair<const std::byte*, const std::byte*> bytes,
98 IceInternal::Instance* instance,
100 IceInternal::Buffer& buf,
117 if (_currentEncaps != &_preAllocatedEncaps)
122 for (
const auto& d : _deleters)
133 [[nodiscard]] IceInternal::Instance* instance()
const {
return _instance; }
143 [[nodiscard]]
void* getClosure()
const;
148 void* setClosure(
void* p);
150 void resetEncapsulation();
154 void resize(Container::size_type sz)
164 assert(_currentEncaps && _currentEncaps->decoder);
165 _currentEncaps->decoder->startInstance(ValueSlice);
172 assert(_currentEncaps && _currentEncaps->decoder);
173 return _currentEncaps->decoder->endInstance();
179 assert(_currentEncaps && _currentEncaps->decoder);
180 _currentEncaps->decoder->startInstance(ExceptionSlice);
186 assert(_currentEncaps && _currentEncaps->decoder);
187 _currentEncaps->decoder->endInstance();
212 return _currentEncaps ? _currentEncaps->encoding : _encoding;
226 assert(_currentEncaps && _currentEncaps->decoder);
227 _currentEncaps->decoder->startSlice();
233 assert(_currentEncaps && _currentEncaps->decoder);
234 _currentEncaps->decoder->endSlice();
240 assert(_currentEncaps && _currentEncaps->decoder);
241 _currentEncaps->decoder->skipSlice();
255 auto val =
static_cast<unsigned char>(byte);
262 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
268 return static_cast<std::int32_t
>(
static_cast<unsigned char>(byte));
280 void readBlob(std::vector<std::byte>& bytes, std::int32_t sz);
285 void readBlob(
const std::byte*& v, Container::size_type sz)
290 if (
static_cast<Container::size_type
>(b.end() - i) < sz)
292 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
312 template<
typename T>
void read(std::int32_t tag, T& v);
325 template<
typename T,
typename... Te>
void readAll(T& v, Te&... ve)
335 template<
typename T>
void readAll(std::initializer_list<std::int32_t> tags, std::optional<T>& v)
337 read(*(tags.begin() + tags.size() - 1), v);
346 template<
typename T,
typename... Te>
347 void readAll(std::initializer_list<std::int32_t> tags, std::optional<T>& v, std::optional<Te>&... ve)
349 size_t index = tags.size() -
sizeof...(ve) - 1;
350 read(*(tags.begin() + index), v);
360 assert(_currentEncaps);
361 if (_currentEncaps->decoder)
363 return _currentEncaps->decoder->readOptional(tag, expectedFormat);
367 return readOptImpl(tag, expectedFormat);
380 template<
typename T, std::enable_if_t<!std::is_base_of_v<ObjectPrx, T>,
bool> = true>
381 void read(std::int32_t tag, std::optional<T>& v)
403 template<
typename T, std::enable_if_t<std::is_base_of_v<ObjectPrx, T>,
bool> = true>
404 void read(std::int32_t tag, std::optional<T>& v)
406 if (readOptional(tag, OptionalFormat::FSize))
419 template<
typename T>
void read(std::pair<const T*, const T*>& v)
421 auto holder =
new std::vector<T>;
422 _deleters.push_back([holder] {
delete holder; });
424 if (holder->size() > 0)
426 v.first = holder->data();
427 v.second = holder->data() + holder->size();
436#if defined(ICE_UNALIGNED) || (defined(_WIN32) && defined(ICE_API_EXPORTS))
438 void read(std::pair<const std::int16_t*, const std::int16_t*>& v) { unalignedRead(v); }
439 void read(std::pair<const std::int32_t*, const std::int32_t*>& v) { unalignedRead(v); }
440 void read(std::pair<const std::int64_t*, const std::int64_t*>& v) { unalignedRead(v); }
441 void read(std::pair<const float*, const float*>& v) { unalignedRead(v); }
442 void read(std::pair<const double*, const double*>& v) { unalignedRead(v); }
447 void read(std::byte& v)
451 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
458 void read(std::uint8_t& v)
462 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
464 v =
static_cast<std::uint8_t
>(*i++);
469 void read(std::vector<std::byte>& v);
474 void read(std::pair<const std::byte*, const std::byte*>& v);
482 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
484 v = (std::byte{0} != *i++);
489 void read(std::vector<bool>& v);
494 void read(std::pair<const bool*, const bool*>& v);
498 void read(std::int16_t& v);
502 void read(std::vector<std::int16_t>& v);
506 void read(std::int32_t& v);
510 void read(std::vector<std::int32_t>& v);
514 void read(std::int64_t& v);
518 void read(std::vector<std::int64_t>& v);
526 void read(std::vector<float>& v);
530 void read(
double& v);
534 void read(std::vector<double>& v);
544 void read(std::string& v,
bool convert =
true);
551 void read(
const char*& vdata,
size_t& vsize,
bool convert =
true);
557 void read(std::vector<std::string>& v,
bool convert =
true);
563 void read(std::wstring& v);
567 void read(std::vector<std::wstring>& v);
572 template<
typename Prx, std::enable_if_t<std::is_base_of_v<ObjectPrx, Prx>,
bool> = true>
573 void read(std::optional<Prx>& v)
575 IceInternal::ReferencePtr ref = readReference();
578 v = Prx::_fromReference(ref);
589 template<
typename T, std::enable_if_t<std::is_base_of_v<Value, T>>* =
nullptr>
void read(std::shared_ptr<T>& v)
591 read(patchValue<T>, &v);
598 void read(PatchFunc patchFunc,
void* patchAddr)
601 _currentEncaps->decoder->read(std::move(patchFunc), patchAddr);
628 if (i + size > b.end())
630 throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
640 if (
static_cast<unsigned char>(bt) == 255)
658#if defined(ICE_UNALIGNED) || (defined(_WIN32) && defined(ICE_API_EXPORTS))
659 template<
typename T>
void unalignedRead(std::pair<const T*, const T*>& v)
661 int sz = readAndCheckSeqSize(
static_cast<int>(
sizeof(T)));
665 v.first =
reinterpret_cast<T*
>(i);
666 i += sz *
static_cast<int>(
sizeof(T));
667 v.second =
reinterpret_cast<T*
>(i);
671 v.first = v.second =
nullptr;
678 IceInternal::Instance* instance,
679 EncodingVersion encoding,
680 IceInternal::Buffer&& buf,
681 SliceLoaderPtr sliceLoader);
684 IceInternal::ReferencePtr readReference();
686 bool readConverted(std::string&, std::int32_t);
688 void throwUnmarshalOutOfBoundsException(
const char*,
int);
698 void traceSkipSlice(std::string_view, SliceType)
const;
700 using ValueList = std::vector<ValuePtr>;
702 class ICE_API EncapsDecoder
705 EncapsDecoder(
const EncapsDecoder&) =
delete;
706 virtual ~EncapsDecoder();
708 EncapsDecoder& operator=(
const EncapsDecoder&) =
delete;
710 virtual void read(PatchFunc,
void*) = 0;
711 virtual void throwException(UserExceptionFactory) = 0;
713 virtual void startInstance(SliceType) = 0;
715 virtual void startSlice() = 0;
716 virtual void endSlice() = 0;
717 virtual void skipSlice() = 0;
719 virtual bool readOptional(std::int32_t, OptionalFormat) {
return false; }
721 virtual void readPendingValues() {}
724 EncapsDecoder(InputStream* stream, Encaps* encaps, std::int32_t classGraphDepthMax)
727 _classGraphDepthMax(classGraphDepthMax)
731 std::string readTypeId(
bool);
732 ValuePtr newInstance(std::string_view);
734 void addPatchEntry(std::int32_t,
const PatchFunc&,
void*);
735 void unmarshal(std::int32_t,
const ValuePtr&);
737 using IndexToPtrMap = std::map<std::int32_t, ValuePtr>;
738 using TypeIdMap = std::map<std::int32_t, std::string>;
745 std::int32_t classGraphDepth;
747 using PatchList = std::vector<PatchEntry>;
748 using PatchMap = std::map<std::int32_t, PatchList>;
750 InputStream* _stream;
752 const std::int32_t _classGraphDepthMax;
753 std::int32_t _classGraphDepth{0};
760 IndexToPtrMap _unmarshaledMap;
761 TypeIdMap _typeIdMap;
762 std::int32_t _typeIdIndex{0};
763 ValueList _valueList;
766 class ICE_API EncapsDecoder10 :
public EncapsDecoder
769 EncapsDecoder10(InputStream* stream, Encaps* encaps, std::int32_t classGraphDepthMax)
770 : EncapsDecoder(stream, encaps, classGraphDepthMax)
774 void read(PatchFunc,
void*)
override;
775 void throwException(UserExceptionFactory)
override;
777 void startInstance(SliceType)
override;
779 void startSlice()
override;
780 void endSlice()
override;
781 void skipSlice()
override;
783 void readPendingValues()
override;
789 SliceType _sliceType{NoSlice};
790 bool _skipFirstSlice{
false};
793 std::int32_t _sliceSize{0};
797 class ICE_API EncapsDecoder11 :
public EncapsDecoder
800 EncapsDecoder11(InputStream* stream, Encaps* encaps, std::int32_t classGraphDepthMax)
801 : EncapsDecoder(stream, encaps, classGraphDepthMax),
802 _preAllocatedInstanceData(nullptr)
806 void read(PatchFunc,
void*)
override;
807 void throwException(UserExceptionFactory)
override;
809 void startInstance(SliceType)
override;
811 void startSlice()
override;
812 void endSlice()
override;
813 void skipSlice()
override;
815 bool readOptional(std::int32_t, OptionalFormat)
override;
818 std::int32_t readInstance(std::int32_t,
const PatchFunc&,
void*);
821 struct IndirectPatchEntry
827 using IndirectPatchList = std::vector<IndirectPatchEntry>;
829 using IndexList = std::vector<std::int32_t>;
830 using IndexListList = std::vector<IndexList>;
834 InstanceData(InstanceData* p) : previous(p)
838 previous->next =
this;
851 SliceType sliceType{NoSlice};
852 bool skipFirstSlice{
false};
854 IndexListList indirectionTables;
857 std::uint8_t sliceFlags{0};
858 std::int32_t sliceSize{0};
861 IndirectPatchList indirectPatchList;
863 InstanceData* previous{
nullptr};
864 InstanceData* next{
nullptr};
866 InstanceData _preAllocatedInstanceData;
867 InstanceData* _current{
nullptr};
869 void push(SliceType sliceType)
873 _current = &_preAllocatedInstanceData;
877 _current = _current->next ? _current->next :
new InstanceData(_current);
879 _current->sliceType = sliceType;
880 _current->skipFirstSlice =
false;
883 std::int32_t _valueIdIndex{1};
890 Encaps(
const Encaps&) =
delete;
891 ~Encaps() {
delete decoder; }
892 Encaps& operator=(
const Encaps&) =
delete;
903 Container::size_type start{0};
905 EncodingVersion encoding;
907 EncapsDecoder* decoder{
nullptr};
909 Encaps* previous{
nullptr};
913 IceInternal::Instance*
const _instance;
919 EncodingVersion _encoding;
921 Encaps* _currentEncaps{
nullptr};
925 Encaps _preAllocatedEncaps;
928 const std::int32_t _classGraphDepthMax;
930 void* _closure{
nullptr};
937 std::vector<std::function<void()>> _deleters;