Line data 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 13678 : buffer() = default;
29 :
30 : bool
31 9362 : empty() const noexcept
32 : {
33 9362 : return size_ == 0;
34 : }
35 :
36 : string_view
37 10691 : get() const noexcept
38 : {
39 10691 : 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 30251 : size() const noexcept
55 : {
56 30251 : return size_;
57 : }
58 :
59 : size_type
60 17244 : capacity() const noexcept
61 : {
62 17244 : return N - size_;
63 : }
64 :
65 : size_type
66 15663 : max_size() const noexcept
67 : {
68 15663 : return N;
69 : }
70 :
71 : void
72 1524 : clear() noexcept
73 : {
74 1524 : size_ = 0;
75 1524 : }
76 :
77 : void
78 2934 : push_back(char ch) noexcept
79 : {
80 2934 : BOOST_ASSERT(capacity() > 0);
81 2934 : buf_[size_++] = ch;
82 2934 : }
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 11989 : append_utf8(
98 : unsigned long cp) noexcept
99 : {
100 11989 : auto dest = buf_ + size_;
101 11989 : if(cp < 0x80)
102 : {
103 1137 : BOOST_ASSERT(size_ <= N - 1);
104 1137 : dest[0] = static_cast<char>(cp);
105 1137 : size_ += 1;
106 1137 : return;
107 : }
108 :
109 10852 : if(cp < 0x800)
110 : {
111 319 : BOOST_ASSERT(size_ <= N - 2);
112 319 : dest[0] = static_cast<char>( (cp >> 6) | 0xc0);
113 319 : dest[1] = static_cast<char>( (cp & 0x3f) | 0x80);
114 319 : size_ += 2;
115 319 : return;
116 : }
117 :
118 10533 : if(cp < 0x10000)
119 : {
120 7240 : BOOST_ASSERT(size_ <= N - 3);
121 7240 : dest[0] = static_cast<char>( (cp >> 12) | 0xe0);
122 7240 : dest[1] = static_cast<char>(((cp >> 6) & 0x3f) | 0x80);
123 7240 : dest[2] = static_cast<char>( (cp & 0x3f) | 0x80);
124 7240 : size_ += 3;
125 7240 : return;
126 : }
127 :
128 : {
129 3293 : BOOST_ASSERT(size_ <= N - 4);
130 3293 : dest[0] = static_cast<char>( (cp >> 18) | 0xf0);
131 3293 : dest[1] = static_cast<char>(((cp >> 12) & 0x3f) | 0x80);
132 3293 : dest[2] = static_cast<char>(((cp >> 6) & 0x3f) | 0x80);
133 3293 : dest[3] = static_cast<char>( (cp & 0x3f) | 0x80);
134 3293 : 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
|