netmsgs  1.2.2
RoadNarrows Robotics Network Messaging Package
nmLibInternal.c
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: netmsgs
4 //
5 // Library: libnetmsgs
6 //
7 // File: nmLibInternal.c
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2010-02-12 14:27:57 -0700 (Fri, 12 Feb 2010) $
12  * $Rev: 247 $
13  *
14  * \brief Internal intra-library definitions
15  *
16  * \author Robin Knight (robin.knight@roadnarrows.com)
17  *
18  * \copyright
19  * \h_copy 2009-2017. RoadNarrows LLC.\n
20  * http://www.roadnarrows.com\n
21  * All Rights Reserved
22  */
23 // Permission is hereby granted, without written agreement and without
24 // license or royalty fees, to use, copy, modify, and distribute this
25 // software and its documentation for any purpose, provided that
26 // (1) The above copyright notice and the following two paragraphs
27 // appear in all copies of the source code and (2) redistributions
28 // including binaries reproduces these notices in the supporting
29 // documentation. Substantial modifications to this software may be
30 // copyrighted by their authors and need not follow the licensing terms
31 // described here, provided that the new terms are clearly indicated in
32 // all files where they apply.
33 //
34 // IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES
35 // OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
36 // PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
37 // DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
38 // EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
39 // THE POSSIBILITY OF SUCH DAMAGE.
40 //
41 // THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
42 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
43 // FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
44 // "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
45 // PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
46 //
47 ////////////////////////////////////////////////////////////////////////////////
48 
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include <stdarg.h>
52 #include <libgen.h>
53 #include <string.h>
54 
55 #include "rnr/rnrconfig.h"
56 #include "rnr/log.h"
57 
58 #include "rnr/netmsgs.h"
59 
60 #include "nmLibInternal.h"
61 
62 
63 // ---------------------------------------------------------------------------
64 // Private Interface
65 // ---------------------------------------------------------------------------
66 
67 /*!
68  * \brief Set field value.
69  *
70  * \param _this This field's specific information.
71  * \param pv Pointer to field value.
72  * \param T Field C type.
73  */
74 #define _NMSET_VAL(_this, pv, T) \
75  (T)(_this.m_bits & NMBITS_HAS_CONST? (T)(_this.m_valConst): *((T*)pv))
76 
77 /*!
78  * \brief Check value is \h_ge minimum.
79  *
80  * \note Out-of-range violation results is calling function return.
81  *
82  * \param fname This field's string name.
83  * \param _this This field's specific information.
84  * \param v Field value.
85  * \param T Field C type.
86  * \param fmt Format string on error.
87  */
88 #define _NMCHK_MIN(fname, _this, v, T, fmt) \
89  do \
90  { \
91  if( _this.m_bits & NMBITS_HAS_MIN ) \
92  { \
93  if( (v) < (T)(_this.m_valMin) ) \
94  { \
95  NMLIB_RAISE_ERROR(NM_ECODE_RANGE, "%s val=" fmt " < min=" fmt, \
96  fname, v, (T)(_this.m_valMin)); \
97  } \
98  } \
99  } while(0)
100 
101 /*!
102  * \brief Check value is \h_le maximum.
103  *
104  * \note Out-of-range violation results is calling function return.
105  *
106  * \param fname This field's string name.
107  * \param _this This field's specific information.
108  * \param v Field value.
109  * \param T Field C type.
110  * \param fmt Format string on error.
111  */
112 #define _NMCHK_MAX(fname, _this, v, T, fmt) \
113  do \
114  { \
115  if( _this.m_bits & NMBITS_HAS_MAX ) \
116  { \
117  if( (v) > (T)(_this.m_valMax) ) \
118  { \
119  NMLIB_RAISE_ERROR(NM_ECODE_RANGE, "%s val=" fmt " > max=" fmt, \
120  fname, v, (T)(_this.m_valMax)); \
121  } \
122  } \
123  } while(0)
124 
125 
126 // ---------------------------------------------------------------------------
127 // Internal Public Interface
128 // ---------------------------------------------------------------------------
129 
130 const int NMHashOffset = (int)NMFTypeBool; ///< hash base offset
131 const int NMHashNoIdx = 0xff; ///< hash no index value
132 
133 /*!
134  * Field Type Hash Table.
135  *
136  * Maps field type to zero base index.
137  *
138  * \note The table is hand-crafted to optimize access speed.
139  */
140 const byte_t NMHashTbl[] =
141 {
142  // [0] ? @ A B C D E F
143  0, 0xff, 0xff, 1, 0xff, 0xff, 0xff, 2,
144 
145  // [8] G H I J K L M N
146  0xff, 3, 4, 0xff, 0xff, 0xff, 0xff, 0xff,
147 
148  // [16] O P Q R S T U V
149  0xff, 5, 6, 0xff, 0xff, 0xff, 0xff, 0xff,
150 
151  // [24] W X Y Z [ \ ] ^
152  0xff, 0xff, 0xff, 0xff, 7, 0xff, 0xff, 0xff,
153 
154  // [32] _ ` a b c d e f
155  0xff, 0xff, 0xff, 8, 9, 0xff, 0xff, 10,
156 
157  // [40] g h i j k l m n
158  0xff, 11, 12, 0xff, 0xff, 0xff, 0xff, 0xff,
159 
160  // [48] o p q r s t u v
161  0xff, 13, 14, 0xff, 15, 0xff, 0xff, 0xff,
162 
163  // [56] w x y z {
164  0xff, 16, 0xff, 0xff, 17
165 };
166 
167 /*! number of hash entries */
168 const size_t NMHashNumEntries = arraysize(NMHashTbl);
169 
170 /*!
171  * \brief Helper function to set an unsigned 8-bit integer.
172  *
173  * \param pFieldDef Pointer to message field definition.
174  * \param [in] pValIn Pointer to field value.
175  * \param [out] pValOut Pointer to constrained, assigned field value.
176  *
177  * \return
178  * On success, returns \ref NM_OK.\n
179  * On error, the appropriate negated
180  * \ref man_libnetmsgs_ecodes "netmsgs error code" (\h_lt 0) is returned.
181  */
182 int nmSetU8(const NMFieldDef_T *pFieldDef, void *pValIn, byte_t *pValOut)
183 {
184  byte_t val;
185 
186  // set value, override if is constant value
187  val = _NMSET_VAL(pFieldDef->m_this.m_u8, pValIn, byte_t);
188  //val = (pFieldDef->m_this.m_u8.m_bits & NMBITS_HAS_CONST?
189  // (byte_t)(pFieldDef->m_this.m_u8.m_valConst):
190  // *((byte_t*)pValIn))
191 
192  // check against minimum limits
193  _NMCHK_MIN(pFieldDef->m_sFName, pFieldDef->m_this.m_u8, val, byte_t, "%hhu");
194 
195  // check against maximum limits
196  _NMCHK_MAX(pFieldDef->m_sFName, pFieldDef->m_this.m_u8, val, byte_t, "%hhu");
197 
198  // set
199  *pValOut = val;
200 
201  return NM_OK;
202 }
203 
204 /*!
205  * \brief Helper function to set a signed 8-bit integer.
206  *
207  * \param pFieldDef Pointer to message field definition.
208  * \param [in] pValIn Pointer to field value.
209  * \param [out] pValOut Pointer to constrained, assigned field value.
210  *
211  * \return
212  * On success, returns \ref NM_OK.\n
213  * On error, the appropriate negated
214  * \ref man_libnetmsgs_ecodes "netmsgs error code" (\h_lt 0) is returned.
215  */
216 int nmSetS8(const NMFieldDef_T *pFieldDef, void *pValIn, signed char *pValOut)
217 {
218  signed char val;
219 
220  // set value, override if is constant value
221  val = _NMSET_VAL(pFieldDef->m_this.m_u8, pValIn, signed char);
222 
223  // check against minimum limits
224  _NMCHK_MIN(pFieldDef->m_sFName, pFieldDef->m_this.m_u8,
225  val, signed char, "%hhd");
226 
227  // check against maximum limits
228  _NMCHK_MAX(pFieldDef->m_sFName, pFieldDef->m_this.m_u8,
229  val, signed char, "%hhd");
230 
231  // set
232  *pValOut = val;
233 
234  return NM_OK;
235 }
236 
237 /*!
238  * \brief Helper function to set an unsigned 16-bit integer.
239  *
240  * \param pFieldDef Pointer to message field definition.
241  * \param [in] pValIn Pointer to field value.
242  * \param [out] pValOut Pointer to constrained, assigned field value.
243  *
244  * \return
245  * On success, returns \ref NM_OK.\n
246  * On error, the appropriate negated
247  * \ref man_libnetmsgs_ecodes "netmsgs error code" (\h_lt 0) is returned.
248  */
249 int nmSetU16(const NMFieldDef_T *pFieldDef, void *pValIn, ushort_t *pValOut)
250 {
251  ushort_t val;
252 
253  // set value, override if is constant value
254  val = _NMSET_VAL(pFieldDef->m_this.m_u16, pValIn, ushort_t);
255 
256  // check against minimum limits
257  _NMCHK_MIN(pFieldDef->m_sFName, pFieldDef->m_this.m_u16,
258  val, ushort_t, "%hu");
259 
260  // check against maximum limits
261  _NMCHK_MAX(pFieldDef->m_sFName, pFieldDef->m_this.m_u16,
262  val, ushort_t, "%hu");
263 
264  // set
265  *pValOut = val;
266 
267  return NM_OK;
268 }
269 
270 /*!
271  * \brief Helper function to set a signed 16-bit integer.
272  *
273  * \param pFieldDef Pointer to message field definition.
274  * \param [in] pValIn Pointer to field value.
275  * \param [out] pValOut Pointer to constrained, assigned field value.
276  *
277  * \return
278  * On success, returns \ref NM_OK.\n
279  * On error, the appropriate negated
280  * \ref man_libnetmsgs_ecodes "netmsgs error code" (\h_lt 0) is returned.
281  */
282 int nmSetS16(const NMFieldDef_T *pFieldDef, void *pValIn, short *pValOut)
283 {
284  short val;
285 
286  // set value, override if is constant value
287  val = _NMSET_VAL(pFieldDef->m_this.m_u16, pValIn, short);
288 
289  // check against minimum limits
290  _NMCHK_MIN(pFieldDef->m_sFName, pFieldDef->m_this.m_u16, val, short, "%hd");
291 
292  // check against maximum limits
293  _NMCHK_MAX(pFieldDef->m_sFName, pFieldDef->m_this.m_u16, val, short, "%hd");
294 
295  // set
296  *pValOut = val;
297 
298  return NM_OK;
299 }
300 
301 /*!
302  * \brief Helper function to set an unsigned 32-bit integer.
303  *
304  * \param pFieldDef Pointer to message field definition.
305  * \param [in] pValIn Pointer to field value.
306  * \param [out] pValOut Pointer to constrained, assigned field value.
307  *
308  * \return
309  * On success, returns \ref NM_OK.\n
310  * On error, the appropriate negated
311  * \ref man_libnetmsgs_ecodes "netmsgs error code" (\h_lt 0) is returned.
312  */
313 int nmSetU32(const NMFieldDef_T *pFieldDef, void *pValIn, uint_t *pValOut)
314 {
315  uint_t val;
316 
317  // set value, override if is constant value
318  val = _NMSET_VAL(pFieldDef->m_this.m_u32, pValIn, uint_t);
319 
320  // check against minimum limits
321  _NMCHK_MIN(pFieldDef->m_sFName, pFieldDef->m_this.m_u32, val, uint_t, "%u");
322 
323  // check against maximum limits
324  _NMCHK_MAX(pFieldDef->m_sFName, pFieldDef->m_this.m_u32, val, uint_t, "%u");
325 
326  // set
327  *pValOut = val;
328 
329  return NM_OK;
330 }
331 
332 /*!
333  * \brief Helper function to set a signed 32-bit integer.
334  *
335  * \param pFieldDef Pointer to message field definition.
336  * \param [in] pValIn Pointer to field value.
337  * \param [out] pValOut Pointer to constrained, assigned field value.
338  *
339  * \return
340  * On success, returns \ref NM_OK.\n
341  * On error, the appropriate negated
342  * \ref man_libnetmsgs_ecodes "netmsgs error code" (\h_lt 0) is returned.
343  */
344 int nmSetS32(const NMFieldDef_T *pFieldDef, void *pValIn, int *pValOut)
345 {
346  int val;
347 
348  // set value, override if constant value
349  val = _NMSET_VAL(pFieldDef->m_this.m_u32, pValIn, int);
350 
351  // check against minimum limits
352  _NMCHK_MIN(pFieldDef->m_sFName, pFieldDef->m_this.m_u32, val, int, "%d");
353 
354  // check against maximum limits
355  _NMCHK_MAX(pFieldDef->m_sFName, pFieldDef->m_this.m_u32, val, int, "%d");
356 
357  // set
358  *pValOut = val;
359 
360  return NM_OK;
361 }
362 
363 /*!
364  * \brief Helper function to set an unsigned 64-bit integer.
365  *
366  * \param pFieldDef Pointer to message field definition.
367  * \param [in] pValIn Pointer to field value.
368  * \param [out] pValOut Pointer to constrained, assigned field value.
369  *
370  * \return
371  * On success, returns \ref NM_OK.\n
372  * On error, the appropriate negated
373  * \ref man_libnetmsgs_ecodes "netmsgs error code" (\h_lt 0) is returned.
374  */
375 int nmSetU64(const NMFieldDef_T *pFieldDef,
376  void *pValIn,
377  ulonglong_t *pValOut)
378 {
379  ulonglong_t val;
380 
381  // set value, override if constant value
382  val = _NMSET_VAL(pFieldDef->m_this.m_u64, pValIn, ulonglong_t);
383 
384  // check against minimum limits
385  _NMCHK_MIN(pFieldDef->m_sFName, pFieldDef->m_this.m_u64,
386  val, ulonglong_t, "%llu");
387 
388  // check against maximum limits
389  _NMCHK_MAX(pFieldDef->m_sFName, pFieldDef->m_this.m_u64,
390  val, ulonglong_t, "%llu");
391 
392  // set
393  *pValOut = val;
394 
395  return NM_OK;
396 }
397 
398 /*!
399  * \brief Helper function to set a signed 64-bit integer.
400  *
401  * \param pFieldDef Pointer to message field definition.
402  * \param [in] pValIn Pointer to field value.
403  * \param [out] pValOut Pointer to constrained, assigned field value.
404  *
405  * \return
406  * On success, returns \ref NM_OK.\n
407  * On error, the appropriate negated
408  * \ref man_libnetmsgs_ecodes "netmsgs error code" (\h_lt 0) is returned.
409  */
410 int nmSetS64(const NMFieldDef_T *pFieldDef, void *pValIn, long long *pValOut)
411 {
412  long long val;
413 
414  // set value, override if constant value
415  val = _NMSET_VAL(pFieldDef->m_this.m_u64, pValIn, long long);
416 
417  // check against minimum limits
418  _NMCHK_MIN(pFieldDef->m_sFName, pFieldDef->m_this.m_u64,
419  val, long long, "%hhu");
420 
421  // check against maximum limits
422  _NMCHK_MAX(pFieldDef->m_sFName, pFieldDef->m_this.m_u64,
423  val, long long, "%hhu");
424 
425  // set
426  *pValOut = val;
427 
428  return NM_OK;
429 }
430 
431 /*!
432  * \brief Helper function to set a 32-bit floating point number.
433  *
434  * \param pFieldDef Pointer to message field definition.
435  * \param [in] pValIn Pointer to field value.
436  * \param [out] pValOut Pointer to constrained, assigned field value.
437  *
438  * \return
439  * On success, returns \ref NM_OK.\n
440  * On error, the appropriate negated
441  * \ref man_libnetmsgs_ecodes "netmsgs error code" (\h_lt 0) is returned.
442  */
443 int nmSetF32(const NMFieldDef_T *pFieldDef, void *pValIn, float *pValOut)
444 {
445  float val;
446 
447  // set value, override if constant value
448  val = _NMSET_VAL(pFieldDef->m_this.m_f32, pValIn, float);
449 
450  // check against minimum limits
451  _NMCHK_MIN(pFieldDef->m_sFName, pFieldDef->m_this.m_f32, val, float, "%f");
452 
453  // check against maximum limits
454  _NMCHK_MAX(pFieldDef->m_sFName, pFieldDef->m_this.m_f32, val, float, "%f");
455 
456  // set
457  *pValOut = val;
458 
459  return NM_OK;
460 }
461 
462 /*!
463  * \brief Helper function to set a 64-bit floating point number.
464  *
465  * \param pFieldDef Pointer to message field definition.
466  * \param [in] pValIn Pointer to field value.
467  * \param [out] pValOut Pointer to constrained, assigned field value.
468  *
469  * \return
470  * On success, returns \ref NM_OK.\n
471  * On error, the appropriate negated
472  * \ref man_libnetmsgs_ecodes "netmsgs error code" (\h_lt 0) is returned.
473  */
474 int nmSetF64(const NMFieldDef_T *pFieldDef, void *pValIn, double *pValOut)
475 {
476  double val;
477 
478  // set value, override if constant value
479  val = _NMSET_VAL(pFieldDef->m_this.m_f64, pValIn, double);
480 
481  // check against minimum limits
482  _NMCHK_MIN(pFieldDef->m_sFName, pFieldDef->m_this.m_f64, val, double, "%f");
483 
484  // check against maximum limits
485  _NMCHK_MAX(pFieldDef->m_sFName, pFieldDef->m_this.m_f64, val, double, "%f");
486 
487  // set
488  *pValOut = val;
489 
490  return NM_OK;
491 }
492 
493 #ifdef NMLIB_DEBUG
494 /*!
495  * \brief Trace packing/unpacking of a message field.
496  *
497  * \param pFieldDef Pointer to field definition.
498  * \param buf Packed/unpacked buffer.
499  * \param uCount Number of bytes in buffer to trace.
500  * \param uDepth Depth of field in recursive definition.
501  * \param sFmt Field representation format string.
502  * \param ... Field representation variable arguments.
503  */
504 void nmTraceField(const NMFieldDef_T *pFieldDef,
505  byte_t buf[],
506  size_t uCount,
507  uint_t uDepth,
508  const char *sFmt,
509  ...)
510 {
511  va_list ap;
512  char bufRepr[256];
513  uint_t uIndent;
514  int n;
515 
516  va_start(ap, sFmt);
517  vsnprintf(bufRepr, sizeof(bufRepr), sFmt, ap);
518  va_end(ap);
519  bufRepr[sizeof(bufRepr)-1] = 0;
520 
521  uIndent = uDepth * 2;
522 
523  if( pFieldDef != NULL )
524  {
525  // "normal"
526  if( pFieldDef->m_eFId != NMFID_NONE )
527  {
528  n = fprintf(stderr, "%*s%c:%s(%u) = %s: ",
529  uIndent, "", pFieldDef->m_eFType, pFieldDef->m_sFName,
530  pFieldDef->m_eFId, bufRepr);
531  }
532  // vector items have no field ids
533  else
534  {
535  n = fprintf(stderr, "%*s[%c]: = %s: ",
536  uIndent, "", pFieldDef->m_eFType, bufRepr);
537  }
538  }
539  else
540  {
541  n = fprintf(stderr, "%*s%s: ", uDepth*2, "", bufRepr);
542  }
543 
544  if( uCount > 0 )
545  {
546  if( n > 36 )
547  {
548  fprintf(stderr, "\n");
549  n = 0;
550  }
551 
552  fprintf(stderr, "%*s", 38-n, "");
553  nmPrintBuf(stderr, NULL, buf, uCount, 8, 38);
554  }
555  fprintf(stderr, "\n");
556 }
557 #endif // NMLIB_DEBUG
const size_t NMHashNumEntries
int nmSetU32(const NMFieldDef_T *pFieldDef, void *pValIn, uint_t *pValOut)
Helper function to set an unsigned 32-bit integer.
NMFieldThisU8_T m_u8
[unsigned] 8-bit integer specific info
Definition: netmsgs.h:365
const int NMHashNoIdx
hash no index value
#define _NMSET_VAL(_this, pv, T)
Set field value.
Definition: nmLibInternal.c:74
NMFType_T m_eFType
field type
Definition: netmsgs.h:383
#define NMFID_NONE
no field id (reserved)
Definition: netmsgs.h:211
#define NM_OK
not an error, success
Definition: netmsgs.h:70
int nmSetF64(const NMFieldDef_T *pFieldDef, void *pValIn, double *pValOut)
Helper function to set a 64-bit floating point number.
NMFieldThis_T m_this
specific field information
Definition: netmsgs.h:385
8-bit bool 0/1 bool_t
Definition: netmsgs.h:117
int nmSetS8(const NMFieldDef_T *pFieldDef, void *pValIn, signed char *pValOut)
Helper function to set a signed 8-bit integer.
int nmSetU8(const NMFieldDef_T *pFieldDef, void *pValIn, byte_t *pValOut)
Helper function to set an unsigned 8-bit integer.
int nmSetF32(const NMFieldDef_T *pFieldDef, void *pValIn, float *pValOut)
Helper function to set a 32-bit floating point number.
const byte_t NMHashTbl[]
NMFieldThisU32_T m_u32
[unsigned] 32-bit integer specific info
Definition: netmsgs.h:367
#define _NMCHK_MAX(fname, _this, v, T, fmt)
Check value is &le; maximum.
int nmSetS16(const NMFieldDef_T *pFieldDef, void *pValIn, short *pValOut)
Helper function to set a signed 16-bit integer.
const char * m_sFName
field string name
Definition: netmsgs.h:381
const int NMHashOffset
hash base offset
void nmTraceField(const NMFieldDef_T *pFieldDef, byte_t buf[], size_t uCount, uint_t uDepth, const char *sFmt,...)
Trace packing/unpacking of a message field.
int nmSetS32(const NMFieldDef_T *pFieldDef, void *pValIn, int *pValOut)
Helper function to set a signed 32-bit integer.
NMFieldThisF32_T m_f32
32-bit fpn specific info
Definition: netmsgs.h:369
NMFieldThisU64_T m_u64
[unsigned] 64-bit integer specific info
Definition: netmsgs.h:368
int nmSetS64(const NMFieldDef_T *pFieldDef, void *pValIn, long long *pValOut)
Helper function to set a signed 64-bit integer.
Internal intra-library declarations.
int nmSetU64(const NMFieldDef_T *pFieldDef, void *pValIn, ulonglong_t *pValOut)
Helper function to set an unsigned 64-bit integer.
void nmPrintBuf(FILE *fp, const char *sPreface, byte_t buf[], size_t uCount, size_t uNLFreq, uint_t uCol)
Pretty print buffer to opened file stream.
Definition: nmLibUtils.c:138
#define _NMCHK_MIN(fname, _this, v, T, fmt)
Check value is &ge; minimum.
Definition: nmLibInternal.c:88
NMFieldThisU16_T m_u16
[unsigned] 16-bit integer specific info
Definition: netmsgs.h:366
Network Messaging declarations.
int nmSetU16(const NMFieldDef_T *pFieldDef, void *pValIn, ushort_t *pValOut)
Helper function to set an unsigned 16-bit integer.
NMFieldThisF64_T m_f64
64-bit fpn specific info
Definition: netmsgs.h:370
uint_t m_eFId
filed id (message/struct unique)
Definition: netmsgs.h:382