Alchemy  1.0
A framework to robustly process network messages and structured data
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Alchemy.h
Go to the documentation of this file.
1 /// @file Alchemy.h
2 ///
3 /// Network Alchemy is a message and structured data processing framework.
4 ///
5 /// Include this file for access to the alchemy message structure framework.
6 ///
7 /// This framework provides the ability to define structured message formats,
8 /// which can be used portably across platforms. These structured definitions
9 /// will facilitate the population of the data in the memoery buffers for
10 /// inter-process communication, file and network transfer as well as
11 /// direct memory access mapping..
12 ///
13 /// Byte-alignment processing is completely transparent to application level
14 /// users. Conversion utilities are automatically generated for conversion
15 /// between host, network, big and little-endian formats for transport developers.
16 ///
17 /// Alchemy is portable across different processor types and platforms.
18 /// Word alignment and memory access issues are also handled transparently by
19 /// the framework. Users interface with Hg message structures in the same way
20 /// structures are accessed. Nested structures are supported.
21 ///
22 /// Message structure definitions are created with the list of MACROs below.
23 /// Refer to the appropriate MACROs documentation for details on correct usage:
24 ///
25 /// - ALCHEMY_STRUCT(TYPE_LIST)
26 /// - ALCHEMY_DATUM(TYPE,NAME)
27 /// - ALCHEMY_ARRAY(TYPE,COUNT,NAME)
28 /// - ALCHEMY_ALLOC(TYPE,COUNT,NAME)
29 /// - ALCHEMY_ALLOC_EX(TYPE,ALLOCATOR,COUNT,NAME)
30 ///
31 /// Hg provides a portable bit-field interface that works by generating the
32 /// appropriate shift and mask operations for each field. Use these MACROS
33 /// to define a set of bit-fields that are packed into a user-specified integral type.
34 /// Hg currently is written to allow up to 32 bit-fields in a single parameter.
35 ///
36 /// - ALCHEMY_PACKED(TYPE,BITSET)
37 /// - ALCHEMY_END_PACKED
38 /// - ALCHEMY_BITS(INDEX,COUNT,NAME)
39 ///
40 /// The MIT License(MIT)
41 ///
42 /// @copyright 2014 Paul M Watt
43 ///
44 /// Permission is hereby granted, free of charge, to any person obtaining a copy
45 /// of this software and associated documentation files(the "Software"), to deal
46 /// in the Software without restriction, including without limitation the rights
47 /// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
48 /// copies of the Software, and to permit persons to whom the Software is
49 /// furnished to do so, subject to the following conditions :
50 ///
51 /// The above copyright notice and this permission notice shall be included in
52 /// all copies or substantial portions of the Software.
53 ///
54 /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55 /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
56 /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
57 /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
58 /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
59 /// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
60 /// THE SOFTWARE.
61 ///
62 // ***************************************************************************
63 #ifndef ALCHEMY_H_INCLUDED
64 #define ALCHEMY_H_INCLUDED
65 
66 // Includes ******************************************************************
67 #include <C/carbon_def.h>
68 #include <Hg/msg_def.h>
69 
70 
71 // ****************************************************************************
72 /// Marks the beginning of a message format.
73 ///
74 /// A MACRO used to start the definition for a message format interface.
75 /// This definition requires that the parent class derive from the MsgFormat
76 /// base class.
77 ///
78 /// @param TYPE_LIST The TypeList used to defined the layout format.
79 ///
80 /// @note This definition MACRO should be placed in the global namespace.
81 /// C++ objects will be placed in a namespace that corresponds
82 /// with the elemental name of its library, such as Hg.
83 /// ~~~{.cpp}
84 ///
85 /// // Define the message data format
86 /// ALCHEMY_STRUCT
87 /// ( new_point_t,
88 /// ALCHEMY_DATUM (uint8_t, msgType),
89 /// ALCHEMY_DATUM (uint8_t, verNum),
90 /// ALCHEMY_DATUM (uint16_t, id),
91 /// ALCHEMY_DATUM (uint32_t, X),
92 /// ALCHEMY_DATUM (uint32_t, Y),
93 /// ALCHEMY_DATUM (uint32_t, Z),
94 /// ALCHEMY_DATUM (uint16_t, flags),
95 /// ALCHEMY_DATUM (uint8_t, priority),
96 /// ALCHEMY_DATUM (uint8_t, count)
97 /// )
98 ///
99 /// ~~~
100 ///
101 #define ALCHEMY_STRUCT(NAME, ...) DECLARE_STRUCT(NAME, Hg_, __VA_ARGS__);\
102  DECLARE_STRUCT(NAME, C_, __VA_ARGS__);
103 
104 // ****************************************************************************
105 /// Adds a field to the message definition.
106 ///
107 /// This MACRO generates code based on the TypeList specified in the
108 /// ALCHEMY_STRUCT MACRO. This MACRO also provides the user the ability to
109 /// name the property associated with this message format field.
110 ///
111 /// @param TYPE The type to use for this field
112 /// @param NAME The name to assign this parameter in the message definition.
113 /// NAME will be the name used to access this field directly.
114 ///
115 #define ALCHEMY_DATUM(TYPE,NAME) DECLARE_DATUM(TYPE,NAME)
116 
117 
118 // ****************************************************************************
119 /// Adds a fixed-size array field to the message definition.
120 ///
121 /// This MACRO generates code based on the TypeList specified in the
122 /// ALCHEMY_STRUCT MACRO. This MACRO also provides the user the ability to
123 /// name the property associated with this message format field.
124 ///
125 /// @param TYPE The type to use for this field
126 /// @param COUNT The number of elements allocated for the array.
127 /// @param NAME The name to assign this parameter in the message definition.
128 /// NAME will be the name used to access this field directly.
129 ///
130 #define ALCHEMY_ARRAY(TYPE,COUNT,NAME) DECLARE_ARRAY_DATUM(TYPE,COUNT,NAME)
131 
132 
133 // ****************************************************************************
134 /// Adds a field with a dynamic size to the message definition.
135 ///
136 /// This MACRO generates code based on the TypeList specified in the
137 /// ALCHEMY_STRUCT MACRO. This MACRO also provides the user the ability to
138 /// name the property associated with this message format field.
139 /// Finally, a field is provided to specify how this datum will know how
140 /// large the field should be when reading data on input.
141 ///
142 /// @param TYPE The type to use for this field
143 /// @param COUNT Specifies how the size of the field is determined on input.
144 /// There are a few possible ways to indicate the method:
145 /// * Reference a field previously defined in the message that
146 /// indicates the number of entries.
147 /// * Specify a function pointer to a user-defined function
148 /// that will inspect the data and return the size.
149 /// the function should have the following signature:
150 /// size_t pfn_GetDatumSize(uint8_t* pCur, size_t len)
151 /// @param NAME The name to assign this parameter in the message definition.
152 /// NAME will be the name used to access this field directly.
153 ///
154 ///
155 #define ALCHEMY_ALLOC(TYPE,COUNT,NAME)\
156  DECLARE_VECTOR_DATUM(TYPE,COUNT,NAME)
157 
158 
159 // ****************************************************************************
160 /// Adds a field with a dynamic size controlled by a user specified allocator.
161 ///
162 /// This MACRO generates code based on the TypeList specified in the
163 /// ALCHEMY_STRUCT MACRO. This MACRO also provides the user the ability to
164 /// name the property associated with this message format field.
165 /// A field is provided for the user to indicate how the field can determine
166 /// its own size. This MACRO is similar to ALCHEMY_ALLOC, with the exception
167 /// that a user specified allocator can be used.
168 ///
169 /// @param TYPE The type to use for this field
170 /// @param ALLOCATOR An allocator that will be used to allocate space for
171 /// the dynamically sized field.
172 /// @param COUNT Specifies how the size of the field is determined on input.
173 /// There are a few possible ways to indicate the method:
174 /// * Reference a field previously defined in the message that
175 /// indicates the number of entries.
176 /// * Specify a function pointer to a user-defined function
177 /// that will inspect the data and return the size.
178 /// the function should have the following signature:
179 /// size_t pfn_GetDatumSize(uint8_t* pCur, size_t len)
180 /// @param NAME The name to assign this parameter in the message definition.
181 /// NAME will be the name used to access this field directly.
182 ///
183 ///
184 #define ALCHEMY_ALLOC_EX(TYPE,ALLOCATOR,COUNT,NAME)\
185  DECLARE_ALLOCATOR_DATUM(TYPE,ALLOCATOR,COUNT,NAME)
186 
187 
188 // ****************************************************************************
189 /// Marks the end of a message format.
190 ///
191 /// A MACRO used to end the definition for a message format interface.
192 /// This MACRO adds no functionality, it simply acts as a bookend to indicate
193 /// the end of the message format definition.
194 ///
195 /// This MACRO will verify that all of the entries have been configured in the
196 /// data format definition. A compiler error will be emitted if the number
197 /// of declared HG_MSG_FIELD entries does not match the number expected.
198 ///
199 #define ALCHEMY_END_STRUCT(TYPE_LIST) DECLARE_STRUCT_FOOTER(TYPE_LIST)
200 
201 
202 // ****************************************************************************
203 /// Starts the definition for a message field that represents a set of packed bits.
204 ///
205 /// This definition builds a packed bit definition in place, and allows the user
206 /// to specify the size and names of each bit-field. This provides a very
207 /// convenient and natural way to interact with the named bit-fields in an expressive
208 /// manner.
209 ///
210 /// @param TYPE The integer type to use for this field.
211 /// @param NAME The name to assign to this bitset definition.
212 ///
213 /// @note A current limitation requires that bit-sets, defined with this
214 /// MACRO definition, are performed in the *Hg* namespace.
215 ///
216 /// usage:
217 /// ~~~{.cpp}
218 ///
219 /// ALCHEMY_PACKED
220 /// ( uint8_t,
221 /// flags,
222 /// ALCHEMY_BITS (0, is_visible, 1),
223 /// ALCHEMY_BITS (1, is_light , 1),
224 /// ALCHEMY_BITS (2, ambient , 3),
225 /// ALCHEMY_BITS (3, diffuse , 3)
226 /// );
227 ///
228 /// ~~~
229 ///
230 /// @remarks There are a number of constructs that are created by the definition
231 /// of this MACRO:
232 /// 1) ContainerSize<> specialization to properly return the
233 /// size of the data buffer required for the bitset.
234 /// Otherwise the size of the BIT_SET object would be returned.
235 /// 2) field_data_t<> specialization that defines the
236 /// value_type and a data cache for the message field.
237 /// 3) The definition of the BIT_SET struct, which contains
238 /// all of the named bit-field properties managed by the BIT_SET.
239 /// 4) If ALCHEMY_CARBONATE is defined before the Alchemy.h,
240 /// a set of C-linkable structs and utility functions will be
241 /// generated and exported for use in a library.
242 ///
243 #define ALCHEMY_PACKED(TYPE, NAME, ...) DECLARE_PACKED(TYPE, NAME, C_, __VA_ARGS__);\
244  DECLARE_PACKED(TYPE, NAME, Hg_, __VA_ARGS__);
245 
246 // ****************************************************************************
247 /// Adds a bit-field type parameter to the bit-set.
248 ///
249 /// This MACRO generates the code required to add a bit-field to a parent bit-set.
250 /// The name of the bit-field can be specified as well as the number of bits
251 /// this field should occupy.
252 ///
253 /// @param INDEX The index of this bit-field in the definition.
254 /// @param NAME The name to assign this parameter in the bit-set definition.
255 /// NAME will be the name used to access this bit-field directly.
256 /// @param COUNT The number of bits this Bit-Field occupies.
257 ///
258 #define ALCHEMY_BITS(INDEX,NAME,COUNT)\
259  DECLARE_BIT_FIELD(INDEX, NAME, COUNT)
260 
261 
262 // ****************************************************************************
263 /// Ends the definition for a message field that represents a set of packed bits.
264 ///
265 /// A type container specialization is declared for this class to facilitate
266 /// the proper calculation of the internal buffer size for the container.
267 ///
268 #define ALCHEMY_END_PACKED DECLARE_PACKED_FOOTER
269 
270 
271 //#define ALCHEMY_PACKED(TYPE,NAME) DECLARE_PACKED_HEADER(TYPE,NAME)
272 //#define C_BEGIN_PACKED(TYPE,NAME) C_DECLARE_PACKED_HEADER(TYPE,NAME)
273 //#define ALCHEMY_PACKED(TYPE,NAME) Hg_DECLARE_PACKED_HEADER(TYPE,NAME)
274 
275 //#define C_BIT_FIELD(INDEX,NAME,COUNT)\
276 // C_DECLARE_BIT_FIELD(INDEX, NAME, COUNT)
277 //
278 //#define ALCHEMY_BITS(INDEX,NAME,COUNT)\
279 // Hg_DECLARE_BIT_FIELD(INDEX, NAME, COUNT)
280 
281 //#define C_END_PACKED C_DECLARE_PACKED_FOOTER
282 //#define ); Hg_DECLARE_PACKED_FOOTER
283 
284 #endif