1 #if !defined(PQXX_ARRAY_COMPOSITE_HXX)
2 # define PQXX_ARRAY_COMPOSITE_HXX
25 template<encoding_group ENC>
29 assert(input[pos] ==
'"');
30 auto const sz{std::size(input)};
50 else if (input[pos] ==
'"')
57 "Unexpected end of string: double double-quote."};
74 if ((input[pos] ==
'\\') or (input[pos] ==
'"'))
82 "Unexpected end of string: escape sequence.", loc};
94 "Missing closing double-quote: " + std::string{input}, loc};
104 template<encoding_group ENC>
109 auto const end{std::size(input)};
110 assert((end - pos) > 1);
111 assert(input[end - 1] ==
'"');
116 output.reserve(std::size_t(end - pos - 2));
118 auto const closing_quote{end - 1};
121 assert(pos < closing_quote);
122 assert(input[pos] ==
'"');
124 assert(pos <= closing_quote);
129 assert(input[closing_quote] ==
'"');
131 while (pos < closing_quote)
134 output.append(input.substr(pos, next - pos));
136 assert(pos <= closing_quote);
137 assert((input[pos] ==
'"') or (input[pos] ==
'\\'));
139 if (pos >= closing_quote)
148 assert(pos < closing_quote);
150 if ((input[pos] ==
'"') or (input[pos] ==
'\\'))
154 output.push_back(input[pos]);
163 assert(pos == closing_quote);
191 template<encoding_group ENC>
195 return input.substr(pos);
223 template<encoding_group ENC,
typename T>
225 std::size_t &index, std::string_view input, std::size_t &pos, T &
field,
226 std::size_t last_field,
sl loc)
228 assert(index <= last_field);
229 assert(pos < std::size(input));
239 if constexpr (has_null<T>())
240 field = make_null<T>();
244 "Can't read composite field {}: C++ type {} does not support nulls.",
250 auto const stop{scan_double_quoted_string<ENC>(input, pos, loc)};
253 parse_double_quoted_string<ENC>(input.substr(0, stop), pos, loc)};
263 auto const stop{scan_unquoted_string<ENC, ',', ')', ']'>(input, pos, loc)};
265 field = from_string<T>(input.substr(pos, stop - pos), c);
273 if (index < last_field)
276 if (input[pos] !=
',')
279 "Found '{}' in composite value where comma was expected: '{}.",
287 if (input[pos] ==
',')
290 "Composite value contained more fields than the expected {}: '{}'.",
291 to_string(last_field, c), std::data(input)),
293 if (input[pos] !=
')' and input[pos] !=
']')
296 "Composite value has unexpected characters where closing "
298 "was expected: '{}'.",
304 if (pos != std::size(input))
307 "Composite value has unexpected text after closing parenthesis: "
319 std::size_t &index, std::string_view input, std::size_t &pos, T &
field,
320 std::size_t last_field,
sl loc);
332 "Tried to parse array/composite without knowing its text encoding.",
336 return parse_composite_field<encoding_group::ascii_safe>;
338 return parse_composite_field<encoding_group::two_tier>;
340 return parse_composite_field<encoding_group::gb18030>;
342 return parse_composite_field<encoding_group::sjis>;
374 std::span<char> buf, std::size_t &pos, T
const &
field,
ctx c)
388 assert(budget < std::size(buf));
393 for (
char const x :
to_buf(buf.last(budget),
field, c))
395 if ((x ==
'"') or (x ==
'\\'))
416 template<nonbinary_range TYPE>
418 std::span<char> buf, TYPE
const &value, std::size_t budget,
ctx c)
420 using elt_type = std::remove_cvref_t<value_type<TYPE>>;
422 if (std::cmp_less(std::size(buf), budget))
424 "Not enough buffer space to convert array to string.", c.loc};
426 std::size_t here{0u};
430 bool nonempty{
false};
431 for (
auto const &elt : value)
433 static constexpr
zview s_null{
"NULL"};
436 here = copy_chars<false>(s_null, buf, here, c.loc);
438 else if constexpr (is_sql_array<elt_type>)
443 else if constexpr (is_unquoted_safe<elt_type>)
459 assert(std::cmp_less(elt_budget, sz - here));
460 auto const from{
pqxx::to_buf(buf.last(elt_budget), elt, c)};
461 auto const end{std::size(from)};
469 auto next{find(from, i, c.loc)};
471 copy_chars<false>({std::data(from) + i, next - i}, buf, here, c.loc);
482 buf[here++] = from[next++];
488 copy_chars<false>({std::data(from) + i, end - i}, buf, here, c.loc);
494 buf[here++] = array_separator<elt_type>;
Reference to a field in a result set.
Definition: field.hxx:309
Marker-type wrapper: zero-terminated std::string_view.
Definition: zview.hxx:55
Invalid argument passed to libpqxx, similar to std::invalid_argument.
Definition: except.hxx:599
Value conversion failed, e.g. when converting "Hello" to int.
Definition: except.hxx:612
Could not convert value to string: not enough buffer space.
Definition: except.hxx:638
Internal error in libpqxx library.
Definition: except.hxx:558
Error in usage of libpqxx library, similar to std::logic_error.
Definition: except.hxx:580
Private namespace for libpqxx's internal use; do not access.
Definition: connection.cxx:333
PQXX_INLINE_ONLY void write_composite_field(std::span< char > buf, std::size_t &pos, T const &field, ctx c)
Definition: array-composite.hxx:373
PQXX_INLINE_COV void parse_composite_field(std::size_t &index, std::string_view input, std::size_t &pos, T &field, std::size_t last_field, sl loc)
Parse a field of a composite-type value.
Definition: array-composite.hxx:224
PQXX_INLINE_COV std::size_t size_composite_field_buffer(T const &field)
Conservatively estimate buffer size needed for a composite field.
Definition: array-composite.hxx:352
PQXX_PURE PQXX_RETURNS_NONNULL constexpr PQXX_INLINE_COV char_finder_func * get_char_finder(encoding_group enc, sl loc)
Look up a character search function for an encoding group.
Definition: encodings.hxx:310
void(*)(std::size_t &index, std::string_view input, std::size_t &pos, T &field, std::size_t last_field, sl loc) composite_field_parser
Pointer to an encoding-specific specialisation of parse_composite_field.
Definition: array-composite.hxx:320
constexpr PQXX_INLINE_COV composite_field_parser< T > specialize_parse_composite_field(conversion_context const &c)
Look up implementation of parse_composite_field for ENC.
Definition: array-composite.hxx:326
constexpr PQXX_INLINE_ONLY std::string_view parse_unquoted_string(std::string_view input, std::size_t pos, sl)
Parse an unquoted array entry or cfield of a composite-type field.
Definition: array-composite.hxx:193
constexpr std::size_t one_ascii_char
Definition: array-composite.hxx:14
constexpr PQXX_INLINE_COV std::string parse_double_quoted_string(std::string_view input, std::size_t pos, sl loc)
Un-quote and un-escape a double-quoted SQL string.
Definition: array-composite.hxx:106
constexpr PQXX_INLINE_COV std::size_t scan_unquoted_string(std::string_view input, std::size_t pos, sl loc)
Find the end of an unquoted string in an array or composite-type value.
Definition: array-composite.hxx:179
PQXX_INLINE_COV std::size_t array_into_buf(std::span< char > buf, TYPE const &value, std::size_t budget, ctx c)
Write an SQL array representation into buf.
Definition: array-composite.hxx:417
constexpr PQXX_INLINE_COV std::size_t find_ascii_char(std::string_view haystack, std::size_t here, sl loc)
Find any of the ASCII characters in NEEDLE in haystack.
Definition: encodings.hxx:108
constexpr PQXX_INLINE_COV std::size_t scan_double_quoted_string(std::string_view input, std::size_t pos, sl loc)
Definition: array-composite.hxx:27
std::string_view to_buf(std::span< char > buf, TYPE const &value, ctx c={})
Represent value as SQL text, optionally using buf as storage.
Definition: strconv.hxx:430
std::source_location sl
Convenience alias for std::source_location. It's just too long.
Definition: types.hxx:38
PQXX_LIBEXPORT std::string to_string(field_ref const &value, ctx)
Convert a field_ref to a string.
Definition: field.hxx:891
constexpr bool is_unquoted_safe< T >
Definition: conversions.hxx:244
encoding_group
Definition: encoding_group.hxx:40
@ two_tier
Low byte is ASCII, high byte starts a 2-byte character.
@ sjis
Non-ASCII-safe: Japanese JIS and Shift JIS.
@ unknown
Default: indeterminate encoding. All we know is it supports ASCII.
@ ascii_safe
"ASCII-safe" encodings.
@ gb18030
Non-ASCII-safe: GB18030 for Chinese (Traditional & Simplified).
constexpr 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:399
constexpr bool is_null(TYPE const &value) noexcept
Is value a null?
Definition: strconv.hxx:764
std::size_t into_buf(std::span< char > buf, TYPE const &value, ctx c={})
Write an SQL representation of value into buf.
Definition: strconv.hxx:454
conversion_context const & ctx
Convenience alias: const reference to a pqxx::conversion_context.
Definition: strconv.hxx:201
format
Format code: is data text or binary?
Definition: types.hxx:121
Contextual parameters for string conversions implementations.
Definition: strconv.hxx:163
sl loc
A std::source_location for the call.
Definition: strconv.hxx:183
encoding_group enc
Encoding group describing the client text encoding.
Definition: strconv.hxx:172