bmv2
Designing your own switch target with bmv2
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 
34 namespace 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 
280 struct 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_
bm::ByteContainer::operator[]
reference operator[](size_type n)
Definition: bytecontainer.h:187
bm::ByteContainer::append
ByteContainer & append(const char *byte_array, size_t nbytes)
Appends a byte array to this container.
Definition: bytecontainer.h:160
bm::ByteContainer::operator[]
const_reference operator[](size_type n) const
Definition: bytecontainer.h:193
bm::ByteContainer::resize
void resize(size_t n, char c)
Definition: bytecontainer.h:254
bm::ByteContainer::ByteContainer
ByteContainer(const std::vector< char > &bytes)
Constructs the container by copying the bytes in vector bytes.
Definition: bytecontainer.h:63
bm::ByteContainer::reserve
void reserve(size_t n)
Increase the capacity of the container.
Definition: bytecontainer.h:243
bm::ByteContainer::begin
const_iterator begin() const
NC.
Definition: bytecontainer.h:128
bm::ByteContainer::front
reference front()
Definition: bytecontainer.h:211
bm::ByteContainer::back
reference back()
Definition: bytecontainer.h:200
bm::ByteContainer::to_hex
std::string to_hex(size_t start, size_t s, bool upper_case=false) const
bm::ByteContainer::ByteContainer
ByteContainer(const char *bytes, size_t nbytes)
Constructs the container by copying the bytes in this byte array.
Definition: bytecontainer.h:67
bm::ByteContainer::front
const_reference front() const
Definition: bytecontainer.h:216
bm::ByteContainer
Definition: bytecontainer.h:39
bm::ByteContainer::apply_mask
void apply_mask(const ByteContainer &mask)
Definition: bytecontainer.h:260
bm::ByteContainer::size
size_type size() const noexcept
Returns the number of bytes in the container.
Definition: bytecontainer.h:117
bm::ByteContainer::append
ByteContainer & append(const ByteContainer &other)
Definition: bytecontainer.h:154
bm::ByteContainer::append
ByteContainer & append(const std::string &other)
Appends a binary string to this container.
Definition: bytecontainer.h:166
bm::ByteContainer::back
const_reference back() const
Definition: bytecontainer.h:205
bm::ByteContainer::operator==
bool operator==(const ByteContainer &other) const
Returns true is the contents of the containers are equal.
Definition: bytecontainer.h:233
bm::ByteContainer::data
const char * data() const noexcept
Definition: bytecontainer.h:228
bm::ByteContainer::operator!=
bool operator!=(const ByteContainer &other) const
Returns true is the contents of the containers are not equal.
Definition: bytecontainer.h:238
bm::ByteContainer::begin
iterator begin()
NC.
Definition: bytecontainer.h:125
bm::ByteContainer::ByteContainer
ByteContainer(const std::string &hexstring)
Definition: bytecontainer.h:83
bm::ByteContainer::data
char * data() noexcept
Definition: bytecontainer.h:223
bm::ByteContainer::push_back
void push_back(char c)
Appends a character at the end of the container.
Definition: bytecontainer.h:181
bm::ByteContainer::to_hex
std::string to_hex(bool upper_case=false) const
Returns the hexadecimal representation of the byte container as a string.
Definition: bytecontainer.h:271
bm::ByteContainer::ByteContainer
ByteContainer(const size_t nbytes, const char c='\x00')
Constructs the container with nbytes copies of elements with value c.
Definition: bytecontainer.h:59
bm::ByteContainer::clear
void clear()
Clears the contents of the container.
Definition: bytecontainer.h:120
bm::ByteContainer::end
iterator end()
NC.
Definition: bytecontainer.h:131
bm::ByteContainer::resize
void resize(size_t n)
Resizes the container to contain bytes.
Definition: bytecontainer.h:248
bm::ByteContainer::insert
void insert(iterator pos, const ByteContainer &other)
Inserts another ByteContainer object into this container, before pos.
Definition: bytecontainer.h:175
bm::ByteContainer::end
const_iterator end() const
NC.
Definition: bytecontainer.h:134