cpp-msgpack-light 0.3.0
A light library to serialize MessagePack.
Loading...
Searching...
No Matches
binary.h
Go to the documentation of this file.
1/*
2 * Copyright 2024 MusicScience37 (Kenta Kabashima)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
20#pragma once
21
22#include <cstddef> // IWYU pragma: keep
23#include <cstring>
24#include <initializer_list>
25#include <limits>
26#include <ostream>
27#include <stdexcept>
28#include <string_view>
29#include <vector>
30
32
33namespace msgpack_light {
34
35namespace details {
36
44[[nodiscard]] inline std::size_t calculate_expanded_memory_buffer_size(
45 std::size_t current_size, std::size_t additional_size) {
46 std::size_t next_size = current_size;
47 while (true) {
48 next_size *= 2;
49 if (next_size <= current_size) {
50 // Overflow
51 const std::size_t max_size =
52 std::numeric_limits<std::size_t>::max();
53 if (max_size - current_size >= additional_size) {
54 return max_size;
55 }
56 throw std::bad_alloc();
57 }
58 if (next_size - current_size >= additional_size) {
59 return next_size;
60 }
61 }
62}
63
67constexpr std::size_t default_binary_capacity = 8U;
68
69} // namespace details
70
71class binary;
72
79public:
85 binary_view() noexcept : data_(nullptr), size_(0U) {}
86
93 binary_view(const unsigned char* data, std::size_t size) noexcept
94 : data_(data), size_(size) {}
95
101 binary_view( // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
102 const binary& data) noexcept;
103
109 [[nodiscard]] const unsigned char* data() const noexcept { return data_; }
110
116 [[nodiscard]] std::size_t size() const noexcept { return size_; }
117
118private:
120 const unsigned char* data_;
121
123 std::size_t size_;
124};
125
129class binary {
130public:
136 binary() : buffer_(details::default_binary_capacity), size_(0U) {}
137
145 explicit binary(std::size_t size) : buffer_(size), size_(size) {}
146
153 binary(const unsigned char* data, std::size_t size) : binary(size) {
154 if (size == 0U) {
155 return;
156 }
157 std::memcpy(buffer_.data(), data, size);
158 }
159
166
172 explicit binary(const std::vector<unsigned char>& data)
173 : binary(data.data(), data.size()) {}
174
180 binary(std::initializer_list<unsigned char> data)
181 : binary(data.begin(), data.size()) {}
182
195 explicit binary(std::string_view data_string)
196 : binary(data_string.size() / 2U) {
197 constexpr std::string_view hex_digits = "0123456789ABCDEF";
198 unsigned int byte = 0U;
199 bool is_first_digit = true;
200 std::size_t current_byte_index = 0U;
201 for (char digit : data_string) {
202 const auto pos = hex_digits.find(digit);
203 if (pos == std::string_view::npos) {
204 throw std::invalid_argument("Invalid hex expression.");
205 }
206 if (is_first_digit) {
207 byte = static_cast<unsigned int>(pos);
208 is_first_digit = false;
209 } else {
210 byte <<= 4U;
211 byte |= static_cast<unsigned int>(pos);
212 buffer_.data()[current_byte_index] =
213 static_cast<unsigned char>(byte);
214 ++current_byte_index;
215 is_first_digit = true;
216 }
217 }
218 if (!is_first_digit) {
219 throw std::invalid_argument("Invalid hex expression.");
220 }
221 }
222
231 void resize(std::size_t size) {
232 if (size > buffer_.size()) {
233 buffer_.resize(size);
234 }
235 size_ = size;
236 }
237
245 void reserve(std::size_t size) {
246 if (size > buffer_.size()) {
247 buffer_.resize(size);
248 }
249 }
250
257 void append(const unsigned char* data, std::size_t size) {
258 const std::size_t current_size = size_;
259 const std::size_t remaining_capacity = buffer_.size() - size_;
260 if (remaining_capacity < size) {
262 buffer_.size(), size - remaining_capacity));
263 }
264 std::memcpy(buffer_.data() + current_size, data, size);
265 size_ += size;
266 }
267
274 binary& operator+=(const binary& other) {
275 append(other.data(), other.size());
276 return *this;
277 }
278
285 [[nodiscard]] unsigned char& operator[](std::size_t index) noexcept {
286 return buffer_.data()[index];
287 }
288
295 [[nodiscard]] unsigned char operator[](std::size_t index) const noexcept {
296 return buffer_.data()[index];
297 }
298
304 [[nodiscard]] unsigned char* data() noexcept { return buffer_.data(); }
305
311 [[nodiscard]] const unsigned char* data() const noexcept {
312 return buffer_.data();
313 }
314
320 [[nodiscard]] std::size_t size() const noexcept { return size_; }
321
327 [[nodiscard]] std::size_t capacity() const noexcept {
328 return buffer_.size();
329 }
330
338 [[nodiscard]] bool operator==(const binary& other) const noexcept {
339 return size_ == other.size_ &&
340 std::memcmp(buffer_.data(), other.buffer_.data(), size_) == 0;
341 }
342
350 [[nodiscard]] bool operator!=(const binary& other) const noexcept {
351 return !operator==(other);
352 }
353
354private:
357
359 std::size_t size_;
360};
361
362inline binary_view::binary_view(const binary& data) noexcept
363 : data_(data.data()), size_(data.size()) {}
364
372[[nodiscard]] inline binary operator+(const binary& lhs, const binary& rhs) {
373 return binary(lhs) += rhs;
374}
375
384[[nodiscard]] inline bool operator==(binary_view lhs, binary_view rhs) {
385 return lhs.size() == rhs.size() &&
386 std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
387}
388
397[[nodiscard]] inline bool operator!=(binary_view lhs, binary_view rhs) {
398 return !(lhs == rhs);
399}
400
408inline std::ostream& operator<<(std::ostream& stream, const binary& value) {
409 constexpr std::string_view hex_digits = "0123456789ABCDEF";
410 for (std::size_t i = 0; i < value.size(); ++i) {
411 const unsigned int byte = value.data()[i];
412 // NOLINTNEXTLINE(readability-magic-numbers)
413 stream << hex_digits[(byte >> 4U) & 0x0FU];
414 // NOLINTNEXTLINE(readability-magic-numbers)
415 stream << hex_digits[byte & 0x0FU];
416 }
417 return stream;
418}
419
420} // namespace msgpack_light
Definition of basic_binary_buffer class.
Class to refer binary data.
Definition binary.h:78
std::size_t size() const noexcept
Get the size of the data.
Definition binary.h:116
const unsigned char * data() const noexcept
Get the pointer to the data.
Definition binary.h:109
binary_view() noexcept
Constructor.
Definition binary.h:85
binary_view(const unsigned char *data, std::size_t size) noexcept
Constructor.
Definition binary.h:93
const unsigned char * data_
Data.
Definition binary.h:120
std::size_t size_
Size.
Definition binary.h:123
Class of binary data.
Definition binary.h:129
binary(binary_view data)
Constructor.
Definition binary.h:165
void reserve(std::size_t size)
Change the size of the internal buffer.
Definition binary.h:245
unsigned char * data() noexcept
Get the pointer to the data.
Definition binary.h:304
binary & operator+=(const binary &other)
Append another binary data.
Definition binary.h:274
std::size_t size_
Size.
Definition binary.h:359
binary(const std::vector< unsigned char > &data)
Constructor.
Definition binary.h:172
binary(std::size_t size)
Constructor.
Definition binary.h:145
std::size_t size() const noexcept
Get the size of the data.
Definition binary.h:320
binary(const unsigned char *data, std::size_t size)
Constructor.
Definition binary.h:153
binary()
Constructor.
Definition binary.h:136
bool operator==(const binary &other) const noexcept
Compare with another instance.
Definition binary.h:338
void resize(std::size_t size)
Change the size of this data.
Definition binary.h:231
binary(std::initializer_list< unsigned char > data)
Constructor.
Definition binary.h:180
unsigned char & operator[](std::size_t index) noexcept
Access to a byte.
Definition binary.h:285
binary(std::string_view data_string)
Constructor.
Definition binary.h:195
unsigned char operator[](std::size_t index) const noexcept
Access to a byte.
Definition binary.h:295
bool operator!=(const binary &other) const noexcept
Compare with another instance.
Definition binary.h:350
const unsigned char * data() const noexcept
Get the pointer to the data.
Definition binary.h:311
details::basic_binary_buffer buffer_
Buffer.
Definition binary.h:356
void append(const unsigned char *data, std::size_t size)
Append another binary data.
Definition binary.h:257
std::size_t capacity() const noexcept
Get the size of the internal buffer for data.
Definition binary.h:327
Class of basic buffers for binary data.
Namespace of internal implementations.
Definition binary.h:35
constexpr std::size_t default_binary_capacity
Default of the capacity of the buffer in msgpack_light::binary class.
Definition binary.h:67
std::size_t calculate_expanded_memory_buffer_size(std::size_t current_size, std::size_t additional_size)
Calculate the size of an expanded buffer.
Definition binary.h:44
Namespace of this project.
Definition binary.h:33
bool operator==(binary_view lhs, binary_view rhs)
Compare two binary data.
Definition binary.h:384
binary operator+(const binary &lhs, const binary &rhs)
Connect two binary data.
Definition binary.h:372
bool operator!=(binary_view lhs, binary_view rhs)
Compare two binary data.
Definition binary.h:397
std::ostream & operator<<(std::ostream &stream, const binary &value)
Format a value to a stream.
Definition binary.h:408