binarystring.hxx 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /* Deprecated representation for raw, binary data.
  2. *
  3. * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/binarystring 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_BINARYSTRING
  12. #define PQXX_H_BINARYSTRING
  13. #if !defined(PQXX_HEADER_PRE)
  14. # error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
  15. #endif
  16. #include <memory>
  17. #include <string>
  18. #include <string_view>
  19. #include "pqxx/result.hxx"
  20. #include "pqxx/strconv.hxx"
  21. namespace pqxx
  22. {
  23. class binarystring;
  24. template<> struct string_traits<binarystring>;
  25. /// Binary data corresponding to PostgreSQL's "BYTEA" binary-string type.
  26. /** @ingroup escaping-functions
  27. * @deprecated Use @c std::basic_string<std::byte> and
  28. * @c std::basic_string_view<std::byte> for binary data. In C++20 or better,
  29. * any @c contiguous_range of @c std::byte will do.
  30. *
  31. * This class represents a binary string as stored in a field of type @c bytea.
  32. *
  33. * Internally a binarystring is zero-terminated, but it may also contain null
  34. * bytes, they're just like any other byte value. So don't assume that it's
  35. * safe to treat the contents as a C-style string.
  36. *
  37. * The binarystring retains its value even if the result it was obtained from
  38. * is destroyed, but it cannot be copied or assigned.
  39. *
  40. * \relatesalso transaction_base::quote_raw
  41. *
  42. * To include a @c binarystring value in an SQL query, escape and quote it
  43. * using the transaction's @c quote_raw function.
  44. *
  45. * @warning This class is implemented as a reference-counting smart pointer.
  46. * Copying, swapping, and destroying binarystring objects that refer to the
  47. * same underlying data block is <em>not thread-safe</em>. If you wish to pass
  48. * binarystrings around between threads, make sure that each of these
  49. * operations is protected against concurrency with similar operations on the
  50. * same object, or other objects pointing to the same data block.
  51. */
  52. class PQXX_LIBEXPORT binarystring
  53. {
  54. public:
  55. using char_type = unsigned char;
  56. using value_type = std::char_traits<char_type>::char_type;
  57. using size_type = std::size_t;
  58. using difference_type = long;
  59. using const_reference = value_type const &;
  60. using const_pointer = value_type const *;
  61. using const_iterator = const_pointer;
  62. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  63. [[deprecated("Use std::byte for binary data.")]] binarystring(
  64. binarystring const &) = default;
  65. /// Read and unescape bytea field.
  66. /** The field will be zero-terminated, even if the original bytea field
  67. * isn't.
  68. * @param F the field to read; must be a bytea field
  69. */
  70. [[deprecated("Use std::byte for binary data.")]] explicit binarystring(
  71. field const &);
  72. /// Copy binary data from std::string_view on binary data.
  73. /** This is inefficient in that it copies the data to a buffer allocated on
  74. * the heap.
  75. */
  76. [[deprecated("Use std::byte for binary data.")]] explicit binarystring(
  77. std::string_view);
  78. /// Copy binary data of given length straight out of memory.
  79. [[deprecated("Use std::byte for binary data.")]] binarystring(
  80. void const *, std::size_t);
  81. /// Efficiently wrap a buffer of binary data in a @c binarystring.
  82. [[deprecated("Use std::byte for binary data.")]] binarystring(
  83. std::shared_ptr<value_type> ptr, size_type size) :
  84. m_buf{std::move(ptr)}, m_size{size}
  85. {}
  86. /// Size of converted string in bytes.
  87. [[nodiscard]] size_type size() const noexcept { return m_size; }
  88. /// Size of converted string in bytes.
  89. [[nodiscard]] size_type length() const noexcept { return size(); }
  90. [[nodiscard]] bool empty() const noexcept { return size() == 0; }
  91. [[nodiscard]] const_iterator begin() const noexcept { return data(); }
  92. [[nodiscard]] const_iterator cbegin() const noexcept { return begin(); }
  93. [[nodiscard]] const_iterator end() const noexcept { return data() + m_size; }
  94. [[nodiscard]] const_iterator cend() const noexcept { return end(); }
  95. [[nodiscard]] const_reference front() const noexcept { return *begin(); }
  96. [[nodiscard]] const_reference back() const noexcept
  97. {
  98. return *(data() + m_size - 1);
  99. }
  100. [[nodiscard]] const_reverse_iterator rbegin() const
  101. {
  102. return const_reverse_iterator{end()};
  103. }
  104. [[nodiscard]] const_reverse_iterator crbegin() const { return rbegin(); }
  105. [[nodiscard]] const_reverse_iterator rend() const
  106. {
  107. return const_reverse_iterator{begin()};
  108. }
  109. [[nodiscard]] const_reverse_iterator crend() const { return rend(); }
  110. /// Unescaped field contents.
  111. [[nodiscard]] value_type const *data() const noexcept { return m_buf.get(); }
  112. [[nodiscard]] const_reference operator[](size_type i) const noexcept
  113. {
  114. return data()[i];
  115. }
  116. [[nodiscard]] PQXX_PURE bool operator==(binarystring const &) const noexcept;
  117. [[nodiscard]] bool operator!=(binarystring const &rhs) const noexcept
  118. {
  119. return not operator==(rhs);
  120. }
  121. binarystring &operator=(binarystring const &);
  122. /// Index contained string, checking for valid index.
  123. const_reference at(size_type) const;
  124. /// Swap contents with other binarystring.
  125. void swap(binarystring &);
  126. /// Raw character buffer (no terminating zero is added).
  127. /** @warning No terminating zero is added! If the binary data did not end in
  128. * a null character, you will not find one here.
  129. */
  130. [[nodiscard]] char const *get() const noexcept
  131. {
  132. return reinterpret_cast<char const *>(m_buf.get());
  133. }
  134. /// Read contents as a std::string_view.
  135. [[nodiscard]] std::string_view view() const noexcept
  136. {
  137. return std::string_view(get(), size());
  138. }
  139. /// Read as regular C++ string (may include null characters).
  140. /** This creates and returns a new string object. Don't call this
  141. * repeatedly; retrieve your string once and keep it in a local variable.
  142. * Also, do not expect to be able to compare the string's address to that of
  143. * an earlier invocation.
  144. */
  145. [[nodiscard]] std::string str() const;
  146. /// Access data as a pointer to @c std::byte.
  147. [[nodiscard]] std::byte const *bytes() const
  148. {
  149. return reinterpret_cast<std::byte const *>(get());
  150. }
  151. /// Read data as a @c std::basic_string_view<std::byte>.
  152. [[nodiscard]] std::basic_string_view<std::byte> bytes_view() const
  153. {
  154. return std::basic_string_view<std::byte>{bytes(), size()};
  155. }
  156. private:
  157. std::shared_ptr<value_type> m_buf;
  158. size_type m_size{0};
  159. };
  160. template<> struct nullness<binarystring> : no_null<binarystring>
  161. {};
  162. /// String conversion traits for @c binarystring.
  163. /** Defines the conversions between a @c binarystring and its PostgreSQL
  164. * textual format, for communication with the database.
  165. *
  166. * These conversions rely on the "hex" format which was introduced in
  167. * PostgreSQL 9.0. Both your libpq and the server must be recent enough to
  168. * speak this format.
  169. */
  170. template<> struct string_traits<binarystring>
  171. {
  172. static std::size_t size_buffer(binarystring const &value) noexcept
  173. {
  174. return internal::size_esc_bin(std::size(value));
  175. }
  176. static zview to_buf(char *begin, char *end, binarystring const &value)
  177. {
  178. return generic_to_buf(begin, end, value);
  179. }
  180. static char *into_buf(char *begin, char *end, binarystring const &value)
  181. {
  182. auto const budget{size_buffer(value)};
  183. if (internal::cmp_less(end - begin, budget))
  184. throw conversion_overrun{
  185. "Not enough buffer space to escape binary data."};
  186. std::string_view text{value.view()};
  187. internal::esc_bin(binary_cast(text), begin);
  188. return begin + budget;
  189. }
  190. static binarystring from_string(std::string_view text)
  191. {
  192. auto const size{pqxx::internal::size_unesc_bin(std::size(text))};
  193. std::shared_ptr<unsigned char> buf{
  194. new unsigned char[size], [](unsigned char const *x) { delete[] x; }};
  195. pqxx::internal::unesc_bin(text, reinterpret_cast<std::byte *>(buf.get()));
  196. #include "pqxx/internal/ignore-deprecated-pre.hxx"
  197. return binarystring{std::move(buf), size};
  198. #include "pqxx/internal/ignore-deprecated-post.hxx"
  199. }
  200. };
  201. } // namespace pqxx
  202. #endif