| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- /* Deprecated representation for raw, binary data.
- *
- * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/binarystring instead.
- *
- * Copyright (c) 2000-2022, Jeroen T. Vermeulen.
- *
- * See COPYING for copyright license. If you did not receive a file called
- * COPYING with this source code, please notify the distributor of this
- * mistake, or contact the author.
- */
- #ifndef PQXX_H_BINARYSTRING
- #define PQXX_H_BINARYSTRING
- #if !defined(PQXX_HEADER_PRE)
- # error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
- #endif
- #include <memory>
- #include <string>
- #include <string_view>
- #include "pqxx/result.hxx"
- #include "pqxx/strconv.hxx"
- namespace pqxx
- {
- class binarystring;
- template<> struct string_traits<binarystring>;
- /// Binary data corresponding to PostgreSQL's "BYTEA" binary-string type.
- /** @ingroup escaping-functions
- * @deprecated Use @c std::basic_string<std::byte> and
- * @c std::basic_string_view<std::byte> for binary data. In C++20 or better,
- * any @c contiguous_range of @c std::byte will do.
- *
- * This class represents a binary string as stored in a field of type @c bytea.
- *
- * Internally a binarystring is zero-terminated, but it may also contain null
- * bytes, they're just like any other byte value. So don't assume that it's
- * safe to treat the contents as a C-style string.
- *
- * The binarystring retains its value even if the result it was obtained from
- * is destroyed, but it cannot be copied or assigned.
- *
- * \relatesalso transaction_base::quote_raw
- *
- * To include a @c binarystring value in an SQL query, escape and quote it
- * using the transaction's @c quote_raw function.
- *
- * @warning This class is implemented as a reference-counting smart pointer.
- * Copying, swapping, and destroying binarystring objects that refer to the
- * same underlying data block is <em>not thread-safe</em>. If you wish to pass
- * binarystrings around between threads, make sure that each of these
- * operations is protected against concurrency with similar operations on the
- * same object, or other objects pointing to the same data block.
- */
- class PQXX_LIBEXPORT binarystring
- {
- public:
- using char_type = unsigned char;
- using value_type = std::char_traits<char_type>::char_type;
- using size_type = std::size_t;
- using difference_type = long;
- using const_reference = value_type const &;
- using const_pointer = value_type const *;
- using const_iterator = const_pointer;
- using const_reverse_iterator = std::reverse_iterator<const_iterator>;
- [[deprecated("Use std::byte for binary data.")]] binarystring(
- binarystring const &) = default;
- /// Read and unescape bytea field.
- /** The field will be zero-terminated, even if the original bytea field
- * isn't.
- * @param F the field to read; must be a bytea field
- */
- [[deprecated("Use std::byte for binary data.")]] explicit binarystring(
- field const &);
- /// Copy binary data from std::string_view on binary data.
- /** This is inefficient in that it copies the data to a buffer allocated on
- * the heap.
- */
- [[deprecated("Use std::byte for binary data.")]] explicit binarystring(
- std::string_view);
- /// Copy binary data of given length straight out of memory.
- [[deprecated("Use std::byte for binary data.")]] binarystring(
- void const *, std::size_t);
- /// Efficiently wrap a buffer of binary data in a @c binarystring.
- [[deprecated("Use std::byte for binary data.")]] binarystring(
- std::shared_ptr<value_type> ptr, size_type size) :
- m_buf{std::move(ptr)}, m_size{size}
- {}
- /// Size of converted string in bytes.
- [[nodiscard]] size_type size() const noexcept { return m_size; }
- /// Size of converted string in bytes.
- [[nodiscard]] size_type length() const noexcept { return size(); }
- [[nodiscard]] bool empty() const noexcept { return size() == 0; }
- [[nodiscard]] const_iterator begin() const noexcept { return data(); }
- [[nodiscard]] const_iterator cbegin() const noexcept { return begin(); }
- [[nodiscard]] const_iterator end() const noexcept { return data() + m_size; }
- [[nodiscard]] const_iterator cend() const noexcept { return end(); }
- [[nodiscard]] const_reference front() const noexcept { return *begin(); }
- [[nodiscard]] const_reference back() const noexcept
- {
- return *(data() + m_size - 1);
- }
- [[nodiscard]] const_reverse_iterator rbegin() const
- {
- return const_reverse_iterator{end()};
- }
- [[nodiscard]] const_reverse_iterator crbegin() const { return rbegin(); }
- [[nodiscard]] const_reverse_iterator rend() const
- {
- return const_reverse_iterator{begin()};
- }
- [[nodiscard]] const_reverse_iterator crend() const { return rend(); }
- /// Unescaped field contents.
- [[nodiscard]] value_type const *data() const noexcept { return m_buf.get(); }
- [[nodiscard]] const_reference operator[](size_type i) const noexcept
- {
- return data()[i];
- }
- [[nodiscard]] PQXX_PURE bool operator==(binarystring const &) const noexcept;
- [[nodiscard]] bool operator!=(binarystring const &rhs) const noexcept
- {
- return not operator==(rhs);
- }
- binarystring &operator=(binarystring const &);
- /// Index contained string, checking for valid index.
- const_reference at(size_type) const;
- /// Swap contents with other binarystring.
- void swap(binarystring &);
- /// Raw character buffer (no terminating zero is added).
- /** @warning No terminating zero is added! If the binary data did not end in
- * a null character, you will not find one here.
- */
- [[nodiscard]] char const *get() const noexcept
- {
- return reinterpret_cast<char const *>(m_buf.get());
- }
- /// Read contents as a std::string_view.
- [[nodiscard]] std::string_view view() const noexcept
- {
- return std::string_view(get(), size());
- }
- /// Read as regular C++ string (may include null characters).
- /** This creates and returns a new string object. Don't call this
- * repeatedly; retrieve your string once and keep it in a local variable.
- * Also, do not expect to be able to compare the string's address to that of
- * an earlier invocation.
- */
- [[nodiscard]] std::string str() const;
- /// Access data as a pointer to @c std::byte.
- [[nodiscard]] std::byte const *bytes() const
- {
- return reinterpret_cast<std::byte const *>(get());
- }
- /// Read data as a @c std::basic_string_view<std::byte>.
- [[nodiscard]] std::basic_string_view<std::byte> bytes_view() const
- {
- return std::basic_string_view<std::byte>{bytes(), size()};
- }
- private:
- std::shared_ptr<value_type> m_buf;
- size_type m_size{0};
- };
- template<> struct nullness<binarystring> : no_null<binarystring>
- {};
- /// String conversion traits for @c binarystring.
- /** Defines the conversions between a @c binarystring and its PostgreSQL
- * textual format, for communication with the database.
- *
- * These conversions rely on the "hex" format which was introduced in
- * PostgreSQL 9.0. Both your libpq and the server must be recent enough to
- * speak this format.
- */
- template<> struct string_traits<binarystring>
- {
- static std::size_t size_buffer(binarystring const &value) noexcept
- {
- return internal::size_esc_bin(std::size(value));
- }
- static zview to_buf(char *begin, char *end, binarystring const &value)
- {
- return generic_to_buf(begin, end, value);
- }
- static char *into_buf(char *begin, char *end, binarystring const &value)
- {
- auto const budget{size_buffer(value)};
- if (internal::cmp_less(end - begin, budget))
- throw conversion_overrun{
- "Not enough buffer space to escape binary data."};
- std::string_view text{value.view()};
- internal::esc_bin(binary_cast(text), begin);
- return begin + budget;
- }
- static binarystring from_string(std::string_view text)
- {
- auto const size{pqxx::internal::size_unesc_bin(std::size(text))};
- std::shared_ptr<unsigned char> buf{
- new unsigned char[size], [](unsigned char const *x) { delete[] x; }};
- pqxx::internal::unesc_bin(text, reinterpret_cast<std::byte *>(buf.get()));
- #include "pqxx/internal/ignore-deprecated-pre.hxx"
- return binarystring{std::move(buf), size};
- #include "pqxx/internal/ignore-deprecated-post.hxx"
- }
- };
- } // namespace pqxx
- #endif
|