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