|
1 | 1 | /** @mainpage Binary Serialuze, Classes and Functions For Binary Data Serialization
|
2 | 2 | *
|
3 |
| - * Serialization transforms objects into a byte stream for transmission over a |
4 |
| - * network or for file IO. Deserialization is the converse, transforming a byte |
5 |
| - * stream into application level objects. |
6 |
| - * |
7 |
| - * This library differs from other binary serialization libraries in that the |
8 |
| - * main interfaces is a "std::format" like |
9 |
| - * These functions and classes provide a simple and light abstraction for binary big-endian serialization. There are no |
10 |
| - * message or element definitions, no embedded preprocesser syntax, and no extra |
11 |
| - * build steps. |
12 |
| - * |
13 |
| - * These facilities are useful when explicit control of every bit and byte is needed |
14 |
| - * (and the wire protocol format is big-endian). Other marshalling and serialization |
15 |
| - * designs have strengths and weaknesses (see higher level documentation for more |
16 |
| - * explanation). |
17 |
| - * |
18 |
| - * @note The design of the binary marshall and unmarshall functions is a good fit |
19 |
| - * for a C++ metaprogamming implementation (using variadic templates). In particular, |
20 |
| - * the primary design concept is a mapping of two (and sometimes three) types to a |
21 |
| - * single value. A typelist would allow a single function (or method) call to operate |
22 |
| - * on multiple values, instead of being forced to call the @c marshall or @c unmarshall |
23 |
| - * function once for each value (or sequence). However, the first release uses the |
24 |
| - * simpler (no metaprogramming, no variadic templates) implementation with a hope that |
25 |
| - * a more sophisticated version will be available in the future. |
26 |
| - * |
27 |
| - * The marshalling classes and functions are designed for networking (or file I/O), |
28 |
| - * where binary data marshalling and unmarshalling is needed to send and receive |
29 |
| - * messages (or to write or read defined portions of a file). Application code using |
30 |
| - * this library has full control of every byte that is sent or received. Application |
31 |
| - * objects are transformed into a @c std::byte buffer (and the converse) keeping a |
32 |
| - * binary representation in network (big-endian) order. |
33 |
| - * |
34 |
| - * For example, a 32-bit binary number (either a signed or unsigned integer) in native |
35 |
| - * endian order will be transformed into four 8-bit bytes in network (big) endian order |
36 |
| - * for sending over a network (or for file I/O). Conversely, the four 8-bit bytes in |
37 |
| - * network endian order will be transformed back into the original 32-bit binary number |
38 |
| - * when received (or read as file I/O). A @c bool can be transformed into either a 8-bit, |
39 |
| - * 16-bit, 32-bit, or 64-bit number of either 1 or 0 (and back). A sequence |
40 |
| - * (@c std::vector or array or other container) can be transformed into a count (8-bit, |
41 |
| - * 16-bit, et al) followed by each element of the sequence. A @c std::optional can be |
42 |
| - * transformed into a @c bool (8-bit, 16-bit, et al) followed by the value (if present). |
43 |
| - * |
44 |
| - * No support is directly provided for higher level abstractions such as inheritance |
45 |
| - * hierarchies, version numbers, type flags, or object relations. Pointers are also not |
46 |
| - * directly supported (which would typically be part of an object relation). No specific |
47 |
| - * wire protocol or data encoding is specified (other than big-endian). These higher |
48 |
| - * level abstractions as well as "saving and later restoring a full application state" |
49 |
| - * are better served by a library such as Boost Serialization or Google Protocol |
50 |
| - * Buffers or Cap'n Proto. |
51 |
| - * |
52 |
| - * There is not any automatic generation of message processing code (e.g. Google |
53 |
| - * Protocol Buffers, a language neutral message definition process that generates |
54 |
| - * marshalling and unmarshalling code). Future C++ standards supporting reflection |
55 |
| - * may allow higher abstractions and more automation of marshalling code, but this |
56 |
| - * library provides a modern C++ API (post C++ 11) for direct control of the |
57 |
| - * byte buffers. In particular, all of the build process complications required for |
58 |
| - * code generation are not present in this (header only) library. |
59 |
| - * |
60 |
| - * Wire protocols that are in full text mode do not need to deal with binary endian |
61 |
| - * swapping. However, sending or receiving data in a binary form is often desired |
62 |
| - * for size efficiency (e.g. sending images and video, large data sets, or where |
63 |
| - * the message size needs to be as small as possible). |
64 |
| - * |
65 |
| - * Functionality is provided for fundamental types, including @c bool, as well as vocabulary |
66 |
| - * types such as @c std::string and @c std::optional. Support is also provided for sequences, |
67 |
| - * where the number of elements is placed before the element sequence in the stream of |
68 |
| - * bytes. |
69 |
| - * |
70 |
| - * Application defined types can be associated with a @c marshall and @c unmarshall |
71 |
| - * function overload, providing a convenient way to reuse the same lower-level |
72 |
| - * marshalling code. Specifically, a type @c MyType can be used in a sequence or in |
73 |
| - * a @c std::optional or as part of a higher level @c struct or @c class type without needing |
74 |
| - * to duplicate the marshalling calls within the @c MyType @c marshall and @c unmarshall |
75 |
| - * functions. |
| 3 | + * Serialization transforms objects into a byte stream for transmission over a |
| 4 | + * network or for file IO. Deserialization is the converse, transforming a byte |
| 5 | + * stream into application level objects. |
| 6 | + * |
| 7 | + * This library differs from other binary serialization libraries in that the |
| 8 | + * main interfaces is a "std::format" like |
| 9 | + * These functions and classes provide a simple and light abstraction for binary big-endian serialization. There are no |
| 10 | + * message or element definitions, no embedded preprocesser syntax, and no extra |
| 11 | + * build steps. |
| 12 | + * |
| 13 | + * These facilities are useful when explicit control of every bit and byte is needed |
| 14 | + * (and the wire protocol format is big-endian). Other marshalling and serialization |
| 15 | + * designs have strengths and weaknesses (see higher level documentation for more |
| 16 | + * explanation). |
| 17 | + * |
| 18 | + * @note The design of the binary marshall and unmarshall functions is a good fit |
| 19 | + * for a C++ metaprogamming implementation (using variadic templates). In particular, |
| 20 | + * the primary design concept is a mapping of two (and sometimes three) types to a |
| 21 | + * single value. A typelist would allow a single function (or method) call to operate |
| 22 | + * on multiple values, instead of being forced to call the @c marshall or @c unmarshall |
| 23 | + * function once for each value (or sequence). However, the first release uses the |
| 24 | + * simpler (no metaprogramming, no variadic templates) implementation with a hope that |
| 25 | + * a more sophisticated version will be available in the future. |
| 26 | + * |
| 27 | + * The marshalling classes and functions are designed for networking (or file I/O), |
| 28 | + * where binary data marshalling and unmarshalling is needed to send and receive |
| 29 | + * messages (or to write or read defined portions of a file). Application code using |
| 30 | + * this library has full control of every byte that is sent or received. Application |
| 31 | + * objects are transformed into a @c std::byte buffer (and the converse) keeping a |
| 32 | + * binary representation in network (big-endian) order. |
| 33 | + * |
| 34 | + * For example, a 32-bit binary number (either a signed or unsigned integer) in native |
| 35 | + * endian order will be transformed into four 8-bit bytes in network (big) endian order |
| 36 | + * for sending over a network (or for file I/O). Conversely, the four 8-bit bytes in |
| 37 | + * network endian order will be transformed back into the original 32-bit binary number |
| 38 | + * when received (or read as file I/O). A @c bool can be transformed into either a 8-bit, |
| 39 | + * 16-bit, 32-bit, or 64-bit number of either 1 or 0 (and back). A sequence |
| 40 | + * (@c std::vector or array or other container) can be transformed into a count (8-bit, |
| 41 | + * 16-bit, et al) followed by each element of the sequence. A @c std::optional can be |
| 42 | + * transformed into a @c bool (8-bit, 16-bit, et al) followed by the value (if present). |
| 43 | + * |
| 44 | + * No support is directly provided for higher level abstractions such as inheritance |
| 45 | + * hierarchies, version numbers, type flags, or object relations. Pointers are also not |
| 46 | + * directly supported (which would typically be part of an object relation). No specific |
| 47 | + * wire protocol or data encoding is specified (other than big-endian). These higher |
| 48 | + * level abstractions as well as "saving and later restoring a full application state" |
| 49 | + * are better served by a library such as Boost Serialization or Google Protocol |
| 50 | + * Buffers or Cap'n Proto. |
| 51 | + * |
| 52 | + * There is not any automatic generation of message processing code (e.g. Google |
| 53 | + * Protocol Buffers, a language neutral message definition process that generates |
| 54 | + * marshalling and unmarshalling code). Future C++ standards supporting reflection |
| 55 | + * may allow higher abstractions and more automation of marshalling code, but this |
| 56 | + * library provides a modern C++ API (post C++ 11) for direct control of the |
| 57 | + * byte buffers. In particular, all of the build process complications required for |
| 58 | + * code generation are not present in this (header only) library. |
| 59 | + * |
| 60 | + * Wire protocols that are in full text mode do not need to deal with binary endian |
| 61 | + * swapping. However, sending or receiving data in a binary form is often desired |
| 62 | + * for size efficiency (e.g. sending images and video, large data sets, or where |
| 63 | + * the message size needs to be as small as possible). |
| 64 | + * |
| 65 | + * Functionality is provided for fundamental types, including @c bool, as well as vocabulary |
| 66 | + * types such as @c std::string and @c std::optional. Support is also provided for sequences, |
| 67 | + * where the number of elements is placed before the element sequence in the stream of |
| 68 | + * bytes. |
| 69 | + * |
| 70 | + * Application defined types can be associated with a @c marshall and @c unmarshall |
| 71 | + * function overload, providing a convenient way to reuse the same lower-level |
| 72 | + * marshalling code. Specifically, a type @c MyType can be used in a sequence or in |
| 73 | + * a @c std::optional or as part of a higher level @c struct or @c class type without needing |
| 74 | + * to duplicate the marshalling calls within the @c MyType @c marshall and @c unmarshall |
| 75 | + * functions. |
76 | 76 | *
|
77 |
| - * @c std::variant and @c std::any are not directly supported and require value extraction |
78 |
| - * by the application. (Supporting @c std::variant or @c std::any might be a future |
79 |
| - * enhancement if a good design is proposed.) @c std::wstring and other non-char strings are |
80 |
| - * also not directly supported, and require additional calls from the application. |
81 |
| - * |
82 |
| - * Central to the design of these marshalling and unmarshalling functions is a mapping of |
83 |
| - * two types to a single value. For marshalling, the two types are the native type (e.g. |
84 |
| - * @c int, @c short, @c bool), and the type to be used for the marshalling, typically |
85 |
| - * a fixed width integer type, as specified in the @c <cstdint> header (e.g. |
86 |
| - * @c std::uint32_t, @c std::int16_t, @c std::int8_t). For unmarshalling, the same |
87 |
| - * concept is used, a fixed width integer type that specifies the size in the byte |
88 |
| - * buffer, and the native type, thus the application would specify that a @c std::int16_t |
89 |
| - * in the byte buffer will be unmarshalled into an application @c int value. |
90 |
| - * |
91 |
| - * @note No support is provided for little-endian in the byte buffer. No support is provided |
92 |
| - * for mixed endian (big-endian with little-endian) or where the endianness is specified as a |
93 |
| - * type parameter. No support is provided for "in-place" swapping of values. All of these |
94 |
| - * use cases can be implemented using other libraries such as Boost Endian. |
95 |
| - * |
96 |
| - * @note Performance considerations - for marshalling, iterative resizing of the output |
97 |
| - * buffer is a fundamental operation. @c std::vector and @c mutable_shared_buffer |
98 |
| - * @c resize methods use efficient logic for internal buffer allocations (@c mutable_shared_buffer |
99 |
| - * uses @c std::vector internally). Custom containers used as the buffer parameter should |
100 |
| - * have similar efficient @c resize method logic. Calling @c reserve at appropriate places may |
101 |
| - * provide a small performance increase, at the cost of additional requirements on the buffer |
102 |
| - * type. |
103 |
| - * |
104 |
| - * @author Cliff Green |
105 |
| - * |
106 |
| - * Copyright (c) 2019 by Cliff Green |
107 |
| - * |
108 |
| - * Distributed under the Boost Software License, Version 1.0. |
109 |
| - * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| 77 | + * @c std::variant and @c std::any are not directly supported and require value extraction |
| 78 | + * by the application. (Supporting @c std::variant or @c std::any might be a future |
| 79 | + * enhancement if a good design is proposed.) @c std::wstring and other non-char strings are |
| 80 | + * also not directly supported, and require additional calls from the application. |
| 81 | + * |
| 82 | + * Central to the design of these marshalling and unmarshalling functions is a mapping of |
| 83 | + * two types to a single value. For marshalling, the two types are the native type (e.g. |
| 84 | + * @c int, @c short, @c bool), and the type to be used for the marshalling, typically |
| 85 | + * a fixed width integer type, as specified in the @c <cstdint> header (e.g. |
| 86 | + * @c std::uint32_t, @c std::int16_t, @c std::int8_t). For unmarshalling, the same |
| 87 | + * concept is used, a fixed width integer type that specifies the size in the byte |
| 88 | + * buffer, and the native type, thus the application would specify that a @c std::int16_t |
| 89 | + * in the byte buffer will be unmarshalled into an application @c int value. |
| 90 | + * |
| 91 | + * @note No support is provided for little-endian in the byte buffer. No support is provided |
| 92 | + * for mixed endian (big-endian with little-endian) or where the endianness is specified as a |
| 93 | + * type parameter. No support is provided for "in-place" swapping of values. All of these |
| 94 | + * use cases can be implemented using other libraries such as Boost Endian. |
| 95 | + * |
| 96 | + * @note Performance considerations - for marshalling, iterative resizing of the output |
| 97 | + * buffer is a fundamental operation. @c std::vector and @c mutable_shared_buffer |
| 98 | + * @c resize methods use efficient logic for internal buffer allocations (@c mutable_shared_buffer |
| 99 | + * uses @c std::vector internally). Custom containers used as the buffer parameter should |
| 100 | + * have similar efficient @c resize method logic. Calling @c reserve at appropriate places may |
| 101 | + * provide a small performance increase, at the cost of additional requirements on the buffer |
| 102 | + * type. |
| 103 | + * |
| 104 | + * @author Cliff Green |
| 105 | + * |
| 106 | + * @copyright (c) 2019-2024 by Cliff Green |
| 107 | + * |
| 108 | + * Distributed under the Boost Software License, Version 1.0. |
| 109 | + * (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
110 | 110 | *
|
111 | 111 | */
|
112 | 112 |
|
113 | 113 | #ifndef BINARY_SERIALIZE_HPP_INCLUDED
|
114 | 114 | #define BINARY_SERIALIZE_HPP_INCLUDED
|
115 | 115 |
|
116 | 116 | #include "utility/cast_ptr_to.hpp"
|
117 |
| -#include "marshall/shared_buffer.hpp" |
118 |
| -#include "marshall/extract_append.hpp" |
| 117 | +#include "buffer/shared_buffer.hpp" |
| 118 | +#include "serialize/extract_append.hpp" |
119 | 119 |
|
120 | 120 | #include <cstddef> // std::byte, std::size_t, std::nullptr_t
|
121 | 121 | #include <cstdint> // std::uint32_t, etc
|
|
0 commit comments