field_view.ipp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. //
  2. // Copyright (c) 2019-2023 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. #ifndef BHO_MYSQL_IMPL_FIELD_VIEW_IPP
  8. #define BHO_MYSQL_IMPL_FIELD_VIEW_IPP
  9. #pragma once
  10. #include <asio2/bho/mysql/field_view.hpp>
  11. #include <asio2/bho/mysql/detail/config.hpp>
  12. #include <ostream>
  13. namespace bho {
  14. namespace mysql {
  15. namespace detail {
  16. BHO_MYSQL_STATIC_OR_INLINE
  17. std::ostream& print_blob(std::ostream& os, blob_view value)
  18. {
  19. if (value.empty())
  20. return os << "{}";
  21. char buffer[16]{};
  22. os << "{ ";
  23. for (std::size_t i = 0; i < value.size(); ++i)
  24. {
  25. if (i != 0)
  26. os << ", ";
  27. unsigned byte = value[i];
  28. std::snprintf(buffer, sizeof(buffer), "0x%02x", byte);
  29. os << buffer;
  30. }
  31. os << " }";
  32. return os;
  33. }
  34. BHO_MYSQL_STATIC_OR_INLINE
  35. std::ostream& print_time(std::ostream& os, const bho::mysql::time& value)
  36. {
  37. // Worst-case output is 26 chars, extra space just in case
  38. char buffer[64]{};
  39. using namespace std::chrono;
  40. const char* sign = value < microseconds(0) ? "-" : "";
  41. auto num_micros = value % seconds(1);
  42. auto num_secs = duration_cast<seconds>(value % minutes(1) - num_micros);
  43. auto num_mins = duration_cast<minutes>(value % hours(1) - num_secs);
  44. auto num_hours = duration_cast<hours>(value - num_mins);
  45. snprintf(
  46. buffer,
  47. sizeof(buffer),
  48. "%s%02d:%02u:%02u.%06u",
  49. sign,
  50. static_cast<int>(std::abs(num_hours.count())),
  51. static_cast<unsigned>(std::abs(num_mins.count())),
  52. static_cast<unsigned>(std::abs(num_secs.count())),
  53. static_cast<unsigned>(std::abs(num_micros.count()))
  54. );
  55. os << buffer;
  56. return os;
  57. }
  58. } // namespace detail
  59. } // namespace mysql
  60. } // namespace bho
  61. std::ostream& bho::mysql::operator<<(std::ostream& os, const field_view& value)
  62. {
  63. // Make operator<< work for detail::string_view_offset types
  64. if (value.impl_.is_string_offset() || value.impl_.is_blob_offset())
  65. {
  66. return os << "<sv_offset>";
  67. }
  68. switch (value.kind())
  69. {
  70. case field_kind::null: return os << "<NULL>";
  71. case field_kind::int64: return os << value.get_int64();
  72. case field_kind::uint64: return os << value.get_uint64();
  73. case field_kind::string: return os << value.get_string();
  74. case field_kind::blob: return detail::print_blob(os, value.get_blob());
  75. case field_kind::float_: return os << value.get_float();
  76. case field_kind::double_: return os << value.get_double();
  77. case field_kind::date: return os << value.get_date();
  78. case field_kind::datetime: return os << value.get_datetime();
  79. case field_kind::time: return detail::print_time(os, value.get_time());
  80. default: BHO_ASSERT(false); return os;
  81. }
  82. }
  83. #endif