Skip to content

Commit 7a974bc

Browse files
Enhancing README, removed reinterpret_cast from extract_append.hpp
1 parent f1f28de commit 7a974bc

File tree

2 files changed

+27
-29
lines changed

2 files changed

+27
-29
lines changed

README.md

+12-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Binary Serialize, Header-Only C++ 20 Binary Serialization Classes and Functions
1+
# Binary Serialize, Header-Only C++ 20 Binary Serialization Classes and Functions Using a `std::format` Like Syntax
22

33
#### Unit Test and Documentation Generation Workflow Status
44

@@ -14,10 +14,20 @@
1414

1515
## Overview
1616

17-
The `binary_serialize` functions and classes provide serializing and unserializing of binary data. Serialization provides a way to transform application objects into and out of byte streams that can be sent over a network (or used for file IO).
17+
The `binary_serialize` functions and classes provide serializing and unserializing of binary data. Serialization provides a way to transform application objects into and out of byte streams that can be sent over a network (or used for file IO). Many serialization libraries transform objects to and from text representations, but this library keeps data in binary formats.
1818

1919
The serialization functionality in this repository is useful when explicit control is needed for every bit and byte. This allows a developer to match an existing wire protocol or encoding scheme or to define his or her own wire protocol. Support is provided for fundamental arithmetic types as well as certain C++ vocabulary types such as `std::optional`. Both big and little endian support is provided.
2020

21+
This library uses `std::format` style formatting. For example:
22+
23+
```
24+
(insert example code)
25+
```
26+
27+
The documentation overview provides a comparison with other serialization libraries as well as a rationale for the design decisions.
28+
29+
Inspiration and thanks go to [Louis Langholtz](https://github.com/louis-langholtz), who steered me towards considering the `std::format` API.
30+
2131
## Generated Documentation
2232

2333
The generated Doxygen documentation for `binary_serialize` is [here](https://connectivecpp.github.io/binary-serialize/).

include/serialize/extract_append.hpp

+15-27
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,25 @@
44
* endian order) to native format; conversely, given an arithmetic binary value, append
55
* it to a buffer of bytes in the specified endian order.
66
*
7-
* The functions in this file are low-level, handling fundamental arithmetic types and
7+
* The functions in this file are low-level. The handle fundamental arithmetic types and
88
* extracting or appending to @c std::byte buffers. It is meant to be the lower layer
99
* of serializing utilities, where the next layer up provides buffer management,
1010
* sequences, and overloads for specific types such as @c std::string, @c bool, and
1111
* @c std::optional.
1212
*
13-
* @note When C++ 20 @c std::endian is available, many of these functions can be made
14-
* @c constexpr and evaluated at compile time. Until then, run-time endian detection and
15-
* copying is performed.
13+
* @note The variable sized integer functions (@c extract_var_int, @c append_var_int)
14+
* support the variable byte integer type in MQTT (Message Queuing Telemetry Transport),
15+
* a commonly used IoT protocol. The code in this header is adapted from a
16+
* Techoverflow.net article by Uli Koehler and published under the CC0 1.0 Universal
17+
* license:
18+
* https://techoverflow.net/2013/01/25/efficiently-encoding-variable-length-integers-in-cc/
1619
*
17-
* @note The variable sized integer functions (@c extract_var_int, @c append_var_int)
18-
* support the variable byte integer type in MQTT (Message Queuing Telemetry Transport),
19-
* a commonly used IoT protocol. The code in this header is adapted from a
20-
* Techoverflow.net article by Uli Koehler and published under the CC0 1.0 Universal
21-
* license:
22-
* https://techoverflow.net/2013/01/25/efficiently-encoding-variable-length-integers-in-cc/
20+
* @author Cliff Green, Roxanne Agerone, Uli Koehler
2321
*
24-
* @note This implementation has manual generated unrolled loops for the byte moving and
25-
* swapping. This can be improved in the future by using a compile-time unrolling utility, such
26-
* as the @c repeat function (compile time unrolling version) by Vittorio Romeo.
22+
* @copyright (c) 2019-2024 by Cliff Green, Roxanne Agerone
2723
*
28-
* @author Cliff Green, Roxanne Agerone, Uli Koehler
29-
*
30-
* @copyright (c) 2019-2024 by Cliff Green, Roxanne Agerone
31-
*
32-
* Distributed under the Boost Software License, Version 1.0.
33-
* (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
24+
* Distributed under the Boost Software License, Version 1.0.
25+
* (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
3426
*
3527
*/
3628

@@ -191,19 +183,18 @@ constexpr std::size_t append_val(std::byte* buf, const T& val) noexcept {
191183
template<std::unsigned_integral T>
192184
constexpr std::size_t append_var_int(std::byte* output, T val) {
193185

194-
std::uint8_t* output_ptr = reinterpret_cast<std::uint8_t *>(output);
195186
std::size_t output_size = 0;
196187

197188
// While more than 7 bits of data are left, occupy the last output byte
198189
// and set the next byte flag
199190
while (val > 127) {
200191

201-
output_ptr[output_size] = (static_cast<std::uint8_t> (val & 127)) | 128;
192+
output[output_size] = std::bit_cast<std::byte>(static_cast<std::uint8_t>((static_cast<std::uint8_t> (val & 127)) | 128));
202193
//Remove the seven bits we just wrote
203194
val >>= 7;
204195
++output_size;
205196
}
206-
output_ptr[output_size++] = static_cast<std::uint8_t> (val) & 127;
197+
output[output_size++] = std::bit_cast<std::byte>(static_cast<std::uint8_t>(static_cast<std::uint8_t> (val) & 127));
207198
return output_size;
208199
}
209200
/**
@@ -222,14 +213,11 @@ constexpr std::size_t append_var_int(std::byte* output, T val) {
222213
*/
223214
template<std::unsigned_integral T>
224215
constexpr T extract_var_int(const std::byte* input, std::size_t input_size) {
225-
226-
const std::uint8_t* input_ptr = reinterpret_cast<const std::uint8_t *> (input);
227-
228216
T ret = 0;
229217
for (std::size_t i = 0; i < input_size; ++i) {
230-
ret |= (input_ptr[i] & 127) << (7 * i);
218+
ret |= (std::bit_cast<std::uint8_t>(input[i]) & 127) << (7 * i);
231219
//If the next-byte flag is set
232-
if(!(input_ptr[i] & 128)) {
220+
if(!(std::bit_cast<std::uint8_t>(input[i]) & 128)) {
233221
break;
234222
}
235223
}

0 commit comments

Comments
 (0)