libpqxx  7.3.0
composite.hxx
1 #ifndef PQXX_H_COMPOSITE
2 #define PQXX_H_COMPOSITE
3 
4 #include "pqxx/internal/compiler-internal-pre.hxx"
5 
6 #include "pqxx/internal/array-composite.hxx"
7 #include "pqxx/internal/concat.hxx"
8 #include "pqxx/util.hxx"
9 
10 namespace pqxx
11 {
13 
32 template<typename... T>
33 inline void parse_composite(
34  pqxx::internal::encoding_group enc, std::string_view text, T &...fields)
35 {
36  static_assert(sizeof...(fields) > 0);
37 
38  auto const scan{pqxx::internal::get_glyph_scanner(enc)};
39  auto const data{text.data()};
40  auto const size{std::size(text)};
41  if (size == 0)
42  throw conversion_error{"Cannot parse composite value from empty string."};
43 
44  std::size_t here{0}, next{scan(data, size, here)};
45  if (next != 1 or data[here] != '(')
46  throw conversion_error{
47  internal::concat("Invalid composite value string: ", text)};
48 
49  here = next;
50 
51  constexpr auto num_fields{sizeof...(fields)};
52  std::size_t index{0};
53  (pqxx::internal::parse_composite_field(
54  index, text, here, fields, scan, num_fields - 1),
55  ...);
56 }
57 
58 
60 
65 template<typename... T>
66 inline void parse_composite(std::string_view text, T &...fields)
67 {
68  parse_composite(pqxx::internal::encoding_group::MONOBYTE, text, fields...);
69 }
70 } // namespace pqxx
71 
72 
73 namespace pqxx::internal
74 {
75 constexpr char empty_composite_str[]{"()"};
76 } // namespace pqxx::internal
77 
78 
79 namespace pqxx
80 {
82 
84 template<typename... T>
85 inline std::size_t composite_size_buffer(T const &...fields) noexcept
86 {
87  constexpr auto num{sizeof...(fields)};
88 
89  // Size for a multi-field composite includes room for...
90  // + opening parenthesis
91  // + field budgets
92  // + separating comma per field
93  // - comma after final field
94  // + closing parenthesis
95  // + terminating zero
96 
97  if constexpr (sizeof...(fields) == 0)
98  return std::size(pqxx::internal::empty_composite_str);
99  else
100  return 1 + (pqxx::internal::size_composite_field_buffer(fields) + ...) +
101  num + 1;
102 }
103 
104 
106 
111 template<typename... T>
112 inline char *composite_into_buf(char *begin, char *end, T const &...fields)
113 {
114  if (std::size_t(end - begin) < composite_size_buffer(fields...))
115  throw conversion_error{
116  "Buffer space may not be enough to represent composite value."};
117 
118  constexpr auto num_fields{sizeof...(fields)};
119  if constexpr (num_fields == 0)
120  {
121  constexpr char empty[]{"()"};
122  std::memcpy(begin, empty, std::size(empty));
123  return begin + std::size(empty);
124  }
125 
126  char *pos{begin};
127  *pos++ = '(';
128 
129  (pqxx::internal::write_composite_field<T>(pos, end, fields), ...);
130 
131  // If we've got multiple fields, "backspace" that last comma.
132  if constexpr (num_fields > 1)
133  --pos;
134  *pos++ = ')';
135  *pos++ = '\0';
136  return pos;
137 }
138 } // namespace pqxx
139 #include "pqxx/internal/compiler-internal-post.hxx"
140 #endif
pqxx::conversion_error
Value conversion failed, e.g. when converting "Hello" to int.
Definition: except.hxx:179
pqxx
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:26
pqxx::composite_size_buffer
std::size_t composite_size_buffer(T const &...fields) noexcept
Estimate the buffer size needed to represent a value of a composite type.
Definition: composite.hxx:85
pqxx::parse_composite
void parse_composite(pqxx::internal::encoding_group enc, std::string_view text, T &...fields)
Parse a string representation of a value of a composite type.
Definition: composite.hxx:33
pqxx::internal
Internal items for libpqxx' own use. Do not use these yourself.
Definition: composite.hxx:74
pqxx::internal::get_glyph_scanner
PQXX_PURE glyph_scanner_func * get_glyph_scanner(encoding_group enc)
Definition: encodings.cxx:670
pqxx::composite_into_buf
char * composite_into_buf(char *begin, char *end, T const &...fields)
Render a series of values as a single composite SQL value.
Definition: composite.hxx:112
pqxx::internal::empty_composite_str
constexpr char empty_composite_str[]
Definition: composite.hxx:75