/src/boost/boost/json/detail/buffer.hpp
Line | Count | Source |
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 | 14.0k | buffer() = default; |
29 | | |
30 | | bool |
31 | | empty() const noexcept |
32 | 9.01k | { |
33 | 9.01k | return size_ == 0; |
34 | 9.01k | } |
35 | | |
36 | | string_view |
37 | | get() const noexcept |
38 | 20.6k | { |
39 | 20.6k | return {buf_, size_}; |
40 | 20.6k | } |
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 | | size() const noexcept |
55 | 41.2k | { |
56 | 41.2k | return size_; |
57 | 41.2k | } |
58 | | |
59 | | size_type |
60 | | capacity() const noexcept |
61 | 24.5M | { |
62 | 24.5M | return N - size_; |
63 | 24.5M | } |
64 | | |
65 | | size_type |
66 | | max_size() const noexcept |
67 | 22.7k | { |
68 | 22.7k | return N; |
69 | 22.7k | } |
70 | | |
71 | | void |
72 | | clear() noexcept |
73 | 8.26k | { |
74 | 8.26k | size_ = 0; |
75 | 8.26k | } |
76 | | |
77 | | void |
78 | | push_back(char ch) noexcept |
79 | 23.1M | { |
80 | 23.1M | BOOST_ASSERT(capacity() > 0); |
81 | 23.1M | buf_[size_++] = ch; |
82 | 23.1M | } |
83 | | |
84 | | // append an unescaped string |
85 | | void |
86 | | append( |
87 | | char const* s, |
88 | | size_type n) |
89 | 292k | { |
90 | 292k | BOOST_ASSERT(n <= N - size_); |
91 | 292k | std::memcpy(buf_ + size_, s, n); |
92 | 292k | size_ += n; |
93 | 292k | } |
94 | | |
95 | | // append valid 32-bit code point as utf8 |
96 | | void |
97 | | append_utf8( |
98 | | unsigned long cp) noexcept |
99 | 1.13M | { |
100 | 1.13M | auto dest = buf_ + size_; |
101 | 1.13M | if(cp < 0x80) |
102 | 329k | { |
103 | 329k | BOOST_ASSERT(size_ <= N - 1); |
104 | 329k | dest[0] = static_cast<char>(cp); |
105 | 329k | size_ += 1; |
106 | 329k | return; |
107 | 329k | } |
108 | | |
109 | 807k | if(cp < 0x800) |
110 | 326k | { |
111 | 326k | BOOST_ASSERT(size_ <= N - 2); |
112 | 326k | dest[0] = static_cast<char>( (cp >> 6) | 0xc0); |
113 | 326k | dest[1] = static_cast<char>( (cp & 0x3f) | 0x80); |
114 | 326k | size_ += 2; |
115 | 326k | return; |
116 | 326k | } |
117 | | |
118 | 481k | if(cp < 0x10000) |
119 | 452k | { |
120 | 452k | BOOST_ASSERT(size_ <= N - 3); |
121 | 452k | dest[0] = static_cast<char>( (cp >> 12) | 0xe0); |
122 | 452k | dest[1] = static_cast<char>(((cp >> 6) & 0x3f) | 0x80); |
123 | 452k | dest[2] = static_cast<char>( (cp & 0x3f) | 0x80); |
124 | 452k | size_ += 3; |
125 | 452k | return; |
126 | 452k | } |
127 | | |
128 | 28.5k | { |
129 | 28.5k | BOOST_ASSERT(size_ <= N - 4); |
130 | 28.5k | dest[0] = static_cast<char>( (cp >> 18) | 0xf0); |
131 | 28.5k | dest[1] = static_cast<char>(((cp >> 12) & 0x3f) | 0x80); |
132 | 28.5k | dest[2] = static_cast<char>(((cp >> 6) & 0x3f) | 0x80); |
133 | 28.5k | dest[3] = static_cast<char>( (cp & 0x3f) | 0x80); |
134 | 28.5k | size_ += 4; |
135 | 28.5k | } |
136 | 28.5k | } |
137 | | private: |
138 | | char buf_[N]; |
139 | | size_type size_ = 0; |
140 | | }; |
141 | | |
142 | | } // detail |
143 | | } // namespace json |
144 | | } // namespace boost |
145 | | |
146 | | #endif |