Mistake on this page?
Report an issue in GitHub or email us
UsefulBuf.h
Go to the documentation of this file.
1 /*==============================================================================
2  Copyright (c) 2016-2018, The Linux Foundation.
3  Copyright (c) 2018-2019, Laurence Lundblade.
4  All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are
8 met:
9  * Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11  * Redistributions in binary form must reproduce the above
12  copyright notice, this list of conditions and the following
13  disclaimer in the documentation and/or other materials provided
14  with the distribution.
15  * Neither the name of The Linux Foundation nor the names of its
16  contributors, nor the name "Laurence Lundblade" may be used to
17  endorse or promote products derived from this software without
18  specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
21 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
24 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
30 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  ==============================================================================*/
32 
33 /*===================================================================================
34  FILE: UsefulBuf.h
35 
36  DESCRIPTION: General purpose input and output buffers
37 
38  EDIT HISTORY FOR FILE:
39 
40  This section contains comments describing changes made to the module.
41  Notice that changes are listed in reverse chronological order.
42 
43  when who what, where, why
44  -------- ---- ---------------------------------------------------
45  12/17/2018 llundblade Remove const from UsefulBuf and UsefulBufC .len
46  12/13/2018 llundblade Documentation improvements
47  09/18/2018 llundblade Cleaner distinction between UsefulBuf and UsefulBufC
48  02/02/18 llundbla Full support for integers in and out; fix pointer
49  alignment bug. Incompatible change: integers in/out
50  are now in network byte order.
51  08/12/17 llundbla Added UsefulOutBuf_AtStart and UsefulBuf_Find
52  06/27/17 llundbla Fix UsefulBuf_Compare() bug. Only affected comparison
53  for < or > for unequal length buffers. Added
54  UsefulBuf_Set() function.
55  05/30/17 llundbla Functions for NULL UsefulBufs and const / unconst
56  11/13/16 llundbla Initial Version.
57 
58 
59  =====================================================================================*/
60 
61 #ifndef _UsefulBuf_h
62 #define _UsefulBuf_h
63 
64 
65 #include <stdint.h> // for uint8_t, uint16_t....
66 #include <string.h> // for strlen, memcpy, memmove, memset
67 #include <stddef.h> // for size_t
68 
69 /**
70  @file UsefulBuf.h
71 
72  The goal of this code is to make buffer and pointer manipulation
73  easier and safer when working with binary data.
74 
75  You use the UsefulBuf, UsefulOutBuf and UsefulInputBuf
76  structures to represent buffers rather than ad hoc pointers and lengths.
77 
78  With these it will often be possible to write code that does little or no
79  direct pointer manipulation for copying and formatting data. For example
80  the QCBOR encoder was rewritten using these and has no direct pointer
81  manipulation.
82 
83  While it is true that object code using these functions will be a little
84  larger and slower than a white-knuckle clever use of pointers might be, but
85  not by that much or enough to have an affect for most use cases. For
86  security-oriented code this is highly worthwhile. Clarity, simplicity,
87  reviewability and are more important.
88 
89  There are some extra sanity and double checks in this code to help catch
90  coding errors and simple memory corruption. They are helpful, but not a
91  substitute for proper code review, input validation and such.
92 
93  This code consists of a lot of inline functions and a few that are not.
94  It should not generate very much object code, especially with the
95  optimizer turned up to -Os or -O3. The idea is that the inline
96  functions are easier to review and understand and the optimizer does
97  the work of making the code small.
98  */
99 
100 
101 /*...... This is a ruler that is 80 characters long...........................*/
102 
103 /**
104  UsefulBufC and UsefulBuf are simple data structures to hold a pointer and
105  length for a binary data. In C99 this data structure can be passed on the
106  stack making a lot of code cleaner than carrying around a pointer and
107  length as two parameters.
108 
109  This is also conducive to secure code practice as the lengths are
110  always carried with the pointer and the convention for handling a
111  pointer and a length is clear.
112 
113  While it might be possible to write buffer and pointer code more
114  efficiently in some use cases, the thought is that unless there is an
115  extreme need for performance (e.g., you are building a gigabit-per-second
116  IP router), it is probably better to have cleaner code you can be most
117  certain about the security of.
118 
119  The non-const UsefulBuf is usually used to refer a buffer to be filled in.
120  The length is the size of the buffer.
121 
122  The const UsefulBufC is usually used to refer to some data that has been
123  filled in. The length is amount of valid data pointed to.
124 
125  A common use is to pass a UsefulBuf to a function, the function fills it
126  in, the function returns a UsefulBufC. The pointer is the same in both.
127 
128  A UsefulBuf is NULL, it has no value, when the ptr in it is NULL.
129 
130  There are utility functions for the following:
131  - Checking for UsefulBufs that are NULL, empty or both
132  - Copying, copying with offset, copying head or tail
133  - Comparing and finding substrings
134  - Initializating
135  - Create initialized const UsefulBufC from compiler literals
136  - Create initialized const UsefulBufC from NULL-terminated string
137  - Make an empty UsefulBuf on the stack
138 
139  See also UsefulOutBuf. It is a richer structure that has both the size of
140  the valid data and the size of the buffer.
141 
142  UsefulBuf is only 16 or 8 bytes on a 64- or 32-bit machine so it can go
143  on the stack and be a function parameter or return value.
144 
145  UsefulBuf is kind of like the Useful Pot Pooh gave Eeyore on his birthday.
146  Eeyore's balloon fits beautifully, "it goes in and out like anything".
147 
148 */
149 typedef struct useful_buf_c {
150  const void *ptr;
151  size_t len;
152 } UsefulBufC;
153 
154 
155 /**
156  The non-const UsefulBuf typically used for some allocated memory
157  that is to be filled in. The len is the amount of memory,
158  not the length of the valid data in the buffer.
159  */
160 typedef struct useful_buf {
161  void *ptr;
162  size_t len;
163 } UsefulBuf;
164 
165 
166 /**
167  A "NULL" UsefulBufC is one that has no value in the same way a NULL pointer has no value.
168  A UsefulBuf is NULL when the ptr field is NULL. It doesn't matter what len is.
169  See UsefulBuf_IsEmpty() for the distinction between NULL and empty.
170  */
171 #define NULLUsefulBufC ((UsefulBufC) {NULL, 0})
172 
173 /** A NULL UsefulBuf is one that has no memory associated the say way
174  NULL points to nothing. It does not matter what len is.
175  */
176 #define NULLUsefulBuf ((UsefulBuf) {NULL, 0})
177 
178 
179 /**
180  @brief Check if a UsefulBuf is NULL or not
181 
182  @param[in] UB The UsefulBuf to check
183 
184  @return 1 if it is NULL, 0 if not.
185  */
186 static inline int UsefulBuf_IsNULL(UsefulBuf UB) {
187  return !UB.ptr;
188 }
189 
190 
191 /**
192  @brief Check if a UsefulBufC is NULL or not
193 
194  @param[in] UB The UsefulBufC to check
195 
196  @return 1 if it is NULL, 0 if not.
197  */
198 static inline int UsefulBuf_IsNULLC(UsefulBufC UB) {
199  return !UB.ptr;
200 }
201 
202 
203 /**
204  @brief Check if a UsefulBuf is empty or not
205 
206  @param[in] UB The UsefulBuf to check
207 
208  @return 1 if it is empty, 0 if not.
209 
210  An "Empty" UsefulBuf is one that has a value and can be considered to be set,
211  but that value is of zero length. It is empty when len is zero. It
212  doesn't matter what the ptr is.
213 
214  A lot of uses will not need to clearly distinguish a NULL UsefulBuf
215  from an empty one and can have the ptr NULL and the len 0. However
216  if a use of UsefulBuf needs to make a distinction then ptr should
217  not be NULL when the UsefulBuf is considered empty, but not NULL.
218 
219  */
220 static inline int UsefulBuf_IsEmpty(UsefulBuf UB) {
221  return !UB.len;
222 }
223 
224 
225 /**
226  @brief Check if a UsefulBufC is empty or not
227 
228  @param[in] UB The UsefulBufC to check
229 
230  @return 1 if it is empty, 0 if not.
231  */
232 static inline int UsefulBuf_IsEmptyC(UsefulBufC UB) {
233  return !UB.len;
234 }
235 
236 
237 /**
238  @brief Check if a UsefulBuf is NULL or empty
239 
240  @param[in] UB The UsefulBuf to check
241 
242  @return 1 if it is either NULL or empty, 0 if not.
243  */
244 static inline int UsefulBuf_IsNULLOrEmpty(UsefulBuf UB) {
245  return UsefulBuf_IsEmpty(UB) || UsefulBuf_IsNULL(UB);
246 }
247 
248 
249 /**
250  @brief Check if a UsefulBufC is NULL or empty
251 
252  @param[in] UB The UsefulBufC to check
253 
254  @return 1 if it is either NULL or empty, 0 if not.
255  */
256 static inline int UsefulBuf_IsNULLOrEmptyC(UsefulBufC UB) {
257  return UsefulBuf_IsEmptyC(UB) || UsefulBuf_IsNULLC(UB);
258 }
259 
260 
261 /**
262  @brief Convert a non const UsefulBuf to a const UsefulBufC
263 
264  @param[in] UB The UsefulBuf to convert
265 
266  Returns: a UsefulBufC struct
267  */
268 
269 static inline UsefulBufC UsefulBuf_Const(const UsefulBuf UB)
270 {
271  return (UsefulBufC){UB.ptr, UB.len};
272 }
273 
274 
275 /**
276  @brief Convert a const UsefulBufC to a non-const UsefulBuf
277 
278  @param[in] UBC The UsefulBuf to convert
279 
280  Returns: a non const UsefulBuf struct
281  */
282 static inline UsefulBuf UsefulBuf_Unconst(const UsefulBufC UBC)
283 {
284  return (UsefulBuf){(void *)UBC.ptr, UBC.len};
285 }
286 
287 
288 /**
289  Convert a literal string to a UsefulBufC.
290 
291  szString must be a literal string that you can take sizeof.
292  This is better for literal strings than UsefulBuf_FromSZ()
293  because it generates less code. It will not work on
294  non-literal strings.
295 
296  The terminating \0 (NULL) is NOT included in the length!
297 
298  */
299 #define UsefulBuf_FROM_SZ_LITERAL(szString) \
300  ((UsefulBufC) {(szString), sizeof(szString)-1})
301 
302 
303 /**
304  Convert a literal byte array to a UsefulBufC.
305 
306  pBytes must be a literal string that you can take sizeof.
307  It will not work on non-literal arrays.
308 
309  */
310 #define UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pBytes) \
311  ((UsefulBufC) {(pBytes), sizeof(pBytes)})
312 
313 
314 /**
315  Make an automatic variable with name of type UsefulBuf and point it to a stack
316  variable of the give size
317  */
318 #define UsefulBuf_MAKE_STACK_UB(name, size) \
319  uint8_t __pBuf##name[(size)];\
320  UsefulBuf name = {__pBuf##name , sizeof( __pBuf##name )}
321 
322 
323 /**
324  Make a byte array in to a UsefulBuf
325  */
326 #define UsefulBuf_FROM_BYTE_ARRAY(pBytes) \
327  ((UsefulBuf) {(pBytes), sizeof(pBytes)})
328 
329 /**
330  @brief Convert a NULL terminated string to a UsefulBufC.
331 
332  @param[in] szString The string to convert
333 
334  @return a UsefulBufC struct
335 
336  UsefulBufC.ptr points to the string so it's lifetime
337  must be maintained.
338 
339  The terminating \0 (NULL) is NOT included in the length!
340 
341  */
342 static inline UsefulBufC UsefulBuf_FromSZ(const char *szString){
343  return ((UsefulBufC) {szString, strlen(szString)});
344 }
345 
346 
347 /**
348  @brief Copy one UsefulBuf into another at an offset
349 
350  @param[in] Dest Destiation buffer to copy into
351  @param[in] uOffset The byte offset in Dest at which to copy to
352  @param[in] Src The bytes to copy
353 
354  @return Pointer and length of the copy
355 
356  This fails and returns NULLUsefulBufC Src.len + uOffset > Dest.len.
357 
358  Like memcpy, there is no check for NULL. If NULL is passed
359  this will crash.
360 
361  There is an assumption that there is valid data in Dest up to
362  uOffset as the resulting UsefulBufC returned starts
363  at the beginning of Dest and goes to Src.len + uOffset.
364 
365  */
366 UsefulBufC UsefulBuf_CopyOffset(UsefulBuf Dest, size_t uOffset, const UsefulBufC Src);
367 
368 
369 /**
370  @brief Copy one UsefulBuf into another
371 
372  @param[in] Dest The destination buffer to copy into
373  @param[out] Src The source to copy from
374 
375  @return filled in UsefulBufC on success, NULLUsefulBufC on failure
376 
377  This fails if Src.len is greater than Dest.len.
378 
379  Note that like memcpy, the pointers are not checked and
380  this will crash, rather than return NULLUsefulBufC if
381  they are NULL or invalid.
382 
383  Results are undefined if Dest and Src overlap.
384 
385  */
386 static inline UsefulBufC UsefulBuf_Copy(UsefulBuf Dest, const UsefulBufC Src) {
387  return UsefulBuf_CopyOffset(Dest, 0, Src);
388 }
389 
390 
391 /**
392  @brief Set all bytes in a UsefulBuf to a value, for example 0
393 
394  @param[in] pDest The destination buffer to copy into
395  @param[in] value The value to set the bytes to
396 
397  Note that like memset, the pointer in pDest is not checked and
398  this will crash if NULL or invalid.
399 
400  */
401 static inline UsefulBufC UsefulBuf_Set(UsefulBuf pDest, uint8_t value)
402 {
403  memset(pDest.ptr, value, pDest.len);
404  return (UsefulBufC){pDest.ptr, pDest.len};
405 }
406 
407 
408 /**
409  @brief Copy a pointer into a UsefulBuf
410 
411  @param[in,out] Dest The destination buffer to copy into
412  @param[in] ptr The source to copy from
413  @param[in] len Length of the source; amoutn to copy
414 
415  @return 0 on success, 1 on failure
416 
417  This fails and returns NULLUsefulBufC if len is greater than
418  pDest->len.
419 
420  Note that like memcpy, the pointers are not checked and
421  this will crash, rather than return 1 if they are NULL
422  or invalid.
423 
424  */
425 inline static UsefulBufC UsefulBuf_CopyPtr(UsefulBuf Dest, const void *ptr, size_t len)
426 {
427  return UsefulBuf_Copy(Dest, (UsefulBufC){ptr, len});
428 }
429 
430 
431 /**
432  @brief Returns a truncation of a UsefulBufC
433 
434  @param[in] UB The buffer to get the head of
435  @param[in] uAmount The number of bytes in the head
436 
437  @return A UsefulBufC that is the head of UB
438 
439  */
440 static inline UsefulBufC UsefulBuf_Head(UsefulBufC UB, size_t uAmount)
441 {
442  if(uAmount > UB.len) {
443  return NULLUsefulBufC;
444  }
445  return (UsefulBufC){UB.ptr, uAmount};
446 }
447 
448 
449 /**
450  @brief Returns bytes from the end of a UsefulBufC
451 
452  @param[in] UB The buffer to get the tail of
453  @param[in] uAmount The offset from the start where the tail is to begin
454 
455  @return A UsefulBufC that is the tail of UB or NULLUsefulBufC if
456  uAmount is greater than the length of the UsefulBufC
457 
458  If the input UsefulBufC is NULL, but the len is not, then the
459  length of the tail will be calculated and returned along
460  with a NULL ptr.
461  */
462 static inline UsefulBufC UsefulBuf_Tail(UsefulBufC UB, size_t uAmount)
463 {
464  UsefulBufC ReturnValue;
465 
466  if(uAmount > UB.len) {
467  ReturnValue = NULLUsefulBufC;
468  } else if(UB.ptr == NULL) {
469  ReturnValue = (UsefulBufC){NULL, UB.len - uAmount};
470  } else {
471  ReturnValue = (UsefulBufC){(uint8_t *)UB.ptr + uAmount, UB.len - uAmount};
472  }
473 
474  return ReturnValue;
475 }
476 
477 
478 /**
479  @brief Compare two UsefulBufCs
480 
481  @param[in] UB1 The destination buffer to copy into
482  @param[in] UB2 The source to copy from
483 
484  @return 0 if equal...
485 
486  Returns a negative value if UB1 if is less than UB2. UB1 is
487  less than UB2 if it is shorter or the first byte that is not
488  the same is less.
489 
490  Returns 0 if the UsefulBufs are the same.
491 
492  Returns a positive value if UB2 is less than UB1.
493 
494  All that is of significance is that the result is positive,
495  negative or 0. (This doesn't return the difference between
496  the first non-matching byte like memcmp).
497 
498  */
499 int UsefulBuf_Compare(const UsefulBufC UB1, const UsefulBufC UB2);
500 
501 
502 /**
503  @brief Find one UsefulBuf in another
504 
505  @param[in] BytesToSearch UsefulBuf to search through
506  @param[in] BytesToFind UsefulBuf with bytes to be found
507 
508  @return position of found bytes or SIZE_MAX if not found.
509 
510  */
511 size_t UsefulBuf_FindBytes(UsefulBufC BytesToSearch, UsefulBufC BytesToFind);
512 
513 
514 
515 
516 #if 0 // NOT_DEPRECATED
517 /** Deprecated macro; use UsefulBuf_FROM_SZ_LITERAL instead */
518 #define SZLiteralToUsefulBufC(szString) \
519  ((UsefulBufC) {(szString), sizeof(szString)-1})
520 
521 /** Deprecated macro; use UsefulBuf_MAKE_STACK_UB instead */
522 #define MakeUsefulBufOnStack(name, size) \
523  uint8_t __pBuf##name[(size)];\
524  UsefulBuf name = {__pBuf##name , sizeof( __pBuf##name )}
525 
526 /** Deprecated macro; use UsefulBuf_FROM_BYTE_ARRAY_LITERAL instead */
527 #define ByteArrayLiteralToUsefulBufC(pBytes) \
528  ((UsefulBufC) {(pBytes), sizeof(pBytes)})
529 
530 /** Deprecated function; use UsefulBuf_Unconst() instead */
531 static inline UsefulBuf UsefulBufC_Unconst(const UsefulBufC UBC)
532 {
533  return (UsefulBuf){(void *)UBC.ptr, UBC.len};
534 }
535 #endif
536 
537 
538 
539 /*
540  Convenient functions to avoid type punning, compiler warnings and such
541  The optimizer reduces them to a simple assignment
542  This is a crusty corner of C. It shouldn't be this hard.
543  */
544 static inline uint32_t UsefulBufUtil_CopyFloatToUint32(float f)
545 {
546  uint32_t u32;
547  memcpy(&u32, &f, sizeof(uint32_t));
548  return u32;
549 }
550 
551 static inline uint64_t UsefulBufUtil_CopyDoubleToUint64(double d)
552 {
553  uint64_t u64;
554  memcpy(&u64, &d, sizeof(uint64_t));
555  return u64;
556 }
557 
558 static inline double UsefulBufUtil_CopyUint64ToDouble(uint64_t u64)
559 {
560  double d;
561  memcpy(&d, &u64, sizeof(uint64_t));
562  return d;
563 }
564 
565 static inline float UsefulBufUtil_CopyUint32ToFloat(uint32_t u32)
566 {
567  float f;
568  memcpy(&f, &u32, sizeof(uint32_t));
569  return f;
570 }
571 
572 
573 
574 
575 
576 /**
577  UsefulOutBuf is a structure and functions (an object) that are good
578  for serializing data into a buffer such as is often done with network
579  protocols or data written to files.
580 
581  The main idea is that all the pointer manipulation for adding data is
582  done by UsefulOutBuf functions so the caller doesn't have to do any.
583  All the pointer manipulation is centralized here. This code will
584  have been reviewed and written carefully so it spares the caller of
585  much of this work and results in much safer code with much less work.
586 
587  The functions to add data to the output buffer always check the
588  length and will never write off the end of the output buffer. If an
589  attempt to add data that will not fit is made, an internal error flag
590  will be set and further attempts to add data will not do anything.
591 
592  Basically, if you initialized with the correct buffer, there is no
593  way to ever write off the end of that buffer when calling the Add
594  and Insert functions here.
595 
596  The functions to add data do not return an error. The working model
597  is that the caller just makes all the calls to add data without any
598  error checking on each one. The error is instead checked after all the
599  data is added when the result is to be used. This makes the caller's
600  code cleaner.
601 
602  There is a utility function to get the error status anytime along the
603  way if the caller wants. There are functions to see how much room is
604  left and see if some data will fit too, but their use is generally
605  not necessary.
606 
607  The general call flow is like this:
608 
609  - Initialize the UsefulOutBuf with the buffer that is to have the
610  data added. The caller allocates the buffer. It can be heap
611  or stack or shared memory (or other).
612 
613  - Make calls to add data to the output buffer. Insert and append
614  are both supported. The append and insert calls will never write
615  off the end of the buffer.
616 
617  - When all data is added, check the error status to make sure
618  everything fit.
619 
620  - Get the resulting serialized data either as a UsefulBuf (a
621  pointer and length) or have it copied to another buffer.
622 
623  UsefulOutBuf can be initialized with just a buffer length by passing
624  NULL as the pointer to the output buffer. This is useful if you want
625  to go through the whole serialization process to either see if it
626  will fit into a given buffer or compute the size of the buffer
627  needed. Pass a very large buffer size when calling Init, if you want
628  just to compute the size.
629 
630  Some inexpensive simple sanity checks are performed before every data
631  addition to guard against use of an uninitialized or corrupted
632  UsefulOutBuf.
633 
634  This has been used to create a CBOR encoder. The CBOR encoder has
635  almost no pointer manipulation in it, is much easier to read, and
636  easier to review.
637 
638  A UsefulOutBuf is 27 bytes or 15 bytes on 64- or 32-bit machines so it
639  can go on the stack or be a C99 function parameter.
640  */
641 
642 typedef struct useful_out_buf {
643  UsefulBuf UB; // Memory that is being output to
644  size_t data_len; // length of the data
645  uint16_t magic; // Used to detect corruption and lack of initialization
646  uint8_t err;
647 } UsefulOutBuf;
648 
649 
650 /**
651  @brief Initialize and supply the actual output buffer
652 
653  @param[out] me The UsefulOutBuf to initialize
654  @param[in] Storage Buffer to output into
655 
656  Intializes the UsefulOutBuf with storage. Sets the current position
657  to the beginning of the buffer clears the error.
658 
659  This must be called before the UsefulOutBuf is used.
660  */
661 void UsefulOutBuf_Init(UsefulOutBuf *me, UsefulBuf Storage);
662 
663 
664 
665 
666 /** Convenience marco to make a UsefulOutBuf on the stack and
667  initialize it with stack buffer
668  */
669 #define UsefulOutBuf_MakeOnStack(name, size) \
670  uint8_t __pBuf##name[(size)];\
671  UsefulOutBuf name;\
672  UsefulOutBuf_Init(&(name), (UsefulBuf){__pBuf##name, (size)});
673 
674 
675 
676 /**
677  @brief Reset a UsefulOutBuf for re use
678 
679  @param[in] me Pointer to the UsefulOutBuf
680 
681  This sets the amount of data in the output buffer to none and
682  clears the error state.
683 
684  The output buffer is still the same one and size as from the
685  UsefulOutBuf_Init() call.
686 
687  It doesn't zero the data, just resets to 0 bytes of valid data.
688  */
689 static inline void UsefulOutBuf_Reset(UsefulOutBuf *me)
690 {
691  me->data_len = 0;
692  me->err = 0;
693 }
694 
695 
696 /**
697  @brief Returns position of end of data in the UsefulOutBuf
698 
699  @param[in] me Pointer to the UsefulOutBuf
700 
701  @return position of end of data
702 
703  On a freshly initialized UsefulOutBuf with no data added, this will
704  return 0. After ten bytes have been added, it will return 10 and so
705  on.
706 
707  Generally callers will not need this function for most uses of
708  UsefulOutBuf.
709 
710  */
711 static inline size_t UsefulOutBuf_GetEndPosition(UsefulOutBuf *me)
712 {
713  return me->data_len;
714 }
715 
716 
717 /**
718  @brief Returns whether any data has been added to the UsefulOutBuf
719 
720  @param[in] me Pointer to the UsefulOutBuf
721 
722  @return 1 if output position is at start
723 
724  */
725 static inline int UsefulOutBuf_AtStart(UsefulOutBuf *me)
726 {
727  return 0 == me->data_len;
728 }
729 
730 
731 /**
732  @brief Inserts bytes into the UsefulOutBuf
733 
734  @param[in] me Pointer to the UsefulOutBuf
735  @param[in] NewData UsefulBuf with the bytes to insert
736  @param[in] uPos Index in output buffer at which to insert
737 
738  NewData is the pointer and length for the bytes to be added to the
739  output buffer. There must be room in the output buffer for all of
740  NewData or an error will occur.
741 
742  The insertion point must be between 0 and the current valid data. If
743  not an error will occur. Appending data to the output buffer is
744  achieved by inserting at the end of the valid data. This can be
745  retrieved by calling UsefulOutBuf_GetEndPosition().
746 
747  When insertion is performed, the bytes between the insertion point and
748  the end of data previously added to the output buffer is slid to the
749  right to make room for the new data.
750 
751  Overlapping buffers are OK. NewData can point to data in the output
752  buffer.
753 
754  If an error occurs an error state is set in the UsefulOutBuf. No
755  error is returned. All subsequent attempts to add data will do
756  nothing.
757 
758  Call UsefulOutBuf_GetError() to find out if there is an error. This
759  is usually not needed until all additions of data are complete.
760 
761  */
762 void UsefulOutBuf_InsertUsefulBuf(UsefulOutBuf *me, UsefulBufC NewData, size_t uPos);
763 
764 
765 /**
766  @brief Insert a data buffer into the UsefulOutBuf
767 
768  @param[in] me Pointer to the UsefulOutBul
769  @param[in] pBytes Pointer to the bytes to insert
770  @param[in] uLen Length of the bytes to insert
771  @param[in] uPos Index in output buffer at which to insert
772 
773  See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
774  the difference being a pointer and length is passed in rather than an
775  UsefulBuf.
776 
777  */
778 static inline void UsefulOutBuf_InsertData(UsefulOutBuf *me, const void *pBytes, size_t uLen, size_t uPos)
779 {
780  UsefulBufC Data = {pBytes, uLen};
781  UsefulOutBuf_InsertUsefulBuf(me, Data, uPos);
782 }
783 
784 
785 /**
786  @brief Insert a NULL-terminated string into the UsefulOutBuf
787 
788  @param[in] me Pointer to the UsefulOutBuf
789  @param[in] szString string to append
790 
791  */
792 static inline void UsefulOutBuf_InsertString(UsefulOutBuf *me, const char *szString, size_t uPos)
793 {
794  UsefulOutBuf_InsertUsefulBuf(me, (UsefulBufC){szString, strlen(szString)}, uPos);
795 }
796 
797 
798 /**
799  @brief Insert a byte into the UsefulOutBuf
800 
801  @param[in] me Pointer to the UsefulOutBul
802  @param[in] byte Bytes to insert
803  @param[in] uPos Index in output buffer at which to insert
804 
805  See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
806  the difference being a single byte is to be inserted.
807  */
808 static inline void UsefulOutBuf_InsertByte(UsefulOutBuf *me, uint8_t byte, size_t uPos)
809 {
810  UsefulOutBuf_InsertData(me, &byte, 1, uPos);
811 }
812 
813 
814 /**
815  @brief Insert a 16-bit integer into the UsefulOutBuf
816 
817  @param[in] me Pointer to the UsefulOutBul
818  @param[in] uInteger16 Integer to insert
819  @param[in] uPos Index in output buffer at which to insert
820 
821  See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
822  the difference being a single byte is to be inserted.
823 
824  The integer will be inserted in network byte order (big endian)
825  */
826 static inline void UsefulOutBuf_InsertUint16(UsefulOutBuf *me, uint16_t uInteger16, size_t uPos)
827 {
828  // Converts native integer format to network byte order (big endian)
829  uint8_t tmp[2];
830  tmp[0] = (uInteger16 & 0xff00) >> 8;
831  tmp[1] = (uInteger16 & 0xff);
832  UsefulOutBuf_InsertData(me, tmp, 2, uPos);
833 }
834 
835 
836 /**
837  @brief Insert a 32-bit integer into the UsefulOutBuf
838 
839  @param[in] me Pointer to the UsefulOutBul
840  @param[in] uInteger32 Integer to insert
841  @param[in] uPos Index in output buffer at which to insert
842 
843  See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
844  the difference being a single byte is to be inserted.
845 
846  The integer will be inserted in network byte order (big endian)
847  */
848 static inline void UsefulOutBuf_InsertUint32(UsefulOutBuf *me, uint32_t uInteger32, size_t uPos)
849 {
850  // Converts native integer format to network byte order (big endian)
851  uint8_t tmp[4];
852  tmp[0] = (uInteger32 & 0xff000000) >> 24;
853  tmp[1] = (uInteger32 & 0xff0000) >> 16;
854  tmp[2] = (uInteger32 & 0xff00) >> 8;
855  tmp[3] = (uInteger32 & 0xff);
856  UsefulOutBuf_InsertData(me, tmp, 4, uPos);
857 }
858 
859 
860 /**
861  @brief Insert a 64-bit integer into the UsefulOutBuf
862 
863  @param[in] me Pointer to the UsefulOutBul
864  @param[in] uInteger64 Integer to insert
865  @param[in] uPos Index in output buffer at which to insert
866 
867  See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
868  the difference being a single byte is to be inserted.
869 
870  The integer will be inserted in network byte order (big endian)
871  */
872 static inline void UsefulOutBuf_InsertUint64(UsefulOutBuf *me, uint64_t uInteger64, size_t uPos)
873 {
874  // Converts native integer format to network byte order (big endian)
875  uint8_t tmp[8];
876  tmp[0] = (uInteger64 & 0xff00000000000000) >> 56;
877  tmp[1] = (uInteger64 & 0xff000000000000) >> 48;
878  tmp[2] = (uInteger64 & 0xff0000000000) >> 40;
879  tmp[3] = (uInteger64 & 0xff00000000) >> 32;
880  tmp[4] = (uInteger64 & 0xff000000) >> 24;
881  tmp[5] = (uInteger64 & 0xff0000) >> 16;
882  tmp[6] = (uInteger64 & 0xff00) >> 8;
883  tmp[7] = (uInteger64 & 0xff);
884  UsefulOutBuf_InsertData(me, tmp, 8, uPos);
885 }
886 
887 
888 /**
889  @brief Insert a float into the UsefulOutBuf
890 
891  @param[in] me Pointer to the UsefulOutBul
892  @param[in] f Integer to insert
893  @param[in] uPos Index in output buffer at which to insert
894 
895  See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
896  the difference being a single byte is to be inserted.
897 
898  The float will be inserted in network byte order (big endian)
899  */
900 static inline void UsefulOutBuf_InsertFloat(UsefulOutBuf *me, float f, size_t uPos)
901 {
902  UsefulOutBuf_InsertUint32(me, UsefulBufUtil_CopyFloatToUint32(f), uPos);
903 }
904 
905 
906 /**
907  @brief Insert a double into the UsefulOutBuf
908 
909  @param[in] me Pointer to the UsefulOutBul
910  @param[in] d Integer to insert
911  @param[in] uPos Index in output buffer at which to insert
912 
913  See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
914  the difference being a single byte is to be inserted.
915 
916  The double will be inserted in network byte order (big endian)
917  */
918 static inline void UsefulOutBuf_InsertDouble(UsefulOutBuf *me, double d, size_t uPos)
919 {
920  UsefulOutBuf_InsertUint64(me, UsefulBufUtil_CopyDoubleToUint64(d), uPos);
921 }
922 
923 
924 
925 /**
926  Append a UsefulBuf into the UsefulOutBuf
927 
928  @param[in] me Pointer to the UsefulOutBuf
929  @param[in] NewData UsefulBuf with the bytes to append
930 
931  See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
932  with the insertion point at the end of the valid data.
933 
934 */
935 static inline void UsefulOutBuf_AppendUsefulBuf(UsefulOutBuf *me, UsefulBufC NewData)
936 {
937  // An append is just a insert at the end
939 }
940 
941 
942 /**
943  Append bytes to the UsefulOutBuf
944 
945  @param[in] me Pointer to the UsefulOutBuf
946  @param[in] pBytes Pointer to bytes to append
947  @param[in] uLen Index in output buffer at which to append
948 
949  See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
950  with the insertion point at the end of the valid data.
951  */
952 
953 static inline void UsefulOutBuf_AppendData(UsefulOutBuf *me, const void *pBytes, size_t uLen)
954 {
955  UsefulBufC Data = {pBytes, uLen};
957 }
958 
959 
960 /**
961  Append a NULL-terminated string to the UsefulOutBuf
962 
963  @param[in] me Pointer to the UsefulOutBuf
964  @param[in] szString string to append
965 
966  */
967 static inline void UsefulOutBuf_AppendString(UsefulOutBuf *me, const char *szString)
968 {
969  UsefulOutBuf_AppendUsefulBuf(me, (UsefulBufC){szString, strlen(szString)});
970 }
971 
972 
973 /**
974  @brief Append a byte to the UsefulOutBuf
975 
976  @param[in] me Pointer to the UsefulOutBuf
977  @param[in] byte Bytes to append
978 
979  See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
980  with the insertion point at the end of the valid data.
981  */
982 static inline void UsefulOutBuf_AppendByte(UsefulOutBuf *me, uint8_t byte)
983 {
984  UsefulOutBuf_AppendData(me, &byte, 1);
985 }
986 
987 /**
988  @brief Append an integer to the UsefulOutBuf
989 
990  @param[in] me Pointer to the UsefulOutBuf
991  @param[in] uInteger16 Integer to append
992 
993  See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
994  with the insertion point at the end of the valid data.
995 
996  The integer will be appended in network byte order (big endian).
997  */
998 static inline void UsefulOutBuf_AppendUint16(UsefulOutBuf *me, uint16_t uInteger16){
1000 }
1001 
1002 /**
1003  @brief Append an integer to the UsefulOutBuf
1004 
1005  @param[in] me Pointer to the UsefulOutBuf
1006  @param[in] uInteger32 Integer to append
1007 
1008  See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
1009  with the insertion point at the end of the valid data.
1010 
1011  The integer will be appended in network byte order (big endian).
1012  */
1013 static inline void UsefulOutBuf_AppendUint32(UsefulOutBuf *me, uint32_t uInteger32){
1015 }
1016 
1017 /**
1018  @brief Append an integer to the UsefulOutBuf
1019 
1020  @param[in] me Pointer to the UsefulOutBuf
1021  @param[in] uInteger64 Integer to append
1022 
1023  See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
1024  with the insertion point at the end of the valid data.
1025 
1026  The integer will be appended in network byte order (big endian).
1027  */
1028 static inline void UsefulOutBuf_AppendUint64(UsefulOutBuf *me, uint64_t uInteger64){
1030 }
1031 
1032 
1033 /**
1034  @brief Append a float to the UsefulOutBuf
1035 
1036  @param[in] me Pointer to the UsefulOutBuf
1037  @param[in] f Float to append
1038 
1039  See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
1040  with the insertion point at the end of the valid data.
1041 
1042  The float will be appended in network byte order (big endian).
1043  */
1044 static inline void UsefulOutBuf_AppendFloat(UsefulOutBuf *me, float f){
1046 }
1047 
1048 /**
1049  @brief Append a float to the UsefulOutBuf
1050 
1051  @param[in] me Pointer to the UsefulOutBuf
1052  @param[in] d Double to append
1053 
1054  See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
1055  with the insertion point at the end of the valid data.
1056 
1057  The double will be appended in network byte order (big endian).
1058  */
1059 static inline void UsefulOutBuf_AppendDouble(UsefulOutBuf *me, double d){
1061 }
1062 
1063 /**
1064  @brief Returns the current error status
1065 
1066  @param[in] me Pointer to the UsefulOutBuf
1067 
1068  @return 0 if all OK, 1 on error
1069 
1070  This is the error status since the call to either
1071  UsefulOutBuf_Reset() of UsefulOutBuf_Init(). Once it goes into error
1072  state it will stay until one of those functions is called.
1073 
1074  Possible error conditions are:
1075  - bytes to be inserted will not fit
1076  - insertion point is out of buffer or past valid data
1077  - current position is off end of buffer (probably corruption or uninitialized)
1078  - detect corruption / uninitialized by bad magic number
1079  */
1080 
1081 static inline int UsefulOutBuf_GetError(UsefulOutBuf *me)
1082 {
1083  return me->err;
1084 }
1085 
1086 
1087 /**
1088  @brief Returns number of bytes unused used in the output buffer
1089 
1090  @param[in] me Pointer to the UsefulOutBuf
1091 
1092  @return Number of unused bytes or zero
1093 
1094  Because of the error handling strategy and checks in UsefulOutBuf_InsertUsefulBuf()
1095  it is usually not necessary to use this.
1096  */
1097 
1098 static inline size_t UsefulOutBuf_RoomLeft(UsefulOutBuf *me)
1099 {
1100  return me->UB.len - me->data_len;
1101 }
1102 
1103 
1104 /**
1105  @brief Returns true / false if some number of bytes will fit in the UsefulOutBuf
1106 
1107  @param[in] me Pointer to the UsefulOutBuf
1108  @param[in] uLen Number of bytes for which to check
1109 
1110  @return 1 or 0 if nLen bytes would fit
1111 
1112  Because of the error handling strategy and checks in UsefulOutBuf_InsertUsefulBuf()
1113  it is usually not necessary to use this.
1114  */
1115 
1116 static inline int UsefulOutBuf_WillItFit(UsefulOutBuf *me, size_t uLen)
1117 {
1118  return uLen <= UsefulOutBuf_RoomLeft(me);
1119 }
1120 
1121 
1122 /**
1123  @brief Returns the resulting valid data in a UsefulOutBuf
1124 
1125  @param[in] me Pointer to the UsefulOutBuf.
1126 
1127  @return The valid data in UsefulOutBuf.
1128 
1129  The storage for the returned data is Storage parameter passed
1130  to UsefulOutBuf_Init(). See also UsefulOutBuf_CopyOut().
1131 
1132  This can be called anytime and many times to get intermediate
1133  results. It doesn't change the data or reset the current position
1134  so you can keep adding data.
1135  */
1136 
1138 
1139 
1140 /**
1141  @brief Copies the valid data out into a supplied buffer
1142 
1143  @param[in] me Pointer to the UsefulOutBuf
1144  @param[out] Dest The destination buffer to copy into
1145 
1146  @return Pointer and length of copied data.
1147 
1148  This is the same as UsefulOutBuf_OutUBuf() except it copies the data.
1149 */
1150 
1152 
1153 
1154 
1155 
1156 
1157 
1158 
1159 
1160 
1161 
1162 
1163 
1164 
1165 /**
1166  UsefulInputBuf is the counterpart to UsefulOutBuf and is for parsing
1167  data read or received. Initialize it with the data
1168  from the network and its length. Then use the functions
1169  here to get the various data types out of it. It maintains a position
1170  for getting the next item. This means you don't have to track a
1171  pointer as you get each object. UsefulInputBuf does that for you and
1172  makes sure it never goes off the end of the buffer. The QCBOR
1173  implementation parser makes use of this for all its pointer math and
1174  length checking.
1175 
1176  UsefulInputBuf also maintains an internal error state so you do not have
1177  to. Once data has been requested off the end of the buffer, it goes
1178  into an error state. You can keep calling functions to get more data
1179  but they will either return 0 or NULL. As long as you don't
1180  dereference the NULL, you can wait until all data items have been
1181  fetched before checking for the error and this can simplify your
1182  code.
1183 
1184  The integer and float parsing expects network byte order (big endian).
1185  Network byte order is what is used by TCP/IP, CBOR and most internet
1186  protocols.
1187 
1188  Lots of inlining is used to keep code size down. The code optimizer,
1189  particularly with the -Os, also reduces code size a lot. The only
1190  non-inline code is UsefulInputBuf_GetBytes() which is less than 100
1191  bytes so use of UsefulInputBuf doesn't add much code for all the messy
1192  hard-to-get right issues with parsing in C that is solves.
1193 
1194  The parse context size is:
1195  64-bit machine: 16 + 8 + 2 + 1 (5 bytes padding to align) = 32 bytes
1196  32-bit machine: 8 + 4 + 2 + 1 (1 byte padding to align) = 16 bytes
1197 
1198  */
1199 
1200 #define UIB_MAGIC (0xB00F)
1201 
1202 typedef struct useful_input_buf {
1203  // Private data structure
1204  UsefulBufC UB; // Data being parsed
1205  size_t cursor; // Current offset in data being parse
1206  uint16_t magic; // Check for corrupted or uninitialized UsefulInputBuf
1207  uint8_t err; // Set request goes off end or magic number is bad
1208 } UsefulInputBuf;
1209 
1210 
1211 
1212 /**
1213  @brief Initialize the UsefulInputBuf structure before use.
1214 
1215  @param[in] me Pointer to the UsefulInputBuf instance.
1216  @param[in] UB Pointer to the data to parse.
1217 
1218  */
1219 static inline void UsefulInputBuf_Init(UsefulInputBuf *me, UsefulBufC UB)
1220 {
1221  me->cursor = 0;
1222  me->err = 0;
1223  me->magic = UIB_MAGIC;
1224  me->UB = UB;
1225 }
1226 
1227 
1228 /**
1229  @brief Returns current position in input buffer
1230 
1231  @param[in] me Pointer to the UsefulInputBuf.
1232 
1233  @return Integer position of the cursor
1234 
1235  The position that the next bytes will be returned from.
1236 
1237  */
1238 static inline size_t UsefulInputBuf_Tell(UsefulInputBuf *me)
1239 {
1240  return me->cursor;
1241 }
1242 
1243 
1244 /**
1245  @brief Sets current position in input buffer
1246 
1247  @param[in] me Pointer to the UsefulInputBuf.
1248  @param[in] uPos Position to set to
1249 
1250  If the position is off the end of the input buffer, the error state
1251  is entered and all functions will do nothing.
1252 
1253  Seeking to a valid position in the buffer will not reset the error
1254  state. Only re initialization will do that.
1255 
1256  */
1257 static inline void UsefulInputBuf_Seek(UsefulInputBuf *me, size_t uPos)
1258 {
1259  if(uPos > me->UB.len) {
1260  me->err = 1;
1261  } else {
1262  me->cursor = uPos;
1263  }
1264 }
1265 
1266 
1267 /**
1268  @brief Returns the number of bytes from the cursor to the end of the buffer,
1269  the uncomsummed bytes.
1270 
1271  @param[in] me Pointer to the UsefulInputBuf.
1272 
1273  @return number of bytes unconsumed or 0 on error.
1274 
1275  This is a critical function for input length validation. This does
1276  some pointer / offset math.
1277 
1278  Returns 0 if the cursor it invalid or corruption of the structure is
1279  detected.
1280 
1281  Code Reviewers: THIS FUNCTION DOES POINTER MATH
1282  */
1284 {
1285  // Magic number is messed up. Either the structure got overwritten
1286  // or was never initialized.
1287  if(me->magic != UIB_MAGIC) {
1288  return 0;
1289  }
1290 
1291  // The cursor is off the end of the input buffer given
1292  // Presuming there are no bugs in this code, this should never happen.
1293  // If it so, the struct was corrupted. The check is retained as
1294  // as a defense in case there is a bug in this code or the struct is corrupted.
1295  if(me->cursor > me->UB.len) {
1296  return 0;
1297  }
1298 
1299  // subtraction can't go neative because of check above
1300  return me->UB.len - me->cursor;
1301 }
1302 
1303 
1304 /**
1305  @brief Check if there are any unconsumed bytes
1306 
1307  @param[in] me Pointer to the UsefulInputBuf.
1308 
1309  @return 1 if len bytes are available after the cursor, and 0 if not
1310 
1311  */
1312 static inline int UsefulInputBuf_BytesAvailable(UsefulInputBuf *me, size_t uLen)
1313 {
1314  return UsefulInputBuf_BytesUnconsumed(me) >= uLen ? 1 : 0;
1315 }
1316 
1317 
1318 /**
1319  @brief Get pointer to bytes out of the input buffer
1320 
1321  @param[in] me Pointer to the UsefulInputBuf.
1322  @param[in] uNum Number of bytes to get
1323 
1324  @return Pointer to bytes.
1325 
1326  This consumes n bytes from the input buffer. It returns a pointer to
1327  the start of the n bytes.
1328 
1329  If there are not n bytes in the input buffer, NULL will be returned
1330  and an error will be set.
1331 
1332  It advances the current position by n bytes.
1333  */
1334 const void * UsefulInputBuf_GetBytes(UsefulInputBuf *me, size_t uNum);
1335 
1336 
1337 /**
1338  @brief Get UsefulBuf out of the input buffer
1339 
1340  @param[in] me Pointer to the UsefulInputBuf.
1341  @param[in] uNum Number of bytes to get
1342 
1343  @return UsefulBufC with ptr and length for bytes consumed.
1344 
1345  This consumes n bytes from the input buffer and returns the pointer
1346  and len to them as a UsefulBufC. The len returned will always be n.
1347 
1348  If there are not n bytes in the input buffer, UsefulBufC.ptr will be
1349  NULL and UsefulBufC.len will be 0. An error will be set.
1350 
1351  It advances the current position by n bytes.
1352  */
1354 {
1355  const void *pResult = UsefulInputBuf_GetBytes(me, uNum);
1356  if(!pResult) {
1357  return NULLUsefulBufC;
1358  } else {
1359  return (UsefulBufC){pResult, uNum};
1360  }
1361 }
1362 
1363 
1364 /**
1365  @brief Get a byte out of the input buffer.
1366 
1367  @param[in] me Pointer to the UsefulInputBuf.
1368 
1369  @return The byte
1370 
1371  This consumes 1 byte from the input buffer. It returns the byte.
1372 
1373  If there is not 1 byte in the buffer, 0 will be returned for the byte
1374  and an error set internally. You must check the error at some point
1375  to know whether the 0 was the real value or just returned in error,
1376  but you may not have to do that right away. Check the error state
1377  with UsefulInputBuf_GetError(). You can also know you are in the
1378  error state if UsefulInputBuf_GetBytes() returns NULL or the ptr from
1379  UsefulInputBuf_GetUsefulBuf() is NULL.
1380 
1381  It advances the current position by 1 byte.
1382  */
1383 static inline uint8_t UsefulInputBuf_GetByte(UsefulInputBuf *me)
1384 {
1385  const void *pResult = UsefulInputBuf_GetBytes(me, sizeof(uint8_t));
1386 
1387  return pResult ? *(uint8_t *)pResult : 0;
1388 }
1389 
1390 
1391 /**
1392  @brief Get a uint16_t out of the input buffer
1393 
1394  @param[in] me Pointer to the UsefulInputBuf.
1395 
1396  @return The uint16_t
1397 
1398  See UsefulInputBuf_GetByte(). This works the same, except it returns
1399  a uint16_t and two bytes are consumed.
1400 
1401  The input bytes must be in network order (big endian).
1402  */
1403 static inline uint16_t UsefulInputBuf_GetUint16(UsefulInputBuf *me)
1404 {
1405  const uint8_t *pResult = (const uint8_t *)UsefulInputBuf_GetBytes(me, sizeof(uint16_t));
1406 
1407  if(!pResult) {
1408  return 0;
1409  }
1410 
1411  return ((uint16_t)pResult[0] << 8) + (uint16_t)pResult[1];
1412 }
1413 
1414 
1415 /**
1416  @brief Get a uint32_t out of the input buffer
1417 
1418  @param[in] me Pointer to the UsefulInputBuf.
1419 
1420  @return The uint32_t
1421 
1422  See UsefulInputBuf_GetByte(). This works the same, except it returns
1423  a uint32_t and four bytes are consumed.
1424 
1425  The input bytes must be in network order (big endian).
1426  */
1427 static inline uint32_t UsefulInputBuf_GetUint32(UsefulInputBuf *me)
1428 {
1429  const uint8_t *pResult = (const uint8_t *)UsefulInputBuf_GetBytes(me, sizeof(uint32_t));
1430 
1431  if(!pResult) {
1432  return 0;
1433  }
1434 
1435  return ((uint32_t)pResult[0]<<24) +
1436  ((uint32_t)pResult[1]<<16) +
1437  ((uint32_t)pResult[2]<<8) +
1438  (uint32_t)pResult[3];
1439 }
1440 
1441 
1442 /**
1443  @brief Get a uint64_t out of the input buffer
1444 
1445  @param[in] me Pointer to the UsefulInputBuf.
1446 
1447  @return The uint64_t
1448 
1449  See UsefulInputBuf_GetByte(). This works the same, except it returns
1450  a uint64_t and eight bytes are consumed.
1451 
1452  The input bytes must be in network order (big endian).
1453  */
1454 static inline uint64_t UsefulInputBuf_GetUint64(UsefulInputBuf *me)
1455 {
1456  const uint8_t *pResult = (const uint8_t *)UsefulInputBuf_GetBytes(me, sizeof(uint64_t));
1457 
1458  if(!pResult) {
1459  return 0;
1460  }
1461 
1462  return ((uint64_t)pResult[0]<<56) +
1463  ((uint64_t)pResult[1]<<48) +
1464  ((uint64_t)pResult[2]<<40) +
1465  ((uint64_t)pResult[3]<<32) +
1466  ((uint64_t)pResult[4]<<24) +
1467  ((uint64_t)pResult[5]<<16) +
1468  ((uint64_t)pResult[6]<<8) +
1469  (uint64_t)pResult[7];
1470 }
1471 
1472 
1473 /**
1474  @brief Get a float out of the input buffer
1475 
1476  @param[in] me Pointer to the UsefulInputBuf.
1477 
1478  @return The float
1479 
1480  See UsefulInputBuf_GetByte(). This works the same, except it returns
1481  a float and four bytes are consumed.
1482 
1483  The input bytes must be in network order (big endian).
1484  */
1485 static inline float UsefulInputBuf_GetFloat(UsefulInputBuf *me)
1486 {
1487  uint32_t uResult = UsefulInputBuf_GetUint32(me);
1488 
1489  return uResult ? UsefulBufUtil_CopyUint32ToFloat(uResult) : 0;
1490 }
1491 
1492 /**
1493  @brief Get a double out of the input buffer
1494 
1495  @param[in] me Pointer to the UsefulInputBuf.
1496 
1497  @return The double
1498 
1499  See UsefulInputBuf_GetByte(). This works the same, except it returns
1500  a double and eight bytes are consumed.
1501 
1502  The input bytes must be in network order (big endian).
1503  */
1504 static inline double UsefulInputBuf_GetDouble(UsefulInputBuf *me)
1505 {
1506  uint64_t uResult = UsefulInputBuf_GetUint64(me);
1507 
1508  return uResult ? UsefulBufUtil_CopyUint64ToDouble(uResult) : 0;
1509 }
1510 
1511 
1512 /**
1513  @brief Get the error status
1514 
1515  @param[in] me Pointer to the UsefulInputBuf.
1516 
1517  @return The error.
1518 
1519  Zero is success, non-zero is error. Once in the error state, the only
1520  way to clear it is to call Init again.
1521 
1522  You may be able to only check the error state at the end after all
1523  the Get()'s have been done, but if what you get later depends on what
1524  you get sooner you cannot. For example if you get a length or count
1525  of following items you will have to check the error.
1526 
1527  */
1529 {
1530  return me->err;
1531 }
1532 
1533 
1534 #endif // _UsefulBuf_h
1535 
1536 
static int UsefulInputBuf_GetError(UsefulInputBuf *me)
Get the error status.
Definition: UsefulBuf.h:1528
static void UsefulOutBuf_InsertByte(UsefulOutBuf *me, uint8_t byte, size_t uPos)
Insert a byte into the UsefulOutBuf.
Definition: UsefulBuf.h:808
int UsefulBuf_Compare(const UsefulBufC UB1, const UsefulBufC UB2)
Compare two UsefulBufCs.
static UsefulBufC UsefulBuf_Copy(UsefulBuf Dest, const UsefulBufC Src)
Copy one UsefulBuf into another.
Definition: UsefulBuf.h:386
static size_t UsefulInputBuf_Tell(UsefulInputBuf *me)
Returns current position in input buffer.
Definition: UsefulBuf.h:1238
static void UsefulOutBuf_Reset(UsefulOutBuf *me)
Reset a UsefulOutBuf for re use.
Definition: UsefulBuf.h:689
struct useful_out_buf UsefulOutBuf
UsefulOutBuf is a structure and functions (an object) that are good for serializing data into a buffe...
static void UsefulOutBuf_InsertDouble(UsefulOutBuf *me, double d, size_t uPos)
Insert a double into the UsefulOutBuf.
Definition: UsefulBuf.h:918
static int UsefulOutBuf_AtStart(UsefulOutBuf *me)
Returns whether any data has been added to the UsefulOutBuf.
Definition: UsefulBuf.h:725
void UsefulOutBuf_Init(UsefulOutBuf *me, UsefulBuf Storage)
Initialize and supply the actual output buffer.
static size_t UsefulOutBuf_GetEndPosition(UsefulOutBuf *me)
Returns position of end of data in the UsefulOutBuf.
Definition: UsefulBuf.h:711
static int UsefulBuf_IsEmpty(UsefulBuf UB)
Check if a UsefulBuf is empty or not.
Definition: UsefulBuf.h:220
static float UsefulInputBuf_GetFloat(UsefulInputBuf *me)
Get a float out of the input buffer.
Definition: UsefulBuf.h:1485
UsefulBufC UsefulOutBuf_CopyOut(UsefulOutBuf *me, UsefulBuf Dest)
Copies the valid data out into a supplied buffer.
struct useful_buf UsefulBuf
The non-const UsefulBuf typically used for some allocated memory that is to be filled in...
static void UsefulInputBuf_Seek(UsefulInputBuf *me, size_t uPos)
Sets current position in input buffer.
Definition: UsefulBuf.h:1257
struct useful_buf_c UsefulBufC
UsefulBufC and UsefulBuf are simple data structures to hold a pointer and length for a binary data...
static UsefulBufC UsefulBuf_Set(UsefulBuf pDest, uint8_t value)
Set all bytes in a UsefulBuf to a value, for example 0.
Definition: UsefulBuf.h:401
size_t UsefulBuf_FindBytes(UsefulBufC BytesToSearch, UsefulBufC BytesToFind)
Find one UsefulBuf in another.
The non-const UsefulBuf typically used for some allocated memory that is to be filled in...
Definition: UsefulBuf.h:160
static int UsefulInputBuf_BytesAvailable(UsefulInputBuf *me, size_t uLen)
Check if there are any unconsumed bytes.
Definition: UsefulBuf.h:1312
static UsefulBuf UsefulBuf_Unconst(const UsefulBufC UBC)
Convert a const UsefulBufC to a non-const UsefulBuf.
Definition: UsefulBuf.h:282
static size_t UsefulOutBuf_RoomLeft(UsefulOutBuf *me)
Returns number of bytes unused used in the output buffer.
Definition: UsefulBuf.h:1098
static double UsefulInputBuf_GetDouble(UsefulInputBuf *me)
Get a double out of the input buffer.
Definition: UsefulBuf.h:1504
static void UsefulOutBuf_AppendByte(UsefulOutBuf *me, uint8_t byte)
Append a byte to the UsefulOutBuf.
Definition: UsefulBuf.h:982
static size_t UsefulInputBuf_BytesUnconsumed(UsefulInputBuf *me)
Returns the number of bytes from the cursor to the end of the buffer, the uncomsummed bytes...
Definition: UsefulBuf.h:1283
static int UsefulBuf_IsNULLOrEmpty(UsefulBuf UB)
Check if a UsefulBuf is NULL or empty.
Definition: UsefulBuf.h:244
UsefulBufC and UsefulBuf are simple data structures to hold a pointer and length for a binary data...
Definition: UsefulBuf.h:149
static void UsefulOutBuf_AppendUint32(UsefulOutBuf *me, uint32_t uInteger32)
Append an integer to the UsefulOutBuf.
Definition: UsefulBuf.h:1013
#define UIB_MAGIC
UsefulInputBuf is the counterpart to UsefulOutBuf and is for parsing data read or received...
Definition: UsefulBuf.h:1200
void UsefulOutBuf_InsertUsefulBuf(UsefulOutBuf *me, UsefulBufC NewData, size_t uPos)
Inserts bytes into the UsefulOutBuf.
static int UsefulBuf_IsNULLOrEmptyC(UsefulBufC UB)
Check if a UsefulBufC is NULL or empty.
Definition: UsefulBuf.h:256
static void UsefulOutBuf_InsertData(UsefulOutBuf *me, const void *pBytes, size_t uLen, size_t uPos)
Insert a data buffer into the UsefulOutBuf.
Definition: UsefulBuf.h:778
static uint32_t UsefulInputBuf_GetUint32(UsefulInputBuf *me)
Get a uint32_t out of the input buffer.
Definition: UsefulBuf.h:1427
static void UsefulOutBuf_AppendUint16(UsefulOutBuf *me, uint16_t uInteger16)
Append an integer to the UsefulOutBuf.
Definition: UsefulBuf.h:998
const void * UsefulInputBuf_GetBytes(UsefulInputBuf *me, size_t uNum)
Get pointer to bytes out of the input buffer.
static int UsefulBuf_IsEmptyC(UsefulBufC UB)
Check if a UsefulBufC is empty or not.
Definition: UsefulBuf.h:232
static UsefulBufC UsefulInputBuf_GetUsefulBuf(UsefulInputBuf *me, size_t uNum)
Get UsefulBuf out of the input buffer.
Definition: UsefulBuf.h:1353
static void UsefulInputBuf_Init(UsefulInputBuf *me, UsefulBufC UB)
Initialize the UsefulInputBuf structure before use.
Definition: UsefulBuf.h:1219
static void UsefulOutBuf_AppendString(UsefulOutBuf *me, const char *szString)
Append a NULL-terminated string to the UsefulOutBuf.
Definition: UsefulBuf.h:967
static void UsefulOutBuf_InsertUint32(UsefulOutBuf *me, uint32_t uInteger32, size_t uPos)
Insert a 32-bit integer into the UsefulOutBuf.
Definition: UsefulBuf.h:848
static void UsefulOutBuf_AppendUint64(UsefulOutBuf *me, uint64_t uInteger64)
Append an integer to the UsefulOutBuf.
Definition: UsefulBuf.h:1028
static void UsefulOutBuf_AppendFloat(UsefulOutBuf *me, float f)
Append a float to the UsefulOutBuf.
Definition: UsefulBuf.h:1044
static void UsefulOutBuf_AppendUsefulBuf(UsefulOutBuf *me, UsefulBufC NewData)
Append a UsefulBuf into the UsefulOutBuf.
Definition: UsefulBuf.h:935
static uint8_t UsefulInputBuf_GetByte(UsefulInputBuf *me)
Get a byte out of the input buffer.
Definition: UsefulBuf.h:1383
static void UsefulOutBuf_InsertFloat(UsefulOutBuf *me, float f, size_t uPos)
Insert a float into the UsefulOutBuf.
Definition: UsefulBuf.h:900
static uint64_t UsefulInputBuf_GetUint64(UsefulInputBuf *me)
Get a uint64_t out of the input buffer.
Definition: UsefulBuf.h:1454
UsefulOutBuf is a structure and functions (an object) that are good for serializing data into a buffe...
Definition: UsefulBuf.h:642
static void UsefulOutBuf_InsertUint16(UsefulOutBuf *me, uint16_t uInteger16, size_t uPos)
Insert a 16-bit integer into the UsefulOutBuf.
Definition: UsefulBuf.h:826
static void UsefulOutBuf_InsertUint64(UsefulOutBuf *me, uint64_t uInteger64, size_t uPos)
Insert a 64-bit integer into the UsefulOutBuf.
Definition: UsefulBuf.h:872
static UsefulBufC UsefulBuf_Const(const UsefulBuf UB)
Convert a non const UsefulBuf to a const UsefulBufC.
Definition: UsefulBuf.h:269
static UsefulBufC UsefulBuf_FromSZ(const char *szString)
Convert a NULL terminated string to a UsefulBufC.
Definition: UsefulBuf.h:342
static void UsefulOutBuf_AppendDouble(UsefulOutBuf *me, double d)
Append a float to the UsefulOutBuf.
Definition: UsefulBuf.h:1059
static UsefulBufC UsefulBuf_Head(UsefulBufC UB, size_t uAmount)
Returns a truncation of a UsefulBufC.
Definition: UsefulBuf.h:440
static void UsefulOutBuf_AppendData(UsefulOutBuf *me, const void *pBytes, size_t uLen)
Append bytes to the UsefulOutBuf.
Definition: UsefulBuf.h:953
UsefulBufC UsefulOutBuf_OutUBuf(UsefulOutBuf *me)
Returns the resulting valid data in a UsefulOutBuf.
static int UsefulOutBuf_GetError(UsefulOutBuf *me)
Returns the current error status.
Definition: UsefulBuf.h:1081
static int UsefulBuf_IsNULLC(UsefulBufC UB)
Check if a UsefulBufC is NULL or not.
Definition: UsefulBuf.h:198
static int UsefulOutBuf_WillItFit(UsefulOutBuf *me, size_t uLen)
Returns true / false if some number of bytes will fit in the UsefulOutBuf.
Definition: UsefulBuf.h:1116
static UsefulBufC UsefulBuf_CopyPtr(UsefulBuf Dest, const void *ptr, size_t len)
Copy a pointer into a UsefulBuf.
Definition: UsefulBuf.h:425
static void UsefulOutBuf_InsertString(UsefulOutBuf *me, const char *szString, size_t uPos)
Insert a NULL-terminated string into the UsefulOutBuf.
Definition: UsefulBuf.h:792
static UsefulBufC UsefulBuf_Tail(UsefulBufC UB, size_t uAmount)
Returns bytes from the end of a UsefulBufC.
Definition: UsefulBuf.h:462
static int UsefulBuf_IsNULL(UsefulBuf UB)
Check if a UsefulBuf is NULL or not.
Definition: UsefulBuf.h:186
static uint16_t UsefulInputBuf_GetUint16(UsefulInputBuf *me)
Get a uint16_t out of the input buffer.
Definition: UsefulBuf.h:1403
UsefulBufC UsefulBuf_CopyOffset(UsefulBuf Dest, size_t uOffset, const UsefulBufC Src)
Copy one UsefulBuf into another at an offset.
#define NULLUsefulBufC
A "NULL" UsefulBufC is one that has no value in the same way a NULL pointer has no value...
Definition: UsefulBuf.h:171
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.