QCBOR
UsefulBuf.h
Go to the documentation of this file.
1 /* =========================================================================
2  * Copyright (c) 2016-2018, The Linux Foundation.
3  * Copyright (c) 2018-2025, Laurence Lundblade.
4  * Copyright (c) 2021, Arm Limited. All rights reserved.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are
9  * met:
10  * * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above
13  * copyright notice, this list of conditions and the following
14  * disclaimer in the documentation and/or other materials provided
15  * with the distribution.
16  * * Neither the name of The Linux Foundation nor the names of its
17  * contributors, nor the name "Laurence Lundblade" may be used to
18  * endorse or promote products derived from this software without
19  * specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
22  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
30  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
31  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  * ========================================================================= */
33 
34 /*============================================================================
35  FILE: UsefulBuf.h
36 
37  DESCRIPTION: General purpose input and output buffers
38 
39  EDIT HISTORY FOR FILE:
40 
41  This section contains comments describing changes made to the module.
42  Notice that changes are listed in reverse chronological order.
43 
44  when who what, where, why
45  -------- ---- --------------------------------------------------
46  11/10/2025 llundblade Explicitly size integer literals (MSVC fix).
47  08/14/2024 llundblade Add UsefulOutBuf_RetrieveOutputStorage().
48  08/13/2024 llundblade Add UsefulInputBuf_RetrieveUndecodedInput().
49  08/08/2024 llundblade Add UsefulOutBuf_SubString().
50  10/05/2024 llundblade Add Xxx_OffsetToPointer.
51  19/12/2022 llundblade Document that adding empty data is allowed.
52  4/11/2022 llundblade Add GetOutPlace and Advance to UsefulOutBuf.
53  9/21/2021 llundbla Clarify UsefulOutBuf size calculation mode
54  8/8/2021 dthaler/llundbla Work with C++ without compiler extensions
55  5/11/2021 llundblade Improve comments and comment formatting.
56  3/6/2021 mcr/llundblade Fix warnings related to --Wcast-qual
57  2/17/2021 llundblade Add method to go from a pointer to an offset.
58  1/25/2020 llundblade Add some casts so static anlyzers don't complain.
59  5/21/2019 llundblade #define configs for efficient endianness handling.
60  5/16/2019 llundblade Add UsefulOutBuf_IsBufferNULL().
61  3/23/2019 llundblade Big documentation & style update. No interface
62  change.
63  3/6/2019 llundblade Add UsefulBuf_IsValue()
64  12/17/2018 llundblade Remove const from UsefulBuf and UsefulBufC .len
65  12/13/2018 llundblade Documentation improvements
66  09/18/2018 llundblade Cleaner distinction between UsefulBuf and
67  UsefulBufC.
68  02/02/18 llundbla Full support for integers in and out; fix pointer
69  alignment bug. Incompatible change: integers
70  in/out are now in network byte order.
71  08/12/17 llundbla Added UsefulOutBuf_AtStart and UsefulBuf_Find
72  06/27/17 llundbla Fix UsefulBuf_Compare() bug. Only affected
73  comparison for < or > for unequal length buffers.
74  Added UsefulBuf_Set() function.
75  05/30/17 llundbla Functions for NULL UsefulBufs and const / unconst
76  11/13/16 llundbla Initial Version.
77 
78  =============================================================================*/
79 
80 #ifndef _UsefulBuf_h
81 #define _UsefulBuf_h
82 
83 
84 /*
85  * Endianness Configuration
86  *
87  * This code is written so it will work correctly on big- and
88  * little-endian CPUs without configuration or any auto-detection of
89  * endianness. All code here will run correctly regardless of the
90  * endianness of the CPU it is running on.
91  *
92  * There are four C preprocessor macros that can be set with #define
93  * to explicitly configure endianness handling. Setting them can
94  * reduce code size a little and improve efficiency a little.
95  *
96  * Note that most of QCBOR is unaffected by this configuration. Its
97  * endianness handling is integrated with the code that handles
98  * alignment and preferred serialization. This configuration does
99  * affect QCBOR's (planned) implementation of integer arrays (tagged
100  * arrays) and use of the functions here to serialize or deserialize
101  * integers and floating-point values.
102  *
103  * Following is the recipe for configuring the endianness-related
104  * #defines.
105  *
106  * The first option is to not define anything. This will work fine
107  * with all CPUs, OS's and compilers. The code for encoding integers
108  * may be a little larger and slower.
109  *
110  * If your CPU is big-endian then define
111  * USEFULBUF_CONFIG_BIG_ENDIAN. This will give the most efficient code
112  * for big-endian CPUs. It will be small and efficient because there
113  * will be no byte swapping.
114  *
115  * Try defining USEFULBUF_CONFIG_HTON. This will work on most CPUs,
116  * OS's and compilers, but not all. On big-endian CPUs this should
117  * give the most efficient code, the same as
118  * USEFULBUF_CONFIG_BIG_ENDIAN does. On little-endian CPUs it should
119  * call the system-defined byte swapping method which is presumably
120  * implemented efficiently. In some cases, this will be a dedicated
121  * byte swap instruction like Intel's bswap.
122  *
123  * If USEFULBUF_CONFIG_HTON works and you know your CPU is
124  * little-endian, it is also good to define
125  * USEFULBUF_CONFIG_LITTLE_ENDIAN.
126  *
127  * if USEFULBUF_CONFIG_HTON doesn't work and you know your system is
128  * little-endian, try defining both USEFULBUF_CONFIG_LITTLE_ENDIAN and
129  * USEFULBUF_CONFIG_BSWAP. This should call the most efficient
130  * system-defined byte swap method. However, note
131  * https://hardwarebug.org/2010/01/14/beware-the-builtins/. Perhaps
132  * this is fixed now. Often hton() and ntoh() will call the built-in
133  * __builtin_bswapXX()() function, so this size issue could affect
134  * USEFULBUF_CONFIG_HTON.
135  *
136  * Last, run the tests. They must all pass.
137  *
138  * These #define config options affect the inline implementation of
139  * UsefulOutBuf_InsertUint64() and UsefulInputBuf_GetUint64(). They
140  * also affect the 16-, 32-bit, float and double versions of these
141  * functions. Since they are inline, the size effect is not in the
142  * UsefulBuf object code, but in the calling code.
143  *
144  * Summary:
145  * USEFULBUF_CONFIG_BIG_ENDIAN -- Force configuration to big-endian.
146  * USEFULBUF_CONFIG_LITTLE_ENDIAN -- Force to little-endian.
147  * USEFULBUF_CONFIG_HTON -- Use hton(), htonl(), ntohl()... to
148  * handle big and little-endian with system option.
149  * USEFULBUF_CONFIG_BSWAP -- With USEFULBUF_CONFIG_LITTLE_ENDIAN,
150  * use __builtin_bswapXX().
151  *
152  * It is possible to run this code in environments where using floating point is
153  * not allowed. Defining USEFULBUF_DISABLE_ALL_FLOAT will disable all the code
154  * that is related to handling floating point types, along with related
155  * interfaces. This makes it possible to compile the code with the compile
156  * option -mgeneral-regs-only.
157  */
158 
159 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN) && defined(USEFULBUF_CONFIG_LITTLE_ENDIAN)
160 #error "Cannot define both USEFULBUF_CONFIG_BIG_ENDIAN and USEFULBUF_CONFIG_LITTLE_ENDIAN"
161 #endif
162 
163 
164 #include <stdint.h> /* for uint8_t, uint16_t.... */
165 #include <string.h> /* for strlen, memcpy, memmove, memset */
166 #include <stddef.h> /* for size_t */
167 
168 
169 #ifdef USEFULBUF_CONFIG_HTON
170 #include <arpa/inet.h> /* for htons, htonl, htonll, ntohs... */
171 #endif
172 
173 #ifdef __cplusplus
174 extern "C" {
175 #if 0
176 } /* Keep editor indention formatting happy */
177 #endif
178 #endif
179 
273 typedef struct q_useful_buf_c {
274  const void *ptr;
275  size_t len;
277 
278 
284 typedef struct q_useful_buf {
285  void *ptr;
286  size_t len;
288 
289 
296 /*
297  * NULLUsefulBufC and few other macros have to be
298  * definied differently in C than C++ because there
299  * is no common construct for a literal structure.
300  *
301  * In C compound literals are used.
302  *
303  * In C++ list initalization is used. This only works
304  * in C++11 and later.
305  *
306  * Note that some popular C++ compilers can handle compound
307  * literals with on-by-default extensions, however
308  * this code aims for full correctness with strict
309  * compilers so they are not used.
310  */
311 #ifdef __cplusplus
312 #define NULLUsefulBufC {NULL, 0}
313 #else
314 #define NULLUsefulBufC ((UsefulBufC) {NULL, 0})
315 #endif
316 
321 #ifdef __cplusplus
322 #define NULLUsefulBuf {NULL, 0}
323 #else
324 #define NULLUsefulBuf ((UsefulBuf) {NULL, 0})
325 #endif
326 
327 
335 static inline int UsefulBuf_IsNULL(UsefulBuf UB);
336 
337 
345 static inline int UsefulBuf_IsNULLC(UsefulBufC UB);
346 
347 
365 static inline int UsefulBuf_IsEmpty(UsefulBuf UB);
366 
367 
375 static inline int UsefulBuf_IsEmptyC(UsefulBufC UB);
376 
377 
385 static inline int UsefulBuf_IsNULLOrEmpty(UsefulBuf UB);
386 
387 
395 static inline int UsefulBuf_IsNULLOrEmptyC(UsefulBufC UB);
396 
397 
405 static inline UsefulBufC UsefulBuf_Const(const UsefulBuf UB);
406 
407 
425 static inline UsefulBuf UsefulBuf_Unconst(const UsefulBufC UBC);
426 
427 
437 #ifdef __cplusplus
438 #define UsefulBuf_FROM_SZ_LITERAL(szString) {(szString), sizeof(szString)-1}
439 #else
440 #define UsefulBuf_FROM_SZ_LITERAL(szString) \
441  ((UsefulBufC) {(szString), sizeof(szString)-1})
442 #endif
443 
444 
451 #ifdef __cplusplus
452 #define UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pBytes) {(pBytes), sizeof(pBytes)}
453 #else
454 #define UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pBytes) \
455  ((UsefulBufC) {(pBytes), sizeof(pBytes)})
456 #endif
457 
462 #define UsefulBuf_MAKE_STACK_UB(name, size) \
463  uint8_t __pBuf##name[(size)];\
464  UsefulBuf name = {__pBuf##name , sizeof( __pBuf##name )}
465 
466 
472 #ifdef __cplusplus
473 #define UsefulBuf_FROM_BYTE_ARRAY(pBytes) {(pBytes), sizeof(pBytes)}
474 #else
475 #define UsefulBuf_FROM_BYTE_ARRAY(pBytes) \
476  ((UsefulBuf) {(pBytes), sizeof(pBytes)})
477 #endif
478 
479 
492 static inline UsefulBufC UsefulBuf_FromSZ(const char *szString);
493 
494 
516 UsefulBufC UsefulBuf_CopyOffset(UsefulBuf Dest, size_t uOffset, const UsefulBufC Src);
517 
518 
536 static inline UsefulBufC UsefulBuf_Copy(UsefulBuf Dest, const UsefulBufC Src);
537 
538 
548 static inline UsefulBufC UsefulBuf_Set(UsefulBuf pDest, uint8_t value);
549 
550 
567 static inline UsefulBufC UsefulBuf_CopyPtr(UsefulBuf Dest,
568  const void *ptr,
569  size_t uLen);
570 
571 
580 static inline UsefulBufC UsefulBuf_Head(UsefulBufC UB, size_t uAmount);
581 
582 
596 static inline UsefulBufC UsefulBuf_Tail(UsefulBufC UB, size_t uAmount);
597 
598 
619 int UsefulBuf_Compare(const UsefulBufC UB1, const UsefulBufC UB2);
620 
621 
640 size_t UsefulBuf_IsValue(const UsefulBufC UB, uint8_t uValue);
641 
642 
651 size_t UsefulBuf_FindBytes(UsefulBufC BytesToSearch, UsefulBufC BytesToFind);
652 
653 
662 static inline size_t UsefulBuf_PointerToOffset(UsefulBufC UB, const void *p);
663 
664 
673 static inline const void *UsefulBuf_OffsetToPointer(UsefulBufC UB, size_t uOffset);
674 
675 
676 #ifndef USEFULBUF_DISABLE_DEPRECATED
678 #define SZLiteralToUsefulBufC(szString) UsefulBuf_FROM_SZ_LITERAL(szString)
679 
681 #define MakeUsefulBufOnStack(name, size) \
682  uint8_t __pBuf##name[(size)];\
683  UsefulBuf name = {__pBuf##name , sizeof( __pBuf##name )}
684 
686 #define ByteArrayLiteralToUsefulBufC(pBytes) \
687  UsefulBuf_FROM_BYTE_ARRAY_LITERAL(pBytes)
688 
690 static inline UsefulBuf UsefulBufC_Unconst(const UsefulBufC UBC)
691 {
692  UsefulBuf UB;
693 
694  /* See UsefulBuf_Unconst() implementation for comment */
695  UB.ptr = (void *)(uintptr_t)UBC.ptr;
696 
697  UB.len = UBC.len;
698 
699  return UB;
700 }
701 #endif /* USEFULBUF_DISABLE_DEPRECATED */
702 
703 
704 
705 
706 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
718 static inline uint32_t UsefulBufUtil_CopyFloatToUint32(float f);
719 
720 
732 static inline uint64_t UsefulBufUtil_CopyDoubleToUint64(double d);
733 
734 
746 static inline float UsefulBufUtil_CopyUint32ToFloat(uint32_t u32);
747 
748 
760 static inline double UsefulBufUtil_CopyUint64ToDouble(uint64_t u64);
761 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
762 
763 
764 
765 
845 typedef struct useful_out_buf {
846  /* PRIVATE DATA STRUCTURE */
847  UsefulBuf UB; /* Memory that is being output to */
848  size_t data_len; /* length of the valid data, the insertion point */
849  uint16_t magic; /* Used to detect corruption and lack
850  * of initialization */
851  uint8_t err;
853 
854 
865 #ifdef __cplusplus
866 #define SizeCalculateUsefulBuf {NULL, SIZE_MAX}
867 #else
868 #define SizeCalculateUsefulBuf ((UsefulBuf) {NULL, SIZE_MAX})
869 #endif
870 
871 
888 void UsefulOutBuf_Init(UsefulOutBuf *pUOutBuf, UsefulBuf Storage);
889 
890 
896 #define UsefulOutBuf_MakeOnStack(name, size) \
897  uint8_t __pBuf##name[(size)];\
898  UsefulOutBuf name;\
899  UsefulOutBuf_Init(&(name), (UsefulBuf){__pBuf##name, (size)});
900 
901 
915 static inline void UsefulOutBuf_Reset(UsefulOutBuf *pUOutBuf);
916 
917 
932 static inline size_t UsefulOutBuf_GetEndPosition(UsefulOutBuf *pUOutBuf);
933 
934 
942 static inline int UsefulOutBuf_AtStart(UsefulOutBuf *pUOutBuf);
943 
944 
980  UsefulBufC NewData,
981  size_t uPos);
982 
983 
996 static inline void UsefulOutBuf_InsertData(UsefulOutBuf *pUOutBuf,
997  const void *pBytes,
998  size_t uLen,
999  size_t uPos);
1000 
1001 
1009 static inline void UsefulOutBuf_InsertString(UsefulOutBuf *pUOutBuf,
1010  const char *szString,
1011  size_t uPos);
1012 
1013 
1024 static inline void UsefulOutBuf_InsertByte(UsefulOutBuf *pUOutBuf,
1025  uint8_t byte,
1026  size_t uPos);
1027 
1028 
1041 static inline void UsefulOutBuf_InsertUint16(UsefulOutBuf *pUOutBuf,
1042  uint16_t uInteger16,
1043  size_t uPos);
1044 
1045 
1058 static inline void UsefulOutBuf_InsertUint32(UsefulOutBuf *pUOutBuf,
1059  uint32_t uInteger32,
1060  size_t uPos);
1061 
1062 
1075 static inline void UsefulOutBuf_InsertUint64(UsefulOutBuf *pUOutBuf,
1076  uint64_t uInteger64,
1077  size_t uPos);
1078 
1079 
1080 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
1093 static inline void UsefulOutBuf_InsertFloat(UsefulOutBuf *pUOutBuf,
1094  float f,
1095  size_t uPos);
1096 
1097 
1110 static inline void UsefulOutBuf_InsertDouble(UsefulOutBuf *pUOutBuf,
1111  double d,
1112  size_t uPos);
1113 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
1114 
1115 
1125 static inline void UsefulOutBuf_AppendUsefulBuf(UsefulOutBuf *pUOutBuf,
1126  UsefulBufC NewData);
1127 
1128 
1139 static inline void UsefulOutBuf_AppendData(UsefulOutBuf *pUOutBuf,
1140  const void *pBytes,
1141  size_t uLen);
1142 
1143 
1150 static inline void UsefulOutBuf_AppendString(UsefulOutBuf *pUOutBuf,
1151  const char *szString);
1152 
1153 
1163 static inline void UsefulOutBuf_AppendByte(UsefulOutBuf *pUOutBuf,
1164  uint8_t byte);
1165 
1166 
1178 static inline void UsefulOutBuf_AppendUint16(UsefulOutBuf *pUOutBuf,
1179  uint16_t uInteger16);
1180 
1181 
1193 static inline void UsefulOutBuf_AppendUint32(UsefulOutBuf *pUOutBuf,
1194  uint32_t uInteger32);
1195 
1196 
1208 static inline void UsefulOutBuf_AppendUint64(UsefulOutBuf *pUOutBuf,
1209  uint64_t uInteger64);
1210 
1211 
1212 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
1224 static inline void UsefulOutBuf_AppendFloat(UsefulOutBuf *pUOutBuf,
1225  float f);
1226 
1227 
1239 static inline void UsefulOutBuf_AppendDouble(UsefulOutBuf *pUOutBuf,
1240  double d);
1241 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
1242 
1243 
1262 static inline int UsefulOutBuf_GetError(UsefulOutBuf *pUOutBuf);
1263 
1264 
1276 static inline size_t UsefulOutBuf_RoomLeft(UsefulOutBuf *pUOutBuf);
1277 
1278 
1291 static inline int UsefulOutBuf_WillItFit(UsefulOutBuf *pUOutBuf, size_t uLen);
1292 
1293 
1304 static inline int UsefulOutBuf_IsBufferNULL(UsefulOutBuf *pUOutBuf);
1305 
1306 
1332 static inline UsefulBuf
1334 
1335 
1350 void
1351 UsefulOutBuf_Advance(UsefulOutBuf *pUOutBuf, size_t uAmount);
1352 
1353 
1370 
1371 
1386 
1387 
1400  const size_t uStart,
1401  const size_t uLen);
1402 
1403 
1416 
1417 
1418 
1459 typedef struct useful_input_buf {
1460  /* PRIVATE DATA STRUCTURE */
1461  UsefulBufC UB; /* Data being parsed */
1462  size_t cursor; /* Current offset in data being parse */
1463  uint16_t magic; /* Check for corrupted or uninitialized UsefulInputBuf */
1464  uint8_t err; /* Set request goes off end or magic number is bad */
1466 
1467 #define UIB_MAGIC (0xB00F)
1468 
1469 
1476 static inline void UsefulInputBuf_Init(UsefulInputBuf *pUInBuf, UsefulBufC UB);
1477 
1478 
1488 static size_t UsefulInputBuf_Tell(UsefulInputBuf *pUInBuf);
1489 
1490 
1503 static void UsefulInputBuf_Seek(UsefulInputBuf *pUInBuf, size_t uPos);
1504 
1505 
1517 static size_t UsefulInputBuf_BytesUnconsumed(UsefulInputBuf *pUInBuf);
1518 
1519 
1528 static int UsefulInputBuf_BytesAvailable(UsefulInputBuf *pUInBuf, size_t uLen);
1529 
1530 
1539 static size_t UsefulInputBuf_PointerToOffset(UsefulInputBuf *pUInBuf, const void *p);
1540 
1541 
1550 static const void *UsefulInputBuf_OffsetToPointer(UsefulInputBuf *pUInBuf, size_t uOffset);
1551 
1552 
1569 const void * UsefulInputBuf_GetBytes(UsefulInputBuf *pUInBuf, size_t uNum);
1570 
1571 
1588 static inline UsefulBufC UsefulInputBuf_GetUsefulBuf(UsefulInputBuf *pUInBuf, size_t uNum);
1589 
1590 
1610 static inline uint8_t UsefulInputBuf_GetByte(UsefulInputBuf *pUInBuf);
1611 
1612 
1625 static inline uint16_t UsefulInputBuf_GetUint16(UsefulInputBuf *pUInBuf);
1626 
1627 
1640 static uint32_t UsefulInputBuf_GetUint32(UsefulInputBuf *pUInBuf);
1641 
1642 
1655 static uint64_t UsefulInputBuf_GetUint64(UsefulInputBuf *pUInBuf);
1656 
1657 
1658 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
1671 static float UsefulInputBuf_GetFloat(UsefulInputBuf *pUInBuf);
1672 
1673 
1686 static double UsefulInputBuf_GetDouble(UsefulInputBuf *pUInBuf);
1687 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
1688 
1689 
1719 static int UsefulInputBuf_GetError(UsefulInputBuf *pUInBuf);
1720 
1721 
1732 static inline size_t UsefulInputBuf_GetBufferLength(UsefulInputBuf *pUInBuf);
1733 
1734 
1757 static void UsefulInputBuf_SetBufferLength(UsefulInputBuf *pUInBuf, size_t uNewLen);
1758 
1759 
1770 
1771 
1772 /*----------------------------------------------------------
1773  Inline implementations.
1774  */
1775 static inline int UsefulBuf_IsNULL(UsefulBuf UB)
1776 {
1777  return !UB.ptr;
1778 }
1779 
1780 
1781 static inline int UsefulBuf_IsNULLC(UsefulBufC UB)
1782 {
1783  return !UB.ptr;
1784 }
1785 
1786 
1787 static inline int UsefulBuf_IsEmpty(UsefulBuf UB)
1788 {
1789  return !UB.len;
1790 }
1791 
1792 
1793 static inline int UsefulBuf_IsEmptyC(UsefulBufC UB)
1794 {
1795  return !UB.len;
1796 }
1797 
1798 
1799 static inline int UsefulBuf_IsNULLOrEmpty(UsefulBuf UB)
1800 {
1801  return UsefulBuf_IsEmpty(UB) || UsefulBuf_IsNULL(UB);
1802 }
1803 
1804 
1806 {
1807  return UsefulBuf_IsEmptyC(UB) || UsefulBuf_IsNULLC(UB);
1808 }
1809 
1810 
1811 static inline UsefulBufC UsefulBuf_Const(const UsefulBuf UB)
1812 {
1813  UsefulBufC UBC;
1814  UBC.ptr = UB.ptr;
1815  UBC.len = UB.len;
1816 
1817  return UBC;
1818 }
1819 
1820 static inline UsefulBuf UsefulBuf_Unconst(const UsefulBufC UBC)
1821 {
1822  UsefulBuf UB;
1823 
1824  /* -Wcast-qual is a good warning flag to use in general. This is
1825  * the one place in UsefulBuf where it needs to be quieted.
1826  */
1827  UB.ptr = (void *)(uintptr_t)UBC.ptr;
1828 
1829  UB.len = UBC.len;
1830 
1831  return UB;
1832 }
1833 
1834 
1835 static inline UsefulBufC UsefulBuf_FromSZ(const char *szString)
1836 {
1837  UsefulBufC UBC;
1838  UBC.ptr = szString;
1839  UBC.len = strlen(szString);
1840  return UBC;
1841 }
1842 
1843 
1844 static inline UsefulBufC UsefulBuf_Copy(UsefulBuf Dest, const UsefulBufC Src)
1845 {
1846  return UsefulBuf_CopyOffset(Dest, 0, Src);
1847 }
1848 
1849 
1850 static inline UsefulBufC UsefulBuf_Set(UsefulBuf Dest, uint8_t value)
1851 {
1852  memset(Dest.ptr, value, Dest.len);
1853 
1854  UsefulBufC UBC;
1855  UBC.ptr = Dest.ptr;
1856  UBC.len = Dest.len;
1857 
1858  return UBC;
1859 }
1860 
1861 
1862 static inline UsefulBufC UsefulBuf_CopyPtr(UsefulBuf Dest, const void *ptr, size_t len)
1863 {
1864  UsefulBufC UBC;
1865  UBC.ptr = ptr;
1866  UBC.len = len;
1867  return UsefulBuf_Copy(Dest, UBC);
1868 }
1869 
1870 
1871 static inline UsefulBufC UsefulBuf_Head(UsefulBufC UB, size_t uAmount)
1872 {
1873  if(uAmount > UB.len) {
1874  return NULLUsefulBufC;
1875  }
1876  UsefulBufC UBC;
1877 
1878  UBC.ptr = UB.ptr;
1879  UBC.len = uAmount;
1880 
1881  return UBC;
1882 }
1883 
1884 
1885 static inline UsefulBufC UsefulBuf_Tail(UsefulBufC UB, size_t uAmount)
1886 {
1887  UsefulBufC ReturnValue;
1888 
1889  if(uAmount > UB.len) {
1890  ReturnValue = NULLUsefulBufC;
1891  } else if(UB.ptr == NULL) {
1892  ReturnValue.ptr = NULL;
1893  ReturnValue.len = UB.len - uAmount;
1894  } else {
1895  ReturnValue.ptr = (const uint8_t *)UB.ptr + uAmount;
1896  ReturnValue.len = UB.len - uAmount;
1897  }
1898 
1899  return ReturnValue;
1900 }
1901 
1902 
1903 static inline size_t UsefulBuf_PointerToOffset(UsefulBufC UB, const void *p)
1904 {
1905  if(UB.ptr == NULL) {
1906  return SIZE_MAX;
1907  }
1908 
1909  if(p < UB.ptr) {
1910  /* given pointer is before start of buffer */
1911  return SIZE_MAX;
1912  }
1913 
1914  /* Cast to size_t (from ptrdiff_t) is OK because of check above */
1915  const size_t uOffset = (size_t)((const uint8_t *)p - (const uint8_t *)UB.ptr);
1916 
1917  if(uOffset >= UB.len) {
1918  /* given pointer is off the end of the buffer */
1919  return SIZE_MAX;
1920  }
1921 
1922  return uOffset;
1923 }
1924 
1925 
1926 static inline const void *UsefulBuf_OffsetToPointer(UsefulBufC UB, size_t uOffset)
1927 {
1928  if(UsefulBuf_IsNULLC(UB) || uOffset >= UB.len) {
1929  return NULL;
1930  }
1931 
1932  return (const uint8_t *)UB.ptr + uOffset;
1933 }
1934 
1935 
1936 
1937 
1938 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
1939 static inline uint32_t UsefulBufUtil_CopyFloatToUint32(float f)
1940 {
1941  uint32_t u32;
1942  memcpy(&u32, &f, sizeof(uint32_t));
1943  return u32;
1944 }
1945 
1946 static inline uint64_t UsefulBufUtil_CopyDoubleToUint64(double d)
1947 {
1948  uint64_t u64;
1949  memcpy(&u64, &d, sizeof(uint64_t));
1950  return u64;
1951 }
1952 
1953 static inline double UsefulBufUtil_CopyUint64ToDouble(uint64_t u64)
1954 {
1955  double d;
1956  memcpy(&d, &u64, sizeof(uint64_t));
1957  return d;
1958 }
1959 
1960 static inline float UsefulBufUtil_CopyUint32ToFloat(uint32_t u32)
1961 {
1962  float f;
1963  memcpy(&f, &u32, sizeof(uint32_t));
1964  return f;
1965 }
1966 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
1967 
1968 
1969 
1970 
1971 static inline void UsefulOutBuf_Reset(UsefulOutBuf *pMe)
1972 {
1973  pMe->data_len = 0;
1974  pMe->err = 0;
1975 }
1976 
1977 
1978 static inline size_t UsefulOutBuf_GetEndPosition(UsefulOutBuf *pMe)
1979 {
1980  return pMe->data_len;
1981 }
1982 
1983 
1984 static inline int UsefulOutBuf_AtStart(UsefulOutBuf *pMe)
1985 {
1986  return 0 == pMe->data_len;
1987 }
1988 
1989 
1990 static inline void UsefulOutBuf_InsertData(UsefulOutBuf *pMe,
1991  const void *pBytes,
1992  size_t uLen,
1993  size_t uPos)
1994 {
1995  UsefulBufC Data = {pBytes, uLen};
1996  UsefulOutBuf_InsertUsefulBuf(pMe, Data, uPos);
1997 }
1998 
1999 
2000 static inline void UsefulOutBuf_InsertString(UsefulOutBuf *pMe,
2001  const char *szString,
2002  size_t uPos)
2003 {
2004  UsefulBufC UBC;
2005  UBC.ptr = szString;
2006  UBC.len = strlen(szString);
2007 
2008  UsefulOutBuf_InsertUsefulBuf(pMe, UBC, uPos);
2009 }
2010 
2011 
2012 static inline void UsefulOutBuf_InsertByte(UsefulOutBuf *me,
2013  uint8_t byte,
2014  size_t uPos)
2015 {
2016  UsefulOutBuf_InsertData(me, &byte, 1, uPos);
2017 }
2018 
2019 
2021  uint16_t uInteger16,
2022  size_t uPos)
2023 {
2024  /* See UsefulOutBuf_InsertUint64() for comments on this code */
2025 
2026  const void *pBytes;
2027 
2028 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN)
2029  pBytes = &uInteger16;
2030 
2031 #elif defined(USEFULBUF_CONFIG_HTON)
2032  uint16_t uTmp = htons(uInteger16);
2033  pBytes = &uTmp;
2034 
2035 #elif defined(USEFULBUF_CONFIG_LITTLE_ENDIAN) && defined(USEFULBUF_CONFIG_BSWAP)
2036  uint16_t uTmp = __builtin_bswap16(uInteger16);
2037  pBytes = &uTmp;
2038 
2039 #else
2040  uint8_t aTmp[2];
2041 
2042  aTmp[0] = (uint8_t)((uInteger16 & 0xff00) >> 8);
2043  aTmp[1] = (uint8_t)(uInteger16 & 0xff);
2044 
2045  pBytes = aTmp;
2046 #endif
2047 
2048  UsefulOutBuf_InsertData(me, pBytes, 2, uPos);
2049 }
2050 
2051 
2052 static inline void UsefulOutBuf_InsertUint32(UsefulOutBuf *pMe,
2053  uint32_t uInteger32,
2054  size_t uPos)
2055 {
2056  /* See UsefulOutBuf_InsertUint64() for comments on this code */
2057 
2058  const void *pBytes;
2059 
2060 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN)
2061  pBytes = &uInteger32;
2062 
2063 #elif defined(USEFULBUF_CONFIG_HTON)
2064  uint32_t uTmp = htonl(uInteger32);
2065  pBytes = &uTmp;
2066 
2067 #elif defined(USEFULBUF_CONFIG_LITTLE_ENDIAN) && defined(USEFULBUF_CONFIG_BSWAP)
2068  uint32_t uTmp = __builtin_bswap32(uInteger32);
2069 
2070  pBytes = &uTmp;
2071 
2072 #else
2073  uint8_t aTmp[4];
2074 
2075  aTmp[0] = (uint8_t)((uInteger32 & 0xff000000) >> 24);
2076  aTmp[1] = (uint8_t)((uInteger32 & 0xff0000) >> 16);
2077  aTmp[2] = (uint8_t)((uInteger32 & 0xff00) >> 8);
2078  aTmp[3] = (uint8_t)(uInteger32 & 0xff);
2079 
2080  pBytes = aTmp;
2081 #endif
2082 
2083  UsefulOutBuf_InsertData(pMe, pBytes, 4, uPos);
2084 }
2085 
2086 static inline void UsefulOutBuf_InsertUint64(UsefulOutBuf *pMe,
2087  uint64_t uInteger64,
2088  size_t uPos)
2089 {
2090  const void *pBytes;
2091 
2092 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN)
2093  /* We have been told explicitly we are running on a big-endian
2094  * machine. Network byte order is big endian, so just copy. There
2095  * is no issue with alignment here because uInteger64 is always
2096  * aligned (and it doesn't matter if pBytes is aligned).
2097  */
2098  pBytes = &uInteger64;
2099 
2100 #elif defined(USEFULBUF_CONFIG_HTON)
2101  /* Use system function to handle big- and little-endian. This works
2102  * on both big- and little-endian machines, but hton() is not
2103  * always available or in a standard place so it is not used by
2104  * default. With some compilers and CPUs the code for this is very
2105  * compact through use of a special swap instruction and on
2106  * big-endian machines hton() will reduce to nothing.
2107  */
2108  uint64_t uTmp = htonll(uInteger64);
2109 
2110  pBytes = &uTmp;
2111 
2112 #elif defined(USEFULBUF_CONFIG_LITTLE_ENDIAN) && defined(USEFULBUF_CONFIG_BSWAP)
2113  /* Use built-in function for byte swapping. This usually compiles
2114  * to an efficient special byte swap instruction. Unlike hton() it
2115  * does not do this conditionally on the CPU endianness, so this
2116  * code is also conditional on USEFULBUF_CONFIG_LITTLE_ENDIAN
2117  */
2118  uint64_t uTmp = __builtin_bswap64(uInteger64);
2119 
2120  pBytes = &uTmp;
2121 
2122 #else
2123  /* Default which works on every CPU with no dependency on anything
2124  * from the CPU, compiler, libraries or OS. This always works, but
2125  * it is usually a little larger and slower than hton().
2126  */
2127  uint8_t aTmp[8];
2128 
2129  aTmp[0] = (uint8_t)((uInteger64 & 0xff00000000000000ULL) >> 56);
2130  aTmp[1] = (uint8_t)((uInteger64 & 0xff000000000000ULL) >> 48);
2131  aTmp[2] = (uint8_t)((uInteger64 & 0xff0000000000ULL) >> 40);
2132  aTmp[3] = (uint8_t)((uInteger64 & 0xff00000000ULL) >> 32);
2133  aTmp[4] = (uint8_t)((uInteger64 & 0xff000000ULL) >> 24);
2134  aTmp[5] = (uint8_t)((uInteger64 & 0xff0000ULL) >> 16);
2135  aTmp[6] = (uint8_t)((uInteger64 & 0xff00ULL) >> 8);
2136  aTmp[7] = (uint8_t)(uInteger64 & 0xffULL);
2137 
2138  pBytes = aTmp;
2139 #endif
2140 
2141  /* Do the insert */
2142  UsefulOutBuf_InsertData(pMe, pBytes, sizeof(uint64_t), uPos);
2143 }
2144 
2145 
2146 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
2147 static inline void UsefulOutBuf_InsertFloat(UsefulOutBuf *pMe,
2148  float f,
2149  size_t uPos)
2150 {
2152 }
2153 
2154 
2155 static inline void UsefulOutBuf_InsertDouble(UsefulOutBuf *pMe,
2156  double d,
2157  size_t uPos)
2158 {
2160 }
2161 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
2162 
2163 
2165  UsefulBufC NewData)
2166 {
2167  /* An append is just a insert at the end */
2169 }
2170 
2171 
2172 static inline void UsefulOutBuf_AppendData(UsefulOutBuf *pMe,
2173  const void *pBytes,
2174  size_t uLen)
2175 {
2176  UsefulBufC Data = {pBytes, uLen};
2177  UsefulOutBuf_AppendUsefulBuf(pMe, Data);
2178 }
2179 
2180 
2181 static inline void UsefulOutBuf_AppendString(UsefulOutBuf *pMe,
2182  const char *szString)
2183 {
2184  UsefulBufC UBC;
2185  UBC.ptr = szString;
2186  UBC.len = strlen(szString);
2187 
2188  UsefulOutBuf_AppendUsefulBuf(pMe, UBC);
2189 }
2190 
2191 
2192 static inline void UsefulOutBuf_AppendByte(UsefulOutBuf *pMe,
2193  uint8_t byte)
2194 {
2195  UsefulOutBuf_AppendData(pMe, &byte, 1);
2196 }
2197 
2198 
2199 static inline void UsefulOutBuf_AppendUint16(UsefulOutBuf *pMe,
2200  uint16_t uInteger16)
2201 {
2203 }
2204 
2205 static inline void UsefulOutBuf_AppendUint32(UsefulOutBuf *pMe,
2206  uint32_t uInteger32)
2207 {
2209 }
2210 
2211 
2212 static inline void UsefulOutBuf_AppendUint64(UsefulOutBuf *pMe,
2213  uint64_t uInteger64)
2214 {
2216 }
2217 
2218 
2219 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
2220 static inline void UsefulOutBuf_AppendFloat(UsefulOutBuf *pMe,
2221  float f)
2222 {
2224 }
2225 
2226 
2227 static inline void UsefulOutBuf_AppendDouble(UsefulOutBuf *pMe,
2228  double d)
2229 {
2231 }
2232 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
2233 
2234 
2235 static inline int UsefulOutBuf_GetError(UsefulOutBuf *pMe)
2236 {
2237  return pMe->err;
2238 }
2239 
2240 
2241 static inline size_t UsefulOutBuf_RoomLeft(UsefulOutBuf *pMe)
2242 {
2243  return pMe->UB.len - pMe->data_len;
2244 }
2245 
2246 
2247 static inline int UsefulOutBuf_WillItFit(UsefulOutBuf *pMe, size_t uLen)
2248 {
2249  return uLen <= UsefulOutBuf_RoomLeft(pMe);
2250 }
2251 
2252 
2254 {
2255  return pMe->UB.ptr == NULL;
2256 }
2257 
2258 
2260 {
2261  UsefulBuf R;
2262 
2263  R.len = UsefulOutBuf_RoomLeft(pUOutBuf);
2264  if(R.len > 0 && pUOutBuf->UB.ptr != NULL) {
2265  R.ptr = (uint8_t *)pUOutBuf->UB.ptr + pUOutBuf->data_len;
2266  } else {
2267  R.ptr = NULL;
2268  }
2269 
2270  return R;
2271 }
2272 
2273 
2275 {
2276  return pMe->UB;
2277 }
2278 
2279 
2280 
2281 
2282 static inline void UsefulInputBuf_Init(UsefulInputBuf *pMe, UsefulBufC UB)
2283 {
2284  pMe->cursor = 0;
2285  pMe->err = 0;
2286  pMe->magic = UIB_MAGIC;
2287  pMe->UB = UB;
2288 }
2289 
2290 static inline size_t UsefulInputBuf_Tell(UsefulInputBuf *pMe)
2291 {
2292  return pMe->cursor;
2293 }
2294 
2295 
2297 {
2298  return pMe->UB.len;
2299 }
2300 
2301 
2302 static inline void UsefulInputBuf_Seek(UsefulInputBuf *pMe, size_t uPos)
2303 {
2304  if(uPos > pMe->UB.len) {
2305  pMe->err = 1;
2306  } else {
2307  pMe->cursor = uPos;
2308  }
2309 }
2310 
2311 
2313 {
2314  /* Code Reviewers: THIS FUNCTION DOES POINTER MATH */
2315 
2316  /* Magic number is messed up. Either the structure got overwritten
2317  * or was never initialized.
2318  */
2319  if(pMe->magic != UIB_MAGIC) {
2320  return 0;
2321  }
2322 
2323  /* The cursor is off the end of the input buffer given.
2324  * Presuming there are no bugs in this code, this should never happen.
2325  * If it is so, the struct was corrupted. The check is retained as
2326  * as a defense in case there is a bug in this code or the struct is
2327  * corrupted by an attacker or accidentally.
2328  */
2329  if(pMe->cursor > pMe->UB.len) {
2330  return 0;
2331  }
2332 
2333  /* subtraction can't go negative because of check above */
2334  return pMe->UB.len - pMe->cursor;
2335 }
2336 
2337 
2338 static inline int UsefulInputBuf_BytesAvailable(UsefulInputBuf *pMe, size_t uLen)
2339 {
2340  return UsefulInputBuf_BytesUnconsumed(pMe) >= uLen ? 1 : 0;
2341 }
2342 
2343 
2344 static inline size_t UsefulInputBuf_PointerToOffset(UsefulInputBuf *pUInBuf, const void *p)
2345 {
2346  return UsefulBuf_PointerToOffset(pUInBuf->UB, p);
2347 }
2348 
2349 
2350 static inline const void *UsefulInputBuf_OffsetToPointer(UsefulInputBuf *pUInBuf, size_t uOffset)
2351  {
2352  return UsefulBuf_OffsetToPointer(pUInBuf->UB, uOffset);
2353  }
2354 
2355 
2357 {
2358  const void *pResult = UsefulInputBuf_GetBytes(pMe, uNum);
2359  if(!pResult) {
2360  return NULLUsefulBufC;
2361  } else {
2362  UsefulBufC UBC;
2363  UBC.ptr = pResult;
2364  UBC.len = uNum;
2365  return UBC;
2366  }
2367 }
2368 
2369 
2370 static inline uint8_t UsefulInputBuf_GetByte(UsefulInputBuf *pMe)
2371 {
2372  const void *pResult = UsefulInputBuf_GetBytes(pMe, sizeof(uint8_t));
2373 
2374  /* The ternary operator is subject to integer promotion, because
2375  * the operands are smaller than int, so cast back to uint8_t is
2376  * needed to be completely explicit about types (for static
2377  * analyzers).
2378  */
2379  return (uint8_t)(pResult ? *(const uint8_t *)pResult : 0);
2380 }
2381 
2382 static inline uint16_t UsefulInputBuf_GetUint16(UsefulInputBuf *pMe)
2383 {
2384  const uint8_t *pResult = (const uint8_t *)UsefulInputBuf_GetBytes(pMe, sizeof(uint16_t));
2385 
2386  if(!pResult) {
2387  return 0;
2388  }
2389 
2390  /* See UsefulInputBuf_GetUint64() for comments on this code */
2391 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN) || defined(USEFULBUF_CONFIG_HTON) || defined(USEFULBUF_CONFIG_BSWAP)
2392  uint16_t uTmp;
2393  memcpy(&uTmp, pResult, sizeof(uint16_t));
2394 
2395 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN)
2396  return uTmp;
2397 
2398 #elif defined(USEFULBUF_CONFIG_HTON)
2399  return ntohs(uTmp);
2400 
2401 #else
2402  return __builtin_bswap16(uTmp);
2403 
2404 #endif
2405 
2406 #else
2407 
2408  /* The operations here are subject to integer promotion because the
2409  * operands are smaller than int. They will be promoted to unsigned
2410  * int for the shift and addition. The cast back to uint16_t is is
2411  * needed to be completely explicit about types (for static
2412  * analyzers).
2413  */
2414  return (uint16_t)((pResult[0] << 8) + pResult[1]);
2415 
2416 #endif
2417 }
2418 
2419 
2420 static inline uint32_t UsefulInputBuf_GetUint32(UsefulInputBuf *pMe)
2421 {
2422  const uint8_t *pResult = (const uint8_t *)UsefulInputBuf_GetBytes(pMe, sizeof(uint32_t));
2423 
2424  if(!pResult) {
2425  return 0;
2426  }
2427 
2428  /* See UsefulInputBuf_GetUint64() for comments on this code */
2429 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN) || defined(USEFULBUF_CONFIG_HTON) || defined(USEFULBUF_CONFIG_BSWAP)
2430  uint32_t uTmp;
2431  memcpy(&uTmp, pResult, sizeof(uint32_t));
2432 
2433 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN)
2434  return uTmp;
2435 
2436 #elif defined(USEFULBUF_CONFIG_HTON)
2437  return ntohl(uTmp);
2438 
2439 #else
2440  return __builtin_bswap32(uTmp);
2441 
2442 #endif
2443 
2444 #else
2445  return ((uint32_t)pResult[0]<<24) +
2446  ((uint32_t)pResult[1]<<16) +
2447  ((uint32_t)pResult[2]<<8) +
2448  (uint32_t)pResult[3];
2449 #endif
2450 }
2451 
2452 
2453 static inline uint64_t UsefulInputBuf_GetUint64(UsefulInputBuf *pMe)
2454 {
2455  const uint8_t *pResult = (const uint8_t *)UsefulInputBuf_GetBytes(pMe, sizeof(uint64_t));
2456 
2457  if(!pResult) {
2458  return 0;
2459  }
2460 
2461 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN) || defined(USEFULBUF_CONFIG_HTON) || defined(USEFULBUF_CONFIG_BSWAP)
2462  /* pResult will probably not be aligned. This memcpy() moves the
2463  * bytes into a temp variable safely for CPUs that can or can't do
2464  * unaligned memory access. Many compilers will optimize the
2465  * memcpy() into a simple move instruction.
2466  */
2467  uint64_t uTmp;
2468  memcpy(&uTmp, pResult, sizeof(uint64_t));
2469 
2470 #if defined(USEFULBUF_CONFIG_BIG_ENDIAN)
2471  /* We have been told expliclity this is a big-endian CPU. Since
2472  * network byte order is big-endian, there is nothing to do.
2473  */
2474 
2475  return uTmp;
2476 
2477 #elif defined(USEFULBUF_CONFIG_HTON)
2478  /* We have been told to use ntoh(), the system function to handle
2479  * big- and little-endian. This works on both big- and
2480  * little-endian machines, but ntoh() is not always available or in
2481  * a standard place so it is not used by default. On some CPUs the
2482  * code for this is very compact through use of a special swap
2483  * instruction.
2484  */
2485 
2486  return ntohll(uTmp);
2487 
2488 #else
2489  /* Little-endian (since it is not USEFULBUF_CONFIG_BIG_ENDIAN) and
2490  * USEFULBUF_CONFIG_BSWAP (since it is not USEFULBUF_CONFIG_HTON).
2491  * __builtin_bswap64() and friends are not conditional on CPU
2492  * endianness so this must only be used on little-endian machines.
2493  */
2494 
2495  return __builtin_bswap64(uTmp);
2496 
2497 
2498 #endif
2499 
2500 #else
2501  /* This is the default code that works on every CPU and every
2502  * endianness with no dependency on ntoh(). This works on CPUs
2503  * that either allow or do not allow unaligned access. It will
2504  * always work, but usually is a little less efficient than ntoh().
2505  */
2506 
2507  return ((uint64_t)pResult[0]<<56) +
2508  ((uint64_t)pResult[1]<<48) +
2509  ((uint64_t)pResult[2]<<40) +
2510  ((uint64_t)pResult[3]<<32) +
2511  ((uint64_t)pResult[4]<<24) +
2512  ((uint64_t)pResult[5]<<16) +
2513  ((uint64_t)pResult[6]<<8) +
2514  (uint64_t)pResult[7];
2515 #endif
2516 }
2517 
2518 
2519 #ifndef USEFULBUF_DISABLE_ALL_FLOAT
2520 static inline float UsefulInputBuf_GetFloat(UsefulInputBuf *pMe)
2521 {
2522  uint32_t uResult = UsefulInputBuf_GetUint32(pMe);
2523 
2524  return uResult ? UsefulBufUtil_CopyUint32ToFloat(uResult) : 0;
2525 }
2526 
2527 
2528 static inline double UsefulInputBuf_GetDouble(UsefulInputBuf *pMe)
2529 {
2530  uint64_t uResult = UsefulInputBuf_GetUint64(pMe);
2531 
2532  return uResult ? UsefulBufUtil_CopyUint64ToDouble(uResult) : 0;
2533 }
2534 #endif /* USEFULBUF_DISABLE_ALL_FLOAT */
2535 
2536 
2538 {
2539  return pMe->err;
2540 }
2541 
2542 
2543 static inline void UsefulInputBuf_SetBufferLength(UsefulInputBuf *pMe, size_t uNewLen)
2544 {
2545  pMe->UB.len = uNewLen;
2546 }
2547 
2549 {
2550  return pMe->UB;
2551 }
2552 
2553 
2554 #ifdef __cplusplus
2555 }
2556 #endif
2557 
2558 #endif /* _UsefulBuf_h */
2559 
2560 
static UsefulBufC UsefulInputBuf_GetUsefulBuf(UsefulInputBuf *pUInBuf, size_t uNum)
Get UsefulBuf out of the input buffer.
Definition: UsefulBuf.h:2356
static void UsefulOutBuf_InsertByte(UsefulOutBuf *pUOutBuf, uint8_t byte, size_t uPos)
Insert a byte into the UsefulOutBuf.
Definition: UsefulBuf.h:2012
size_t UsefulBuf_FindBytes(UsefulBufC BytesToSearch, UsefulBufC BytesToFind)
Find one UsefulBufC in another.
UsefulBufC UsefulOutBuf_OutUBuf(UsefulOutBuf *pUOutBuf)
Returns the resulting valid data in a UsefulOutBuf.
static int UsefulOutBuf_WillItFit(UsefulOutBuf *pUOutBuf, size_t uLen)
Returns 1 if some number of bytes will fit in the UsefulOutBuf.
Definition: UsefulBuf.h:2247
void UsefulOutBuf_InsertUsefulBuf(UsefulOutBuf *pUOutBuf, UsefulBufC NewData, size_t uPos)
Inserts bytes into the UsefulOutBuf.
static uint8_t UsefulInputBuf_GetByte(UsefulInputBuf *pUInBuf)
Get a byte out of the input buffer.
Definition: UsefulBuf.h:2370
static UsefulBuf UsefulBuf_Unconst(const UsefulBufC UBC)
Convert a const UsefulBufC to a non-const UsefulBuf.
Definition: UsefulBuf.h:1820
static int UsefulInputBuf_BytesAvailable(UsefulInputBuf *pUInBuf, size_t uLen)
Check if there are unconsumed bytes.
Definition: UsefulBuf.h:2338
static void UsefulOutBuf_InsertString(UsefulOutBuf *pUOutBuf, const char *szString, size_t uPos)
Insert a NULL-terminated string into the UsefulOutBuf.
Definition: UsefulBuf.h:2000
static void UsefulOutBuf_InsertFloat(UsefulOutBuf *pUOutBuf, float f, size_t uPos)
Insert a float into the UsefulOutBuf.
Definition: UsefulBuf.h:2147
static size_t UsefulOutBuf_GetEndPosition(UsefulOutBuf *pUOutBuf)
Returns position of end of data in the UsefulOutBuf.
Definition: UsefulBuf.h:1978
static void UsefulOutBuf_AppendUsefulBuf(UsefulOutBuf *pUOutBuf, UsefulBufC NewData)
Append a UsefulBuf into the UsefulOutBuf.
Definition: UsefulBuf.h:2164
static void UsefulOutBuf_InsertData(UsefulOutBuf *pUOutBuf, const void *pBytes, size_t uLen, size_t uPos)
Insert a data buffer into the UsefulOutBuf.
Definition: UsefulBuf.h:1990
const void * UsefulInputBuf_GetBytes(UsefulInputBuf *pUInBuf, size_t uNum)
Get pointer to bytes out of the input buffer.
UsefulBufC UsefulOutBuf_CopyOut(UsefulOutBuf *pUOutBuf, UsefulBuf Dest)
Copies the valid data into a supplied buffer.
struct q_useful_buf UsefulBuf
static UsefulBufC UsefulBuf_FromSZ(const char *szString)
Convert a NULL-terminated string to a UsefulBufC.
Definition: UsefulBuf.h:1835
static void UsefulInputBuf_SetBufferLength(UsefulInputBuf *pUInBuf, size_t uNewLen)
Alters the input buffer length (use with caution).
Definition: UsefulBuf.h:2543
static uint32_t UsefulInputBuf_GetUint32(UsefulInputBuf *pUInBuf)
Get a uint32_t out of the input buffer.
Definition: UsefulBuf.h:2420
static size_t UsefulInputBuf_BytesUnconsumed(UsefulInputBuf *pUInBuf)
Returns the number of bytes from the cursor to the end of the buffer, the unconsumed bytes.
Definition: UsefulBuf.h:2312
static void UsefulInputBuf_Seek(UsefulInputBuf *pUInBuf, size_t uPos)
Sets the current position in input buffer.
Definition: UsefulBuf.h:2302
static uint32_t UsefulBufUtil_CopyFloatToUint32(float f)
Copy a float to a uint32_t.
Definition: UsefulBuf.h:1939
struct useful_input_buf UsefulInputBuf
static size_t UsefulBuf_PointerToOffset(UsefulBufC UB, const void *p)
Convert a pointer to an offset with bounds checking.
Definition: UsefulBuf.h:1903
static void UsefulOutBuf_InsertUint32(UsefulOutBuf *pUOutBuf, uint32_t uInteger32, size_t uPos)
Insert a 32-bit integer into the UsefulOutBuf.
Definition: UsefulBuf.h:2052
static UsefulBuf UsefulOutBuf_RetrieveOutputStorage(UsefulOutBuf *pUOutBuf)
Retrieve the storage buffer passed in to UsefulOutBuf_Init().
Definition: UsefulBuf.h:2274
static void UsefulInputBuf_Init(UsefulInputBuf *pUInBuf, UsefulBufC UB)
Initialize the UsefulInputBuf structure before use.
Definition: UsefulBuf.h:2282
static UsefulBufC UsefulBuf_CopyPtr(UsefulBuf Dest, const void *ptr, size_t uLen)
Copy a pointer into a UsefulBuf.
Definition: UsefulBuf.h:1862
static void UsefulOutBuf_AppendDouble(UsefulOutBuf *pUOutBuf, double d)
Append a double to the UsefulOutBuf.
Definition: UsefulBuf.h:2227
static int UsefulBuf_IsNULLC(UsefulBufC UB)
Check if a UsefulBufC is NULLUsefulBufC or not.
Definition: UsefulBuf.h:1781
static uint64_t UsefulInputBuf_GetUint64(UsefulInputBuf *pUInBuf)
Get a uint64_t out of the input buffer.
Definition: UsefulBuf.h:2453
static uint16_t UsefulInputBuf_GetUint16(UsefulInputBuf *pUInBuf)
Get a uint16_t out of the input buffer.
Definition: UsefulBuf.h:2382
void UsefulOutBuf_Advance(UsefulOutBuf *pUOutBuf, size_t uAmount)
Advance the amount output assuming it was written by the caller.
static float UsefulBufUtil_CopyUint32ToFloat(uint32_t u32)
Copy a uint32_t to a float.
Definition: UsefulBuf.h:1960
static int UsefulBuf_IsEmptyC(UsefulBufC UB)
Check if a UsefulBufC is empty or not.
Definition: UsefulBuf.h:1793
static int UsefulBuf_IsNULL(UsefulBuf UB)
Check if a UsefulBuf is NULLUsefulBuf or not.
Definition: UsefulBuf.h:1775
static float UsefulInputBuf_GetFloat(UsefulInputBuf *pUInBuf)
Get a float out of the input buffer.
Definition: UsefulBuf.h:2520
static void UsefulOutBuf_AppendUint32(UsefulOutBuf *pUOutBuf, uint32_t uInteger32)
Append an integer to the UsefulOutBuf.
Definition: UsefulBuf.h:2205
static void UsefulOutBuf_AppendData(UsefulOutBuf *pUOutBuf, const void *pBytes, size_t uLen)
Append bytes to the UsefulOutBuf.
Definition: UsefulBuf.h:2172
static UsefulBufC UsefulBuf_Set(UsefulBuf pDest, uint8_t value)
Set all bytes in a UsefulBuf to a value, for example to 0.
Definition: UsefulBuf.h:1850
static UsefulBufC UsefulInputBuf_RetrieveUndecodedInput(UsefulInputBuf *pUInBuf)
Retrieve the undecoded input buffer.
Definition: UsefulBuf.h:2548
static uint64_t UsefulBufUtil_CopyDoubleToUint64(double d)
Copy a double to a uint64_t.
Definition: UsefulBuf.h:1946
UsefulBufC UsefulOutBuf_SubString(UsefulOutBuf *pUOutBuf, const size_t uStart, const size_t uLen)
Return a substring of the output data.
static size_t UsefulInputBuf_Tell(UsefulInputBuf *pUInBuf)
Returns current position in input buffer.
Definition: UsefulBuf.h:2290
static void UsefulOutBuf_AppendString(UsefulOutBuf *pUOutBuf, const char *szString)
Append a NULL-terminated string to the UsefulOutBuf.
Definition: UsefulBuf.h:2181
static int UsefulInputBuf_GetError(UsefulInputBuf *pUInBuf)
Get the error status.
Definition: UsefulBuf.h:2537
static UsefulBuf UsefulBufC_Unconst(const UsefulBufC UBC)
Definition: UsefulBuf.h:690
static void UsefulOutBuf_InsertUint16(UsefulOutBuf *pUOutBuf, uint16_t uInteger16, size_t uPos)
Insert a 16-bit integer into the UsefulOutBuf.
Definition: UsefulBuf.h:2020
UsefulBufC UsefulBuf_CopyOffset(UsefulBuf Dest, size_t uOffset, const UsefulBufC Src)
Copy one UsefulBuf into another at an offset.
struct useful_out_buf UsefulOutBuf
static void UsefulOutBuf_AppendUint16(UsefulOutBuf *pUOutBuf, uint16_t uInteger16)
Append an integer to the UsefulOutBuf.
Definition: UsefulBuf.h:2199
static void UsefulOutBuf_AppendFloat(UsefulOutBuf *pUOutBuf, float f)
Append a float to the UsefulOutBuf.
Definition: UsefulBuf.h:2220
static size_t UsefulInputBuf_PointerToOffset(UsefulInputBuf *pUInBuf, const void *p)
Convert a pointer to an offset with bounds checking.
Definition: UsefulBuf.h:2344
static const void * UsefulInputBuf_OffsetToPointer(UsefulInputBuf *pUInBuf, size_t uOffset)
Convert an offset to a pointer with bounds checking.
Definition: UsefulBuf.h:2350
static void UsefulOutBuf_InsertDouble(UsefulOutBuf *pUOutBuf, double d, size_t uPos)
Insert a double into the UsefulOutBuf.
Definition: UsefulBuf.h:2155
void UsefulOutBuf_Init(UsefulOutBuf *pUOutBuf, UsefulBuf Storage)
Initialize and supply the actual output buffer.
static UsefulBuf UsefulOutBuf_GetOutPlace(UsefulOutBuf *pUOutBuf)
Returns pointer and length of the output buffer not yet used.
Definition: UsefulBuf.h:2259
static const void * UsefulBuf_OffsetToPointer(UsefulBufC UB, size_t uOffset)
Convert an offset to a pointer with bounds checking.
Definition: UsefulBuf.h:1926
static void UsefulOutBuf_AppendUint64(UsefulOutBuf *pUOutBuf, uint64_t uInteger64)
Append an integer to the UsefulOutBuf.
Definition: UsefulBuf.h:2212
static double UsefulBufUtil_CopyUint64ToDouble(uint64_t u64)
Copy a uint64_t to a double.
Definition: UsefulBuf.h:1953
size_t UsefulBuf_IsValue(const UsefulBufC UB, uint8_t uValue)
Find first byte that is not a particular byte value.
static size_t UsefulOutBuf_RoomLeft(UsefulOutBuf *pUOutBuf)
Returns number of bytes unused used in the output buffer.
Definition: UsefulBuf.h:2241
static void UsefulOutBuf_Reset(UsefulOutBuf *pUOutBuf)
Reset a UsefulOutBuf for re use.
Definition: UsefulBuf.h:1971
static int UsefulOutBuf_IsBufferNULL(UsefulOutBuf *pUOutBuf)
Returns 1 if buffer given to UsefulOutBuf_Init() was NULL.
Definition: UsefulBuf.h:2253
int UsefulBuf_Compare(const UsefulBufC UB1, const UsefulBufC UB2)
Compare one UsefulBufC to another.
static void UsefulOutBuf_AppendByte(UsefulOutBuf *pUOutBuf, uint8_t byte)
Append a byte to the UsefulOutBuf.
Definition: UsefulBuf.h:2192
static int UsefulBuf_IsNULLOrEmptyC(UsefulBufC UB)
Check if a UsefulBufC is NULLUsefulBufC or empty.
Definition: UsefulBuf.h:1805
static UsefulBufC UsefulBuf_Copy(UsefulBuf Dest, const UsefulBufC Src)
Copy one UsefulBuf into another.
Definition: UsefulBuf.h:1844
static double UsefulInputBuf_GetDouble(UsefulInputBuf *pUInBuf)
Get a double out of the input buffer.
Definition: UsefulBuf.h:2528
static UsefulBufC UsefulBuf_Const(const UsefulBuf UB)
Convert a non-const UsefulBuf to a const UsefulBufC.
Definition: UsefulBuf.h:1811
struct q_useful_buf_c UsefulBufC
static UsefulBufC UsefulBuf_Head(UsefulBufC UB, size_t uAmount)
Returns a truncation of a UsefulBufC.
Definition: UsefulBuf.h:1871
static UsefulBufC UsefulBuf_Tail(UsefulBufC UB, size_t uAmount)
Returns bytes from the end of a UsefulBufC.
Definition: UsefulBuf.h:1885
static void UsefulOutBuf_InsertUint64(UsefulOutBuf *pUOutBuf, uint64_t uInteger64, size_t uPos)
Insert a 64-bit integer into the UsefulOutBuf.
Definition: UsefulBuf.h:2086
static int UsefulBuf_IsNULLOrEmpty(UsefulBuf UB)
Check if a UsefulBuf is NULLUsefulBuf or empty.
Definition: UsefulBuf.h:1799
static int UsefulOutBuf_GetError(UsefulOutBuf *pUOutBuf)
Returns the current error status.
Definition: UsefulBuf.h:2235
static int UsefulOutBuf_AtStart(UsefulOutBuf *pUOutBuf)
Returns whether any data has been added to the UsefulOutBuf.
Definition: UsefulBuf.h:1984
#define NULLUsefulBufC
Definition: UsefulBuf.h:314
static size_t UsefulInputBuf_GetBufferLength(UsefulInputBuf *pUInBuf)
Gets the input buffer length.
Definition: UsefulBuf.h:2296
static int UsefulBuf_IsEmpty(UsefulBuf UB)
Check if a UsefulBuf is empty or not.
Definition: UsefulBuf.h:1787
Definition: UsefulBuf.h:273
Definition: UsefulBuf.h:284
Definition: UsefulBuf.h:1459
Definition: UsefulBuf.h:845