3#ifndef ICE_OUTPUT_STREAM_H
4#define ICE_OUTPUT_STREAM_H
7#include "CommunicatorF.h"
9#include "Ice/StringConverter.h"
10#include "Ice/Version.h"
11#include "Ice/VersionFunctions.h"
13#include "SlicedDataF.h"
14#include "StreamableTraits.h"
67 std::pair<const std::byte*, const std::byte*> bytes,
86 if (_currentEncaps != &_preAllocatedEncaps)
103 [[nodiscard]]
void* getClosure()
const;
108 void* setClosure(
void* p);
110 void resetEncapsulation();
115 void resize(Container::size_type sz) { b.resize(sz); }
122 assert(_currentEncaps && _currentEncaps->encoder);
123 _currentEncaps->encoder->startInstance(ValueSlice, data);
129 assert(_currentEncaps && _currentEncaps->encoder);
130 _currentEncaps->encoder->endInstance();
136 assert(_currentEncaps && _currentEncaps->encoder);
137 _currentEncaps->encoder->startInstance(ExceptionSlice,
nullptr);
143 assert(_currentEncaps && _currentEncaps->encoder);
144 _currentEncaps->encoder->endInstance();
172 return _currentEncaps ? _currentEncaps->encoding : _encoding;
179 void startSlice(std::string_view typeId,
int compactId,
bool last)
181 assert(_currentEncaps && _currentEncaps->encoder);
182 _currentEncaps->encoder->startSlice(typeId, compactId, last);
188 assert(_currentEncaps && _currentEncaps->encoder);
189 _currentEncaps->encoder->endSlice();
204 write(std::uint8_t(255));
209 write(
static_cast<std::uint8_t
>(v));
222 *dest++ = std::byte{255};
227 *dest =
static_cast<std::byte
>(v);
237 write(std::int32_t(0));
252 void writeBlob(
const std::byte* v, Container::size_type sz)
256 Container::size_type position = b.size();
258 memcpy(&b[position], &v[0], sz);
272 template<
typename T>
void write(std::int32_t tag,
const std::optional<T>& v);
279 template<
size_t I = 0,
typename... Te >>
writeAll(std::tuple<Te...> tuple);
292 template<
typename T,
typename... Te>
void writeAll(
const T& v,
const Te&... ve)
302 template<
typename T>
void writeAll(std::initializer_list<std::int32_t> tags,
const std::optional<T>& v)
304 write(*(tags.begin() + tags.size() - 1), v);
313 template<
typename T,
typename... Te>
315 writeAll(std::initializer_list<std::int32_t> tags,
const std::optional<T>& v,
const std::optional<Te>&... ve)
317 size_t index = tags.size() -
sizeof...(ve) - 1;
318 write(*(tags.begin() + index), v);
329 assert(_currentEncaps);
330 if (_currentEncaps->encoder)
332 return _currentEncaps->encoder->writeOptional(tag, format);
336 return writeOptImpl(tag, format);
349 template<
typename T, std::enable_if_t<!std::is_base_of_v<ObjectPrx, T>,
bool> = true>
350 void write(std::int32_t tag,
const std::optional<T>& v)
359 StreamOptionalHelper<T, StreamableTraits<T>::helper, StreamableTraits<T>::fixedLength>::
362 StreamOptionalHelper<T, StreamableTraits<T>::helper, StreamableTraits<T>::fixedLength>::write(
this, *v);
370 template<
typename T, std::enable_if_t<std::is_base_of_v<ObjectPrx, T>,
bool> = true>
371 void write(std::int32_t tag,
const std::optional<T>& v)
378 if (writeOptional(tag, OptionalFormat::FSize))
380 size_type pos = startSize();
389 template<
typename T>
void write(
const std::vector<T>& v)
397 write(&v[0], &v[0] + v.size());
405 template<
typename T>
void write(
const T* begin,
const T* end)
407 writeSize(
static_cast<std::int32_t
>(end - begin));
408 for (
const T* p = begin; p != end; ++p)
415 template<
size_t I = 0,
typename... Te> std::enable_if_t<I ==
sizeof...(Te),
void> writeAll(std::tuple<Te...>)
424 template<
size_t I = 0,
typename... Te>
425 std::enable_if_t < I<
sizeof...(Te),
void> writeAll(std::tuple<Te...> tuple)
427 write(std::get<I>(tuple));
428 writeAll<I + 1, Te...>(tuple);
433 void write(std::byte v) { b.push_back(v); }
437 void write(std::uint8_t v) { b.push_back(std::byte{v}); }
441 void write(
bool v) { b.push_back(
static_cast<std::byte
>(v)); }
445 void write(
const std::vector<bool>& v);
449 void write(std::int16_t v);
453 void write(std::int32_t v)
455 Container::size_type position = b.size();
456 resize(position +
sizeof(std::int32_t));
457 write(v, &b[position]);
462 void write(std::int64_t v);
470 void write(
double v);
474 void write(
const std::wstring& v) { write(std::wstring_view(v)); }
478 void write(std::wstring_view v);
486 void write(std::int32_t v, Container::iterator dest);
491 void write(
const std::byte* start,
const std::byte* end);
496 void write(
const std::uint8_t* start,
const std::uint8_t* end);
501 void write(
const bool* begin,
const bool* end);
506 void write(
const std::int16_t* begin,
const std::int16_t* end);
511 void write(
const std::int32_t* begin,
const std::int32_t* end);
516 void write(
const std::int64_t* begin,
const std::int64_t* end);
521 void write(
const float* begin,
const float* end);
526 void write(
const double* begin,
const double* end);
532 void write(
const std::string& v,
bool convert =
true) {
write(std::string_view(v), convert); }
538 void write(std::string_view v,
bool convert =
true)
540 auto sz =
static_cast<std::int32_t
>(v.size());
541 if (convert && sz > 0)
543 writeConverted(v.data(),
static_cast<size_t>(sz));
550 Container::size_type position = b.size();
551 resize(position +
static_cast<size_t>(sz));
552 memcpy(&b[position], v.data(),
static_cast<size_t>(sz));
562 void write(
const char* vdata,
size_t vsize,
bool convert =
true)
564 auto sz =
static_cast<std::int32_t
>(vsize);
565 if (convert && sz > 0)
567 writeConverted(vdata, vsize);
574 Container::size_type position = b.size();
575 resize(position +
static_cast<size_t>(sz));
576 memcpy(&b[position], vdata, vsize);
585 void write(
const char* vdata,
bool convert =
true) {
write(vdata, strlen(vdata), convert); }
592 void write(
const std::string* begin,
const std::string* end,
bool convert =
true);
597 void write(
const std::wstring* begin,
const std::wstring* end);
610 template<
typename Prx, std::enable_if_t<std::is_base_of_v<ObjectPrx, Prx>,
bool> = true>
611 void write(
const std::optional<Prx>& v)
625 template<
typename T, std::enable_if_t<std::is_base_of_v<Value, T>>* =
nullptr>
626 void write(
const std::shared_ptr<T>& v)
629 _currentEncaps->encoder->write(v);
660 std::pair<const std::byte*, const std::byte*>
finished();
672 void writeConverted(
const char*,
size_t);
690 using ValueList = std::vector<ValuePtr>;
692 class ICE_API EncapsEncoder
695 EncapsEncoder(
const EncapsEncoder&) =
delete;
696 virtual ~EncapsEncoder();
698 EncapsEncoder& operator=(
const EncapsEncoder&) =
delete;
700 virtual void write(
const ValuePtr&) = 0;
703 virtual void startInstance(SliceType,
const SlicedDataPtr&) = 0;
704 virtual void endInstance() = 0;
705 virtual void startSlice(std::string_view,
int,
bool) = 0;
706 virtual void endSlice() = 0;
708 virtual bool writeOptional(std::int32_t,
OptionalFormat) {
return false; }
710 virtual void writePendingValues() {}
713 EncapsEncoder(OutputStream* stream, Encaps* encaps) : _stream(stream), _encaps(encaps) {}
715 std::int32_t registerTypeId(std::string_view);
717 OutputStream* _stream;
720 using PtrToIndexMap = std::map<ValuePtr, std::int32_t>;
721 using TypeIdMap = std::map<std::string, std::int32_t, std::less<>>;
724 PtrToIndexMap _marshaledMap;
728 TypeIdMap _typeIdMap;
729 std::int32_t _typeIdIndex{0};
732 class ICE_API EncapsEncoder10 :
public EncapsEncoder
735 EncapsEncoder10(OutputStream* stream, Encaps* encaps) : EncapsEncoder(stream, encaps) {}
737 void write(
const ValuePtr&)
override;
738 void write(
const UserException&)
override;
740 void startInstance(SliceType,
const SlicedDataPtr&)
override;
741 void endInstance()
override;
742 void startSlice(std::string_view,
int,
bool)
override;
743 void endSlice()
override;
745 void writePendingValues()
override;
748 std::int32_t registerValue(
const ValuePtr&);
751 SliceType _sliceType{NoSlice};
754 Container::size_type _writeSlice{0};
757 std::int32_t _valueIdIndex{0};
758 PtrToIndexMap _toBeMarshaledMap;
761 class ICE_API EncapsEncoder11 :
public EncapsEncoder
764 EncapsEncoder11(OutputStream* stream, Encaps* encaps)
765 : EncapsEncoder(stream, encaps),
766 _preAllocatedInstanceData(nullptr)
770 void write(
const ValuePtr&)
override;
771 void write(
const UserException&)
override;
773 void startInstance(SliceType,
const SlicedDataPtr&)
override;
774 void endInstance()
override;
775 void startSlice(std::string_view,
int,
bool)
override;
776 void endSlice()
override;
778 bool writeOptional(std::int32_t, OptionalFormat)
override;
781 void writeSlicedData(
const SlicedDataPtr&);
782 void writeInstance(
const ValuePtr&);
786 InstanceData(InstanceData* p) : previous(p)
790 previous->next =
this;
803 SliceType sliceType{NoSlice};
804 bool firstSlice{
false};
807 std::uint8_t sliceFlags{0};
808 Container::size_type writeSlice{0};
809 Container::size_type sliceFlagsPos{0};
810 PtrToIndexMap indirectionMap;
811 ValueList indirectionTable;
813 InstanceData* previous{
nullptr};
814 InstanceData* next{
nullptr};
816 InstanceData _preAllocatedInstanceData;
817 InstanceData* _current{
nullptr};
819 std::int32_t _valueIdIndex{1};
826 Encaps(
const Encaps&) =
delete;
827 ~Encaps() {
delete encoder; }
828 Encaps& operator=(
const Encaps&) =
delete;
839 Container::size_type start;
840 EncodingVersion encoding;
843 EncapsEncoder* encoder{
nullptr};
845 Encaps* previous{
nullptr};
854 EncodingVersion _encoding;
858 Encaps* _currentEncaps;
862 Encaps _preAllocatedEncaps;
The base class for all Ice proxies.
void startValue(const SlicedDataPtr &data)
Marks the start of a class instance.
void startEncapsulation()
Writes the start of an encapsulation using the default encoding version and class encoding format.
void write(const std::int16_t *begin, const std::int16_t *end)
Writes an int16_t sequence as a Slice short sequence.
void rewriteSize(std::int32_t v, Container::iterator dest)
Replaces a size value at the specified position in the stream.
void writePendingValues()
Encodes the state of class instances whose insertion was delayed during a previous call write.
void write(const T &v)
Writes a value to the stream.
OutputStream(EncodingVersion encoding=currentEncoding, FormatType format=FormatType::CompactFormat, StringConverterPtr stringConverter=nullptr, WstringConverterPtr wstringConverter=nullptr)
Constructs an OutputStream.
void write(const std::uint8_t *start, const std::uint8_t *end)
Writes a byte sequence to the stream.
void writeException(const UserException &v)
Writes a user exception to the stream.
void writeBlob(const std::vector< std::byte > &v)
Copies the specified blob of bytes to the stream without modification.
void write(std::int32_t v, Container::iterator dest)
Overwrites a 32-bit integer value at the given position in the stream.
void finished(std::vector< std::byte > &v)
Indicates that marshaling is complete.
void writeAll(const T &v)
Writes a value (single element list) to the stream.
void writeNullProxy()
Writes a null proxy to the stream.
void startException()
Marks the start of an exception instance.
OutputStream(const CommunicatorPtr &communicator, EncodingVersion encoding)
Constructs an OutputStream using the format, string converter and wstring converter provided by the c...
void write(const std::int64_t *begin, const std::int64_t *end)
Writes a long sequence to the stream.
void writeAll(std::initializer_list< std::int32_t > tags, const std::optional< T > &v)
Writes an optional value (single element list) to the stream.
size_type startSize()
Writes a placeholder value for the size and returns the starting position of the size value; after wr...
size_type pos()
Gets the current position of the stream.
void writeAll(const T &v, const Te &... ve)
Writes a list of values to the stream.
void resize(Container::size_type sz)
Resizes the stream to a new size.
bool writeOptional(std::int32_t tag, OptionalFormat format)
Writes the tag and format of an optional value.
void startEncapsulation(const EncodingVersion &encoding, std::optional< FormatType > format)
Writes the start of an encapsulation using the specified encoding version and class encoding format.
void write(const float *begin, const float *end)
Writes a float sequence as a Slice float sequence.
void writeEncapsulation(const std::byte *v, std::int32_t sz)
Copies the marshaled form of an encapsulation to the buffer.
void startSlice(std::string_view typeId, int compactId, bool last)
Writes the start of a class instance or exception slice.
const EncodingVersion & getEncoding() const
Gets the current encoding version.
void write(const bool *begin, const bool *end)
Writes a boolean sequence to the stream.
void write(std::int32_t tag, const std::optional< T > &v)
Writes an optional value to the stream.
void write(const std::wstring *begin, const std::wstring *end)
Writes a wide string sequence to the stream.
void write(const double *begin, const double *end)
Writes a double sequence as a Slice double sequence.
void endEncapsulation()
Ends the current encapsulation.
void endValue()
Marks the end of a class instance.
void write(std::string_view v, bool convert=true)
Writes a string view to the stream.
void endSize(size_type position)
Updates the size value at the given position.
void writeEnum(std::int32_t v, std::int32_t maxValue)
Writes an enumerator to the stream.
void swap(OutputStream &other) noexcept
Swaps the contents of one stream with another.
void endException()
Marks the end of an exception instance.
writeAll(std::tuple< Te... > tuple)
Writes a tuple to the stream.
void write(const std::int32_t *begin, const std::int32_t *end)
Writes an int sequence to the stream.
void writeProxy(const ObjectPrx &v)
Writes a proxy to the stream.
void write(const std::string *begin, const std::string *end, bool convert=true)
Writes a string sequence to the stream.
void writeAll(std::initializer_list< std::int32_t > tags, const std::optional< T > &v, const std::optional< Te > &... ve)
Writes a list of optional values to the stream.
OutputStream(OutputStream &&other) noexcept
Move constructor.
void writeEmptyEncapsulation(const EncodingVersion &encoding)
Writes an empty encapsulation using the specified encoding version.
OutputStream(std::pair< const std::byte *, const std::byte * > bytes, EncodingVersion encoding=currentEncoding, FormatType format=FormatType::CompactFormat, StringConverterPtr stringConverter=nullptr, WstringConverterPtr wstringConverter=nullptr)
Constructs an OutputStream over an application-supplied buffer.
void write(const std::string &v, bool convert=true)
Writes a string to the stream.
void endSlice()
Marks the end of a class instance or exception slice.
void writeSize(std::int32_t v)
Writes a size value.
std::size_t size_type
The size type for this byte buffer.
std::pair< const std::byte *, const std::byte * > finished()
Indicates that marshaling is complete.
void write(const char *vdata, size_t vsize, bool convert=true)
Writes a string to the stream.
void rewrite(std::int32_t v, size_type pos)
Overwrites a 32-bit integer value at the specified position in the stream.
void write(const char *vdata, bool convert=true)
Writes a string to the stream.
OutputStream(const CommunicatorPtr &communicator)
Constructs an OutputStream using the encoding, format, string converter and wstring converter provide...
void clear()
Releases any data retained by encapsulations.
void writeBlob(const std::byte *v, Container::size_type sz)
Copies the specified blob of bytes to the stream without modification.
void write(const std::byte *start, const std::byte *end)
Writes a byte sequence to the stream.
OutputStream & operator=(OutputStream &&other) noexcept
Move assignment operator.
Abstract base class for all Ice exceptions defined in Slice.
std::shared_ptr< Communicator > CommunicatorPtr
A shared pointer to a Communicator.
std::shared_ptr< StringConverter > StringConverterPtr
A shared pointer to a StringConverter.
OptionalFormat
The optional format, used for marshaling optional fields and arguments.
constexpr EncodingVersion currentEncoding
Identifies the latest encoding version.
std::shared_ptr< Value > ValuePtr
A shared pointer to a Value.
FormatType
Specifies the format for marshaling classes and exceptions with the Slice 1.1 encoding.
@ CompactFormat
Favors compactness, but does not support slicing-off unknown slices during unmarshaling.
std::shared_ptr< SlicedData > SlicedDataPtr
A shared pointer to a SlicedData.
std::shared_ptr< WstringConverter > WstringConverterPtr
A shared pointer to a WstringConverter.
Represents a version of the Slice encoding.
A helper template class for writing (marshaling) and reading (unmarshaling) values to and from a stre...