xref: /optee_os/core/lib/qcbor/inc/qcbor/UsefulBuf.h (revision b586599be35c4311337a5d8db5f4b5e5c81a754d)
1 // SPDX-License-Identifier: BSD-3-Clause
2 /* =========================================================================
3  * Copyright (c) 2016-2018, The Linux Foundation.
4  * Copyright (c) 2018-2024, Laurence Lundblade.
5  * Copyright (c) 2021, Arm Limited. All rights reserved.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are
10  * met:
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above
14  *       copyright notice, this list of conditions and the following
15  *       disclaimer in the documentation and/or other materials provided
16  *       with the distribution.
17  *     * Neither the name of The Linux Foundation nor the names of its
18  *       contributors, nor the name "Laurence Lundblade" may be used to
19  *       endorse or promote products derived from this software without
20  *       specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
23  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
26  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
32  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  * ========================================================================= */
34 
35 /*============================================================================
36  FILE:  UsefulBuf.h
37 
38  DESCRIPTION:  General purpose input and output buffers
39 
40  EDIT HISTORY FOR FILE:
41 
42  This section contains comments describing changes made to the module.
43  Notice that changes are listed in reverse chronological order.
44 
45  when         who             what, where, why
46  --------     ----            --------------------------------------------------
47  10/05/2024   llundblade      Add Xxx_OffsetToPointer.
48  19/12/2022   llundblade      Document that adding empty data is allowed.
49  4/11/2022    llundblade      Add GetOutPlace and Advance to UsefulOutBuf.
50  9/21/2021    llundbla        Clarify UsefulOutBuf size calculation mode
51  8/8/2021     dthaler/llundbla Work with C++ without compiler extensions
52  5/11/2021    llundblade      Improve comments and comment formatting.
53  3/6/2021     mcr/llundblade  Fix warnings related to --Wcast-qual
54  2/17/2021    llundblade      Add method to go from a pointer to an offset.
55  1/25/2020    llundblade      Add some casts so static anlyzers don't complain.
56  5/21/2019    llundblade      #define configs for efficient endianness handling.
57  5/16/2019    llundblade      Add UsefulOutBuf_IsBufferNULL().
58  3/23/2019    llundblade      Big documentation & style update. No interface
59                               change.
60  3/6/2019     llundblade      Add UsefulBuf_IsValue()
61  12/17/2018   llundblade      Remove const from UsefulBuf and UsefulBufC .len
62  12/13/2018   llundblade      Documentation improvements
63  09/18/2018   llundblade      Cleaner distinction between UsefulBuf and
64                               UsefulBufC.
65  02/02/18     llundbla        Full support for integers in and out; fix pointer
66                               alignment bug. Incompatible change: integers
67                               in/out are now in network byte order.
68  08/12/17     llundbla        Added UsefulOutBuf_AtStart and UsefulBuf_Find
69  06/27/17     llundbla        Fix UsefulBuf_Compare() bug. Only affected
70                               comparison for < or > for unequal length buffers.
71                               Added UsefulBuf_Set() function.
72  05/30/17     llundbla        Functions for NULL UsefulBufs and const / unconst
73  11/13/16     llundbla        Initial Version.
74 
75  =============================================================================*/
76 
77 #ifndef _UsefulBuf_h
78 #define _UsefulBuf_h
79 
80 
81 /*
82  * Endianness Configuration
83  *
84  * This code is written so it will work correctly on big- and
85  * little-endian CPUs without configuration or any auto-detection of
86  * endianness. All code here will run correctly regardless of the
87  * endianness of the CPU it is running on.
88  *
89  * There are four C preprocessor macros that can be set with #define
90  * to explicitly configure endianness handling. Setting them can
91  * reduce code size a little and improve efficiency a little.
92  *
93  * Note that most of QCBOR is unaffected by this configuration.  Its
94  * endianness handling is integrated with the code that handles
95  * alignment and preferred serialization. This configuration does
96  * affect QCBOR's (planned) implementation of integer arrays (tagged
97  * arrays) and use of the functions here to serialize or deserialize
98  * integers and floating-point values.
99  *
100  * Following is the recipe for configuring the endianness-related
101  * #defines.
102  *
103  * The first option is to not define anything. This will work fine
104  * with all CPUs, OS's and compilers. The code for encoding integers
105  * may be a little larger and slower.
106  *
107  * If your CPU is big-endian then define
108  * USEFULBUF_CONFIG_BIG_ENDIAN. This will give the most efficient code
109  * for big-endian CPUs. It will be small and efficient because there
110  * will be no byte swapping.
111  *
112  * Try defining USEFULBUF_CONFIG_HTON. This will work on most CPUs,
113  * OS's and compilers, but not all. On big-endian CPUs this should
114  * give the most efficient code, the same as
115  * USEFULBUF_CONFIG_BIG_ENDIAN does. On little-endian CPUs it should
116  * call the system-defined byte swapping method which is presumably
117  * implemented efficiently. In some cases, this will be a dedicated
118  * byte swap instruction like Intel's bswap.
119  *
120  * If USEFULBUF_CONFIG_HTON works and you know your CPU is
121  * little-endian, it is also good to define
122  * USEFULBUF_CONFIG_LITTLE_ENDIAN.
123  *
124  * if USEFULBUF_CONFIG_HTON doesn't work and you know your system is
125  * little-endian, try defining both USEFULBUF_CONFIG_LITTLE_ENDIAN and
126  * USEFULBUF_CONFIG_BSWAP. This should call the most efficient
127  * system-defined byte swap method. However, note
128  * https://hardwarebug.org/2010/01/14/beware-the-builtins/.  Perhaps
129  * this is fixed now. Often hton() and ntoh() will call the built-in
130  * __builtin_bswapXX()() function, so this size issue could affect
131  * USEFULBUF_CONFIG_HTON.
132  *
133  * Last, run the tests. They must all pass.
134  *
135  * These #define config options affect the inline implementation of
136  * UsefulOutBuf_InsertUint64() and UsefulInputBuf_GetUint64().  They
137  * also affect the 16-, 32-bit, float and double versions of these
138  * functions. Since they are inline, the size effect is not in the
139  * UsefulBuf object code, but in the calling code.
140  *
141  * Summary:
142  *   USEFULBUF_CONFIG_BIG_ENDIAN -- Force configuration to big-endian.
143  *   USEFULBUF_CONFIG_LITTLE_ENDIAN -- Force to little-endian.
144  *   USEFULBUF_CONFIG_HTON -- Use hton(), htonl(), ntohl()... to
145  *     handle big and little-endian with system option.
146  *   USEFULBUF_CONFIG_BSWAP -- With USEFULBUF_CONFIG_LITTLE_ENDIAN,
147  *     use __builtin_bswapXX().
148  *
149  * It is possible to run this code in environments where using floating point is
150  * not allowed. Defining USEFULBUF_DISABLE_ALL_FLOAT will disable all the code
151  * that is related to handling floating point types, along with related
152  * interfaces. This makes it possible to compile the code with the compile
153  * option -mgeneral-regs-only.
154  */
155 
156 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN) && defined(USEFULBUF_CONFIG_LITTLE_ENDIAN)
157 #error "Cannot define both USEFULBUF_CONFIG_BIG_ENDIAN and USEFULBUF_CONFIG_LITTLE_ENDIAN"
158 #endif
159 
160 
161 #include <stdint.h> /* for uint8_t, uint16_t.... */
162 #include <string.h> /* for strlen, memcpy, memmove, memset */
163 #include <stddef.h> /* for size_t */
164 
165 
166 #ifdef USEFULBUF_CONFIG_HTON
167 #include <arpa/inet.h> /* for htons, htonl, htonll, ntohs... */
168 #endif
169 
170 #ifdef __cplusplus
171 extern "C" {
172 #if 0
173 } /* Keep editor indention formatting happy */
174 #endif
175 #endif
176 
177 /**
178  * @file UsefulBuf.h
179  *
180  * The goal of this code is to make buffer and pointer manipulation
181  * easier and safer when working with binary data.
182  *
183  * The @ref UsefulBuf, @ref UsefulOutBuf and @ref UsefulInputBuf
184  * structures are used to represent buffers rather than ad hoc
185  * pointers and lengths.
186  *
187  * With these it is possible to write code that does little or no
188  * direct pointer manipulation for copying and formatting data. For
189  * example, the QCBOR encoder was written using these and has less
190  * pointer manipulation.
191  *
192  * While it is true that object code using these functions will be a
193  * little larger and slower than a white-knuckle clever use of
194  * pointers might be, but not by that much or enough to have an effect
195  * for most use cases. For security-oriented code this is highly
196  * worthwhile. Clarity, simplicity, reviewability and are more
197  * important.
198  *
199  * There are some extra sanity and double checks in this code to help
200  * catch coding errors and simple memory corruption. They are helpful,
201  * but not a substitute for proper code review, input validation and
202  * such.
203  *
204  * This code consists of a lot of inline functions and a few that are
205  * not.  It should not generate very much object code, especially with
206  * the optimizer turned up to @c -Os or @c -O3.
207  */
208 
209 
210 /**
211  * @ref UsefulBufC and @ref UsefulBuf are simple data structures to
212  * hold a pointer and length for binary data.  In C99 this data
213  * structure can be passed on the stack making a lot of code cleaner
214  * than carrying around a pointer and length as two parameters.
215  *
216  * This is also conducive to secure coding practice as the length is
217  * always carried with the pointer and the convention for handling a
218  * pointer and a length is clear.
219  *
220  * While it might be possible to write buffer and pointer code more
221  * efficiently in some use cases, the thought is that unless there is
222  * an extreme need for performance (e.g., you are building a
223  * gigabit-per-second IP router), it is probably better to have
224  * cleaner code you can be most certain about the security of.
225  *
226  * The non-const @ref UsefulBuf is usually used to refer an empty
227  * buffer to be filled in.  The length is the size of the buffer.
228  *
229  * The const @ref UsefulBufC is usually used to refer to some data
230  * that has been filled in. The length is amount of valid data pointed
231  * to.
232  *
233  * A common use mode is to pass a @ref UsefulBuf to a function, the
234  * function puts some data in it, then the function returns a @ref
235  * UsefulBufC refering to the data. The @ref UsefulBuf is a non-const
236  * "in" parameter and the @ref UsefulBufC is a const "out" parameter
237  * so the constness stays correct. There is no single "in,out"
238  * parameter (if there was, it would have to be non-const).  Note that
239  * the pointer returned in the @ref UsefulBufC usually ends up being
240  * the same pointer passed in as a @ref UsefulBuf, though this is not
241  * striclty required.
242  *
243  * A @ref UsefulBuf is null, it has no value, when @c ptr in it is
244  * @c NULL.
245  *
246  * There are functions and macros for the following:
247  *  - Initializing
248  *  - Create initialized const @ref UsefulBufC from compiler literals
249  *  - Create initialized const @ref UsefulBufC from NULL-terminated string
250  *  - Make an empty @ref UsefulBuf on the stack
251  *  - Checking whether a @ref UsefulBuf is null, empty or both
252  *  - Copying, copying with offset, copying head or tail
253  *  - Comparing and finding substrings
254  *
255  * See also @ref UsefulOutBuf. It is a richer structure that has both
256  * the size of the valid data and the size of the buffer.
257  *
258  * @ref UsefulBuf is only 16 or 8 bytes on a 64- or 32-bit machine so
259  * it can go on the stack and be a function parameter or return value.
260  *
261  * Another way to look at it is this. C has the NULL-terminated string
262  * as a means for handling text strings, but no means or convention
263  * for binary strings. Other languages do have such means, Rust, an
264  * efficient compiled language, for example.
265  *
266  * @ref UsefulBuf is kind of like the Useful Pot Pooh gave Eeyore on
267  * his birthday.  Eeyore's balloon fits beautifully, "it goes in and
268  * out like anything".
269  */
270 typedef struct q_useful_buf_c {
271     const void *ptr;
272     size_t      len;
273 } UsefulBufC;
274 
275 
276 /**
277  * This non-const @ref UsefulBuf is typically used for some allocated
278  * memory that is to be filled in. The @c len is the amount of memory,
279  * not the length of the valid data in the buffer.
280  */
281 typedef struct q_useful_buf {
282    void  *ptr;
283    size_t len;
284 } UsefulBuf;
285 
286 
287 /**
288  * A null @ref UsefulBufC is one that has no value in the same way a
289  * @c NULL pointer has no value.  A @ref UsefulBufC is @c NULL when
290  * the @c ptr field is @c NULL. It doesn't matter what @c len is.  See
291  * UsefulBuf_IsEmpty() for the distinction between null and empty.
292  */
293 /*
294  * NULLUsefulBufC and few other macros have to be
295  * definied differently in C than C++ because there
296  * is no common construct for a literal structure.
297  *
298  * In C compound literals are used.
299  *
300  * In C++ list initalization is used. This only works
301  * in C++11 and later.
302  *
303  * Note that some popular C++ compilers can handle compound
304  * literals with on-by-default extensions, however
305  * this code aims for full correctness with strict
306  * compilers so they are not used.
307  */
308 #ifdef __cplusplus
309 #define NULLUsefulBufC {NULL, 0}
310 #else
311 #define NULLUsefulBufC ((UsefulBufC) {NULL, 0})
312 #endif
313 
314 /**
315  * A null @ref UsefulBuf is one that has no memory associated the same
316  * way @c NULL points to nothing. It does not matter what @c len is.
317  **/
318 #ifdef __cplusplus
319 #define NULLUsefulBuf  {NULL, 0}
320 #else
321 #define NULLUsefulBuf  ((UsefulBuf) {NULL, 0})
322 #endif
323 
324 
325 /**
326  * @brief Check if a @ref UsefulBuf is @ref NULLUsefulBuf or not.
327  *
328  * @param[in] UB The UsefulBuf to check.
329  *
330  * @return 1 if it is @ref NULLUsefulBuf, 0 if not.
331  */
332 static inline int UsefulBuf_IsNULL(UsefulBuf UB);
333 
334 
335 /**
336  * @brief Check if a @ref UsefulBufC is @ref NULLUsefulBufC or not.
337  *
338  * @param[in] UB The @ref UsefulBufC to check.
339  *
340  * @return 1 if it is @c NULLUsefulBufC, 0 if not.
341  */
342 static inline int UsefulBuf_IsNULLC(UsefulBufC UB);
343 
344 
345 /**
346  * @brief Check if a @ref UsefulBuf is empty or not.
347  *
348  * @param[in] UB The @ref UsefulBuf to check.
349  *
350  * @return 1 if it is empty, 0 if not.
351  *
352  * An "empty" @ref UsefulBuf is one that has a value and can be
353  * considered to be set, but that value is of zero length.  It is
354  * empty when @c len is zero. It doesn't matter what the @c ptr is.
355  *
356  * Many uses will not need to clearly distinguish a @c NULL @ref
357  * UsefulBuf from an empty one and can have the @c ptr @c NULL and the
358  * @c len 0.  However if a use of @ref UsefulBuf needs to make a
359  * distinction then @c ptr should not be @c NULL when the @ref
360  * UsefulBuf is considered empty, but not @c NULL.
361  */
362 static inline int UsefulBuf_IsEmpty(UsefulBuf UB);
363 
364 
365 /**
366  * @brief Check if a @ref UsefulBufC is empty or not.
367  *
368  * @param[in] UB The @ref UsefulBufC to check.
369  *
370  * @return 1 if it is empty, 0 if not.
371  */
372 static inline int UsefulBuf_IsEmptyC(UsefulBufC UB);
373 
374 
375 /**
376  * @brief Check if a @ref UsefulBuf is @ref NULLUsefulBuf or empty.
377  *
378  * @param[in] UB The @ref UsefulBuf to check.
379  *
380  * @return 1 if it is either @ref NULLUsefulBuf or empty, 0 if not.
381  */
382 static inline int UsefulBuf_IsNULLOrEmpty(UsefulBuf UB);
383 
384 
385 /**
386  * @brief Check if a @ref UsefulBufC is @ref NULLUsefulBufC or empty.
387  *
388  * @param[in] UB The @ref UsefulBufC to check.
389  *
390  * @return 1 if it is either @ref NULLUsefulBufC or empty, 0 if not.
391  */
392 static inline int UsefulBuf_IsNULLOrEmptyC(UsefulBufC UB);
393 
394 
395 /**
396  * @brief Convert a non-const @ref UsefulBuf to a const @ref UsefulBufC.
397  *
398  * @param[in] UB The @ref UsefulBuf to convert.
399  *
400  * @return A @ref UsefulBufC struct.
401  */
402 static inline UsefulBufC UsefulBuf_Const(const UsefulBuf UB);
403 
404 
405 /**
406  * @brief Convert a const @ref UsefulBufC to a non-const @ref UsefulBuf.
407  *
408  * @param[in] UBC The @ref UsefulBuf to convert.
409  *
410  * @return A non-const @ref UsefulBuf struct.
411  *
412  * Use of this is not necessary for the intended use mode of @ref
413  * UsefulBufC and @ref UsefulBuf.  In that mode, the @ref UsefulBuf is
414  * created to describe a buffer that has not had any data put in
415  * it. Then the data is put in it.  Then a @ref UsefulBufC is create
416  * to describe the part with the data in it. This goes from non-const
417  * to const, so this function is not needed.
418  *
419  * If the -Wcast-qual warning is enabled, this function can be used to
420  * avoid that warning.
421  */
422 static inline UsefulBuf UsefulBuf_Unconst(const UsefulBufC UBC);
423 
424 
425 /**
426  * Convert a literal string to a @ref UsefulBufC.
427  *
428  * @c szString must be a literal string that @c sizeof() works on.
429  * This is better for literal strings than UsefulBuf_FromSZ() because
430  * it generates less code. It will not work on non-literal strings.
431  *
432  * The terminating \0 (NULL) is NOT included in the length!
433  */
434 #ifdef __cplusplus
435 #define UsefulBuf_FROM_SZ_LITERAL(szString)  {(szString), sizeof(szString)-1}
436 #else
437 #define UsefulBuf_FROM_SZ_LITERAL(szString) \
438     ((UsefulBufC) {(szString), sizeof(szString)-1})
439 #endif
440 
441 
442 /**
443  * Convert a literal byte array to a @ref UsefulBufC.
444  *
445  * @c pBytes must be a literal string that @c sizeof() works on.  It
446  * will not work on non-literal arrays.
447  */
448 #ifdef __cplusplus
449 #define UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pBytes)  {(pBytes), sizeof(pBytes)}
450 #else
451 #define UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pBytes) \
452    ((UsefulBufC) {(pBytes), sizeof(pBytes)})
453 #endif
454 
455 /**
456  * Make an automatic variable named @c name of type @ref UsefulBuf and
457  * point it to a stack variable of the given @c size.
458  */
459 #define  UsefulBuf_MAKE_STACK_UB(name, size) \
460     uint8_t    __pBuf##name[(size)];\
461     UsefulBuf  name = {__pBuf##name , sizeof( __pBuf##name )}
462 
463 
464 /**
465  * Make a byte array in to a @ref UsefulBuf. This is usually used on
466  * stack variables or static variables.  Also see @ref
467  * UsefulBuf_MAKE_STACK_UB.
468  */
469 #ifdef __cplusplus
470 #define UsefulBuf_FROM_BYTE_ARRAY(pBytes)  {(pBytes), sizeof(pBytes)}
471 #else
472 #define UsefulBuf_FROM_BYTE_ARRAY(pBytes) \
473    ((UsefulBuf) {(pBytes), sizeof(pBytes)})
474 #endif
475 
476 
477 /**
478  * @brief Convert a NULL-terminated string to a @ref UsefulBufC.
479  *
480  * @param[in] szString The string to convert.
481  *
482  * @return A @ref UsefulBufC struct.
483  *
484  * @c UsefulBufC.ptr points to the string so its lifetime must be
485  * maintained.
486  *
487  * The terminating \0 (NULL) is NOT included in the length.
488  */
489 static inline UsefulBufC UsefulBuf_FromSZ(const char *szString);
490 
491 
492 /**
493  * @brief Copy one @ref UsefulBuf into another at an offset.
494  *
495  * @param[in] Dest     Destination buffer to copy into.
496  * @param[in] uOffset  The byte offset in @c Dest at which to copy to.
497  * @param[in] Src      The bytes to copy.
498  *
499  * @return Pointer and length of the copy or @ref NULLUsefulBufC.
500  *
501  * This fails and returns @ref NULLUsefulBufC if @c offset is beyond the
502  * size of @c Dest.
503  *
504  * This fails and returns @ref NULLUsefulBufC if the @c Src length
505  * plus @c uOffset is greater than the length of @c Dest.
506  *
507  * The results are undefined if @c Dest and @c Src overlap.
508  *
509  * This assumes that there is valid data in @c Dest up to @c
510  * uOffset. The @ref UsefulBufC returned starts at the beginning of @c
511  * Dest and goes to @c Src.len @c + @c uOffset.
512  */
513 UsefulBufC UsefulBuf_CopyOffset(UsefulBuf Dest, size_t uOffset, const UsefulBufC Src);
514 
515 
516 /**
517  * @brief Copy one @ref UsefulBuf into another.
518  *
519  * @param[in] Dest  The destination buffer to copy into.
520  * @param[out] Src  The source to copy from.
521  *
522  * @return Filled in @ref UsefulBufC on success, @ref NULLUsefulBufC
523  *         on failure.
524  *
525  * This fails if @c Src.len is greater than @c Dest.len.
526  *
527  * Note that like @c memcpy(), the pointers are not checked and this
528  * will crash rather than return @ref NULLUsefulBufC if they are @c
529  * NULL or invalid.
530  *
531  * The results are undefined if @c Dest and @c Src overlap.
532  */
533 static inline UsefulBufC UsefulBuf_Copy(UsefulBuf Dest, const UsefulBufC Src);
534 
535 
536 /**
537  * @brief Set all bytes in a @ref UsefulBuf to a value, for example to 0.
538  *
539  * @param[in] pDest  The destination buffer to copy into.
540  * @param[in] value  The value to set the bytes to.
541  *
542  * Note that like @c memset(), the pointer in @c pDest is not checked
543  * and this will crash if @c NULL or invalid.
544  */
545 static inline UsefulBufC UsefulBuf_Set(UsefulBuf pDest, uint8_t value);
546 
547 
548 /**
549  * @brief Copy a pointer into a @ref UsefulBuf.
550  *
551  * @param[in,out] Dest  The destination buffer to copy into.
552  * @param[in] ptr       The source to copy from.
553  * @param[in] uLen      Length of the source; amount to copy.
554  *
555  * @return Filled in @ref UsefulBufC on success, @ref NULLUsefulBufC
556  *         on failure.
557  *
558  * This fails and returns @ref NULLUsefulBufC if @c uLen is greater
559  * than @c pDest->len.
560  *
561  * Note that like @c memcpy(), the pointers are not checked and this
562  * will crash, rather than return 1 if they are @c NULL or invalid.
563  */
564 static inline UsefulBufC UsefulBuf_CopyPtr(UsefulBuf Dest,
565                                            const void *ptr,
566                                            size_t uLen);
567 
568 
569 /**
570  *  @brief Returns a truncation of a @ref UsefulBufC.
571  *
572  *  @param[in] UB       The buffer to get the head of.
573  *  @param[in] uAmount  The number of bytes in the head.
574  *
575  *  @return A @ref UsefulBufC that is the head of UB.
576  */
577 static inline UsefulBufC UsefulBuf_Head(UsefulBufC UB, size_t uAmount);
578 
579 
580 /**
581  * @brief  Returns bytes from the end of a @ref UsefulBufC.
582  *
583  * @param[in] UB       The buffer to get the tail of.
584  * @param[in] uAmount  The offset from the start where the tail is to begin.
585  *
586  * @return A @ref UsefulBufC that is the tail of @c UB or @ref NULLUsefulBufC
587  *         if @c uAmount is greater than the length of the @ref UsefulBufC.
588  *
589  * If @c UB.ptr is @c NULL, but @c UB.len is not zero, then the result will
590  * be a @ref UsefulBufC with a @c NULL @c ptr and @c len with the length
591  * of the tail.
592  */
593 static inline UsefulBufC UsefulBuf_Tail(UsefulBufC UB, size_t uAmount);
594 
595 
596 /**
597  * @brief Compare one @ref UsefulBufC to another.
598  *
599  * @param[in] UB1  The first buffer to compare.
600  * @param[in] UB2  The second buffer to compare.
601  *
602  * @return 0, positive or negative value.
603  *
604  * Returns a negative value if @c UB1 if is less than @c UB2. @c UB1 is
605  * less than @c UB2 if it is shorter or the first byte that is not the
606  * same is less.
607  *
608  * Returns 0 if the inputs are the same.
609  *
610  * Returns a positive value if @c UB2 is less than @c UB1.
611  *
612  * All that is of significance is that the result is positive, negative
613  * or 0. (This doesn't return the difference between the first
614  * non-matching byte like @c memcmp() ).
615  */
616 int UsefulBuf_Compare(const UsefulBufC UB1, const UsefulBufC UB2);
617 
618 
619 /**
620  * @brief Find first byte that is not a particular byte value.
621  *
622  * @param[in] UB     The destination buffer for byte comparison.
623  * @param[in] uValue The byte value to compare to.
624  *
625  * @return  Offset of first byte that isn't @c uValue or
626  *          @c SIZE_MAX if all bytes are @c uValue.
627  *
628  * Note that unlike most comparison functions, 0
629  * does not indicate a successful comparison, so the
630  * test for match is:
631  *
632  *      UsefulBuf_IsValue(...) == SIZE_MAX
633  *
634  * If @c UB is null or empty, there is no match
635  * and 0 is returned.
636  */
637 size_t UsefulBuf_IsValue(const UsefulBufC UB, uint8_t uValue);
638 
639 
640 /**
641  * @brief Find one @ref UsefulBufC in another.
642  *
643  * @param[in] BytesToSearch  Buffer to search through.
644  * @param[in] BytesToFind    Buffer with bytes to be found.
645  *
646  * @return Position of found bytes or @c SIZE_MAX if not found.
647  */
648 size_t UsefulBuf_FindBytes(UsefulBufC BytesToSearch, UsefulBufC BytesToFind);
649 
650 
651 /**
652  * @brief Convert a pointer to an offset with bounds checking.
653  *
654  * @param[in] UB  A UsefulBuf.
655  * @param[in] p   Pointer to convert to offset.
656  *
657  * @return SIZE_MAX if @c p is out of range, the byte offset if not.
658 */
659 static inline size_t UsefulBuf_PointerToOffset(UsefulBufC UB, const void *p);
660 
661 
662 /**
663  * @brief Convert an offset to a pointer with bounds checking.
664  *
665  * @param[in] UB       A UsefulBuf.
666  * @param[in] uOffset  Offset in @c pUInBuf.
667  *
668  * @return @c NULL if @c uOffset is out of range, a pointer into the buffer if not.
669  */
670 static inline const void *UsefulBuf_OffsetToPointer(UsefulBufC UB, size_t uOffset);
671 
672 
673 #ifndef USEFULBUF_DISABLE_DEPRECATED
674 /** Deprecated macro; use @ref UsefulBuf_FROM_SZ_LITERAL instead */
675 #define SZLiteralToUsefulBufC(szString)  UsefulBuf_FROM_SZ_LITERAL(szString)
676 
677 /** Deprecated macro; use UsefulBuf_MAKE_STACK_UB instead */
678 #define  MakeUsefulBufOnStack(name, size) \
679     uint8_t    __pBuf##name[(size)];\
680     UsefulBuf  name = {__pBuf##name , sizeof( __pBuf##name )}
681 
682 /** Deprecated macro; use @ref UsefulBuf_FROM_BYTE_ARRAY_LITERAL instead */
683 #define ByteArrayLiteralToUsefulBufC(pBytes) \
684    UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pBytes)
685 
686 /** Deprecated function; use UsefulBuf_Unconst() instead */
UsefulBufC_Unconst(const UsefulBufC UBC)687 static inline UsefulBuf UsefulBufC_Unconst(const UsefulBufC UBC)
688 {
689    UsefulBuf UB;
690 
691    /* See UsefulBuf_Unconst() implementation for comment */
692    UB.ptr = (void *)(uintptr_t)UBC.ptr;
693 
694    UB.len = UBC.len;
695 
696    return UB;
697 }
698 #endif /* USEFULBUF_DISABLE_DEPRECATED */
699 
700 
701 
702 
703 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
704 /**
705  * @brief Copy a @c float to a @c uint32_t.
706  *
707  * @param[in] f  Float value to copy.
708  *
709  * @return  A @c uint32_t with the float bits.
710  *
711  * Convenience function to avoid type punning, compiler warnings and
712  * such. The optimizer usually reduces this to a simple assignment.  This
713  * is a crusty corner of C.
714  */
715 static inline uint32_t UsefulBufUtil_CopyFloatToUint32(float f);
716 
717 
718 /**
719  * @brief Copy a @c double to a @c uint64_t.
720  *
721  * @param[in] d  Double value to copy.
722  *
723  * @return  A @c uint64_t with the double bits.
724  *
725  * Convenience function to avoid type punning, compiler warnings and
726  * such. The optimizer usually reduces this to a simple assignment.  This
727  * is a crusty corner of C.
728  */
729 static inline uint64_t UsefulBufUtil_CopyDoubleToUint64(double d);
730 
731 
732 /**
733  * @brief Copy a @c uint32_t to a @c float.
734  *
735  * @param[in] u32  Integer value to copy.
736  *
737  * @return  The value as a @c float.
738  *
739  * Convenience function to avoid type punning, compiler warnings and
740  * such. The optimizer usually reduces this to a simple assignment.  This
741  * is a crusty corner of C.
742  */
743 static inline float UsefulBufUtil_CopyUint32ToFloat(uint32_t u32);
744 
745 
746 /**
747  * @brief Copy a @c uint64_t to a @c double.
748  *
749  * @param[in] u64  Integer value to copy.
750  *
751  * @return  The value as a @c double.
752  *
753  * Convenience function to avoid type punning, compiler warnings and
754  * such. The optimizer usually reduces this to a simple assignment.  This
755  * is a crusty corner of C.
756  */
757 static inline double UsefulBufUtil_CopyUint64ToDouble(uint64_t u64);
758 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
759 
760 
761 
762 
763 /**
764  * UsefulOutBuf is a structure and functions (an object) for
765  * serializing data into a buffer to encode for a network protocol or
766  * write data to a file.
767  *
768  * The main idea is that all the pointer manipulation is performed by
769  * @ref UsefulOutBuf functions so the caller doesn't have to do any
770  * pointer manipulation.  The pointer manipulation is centralized.
771  * This code has been reviewed and written carefully so it
772  * spares the caller of much of this work and results in safer code
773  * with less effort.
774  *
775  * The @ref UsefulOutBuf methods that add data to the output buffer
776  * always check the length and will never write off the end of the
777  * output buffer. If an attempt to add data that will not fit is made,
778  * an internal error flag will be set and further attempts to add data
779  * will not do anything.
780  *
781  * There is no way to ever write off the end of that buffer when
782  * calling the @c UsefulOutBuf_AddXxx() and
783  * @c UsefulOutBuf_InsertXxx() functions.
784  *
785  * The functions to add data do not report success of failure. The
786  * caller only needs to check for an error in the final call, either
787  * UsefulOutBuf_OutUBuf() or UsefulOutBuf_CopyOut() to get the
788  * result. This makes the calling code cleaner.
789  *
790  * There is a utility function to get the error status anytime along
791  * the way for a special circumstance. There are functions to see how
792  * much room is left and see if some data will fit too, but their use
793  * is generally unnecessary.
794  *
795  * The general call flow is:
796  *
797  *    - Initialize by calling @ref UsefulOutBuf_Init(). The output
798  *      buffer given to it can be from the heap, stack or
799  *      otherwise. @ref UsefulOutBuf_MakeOnStack is a convenience
800  *      macro that makes a buffer on the stack and initializes it.
801  *
802  *    - Call methods like UsefulOutBuf_InsertString(),
803  *      UsefulOutBuf_AppendUint32() and UsefulOutBuf_InsertUsefulBuf()
804  *      to output data. The append calls add data to the end of the
805  *      valid data. The insert calls take a position argument.
806  *
807  *    - Call UsefulOutBuf_OutUBuf() or UsefulOutBuf_CopyOut() to see
808  *      there were no errors and to get the serialized output bytes.
809  *
810  * @ref UsefulOutBuf can be used in a mode to calculate the size of
811  * what would be output without actually outputting anything.  This is
812  * useful to calculate the size of a buffer that is to be allocated to
813  * hold the output. See @ref SizeCalculateUsefulBuf.
814  *
815  * Methods like UsefulOutBuf_InsertUint64() always output in network
816  * byte order (big endian).
817  *
818  * The possible errors are:
819  *
820  *  - The @ref UsefulOutBuf was not initialized or was corrupted.
821  *
822  *  - An attempt was made to add data that will not fit.
823  *
824  *  - An attempt was made to insert data at a position beyond the end of
825  *    the buffer.
826  *
827  *  - An attempt was made to insert data at a position beyond the valid
828  *    data in the buffer.
829  *
830  * Some inexpensive simple sanity checks are performed before every
831  * data addition to guard against use of an uninitialized or corrupted
832  * UsefulOutBuf.
833  *
834  * @ref UsefulOutBuf has been used to create a CBOR encoder. The CBOR
835  * encoder has almost no pointer manipulation in it, is easier to
836  * read, and easier to review.
837  *
838  * A @ref UsefulOutBuf is small and can go on the stack:
839  *   - 32 bytes (27 bytes plus alignment padding) on a 64-bit CPU
840  *   - 16 bytes (15 bytes plus alignment padding) on a 32-bit CPU
841  */
842 typedef struct useful_out_buf {
843    /* PRIVATE DATA STRUCTURE */
844    UsefulBuf  UB;       /* Memory that is being output to */
845    size_t     data_len; /* length of the valid data, the insertion point */
846    uint16_t   magic;    /* Used to detect corruption and lack
847                          * of initialization */
848    uint8_t    err;
849 } UsefulOutBuf;
850 
851 
852 /**
853  * This is a @ref UsefulBuf value that can be passed to
854  * UsefulOutBuf_Init() to have it calculate the size of the output
855  * buffer needed. Pass this for @c Storage, call all the append and
856  * insert functions normally, then call UsefulOutBuf_OutUBuf(). The
857  * returned @ref UsefulBufC has the size.
858  *
859  * As one can see, this is just a NULL pointer and very large size.
860  * The NULL pointer tells UsefulOutputBuf to not copy any data.
861  */
862 #ifdef __cplusplus
863 #define SizeCalculateUsefulBuf {NULL, SIZE_MAX}
864 #else
865 #define SizeCalculateUsefulBuf ((UsefulBuf) {NULL, SIZE_MAX})
866 #endif
867 
868 
869 /**
870  * @brief Initialize and supply the actual output buffer.
871  *
872  * @param[out] pUOutBuf  The @ref UsefulOutBuf to initialize.
873  * @param[in] Storage    Buffer to output into.
874  *
875  * This initializes the @ref UsefulOutBuf with storage, sets the
876  * current position to the beginning of the buffer and clears the
877  * error state.
878  *
879  * See @ref SizeCalculateUsefulBuf for instructions on how to
880  * initialize a @ref UsefulOutBuf to calculate the size that would be
881  * output without actually outputting.
882  *
883  * This must be called before the @ref UsefulOutBuf is used.
884  */
885 void UsefulOutBuf_Init(UsefulOutBuf *pUOutBuf, UsefulBuf Storage);
886 
887 
888 /**
889  * Convenience macro to make a @ref UsefulOutBuf on the stack and
890  * initialize it with a stack buffer of the given size. The variable
891  * will be named @c name.
892  */
893 #define  UsefulOutBuf_MakeOnStack(name, size) \
894    uint8_t       __pBuf##name[(size)];\
895    UsefulOutBuf  name;\
896    UsefulOutBuf_Init(&(name), (UsefulBuf){__pBuf##name, (size)});
897 
898 
899 /**
900  * @brief Reset a @ref UsefulOutBuf for re use.
901  *
902  * @param[in] pUOutBuf Pointer to the @ref UsefulOutBuf
903  *
904  * This sets the amount of data in the output buffer to none and
905  * clears the error state.
906  *
907  * The output buffer is still the same one and size as from the
908  * UsefulOutBuf_Init() call.
909  *
910  * This doesn't zero the data, just resets to 0 bytes of valid data.
911  */
912 static inline void UsefulOutBuf_Reset(UsefulOutBuf *pUOutBuf);
913 
914 
915 /**
916  * @brief Returns position of end of data in the @ref UsefulOutBuf.
917  *
918  * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
919  *
920  * @return position of end of data.
921  *
922  * On a freshly initialized @ref UsefulOutBuf with no data added, this
923  * will return 0. After 10 bytes have been added, it will return 10
924  * and so on.
925  *
926  * Generally, there is no need to call this for most uses of @ref
927  * UsefulOutBuf.
928  */
929 static inline size_t UsefulOutBuf_GetEndPosition(UsefulOutBuf *pUOutBuf);
930 
931 
932 /**
933  * @brief Returns whether any data has been added to the @ref UsefulOutBuf.
934  *
935  * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
936  *
937  * @return 1 if output position is at start, 0 if not.
938  */
939 static inline int UsefulOutBuf_AtStart(UsefulOutBuf *pUOutBuf);
940 
941 
942 /**
943  * @brief Inserts bytes into the @ref UsefulOutBuf.
944  *
945  * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
946  * @param[in] NewData   The bytes to insert.
947  * @param[in] uPos      Index in output buffer at which to insert.
948  *
949  * @c NewData is the pointer and length for the bytes to be added to
950  * the output buffer. There must be room in the output buffer for all
951  * of @c NewData or an error will occur.
952  *
953  * The insertion point must be between 0 and the current valid
954  * data. If not, an error will occur. Appending data to the output
955  * buffer is achieved by inserting at the end of the valid data. This
956  * can be retrieved by calling UsefulOutBuf_GetEndPosition().
957  *
958  * When insertion is performed, the bytes between the insertion point
959  * and the end of data previously added to the output buffer are slid
960  * to the right to make room for the new data.
961  *
962  * Overlapping buffers are OK. @c NewData can point to data in the
963  * output buffer.
964  *
965  * NewData.len may be 0 in which case nothing will be inserted.
966  *
967  * If an error occurs, an error state is set in the @ref
968  * UsefulOutBuf. No error is returned.  All subsequent attempts to add
969  * data will do nothing.
970  *
971  * The intended use is that all additions are made without checking
972  * for an error. The error will be taken into account when
973  * UsefulOutBuf_OutUBuf() returns @c NullUsefulBufC.
974  * UsefulOutBuf_GetError() can also be called to check for an error.
975  */
976 void UsefulOutBuf_InsertUsefulBuf(UsefulOutBuf *pUOutBuf,
977                                   UsefulBufC NewData,
978                                   size_t uPos);
979 
980 
981 /**
982  * @brief Insert a data buffer into the @ref UsefulOutBuf.
983  *
984  * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
985  * @param[in] pBytes    Pointer to the bytes to insert
986  * @param[in] uLen      Length of the bytes to insert
987  * @param[in] uPos      Index in output buffer at which to insert
988  *
989  * See UsefulOutBuf_InsertUsefulBuf() for details. This is the same with
990  * the difference being a pointer and length is passed in rather than an
991  * @ref UsefulBufC.
992  */
993 static inline void UsefulOutBuf_InsertData(UsefulOutBuf *pUOutBuf,
994                                            const void *pBytes,
995                                            size_t uLen,
996                                            size_t uPos);
997 
998 
999 /**
1000  * @brief Insert a NULL-terminated string into the UsefulOutBuf.
1001  *
1002  * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
1003  * @param[in] szString  NULL-terminated string to insert.
1004  * @param[in] uPos      Index in output buffer at which to insert.
1005  */
1006 static inline void UsefulOutBuf_InsertString(UsefulOutBuf *pUOutBuf,
1007                                              const char *szString,
1008                                              size_t uPos);
1009 
1010 
1011 /**
1012  * @brief Insert a byte into the @ref UsefulOutBuf.
1013  *
1014  * @param[in] pUOutBuf  Pointer to the UsefulOutBuf.
1015  * @param[in] byte      Bytes to insert.
1016  * @param[in] uPos      Index in output buffer at which to insert.
1017  *
1018  * See UsefulOutBuf_InsertUsefulBuf() for details. This is the same
1019  * with the difference being a single byte is to be inserted.
1020  */
1021 static inline void UsefulOutBuf_InsertByte(UsefulOutBuf *pUOutBuf,
1022                                            uint8_t byte,
1023                                            size_t uPos);
1024 
1025 
1026 /**
1027  * @brief Insert a 16-bit integer into the @ref UsefulOutBuf.
1028  *
1029  * @param[in] pUOutBuf    Pointer to the @ref UsefulOutBuf.
1030  * @param[in] uInteger16  Integer to insert.
1031  * @param[in] uPos        Index in output buffer at which to insert.
1032  *
1033  * See UsefulOutBuf_InsertUsefulBuf() for details. This is the same
1034  * with the difference being a two-byte integer is to be inserted.
1035  *
1036  * The integer will be inserted in network byte order (big endian).
1037  */
1038 static inline void UsefulOutBuf_InsertUint16(UsefulOutBuf *pUOutBuf,
1039                                              uint16_t uInteger16,
1040                                              size_t uPos);
1041 
1042 
1043 /**
1044  * @brief Insert a 32-bit integer into the @ref UsefulOutBuf.
1045  *
1046  * @param[in] pUOutBuf    Pointer to the @ref UsefulOutBuf.
1047  * @param[in] uInteger32  Integer to insert.
1048  * @param[in] uPos        Index in output buffer at which to insert.
1049  *
1050  * See UsefulOutBuf_InsertUsefulBuf() for details. This is the same
1051  * with the difference being a four-byte integer is to be inserted.
1052  *
1053  * The integer will be inserted in network byte order (big endian).
1054  */
1055 static inline void UsefulOutBuf_InsertUint32(UsefulOutBuf *pUOutBuf,
1056                                              uint32_t uInteger32,
1057                                              size_t uPos);
1058 
1059 
1060 /**
1061  * @brief Insert a 64-bit integer into the @ref UsefulOutBuf.
1062  *
1063  * @param[in] pUOutBuf    Pointer to the @ref UsefulOutBuf.
1064  * @param[in] uInteger64  Integer to insert.
1065  * @param[in] uPos        Index in output buffer at which to insert.
1066  *
1067  * See UsefulOutBuf_InsertUsefulBuf() for details. This is the same
1068  * with the difference being an eight-byte integer is to be inserted.
1069  *
1070  * The integer will be inserted in network byte order (big endian).
1071  */
1072 static inline void UsefulOutBuf_InsertUint64(UsefulOutBuf *pUOutBuf,
1073                                              uint64_t uInteger64,
1074                                              size_t uPos);
1075 
1076 
1077 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
1078 /**
1079  * @brief Insert a @c float into the @ref UsefulOutBuf.
1080  *
1081  * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
1082  * @param[in] f         @c float to insert.
1083  * @param[in] uPos      Index in output buffer at which to insert.
1084  *
1085  * See UsefulOutBuf_InsertUsefulBuf() for details. This is the same
1086  * with the difference being a @c float is to be inserted.
1087  *
1088  * The @c float will be inserted in network byte order (big endian).
1089  */
1090 static inline void UsefulOutBuf_InsertFloat(UsefulOutBuf *pUOutBuf,
1091                                             float f,
1092                                             size_t uPos);
1093 
1094 
1095 /**
1096  * @brief Insert a @c double into the @ref UsefulOutBuf.
1097  *
1098  * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
1099  * @param[in] d         @c double  to insert.
1100  * @param[in] uPos      Index in output buffer at which to insert.
1101  *
1102  * See UsefulOutBuf_InsertUsefulBuf() for details. This is the same
1103  * with the difference being a @c double is to be inserted.
1104  *
1105  * The @c double will be inserted in network byte order (big endian).
1106  */
1107 static inline void UsefulOutBuf_InsertDouble(UsefulOutBuf *pUOutBuf,
1108                                              double d,
1109                                              size_t uPos);
1110 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
1111 
1112 
1113 /**
1114  * @brief Append a @ref UsefulBuf into the @ref UsefulOutBuf.
1115  *
1116  * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
1117  * @param[in] NewData   The @ref UsefulBuf with the bytes to append.
1118  *
1119  * See UsefulOutBuf_InsertUsefulBuf() for details. This does the same
1120  * with the insertion point at the end of the valid data.
1121  */
1122 static inline void UsefulOutBuf_AppendUsefulBuf(UsefulOutBuf *pUOutBuf,
1123                                                 UsefulBufC NewData);
1124 
1125 
1126 /**
1127  * @brief Append bytes to the @ref UsefulOutBuf.
1128  *
1129  * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
1130  * @param[in] pBytes    Pointer to bytes to append.
1131  * @param[in] uLen      Length of @c pBytes to append.
1132  *
1133  * See UsefulOutBuf_InsertData() for details. This does the same with
1134  * the insertion point at the end of the valid data.
1135  */
1136 static inline void UsefulOutBuf_AppendData(UsefulOutBuf *pUOutBuf,
1137                                            const void *pBytes,
1138                                            size_t uLen);
1139 
1140 
1141 /**
1142  * @brief Append a NULL-terminated string to the @ref UsefulOutBuf
1143  *
1144  * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
1145  * @param[in] szString  NULL-terminated string to append.
1146  */
1147 static inline void UsefulOutBuf_AppendString(UsefulOutBuf *pUOutBuf,
1148                                              const char *szString);
1149 
1150 
1151 /**
1152  * @brief Append a byte to the @ref UsefulOutBuf
1153  *
1154  * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
1155  * @param[in] byte      Bytes to append.
1156  *
1157  * See UsefulOutBuf_InsertByte() for details. This does the same
1158  * with the insertion point at the end of the valid data.
1159  */
1160 static inline void UsefulOutBuf_AppendByte(UsefulOutBuf *pUOutBuf,
1161                                            uint8_t byte);
1162 
1163 
1164 /**
1165  * @brief Append an integer to the @ref UsefulOutBuf
1166  *
1167  * @param[in] pUOutBuf    Pointer to the @ref UsefulOutBuf.
1168  * @param[in] uInteger16  Integer to append.
1169  *
1170  * See UsefulOutBuf_InsertUint16() for details. This does the same
1171  * with the insertion point at the end of the valid data.
1172  *
1173  * The integer will be appended in network byte order (big endian).
1174  */
1175 static inline void UsefulOutBuf_AppendUint16(UsefulOutBuf *pUOutBuf,
1176                                              uint16_t uInteger16);
1177 
1178 
1179 /**
1180  * @brief Append an integer to the @ref UsefulOutBuf
1181  *
1182  * @param[in] pUOutBuf    Pointer to the @ref UsefulOutBuf.
1183  * @param[in] uInteger32  Integer to append.
1184  *
1185  * See UsefulOutBuf_InsertUint32() for details. This does the same
1186  * with the insertion point at the end of the valid data.
1187  *
1188  * The integer will be appended in network byte order (big endian).
1189  */
1190 static inline void UsefulOutBuf_AppendUint32(UsefulOutBuf *pUOutBuf,
1191                                              uint32_t uInteger32);
1192 
1193 
1194 /**
1195  * @brief Append an integer to the @ref UsefulOutBuf
1196  *
1197  * @param[in] pUOutBuf    Pointer to the @ref UsefulOutBuf.
1198  * @param[in] uInteger64  Integer to append.
1199  *
1200  * See UsefulOutBuf_InsertUint64() for details. This does the same
1201  * with the insertion point at the end of the valid data.
1202  *
1203  * The integer will be appended in network byte order (big endian).
1204  */
1205 static inline void UsefulOutBuf_AppendUint64(UsefulOutBuf *pUOutBuf,
1206                                              uint64_t uInteger64);
1207 
1208 
1209 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
1210 /**
1211  * @brief Append a @c float to the @ref UsefulOutBuf
1212  *
1213  * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
1214  * @param[in] f         @c float to append.
1215  *
1216  * See UsefulOutBuf_InsertFloat() for details. This does the same with
1217  * the insertion point at the end of the valid data.
1218  *
1219  * The float will be appended in network byte order (big endian).
1220  */
1221 static inline void UsefulOutBuf_AppendFloat(UsefulOutBuf *pUOutBuf,
1222                                             float f);
1223 
1224 
1225 /**
1226  * @brief Append a @c double to the @ref UsefulOutBuf
1227  *
1228  * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
1229  * @param[in] d         @c double to append.
1230  *
1231  * See UsefulOutBuf_InsertDouble() for details. This does the same
1232  * with the insertion point at the end of the valid data.
1233  *
1234  * The double will be appended in network byte order (big endian).
1235  */
1236 static inline void UsefulOutBuf_AppendDouble(UsefulOutBuf *pUOutBuf,
1237                                              double d);
1238 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
1239 
1240 
1241 /**
1242  * @brief Returns the current error status.
1243  *
1244  * @param[in] pUOutBuf Pointer to the @ref UsefulOutBuf.
1245  *
1246  * @return 0 if all OK, 1 on error.
1247  *
1248  * This returns the error status since a call to either
1249  * UsefulOutBuf_Reset() of UsefulOutBuf_Init().  Once a @ref UsefulOutBuf
1250  * goes into the error state, it will stay until one of those
1251  * functions is called.
1252  *
1253  * Possible error conditions are:
1254  *   - bytes to be inserted will not fit
1255  *   - insertion point is out of buffer or past valid data
1256  *   - current position is off end of buffer (probably corrupted or uninitialized)
1257  *   - detect corruption / uninitialized by bad magic number
1258  */
1259 static inline int UsefulOutBuf_GetError(UsefulOutBuf *pUOutBuf);
1260 
1261 
1262 /**
1263  * @brief Returns number of bytes unused used in the output buffer.
1264  *
1265  * @param[in] pUOutBuf Pointer to the @ref UsefulOutBuf.
1266  *
1267  * @return Number of unused bytes or zero.
1268  *
1269  * Because of the error handling strategy and checks in
1270  * UsefulOutBuf_InsertUsefulBuf() it is usually not necessary to use
1271  * this.
1272  */
1273 static inline size_t UsefulOutBuf_RoomLeft(UsefulOutBuf *pUOutBuf);
1274 
1275 
1276 /**
1277  *@brief Returns 1 if some number of bytes will fit in the @ref UsefulOutBuf.
1278  *
1279  * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf
1280  * @param[in] uLen      Number of bytes for which to check
1281  *
1282  * @return 1 if @c uLen bytes will fit, 0 if not.
1283  *
1284  * Because of the error handling strategy and checks in
1285  * UsefulOutBuf_InsertUsefulBuf() it is usually not necessary to use
1286  * this.
1287  */
1288 static inline int UsefulOutBuf_WillItFit(UsefulOutBuf *pUOutBuf, size_t uLen);
1289 
1290 
1291  /**
1292   * @brief Returns 1 if buffer given to UsefulOutBuf_Init() was @c NULL.
1293   *
1294   * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf
1295   *
1296   * @return 1 if buffer given to UsefulOutBuf_Init() was @c NULL.
1297   *
1298   * Giving a @c NULL output buffer to UsefulOutBuf_Init() is used when
1299   * just calculating the length of the encoded data.
1300   */
1301 static inline int UsefulOutBuf_IsBufferNULL(UsefulOutBuf *pUOutBuf);
1302 
1303 
1304 /**
1305  * @brief Returns pointer and length of the output buffer not yet used.
1306  *
1307  * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
1308  *
1309  * @return pointer and length of output buffer not used.
1310  *
1311  * This is an escape that allows the caller to write directly
1312  * to the output buffer without any checks. This doesn't
1313  * change the output buffer or state. It just returns a pointer
1314  * and length of the bytes remaining.
1315  *
1316  * This is useful to avoid having the bytes to be added all
1317  * in a contiguous buffer. Its use can save memory. A good
1318  * example is in the COSE encrypt implementation where
1319  * the output of the symmetric cipher can go directly
1320  * into the output buffer, rather than having to go into
1321  * an intermediate buffer.
1322  *
1323  * See UsefulOutBuf_Advance() which is used to tell
1324  * UsefulOutBuf how much was written.
1325  *
1326  * Warning: this bypasses the buffer safety provided by
1327  * UsefulOutBuf!
1328  */
1329 static inline UsefulBuf
1330 UsefulOutBuf_GetOutPlace(UsefulOutBuf *pUOutBuf);
1331 
1332 
1333 /**
1334  * @brief Advance the amount output assuming it was written by the caller.
1335  *
1336  * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
1337  * @param[in] uAmount  The amount to advance.
1338  *
1339  * This advances the position in the output buffer
1340  * by \c uAmount. This assumes that the
1341  * caller has written \c uAmount to the pointer obtained
1342  * with UsefulOutBuf_GetOutPlace().
1343  *
1344  * Warning: this bypasses the buffer safety provided by
1345  * UsefulOutBuf!
1346  */
1347 void
1348 UsefulOutBuf_Advance(UsefulOutBuf *pUOutBuf, size_t uAmount);
1349 
1350 
1351 /**
1352  *  @brief Returns the resulting valid data in a UsefulOutBuf
1353  *
1354  *  @param[in] pUOutBuf Pointer to the @ref UsefulOutBuf.
1355  *
1356  *  @return The valid data in @ref UsefulOutBuf or
1357  *           @ref NULLUsefulBufC if there was an error adding data.
1358  *
1359  *  The storage for the returned data is the @c Storage parameter
1360  *  passed to UsefulOutBuf_Init(). See also UsefulOutBuf_CopyOut().
1361  *
1362  *  This can be called anytime and many times to get intermediate
1363  *  results. It doesn't change the data or reset the current position,
1364  *  so further data can be added.
1365  */
1366 UsefulBufC UsefulOutBuf_OutUBuf(UsefulOutBuf *pUOutBuf);
1367 
1368 
1369 /**
1370  * @brief Copies the valid data into a supplied buffer
1371  *
1372  * @param[in] pUOutBuf  Pointer to the @ref UsefulOutBuf.
1373  * @param[out] Dest     The destination buffer to copy into.
1374  *
1375  * @return Pointer and length of copied data or @c NULLUsefulBufC
1376  *         if it will not fit in the @c Dest buffer or the error
1377  *         state was entered.
1378  *
1379  * This is the same as UsefulOutBuf_OutUBuf() except it copies the
1380  * data to @c Dest.
1381  */
1382 UsefulBufC UsefulOutBuf_CopyOut(UsefulOutBuf *pUOutBuf, UsefulBuf Dest);
1383 
1384 
1385 
1386 
1387 /**
1388  * @ref UsefulInputBuf is the counterpart to @ref UsefulOutBuf. It is
1389  * for parsing data received.  Initialize it with the data from the
1390  * network. Then use the functions like UsefulInputBuf_GetBytes() to
1391  * get data chunks of various types. A position cursor is maintained
1392  * internally.
1393  *
1394  * As long as the functions here are used, there will never be any
1395  * reference off the end of the given buffer (except
1396  * UsefulInputBuf_SetBufferLength()). This is true even if they are
1397  * called incorrectly, an attempt is made to seek off the end of the
1398  * buffer or such. This makes it easier to write safe and correct
1399  * code.  For example, the QCBOR decoder implementation is safer and
1400  * easier to review through its use of @ref UsefulInputBuf.
1401  *
1402  * @ref UsefulInputBuf maintains an internal error state.  The
1403  * intended use is fetching data chunks without any error checks until
1404  * the end.  If there was any error, such as an attempt to fetch data
1405  * off the end, the error state is entered and no further data will be
1406  * returned. In the error state the @c UsefulInputBuf_GetXxxx()
1407  * functions return 0, or @c NULL or @ref NULLUsefulBufC. As long as
1408  * null is not dereferenced, the error check can be put off until the
1409  * end, simplifying the calling code.
1410  *
1411  * The integer and float parsing expects network byte order (big
1412  * endian).  Network byte order is what is used by TCP/IP, CBOR and
1413  * most internet protocols.
1414  *
1415  * Lots of inline functions are used to keep code size down. The
1416  * optimizer, particularly with the @c -Os or @c -O3, also reduces
1417  * code size a lot. The only non-inline code is
1418  * UsefulInputBuf_GetBytes().  It is less than 100 bytes so use of
1419  * @ref UsefulInputBuf doesn't add much code for all the messy
1420  * hard-to-get right issues with parsing binary protocols in C that it
1421  * solves.
1422  *
1423  * The parse context size is:
1424  *   - 64-bit machine: 16 + 8 + 2 + 1 (+ 5 bytes padding to align) = 32 bytes
1425  *   - 32-bit machine: 8 + 4 + 2 + 1 (+ 1 byte padding to align) = 16 bytes
1426  */
1427 typedef struct useful_input_buf {
1428    /* PRIVATE DATA STRUCTURE */
1429    UsefulBufC UB;     /* Data being parsed */
1430    size_t     cursor; /* Current offset in data being parse */
1431    uint16_t   magic;  /* Check for corrupted or uninitialized UsefulInputBuf */
1432    uint8_t    err;    /* Set request goes off end or magic number is bad */
1433 } UsefulInputBuf;
1434 
1435 #define UIB_MAGIC (0xB00F)
1436 
1437 
1438 /**
1439  * @brief Initialize the @ref UsefulInputBuf structure before use.
1440  *
1441  * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
1442  * @param[in] UB       The data to parse.
1443  */
1444 static inline void UsefulInputBuf_Init(UsefulInputBuf *pUInBuf, UsefulBufC UB);
1445 
1446 
1447 /**
1448  * @brief Returns current position in input buffer.
1449  *
1450  * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
1451  *
1452  * @return Integer position of the cursor.
1453  *
1454  * The position that the next bytes will be returned from.
1455  */
1456 static size_t UsefulInputBuf_Tell(UsefulInputBuf *pUInBuf);
1457 
1458 
1459 /**
1460  * @brief Sets the current position in input buffer.
1461  *
1462  * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
1463  * @param[in] uPos     Position to set to.
1464  *
1465  * If the position is off the end of the input buffer, the error state
1466  * is entered.
1467  *
1468  * Seeking to a valid position in the buffer will not reset the error
1469  * state. Only re-initialization will do that.
1470  */
1471 static void UsefulInputBuf_Seek(UsefulInputBuf *pUInBuf, size_t uPos);
1472 
1473 
1474 /**
1475  * @brief Returns the number of bytes from the cursor to the end of the buffer,
1476  * the unconsumed bytes.
1477  *
1478  * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
1479  *
1480  * @return Number of bytes unconsumed or 0 on error.
1481  *
1482  * Returns 0 if the cursor is invalid or corruption of the
1483  * @ref UsefulInputBuf structure is detected.
1484  */
1485 static size_t UsefulInputBuf_BytesUnconsumed(UsefulInputBuf *pUInBuf);
1486 
1487 
1488 /**
1489  * @brief Check if there are unconsumed bytes.
1490  *
1491  * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
1492  * @param[in] uLen     Number of bytes to check availability for.
1493  *
1494  * @return 1 if @c uLen bytes are available after the cursor, and 0 if not.
1495  */
1496 static int UsefulInputBuf_BytesAvailable(UsefulInputBuf *pUInBuf, size_t uLen);
1497 
1498 
1499 /**
1500  * @brief Convert a pointer to an offset with bounds checking.
1501  *
1502  * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
1503  * @param[in] p        Pointer to convert to offset.
1504  *
1505  * @return SIZE_MAX if @c p is out of range, the byte offset if not.
1506  */
1507 static size_t UsefulInputBuf_PointerToOffset(UsefulInputBuf *pUInBuf, const void *p);
1508 
1509 
1510 /**
1511  * @brief Convert an offset to a pointer with bounds checking.
1512  *
1513  * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
1514  * @param[in] uOffset  Offset in @c pUInBuf.
1515  *
1516  * @return @c NULL if @c uOffset is out of range, a pointer into the buffer if not.
1517  */
1518 static const void *UsefulInputBuf_OffsetToPointer(UsefulInputBuf *pUInBuf, size_t uOffset);
1519 
1520 
1521 /**
1522  * @brief Get pointer to bytes out of the input buffer.
1523  *
1524  * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
1525  * @param[in] uNum     Number of bytes to get.
1526  *
1527  * @return Pointer to bytes.
1528  *
1529  * This consumes @c uNum bytes from the input buffer. This returns a
1530  * pointer to the start of the @c uNum bytes.
1531  *
1532  * If there are not @c uNum bytes in the input buffer, @c NULL will be
1533  * returned and the error state is entered.
1534  *
1535  * This advances the position cursor by @c uNum bytes.
1536  */
1537 const void * UsefulInputBuf_GetBytes(UsefulInputBuf *pUInBuf, size_t uNum);
1538 
1539 
1540 /**
1541  * @brief Get @ref UsefulBuf out of the input buffer.
1542  *
1543  * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
1544  * @param[in] uNum     Number of bytes to get.
1545  *
1546  * @return A @ref UsefulBufC with ptr and length of bytes consumed.
1547  *
1548  * This consumes @c uNum bytes from the input buffer and returns the
1549  * pointer and length for them as a @ref UsefulBufC. The length
1550  * returned will always be @c uNum. The position cursor is advanced by
1551  * @c uNum bytes.
1552  *
1553  * If there are not @c uNum bytes in the input buffer, @ref
1554  * NULLUsefulBufC will be returned and the error state is entered.
1555  */
1556 static inline UsefulBufC UsefulInputBuf_GetUsefulBuf(UsefulInputBuf *pUInBuf, size_t uNum);
1557 
1558 
1559 /**
1560  * @brief Get a byte out of the input buffer.
1561  *
1562  * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
1563  *
1564  * @return The byte.
1565  *
1566  * This consumes 1 byte from the input buffer, returns it and advances
1567  * the position cursor by 1.
1568  *
1569  * If there is not 1 byte in the buffer, 0 will be returned for the
1570  * byte and the error state is entered. To know if the 0 returned was
1571  * in error or the real value, the error state must be checked.  If
1572  * possible, put this off until all values are retrieved to have
1573  * smaller and simpler code, but if not possible
1574  * UsefulInputBuf_GetError() can be called. Also, in the error state
1575  * UsefulInputBuf_GetBytes() returns @c NULL *or the @c ptr from
1576  * UsefulInputBuf_GetUsefulBuf() is @c NULL.
1577  */
1578 static inline uint8_t UsefulInputBuf_GetByte(UsefulInputBuf *pUInBuf);
1579 
1580 
1581 /**
1582  * @brief Get a @c uint16_t out of the input buffer.
1583  *
1584  * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
1585  *
1586  * @return The @c uint16_t.
1587  *
1588  * See UsefulInputBuf_GetByte(). This works the same, except it returns
1589  * a @c uint16_t and two bytes are consumed.
1590  *
1591  * The input bytes are interpreted in network order (big endian).
1592  */
1593 static inline uint16_t UsefulInputBuf_GetUint16(UsefulInputBuf *pUInBuf);
1594 
1595 
1596 /**
1597  * @brief Get a @c uint32_t out of the input buffer.
1598  *
1599  * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
1600  *
1601  * @return The @c uint32_t.
1602  *
1603  * See UsefulInputBuf_GetByte(). This works the same, except it
1604  * returns a @c uint32_t and four bytes are consumed.
1605  *
1606  * The input bytes are interpreted in network order (big endian).
1607  */
1608 static uint32_t UsefulInputBuf_GetUint32(UsefulInputBuf *pUInBuf);
1609 
1610 
1611 /**
1612  * @brief Get a @c uint64_t out of the input buffer.
1613  *
1614  * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
1615  *
1616  * @return The uint64_t.
1617  *
1618  * See UsefulInputBuf_GetByte(). This works the same, except it returns
1619  * a @c uint64_t and eight bytes are consumed.
1620  *
1621  * The input bytes are interpreted in network order (big endian).
1622  */
1623 static uint64_t UsefulInputBuf_GetUint64(UsefulInputBuf *pUInBuf);
1624 
1625 
1626 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
1627 /**
1628  * @brief Get a float out of the input buffer.
1629  *
1630  * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
1631  *
1632  * @return The float.
1633  *
1634  * See UsefulInputBuf_GetByte(). This works the same, except it
1635  * returns a float and four bytes are consumed.
1636  *
1637  * The input bytes are interpreted in network order (big endian).
1638  */
1639 static float UsefulInputBuf_GetFloat(UsefulInputBuf *pUInBuf);
1640 
1641 
1642 /**
1643  * @brief Get a double out of the input buffer.
1644  *
1645  * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
1646  *
1647  * @return The double.
1648  *
1649  * See UsefulInputBuf_GetByte(). This works the same, except it
1650  * returns a double and eight bytes are consumed.
1651  *
1652  * The input bytes are interpreted in network order (big endian).
1653  */
1654 static double UsefulInputBuf_GetDouble(UsefulInputBuf *pUInBuf);
1655 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
1656 
1657 
1658 /**
1659  * @brief Get the error status.
1660  *
1661  * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
1662  *
1663  * @return 0 if not in the error state, 1 if in the error state.
1664  *
1665  * This returns whether the @ref UsefulInputBuf is in the
1666  * error state or not.
1667  *
1668  * The error state is entered for one of these reasons:
1669  * - Attempt to fetch data past the end of the buffer
1670  * - Attempt to seek to a position past the end of the buffer
1671  * - Attempt to get data from an uninitialized  or corrupt instance
1672  *   of @ref UsefulInputBuf
1673  *
1674  * Once in the error state, it can only be cleared by calling
1675  * UsefulInputBuf_Init().
1676  *
1677  * For many use cases, it is possible to only call this once after all
1678  * the @c UsefulInputBuf_GetXxxx() calls have been made.  This is
1679  * possible if no reference to the data returned are needed before the
1680  * error state is checked.
1681  *
1682  * In some cases UsefulInputBuf_GetUsefulBuf() or
1683  * UsefulInputBuf_GetBytes() can stand in for this because they return
1684  * @c NULL if the error state has been entered. (The others can't stand
1685  * in because they don't return a clearly distinct error value.)
1686  */
1687 static int UsefulInputBuf_GetError(UsefulInputBuf *pUInBuf);
1688 
1689 
1690 /**
1691  * @brief Gets the input buffer length.
1692  *
1693  * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
1694  *
1695  * @return The length of the input buffer.
1696  *
1697  * This returns the length of the input buffer set by
1698  * UsefulInputBuf_Init() or UsefulInputBuf_SetBufferLength().
1699  */
1700 static inline size_t UsefulInputBuf_GetBufferLength(UsefulInputBuf *pUInBuf);
1701 
1702 
1703 /**
1704  * @brief Alters the input buffer length (use with caution).
1705  *
1706  * @param[in] pUInBuf  Pointer to the @ref UsefulInputBuf.
1707  * @param[in] uNewLen  The new length of the input buffer.
1708  *
1709  * This alters the internal remembered length of the input buffer set
1710  * when UsefulInputBuf_Init() was called.
1711  *
1712  * The new length given here should always be equal to or less than
1713  * the length given when UsefulInputBuf_Init() was called. Making it
1714  * larger allows @ref UsefulInputBuf to run off the input buffer.
1715  *
1716  * The typical use is to set a length shorter than that when
1717  * initialized to constrain parsing. If
1718  * UsefulInputBuf_GetBufferLength() was called before this, then the
1719  * original length can be restored with another call to this.
1720  *
1721  * This should be used with caution. It is the only
1722  * @ref UsefulInputBuf method that can violate the safety of input
1723  * buffer parsing.
1724  */
1725 static void UsefulInputBuf_SetBufferLength(UsefulInputBuf *pUInBuf, size_t uNewLen);
1726 
1727 
1728 
1729 
1730 /*----------------------------------------------------------
1731  Inline implementations.
1732  */
UsefulBuf_IsNULL(UsefulBuf UB)1733 static inline int UsefulBuf_IsNULL(UsefulBuf UB)
1734 {
1735    return !UB.ptr;
1736 }
1737 
1738 
UsefulBuf_IsNULLC(UsefulBufC UB)1739 static inline int UsefulBuf_IsNULLC(UsefulBufC UB)
1740 {
1741    return !UB.ptr;
1742 }
1743 
1744 
UsefulBuf_IsEmpty(UsefulBuf UB)1745 static inline int UsefulBuf_IsEmpty(UsefulBuf UB)
1746 {
1747    return !UB.len;
1748 }
1749 
1750 
UsefulBuf_IsEmptyC(UsefulBufC UB)1751 static inline int UsefulBuf_IsEmptyC(UsefulBufC UB)
1752 {
1753    return !UB.len;
1754 }
1755 
1756 
UsefulBuf_IsNULLOrEmpty(UsefulBuf UB)1757 static inline int UsefulBuf_IsNULLOrEmpty(UsefulBuf UB)
1758 {
1759    return UsefulBuf_IsEmpty(UB) || UsefulBuf_IsNULL(UB);
1760 }
1761 
1762 
UsefulBuf_IsNULLOrEmptyC(UsefulBufC UB)1763 static inline int UsefulBuf_IsNULLOrEmptyC(UsefulBufC UB)
1764 {
1765    return UsefulBuf_IsEmptyC(UB) || UsefulBuf_IsNULLC(UB);
1766 }
1767 
1768 
UsefulBuf_Const(const UsefulBuf UB)1769 static inline UsefulBufC UsefulBuf_Const(const UsefulBuf UB)
1770 {
1771    UsefulBufC UBC;
1772    UBC.ptr = UB.ptr;
1773    UBC.len = UB.len;
1774 
1775    return UBC;
1776 }
1777 
UsefulBuf_Unconst(const UsefulBufC UBC)1778 static inline UsefulBuf UsefulBuf_Unconst(const UsefulBufC UBC)
1779 {
1780    UsefulBuf UB;
1781 
1782    /* -Wcast-qual is a good warning flag to use in general. This is
1783     * the one place in UsefulBuf where it needs to be quieted.
1784     */
1785    UB.ptr = (void *)(uintptr_t)UBC.ptr;
1786 
1787    UB.len = UBC.len;
1788 
1789    return UB;
1790 }
1791 
1792 
UsefulBuf_FromSZ(const char * szString)1793 static inline UsefulBufC UsefulBuf_FromSZ(const char *szString)
1794 {
1795    UsefulBufC UBC;
1796    UBC.ptr = szString;
1797    UBC.len = strlen(szString);
1798    return UBC;
1799 }
1800 
1801 
UsefulBuf_Copy(UsefulBuf Dest,const UsefulBufC Src)1802 static inline UsefulBufC UsefulBuf_Copy(UsefulBuf Dest, const UsefulBufC Src)
1803 {
1804    return UsefulBuf_CopyOffset(Dest, 0, Src);
1805 }
1806 
1807 
UsefulBuf_Set(UsefulBuf Dest,uint8_t value)1808 static inline UsefulBufC UsefulBuf_Set(UsefulBuf Dest, uint8_t value)
1809 {
1810    memset(Dest.ptr, value, Dest.len);
1811 
1812    UsefulBufC UBC;
1813    UBC.ptr = Dest.ptr;
1814    UBC.len = Dest.len;
1815 
1816    return UBC;
1817 }
1818 
1819 
UsefulBuf_CopyPtr(UsefulBuf Dest,const void * ptr,size_t len)1820 static inline UsefulBufC UsefulBuf_CopyPtr(UsefulBuf Dest, const void *ptr, size_t len)
1821 {
1822    UsefulBufC UBC;
1823    UBC.ptr = ptr;
1824    UBC.len = len;
1825    return UsefulBuf_Copy(Dest, UBC);
1826 }
1827 
1828 
UsefulBuf_Head(UsefulBufC UB,size_t uAmount)1829 static inline UsefulBufC UsefulBuf_Head(UsefulBufC UB, size_t uAmount)
1830 {
1831    if(uAmount > UB.len) {
1832       return NULLUsefulBufC;
1833    }
1834    UsefulBufC UBC;
1835 
1836    UBC.ptr = UB.ptr;
1837    UBC.len = uAmount;
1838 
1839    return UBC;
1840 }
1841 
1842 
UsefulBuf_Tail(UsefulBufC UB,size_t uAmount)1843 static inline UsefulBufC UsefulBuf_Tail(UsefulBufC UB, size_t uAmount)
1844 {
1845    UsefulBufC ReturnValue;
1846 
1847    if(uAmount > UB.len) {
1848       ReturnValue = NULLUsefulBufC;
1849    } else if(UB.ptr == NULL) {
1850       ReturnValue.ptr = NULL;
1851       ReturnValue.len = UB.len - uAmount;
1852    } else {
1853       ReturnValue.ptr = (const uint8_t *)UB.ptr + uAmount;
1854       ReturnValue.len = UB.len - uAmount;
1855    }
1856 
1857    return ReturnValue;
1858 }
1859 
1860 
UsefulBuf_PointerToOffset(UsefulBufC UB,const void * p)1861 static inline size_t UsefulBuf_PointerToOffset(UsefulBufC UB, const void *p)
1862 {
1863    if(UB.ptr == NULL) {
1864       return SIZE_MAX;
1865    }
1866 
1867    if(p < UB.ptr) {
1868       /* given pointer is before start of buffer */
1869       return SIZE_MAX;
1870    }
1871 
1872    /* Cast to size_t (from ptrdiff_t) is OK because of check above */
1873    const size_t uOffset = (size_t)((const uint8_t *)p - (const uint8_t *)UB.ptr);
1874 
1875     if(uOffset >= UB.len) {
1876       /* given pointer is off the end of the buffer */
1877       return SIZE_MAX;
1878    }
1879 
1880    return uOffset;
1881 }
1882 
1883 
UsefulBuf_OffsetToPointer(UsefulBufC UB,size_t uOffset)1884 static inline const void *UsefulBuf_OffsetToPointer(UsefulBufC UB, size_t uOffset)
1885 {
1886    if(UsefulBuf_IsNULLC(UB) || uOffset >= UB.len) {
1887       return NULL;
1888    }
1889 
1890    return (const uint8_t *)UB.ptr + uOffset;
1891 }
1892 
1893 
1894 
1895 
1896 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
UsefulBufUtil_CopyFloatToUint32(float f)1897 static inline uint32_t UsefulBufUtil_CopyFloatToUint32(float f)
1898 {
1899    uint32_t u32;
1900    memcpy(&u32, &f, sizeof(uint32_t));
1901    return u32;
1902 }
1903 
UsefulBufUtil_CopyDoubleToUint64(double d)1904 static inline uint64_t UsefulBufUtil_CopyDoubleToUint64(double d)
1905 {
1906    uint64_t u64;
1907    memcpy(&u64, &d, sizeof(uint64_t));
1908    return u64;
1909 }
1910 
UsefulBufUtil_CopyUint64ToDouble(uint64_t u64)1911 static inline double UsefulBufUtil_CopyUint64ToDouble(uint64_t u64)
1912 {
1913    double d;
1914    memcpy(&d, &u64, sizeof(uint64_t));
1915    return d;
1916 }
1917 
UsefulBufUtil_CopyUint32ToFloat(uint32_t u32)1918 static inline float UsefulBufUtil_CopyUint32ToFloat(uint32_t u32)
1919 {
1920    float f;
1921    memcpy(&f, &u32, sizeof(uint32_t));
1922    return f;
1923 }
1924 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
1925 
1926 
1927 
1928 
UsefulOutBuf_Reset(UsefulOutBuf * pMe)1929 static inline void UsefulOutBuf_Reset(UsefulOutBuf *pMe)
1930 {
1931    pMe->data_len = 0;
1932    pMe->err      = 0;
1933 }
1934 
1935 
UsefulOutBuf_GetEndPosition(UsefulOutBuf * pMe)1936 static inline size_t UsefulOutBuf_GetEndPosition(UsefulOutBuf *pMe)
1937 {
1938    return pMe->data_len;
1939 }
1940 
1941 
UsefulOutBuf_AtStart(UsefulOutBuf * pMe)1942 static inline int UsefulOutBuf_AtStart(UsefulOutBuf *pMe)
1943 {
1944    return 0 == pMe->data_len;
1945 }
1946 
1947 
UsefulOutBuf_InsertData(UsefulOutBuf * pMe,const void * pBytes,size_t uLen,size_t uPos)1948 static inline void UsefulOutBuf_InsertData(UsefulOutBuf *pMe,
1949                                            const void *pBytes,
1950                                            size_t uLen,
1951                                            size_t uPos)
1952 {
1953    UsefulBufC Data = {pBytes, uLen};
1954    UsefulOutBuf_InsertUsefulBuf(pMe, Data, uPos);
1955 }
1956 
1957 
UsefulOutBuf_InsertString(UsefulOutBuf * pMe,const char * szString,size_t uPos)1958 static inline void UsefulOutBuf_InsertString(UsefulOutBuf *pMe,
1959                                              const char *szString,
1960                                              size_t uPos)
1961 {
1962    UsefulBufC UBC;
1963    UBC.ptr = szString;
1964    UBC.len = strlen(szString);
1965 
1966    UsefulOutBuf_InsertUsefulBuf(pMe, UBC, uPos);
1967 }
1968 
1969 
UsefulOutBuf_InsertByte(UsefulOutBuf * me,uint8_t byte,size_t uPos)1970 static inline void UsefulOutBuf_InsertByte(UsefulOutBuf *me,
1971                                            uint8_t byte,
1972                                            size_t uPos)
1973 {
1974    UsefulOutBuf_InsertData(me, &byte, 1, uPos);
1975 }
1976 
1977 
UsefulOutBuf_InsertUint16(UsefulOutBuf * me,uint16_t uInteger16,size_t uPos)1978 static inline void UsefulOutBuf_InsertUint16(UsefulOutBuf *me,
1979                                              uint16_t uInteger16,
1980                                              size_t uPos)
1981 {
1982    /* See UsefulOutBuf_InsertUint64() for comments on this code */
1983 
1984    const void *pBytes;
1985 
1986 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN)
1987    pBytes = &uInteger16;
1988 
1989 #elif defined(USEFULBUF_CONFIG_HTON)
1990    uint16_t uTmp = htons(uInteger16);
1991    pBytes        = &uTmp;
1992 
1993 #elif defined(USEFULBUF_CONFIG_LITTLE_ENDIAN) && defined(USEFULBUF_CONFIG_BSWAP)
1994    uint16_t uTmp = __builtin_bswap16(uInteger16);
1995    pBytes = &uTmp;
1996 
1997 #else
1998    uint8_t aTmp[2];
1999 
2000    aTmp[0] = (uint8_t)((uInteger16 & 0xff00) >> 8);
2001    aTmp[1] = (uint8_t)(uInteger16 & 0xff);
2002 
2003    pBytes = aTmp;
2004 #endif
2005 
2006    UsefulOutBuf_InsertData(me, pBytes, 2, uPos);
2007 }
2008 
2009 
UsefulOutBuf_InsertUint32(UsefulOutBuf * pMe,uint32_t uInteger32,size_t uPos)2010 static inline void UsefulOutBuf_InsertUint32(UsefulOutBuf *pMe,
2011                                              uint32_t uInteger32,
2012                                              size_t uPos)
2013 {
2014    /* See UsefulOutBuf_InsertUint64() for comments on this code */
2015 
2016    const void *pBytes;
2017 
2018 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN)
2019    pBytes = &uInteger32;
2020 
2021 #elif defined(USEFULBUF_CONFIG_HTON)
2022    uint32_t uTmp = htonl(uInteger32);
2023    pBytes = &uTmp;
2024 
2025 #elif defined(USEFULBUF_CONFIG_LITTLE_ENDIAN) && defined(USEFULBUF_CONFIG_BSWAP)
2026    uint32_t uTmp = __builtin_bswap32(uInteger32);
2027 
2028    pBytes = &uTmp;
2029 
2030 #else
2031    uint8_t aTmp[4];
2032 
2033    aTmp[0] = (uint8_t)((uInteger32 & 0xff000000) >> 24);
2034    aTmp[1] = (uint8_t)((uInteger32 & 0xff0000) >> 16);
2035    aTmp[2] = (uint8_t)((uInteger32 & 0xff00) >> 8);
2036    aTmp[3] = (uint8_t)(uInteger32 & 0xff);
2037 
2038    pBytes = aTmp;
2039 #endif
2040 
2041    UsefulOutBuf_InsertData(pMe, pBytes, 4, uPos);
2042 }
2043 
UsefulOutBuf_InsertUint64(UsefulOutBuf * pMe,uint64_t uInteger64,size_t uPos)2044 static inline void UsefulOutBuf_InsertUint64(UsefulOutBuf *pMe,
2045                                              uint64_t      uInteger64,
2046                                              size_t        uPos)
2047 {
2048    const void *pBytes;
2049 
2050 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN)
2051    /* We have been told explicitly we are running on a big-endian
2052     * machine. Network byte order is big endian, so just copy.  There
2053     * is no issue with alignment here because uInteger64 is always
2054     * aligned (and it doesn't matter if pBytes is aligned).
2055     */
2056    pBytes = &uInteger64;
2057 
2058 #elif defined(USEFULBUF_CONFIG_HTON)
2059    /* Use system function to handle big- and little-endian. This works
2060     * on both big- and little-endian machines, but hton() is not
2061     * always available or in a standard place so it is not used by
2062     * default. With some compilers and CPUs the code for this is very
2063     * compact through use of a special swap instruction and on
2064     * big-endian machines hton() will reduce to nothing.
2065     */
2066    uint64_t uTmp = htonll(uInteger64);
2067 
2068    pBytes = &uTmp;
2069 
2070 #elif defined(USEFULBUF_CONFIG_LITTLE_ENDIAN) && defined(USEFULBUF_CONFIG_BSWAP)
2071    /* Use built-in function for byte swapping. This usually compiles
2072     * to an efficient special byte swap instruction. Unlike hton() it
2073     * does not do this conditionally on the CPU endianness, so this
2074     * code is also conditional on USEFULBUF_CONFIG_LITTLE_ENDIAN
2075     */
2076    uint64_t uTmp = __builtin_bswap64(uInteger64);
2077 
2078    pBytes = &uTmp;
2079 
2080 #else
2081    /* Default which works on every CPU with no dependency on anything
2082     * from the CPU, compiler, libraries or OS.  This always works, but
2083     * it is usually a little larger and slower than hton().
2084     */
2085    uint8_t aTmp[8];
2086 
2087    aTmp[0] = (uint8_t)((uInteger64 & 0xff00000000000000) >> 56);
2088    aTmp[1] = (uint8_t)((uInteger64 & 0xff000000000000) >> 48);
2089    aTmp[2] = (uint8_t)((uInteger64 & 0xff0000000000) >> 40);
2090    aTmp[3] = (uint8_t)((uInteger64 & 0xff00000000) >> 32);
2091    aTmp[4] = (uint8_t)((uInteger64 & 0xff000000) >> 24);
2092    aTmp[5] = (uint8_t)((uInteger64 & 0xff0000) >> 16);
2093    aTmp[6] = (uint8_t)((uInteger64 & 0xff00) >> 8);
2094    aTmp[7] = (uint8_t)(uInteger64 & 0xff);
2095 
2096    pBytes = aTmp;
2097 #endif
2098 
2099    /* Do the insert */
2100    UsefulOutBuf_InsertData(pMe, pBytes, sizeof(uint64_t), uPos);
2101 }
2102 
2103 
2104 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
UsefulOutBuf_InsertFloat(UsefulOutBuf * pMe,float f,size_t uPos)2105 static inline void UsefulOutBuf_InsertFloat(UsefulOutBuf *pMe,
2106                                             float f,
2107                                             size_t uPos)
2108 {
2109    UsefulOutBuf_InsertUint32(pMe, UsefulBufUtil_CopyFloatToUint32(f), uPos);
2110 }
2111 
2112 
UsefulOutBuf_InsertDouble(UsefulOutBuf * pMe,double d,size_t uPos)2113 static inline void UsefulOutBuf_InsertDouble(UsefulOutBuf *pMe,
2114                                              double d,
2115                                              size_t uPos)
2116 {
2117    UsefulOutBuf_InsertUint64(pMe, UsefulBufUtil_CopyDoubleToUint64(d), uPos);
2118 }
2119 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
2120 
2121 
UsefulOutBuf_AppendUsefulBuf(UsefulOutBuf * pMe,UsefulBufC NewData)2122 static inline void UsefulOutBuf_AppendUsefulBuf(UsefulOutBuf *pMe,
2123                                                 UsefulBufC NewData)
2124 {
2125    /* An append is just a insert at the end */
2126    UsefulOutBuf_InsertUsefulBuf(pMe, NewData, UsefulOutBuf_GetEndPosition(pMe));
2127 }
2128 
2129 
UsefulOutBuf_AppendData(UsefulOutBuf * pMe,const void * pBytes,size_t uLen)2130 static inline void UsefulOutBuf_AppendData(UsefulOutBuf *pMe,
2131                                            const void *pBytes,
2132                                            size_t uLen)
2133 {
2134    UsefulBufC Data = {pBytes, uLen};
2135    UsefulOutBuf_AppendUsefulBuf(pMe, Data);
2136 }
2137 
2138 
UsefulOutBuf_AppendString(UsefulOutBuf * pMe,const char * szString)2139 static inline void UsefulOutBuf_AppendString(UsefulOutBuf *pMe,
2140                                              const char *szString)
2141 {
2142    UsefulBufC UBC;
2143    UBC.ptr = szString;
2144    UBC.len = strlen(szString);
2145 
2146    UsefulOutBuf_AppendUsefulBuf(pMe, UBC);
2147 }
2148 
2149 
UsefulOutBuf_AppendByte(UsefulOutBuf * pMe,uint8_t byte)2150 static inline void UsefulOutBuf_AppendByte(UsefulOutBuf *pMe,
2151                                            uint8_t byte)
2152 {
2153    UsefulOutBuf_AppendData(pMe, &byte, 1);
2154 }
2155 
2156 
UsefulOutBuf_AppendUint16(UsefulOutBuf * pMe,uint16_t uInteger16)2157 static inline void UsefulOutBuf_AppendUint16(UsefulOutBuf *pMe,
2158                                              uint16_t uInteger16)
2159 {
2160    UsefulOutBuf_InsertUint16(pMe, uInteger16, UsefulOutBuf_GetEndPosition(pMe));
2161 }
2162 
UsefulOutBuf_AppendUint32(UsefulOutBuf * pMe,uint32_t uInteger32)2163 static inline void UsefulOutBuf_AppendUint32(UsefulOutBuf *pMe,
2164                                              uint32_t uInteger32)
2165 {
2166    UsefulOutBuf_InsertUint32(pMe, uInteger32, UsefulOutBuf_GetEndPosition(pMe));
2167 }
2168 
2169 
UsefulOutBuf_AppendUint64(UsefulOutBuf * pMe,uint64_t uInteger64)2170 static inline void UsefulOutBuf_AppendUint64(UsefulOutBuf *pMe,
2171                                              uint64_t uInteger64)
2172 {
2173    UsefulOutBuf_InsertUint64(pMe, uInteger64, UsefulOutBuf_GetEndPosition(pMe));
2174 }
2175 
2176 
2177 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
UsefulOutBuf_AppendFloat(UsefulOutBuf * pMe,float f)2178 static inline void UsefulOutBuf_AppendFloat(UsefulOutBuf *pMe,
2179                                             float f)
2180 {
2181    UsefulOutBuf_InsertFloat(pMe, f, UsefulOutBuf_GetEndPosition(pMe));
2182 }
2183 
2184 
UsefulOutBuf_AppendDouble(UsefulOutBuf * pMe,double d)2185 static inline void UsefulOutBuf_AppendDouble(UsefulOutBuf *pMe,
2186                                              double d)
2187 {
2188    UsefulOutBuf_InsertDouble(pMe, d, UsefulOutBuf_GetEndPosition(pMe));
2189 }
2190 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
2191 
2192 
UsefulOutBuf_GetError(UsefulOutBuf * pMe)2193 static inline int UsefulOutBuf_GetError(UsefulOutBuf *pMe)
2194 {
2195    return pMe->err;
2196 }
2197 
2198 
UsefulOutBuf_RoomLeft(UsefulOutBuf * pMe)2199 static inline size_t UsefulOutBuf_RoomLeft(UsefulOutBuf *pMe)
2200 {
2201    return pMe->UB.len - pMe->data_len;
2202 }
2203 
2204 
UsefulOutBuf_WillItFit(UsefulOutBuf * pMe,size_t uLen)2205 static inline int UsefulOutBuf_WillItFit(UsefulOutBuf *pMe, size_t uLen)
2206 {
2207    return uLen <= UsefulOutBuf_RoomLeft(pMe);
2208 }
2209 
2210 
UsefulOutBuf_IsBufferNULL(UsefulOutBuf * pMe)2211 static inline int UsefulOutBuf_IsBufferNULL(UsefulOutBuf *pMe)
2212 {
2213    return pMe->UB.ptr == NULL;
2214 }
2215 
2216 
UsefulOutBuf_GetOutPlace(UsefulOutBuf * pUOutBuf)2217 static inline UsefulBuf UsefulOutBuf_GetOutPlace(UsefulOutBuf *pUOutBuf)
2218 {
2219    UsefulBuf R;
2220 
2221    R.len = UsefulOutBuf_RoomLeft(pUOutBuf);
2222    if(R.len > 0 && pUOutBuf->UB.ptr != NULL) {
2223       R.ptr = (uint8_t *)pUOutBuf->UB.ptr + pUOutBuf->data_len;
2224    } else {
2225       R.ptr = NULL;
2226    }
2227 
2228    return R;
2229 }
2230 
2231 
2232 
2233 
UsefulInputBuf_Init(UsefulInputBuf * pMe,UsefulBufC UB)2234 static inline void UsefulInputBuf_Init(UsefulInputBuf *pMe, UsefulBufC UB)
2235 {
2236    pMe->cursor = 0;
2237    pMe->err    = 0;
2238    pMe->magic  = UIB_MAGIC;
2239    pMe->UB     = UB;
2240 }
2241 
UsefulInputBuf_Tell(UsefulInputBuf * pMe)2242 static inline size_t UsefulInputBuf_Tell(UsefulInputBuf *pMe)
2243 {
2244    return pMe->cursor;
2245 }
2246 
2247 
UsefulInputBuf_GetBufferLength(UsefulInputBuf * pMe)2248 static inline size_t UsefulInputBuf_GetBufferLength(UsefulInputBuf *pMe)
2249 {
2250     return pMe->UB.len;
2251 }
2252 
2253 
UsefulInputBuf_Seek(UsefulInputBuf * pMe,size_t uPos)2254 static inline void UsefulInputBuf_Seek(UsefulInputBuf *pMe, size_t uPos)
2255 {
2256    if(uPos > pMe->UB.len) {
2257       pMe->err = 1;
2258    } else {
2259       pMe->cursor = uPos;
2260    }
2261 }
2262 
2263 
UsefulInputBuf_BytesUnconsumed(UsefulInputBuf * pMe)2264 static inline size_t UsefulInputBuf_BytesUnconsumed(UsefulInputBuf *pMe)
2265 {
2266    /* Code Reviewers: THIS FUNCTION DOES POINTER MATH */
2267 
2268    /* Magic number is messed up. Either the structure got overwritten
2269     * or was never initialized.
2270     */
2271    if(pMe->magic != UIB_MAGIC) {
2272       return 0;
2273    }
2274 
2275    /* The cursor is off the end of the input buffer given.
2276     * Presuming there are no bugs in this code, this should never happen.
2277     * If it is so, the struct was corrupted. The check is retained as
2278     * as a defense in case there is a bug in this code or the struct is
2279     * corrupted by an attacker or accidentally.
2280     */
2281    if(pMe->cursor > pMe->UB.len) {
2282       return 0;
2283    }
2284 
2285    /* subtraction can't go negative because of check above */
2286    return pMe->UB.len - pMe->cursor;
2287 }
2288 
2289 
UsefulInputBuf_BytesAvailable(UsefulInputBuf * pMe,size_t uLen)2290 static inline int UsefulInputBuf_BytesAvailable(UsefulInputBuf *pMe, size_t uLen)
2291 {
2292    return UsefulInputBuf_BytesUnconsumed(pMe) >= uLen ? 1 : 0;
2293 }
2294 
2295 
UsefulInputBuf_PointerToOffset(UsefulInputBuf * pUInBuf,const void * p)2296 static inline size_t UsefulInputBuf_PointerToOffset(UsefulInputBuf *pUInBuf, const void *p)
2297 {
2298    return UsefulBuf_PointerToOffset(pUInBuf->UB, p);
2299 }
2300 
2301 
UsefulInputBuf_OffsetToPointer(UsefulInputBuf * pUInBuf,size_t uOffset)2302 static inline const void *UsefulInputBuf_OffsetToPointer(UsefulInputBuf *pUInBuf, size_t uOffset)
2303  {
2304     return UsefulBuf_OffsetToPointer(pUInBuf->UB, uOffset);
2305  }
2306 
2307 
UsefulInputBuf_GetUsefulBuf(UsefulInputBuf * pMe,size_t uNum)2308 static inline UsefulBufC UsefulInputBuf_GetUsefulBuf(UsefulInputBuf *pMe, size_t uNum)
2309 {
2310    const void *pResult = UsefulInputBuf_GetBytes(pMe, uNum);
2311    if(!pResult) {
2312       return NULLUsefulBufC;
2313    } else {
2314       UsefulBufC UBC;
2315       UBC.ptr = pResult;
2316       UBC.len = uNum;
2317       return UBC;
2318    }
2319 }
2320 
2321 
UsefulInputBuf_GetByte(UsefulInputBuf * pMe)2322 static inline uint8_t UsefulInputBuf_GetByte(UsefulInputBuf *pMe)
2323 {
2324    const void *pResult = UsefulInputBuf_GetBytes(pMe, sizeof(uint8_t));
2325 
2326    /* The ternary operator is subject to integer promotion, because
2327     * the operands are smaller than int, so cast back to uint8_t is
2328     * needed to be completely explicit about types (for static
2329     * analyzers).
2330     */
2331    return (uint8_t)(pResult ? *(const uint8_t *)pResult : 0);
2332 }
2333 
UsefulInputBuf_GetUint16(UsefulInputBuf * pMe)2334 static inline uint16_t UsefulInputBuf_GetUint16(UsefulInputBuf *pMe)
2335 {
2336    const uint8_t *pResult = (const uint8_t *)UsefulInputBuf_GetBytes(pMe, sizeof(uint16_t));
2337 
2338    if(!pResult) {
2339       return 0;
2340    }
2341 
2342    /* See UsefulInputBuf_GetUint64() for comments on this code */
2343 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN) || defined(USEFULBUF_CONFIG_HTON) || defined(USEFULBUF_CONFIG_BSWAP)
2344    uint16_t uTmp;
2345    memcpy(&uTmp, pResult, sizeof(uint16_t));
2346 
2347 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN)
2348    return uTmp;
2349 
2350 #elif defined(USEFULBUF_CONFIG_HTON)
2351    return ntohs(uTmp);
2352 
2353 #else
2354    return __builtin_bswap16(uTmp);
2355 
2356 #endif
2357 
2358 #else
2359 
2360    /* The operations here are subject to integer promotion because the
2361     * operands are smaller than int. They will be promoted to unsigned
2362     * int for the shift and addition. The cast back to uint16_t is is
2363     * needed to be completely explicit about types (for static
2364     * analyzers).
2365     */
2366    return (uint16_t)((pResult[0] << 8) + pResult[1]);
2367 
2368 #endif
2369 }
2370 
2371 
UsefulInputBuf_GetUint32(UsefulInputBuf * pMe)2372 static inline uint32_t UsefulInputBuf_GetUint32(UsefulInputBuf *pMe)
2373 {
2374    const uint8_t *pResult = (const uint8_t *)UsefulInputBuf_GetBytes(pMe, sizeof(uint32_t));
2375 
2376    if(!pResult) {
2377       return 0;
2378    }
2379 
2380    /* See UsefulInputBuf_GetUint64() for comments on this code */
2381 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN) || defined(USEFULBUF_CONFIG_HTON) || defined(USEFULBUF_CONFIG_BSWAP)
2382    uint32_t uTmp;
2383    memcpy(&uTmp, pResult, sizeof(uint32_t));
2384 
2385 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN)
2386    return uTmp;
2387 
2388 #elif defined(USEFULBUF_CONFIG_HTON)
2389    return ntohl(uTmp);
2390 
2391 #else
2392    return __builtin_bswap32(uTmp);
2393 
2394 #endif
2395 
2396 #else
2397    return ((uint32_t)pResult[0]<<24) +
2398           ((uint32_t)pResult[1]<<16) +
2399           ((uint32_t)pResult[2]<<8)  +
2400            (uint32_t)pResult[3];
2401 #endif
2402 }
2403 
2404 
UsefulInputBuf_GetUint64(UsefulInputBuf * pMe)2405 static inline uint64_t UsefulInputBuf_GetUint64(UsefulInputBuf *pMe)
2406 {
2407    const uint8_t *pResult = (const uint8_t *)UsefulInputBuf_GetBytes(pMe, sizeof(uint64_t));
2408 
2409    if(!pResult) {
2410       return 0;
2411    }
2412 
2413 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN) || defined(USEFULBUF_CONFIG_HTON) || defined(USEFULBUF_CONFIG_BSWAP)
2414    /* pResult will probably not be aligned.  This memcpy() moves the
2415     * bytes into a temp variable safely for CPUs that can or can't do
2416     * unaligned memory access. Many compilers will optimize the
2417     * memcpy() into a simple move instruction.
2418     */
2419    uint64_t uTmp;
2420    memcpy(&uTmp, pResult, sizeof(uint64_t));
2421 
2422 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN)
2423    /* We have been told expliclity this is a big-endian CPU.  Since
2424     * network byte order is big-endian, there is nothing to do.
2425     */
2426 
2427    return uTmp;
2428 
2429 #elif defined(USEFULBUF_CONFIG_HTON)
2430    /* We have been told to use ntoh(), the system function to handle
2431     * big- and little-endian. This works on both big- and
2432     * little-endian machines, but ntoh() is not always available or in
2433     * a standard place so it is not used by default. On some CPUs the
2434     * code for this is very compact through use of a special swap
2435     * instruction.
2436     */
2437 
2438    return ntohll(uTmp);
2439 
2440 #else
2441    /* Little-endian (since it is not USEFULBUF_CONFIG_BIG_ENDIAN) and
2442     * USEFULBUF_CONFIG_BSWAP (since it is not USEFULBUF_CONFIG_HTON).
2443     * __builtin_bswap64() and friends are not conditional on CPU
2444     * endianness so this must only be used on little-endian machines.
2445     */
2446 
2447    return __builtin_bswap64(uTmp);
2448 
2449 
2450 #endif
2451 
2452 #else
2453    /* This is the default code that works on every CPU and every
2454     * endianness with no dependency on ntoh().  This works on CPUs
2455     * that either allow or do not allow unaligned access. It will
2456     * always work, but usually is a little less efficient than ntoh().
2457     */
2458 
2459    return   ((uint64_t)pResult[0]<<56) +
2460             ((uint64_t)pResult[1]<<48) +
2461             ((uint64_t)pResult[2]<<40) +
2462             ((uint64_t)pResult[3]<<32) +
2463             ((uint64_t)pResult[4]<<24) +
2464             ((uint64_t)pResult[5]<<16) +
2465             ((uint64_t)pResult[6]<<8)  +
2466             (uint64_t)pResult[7];
2467 #endif
2468 }
2469 
2470 
2471 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
UsefulInputBuf_GetFloat(UsefulInputBuf * pMe)2472 static inline float UsefulInputBuf_GetFloat(UsefulInputBuf *pMe)
2473 {
2474    uint32_t uResult = UsefulInputBuf_GetUint32(pMe);
2475 
2476    return uResult ? UsefulBufUtil_CopyUint32ToFloat(uResult) : 0;
2477 }
2478 
2479 
UsefulInputBuf_GetDouble(UsefulInputBuf * pMe)2480 static inline double UsefulInputBuf_GetDouble(UsefulInputBuf *pMe)
2481 {
2482    uint64_t uResult = UsefulInputBuf_GetUint64(pMe);
2483 
2484    return uResult ? UsefulBufUtil_CopyUint64ToDouble(uResult) : 0;
2485 }
2486 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
2487 
2488 
UsefulInputBuf_GetError(UsefulInputBuf * pMe)2489 static inline int UsefulInputBuf_GetError(UsefulInputBuf *pMe)
2490 {
2491    return pMe->err;
2492 }
2493 
2494 
UsefulInputBuf_SetBufferLength(UsefulInputBuf * pMe,size_t uNewLen)2495 static inline void UsefulInputBuf_SetBufferLength(UsefulInputBuf *pMe, size_t uNewLen)
2496 {
2497     pMe->UB.len = uNewLen;
2498 }
2499 
2500 
2501 #ifdef __cplusplus
2502 }
2503 #endif
2504 
2505 #endif  /* _UsefulBuf_h */
2506 
2507 
2508