detail/buffer.hpp

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