File: buffer.hpp

package info (click to toggle)
protozero 1.8.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,548 kB
  • sloc: cpp: 20,364; sh: 18; makefile: 14
file content (163 lines) | stat: -rw-r--r-- 4,214 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#ifndef BUFFER_HPP
#define BUFFER_HPP

#include "test.hpp"

#include <protozero/buffer_fixed.hpp>
#include <protozero/buffer_string.hpp>
#include <protozero/buffer_vector.hpp>

// This "simulates" an externally defined buffer type to make sure our
// buffer adaptor functions do the right thing.
namespace test_external {
    class ext_buffer : public std::string {
    };
} // namespace test_external

namespace protozero {

    template <>
    struct buffer_customization<test_external::ext_buffer> {

        static std::size_t size(const test_external::ext_buffer* buffer) noexcept {
            return buffer->size();
        }

        static void append(test_external::ext_buffer* buffer, const char* data, std::size_t count) {
            buffer->append(data, count);
        }

        static void append_zeros(test_external::ext_buffer* buffer, std::size_t count) {
            buffer->append(count, '\0');
        }

        static void resize(test_external::ext_buffer* buffer, std::size_t size) {
            protozero_assert(size < buffer->size());
            buffer->resize(size);
        }

        static void reserve_additional(test_external::ext_buffer* buffer, std::size_t size) {
            buffer->reserve(buffer->size() + size);
        }

        static void erase_range(test_external::ext_buffer* buffer, std::size_t from, std::size_t to) {
            protozero_assert(from <= buffer->size());
            protozero_assert(to <= buffer->size());
            protozero_assert(from <= to);
            buffer->erase(std::next(buffer->begin(), static_cast<std::string::iterator::difference_type>(from)),
                          std::next(buffer->begin(), static_cast<std::string::iterator::difference_type>(to)));
        }

        static char* at_pos(test_external::ext_buffer* buffer, std::size_t pos) {
            protozero_assert(pos <= buffer->size());
            return (&*buffer->begin()) + pos;
        }

        static void push_back(test_external::ext_buffer* buffer, char ch) {
            buffer->push_back(ch);
        }

    };

} // namespace protozero

// The following structs are used in many tests using TEMPLATE_TEST_CASE() to
// test the different buffer types:
//
// 1. Dynamically sized buffer based on std::string.
// 2. Dynamically sized buffer based on std::vector<char>.
// 3. Statically sized buffer based on std::array<char, N>.
// 4. Externally defined buffer.

class buffer_test_string {

    std::string m_buffer;

public:

    using type = std::string;
    using writer_type = protozero::pbf_writer; // == protozero::basic_pbf_writer<type>;

    type& buffer() noexcept {
        return m_buffer;
    }

    const char *data() const noexcept {
        return m_buffer.data();
    }

    std::size_t size() const noexcept {
        return m_buffer.size();
    }
}; // class buffer_test_string

class buffer_test_vector {

    std::vector<char> m_buffer;

public:

    using type = std::vector<char>;
    using writer_type = protozero::basic_pbf_writer<type>;

    type& buffer() noexcept {
        return m_buffer;
    }

    const char *data() const noexcept {
        return m_buffer.data();
    }

    std::size_t size() const noexcept {
        return m_buffer.size();
    }
}; // class buffer_test_vector

class buffer_test_array {

public:
    using type = protozero::fixed_size_buffer_adaptor;
    using writer_type = protozero::basic_pbf_writer<type>;

    type& buffer() noexcept {
        return adaptor;
    }

    const char *data() const noexcept {
        return adaptor.data();
    }

    std::size_t size() const noexcept {
        return adaptor.size();
    }

private:

    std::array<char, 1024> m_buffer = {{0}};
    type adaptor{m_buffer};

}; // class buffer_test_array

class buffer_test_external {

    test_external::ext_buffer m_buffer;

public:

    using type = test_external::ext_buffer;
    using writer_type = protozero::basic_pbf_writer<type>;

    type& buffer() noexcept {
        return m_buffer;
    }

    const char *data() const noexcept {
        return m_buffer.data();
    }

    std::size_t size() const noexcept {
        return m_buffer.size();
    }
}; // class buffer_test_external

#endif // BUFFER_HPP