| /** | |
| * Copyright (c) 2019, The Linux Foundation. All rights reserved. | |
| * | |
| * Redistribution and use in source and binary forms, with or without | |
| * modification, are permitted provided that the following conditions are | |
| * met: | |
| * * Redistributions of source code must retain the above copyright | |
| * notice, this list of conditions and the following disclaimer. | |
| * * Redistributions in binary form must reproduce the above | |
| * copyright notice, this list of conditions and the following | |
| * disclaimer in the documentation and/or other materials provided | |
| * with the distribution. | |
| * * Neither the name of The Linux Foundation nor the names of its | |
| * contributors may be used to endorse or promote products derived | |
| * from this software without specific prior written permission. | |
| * | |
| * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED | |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT | |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS | |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | |
| * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | |
| * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN | |
| * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| */ | |
| #ifndef AEEBUFBOUND_H | |
| #define AEEBUFBOUND_H | |
| /*============================================================================== | |
| FILE: AEEBufBound.h | |
| SERVICES: | |
| BufBound APIs | |
| GENERAL DESCRIPTION: | |
| BufBound provides a "bounded buffer" API that facilitates | |
| measuring strings or character output. It's design accomodates | |
| the implementation of functions that can have the same exact logic | |
| for measuring and outputting char buffer content. | |
| REVISION HISTORY: | |
| Fri Aug 08 17:38:29 2003: Created | |
| ==============================================================================*/ | |
| typedef struct BufBound | |
| { | |
| char* pcBuf; /* original buffer */ | |
| char* pcWrite; /* write pointer */ | |
| char* pcEnd; /* first illegal write pointer */ | |
| } BufBound; | |
| #ifdef __cplusplus | |
| extern "C" { | |
| #endif /* #ifdef __cplusplus */ | |
| extern void BufBound_Init(BufBound *me, char *pBuf, int nLen); | |
| extern void BufBound_Write(BufBound *me, const char *pc, int nLen); | |
| extern void BufBound_Putc(BufBound *me, char c); | |
| extern void BufBound_Putnc(BufBound *me, char c, int nCount); | |
| extern void BufBound_ForceNullTerm(BufBound *me); | |
| extern void BufBound_Puts(BufBound *me, const char* cpsz); | |
| extern void BufBound_Advance(BufBound *me, int nLen); | |
| extern void BufBound_WriteLE(BufBound* me, | |
| const void *pvSrc, int nSrcSize, | |
| const char *pszFields); | |
| extern void BufBound_WriteBE(BufBound* me, | |
| const void *pvSrc, int nSrcSize, | |
| const char *pszFields); | |
| extern int BufBound_BufSize(BufBound *me); | |
| extern int BufBound_Left(BufBound* me); | |
| extern int BufBound_ReallyWrote(BufBound* me); | |
| extern int BufBound_Wrote(BufBound* me); | |
| static __inline int BufBound_IsFull(BufBound* me) | |
| { | |
| return (BufBound_Left(me) <= 0); | |
| } | |
| // Deprecated: | |
| static __inline int BufBound_IsCounter(BufBound* me) | |
| { | |
| return BufBound_BufSize(me) == 0; | |
| } | |
| #ifdef __cplusplus | |
| } | |
| #endif /* #ifdef __cplusplus */ | |
| /*===================================================================== | |
| ======================================================================= | |
| DATA STRUCTURE DOCUMENTATION | |
| ======================================================================= | |
| BufBound | |
| Description: | |
| An BufBound keeps track of whether appending to a bounded buffer | |
| has overflowed. | |
| Definition: | |
| typedef struct BufBound | |
| { | |
| char* pcBuf; | |
| char* pcWrite; | |
| char* pcEnd; | |
| } BufBound; | |
| Members: | |
| pcBuf: original start pointer | |
| pcWrite: current write location | |
| pcEnd: first illegal write position | |
| See Also: | |
| BufBound Interface | |
| ======================================================================= | |
| INTERFACE DOCUMENTATION | |
| ======================================================================= | |
| BufBound Interface | |
| BufBound is a statically-linked interface. | |
| BufBound provides functions for safely appending to a character buffer. On | |
| initialization, the buffer start address and size are provided. Subsequent | |
| write operations are checked against the buffer bounds. | |
| Once the buffer bounds are exceeded, no bytes will be written but the | |
| BufBound will continue to increment its internal "write pointer" to reflect | |
| the number of bytes that would have been written (had the bounds not been | |
| exceeded). | |
| When initialized with a buffer size of zero, a BufBound simply counts the | |
| number of bytes that would be required to contain the result. This design | |
| accommodates implementations that use the same logic for generating output | |
| and measuring the space required for generated output. | |
| BufBound protects clients from numerical overflow by limiting the write | |
| pointer to a maximum offset of INT_MAX from the start of the buffer. | |
| Functions that write data into the buffer safely ignore negative size inputs | |
| (Write and Putnc). | |
| ======================================================================= | |
| BufBound_Init() | |
| Description: | |
| initialize a BufBound for appending to a buffer | |
| Prototype: | |
| void BufBound_Init(BufBound *me, char *pBuf, int nLen); | |
| Parameters: | |
| me: the BufBound | |
| pBuf: the bounded buffer | |
| nLen: size of pBuf, in bytes | |
| Return Value: | |
| None | |
| Comments: | |
| None | |
| Side Effects: | |
| None | |
| See Also: | |
| None | |
| ======================================================================= | |
| BufBound_Write() | |
| Description: | |
| Appends some number of bytes to a BufBound, if possible. | |
| When a negative size is passed, it is safely treated as zero. | |
| Prototype: | |
| void BufBound_Write(BufBound *me, const char *pc, int nLen); | |
| Parameters: | |
| me: the BufBound | |
| pc: pointer to bytes to append | |
| int nLen: number of bytes to write | |
| Return Value: | |
| None | |
| Comments: | |
| If the BufBound has overflowed, no bytes are written, but pcWrite is | |
| *always* advanced by nLen. | |
| Side Effects: | |
| None | |
| See Also: | |
| None | |
| ======================================================================= | |
| BufBound_Advance() | |
| Description: | |
| Moves the write pointer. Advance is like a relative seek operation. It | |
| does not change the contents of the buffer, so when using a forward seek | |
| (positive advance) be careful of advancing over uninitialized data. | |
| Negative numbers will decrease the write pointer down to 0 (the start of | |
| the buffer) and not below. Positive numbers will increase the write | |
| pointer up to offset INT_MAX and not beyond. | |
| Prototype: | |
| void BufBound_Advance(BufBound *me, int nDelta); | |
| Parameters: | |
| me: the BufBound | |
| int nLen: number of bytes to advance | |
| Return Value: | |
| None | |
| Comments: | |
| None | |
| Side Effects: | |
| None | |
| See Also: | |
| None | |
| ======================================================================= | |
| BufBound_Putc() | |
| Description: | |
| Appends one byte to a BufBound, if possible. | |
| Prototype: | |
| void BufBound_Putc(BufBound *me, char c); | |
| Parameters: | |
| me: the BufBound | |
| c: the byte | |
| Return Value: | |
| None | |
| Comments: | |
| If the BufBound has overflowed, no byte is written, but pcWrite is | |
| *always* advanced by 1. | |
| Side Effects: | |
| None | |
| See Also: | |
| None | |
| ======================================================================= | |
| BufBound_Putnc() | |
| Description: | |
| Appends a byte to a BufBound repeatedly. | |
| When a negative size is passed, it is safely treated as zero. | |
| Prototype: | |
| void BufBound_Putnc(BufBound *me, char c, int nCount); | |
| Parameters: | |
| me: the BufBound | |
| c: the byte | |
| nCount: number of times to append c | |
| Return Value: | |
| None | |
| Comments: | |
| If the BufBound has overflowed, no byte is written, but pcWrite is | |
| *always* advanced by nCount. | |
| Side Effects: | |
| None | |
| See Also: | |
| None | |
| ======================================================================= | |
| BufBound_ForceNullTerm() | |
| Description: | |
| Appends a null terminating character to a BufBound, if possible. | |
| If the BufBound has overflowed, the last legal location is | |
| set to '\0'. | |
| Prototype: | |
| void BufBound_ForceNullTerm(BufBound *me); | |
| Parameters: | |
| me: the BufBound | |
| Return Value: | |
| None | |
| Comments: | |
| pcWrite is *always* advanced by 1. | |
| Side Effects: | |
| None | |
| See Also: | |
| None | |
| ======================================================================= | |
| BufBound_Puts() | |
| Description: | |
| Appends a null-terminated string to a BufBound, if possible | |
| Prototype: | |
| void BufBound_Puts(BufBound *me, const char* cpsz); | |
| Parameters: | |
| me: the BufBound | |
| cpsz: the string to append | |
| Return Value: | |
| Comments: | |
| If the BufBound has overflowed, no bytes are written, but pcWrite is | |
| *always* advanced by strlen(cpsz). | |
| Side Effects: | |
| None | |
| See Also: | |
| None | |
| ======================================================================= | |
| BufBound_BufSize() | |
| Description: | |
| Returns the size of the buffer owned by the BufBound. This is | |
| the same as the number passed to BufBound_Init (MAXed with zero). | |
| Prototype: | |
| int BufBound_IsCounter(BufBound* me); | |
| Parameters: | |
| me: the BufBound | |
| Return Value: | |
| 1 if the BufBound is a counter, 0 otherwise | |
| Comments: | |
| None | |
| Side Effects: | |
| None | |
| See Also: | |
| None | |
| ======================================================================= | |
| BufBound_Left() | |
| Description: | |
| Returns the number of bytes the BufBound can still accomodate, | |
| without overflowing. If overflow has occurred, it will return | |
| a negative number. | |
| Prototype: | |
| int BufBound_Left(BufBound* me); | |
| Parameters: | |
| me: the BufBound | |
| Return Value: | |
| The number of bytes the BufBound can still accomodate, | |
| without overflowing. | |
| Comments: | |
| The return value may be negative, if overflow has already occurred. | |
| Side Effects: | |
| None | |
| See Also: | |
| None | |
| ======================================================================= | |
| BufBound_ReallyWrote() | |
| Description: | |
| Returns the number of bytes actually written to the BufBound, | |
| not including any overflow. | |
| Prototype: | |
| int BufBound_ReallyWrote(BufBound* me); | |
| Parameters: | |
| me: the BufBound | |
| Return Value: | |
| The number of bytes actually written to the BufBound, | |
| not including any overflow. | |
| Comments: | |
| None | |
| Side Effects: | |
| None | |
| See Also: | |
| None | |
| ======================================================================= | |
| BufBound_Wrote() | |
| Description: | |
| Returns the number of bytes written to the BufBound, including any | |
| overflow, up to INT_MAX. | |
| Prototype: | |
| int BufBound_Wrote(BufBound* me); | |
| Parameters: | |
| me: the BufBound | |
| Return Value: | |
| The number of bytes written to the BufBound, including any overflow. | |
| Comments: | |
| None | |
| Side Effects: | |
| None | |
| See Also: | |
| None | |
| ======================================================================= | |
| BufBound_IsFull() | |
| Description: | |
| Tests whether an AEEBuffBound has overflowed. | |
| Prototype: | |
| int BufBound_IsFull(BufBound* me); | |
| Parameters: | |
| me: the BufBound | |
| Return Value: | |
| 1 if the BufBound has overflowed, 0 otherwise | |
| Comments: | |
| None | |
| Side Effects: | |
| None | |
| See Also: | |
| None | |
| ======================================================================= | |
| BufBound_WriteLE() | |
| Description: | |
| Writes data while translating numeric values between host byte ordering and | |
| "little endian" byte ordering. | |
| The input buffer is treated as an array of structures. The 'abySizes' | |
| parameter describes the sizes of fields in the structure. | |
| When the host byte ordering matches the target byte ordering (little | |
| endian) this operation is equivalent to BufBound_Write(). | |
| Prototype: | |
| void BufBound_WriteLE(BufBound* me, | |
| const void *pvSrc, int nSrcSize, | |
| const unsigned char *pszFields); | |
| Parameters: | |
| me: the BufBound | |
| pvSrc: the source buffer | |
| nSrcSize: number of bytes to copy from the source buffer | |
| pszFields: Description of the fields that comprise the source data, | |
| as defined in std_CopyLE. | |
| Return Value: | |
| None | |
| See Also: | |
| BufBound_WriteBE, std_CopyLE | |
| ======================================================================= | |
| BufBound_WriteBE() | |
| Description: | |
| BufBounf_WriteBE() has the same semantics as BufBound_WriteLE() except it | |
| copies between host byte ordering and big-endian ("network") byte order. | |
| See BufBound_WriteLE() for more details. | |
| Prototype: | |
| void BufBound_WriteBE(BufBound* me, | |
| const void *pvSrc, int nSrcSize, | |
| const unsigned char *pszFields); | |
| Parameters: | |
| me: the BufBound | |
| pvSrc: the source buffer | |
| nSrcSize: number of bytes to copy from the source buffer | |
| pszFields: Description of the fields that comprise the source data, | |
| as defined in std_CopyLE. | |
| Return Value: | |
| None | |
| See Also: | |
| BufBound_WriteLE, std_CopyBE | |
| ======================================================================= */ | |
| #endif /* #ifndef AEEBUFBOUND_H */ | |