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) {
17 size = size == npos ? length - offset : size;
18 if (offset + size > length) {
20 fmt::format(
"Attempt to read {} bytes more than was sent by server", offset + size - length)
26 return {is_null, cat, size, new_buffer_start};
31 io::ReadBuffer(GetSubBuffer(0, len, cat), std::forward<T>(value));
39 io::ReadBuffer(GetSubBuffer(0, len, cat), std::forward<T>(value), categories);
47 using ValueType = std::remove_cvref_t<T>;
48 Integer field_length{0};
54 }
else if (field_length < 0) {
57 }
else if (field_length == 0) {
61 return consumed + Read(std::forward<T>(value), categories, field_length, cat);
66std::size_t ReadRawBinary(
FieldBuffer buffer, T& value,
const TypeBufferCategory& categories) {
67 return buffer.ReadRaw(value, categories);
72template <
typename T,
typename Buffer>
73inline constexpr bool kFormatterAcceptsReplacementOid =
requires(T& f,
const UserTypes& types, Buffer& buf, Oid oid) {
79template <
typename T,
typename Buffer>
84 [[maybe_unused]] Oid replace_oid = kInvalidOid
86 traits::CheckFormatter<T>();
87 static constexpr auto size_len =
sizeof(Integer);
91 using BufferFormatter =
typename traits::
IO<T>::FormatterType;
92 auto len_start = buffer.size();
93 buffer.resize(buffer.size() + size_len);
94 auto size_before = buffer.size();
95 if constexpr (detail::kFormatterAcceptsReplacementOid<BufferFormatter, Buffer>) {
96 BufferFormatter{value}(types, buffer, replace_oid);
98 io::WriteBuffer(types, buffer, value);
100 const Integer bytes = buffer.size() - size_before;
101 BufferWriter(bytes)(buffer.begin() + len_start);