buffer.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. //
  2. // Copyright (c) 2019 Vinnie Falco ([email protected])
  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. // Official repository: https://github.com/boostorg/json
  8. //
  9. #ifndef BOOST_JSON_DETAIL_BUFFER_HPP
  10. #define BOOST_JSON_DETAIL_BUFFER_HPP
  11. #include <boost/json/detail/config.hpp>
  12. #include <boost/json/string_view.hpp>
  13. #include <cstring>
  14. namespace boost {
  15. namespace json {
  16. namespace detail {
  17. // A simple string-like temporary static buffer
  18. template<std::size_t N>
  19. class buffer
  20. {
  21. public:
  22. using size_type = std::size_t;
  23. buffer() = default;
  24. bool
  25. empty() const noexcept
  26. {
  27. return size_ == 0;
  28. }
  29. string_view
  30. get() const noexcept
  31. {
  32. return {buf_, size_};
  33. }
  34. operator string_view() const noexcept
  35. {
  36. return get();
  37. }
  38. char const*
  39. data() const noexcept
  40. {
  41. return buf_;
  42. }
  43. size_type
  44. size() const noexcept
  45. {
  46. return size_;
  47. }
  48. size_type
  49. capacity() const noexcept
  50. {
  51. return N - size_;
  52. }
  53. size_type
  54. max_size() const noexcept
  55. {
  56. return N;
  57. }
  58. void
  59. clear() noexcept
  60. {
  61. size_ = 0;
  62. }
  63. void
  64. push_back(char ch) noexcept
  65. {
  66. BOOST_ASSERT(capacity() > 0);
  67. buf_[size_++] = ch;
  68. }
  69. // append an unescaped string
  70. void
  71. append(
  72. char const* s,
  73. size_type n)
  74. {
  75. BOOST_ASSERT(n <= N - size_);
  76. std::memcpy(buf_ + size_, s, n);
  77. size_ += n;
  78. }
  79. // append valid 32-bit code point as utf8
  80. void
  81. append_utf8(
  82. unsigned long cp) noexcept
  83. {
  84. auto dest = buf_ + size_;
  85. if(cp < 0x80)
  86. {
  87. BOOST_ASSERT(size_ <= N - 1);
  88. dest[0] = static_cast<char>(cp);
  89. size_ += 1;
  90. return;
  91. }
  92. if(cp < 0x800)
  93. {
  94. BOOST_ASSERT(size_ <= N - 2);
  95. dest[0] = static_cast<char>( (cp >> 6) | 0xc0);
  96. dest[1] = static_cast<char>( (cp & 0x3f) | 0x80);
  97. size_ += 2;
  98. return;
  99. }
  100. if(cp < 0x10000)
  101. {
  102. BOOST_ASSERT(size_ <= N - 3);
  103. dest[0] = static_cast<char>( (cp >> 12) | 0xe0);
  104. dest[1] = static_cast<char>(((cp >> 6) & 0x3f) | 0x80);
  105. dest[2] = static_cast<char>( (cp & 0x3f) | 0x80);
  106. size_ += 3;
  107. return;
  108. }
  109. {
  110. BOOST_ASSERT(size_ <= N - 4);
  111. dest[0] = static_cast<char>( (cp >> 18) | 0xf0);
  112. dest[1] = static_cast<char>(((cp >> 12) & 0x3f) | 0x80);
  113. dest[2] = static_cast<char>(((cp >> 6) & 0x3f) | 0x80);
  114. dest[3] = static_cast<char>( (cp & 0x3f) | 0x80);
  115. size_ += 4;
  116. }
  117. }
  118. private:
  119. char buf_[N];
  120. size_type size_ = 0;
  121. };
  122. } // detail
  123. } // namespace json
  124. } // namespace boost
  125. #endif