/** * 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 */