|
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