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);
147template<pqxx::
internal::encoding_group ENC>
148inline std::string_view
151 return {&input[pos], end - pos};
179template<encoding_group ENC,
typename T>
181 std::size_t &index, std::string_view input, std::size_t &pos, T &field,
182 std::size_t last_field)
184 assert(index <= last_field);
186 PQXX_ASSUME(next > pos);
187 if ((next - pos) != 1)
201 "Can't read composite field " + to_string(index) +
": C++ type " +
202 type_name<T> +
" does not support nulls."};
207 scan_double_quoted_string<ENC>(std::data(input), std::size(input), pos)};
208 PQXX_ASSUME(stop > pos);
210 parse_double_quoted_string<ENC>(std::data(input), stop, pos)};
211 field = from_string<T>(text);
217 auto const stop{scan_unquoted_string<ENC, ',', ')', ']'>(
218 std::data(input), std::size(input), pos)};
219 PQXX_ASSUME(stop >= pos);
221 from_string<T>(std::string_view{std::data(input) + pos, stop - pos});
229 PQXX_ASSUME(next > pos);
231 if ((next - pos) != 1)
233 "Unexpected non-ASCII character after composite field: " +
236 if (index < last_field)
238 if (input[pos] !=
',')
240 "Found '" + std::string{input[pos]} +
241 "' in composite value where comma was expected: " + std::data(input)};
245 if (input[pos] ==
',')
247 "Composite value contained more fields than the expected " +
248 to_string(last_field) +
": " + std::data(input)};
249 if (input[pos] !=
')' and input[pos] !=
']')
251 "Composite value has unexpected characters where closing parenthesis "
254 if (next != std::size(input))
256 "Composite value has unexpected text after closing parenthesis: " +
268 std::size_t &index, std::string_view input, std::size_t &pos, T &field,
269 std::size_t last_field);
278 case encoding_group::MONOBYTE:
279 return parse_composite_field<encoding_group::MONOBYTE>;
280 case encoding_group::BIG5:
281 return parse_composite_field<encoding_group::BIG5>;
282 case encoding_group::EUC_CN:
283 return parse_composite_field<encoding_group::EUC_CN>;
284 case encoding_group::EUC_JP:
285 return parse_composite_field<encoding_group::EUC_JP>;
286 case encoding_group::EUC_KR:
287 return parse_composite_field<encoding_group::EUC_KR>;
288 case encoding_group::EUC_TW:
289 return parse_composite_field<encoding_group::EUC_TW>;
290 case encoding_group::GB18030:
291 return parse_composite_field<encoding_group::GB18030>;
292 case encoding_group::GBK:
return parse_composite_field<encoding_group::GBK>;
293 case encoding_group::JOHAB:
294 return parse_composite_field<encoding_group::JOHAB>;
295 case encoding_group::MULE_INTERNAL:
296 return parse_composite_field<encoding_group::MULE_INTERNAL>;
297 case encoding_group::SJIS:
298 return parse_composite_field<encoding_group::SJIS>;
299 case encoding_group::UHC:
return parse_composite_field<encoding_group::UHC>;
300 case encoding_group::UTF8:
301 return parse_composite_field<encoding_group::UTF8>;
311 if constexpr (is_unquoted_safe<T>)
330inline void write_composite_field(
char *&pos,
char *end, T
const &field)
332 if constexpr (is_unquoted_safe<T>)
347 for (
char const c : string_traits<T>::
to_buf(end - budget, end, field))
349 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:180
std::size_t size_composite_field_buffer(T const &field)
Conservatively estimate buffer size needed for a composite field.
Definition array-composite.hxx:309
std::string_view 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:149
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:274
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:267
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:493
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:526
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.