Alchemy  1.0
A framework to robustly process network messages and structured data
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
carbonate.h
1 // @file C/carbonate.h
2 //
3 // Internal implementation MACROS for C-linkable structs and function calls.
4 //
5 // @note This header file must not be included directly and the
6 // MACROS defined in this file should not be accessed
7 // directly. Include and used the definitions from the file
8 // **<Carbon.h>** instead.
9 //
10 // The MIT License(MIT)
11 // @copyright 2015 Paul M Watt
12 // ****************************************************************************
13 #ifndef CARBONATE_H_INCLUDED
14 #define CARBONATE_H_INCLUDED
15 // Includes *******************************************************************
16 #include <Carbon.h>
17 #include <Hg/proxy/data_proxy.h>
18 
19 namespace C
20 {
21 // Typedefs *******************************************************************
22 typedef unsigned char carbon_t;
23 
24 // ****************************************************************************
25 /// Opaque type representation of memory buffers returned for Carbon.
26 ///
27 /// Byte [0]: Carbon ID
28 /// Bytes[1,3]: Size of the buffer, 3-bytes, 16 MB max
29 /// Bytes[4,7]: Type Id mapping the C-struct to a C++ Hg::Message format.
30 /// Byte [8]: The pointer returned to the caller.
31 /// The remainder of the structure starts here.
32 /// Therefore, all allocations will be 8-bytes larger than requested.
33 ///
34 const int k_carbon_footprint = -8;
35 const int k_base_offset = -k_carbon_footprint;
36 const int k_type_offset = 4;
37 const uint32_t k_carbon_id = 0xA9;
38 
39 const uint32_t k_size_mask = 0x00FFFFFF;
40 
41 
42 
43 // ****************************************************************************
44 // Assigns the value of a C-struct to a Hg Message.
45 //
46 template< typename T, typename U >
47 U& struct_to_msg(T& src, U& dest)
48 {
49  return dest = src;
50 }
51 
52 // ****************************************************************************
53 // Assigns the values of a Hg Message to a C-struct.
54 //
55 template< typename T, typename U >
56 U& msg_to_struct(T& src, U& dest)
57 {
58  return dest = src;
59 }
60 
61 // ****************************************************************************
62 // Assigns the value of a C-struct to a Hg Message.
63 //
64 template< typename T, typename U >
65 U& struct_to_msg(T& src, Hg::detail::DataProxy<Hg::nested_trait,U& dest)
66 {
67  return dest = src;
68 }
69 
70 // ****************************************************************************
71 // Assigns the values of a Hg Message to a C-struct.
72 //
73 template< typename T, typename U >
74 U& msg_to_struct(T& src, U& dest)
75 {
76  return dest = src;
77 }
78 
79 // TODO: Add specializations for arrays and vectors.
80 
81 // ****************************************************************************
82 /// Given the users msg address, the actual allocated based address is returned.
83 ///
84 inline
85 carbon_t* carbon_ptr(Hg_msg_t* p_msg)
86 {
87  if (!p_msg)
88  return 0;
89 
90  // Offset the user supplied pointer to the
91  // calculated position of the allocation base address.
92  carbon_t* p_base = static_cast<carbon_t*>(p_msg);
93  std::advance(p_base, k_base_offset);
94 
95  // Verify the Carbon ID before returning the pointer.
96  if ( !p_base
97  || p_base[0] != k_carbon_id)
98  return 0;
99 
100  return p_base;
101 }
102 
103 // ****************************************************************************
104 inline
105 carbon_t* carbon_ptr(const Hg_msg_t* p_msg)
106 {
107  return carbon_ptr(const_cast<Hg_msg_t*>(p_msg));
108 }
109 
110 // ****************************************************************************
111 /// Returns the size of the allocated buffer.
112 ///
113 inline
114 size_t carbon_size(const Hg_msg_t* p_msg)
115 {
116  carbon_t* p_base = carbon_ptr(p_msg);
117  if (!p_base)
118  return 0;
119 
120  uint32_t size = 0;
121  memcpy(&size, p_base, 4);
122 
123  return size & k_size_mask;
124 }
125 
126 // ****************************************************************************
127 /// Returns the type of message for which the buffer is allocated.
128 ///
129 inline
130 Hg_type_t carbon_type(const Hg_msg_t* p_msg)
131 {
132  carbon_t* p_base = carbon_ptr(p_msg);
133  if (!p_base)
134  return 0;
135 
136  Hg_type_t type = 0;
137  memcpy(&type, p_base + k_type_offset, 4);
138 
139  return type;
140 }
141 
142 } // namespace C
143 
144 
145 
146 // TODO: For now, hand-writing the implementation. These functions will eventually all be generated.
147 
148 
149 #include <CarbonTestDefs.h>
150 // ****************************************************************************
151 #include <Pb/type_list.h>
152 #include <Pb/size_at.h>
153 
154 typedef Hg::TypeList
155 <
156  color_map_t,
157  pt3d_t,
158  ray_t,
159  vertex_t
161 
162 
163 #define k_color_map 0
164 #define k_pt3d 1
165 #define k_ray 2
166 #define k_vertex 3
167 
168 
169 template< Hg_type_t IdT,
170  typename T
171  >
172 T* Hg_msg_cast(C::carbon_t* p_msg);//, T*);
173 
174 template <>
175 Hg::color_map_t* Hg_msg_cast<k_color_map, Hg::color_map_t>(C::carbon_t* p_msg)//, Hg::color_map_t* = 0)
176 {
177  return reinterpret_cast<Hg::color_map_t*>(p_msg);
178 }
179 
180 template <>
181 Hg::pt3d_t* Hg_msg_cast<k_pt3d, Hg::pt3d_t>(C::carbon_t* p_msg)//, Hg::pt3d_t* = 0)
182 {
183  return reinterpret_cast<Hg::pt3d_t*>(p_msg);
184 }
185 
186 template <>
187 Hg::ray_t* Hg_msg_cast<k_ray, Hg::ray_t>(C::carbon_t* p_msg)//, Hg::ray_t* = 0)
188 {
189  return reinterpret_cast<Hg::ray_t*>(p_msg);
190 }
191 
192 template <>
193 Hg::vertex_t* Hg_msg_cast<k_vertex, Hg::vertex_t>(C::carbon_t* p_msg)//, Hg::vertex_t* = 0)
194 {
195  return reinterpret_cast<Hg::vertex_t*>(p_msg);
196 }
197 
198 // ****************************************************************************
199 size_t GetTypeSize(int v)
200 {
201  switch (v)
202  {
203  case k_color_map:
205  case k_pt3d:
207  case k_ray:
209  case k_vertex:
211  }
212 
213  return 0;
214 }
215 
216 
217 
218 // ****************************************************************************
219 size_t GetTotalSize(Hg_msg_t* p_src)
220 {
221  if (!p_src)
222  return 0;
223 
224  Hg_type_t id = C::carbon_type(p_src);
225 
226 
227  switch (id)
228  {
229  case k_color_map:
230  {
231  Hg::color_map_t* m = Hg_msg_cast<k_color_map, Hg::color_map_t>(p_src);
232  return 0;
233  }
234  case k_pt3d:
235  {
236  Hg::pt3d_t* m = Hg_msg_cast<k_pt3d, Hg::pt3d_t>(p_src);
237  return 0;
238  }
239  case k_ray:
240  {
241  Hg::ray_t* m = Hg_msg_cast<k_ray, Hg::ray_t>(p_src);
242  return 0;
243  }
244  case k_vertex:
245  {
246  Hg::vertex_t* m = Hg_msg_cast<k_vertex, Hg::vertex_t>(p_src);
247  return 0;
248  }
249  }
250 
251 
252  return 0;
253 }
254 
255 
256 
257 
258 
259 
260 
261 
262 #endif