1 /**
2 * Copyright (c) 2019, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #ifndef AEEBUFBOUND_H
31 #define AEEBUFBOUND_H
32 /*==============================================================================
33
34 FILE: AEEBufBound.h
35
36 SERVICES:
37 BufBound APIs
38
39 GENERAL DESCRIPTION:
40 BufBound provides a "bounded buffer" API that facilitates
41 measuring strings or character output. It's design accomodates
42 the implementation of functions that can have the same exact logic
43 for measuring and outputting char buffer content.
44
45 REVISION HISTORY:
46 Fri Aug 08 17:38:29 2003: Created
47
48 ==============================================================================*/
49
50 typedef struct BufBound
51 {
52 char* pcBuf; /* original buffer */
53 char* pcWrite; /* write pointer */
54 char* pcEnd; /* first illegal write pointer */
55 } BufBound;
56
57 #ifdef __cplusplus
58 extern "C" {
59 #endif /* #ifdef __cplusplus */
60
61 extern void BufBound_Init(BufBound *me, char *pBuf, int nLen);
62 extern void BufBound_Write(BufBound *me, const char *pc, int nLen);
63 extern void BufBound_Putc(BufBound *me, char c);
64 extern void BufBound_Putnc(BufBound *me, char c, int nCount);
65 extern void BufBound_ForceNullTerm(BufBound *me);
66 extern void BufBound_Puts(BufBound *me, const char* cpsz);
67 extern void BufBound_Advance(BufBound *me, int nLen);
68 extern void BufBound_WriteLE(BufBound* me,
69 const void *pvSrc, int nSrcSize,
70 const char *pszFields);
71 extern void BufBound_WriteBE(BufBound* me,
72 const void *pvSrc, int nSrcSize,
73 const char *pszFields);
74 extern int BufBound_BufSize(BufBound *me);
75 extern int BufBound_Left(BufBound* me);
76 extern int BufBound_ReallyWrote(BufBound* me);
77 extern int BufBound_Wrote(BufBound* me);
78
BufBound_IsFull(BufBound * me)79 static __inline int BufBound_IsFull(BufBound* me)
80 {
81 return (BufBound_Left(me) <= 0);
82 }
83
84 // Deprecated:
BufBound_IsCounter(BufBound * me)85 static __inline int BufBound_IsCounter(BufBound* me)
86 {
87 return BufBound_BufSize(me) == 0;
88 }
89
90 #ifdef __cplusplus
91 }
92 #endif /* #ifdef __cplusplus */
93
94
95 /*=====================================================================
96 =======================================================================
97 DATA STRUCTURE DOCUMENTATION
98 =======================================================================
99
100 BufBound
101
102 Description:
103 An BufBound keeps track of whether appending to a bounded buffer
104 has overflowed.
105
106 Definition:
107 typedef struct BufBound
108 {
109 char* pcBuf;
110 char* pcWrite;
111 char* pcEnd;
112 } BufBound;
113
114 Members:
115 pcBuf: original start pointer
116 pcWrite: current write location
117 pcEnd: first illegal write position
118
119 See Also:
120 BufBound Interface
121
122 =======================================================================
123 INTERFACE DOCUMENTATION
124 =======================================================================
125 BufBound Interface
126
127 BufBound is a statically-linked interface.
128
129 BufBound provides functions for safely appending to a character buffer. On
130 initialization, the buffer start address and size are provided. Subsequent
131 write operations are checked against the buffer bounds.
132
133 Once the buffer bounds are exceeded, no bytes will be written but the
134 BufBound will continue to increment its internal "write pointer" to reflect
135 the number of bytes that would have been written (had the bounds not been
136 exceeded).
137
138 When initialized with a buffer size of zero, a BufBound simply counts the
139 number of bytes that would be required to contain the result. This design
140 accommodates implementations that use the same logic for generating output
141 and measuring the space required for generated output.
142
143 BufBound protects clients from numerical overflow by limiting the write
144 pointer to a maximum offset of INT_MAX from the start of the buffer.
145 Functions that write data into the buffer safely ignore negative size inputs
146 (Write and Putnc).
147
148 =======================================================================
149 BufBound_Init()
150
151 Description:
152 initialize a BufBound for appending to a buffer
153
154 Prototype:
155
156 void BufBound_Init(BufBound *me, char *pBuf, int nLen);
157
158 Parameters:
159 me: the BufBound
160 pBuf: the bounded buffer
161 nLen: size of pBuf, in bytes
162
163 Return Value:
164 None
165
166 Comments:
167 None
168
169 Side Effects:
170 None
171
172 See Also:
173 None
174
175 =======================================================================
176
177 BufBound_Write()
178
179 Description:
180 Appends some number of bytes to a BufBound, if possible.
181
182 When a negative size is passed, it is safely treated as zero.
183
184 Prototype:
185
186 void BufBound_Write(BufBound *me, const char *pc, int nLen);
187
188 Parameters:
189 me: the BufBound
190 pc: pointer to bytes to append
191 int nLen: number of bytes to write
192
193 Return Value:
194 None
195
196 Comments:
197 If the BufBound has overflowed, no bytes are written, but pcWrite is
198 *always* advanced by nLen.
199
200 Side Effects:
201 None
202
203 See Also:
204 None
205
206 =======================================================================
207
208 BufBound_Advance()
209
210 Description:
211
212 Moves the write pointer. Advance is like a relative seek operation. It
213 does not change the contents of the buffer, so when using a forward seek
214 (positive advance) be careful of advancing over uninitialized data.
215
216 Negative numbers will decrease the write pointer down to 0 (the start of
217 the buffer) and not below. Positive numbers will increase the write
218 pointer up to offset INT_MAX and not beyond.
219
220 Prototype:
221
222 void BufBound_Advance(BufBound *me, int nDelta);
223
224 Parameters:
225 me: the BufBound
226 int nLen: number of bytes to advance
227
228 Return Value:
229 None
230
231 Comments:
232 None
233
234 Side Effects:
235 None
236
237 See Also:
238 None
239
240 =======================================================================
241
242 BufBound_Putc()
243
244 Description:
245 Appends one byte to a BufBound, if possible.
246
247 Prototype:
248
249 void BufBound_Putc(BufBound *me, char c);
250
251 Parameters:
252 me: the BufBound
253 c: the byte
254
255 Return Value:
256 None
257
258 Comments:
259 If the BufBound has overflowed, no byte is written, but pcWrite is
260 *always* advanced by 1.
261
262 Side Effects:
263 None
264
265 See Also:
266 None
267
268
269 =======================================================================
270
271 BufBound_Putnc()
272
273 Description:
274 Appends a byte to a BufBound repeatedly.
275
276 When a negative size is passed, it is safely treated as zero.
277
278 Prototype:
279
280 void BufBound_Putnc(BufBound *me, char c, int nCount);
281
282 Parameters:
283 me: the BufBound
284 c: the byte
285 nCount: number of times to append c
286
287 Return Value:
288 None
289
290 Comments:
291 If the BufBound has overflowed, no byte is written, but pcWrite is
292 *always* advanced by nCount.
293
294 Side Effects:
295 None
296
297 See Also:
298 None
299
300
301 =======================================================================
302
303 BufBound_ForceNullTerm()
304
305 Description:
306 Appends a null terminating character to a BufBound, if possible.
307 If the BufBound has overflowed, the last legal location is
308 set to '\0'.
309
310 Prototype:
311 void BufBound_ForceNullTerm(BufBound *me);
312
313 Parameters:
314 me: the BufBound
315
316 Return Value:
317 None
318
319 Comments:
320 pcWrite is *always* advanced by 1.
321
322 Side Effects:
323 None
324
325 See Also:
326 None
327
328
329 =======================================================================
330
331 BufBound_Puts()
332
333 Description:
334 Appends a null-terminated string to a BufBound, if possible
335
336 Prototype:
337
338 void BufBound_Puts(BufBound *me, const char* cpsz);
339
340 Parameters:
341 me: the BufBound
342 cpsz: the string to append
343
344 Return Value:
345
346 Comments:
347 If the BufBound has overflowed, no bytes are written, but pcWrite is
348 *always* advanced by strlen(cpsz).
349
350 Side Effects:
351 None
352
353 See Also:
354 None
355
356
357 =======================================================================
358
359 BufBound_BufSize()
360
361 Description:
362 Returns the size of the buffer owned by the BufBound. This is
363 the same as the number passed to BufBound_Init (MAXed with zero).
364
365 Prototype:
366
367 int BufBound_IsCounter(BufBound* me);
368
369 Parameters:
370 me: the BufBound
371
372 Return Value:
373 1 if the BufBound is a counter, 0 otherwise
374
375 Comments:
376 None
377
378 Side Effects:
379 None
380
381 See Also:
382 None
383
384
385 =======================================================================
386
387 BufBound_Left()
388
389 Description:
390 Returns the number of bytes the BufBound can still accomodate,
391 without overflowing. If overflow has occurred, it will return
392 a negative number.
393
394 Prototype:
395
396 int BufBound_Left(BufBound* me);
397
398 Parameters:
399 me: the BufBound
400
401 Return Value:
402 The number of bytes the BufBound can still accomodate,
403 without overflowing.
404
405 Comments:
406 The return value may be negative, if overflow has already occurred.
407
408 Side Effects:
409 None
410
411 See Also:
412 None
413
414
415 =======================================================================
416
417 BufBound_ReallyWrote()
418
419 Description:
420 Returns the number of bytes actually written to the BufBound,
421 not including any overflow.
422
423 Prototype:
424
425 int BufBound_ReallyWrote(BufBound* me);
426
427 Parameters:
428 me: the BufBound
429
430 Return Value:
431 The number of bytes actually written to the BufBound,
432 not including any overflow.
433
434 Comments:
435 None
436
437 Side Effects:
438 None
439
440 See Also:
441 None
442
443
444 =======================================================================
445
446 BufBound_Wrote()
447
448 Description:
449
450 Returns the number of bytes written to the BufBound, including any
451 overflow, up to INT_MAX.
452
453 Prototype:
454
455 int BufBound_Wrote(BufBound* me);
456
457 Parameters:
458 me: the BufBound
459
460 Return Value:
461
462 The number of bytes written to the BufBound, including any overflow.
463
464 Comments:
465 None
466
467 Side Effects:
468 None
469
470 See Also:
471 None
472
473
474 =======================================================================
475
476 BufBound_IsFull()
477
478 Description:
479 Tests whether an AEEBuffBound has overflowed.
480
481 Prototype:
482
483 int BufBound_IsFull(BufBound* me);
484
485 Parameters:
486 me: the BufBound
487
488 Return Value:
489 1 if the BufBound has overflowed, 0 otherwise
490
491 Comments:
492 None
493
494 Side Effects:
495 None
496
497 See Also:
498 None
499
500 =======================================================================
501
502 BufBound_WriteLE()
503
504 Description:
505
506 Writes data while translating numeric values between host byte ordering and
507 "little endian" byte ordering.
508
509 The input buffer is treated as an array of structures. The 'abySizes'
510 parameter describes the sizes of fields in the structure.
511
512 When the host byte ordering matches the target byte ordering (little
513 endian) this operation is equivalent to BufBound_Write().
514
515 Prototype:
516
517 void BufBound_WriteLE(BufBound* me,
518 const void *pvSrc, int nSrcSize,
519 const unsigned char *pszFields);
520
521 Parameters:
522 me: the BufBound
523 pvSrc: the source buffer
524 nSrcSize: number of bytes to copy from the source buffer
525 pszFields: Description of the fields that comprise the source data,
526 as defined in std_CopyLE.
527
528 Return Value:
529 None
530
531 See Also:
532 BufBound_WriteBE, std_CopyLE
533
534 =======================================================================
535
536 BufBound_WriteBE()
537
538 Description:
539
540 BufBounf_WriteBE() has the same semantics as BufBound_WriteLE() except it
541 copies between host byte ordering and big-endian ("network") byte order.
542
543 See BufBound_WriteLE() for more details.
544
545
546 Prototype:
547
548 void BufBound_WriteBE(BufBound* me,
549 const void *pvSrc, int nSrcSize,
550 const unsigned char *pszFields);
551
552 Parameters:
553 me: the BufBound
554 pvSrc: the source buffer
555 nSrcSize: number of bytes to copy from the source buffer
556 pszFields: Description of the fields that comprise the source data,
557 as defined in std_CopyLE.
558
559 Return Value:
560 None
561
562 See Also:
563 BufBound_WriteLE, std_CopyBE
564
565 ======================================================================= */
566 #endif /* #ifndef AEEBUFBOUND_H */
567
568