bmv2
Designing your own switch target with bmv2
Loading...
Searching...
No Matches
bytecontainer.h
Go to the documentation of this file.
1/* Copyright 2013-present Barefoot Networks, Inc.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16/*
17 * Antonin Bas (antonin@barefootnetworks.com)
18 *
19 */
20
22
23#ifndef BM_BM_SIM_BYTECONTAINER_H_
24#define BM_BM_SIM_BYTECONTAINER_H_
25
26#include <vector>
27#include <iterator>
28#include <string>
29
30#include <boost/functional/hash.hpp>
31
32#include "short_alloc.h"
33
34namespace bm {
35
40 static constexpr size_t S = 16u;
41 static_assert(sizeof(char) == 1, "");
42 static_assert(alignof(char) == 1, "");
43 using _vector = std::vector<char, detail::short_alloc<char, S, 1> >;
44
45 public:
46 using iterator = _vector::iterator;
47 using const_iterator = _vector::const_iterator;
48 using reference = _vector::reference;
49 using const_reference = _vector::const_reference;
50 using size_type = size_t;
51
52 public:
54 : bytes(_a) {
55 bytes.reserve(S);
56 }
57
59 explicit ByteContainer(const size_t nbytes, const char c = '\x00')
60 : bytes(nbytes, c, _a) { }
61
63 explicit ByteContainer(const std::vector<char> &bytes)
64 : bytes(bytes.begin(), bytes.end(), _a) { }
65
67 ByteContainer(const char *bytes, size_t nbytes)
68 : bytes(bytes, bytes + nbytes, _a) { }
69
70 static char char2digit(char c) {
71 if (c >= '0' && c <= '9')
72 return (c - '0');
73 if (c >= 'A' && c <= 'F')
74 return (c - 'A' + 10);
75 if (c >= 'a' && c <= 'f')
76 return (c - 'a' + 10);
77 assert(0);
78 return 0;
79 }
80
83 explicit ByteContainer(const std::string &hexstring)
84 : bytes(_a) {
85 bytes.reserve(S);
86 size_t idx = 0;
87
88 assert(hexstring[idx] != '-');
89
90 if (hexstring[idx] == '0' && hexstring[idx + 1] == 'x') {
91 idx += 2;
92 }
93 size_t size = hexstring.size();
94 assert((size - idx) > 0);
95
96 if ((size - idx) % 2 != 0) {
97 char c = char2digit(hexstring[idx++]);
98 bytes.push_back(c);
99 }
100
101 for (; idx < size; ) {
102 char c = char2digit(hexstring[idx++]) << 4;
103 c += char2digit(hexstring[idx++]);
104 bytes.push_back(c);
105 }
106 }
107
108 ByteContainer(const ByteContainer &other)
109 : bytes(other.bytes, _a) { }
110
111 ByteContainer &operator=(const ByteContainer &other) {
112 bytes.assign(other.begin(), other.end());
113 return *this;
114 }
115
117 size_type size() const noexcept { return bytes.size(); }
118
120 void clear() { return bytes.clear(); }
121
122 // iterators
123
125 iterator begin() { return bytes.begin(); }
126
128 const_iterator begin() const { return bytes.begin(); }
129
131 iterator end() { return bytes.end(); }
132
134 const_iterator end() const { return bytes.end(); }
135
136 // reverse_iterator rbegin() { return bytes.rbegin(); }
137
138 // const_reverse_iterator rbegin() const { return bytes.rbegin(); }
139
140 // reverse_iterator rend() { return bytes.rend(); }
141
142 // const_reverse_iterator rend() const { return bytes.rend(); }
143
144 // const_iterator cbegin() const { return bytes.cbegin(); }
145
146 // const_iterator cend() const { return bytes.cend(); }
147
148 // const_reverse_iterator crbegin() const { return bytes.crbegin(); }
149
150 // const_reverse_iterator crend() const { return bytes.crend(); }
151
155 bytes.insert(end(), other.begin(), other.end());
156 return *this;
157 }
158
160 ByteContainer &append(const char *byte_array, size_t nbytes) {
161 bytes.insert(end(), byte_array, byte_array + nbytes);
162 return *this;
163 }
164
166 ByteContainer &append(const std::string &other) {
167 bytes.insert(end(), other.begin(), other.end());
168 return *this;
169 }
170
172 // issue with g++-4.8, insert has a non-conforming signature, fixed in g++-4.9
173 // and g++-5.0. However, this signature works for "all" versions
174 // iterator insert(const_iterator pos, const ByteContainer& other) {
175 void insert(iterator pos, const ByteContainer& other) {
176 // return bytes.insert(pos, other.begin(), other.end());
177 bytes.insert(pos, other.begin(), other.end());
178 }
179
181 void push_back(char c) {
182 bytes.push_back(c);
183 }
184
187 reference operator[](size_type n) {
188 assert(n < size());
189 return bytes[n];
190 }
191
193 const_reference operator[](size_type n) const {
194 assert(n < size());
195 return bytes[n];
196 }
197
200 reference back() {
201 return bytes.back();
202 }
203
205 const_reference back() const {
206 return bytes.back();
207 }
208
211 reference front() {
212 return bytes.front();
213 }
214
216 const_reference front() const {
217 return bytes.front();
218 }
219
223 char* data() noexcept {
224 return bytes.data();
225 }
226
228 const char* data() const noexcept {
229 return bytes.data();
230 }
231
233 bool operator==(const ByteContainer& other) const {
234 return bytes == other.bytes;
235 }
236
238 bool operator!=(const ByteContainer& other) const {
239 return !(*this == other);
240 }
241
243 void reserve(size_t n) {
244 bytes.reserve(n);
245 }
246
248 void resize(size_t n) {
249 bytes.resize(n);
250 }
251
254 void resize(size_t n, char c) {
255 bytes.resize(n, c);
256 }
257
260 void apply_mask(const ByteContainer &mask) {
261 assert(size() == mask.size());
262 for (size_t i = 0; i < size(); i++)
263 bytes[i] &= mask[i];
264 }
265
268 std::string to_hex(size_t start, size_t s, bool upper_case = false) const;
269
271 std::string to_hex(bool upper_case = false) const {
272 return to_hex(0, size(), upper_case);
273 }
274
275 private:
276 _vector::allocator_type::arena_type _a;
277 _vector bytes;
278};
279
280struct ByteContainerKeyHash {
281 std::size_t operator()(const ByteContainer& b) const {
282 // Murmur, boost::hash_range or Jenkins?
283 return boost::hash_range(b.begin(), b.end());
284 }
285};
286
287} // namespace bm
288
289#endif // BM_BM_SIM_BYTECONTAINER_H_
Definition bytecontainer.h:39
void clear()
Clears the contents of the container.
Definition bytecontainer.h:120
ByteContainer & append(const char *byte_array, size_t nbytes)
Appends a byte array to this container.
Definition bytecontainer.h:160
ByteContainer & append(const std::string &other)
Appends a binary string to this container.
Definition bytecontainer.h:166
void resize(size_t n, char c)
Definition bytecontainer.h:254
char * data() noexcept
Definition bytecontainer.h:223
void apply_mask(const ByteContainer &mask)
Definition bytecontainer.h:260
ByteContainer(const size_t nbytes, const char c='\x00')
Constructs the container with nbytes copies of elements with value c.
Definition bytecontainer.h:59
bool operator==(const ByteContainer &other) const
Returns true is the contents of the containers are equal.
Definition bytecontainer.h:233
ByteContainer(const std::string &hexstring)
Definition bytecontainer.h:83
void insert(iterator pos, const ByteContainer &other)
Inserts another ByteContainer object into this container, before pos.
Definition bytecontainer.h:175
bool operator!=(const ByteContainer &other) const
Returns true is the contents of the containers are not equal.
Definition bytecontainer.h:238
ByteContainer(const std::vector< char > &bytes)
Constructs the container by copying the bytes in vector bytes.
Definition bytecontainer.h:63
size_type size() const noexcept
Returns the number of bytes in the container.
Definition bytecontainer.h:117
iterator begin()
NC.
Definition bytecontainer.h:125
const_iterator begin() const
NC.
Definition bytecontainer.h:128
ByteContainer & append(const ByteContainer &other)
Definition bytecontainer.h:154
void resize(size_t n)
Resizes the container to contain bytes.
Definition bytecontainer.h:248
std::string to_hex(bool upper_case=false) const
Returns the hexadecimal representation of the byte container as a string.
Definition bytecontainer.h:271
reference operator[](size_type n)
Definition bytecontainer.h:187
const char * data() const noexcept
Definition bytecontainer.h:228
reference back()
Definition bytecontainer.h:200
iterator end()
NC.
Definition bytecontainer.h:131
const_reference operator[](size_type n) const
Definition bytecontainer.h:193
const_reference front() const
Definition bytecontainer.h:216
const_reference back() const
Definition bytecontainer.h:205
ByteContainer(const char *bytes, size_t nbytes)
Constructs the container by copying the bytes in this byte array.
Definition bytecontainer.h:67
void reserve(size_t n)
Increase the capacity of the container.
Definition bytecontainer.h:243
reference front()
Definition bytecontainer.h:211
const_iterator end() const
NC.
Definition bytecontainer.h:134
void push_back(char c)
Appends a character at the end of the container.
Definition bytecontainer.h:181
std::string to_hex(size_t start, size_t s, bool upper_case=false) const