array.hxx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /* Handling of SQL arrays.
  2. *
  3. * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/field instead.
  4. *
  5. * Copyright (c) 2000-2022, Jeroen T. Vermeulen.
  6. *
  7. * See COPYING for copyright license. If you did not receive a file called
  8. * COPYING with this source code, please notify the distributor of this
  9. * mistake, or contact the author.
  10. */
  11. #ifndef PQXX_H_ARRAY
  12. #define PQXX_H_ARRAY
  13. #if !defined(PQXX_HEADER_PRE)
  14. # error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
  15. #endif
  16. #include <stdexcept>
  17. #include <string>
  18. #include <utility>
  19. #include "pqxx/internal/encoding_group.hxx"
  20. #include "pqxx/internal/encodings.hxx"
  21. namespace pqxx
  22. {
  23. /// Low-level array parser.
  24. /** Use this to read an array field retrieved from the database.
  25. *
  26. * This parser will only work reliably if your client encoding is UTF-8, ASCII,
  27. * or a single-byte encoding which is a superset of ASCII (such as Latin-1).
  28. *
  29. * Also, the parser only supports array element types which use either a comma
  30. * or a semicolon ("," or ";") as the separator between array elements. All
  31. * built-in types use comma, except for one which uses semicolon, but some
  32. * custom types may not work.
  33. *
  34. * The input is a C-style string containing the textual representation of an
  35. * array, as returned by the database. The parser reads this representation
  36. * on the fly. The string must remain in memory until parsing is done.
  37. *
  38. * Parse the array by making calls to @ref get_next until it returns a
  39. * @ref juncture of "done". The @ref juncture tells you what the parser found
  40. * in that step: did the array "nest" to a deeper level, or "un-nest" back up?
  41. */
  42. class PQXX_LIBEXPORT array_parser
  43. {
  44. public:
  45. /// What's the latest thing found in the array?
  46. enum class juncture
  47. {
  48. /// Starting a new row.
  49. row_start,
  50. /// Ending the current row.
  51. row_end,
  52. /// Found a NULL value.
  53. null_value,
  54. /// Found a string value.
  55. string_value,
  56. /// Parsing has completed.
  57. done,
  58. };
  59. // TODO: constexpr noexcept. Breaks ABI.
  60. /// Constructor. You don't need this; use @ref field::as_array instead.
  61. /** The parser only remains valid while the data underlying the @ref result
  62. * remains valid. Once all `result` objects referring to that data have been
  63. * destroyed, the parser will no longer refer to valid memory.
  64. */
  65. explicit array_parser(
  66. std::string_view input,
  67. internal::encoding_group = internal::encoding_group::MONOBYTE);
  68. /// Parse the next step in the array.
  69. /** Returns what it found. If the juncture is @ref juncture::string_value,
  70. * the string will contain the value. Otherwise, it will be empty.
  71. *
  72. * Call this until the @ref array_parser::juncture it returns is
  73. * @ref juncture::done.
  74. */
  75. std::pair<juncture, std::string> get_next();
  76. private:
  77. std::string_view m_input;
  78. internal::glyph_scanner_func *const m_scan;
  79. /// Current parsing position in the input.
  80. std::string::size_type m_pos = 0u;
  81. std::string::size_type scan_single_quoted_string() const;
  82. std::string parse_single_quoted_string(std::string::size_type end) const;
  83. std::string::size_type scan_double_quoted_string() const;
  84. std::string parse_double_quoted_string(std::string::size_type end) const;
  85. std::string::size_type scan_unquoted_string() const;
  86. std::string parse_unquoted_string(std::string::size_type end) const;
  87. std::string::size_type scan_glyph(std::string::size_type pos) const;
  88. std::string::size_type
  89. scan_glyph(std::string::size_type pos, std::string::size_type end) const;
  90. };
  91. } // namespace pqxx
  92. #endif