QCBOR
Loading...
Searching...
No Matches
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
174extern "C" {
175#if 0
176} /* Keep editor indention formatting happy */
177#endif
178#endif
179
211
212
273typedef struct q_useful_buf_c {
274 const void *ptr;
275 size_t len;
277
278
284typedef 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
335static inline int UsefulBuf_IsNULL(UsefulBuf UB);
336
337
345static inline int UsefulBuf_IsNULLC(UsefulBufC UB);
346
347
365static inline int UsefulBuf_IsEmpty(UsefulBuf UB);
366
367
375static inline int UsefulBuf_IsEmptyC(UsefulBufC UB);
376
377
385static inline int UsefulBuf_IsNULLOrEmpty(UsefulBuf UB);
386
387
395static inline int UsefulBuf_IsNULLOrEmptyC(UsefulBufC UB);
396
397
405static inline UsefulBufC UsefulBuf_Const(const UsefulBuf UB);
406
407
425static 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
492static inline UsefulBufC UsefulBuf_FromSZ(const char *szString);
493
494
516UsefulBufC UsefulBuf_CopyOffset(UsefulBuf Dest, size_t uOffset, const UsefulBufC Src);
517
518
536static inline UsefulBufC UsefulBuf_Copy(UsefulBuf Dest, const UsefulBufC Src);
537
538
548static inline UsefulBufC UsefulBuf_Set(UsefulBuf pDest, uint8_t value);
549
550
567static inline UsefulBufC UsefulBuf_CopyPtr(UsefulBuf Dest,
568 const void *ptr,
569 size_t uLen);
570
571
580static inline UsefulBufC UsefulBuf_Head(UsefulBufC UB, size_t uAmount);
581
582
596static inline UsefulBufC UsefulBuf_Tail(UsefulBufC UB, size_t uAmount);
597
598
619int UsefulBuf_Compare(const UsefulBufC UB1, const UsefulBufC UB2);
620
621
640size_t UsefulBuf_IsValue(const UsefulBufC UB, uint8_t uValue);
641
642
651size_t UsefulBuf_FindBytes(UsefulBufC BytesToSearch, UsefulBufC BytesToFind);
652
653
662static inline size_t UsefulBuf_PointerToOffset(UsefulBufC UB, const void *p);
663
664
673static 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
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
718static inline uint32_t UsefulBufUtil_CopyFloatToUint32(float f);
719
720
732static inline uint64_t UsefulBufUtil_CopyDoubleToUint64(double d);
733
734
746static inline float UsefulBufUtil_CopyUint32ToFloat(uint32_t u32);
747
748
760static inline double UsefulBufUtil_CopyUint64ToDouble(uint64_t u64);
761#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
762
763
764
765
845typedef 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
888void 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
915static inline void UsefulOutBuf_Reset(UsefulOutBuf *pUOutBuf);
916
917
932static inline size_t UsefulOutBuf_GetEndPosition(UsefulOutBuf *pUOutBuf);
933
934
942static inline int UsefulOutBuf_AtStart(UsefulOutBuf *pUOutBuf);
943
944
980 UsefulBufC NewData,
981 size_t uPos);
982
983
996static inline void UsefulOutBuf_InsertData(UsefulOutBuf *pUOutBuf,
997 const void *pBytes,
998 size_t uLen,
999 size_t uPos);
1000
1001
1009static inline void UsefulOutBuf_InsertString(UsefulOutBuf *pUOutBuf,
1010 const char *szString,
1011 size_t uPos);
1012
1013
1024static inline void UsefulOutBuf_InsertByte(UsefulOutBuf *pUOutBuf,
1025 uint8_t byte,
1026 size_t uPos);
1027
1028
1041static inline void UsefulOutBuf_InsertUint16(UsefulOutBuf *pUOutBuf,
1042 uint16_t uInteger16,
1043 size_t uPos);
1044
1045
1058static inline void UsefulOutBuf_InsertUint32(UsefulOutBuf *pUOutBuf,
1059 uint32_t uInteger32,
1060 size_t uPos);
1061
1062
1075static inline void UsefulOutBuf_InsertUint64(UsefulOutBuf *pUOutBuf,
1076 uint64_t uInteger64,
1077 size_t uPos);
1078
1079
1080#ifndef USEFULBUF_DISABLE_ALL_FLOAT
1093static inline void UsefulOutBuf_InsertFloat(UsefulOutBuf *pUOutBuf,
1094 float f,
1095 size_t uPos);
1096
1097
1110static inline void UsefulOutBuf_InsertDouble(UsefulOutBuf *pUOutBuf,
1111 double d,
1112 size_t uPos);
1113#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
1114
1115
1125static inline void UsefulOutBuf_AppendUsefulBuf(UsefulOutBuf *pUOutBuf,
1126 UsefulBufC NewData);
1127
1128
1139static inline void UsefulOutBuf_AppendData(UsefulOutBuf *pUOutBuf,
1140 const void *pBytes,
1141 size_t uLen);
1142
1143
1150static inline void UsefulOutBuf_AppendString(UsefulOutBuf *pUOutBuf,
1151 const char *szString);
1152
1153
1163static inline void UsefulOutBuf_AppendByte(UsefulOutBuf *pUOutBuf,
1164 uint8_t byte);
1165
1166
1178static inline void UsefulOutBuf_AppendUint16(UsefulOutBuf *pUOutBuf,
1179 uint16_t uInteger16);
1180
1181
1193static inline void UsefulOutBuf_AppendUint32(UsefulOutBuf *pUOutBuf,
1194 uint32_t uInteger32);
1195
1196
1208static inline void UsefulOutBuf_AppendUint64(UsefulOutBuf *pUOutBuf,
1209 uint64_t uInteger64);
1210
1211
1212#ifndef USEFULBUF_DISABLE_ALL_FLOAT
1224static inline void UsefulOutBuf_AppendFloat(UsefulOutBuf *pUOutBuf,
1225 float f);
1226
1227
1239static inline void UsefulOutBuf_AppendDouble(UsefulOutBuf *pUOutBuf,
1240 double d);
1241#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
1242
1243
1262static inline int UsefulOutBuf_GetError(UsefulOutBuf *pUOutBuf);
1263
1264
1276static inline size_t UsefulOutBuf_RoomLeft(UsefulOutBuf *pUOutBuf);
1277
1278
1291static inline int UsefulOutBuf_WillItFit(UsefulOutBuf *pUOutBuf, size_t uLen);
1292
1293
1304static inline int UsefulOutBuf_IsBufferNULL(UsefulOutBuf *pUOutBuf);
1305
1306
1332static inline UsefulBuf
1334
1335
1350void
1351UsefulOutBuf_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
1459typedef 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
1476static inline void UsefulInputBuf_Init(UsefulInputBuf *pUInBuf, UsefulBufC UB);
1477
1478
1488static size_t UsefulInputBuf_Tell(UsefulInputBuf *pUInBuf);
1489
1490
1503static void UsefulInputBuf_Seek(UsefulInputBuf *pUInBuf, size_t uPos);
1504
1505
1517static size_t UsefulInputBuf_BytesUnconsumed(UsefulInputBuf *pUInBuf);
1518
1519
1528static int UsefulInputBuf_BytesAvailable(UsefulInputBuf *pUInBuf, size_t uLen);
1529
1530
1539static size_t UsefulInputBuf_PointerToOffset(UsefulInputBuf *pUInBuf, const void *p);
1540
1541
1550static const void *UsefulInputBuf_OffsetToPointer(UsefulInputBuf *pUInBuf, size_t uOffset);
1551
1552
1569const void * UsefulInputBuf_GetBytes(UsefulInputBuf *pUInBuf, size_t uNum);
1570
1571
1588static inline UsefulBufC UsefulInputBuf_GetUsefulBuf(UsefulInputBuf *pUInBuf, size_t uNum);
1589
1590
1610static inline uint8_t UsefulInputBuf_GetByte(UsefulInputBuf *pUInBuf);
1611
1612
1625static inline uint16_t UsefulInputBuf_GetUint16(UsefulInputBuf *pUInBuf);
1626
1627
1640static uint32_t UsefulInputBuf_GetUint32(UsefulInputBuf *pUInBuf);
1641
1642
1655static uint64_t UsefulInputBuf_GetUint64(UsefulInputBuf *pUInBuf);
1656
1657
1658#ifndef USEFULBUF_DISABLE_ALL_FLOAT
1671static float UsefulInputBuf_GetFloat(UsefulInputBuf *pUInBuf);
1672
1673
1686static double UsefulInputBuf_GetDouble(UsefulInputBuf *pUInBuf);
1687#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
1688
1689
1719static int UsefulInputBuf_GetError(UsefulInputBuf *pUInBuf);
1720
1721
1732static inline size_t UsefulInputBuf_GetBufferLength(UsefulInputBuf *pUInBuf);
1733
1734
1757static void UsefulInputBuf_SetBufferLength(UsefulInputBuf *pUInBuf, size_t uNewLen);
1758
1759
1770
1771
1772/*----------------------------------------------------------
1773 Inline implementations.
1774 */
1775static inline int UsefulBuf_IsNULL(UsefulBuf UB)
1776{
1777 return !UB.ptr;
1778}
1779
1780
1781static inline int UsefulBuf_IsNULLC(UsefulBufC UB)
1782{
1783 return !UB.ptr;
1784}
1785
1786
1787static inline int UsefulBuf_IsEmpty(UsefulBuf UB)
1788{
1789 return !UB.len;
1790}
1791
1792
1793static inline int UsefulBuf_IsEmptyC(UsefulBufC UB)
1794{
1795 return !UB.len;
1796}
1797
1798
1800{
1801 return UsefulBuf_IsEmpty(UB) || UsefulBuf_IsNULL(UB);
1802}
1803
1804
1806{
1807 return UsefulBuf_IsEmptyC(UB) || UsefulBuf_IsNULLC(UB);
1808}
1809
1810
1811static 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
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
1835static 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
1844static inline UsefulBufC UsefulBuf_Copy(UsefulBuf Dest, const UsefulBufC Src)
1845{
1846 return UsefulBuf_CopyOffset(Dest, 0, Src);
1847}
1848
1849
1850static 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
1862static 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
1871static 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
1885static 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
1903static 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
1926static 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
1939static inline uint32_t UsefulBufUtil_CopyFloatToUint32(float f)
1940{
1941 uint32_t u32;
1942 memcpy(&u32, &f, sizeof(uint32_t));
1943 return u32;
1944}
1945
1946static inline uint64_t UsefulBufUtil_CopyDoubleToUint64(double d)
1947{
1948 uint64_t u64;
1949 memcpy(&u64, &d, sizeof(uint64_t));
1950 return u64;
1951}
1952
1953static inline double UsefulBufUtil_CopyUint64ToDouble(uint64_t u64)
1954{
1955 double d;
1956 memcpy(&d, &u64, sizeof(uint64_t));
1957 return d;
1958}
1959
1960static 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
1971static inline void UsefulOutBuf_Reset(UsefulOutBuf *pMe)
1972{
1973 pMe->data_len = 0;
1974 pMe->err = 0;
1975}
1976
1977
1979{
1980 return pMe->data_len;
1981}
1982
1983
1984static inline int UsefulOutBuf_AtStart(UsefulOutBuf *pMe)
1985{
1986 return 0 == pMe->data_len;
1987}
1988
1989
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
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
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
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
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
2148 float f,
2149 size_t uPos)
2150{
2152}
2153
2154
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
2173 const void *pBytes,
2174 size_t uLen)
2175{
2176 UsefulBufC Data = {pBytes, uLen};
2178}
2179
2180
2182 const char *szString)
2183{
2184 UsefulBufC UBC;
2185 UBC.ptr = szString;
2186 UBC.len = strlen(szString);
2187
2189}
2190
2191
2193 uint8_t byte)
2194{
2195 UsefulOutBuf_AppendData(pMe, &byte, 1);
2196}
2197
2198
2200 uint16_t uInteger16)
2201{
2203}
2204
2206 uint32_t uInteger32)
2207{
2209}
2210
2211
2213 uint64_t uInteger64)
2214{
2216}
2217
2218
2219#ifndef USEFULBUF_DISABLE_ALL_FLOAT
2221 float f)
2222{
2224}
2225
2226
2228 double d)
2229{
2231}
2232#endif /* USEFULBUF_DISABLE_ALL_FLOAT */
2233
2234
2236{
2237 return pMe->err;
2238}
2239
2240
2241static inline size_t UsefulOutBuf_RoomLeft(UsefulOutBuf *pMe)
2242{
2243 return pMe->UB.len - pMe->data_len;
2244}
2245
2246
2247static 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
2283{
2284 pMe->cursor = 0;
2285 pMe->err = 0;
2286 pMe->magic = UIB_MAGIC;
2287 pMe->UB = UB;
2288}
2289
2290static inline size_t UsefulInputBuf_Tell(UsefulInputBuf *pMe)
2291{
2292 return pMe->cursor;
2293}
2294
2295
2297{
2298 return pMe->UB.len;
2299}
2300
2301
2302static 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
2338static inline int UsefulInputBuf_BytesAvailable(UsefulInputBuf *pMe, size_t uLen)
2339{
2340 return UsefulInputBuf_BytesUnconsumed(pMe) >= uLen ? 1 : 0;
2341}
2342
2343
2344static inline size_t UsefulInputBuf_PointerToOffset(UsefulInputBuf *pUInBuf, const void *p)
2345{
2346 return UsefulBuf_PointerToOffset(pUInBuf->UB, p);
2347}
2348
2349
2350static 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
2370static 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
2382static 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
2420static 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
2453static 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
2521{
2522 uint32_t uResult = UsefulInputBuf_GetUint32(pMe);
2523
2524 return uResult ? UsefulBufUtil_CopyUint32ToFloat(uResult) : 0;
2525}
2526
2527
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
2543static 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
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
const void * UsefulInputBuf_GetBytes(UsefulInputBuf *pUInBuf, size_t uNum)
Get pointer to bytes out of the input buffer.
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