3#ifndef ICE_STREAM_HELPERS_H
4#define ICE_STREAM_HELPERS_H
6#include "InputStream.h"
7#include "OutputStream.h"
8#include "StringConverter.h"
16# if _MSVC_LANG >= 202002L
19#elif __has_include(<span>)
33 template<
typename T>
void print(std::ostream& stream, T v);
60 static void print(std::ostream& stream, T v);
76 inline void print(std::ostream& stream, T v)
91 inline void print(std::ostream& stream, std::optional<T> v)
113 inline void print(std::ostream& stream,
const T& v)
129 inline void print(std::ostream& stream,
const std::optional<T>& v)
143 static void write(OutputStream* stream, T v) { stream->write(v); }
145 static void read(InputStream* stream, T& v) { stream->read(v); }
147 static void print(std::ostream& stream, T v) { stream << v; }
152 static void print(std::ostream& stream,
bool v) { stream << (v ?
"true" :
"false"); }
157 static void print(std::ostream& stream, std::uint8_t v) { stream << static_cast<int>(v); }
162 static void print(std::ostream& stream, std::byte v) { stream << static_cast<int>(v); }
167 static void write(OutputStream* stream, std::string_view v) { stream->write(v); }
175 static void write(OutputStream* stream, std::wstring_view v) { stream->write(v); }
184 static void write(OutputStream* stream,
const T& v) { stream->write(v); }
186 static void read(InputStream* stream, T& v) { stream->read(v); }
188 static void print(std::ostream& stream,
const T& v) { stream << v; }
198 static void print(std::ostream& stream,
const std::vector<bool>& v)
201 bool firstElement =
true;
202 for (
bool element : v)
208 firstElement =
false;
220 template<
typename T>
struct StreamReader;
224 static void write(OutputStream* stream,
const T& v) { stream->writeAll(v.ice_tuple()); }
226 static void read(InputStream* stream, T& v) { StreamReader<T>::read(stream, v); }
228 static void print(std::ostream& stream,
const T& v) { stream << v; }
233 static void write(OutputStream* stream, T v)
235 if (
static_cast<std::int32_t
>(v) < StreamableTraits<T>::minValue ||
236 static_cast<std::int32_t
>(v) > StreamableTraits<T>::maxValue)
238 IceInternal::Ex::throwMarshalException(__FILE__, __LINE__,
"enumerator out of range");
240 stream->writeEnum(
static_cast<std::int32_t
>(v), StreamableTraits<T>::maxValue);
243 static void read(InputStream* stream, T& v)
245 std::int32_t value = stream->readEnum(StreamableTraits<T>::maxValue);
246 if (value < StreamableTraits<T>::minValue || value > StreamableTraits<T>::maxValue)
248 IceInternal::Ex::throwMarshalException(__FILE__, __LINE__,
"enumerator out of range");
250 v =
static_cast<T
>(value);
253 static void print(std::ostream& stream, T v) { stream << v; }
258 static void write(OutputStream* stream,
const T& v)
260 stream->writeSize(
static_cast<std::int32_t
>(v.size()));
261 for (
const auto& element : v)
263 stream->write(element);
267 static void read(InputStream* stream, T& v)
270 T(
static_cast<size_t>(sz)).swap(v);
271 for (
auto& element : v)
273 stream->read(element);
277 static void print(std::ostream& stream,
const T& v)
280 bool firstElement =
true;
281 for (
const auto& element : v)
287 firstElement =
false;
297 static void write(OutputStream* stream, std::pair<const T*, const T*> v) { stream->write(v.first, v.second); }
299 static void read(InputStream* stream, std::pair<const T*, const T*>& v) { stream->read(v); }
308 static void write(OutputStream* stream,
const std::span<T>& v) { stream->write(v.data(), v.data() + v.size()); }
317 static void write(OutputStream* stream,
const T& v)
319 stream->writeSize(
static_cast<std::int32_t
>(v.size()));
320 for (
const auto& entry : v)
322 stream->write(entry.first);
323 stream->write(entry.second);
327 static void read(InputStream* stream, T& v)
329 std::int32_t sz = stream->readSize();
333 typename T::value_type p;
334 stream->read(
const_cast<typename T::key_type&
>(p.first));
335 auto i = v.insert(v.end(), p);
336 stream->read(i->second);
340 static void print(std::ostream& stream,
const T& v)
343 bool firstEntry =
true;
344 for (
const auto& entry : v)
363 static void write(OutputStream* stream,
const T& v) { stream->writeException(v); }
368 static void print(std::ostream& stream,
const T& v) { stream << v; }
373 static void write(OutputStream* stream,
const T& v) { stream->write(v); }
375 static void read(InputStream* stream, T& v) { stream->read(v); }
377 static void print(std::ostream& stream,
const T& v) { stream << v; }
382 static void write(OutputStream* stream,
const T& v) { stream->write(v); }
384 static void read(InputStream* stream, T& v) { stream->read(v); }
386 static void print(std::ostream& stream,
const T& v) { stream << v; }
397 template<StreamHelperCategory st,
int minWireSize,
bool fixedLength>
struct GetOptionalFormat;
443 template<
typename T, StreamHelperCategory st,
bool fixedLength>
struct StreamOptionalHelper
445 using Traits = StreamableTraits<T>;
452 static constexpr OptionalFormat optionalFormat = GetOptionalFormat<st, Traits::minWireSize, fixedLength>::value;
454 static void write(OutputStream* stream,
const T& v) { stream->write(v); }
456 static void read(InputStream* stream, T& v) { stream->read(v); }
464 static void write(OutputStream* stream,
const T& v)
470 static void read(InputStream* stream, T& v)
482 static void write(OutputStream* stream,
const T& v)
486 stream->endSize(pos);
489 static void read(InputStream* stream, T& v)
500 template<
typename T,
bool fixedLength,
int sz>
struct StreamOptionalContainerHelper;
505 template<
typename T,
int sz>
struct StreamOptionalContainerHelper<T, false, sz>
507 static constexpr OptionalFormat optionalFormat = OptionalFormat::FSize;
509 static void write(OutputStream* stream,
const T& v, std::int32_t)
511 StreamOptionalHelper<T, StreamHelperCategoryStruct, false>::write(stream, v);
514 static void read(InputStream* stream, T& v)
516 StreamOptionalHelper<T, StreamHelperCategoryStruct, false>::read(stream, v);
522 template<
typename T,
int sz>
struct StreamOptionalContainerHelper<T, true, sz>
524 static constexpr OptionalFormat optionalFormat = OptionalFormat::VSize;
526 static void write(OutputStream* stream,
const T& v, std::int32_t n)
530 stream->writeSize(sz * n + (n < 255 ? 1 : 5));
534 static void read(InputStream* stream, T& v)
543 template<
typename T>
struct StreamOptionalContainerHelper<T, true, 1>
545 static constexpr OptionalFormat optionalFormat = OptionalFormat::VSize;
547 static void write(OutputStream* stream,
const T& v, std::int32_t) { stream->write(v); }
549 static void read(InputStream* stream, T& v) { stream->read(v); }
555 using E =
typename T::value_type;
562 StreamOptionalContainerHelper<T, fixedLength, size>::optionalFormat;
564 static void write(OutputStream* stream,
const T& v)
566 StreamOptionalContainerHelper<T, fixedLength, size>::write(stream, v,
static_cast<std::int32_t
>(v.size()));
569 static void read(InputStream* stream, T& v)
571 StreamOptionalContainerHelper<T, fixedLength, size>::read(stream, v);
578 using P = std::pair<const T*, const T*>;
585 StreamOptionalContainerHelper<P, fixedLength, size>::optionalFormat;
587 static void write(OutputStream* stream,
const P& v)
589 auto n =
static_cast<std::int32_t
>(v.second - v.first);
590 StreamOptionalContainerHelper<P, fixedLength, size>::write(stream, v, n);
593 static void read(InputStream* stream, P& v)
595 StreamOptionalContainerHelper<P, fixedLength, size>::read(stream, v);
602 using K =
typename T::key_type;
603 using V =
typename T::mapped_type;
611 StreamOptionalContainerHelper<T, fixedLength, size>::optionalFormat;
613 static void write(OutputStream* stream,
const T& v)
615 StreamOptionalContainerHelper<T, fixedLength, size>::write(stream, v,
static_cast<std::int32_t
>(v.size()));
618 static void read(InputStream* stream, T& v)
620 StreamOptionalContainerHelper<T, fixedLength, size>::read(stream, v);
634 static void read(InputStream* istr, ProtocolVersion& v) { istr->readAll(v.major, v.minor); }
646 static void read(InputStream* istr, EncodingVersion& v) { istr->readAll(v.major, v.minor); }
std::size_t size_type
The size type for this byte buffer.
Represents a byte buffer used for marshaling data using the Slice encoding.
constexpr StreamHelperCategory StreamHelperCategoryBuiltin
Built-in types usually passed by reference.
void print(std::ostream &stream, T v)
Prints a value to a stream.
OptionalFormat
The optional format, used for marshaling optional fields and arguments.
@ VSize
"Size encoding" using 1 to 5 bytes followed by data, e.g., string, fixed size struct,...
@ FSize
Fixed size using 4 bytes followed by data, e.g., variable-size struct, container.
constexpr StreamHelperCategory StreamHelperCategoryDictionary
Dictionary types.
constexpr StreamHelperCategory StreamHelperCategoryEnum
Generated enum types.
constexpr StreamHelperCategory StreamHelperCategoryProxy
Proxy types.
int StreamHelperCategory
The stream helper category allows to select a StreamHelper specialization for a specific category of ...
constexpr StreamHelperCategory StreamHelperCategoryClass
Generated class types.
constexpr StreamHelperCategory StreamHelperCategoryStruct
Generated struct types.
constexpr StreamHelperCategory StreamHelperCategorySequence
Sequence types.
constexpr StreamHelperCategory StreamHelperCategoryBuiltinValue
Built-in types usually passed by value.
constexpr StreamHelperCategory StreamHelperCategoryUserException
User exception types.
std::string wstringToString(const std::wstring &str, const StringConverterPtr &nc=nullptr, const WstringConverterPtr &wc=nullptr)
Converts the given wide string to a narrow string.
Represents a version of the Slice encoding.
Represents a version of the Ice protocol.
static void write(OutputStream *stream, T v)
Writes a value to the stream.
static void print(std::ostream &stream, T v)
Prints a value to the stream.
static void read(InputStream *stream, T &v)
Reads a value from the stream.
A helper template class for writing (marshaling) and reading (unmarshaling) values to and from a stre...
static constexpr bool fixedLength
Indicates if the type is always encoded on a fixed number of bytes.
static constexpr int minWireSize
The minimum number of bytes needed to marshal this type.
static constexpr StreamHelperCategory helper
The category trait, used for selecting the appropriate StreamHelper.
Provides traits for a type that can be marshaled or unmarshaled to/from a stream of bytes using the S...