1#if !defined(PQXX_ARRAY_COMPOSITE_HXX)
2# define PQXX_ARRAY_COMPOSITE_HXX
6# include "pqxx/internal/encodings.hxx"
7# include "pqxx/strconv.hxx"
19template<encoding_group ENC>
21 char const input[], std::size_t size, std::size_t pos)
25 auto next{scanner::call(input, size, pos)};
26 PQXX_ASSUME(next > pos);
29 next = scanner::call(input, size, pos);
30 PQXX_ASSUME(next > pos);
35 if (next - pos == 1 and input[pos] ==
'"')
48 else if (next - pos == 1)
55 next = scanner::call(input, size, pos);
56 PQXX_ASSUME(next > pos);
71 next = scanner::call(input, size, pos);
72 PQXX_ASSUME(next > pos);
76 "Missing closing double-quote: " + std::string{input}};
83template<encoding_group ENC>
85 char const input[], std::size_t end, std::size_t pos)
91 output.reserve(std::size_t(end - pos - 2));
95 auto here{scanner::call(input, end, pos)},
96 next{scanner::call(input, end, here)};
97 PQXX_ASSUME(here > pos);
98 PQXX_ASSUME(next > here);
99 while (here < end - 1)
105 if ((next - here == 1) and (input[here] ==
'\\' or input[here] ==
'"'))
109 next = scanner::call(input, end, here);
110 PQXX_ASSUME(next > here);
112 output.append(input + here, input + next);
114 next = scanner::call(input, end, here);
115 PQXX_ASSUME(next > here);
129template<pqxx::internal::encoding_group ENC,
char... STOP>
134 auto next{scanner::call(input, size, pos)};
135 PQXX_ASSUME(next > pos);
136 while ((pos < size) and ((next - pos) > 1 or ((input[pos] != STOP) and ...)))
139 next = scanner::call(input, size, pos);
140 PQXX_ASSUME(next > pos);
148template<pqxx::
internal::encoding_group ENC>
152 return {&input[pos], end - pos};
180template<encoding_group ENC,
typename T>
182 std::size_t &index, std::string_view input, std::size_t &pos, T &field,
183 std::size_t last_field)
185 assert(index <= last_field);
187 PQXX_ASSUME(next > pos);
188 if ((next - pos) != 1)
202 "Can't read composite field " + to_string(index) +
": C++ type " +
209 PQXX_ASSUME(stop > pos);
219 std::data(input), std::size(input), pos)};
220 PQXX_ASSUME(stop >= pos);
222 from_string<T>(std::string_view{std::data(input) + pos, stop - pos});
230 PQXX_ASSUME(next > pos);
232 if ((next - pos) != 1)
234 "Unexpected non-ASCII character after composite field: " +
237 if (index < last_field)
239 if (input[pos] !=
',')
241 "Found '" + std::string{input[pos]} +
242 "' in composite value where comma was expected: " + std::data(input)};
246 if (input[pos] ==
',')
248 "Composite value contained more fields than the expected " +
249 to_string(last_field) +
": " + std::data(input)};
250 if (input[pos] !=
')' and input[pos] !=
']')
252 "Composite value has unexpected characters where closing parenthesis "
255 if (next != std::size(input))
257 "Composite value has unexpected text after closing parenthesis: " +
269 std::size_t &index, std::string_view input, std::size_t &pos, T &field,
270 std::size_t last_field);
279 case encoding_group::MONOBYTE:
281 case encoding_group::BIG5:
283 case encoding_group::EUC_CN:
285 case encoding_group::EUC_JP:
287 case encoding_group::EUC_KR:
289 case encoding_group::EUC_TW:
291 case encoding_group::GB18030:
294 case encoding_group::JOHAB:
296 case encoding_group::MULE_INTERNAL:
298 case encoding_group::SJIS:
301 case encoding_group::UTF8:
331inline void write_composite_field(
char *&pos,
char *end, T
const &field)
348 for (
char const c : string_traits<T>::
to_buf(end - budget, end, field))
350 if ((c ==
'"') or (c ==
'\\'))
Invalid argument passed to libpqxx, similar to std::invalid_argument.
Definition except.hxx:266
Value conversion failed, e.g. when converting "Hello" to int.
Definition except.hxx:283
Internal error in libpqxx library.
Definition except.hxx:242
Internal items for libpqxx' own use. Do not use these yourself.
Definition encodings.cxx:33
std::string concat(TYPE... item)
Efficiently combine a bunch of items into one big string.
Definition concat.hxx:31
void parse_composite_field(std::size_t &index, std::string_view input, std::size_t &pos, T &field, std::size_t last_field)
Parse a field of a composite-type value.
Definition array-composite.hxx:181
std::size_t size_composite_field_buffer(T const &field)
Conservatively estimate buffer size needed for a composite field.
Definition array-composite.hxx:310
std::string parse_unquoted_string(char const input[], std::size_t end, std::size_t pos)
Parse an unquoted array entry or cfield of a composite-type field.
Definition array-composite.hxx:150
std::size_t scan_double_quoted_string(char const input[], std::size_t size, std::size_t pos)
Definition array-composite.hxx:20
std::size_t scan_unquoted_string(char const input[], std::size_t size, std::size_t pos)
Find the end of an unquoted string in an array or composite-type value.
Definition array-composite.hxx:131
composite_field_parser< T > specialize_parse_composite_field(encoding_group enc)
Look up implementation of parse_composite_field for ENC.
Definition array-composite.hxx:275
std::string parse_double_quoted_string(char const input[], std::size_t end, std::size_t pos)
Un-quote and un-escape a double-quoted SQL string.
Definition array-composite.hxx:84
void(*)( std::size_t &index, std::string_view input, std::size_t &pos, T &field, std::size_t last_field) composite_field_parser
Pointer to an encoding-specific specialisation of parse_composite_field.
Definition array-composite.hxx:268
std::string const type_name
A human-readable name for a type, used in error messages and such.
Definition strconv.hxx:80
std::vector< std::string_view > to_buf(char *here, char const *end, TYPE... value)
Convert multiple values to strings inside a single buffer.
Definition strconv.hxx:492
std::size_t size_buffer(TYPE const &...value) noexcept
Estimate how much buffer space is needed to represent values as a string.
Definition strconv.hxx:525
T from_string(field const &value)
Convert a field's value to type T.
Definition field.hxx:532
constexpr bool is_unquoted_safe
Can we use this type in arrays and composite types without quoting them?
Definition strconv.hxx:554
Wrapper struct template for "find next glyph" functions.
Definition encodings.hxx:143
static PQXX_PURE std::size_t call(char const buffer[], std::size_t buffer_len, std::size_t start)
Find the next glyph in buffer after position start.
Traits describing a type's "null value," if any.
Definition strconv.hxx:91
static char * into_buf(char *begin, char *end, TYPE const &value)
Write value's string representation into buffer at begin.