blob: e5be98a960bd4d6a29a3b1defc1a2e14092f4456 [file] [log] [blame]
Laurence Lundbladeb69cad72018-09-13 11:09:01 -07001/*==============================================================================
Laurence Lundbladed92a6162018-11-01 11:38:35 +07002 Copyright (c) 2016-2018, The Linux Foundation.
Laurence Lundbladeb9702452021-03-08 21:02:57 -08003 Copyright (c) 2018-2021, Laurence Lundblade.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -08004
Laurence Lundblade0dbc9172018-11-01 14:17:21 +07005Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are
7met:
8 * Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above
11 copyright notice, this list of conditions and the following
12 disclaimer in the documentation and/or other materials provided
13 with the distribution.
14 * Neither the name of The Linux Foundation nor the names of its
15 contributors, nor the name "Laurence Lundblade" may be used to
16 endorse or promote products derived from this software without
17 specific prior written permission.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080018
Laurence Lundblade0dbc9172018-11-01 14:17:21 +070019THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
20WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
22ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
23BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
26BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Laurence Lundbladeee851742020-01-08 08:37:05 -080030 =============================================================================*/
Laurence Lundblade624405d2018-09-18 20:10:47 -070031
Laurence Lundbladeee851742020-01-08 08:37:05 -080032/*=============================================================================
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070033 FILE: UsefulBuf.c
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080034
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070035 DESCRIPTION: General purpose input and output buffers
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080036
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070037 EDIT HISTORY FOR FILE:
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080038
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070039 This section contains comments describing changes made to the module.
40 Notice that changes are listed in reverse chronological order.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080041
Laurence Lundbladeee851742020-01-08 08:37:05 -080042 when who what, where, why
43 -------- ---- ---------------------------------------------------
Laurence Lundbladeb9702452021-03-08 21:02:57 -080044 3/6/2021 mcr/llundblade Fix warnings related to --Wcast-qual
Laurence Lundblade06350ea2020-01-27 19:32:40 -080045 01/28/2020 llundblade Refine integer signedness to quiet static analysis.
46 01/08/2020 llundblade Documentation corrections & improved code formatting.
Laurence Lundbladeee851742020-01-08 08:37:05 -080047 11/08/2019 llundblade Re check pointer math and update comments
48 3/6/2019 llundblade Add UsefulBuf_IsValue()
49 09/07/17 llundbla Fix critical bug in UsefulBuf_Find() -- a read off
50 the end of memory when the bytes to find is longer
51 than the bytes to search.
52 06/27/17 llundbla Fix UsefulBuf_Compare() bug. Only affected comparison
53 for < or > for unequal length buffers. Added
54 UsefulBuf_Set() function.
55 05/30/17 llundbla Functions for NULL UsefulBufs and const / unconst
56 11/13/16 llundbla Initial Version.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080057
Laurence Lundbladeee851742020-01-08 08:37:05 -080058 ============================================================================*/
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070059
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070060#include "UsefulBuf.h"
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070061
Laurence Lundbladeee851742020-01-08 08:37:05 -080062// used to catch use of uninitialized or corrupted UsefulOutBuf
63#define USEFUL_OUT_BUF_MAGIC (0x0B0F)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070064
Laurence Lundblade041ffa52018-10-07 11:43:51 +070065
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +053066/*
67 Public function -- see UsefulBuf.h
68 */
Laurence Lundblade041ffa52018-10-07 11:43:51 +070069UsefulBufC UsefulBuf_CopyOffset(UsefulBuf Dest, size_t uOffset, const UsefulBufC Src)
70{
Laurence Lundbladeee851742020-01-08 08:37:05 -080071 // Do this with subtraction so it doesn't give erroneous
72 // result if uOffset + Src.len overflows
Laurence Lundblade7566b9f2018-10-12 09:13:32 +080073 if(uOffset > Dest.len || Src.len > Dest.len - uOffset) { // uOffset + Src.len > Dest.len
74 return NULLUsefulBufC;
75 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080076
Laurence Lundblade570fab52018-10-13 18:28:27 +080077 memcpy((uint8_t *)Dest.ptr + uOffset, Src.ptr, Src.len);
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080078
Laurence Lundblade25c6c0a2018-12-17 13:21:59 -080079 return (UsefulBufC){Dest.ptr, Src.len + uOffset};
Laurence Lundblade041ffa52018-10-07 11:43:51 +070080}
81
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +053082
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070083/*
84 Public function -- see UsefulBuf.h
85 */
86int UsefulBuf_Compare(const UsefulBufC UB1, const UsefulBufC UB2)
87{
88 // use the comparisons rather than subtracting lengths to
89 // return an int instead of a size_t
90 if(UB1.len < UB2.len) {
91 return -1;
92 } else if (UB1.len > UB2.len) {
93 return 1;
94 } // else UB1.len == UB2.len
Laurence Lundblade3aee3a32018-12-17 16:17:45 -080095
Laurence Lundbladeb69cad72018-09-13 11:09:01 -070096 return memcmp(UB1.ptr, UB2.ptr, UB1.len);
97}
98
99
Laurence Lundbladed5e101e2019-03-06 17:23:18 -0800100/*
101 Public function -- see UsefulBuf.h
102 */
103size_t UsefulBuf_IsValue(const UsefulBufC UB, uint8_t uValue)
104{
105 if(UsefulBuf_IsNULLOrEmptyC(UB)) {
106 /* Not a match */
107 return 0;
108 }
109
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800110 const uint8_t * const pEnd = (const uint8_t *)UB.ptr + UB.len;
Laurence Lundbladed5e101e2019-03-06 17:23:18 -0800111 for(const uint8_t *p = UB.ptr; p < pEnd; p++) {
112 if(*p != uValue) {
113 /* Byte didn't match */
Laurence Lundblade06350ea2020-01-27 19:32:40 -0800114 /* Cast from signed to unsigned . Safe because the loop increments.*/
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800115 return (size_t)(p - (const uint8_t *)UB.ptr);
Laurence Lundbladed5e101e2019-03-06 17:23:18 -0800116 }
117 }
118
119 /* Success. All bytes matched */
120 return SIZE_MAX;
121}
122
Laurence Lundbladeda3f0822018-09-18 19:49:02 -0700123
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700124/*
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530125 Public function -- see UsefulBuf.h
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700126 */
127size_t UsefulBuf_FindBytes(UsefulBufC BytesToSearch, UsefulBufC BytesToFind)
128{
129 if(BytesToSearch.len < BytesToFind.len) {
130 return SIZE_MAX;
131 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800132
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700133 for(size_t uPos = 0; uPos <= BytesToSearch.len - BytesToFind.len; uPos++) {
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800134 if(!UsefulBuf_Compare((UsefulBufC){((const uint8_t *)BytesToSearch.ptr) + uPos, BytesToFind.len}, BytesToFind)) {
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700135 return uPos;
136 }
137 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800138
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700139 return SIZE_MAX;
140}
141
142
143/*
144 Public function -- see UsefulBuf.h
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800145
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530146 Code Reviewers: THIS FUNCTION DOES POINTER MATH
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700147 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100148void UsefulOutBuf_Init(UsefulOutBuf *pMe, UsefulBuf Storage)
Laurence Lundblade2296db52018-09-14 18:08:39 -0700149{
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100150 pMe->magic = USEFUL_OUT_BUF_MAGIC;
151 UsefulOutBuf_Reset(pMe);
152 pMe->UB = Storage;
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800153
Laurence Lundblade2296db52018-09-14 18:08:39 -0700154#if 0
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530155 // This check is off by default.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800156
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530157 // The following check fails on ThreadX
158
Laurence Lundblade2296db52018-09-14 18:08:39 -0700159 // Sanity check on the pointer and size to be sure we are not
160 // passed a buffer that goes off the end of the address space.
161 // Given this test, we know that all unsigned lengths less than
162 // me->size are valid and won't wrap in any pointer additions
163 // based off of pStorage in the rest of this code.
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530164 const uintptr_t ptrM = UINTPTR_MAX - Storage.len;
165 if(Storage.ptr && (uintptr_t)Storage.ptr > ptrM) // Check #0
Laurence Lundblade2296db52018-09-14 18:08:39 -0700166 me->err = 1;
167#endif
168}
169
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700170
171
172/*
173 Public function -- see UsefulBuf.h
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800174
Laurence Lundbladeee851742020-01-08 08:37:05 -0800175 The core of UsefulOutBuf -- put some bytes in the buffer without writing off
176 the end of it.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800177
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700178 Code Reviewers: THIS FUNCTION DOES POINTER MATH
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800179
Laurence Lundbladeee851742020-01-08 08:37:05 -0800180 This function inserts the source buffer, NewData, into the destination
181 buffer, me->UB.ptr.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800182
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700183 Destination is represented as:
184 me->UB.ptr -- start of the buffer
Laurence Lundblade9e7f4742018-09-20 18:50:31 -0700185 me->UB.len -- size of the buffer UB.ptr
186 me->data_len -- length of value data in UB
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800187
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700188 Source is data:
189 NewData.ptr -- start of source buffer
190 NewData.len -- length of source buffer
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800191
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700192 Insertion point:
193 uInsertionPos.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800194
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700195 Steps:
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800196
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700197 0. Corruption checks on UsefulOutBuf
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800198
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700199 1. Figure out if the new data will fit or not
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800200
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700201 2. Is insertion position in the range of valid data?
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800202
Laurence Lundbladeee851742020-01-08 08:37:05 -0800203 3. If insertion point is not at the end, slide data to the right of the
204 insertion point to the right
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800205
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700206 4. Put the new data in at the insertion position.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800207
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700208 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100209void UsefulOutBuf_InsertUsefulBuf(UsefulOutBuf *pMe, UsefulBufC NewData, size_t uInsertionPos)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700210{
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100211 if(pMe->err) {
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700212 // Already in error state.
213 return;
214 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800215
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700216 /* 0. Sanity check the UsefulOutBuf structure */
217 // A "counter measure". If magic number is not the right number it
218 // probably means me was not initialized or it was corrupted. Attackers
219 // can defeat this, but it is a hurdle and does good with very
220 // little code.
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100221 if(pMe->magic != USEFUL_OUT_BUF_MAGIC) {
222 pMe->err = 1;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700223 return; // Magic number is wrong due to uninitalization or corrption
224 }
225
226 // Make sure valid data is less than buffer size. This would only occur
227 // if there was corruption of me, but it is also part of the checks to
228 // be sure there is no pointer arithmatic under/overflow.
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100229 if(pMe->data_len > pMe->UB.len) { // Check #1
230 pMe->err = 1;
Laurence Lundbladeee851742020-01-08 08:37:05 -0800231 // Offset of valid data is off the end of the UsefulOutBuf due to
232 // uninitialization or corruption
233 return;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700234 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800235
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700236 /* 1. Will it fit? */
Laurence Lundblade61209742019-11-08 13:16:43 -0800237 // WillItFit() is the same as: NewData.len <= (me->UB.len - me->data_len)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700238 // Check #1 makes sure subtraction in RoomLeft will not wrap around
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100239 if(! UsefulOutBuf_WillItFit(pMe, NewData.len)) { // Check #2
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700240 // The new data will not fit into the the buffer.
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100241 pMe->err = 1;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700242 return;
243 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800244
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700245 /* 2. Check the Insertion Position */
Laurence Lundblade61209742019-11-08 13:16:43 -0800246 // This, with Check #1, also confirms that uInsertionPos <= me->data_len and
247 // that uInsertionPos + pMe->UB.ptr will not wrap around the end of the
248 // address space.
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100249 if(uInsertionPos > pMe->data_len) { // Check #3
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700250 // Off the end of the valid data in the buffer.
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100251 pMe->err = 1;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700252 return;
253 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800254
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700255 /* 3. Slide existing data to the right */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100256 uint8_t *pSourceOfMove = ((uint8_t *)pMe->UB.ptr) + uInsertionPos; // PtrMath #1
257 size_t uNumBytesToMove = pMe->data_len - uInsertionPos; // PtrMath #2
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700258 uint8_t *pDestinationOfMove = pSourceOfMove + NewData.len; // PtrMath #3
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800259
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100260 if(uNumBytesToMove && pMe->UB.ptr) {
Laurence Lundblade56a79322019-01-10 09:12:37 -0800261 // To know memmove won't go off end of destination, see PtrMath #4
Laurence Lundblade61209742019-11-08 13:16:43 -0800262 // Use memove because it handles overlapping buffers
Laurence Lundblade74f68412018-09-13 12:18:49 -0700263 memmove(pDestinationOfMove, pSourceOfMove, uNumBytesToMove);
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700264 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800265
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700266 /* 4. Put the new data in */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100267 uint8_t *pInsertionPoint = ((uint8_t *)pMe->UB.ptr) + uInsertionPos; // PtrMath #5
268 if(pMe->UB.ptr) {
Laurence Lundblade56a79322019-01-10 09:12:37 -0800269 // To know memmove won't go off end of destination, see PtrMath #6
Laurence Lundblade74f68412018-09-13 12:18:49 -0700270 memmove(pInsertionPoint, NewData.ptr, NewData.len);
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700271 }
Laurence Lundblade61209742019-11-08 13:16:43 -0800272 pMe->data_len += NewData.len;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700273}
274
275
276/*
277 Rationale that describes why the above pointer math is safe
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800278
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700279 PtrMath #1 will never wrap around over because
Laurence Lundblade56a79322019-01-10 09:12:37 -0800280 Check #0 in UsefulOutBuf_Init makes sure me->UB.ptr + me->UB.len doesn't wrap
281 Check #1 makes sure me->data_len is less than me->UB.len
282 Check #3 makes sure uInsertionPos is less than me->data_len
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800283
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700284 PtrMath #2 will never wrap around under because
Laurence Lundblade56a79322019-01-10 09:12:37 -0800285 Check #3 makes sure uInsertionPos is less than me->data_len
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800286
Laurence Lundblade61209742019-11-08 13:16:43 -0800287 PtrMath #3 will never wrap around over because
288 PtrMath #1 is checked resulting in pSourceOfMove being between me->UB.ptr and me->UB.ptr + me->data_len
289 Check #2 that NewData.len will fit in the unused space left in me->UB
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800290
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700291 PtrMath #4 will never wrap under because
Laurence Lundblade56a79322019-01-10 09:12:37 -0800292 Calculation for extent or memmove is uRoomInDestination = me->UB.len - (uInsertionPos + NewData.len)
Laurence Lundblade9e7f4742018-09-20 18:50:31 -0700293 Check #3 makes sure uInsertionPos is less than me->data_len
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700294 Check #3 allows Check #2 to be refactored as NewData.Len > (me->size - uInsertionPos)
295 This algebraically rearranges to me->size > uInsertionPos + NewData.len
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800296
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700297 PtrMath #5 is exactly the same as PtrMath #1
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800298
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700299 PtrMath #6 will never wrap under because
Laurence Lundblade56a79322019-01-10 09:12:37 -0800300 Calculation for extent of memove is uRoomInDestination = me->UB.len - uInsertionPos;
301 Check #1 makes sure me->data_len is less than me->size
302 Check #3 makes sure uInsertionPos is less than me->data_len
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700303 */
304
305
306/*
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800307 Public function -- see UsefulBuf.h
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700308 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100309UsefulBufC UsefulOutBuf_OutUBuf(UsefulOutBuf *pMe)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700310{
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100311 if(pMe->err) {
Laurence Lundblade2296db52018-09-14 18:08:39 -0700312 return NULLUsefulBufC;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700313 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800314
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100315 if(pMe->magic != USEFUL_OUT_BUF_MAGIC) {
316 pMe->err = 1;
Laurence Lundblade2296db52018-09-14 18:08:39 -0700317 return NULLUsefulBufC;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700318 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800319
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100320 return (UsefulBufC){pMe->UB.ptr, pMe->data_len};
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700321}
322
323
324/*
325 Public function -- see UsefulBuf.h
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800326
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530327 Copy out the data accumulated in to the output buffer.
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700328 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100329UsefulBufC UsefulOutBuf_CopyOut(UsefulOutBuf *pMe, UsefulBuf pDest)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700330{
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100331 const UsefulBufC Tmp = UsefulOutBuf_OutUBuf(pMe);
Laurence Lundbladedc6e28e2018-10-11 19:19:27 +0530332 if(UsefulBuf_IsNULLC(Tmp)) {
333 return NULLUsefulBufC;
334 }
335 return UsefulBuf_Copy(pDest, Tmp);
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700336}
337
338
339
340
341/*
342 Public function -- see UsefulBuf.h
343
Laurence Lundbladeee851742020-01-08 08:37:05 -0800344 The core of UsefulInputBuf -- consume bytes without going off end of buffer.
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800345
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700346 Code Reviewers: THIS FUNCTION DOES POINTER MATH
347 */
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100348const void * UsefulInputBuf_GetBytes(UsefulInputBuf *pMe, size_t uAmount)
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700349{
350 // Already in error state. Do nothing.
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100351 if(pMe->err) {
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700352 return NULL;
353 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800354
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100355 if(!UsefulInputBuf_BytesAvailable(pMe, uAmount)) {
Laurence Lundbladeee851742020-01-08 08:37:05 -0800356 // Number of bytes asked for at current position are more than available
Laurence Lundblade5cc25682019-03-26 21:58:35 +0100357 pMe->err = 1;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700358 return NULL;
359 }
Laurence Lundblade3aee3a32018-12-17 16:17:45 -0800360
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700361 // This is going to succeed
Laurence Lundbladeb9702452021-03-08 21:02:57 -0800362 const void * const result = ((const uint8_t *)pMe->UB.ptr) + pMe->cursor;
Laurence Lundbladeee851742020-01-08 08:37:05 -0800363 // Will not overflow because of check using UsefulInputBuf_BytesAvailable()
364 pMe->cursor += uAmount;
Laurence Lundbladeb69cad72018-09-13 11:09:01 -0700365 return result;
366}
367