3#include <userver/storages/postgres/exceptions.hpp>
4#include <userver/storages/postgres/io/buffer_io.hpp>
5#include <userver/storages/postgres/io/integral_types.hpp>
6#include <userver/storages/postgres/io/nullable_traits.hpp>
13 const auto* new_buffer_start = buffer + offset;
14 if (offset > length) {
15 throw InvalidInputBufferSize(length,
". Offset requested " + std::to_string(offset));
17 size = size == npos ? length - offset : size;
18 if (offset + size > length) {
19 throw InvalidInputBufferSize(size,
". Buffer remaininig size is " + std::to_string(length - offset));
24 return {is_null, cat, size, new_buffer_start};
29 io::ReadBuffer(GetSubBuffer(0, len, cat), std::forward<T>(value));
37 io::ReadBuffer(GetSubBuffer(0, len, cat), std::forward<T>(value), categories);
45 using ValueType = std::decay_t<T>;
46 Integer field_length{0};
50 traits::GetSetNull<ValueType>::SetNull(std::forward<T>(value));
52 }
else if (field_length < 0) {
54 throw InvalidInputBufferSize(0,
"Negative buffer size value");
55 }
else if (field_length == 0) {
56 traits::GetSetNull<ValueType>::SetDefault(std::forward<T>(value));
59 return consumed + Read(value, categories, field_length, cat);
64std::size_t ReadRawBinary(
FieldBuffer buffer, T& value,
const TypeBufferCategory& categories) {
65 return buffer.ReadRaw(value, categories);
70template <
typename T,
typename Buffer,
typename Enable = USERVER_NAMESPACE::utils::void_t<>>
71struct FormatterAcceptsReplacementOid : std::false_type {};
73template <
typename T,
typename Buffer>
74struct FormatterAcceptsReplacementOid<
77 USERVER_NAMESPACE::utils::void_t<
decltype(std::declval<T&>(
78 )(std::declval<
const UserTypes&>(), std::declval<Buffer&>(), std::declval<Oid>()))>> : std::true_type {};
82template <
typename T,
typename Buffer>
87 [[maybe_unused]] Oid replace_oid = kInvalidOid
89 traits::CheckFormatter<T>();
90 static constexpr auto size_len =
sizeof(Integer);
94 using BufferFormatter =
typename traits::
IO<T>::FormatterType;
95 using AcceptsReplacementOid = detail::FormatterAcceptsReplacementOid<BufferFormatter, Buffer>;
96 auto len_start = buffer.size();
97 buffer.resize(buffer.size() + size_len);
98 auto size_before = buffer.size();
99 if constexpr (AcceptsReplacementOid{}) {
100 BufferFormatter{value}(types, buffer, replace_oid);
102 io::WriteBuffer(types, buffer, value);
104 Integer bytes = buffer.size() - size_before;
105 BufferWriter(bytes)(buffer.begin() + len_start);