diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/AEEBufBound.h | 568 | ||||
-rw-r--r-- | include/AEEQList.h | 857 | ||||
-rw-r--r-- | include/AEEStdDef.h | 1149 | ||||
-rw-r--r-- | include/AEEStdErr.h | 225 | ||||
-rw-r--r-- | include/AEEVaList.h | 115 | ||||
-rw-r--r-- | include/AEEatomic.h | 197 | ||||
-rw-r--r-- | include/AEEstd.h | 2609 | ||||
-rw-r--r-- | include/adsp_current_process.h | 76 | ||||
-rw-r--r-- | include/adsp_default_listener.h | 63 | ||||
-rw-r--r-- | include/adsp_listener.h | 79 | ||||
-rw-r--r-- | include/apps_mem.h | 67 | ||||
-rw-r--r-- | include/apps_remotectl.h | 75 | ||||
-rw-r--r-- | include/apps_std.h | 170 | ||||
-rw-r--r-- | include/fastrpc_apps_user.h | 38 | ||||
-rw-r--r-- | include/fastrpc_internal.h | 312 | ||||
-rw-r--r-- | include/listener.h | 50 | ||||
-rw-r--r-- | include/listener_buf.h | 143 | ||||
-rw-r--r-- | include/mod_table_imp.h | 500 | ||||
-rw-r--r-- | include/pthread_rw_mutex.h | 60 | ||||
-rw-r--r-- | include/qtest_stdlib.h | 123 | ||||
-rw-r--r-- | include/remote.h | 186 | ||||
-rw-r--r-- | include/remote64.h | 83 | ||||
-rw-r--r-- | include/remotectl.h | 77 | ||||
-rw-r--r-- | include/rpcmem.h | 138 | ||||
-rw-r--r-- | include/sbuf.h | 158 | ||||
-rw-r--r-- | include/shared.h | 77 | ||||
-rw-r--r-- | include/uthash.h | 915 | ||||
-rw-r--r-- | include/verify.h | 131 | ||||
-rw-r--r-- | include/version.h | 129 |
29 files changed, 9370 insertions, 0 deletions
diff --git a/include/AEEBufBound.h b/include/AEEBufBound.h new file mode 100644 index 0000000..4146ba6 --- /dev/null +++ b/include/AEEBufBound.h @@ -0,0 +1,568 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 */ + diff --git a/include/AEEQList.h b/include/AEEQList.h new file mode 100644 index 0000000..f3346e0 --- /dev/null +++ b/include/AEEQList.h @@ -0,0 +1,857 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. +*/ +/*=========================================================================== + +FILE: AEEQList.h + +GENERAL DESCRIPTION: Doubly-linked circular list implementation + +===========================================================================*/ +#ifndef _AEEQLIST_H_ +#define _AEEQLIST_H_ + + +typedef struct QNode QNode; +struct QNode +{ + QNode *pNext; + QNode *pPrev; +}; + +#define QLIST_DEFINE_INIT(f) QList f = { { &f.n, &f.n } } + +typedef struct QList QList; +struct QList +{ + QNode n; +}; + + + +static __inline void QNode_InsPrev(QNode *me, QNode *pn) +{ + QNode *pPrev = me->pPrev; + + pn->pNext = me; + pn->pPrev = pPrev; + pPrev->pNext = pn; + me->pPrev = pn; +} + + +static __inline void QNode_InsNext(QNode *me, QNode *pn) +{ + QNode *pNext = me->pNext; + + pn->pPrev = me; + pn->pNext = pNext; + pNext->pPrev = pn; + me->pNext = pn; +} + + + +static __inline void QNode_Dequeue(QNode *me) +{ + QNode *pNext = me->pNext; + QNode *pPrev = me->pPrev; + + pPrev->pNext = pNext; + pNext->pPrev = pPrev; +} + +static __inline void QNode_CtorZ(QNode *me) +{ + me->pNext = me->pPrev = 0; +} + +static __inline int QNode_IsQueuedZ(QNode *me) +{ + return (0 != me->pNext); +} + +static __inline void QNode_DequeueZ(QNode *me) +{ + if (QNode_IsQueuedZ(me)) + { + QNode_Dequeue(me); + me->pNext = me->pPrev = 0; + } +} + +//-------------------------------------------------------------------- +//-- QList functions ---------------------------------------------- +//-------------------------------------------------------------------- + + +static __inline void QList_Zero(QList *me) +{ + me->n.pNext = me->n.pPrev = &me->n; +} + + +static __inline void QList_Ctor(QList *me) +{ + QList_Zero(me); +} + + +static __inline int QList_IsEmpty(QList *me) +{ + return me->n.pNext == &me->n; +} + +static __inline int QList_IsNull(QList *me) +{ + return ((0 == me->n.pNext) && (0 == me->n.pPrev)); +} + + +static __inline void QList_AppendNode(QList *me, QNode *pn) +{ + QNode_InsPrev(&me->n, pn); +} + + +static __inline void QList_PrependNode(QList *me, QNode *pn) +{ + QNode_InsNext(&me->n, pn); +} + + +static __inline void QList_CtorFrom(QList *me, QList *psrc) +{ + QNode *s = &psrc->n; + QNode *d = &me->n; + + s->pNext->pPrev = d; + d->pPrev = s->pPrev; + d->pNext = s->pNext; + s->pPrev->pNext = d; + + QList_Zero(psrc); +} + + + +static __inline void QList_AppendList(QList *me, QList *psrc) +{ + QNode *s = &psrc->n; + QNode *d = &me->n; + QNode *dp = d->pPrev; + QNode *sn = s->pNext; + QNode *sp; + + sn->pPrev = dp; + dp->pNext = sn; + d->pPrev = (sp = s->pPrev); + sp->pNext = d; + + QList_Zero(psrc); +} + + +#define QLIST_FOR_ALL(pList, pNode) \ + for ((pNode) = (pList)->n.pNext; \ + (pNode) != &(pList)->n; \ + (pNode) = (pNode)->pNext) + +#define QLIST_FOR_REST(pList, pNode) \ + for (; \ + (pNode) != &(pList)->n; \ + (pNode) = (pNode)->pNext) + +#define QLIST_REV_FOR_ALL(pList, pNode) \ + for ((pNode) = (pList)->n.pPrev; \ + (pNode) != &(pList)->n; \ + (pNode) = (pNode)->pPrev) + +#define QLIST_REV_FOR_REST(pList, pNode) \ + for (; \ + (pNode) != &(pList)->n; \ + (pNode) = (pNode)->pPrev) + +/* Allows dequeing QNodes during iteration */ +#define QLIST_NEXTSAFE_FOR_ALL(pList, pNode, pNodeNext) \ + for ((pNode) = (pList)->n.pNext, (pNodeNext) = (pNode)->pNext; \ + (pNode) != &(pList)->n; \ + (pNode) = (pNodeNext), (pNodeNext) = (pNode)->pNext) + +static __inline QNode *QList_GetFirst(QList *me) +{ + QNode *pn = me->n.pNext; + + return (pn == &me->n ? 0 : pn); +} + +static __inline QNode *QList_GetLast(QList *me) +{ + QNode *pn = me->n.pPrev; + + return (pn == &me->n ? 0 : pn); +} + +static __inline QNode *QList_Pop(QList *me) +{ + QNode *pn = me->n.pNext; + QNode *pnn = pn->pNext; + + me->n.pNext = pnn; + pnn->pPrev = &me->n; + + return (pn == &me->n ? 0 : pn); +} + +static __inline QNode *QList_PopZ(QList *me) +{ + QNode *pn = QList_Pop(me); + if (0 != pn) + { + QNode_CtorZ(pn); + } + return pn; +} + +static __inline QNode *QList_PopLast(QList *me) +{ + QNode *pp = me->n.pPrev; + QNode *ppp = pp->pPrev; + + me->n.pPrev = ppp; + ppp->pNext = &me->n; + + return (pp == &me->n ? 0 : pp); +} + +static __inline QNode *QList_PopLastZ(QList *me) +{ + QNode *pn = QList_PopLast(me); + if (0 != pn) + { + QNode_CtorZ(pn); + } + return pn; +} + +/*===================================================================== +======================================================================= +DATA STRUCTURE DOCUMENTATION +======================================================================= + +QNode + +Description: + Qnode is the structure that is queued. One or more Qnodes may be + embedded in other structures. An object can contain multiple QNodes if + it needs to be in different lists at the same time. + +Definition: + + typedef struct QNode QNode; + struct QNode { + QNode *pNext; + QNode *pPrev; + }; + +Members: + +See Also: + +======================================================================= + +QList + +Description: + QList keeps a doubly-linked list of QNode structures. + Each queue is represented by a 'head' node, not a head pointer, + simplifying and streamlining many operations. + Because it is doubly-linked it permits constant-time insertion or removal + of items or of entire queues. + Because it is circular it permits constant-time operations at both the + tail and the head of the queue. Circularity also streamlines some + operations by eliminating conditional branches. + + General rules: + QLists are always in a defined state; they should be constructed + before use, using one of the supplied Ctor...() functions. + QNodes do not track queued vs. unqueued state. The client should + never dequeue an un-queued node or queue an already-queued node. + When not queued, QNode internal state is undefined. A client may + implement marking and assertion externally. + +Definition: + + typedef struct QList QList; + struct QList { + QNode n; + }; + +Members: + +See Also: + +======================================================================= +INTERFACE DOCUMENTATION +======================================================================= +QNode Interface + + QNode is a statically-linked interface. + +======================================================================= +QNode_CtorZ() + +Description: + Zero initialize a QNode. + +Prototype: + + void QNode_CtorZ(QNode *me); + +Parameters: + me: the QNode + +Return Value: + None + +Comments: + None + +Side Effects: + None + +See Also: + QNode_IsQueued(), QNode_DequeueZ(), QList_PopZ() + +======================================================================= +QNode_IsQueuedZ() + +Description: + Whether a QNode belongs in a Queue. + +Prototype: + + int QNode_IsQueuedZ(QNode *me); + +Parameters: + me: the QNode + +Return Value: + None + +Comments: + None + +Side Effects: + Does not work if a node needs to live at address 0x0. + +See Also: + QNode_CtorZ(), QNode_DequeueZ(), QList_PopZ() + +======================================================================= +QNode_DequeueZ() + +Description: + Dequeue a QNode if it is in a queue. Idempotent operation. + +Prototype: + + void QNode_DequeueZ(QNode *me); + +Parameters: + me: the QNode + +Return Value: + None + +Comments: + None + +Side Effects: + None + +See Also: + QNode_CtorZ(), QNode_IsQueued(), QList_PopZ() + +======================================================================= + +QNode_InsPrev() + +Description: + insert a node before this one. + +Prototype: + static __inline void QNode_InsPrev(QNode *me, QNode *pn) + +Parameters: + me: the QNode + pn: the node to be inserted. +Return Value: + None + +Comments: + None + +Side Effects: + None + +See Also: + None + +======================================================================= + +QNode_InsNext() + +Description: + insert a node after this one. + +Prototype: + static __inline void QNode_InsNext(QNode *me, QNode *pn) + +Parameters: + me: the QNode + pn: the node to be inserted. + +Return Value: + None + +Comments: + None + +Side Effects: + None + +See Also: + None + +======================================================================= +QNode_Dequeue() + +Description: + dequeue this node. + +Prototype: + static __inline void QNode_Dequeue(QNode *me) + +Parameters: + me: the QNode to be dequeued + +Return Value: + None + +Comments: + None + +Side Effects: + None + +See Also: + None + +======================================================================= +QList Interface + + QList is a statically-linked interface. It provides a Queue of + doubly linked nodes. + +======================================================================= +QList_Zero() + +Description: + discard all queued nodes. + +Prototype: + + void QList_Zero(QList *me) + +Parameters: + me: the QList + +Return Value: + None + +Comments: + None + +Side Effects: + None + +See Also: + None + +======================================================================= +QList_Ctor() + +Description: + Initialize a queue to an empty state + +Prototype: + + void QList_Ctor(QList *me) + +Parameters: + me: the QList + +Return Value: + None + +Comments: + None + +Side Effects: + None + +See Also: + None + +======================================================================= +QList_IsEmpty() + +Description: + Check whether queue is empty. + +Prototype: + + int QList_IsEmpty(QList *me) + +Parameters: + me: the QList + +Return Value: + TRUE if queue is empty. + +Comments: + None + +Side Effects: + None + +See Also: + None + +======================================================================= +QList_AppendNode() + +Description: + Append the node to the queue. Make it the last 'next' (and the + first 'prev') + +Prototype: + + void QList_AppendNode(QList *me, QNode *pn) + +Parameters: + me: the QList + pn: the node to append. + +Return Value: + None + +Comments: + None + +Side Effects: + None + +See Also: + None + +======================================================================= +QList_PrependNode() + +Description: + Prepend a node to the queue. Make it the first 'next' (and the + last 'prev'). + +Prototype: + + void QList_PrependNode(QList *me, QNode *pn) + +Parameters: + me: the QList + pn: the node to prepend. + +Return Value: + None + +Comments: + None + +Side Effects: + None + +See Also: + None + +======================================================================= +QList_CtorFrom() + +Description: + Move nodes from one queue to a newly constructed queue. + Weird aliasing voodoo allows this to work without conditional branches, even + when psrc is empty. In that case, "s->pNext->pPrev = d" overwrites s->pPrev with d, + so that "s->pPrev->pNext = d" will later overwrite d->pNext with d. + +Prototype: + + void QList_CtorFrom(QList *me, QList *psrc) + +Parameters: + me: the QList + psrc: the Qlist from + +Return Value: + None + +Comments: + None + +Side Effects: + None + +See Also: + None + +======================================================================= +QList_AppendList() + +Description: + Move all nodes from a source queue to the end of this queue. + Note that weird aliasing voodoo allows this to work without conditional + branches when psrc is empty. A summary: + + SNP = DP => SP = DP, because SNP aliases SP + DPN = SN => DPN = S + DP = SP => DP = DP, because SP was overwritten with DP + SPN = D => DPN = D + +Prototype: + + void QList_AppendList(QList *me, QList *psrc) + +Parameters: + me: the QList + psrc: the source Qlist. + +Return Value: + None + +Comments: + None + +Side Effects: + None + +See Also: + None + +======================================================================= +QList_GetFirst() + +Description: + Get the first item on the queue + +Prototype: + + QNode *QList_GetFirst(QList *me) + +Parameters: + me: the QList + +Return Value: + pointer to QNode or 0 if queue is empty. + +Comments: + None + +Side Effects: + None + +See Also: + QList_GetLast + +======================================================================= +QList_GetLast() + +Description: + Get the last item on the queue + +Prototype: + + QNode *QList_GetLast(QList *me) + +Parameters: + me: the QList + +Return Value: + pointer to QNode or 0 if queue is empty. + +Comments: + None + +Side Effects: + None + +See Also: + QList_GetFirst + +======================================================================= +QList_Pop() + +Description: + Remove and return the first item on the queue (FIFO). + +Prototype: + + QNode *QList_Pop(QList *me) + +Parameters: + me: the QList + +Return Value: + pointer to QNode or 0 if queue is empty + +Comments: + None + +Side Effects: + None + +See Also: + QNode_PopZ, QNode_PopLast(), QNode_PopLastZ, QNode_CtorZ(), QNode_IsQueued(), + QNode_DequeueZ() + +======================================================================= +QList_PopZ() + +Description: + Remove and return the first item on the queue (FIFO). Same as QList_Pop(), + except the node retured is zero-initialized. + +Prototype: + + QNode *QList_PopZ(QList *me) + +Parameters: + me: the QList + +Return Value: + pointer to QNode or 0 if queue is empty + +Comments: + None + +Side Effects: + None + +See Also: + QNode_Pop, QNode_PopLast(), QNode_PopLastZ, QNode_CtorZ(), QNode_IsQueued(), + QNode_DequeueZ() + +======================================================================= +QList_PopLast() + +Description: + Remove and return the first item on the queue (FILO). + +Prototype: + + QNode *QList_PopLast(QList *me) + +Parameters: + me: the QList + +Return Value: + pointer to QNode or 0 if queue is empty + +Comments: + None + +Side Effects: + None + +See Also: + QNode_PopLastZ, QNode_Pop(), QNode_PopZ, QNode_CtorZ(), QNode_IsQueued(), + QNode_DequeueZ() + +======================================================================= + +QList_IsNull() + +Description: +Checks if the QList is null or not. + +Prototype: +static __inline int QList_IsNull(QList *me) + +Parameters: + me: the QList + +Return Value: + True or False. + +Comments: + None + +Side Effects: + None + +See Also: + None + +======================================================================= + +QList_PopLastZ() + +Description: + Remove and return the first item on the queue (FILO). + Same as QList_PopLast(), except the node retured is zero-initialized. + +Prototype: + + QNode *QList_PopLastZ(QList *me) + +Parameters: + me: the QList + +Return Value: + pointer to QNode or 0 if queue is empty + +Comments: + None + +Side Effects: + None + +See Also: + QNode_Pop(), QNode_PopZ, QNode_CtorZ(), QNode_IsQueued(), QNode_DequeueZ() + +=====================================================================*/ +#endif // _AEEQLIST_H_ diff --git a/include/AEEStdDef.h b/include/AEEStdDef.h new file mode 100644 index 0000000..1baefd2 --- /dev/null +++ b/include/AEEStdDef.h @@ -0,0 +1,1149 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 AEESTDDEF_H +#define AEESTDDEF_H +/* +======================================================================= + +FILE: AEEStdDef.h + +DESCRIPTION: definition of basic types, constants, + preprocessor macros + +======================================================================= +*/ + +#include <stdint.h> + +#if defined(COMDEF_H) /* guards against a known re-definer */ +#define _BOOLEAN_DEFINED +#define _UINT32_DEFINED +#define _UINT16_DEFINED +#define _UINT8_DEFINED +#define _INT32_DEFINED +#define _INT16_DEFINED +#define _INT8_DEFINED +#define _UINT64_DEFINED +#define _INT64_DEFINED +#define _BYTE_DEFINED +#endif /* #if !defined(COMDEF_H) */ + +/* ----------------------------------------------------------------------- +** Standard Types +** ----------------------------------------------------------------------- */ + +/* The following definitions are the same accross platforms. This first +** group are the sanctioned types. +*/ +#ifndef _BOOLEAN_DEFINED +typedef unsigned char boolean; /* Boolean value type. */ +#define _BOOLEAN_DEFINED +#endif + +#ifndef _UINT32_DEFINED +typedef uint32_t uint32; /* Unsigned 32 bit value */ +#define _UINT32_DEFINED +#endif + +#ifndef _UINT16_DEFINED +typedef unsigned short uint16; /* Unsigned 16 bit value */ +#define _UINT16_DEFINED +#endif + +#ifndef _UINT8_DEFINED +typedef unsigned char uint8; /* Unsigned 8 bit value */ +#define _UINT8_DEFINED +#endif + +#ifndef _INT32_DEFINED +typedef int32_t int32; /* Signed 32 bit value */ +#define _INT32_DEFINED +#endif + +#ifndef _INT16_DEFINED +typedef signed short int16; /* Signed 16 bit value */ +#define _INT16_DEFINED +#endif + +#ifndef _INT8_DEFINED +typedef signed char int8; /* Signed 8 bit value */ +#define _INT8_DEFINED +#endif + +#if defined(__GNUC__) +#define __int64 long long +#endif + +#ifndef _UINT64_DEFINED +typedef unsigned __int64 uint64; /* Unsigned 64 bit value */ +#define _UINT64_DEFINED +#endif + +#ifndef _INT64_DEFINED +typedef __int64 int64; /* Signed 64 bit value */ +#define _INT64_DEFINED +#endif + +#ifndef _BYTE_DEFINED +typedef unsigned char byte; /* byte type */ +#define _BYTE_DEFINED +#endif + + +#ifndef _AEEUID_DEFINED +typedef uint32 AEEUID; +#define _AEEUID_DEFINED +#endif + +#ifndef _AEEIID_DEFINED +typedef uint32 AEEIID; +#define _AEEIID_DEFINED +#endif + +#ifndef _AEECLSID_DEFINED +typedef uint32 AEECLSID; +#define _AEECLSID_DEFINED +#endif + +#ifndef _AEEPRIVID_DEFINED +typedef uint32 AEEPRIVID; +#define _AEEPRIVID_DEFINED +#endif + +#ifndef _AECHAR_DEFINED +typedef uint16 AECHAR; +#define _AECHAR_DEFINED +#endif + +#ifndef _AEERESULT_DEFINED +typedef int AEEResult; +#define _AEERESULT_DEFINED +#endif + +/* ----------------------------------------------------------------------- +** Function Calling Conventions +** ----------------------------------------------------------------------- */ + +#ifndef CDECL +#ifdef _MSC_VER +#define CDECL __cdecl +#else +#define CDECL +#endif /* _MSC_VER */ +#endif /* CDECL */ + +/* ----------------------------------------------------------------------- +** Constants +** ----------------------------------------------------------------------- */ + +#ifndef TRUE +#define TRUE 1 /* Boolean true value. */ +#endif + +#ifndef FALSE +#define FALSE 0 /* Boolean false value. */ +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef MIN_INT8 +#define MIN_INT8 -128 +#endif +#ifndef MIN_INT16 +#define MIN_INT16 -32768 +#endif +#ifndef MIN_INT32 +#define MIN_INT32 (~0x7fffffff) /* -2147483648 is unsigned */ +#endif +#ifndef MIN_INT64 +#define MIN_INT64 (~0x7fffffffffffffffLL) /* -9223372036854775808 is unsigned */ +#endif + +#ifndef MAX_INT8 +#define MAX_INT8 127 +#endif +#ifndef MAX_INT16 +#define MAX_INT16 32767 +#endif +#ifndef MAX_INT32 +#define MAX_INT32 2147483647 +#endif +#ifndef MAX_INT64 +#define MAX_INT64 9223372036854775807LL +#endif + +#ifndef MAX_UINT8 +#define MAX_UINT8 255 +#endif +#ifndef MAX_UINT16 +#define MAX_UINT16 65535 +#endif +#ifndef MAX_UINT32 +#define MAX_UINT32 4294967295u +#endif +#ifndef MAX_UINT64 +#define MAX_UINT64 18446744073709551615uLL +#endif + +#ifndef MIN_AECHAR +#define MIN_AECHAR 0 +#endif +#ifndef MAX_AECHAR +#define MAX_AECHAR 65535 +#endif + + +/* ----------------------------------------------------------------------- +** Preprocessor helpers +** ----------------------------------------------------------------------- */ +#define __STR__(x) #x +#define __TOSTR__(x) __STR__(x) +#define __FILE_LINE__ __FILE__ ":" __TOSTR__(__LINE__) + +/* ----------------------------------------------------------------------- +** Types for code generated from IDL +** ----------------------------------------------------------------------- */ + +#ifndef __QIDL_WCHAR_T_DEFINED__ +#define __QIDL_WCHAR_T_DEFINED__ +typedef uint16 _wchar_t; +#endif + +/* __STRING_OBJECT__ will be deprecated in the future */ +#if !defined(__QIDL_STRING_OBJECT_DEFINED__) && !defined(__STRING_OBJECT__) +#define __QIDL_STRING_OBJECT_DEFINED__ +#define __STRING_OBJECT__ +typedef struct _cstring_s +{ + char *data; + int dataLen; + int dataLenReq; +} _cstring_t; + +typedef struct _wstring_s +{ + _wchar_t *data; + int dataLen; + int dataLenReq; +} _wstring_t; +#endif /* __QIDL_STRING_OBJECT_DEFINED__ */ + +/* +======================================================================= + DATA STRUCTURES DOCUMENTATION +======================================================================= + +boolean + +Description: + This type is used to express boolean values (TRUE or FALSE). + +Definition: + typedef unsigned char boolean + +See Also: + byte + int8 + int16 + int32 + int64 + uint32 + uint16 + uint8 + uint64 + +======================================================================= + +uint32 + +Description: + This is a 32-bit unsigned integer. + +Definition: + typedef uint32_t uint32 + +See Also: + boolean + byte + int8 + int16 + int32 + int64 + uint8 + uint16 + uint64 + +======================================================================= + +uint16 + +Description: + This is a 16-bit unsigned integer. + +Definition: + typedef unsigned short uint16 + +See Also: + boolean + byte + int8 + int16 + int32 + int64 + uint8 + uint32 + uint64 + +======================================================================= + +uint8 + +Description: + This is an 8-bit unsigned integer. + +Definition: + typedef unsigned char uint8 + +See Also: + boolean + byte + int8 + int16 + int32 + int64 + uint16 + uint32 + uint64 + +======================================================================= + +int32 + +Description: + This is a 32-bit signed integer. + +Definition: + typedef int32_t int32 + +See Also: + boolean + byte + int8 + int16 + int64 + uint8 + uint16 + uint32 + uint64 + +======================================================================= + +int16 + +Description: + This is a 16-bit signed integer. + +Definition: + typedef signed short int16 + +See Also: + boolean + byte + int8 + int32 + int64 + uint8 + uint16 + uint32 + uint64 + +======================================================================= + +int8 + +Description: + This is an 8-bit signed integer. + +Definition: + typedef signed char int8 + +See Also: + boolean + byte + int16 + int32 + int64 + uint8 + uint16 + uint32 + uint64 + +======================================================================= + +uint64 + +Description: + This is a 64-bit unsigned integer. + +Definition: + typedef unsigned __int64 uint64 + +See Also: + boolean + byte + int8 + int16 + int32 + int64 + uint8 + uint16 + uint32 + +======================================================================= + +int64 + +Description: + This is a 64-bit signed integer. + +Definition: + typedef __int64 int64 + +See Also: + boolean + byte + int8 + int16 + int32 + uint8 + uint16 + uint32 + uint64 + +======================================================================= + +byte + +Description: + This is a byte. + +Definition: + typedef unsigned char byte + +See Also: + boolean + int8 + int16 + int32 + int64 + uint8 + uint16 + uint32 + uint64 + +======================================================================= + +AEEUID + +Description: + This is a BREW unique ID. Used to express unique types, interfaces, classes + groups and privileges. The BREW ClassID Generator generates + unique IDs that can be used anywhere you need a new AEEIID, AEECLSID, + or AEEPRIVID. + +Definition: + typedef uint32 AEEUID + +See Also: + AECHAR + AEECLSID + AEEIID + AEEPRIVID + AEEResult + +======================================================================= + +AEEIID + +Description: + This is an interface ID type, used to denote a BREW interface. It is a special case + of AEEUID. + +Definition: + typedef uint32 AEEIID + +See Also: + AECHAR + AEECLSID + AEEPRIVID + AEEResult + AEEUID + +======================================================================= + +AEECLSID + +Description: + This is a classe ID type, used to denote a BREW class. It is a special case + of AEEUID. + +Definition: + typedef uint32 AEECLSID + +See Also: + AECHAR + AEECLSIDs + AEEIID + AEEPRIVID + AEEResult + AEEUID + +======================================================================= + +AEEPRIVID + +Description: + This is a privilege ID type, used to express a privilege. It is a special case + of AEEUID. + +Definition: + typedef uint32 AEEPRIVID + +See Also: + AECHAR + AEECLSID + AEEIID + AEEResult + AEEUID + +======================================================================= + +AECHAR + +Description: + This is a 16-bit character type. + +Definition: + typedef uint16 AECHAR + +See Also: + AEEPRIVID + AEECLSID + AEEIID + AEEResult + AEEUID + +======================================================================= + +AEEResult + +Description: + This is the standard result type. + +Definition: + typedef int AEEResult + +See Also: + AECHAR + AEEPRIVID + AEECLSID + AEEIID + AEEUID + +======================================================================= + +_wchar_t + +Description: + This is a 16-bit character type corresponding to the IDL 'wchar' + type. + +Definition: + typedef uint16 _wchar_t + +See Also: + _cstring_t + _wstring_t + +======================================================================= + +_cstring_t + +Description: + This structure is used to represent an IDL string when used inside a + sequence or union. + +Definition: + typedef struct _cstring_s { + char* data; + int dataLen; + int dataLenReq; + } _cstring_t; + +Members: + data : A pointer to the NULL-terminated string. + dataLen : The size, in chars, of the buffer pointed to by 'data', + including the NULL terminator. This member is only used + when the structure is part of an rout or inrout + parameter, but must be supplied by the caller as an + input in these cases. + dataLenReq : The size that would have been required to store the + entire result string. This member is only used when the + structure is part of an rout or inrout parameter, when + it is an output value set by the callee. The length of + the returned string (including the NULL terminator) + after a call is the minimum of dataLen and dataLenReq. + +See Also: + _wchar_t + _wstring_t + +======================================================================= + +_wstring_t + +Description: + This structure is used to represent an IDL wstring when used inside a + sequence or union. + +Definition: + typedef struct _wstring_s { + _wchar_t* data; + int dataLen; + int dataLenReq; + } _wstring_t; + +Members: + data : A pointer to the NULL-terminated wide string. + dataLen : The size, in 16-bit characters, of the buffer pointed to + by 'data', including the NULL terminator. This member + is only used when the structure is part of an rout or + inrout parameter, but must be supplied by the caller as + an input in these cases. + dataLenReq : The number of 16-bit characters that would have been + required to store the entire result string. This member + is only used when the structure is part of an rout or + inrout parameter, when it is an output value set by the + callee. The length of the returned wstring (including + the NULL terminator) after a call is the minimum of + dataLen and dataLenReq. + +See Also: + _cstring_t + _wchar_t + +======================================================================= +CONSTANTS DOCUMENTATION +======================================================================= + +TRUE + +Description: + TRUE is the boolean "true." + +Definition: + + #define TRUE 1 + +See Also: + FALSE + NULL + +======================================================================= + +FALSE + +Description: + FALSE is the boolean "false." + +Definition: + + #define FALSE 0 + +See Also: + NULL + TRUE + +======================================================================= + +NULL + +Description: + NULL is the null value, usually used to test a pointer. + +Definition: + + #define NULL 0 + +See Also: + FALSE + TRUE + +======================================================================= + +MIN_INT8 + +Description: + MIN_INT8 is the minimum signed 8-bit integer value. + +Definition: + + #define MIN_INT8 -128 + +See Also: + MAX_AECHAR + MAX_INT8 + MAX_INT16 + MAX_INT32 + MAX_INT64 + MAX_UINT8 + MAX_UINT16 + MAX_UINT32 + MAX_UINT64 + MIN_AECHAR + MIN_INT16 + MIN_INT32 + MIN_INT64 + +======================================================================= + +MIN_INT16 + +Description: + MIN_INT16 is the minimum signed 16-bit integer value + +Definition: + + #define MIN_INT16 -32768 + +See Also: + MAX_AECHAR + MAX_INT8 + MAX_INT16 + MAX_INT32 + MAX_INT64 + MAX_UINT8 + MAX_UINT16 + MAX_UINT32 + MAX_UINT64 + MIN_AECHAR + MIN_INT8 + MIN_INT32 + MIN_INT64 + +======================================================================= + +MIN_INT32 + +Description: + MIN_INT32 is the minimum signed 32-bit integer value. + +Definition: + + #define MIN_INT32 (~0x7fffffff) + +Comments: + Brew MP uses (~0x7fffffff), because -2147483648 is treated as unsigned by compilers. + +See Also: + MAX_AECHAR + MAX_INT8 + MAX_INT16 + MAX_INT32 + MAX_INT64 + MAX_UINT8 + MAX_UINT16 + MAX_UINT32 + MAX_UINT64 + MIN_AECHAR + MIN_INT8 + MIN_INT16 + MIN_INT64 + +======================================================================= + +MIN_INT64 + +Description: + MIN_INT64 is the minimum signed 64-bit integer value. + +Definition: + + #define MIN_INT64 (~0x7fffffffffffffffll) + +Comments: + Brew MP uses (~0x7fffffffffffffffll), because -9223372036854775808 is + treated as unsigned by compilers. + +See Also: + MAX_AECHAR + MAX_INT8 + MAX_INT16 + MAX_INT32 + MAX_INT64 + MAX_UINT8 + MAX_UINT16 + MAX_UINT32 + MAX_UINT64 + MIN_AECHAR + MIN_INT8 + MIN_INT16 + MIN_INT32 + +======================================================================= + +MAX_INT8 + +Description: + MAX_INT8 is the maximum signed 8-bit integer value + +Definition: + + #define MAX_INT8 127 + +See Also: + MAX_AECHAR + MAX_INT16 + MAX_INT32 + MAX_INT64 + MAX_UINT8 + MAX_UINT16 + MAX_UINT32 + MAX_UINT64 + MIN_AECHAR + MIN_INT8 + MIN_INT16 + MIN_INT32 + MIN_INT64 + +======================================================================= + +MAX_INT16 + +Description: + MAX_INT16 is the maximum signed 16-bit integer value. + +Definition: + + #define MAX_INT16 32767 + +See Also: + MAX_AECHAR + MAX_INT8 + MAX_INT32 + MAX_INT64 + MAX_UINT8 + MAX_UINT16 + MAX_UINT32 + MAX_UINT64 + MIN_AECHAR + MIN_INT8 + MIN_INT16 + MIN_INT32 + MIN_INT64 + +======================================================================= + +MAX_INT32 + +Description: + MAX_INT32 is the maximum signed 32-bit integer value. + +Definition: + + #define MAX_INT32 2147483647 + +See Also: + MAX_AECHAR + MAX_INT8 + MAX_INT16 + MAX_INT64 + MAX_UINT8 + MAX_UINT16 + MAX_UINT32 + MAX_UINT64 + MIN_AECHAR + MIN_INT8 + MIN_INT16 + MIN_INT32 + MIN_INT64 + +======================================================================= + +MAX_INT64 + +Description: + MAX_INT64 is the maximum signed 64-bit integer value. + +Definition: + + #define MAX_INT64 9223372036854775807ll + +See Also: + MAX_AECHAR + MAX_INT8 + MAX_INT16 + MAX_INT32 + MAX_UINT8 + MAX_UINT16 + MAX_UINT32 + MAX_UINT64 + MIN_AECHAR + MIN_INT8 + MIN_INT16 + MIN_INT32 + MIN_INT64 + +======================================================================= + +MAX_UINT8 + +Description: + MAX_UINT8 is the maximum unsigned 8-bit integer value. + +Definition: + + #define MAX_UINT8 255 + +See Also: + MAX_AECHAR + MAX_INT8 + MAX_INT16 + MAX_INT32 + MAX_INT64 + MAX_UINT16 + MAX_UINT32 + MAX_UINT64 + MIN_AECHAR + MIN_INT8 + MIN_INT16 + MIN_INT32 + MIN_INT64 + +======================================================================= + +MAX_UINT16 + +Description: + MAX_UINT16 is the maximum unsigned 16-bit integer value. + +Definition: + + #define MAX_UINT16 65535 + +See Also: + MAX_AECHAR + MAX_INT8 + MAX_INT16 + MAX_INT32 + MAX_INT64 + MAX_UINT8 + MAX_UINT32 + MAX_UINT64 + MIN_AECHAR + MIN_INT8 + MIN_INT16 + MIN_INT32 + MIN_INT64 + +======================================================================= + +MAX_UINT32 + +Description: + MAX_UINT32 is the maximum unsigned 32-bit integer value. + +Definition: + + #define MAX_UINT32 4294967295u + +See Also: + MAX_AECHAR + MAX_INT8 + MAX_INT16 + MAX_INT32 + MAX_INT64 + MAX_UINT8 + MAX_UINT16 + MAX_UINT64 + MIN_AECHAR + MIN_INT8 + MIN_INT16 + MIN_INT32 + MIN_INT64 + +======================================================================= + +MAX_UINT64 + +Description: + MAX_UINT64 is the maximum unsigned 64-bit integer value. + +Definition: + + #define MAX_UINT64 18446744073709551615ull + +See Also: + MAX_AECHAR + MAX_INT8 + MAX_INT16 + MAX_INT32 + MAX_INT64 + MAX_UINT8 + MAX_UINT16 + MAX_UINT32 + MIN_AECHAR + MIN_INT8 + MIN_INT16 + MIN_INT32 + MIN_INT64 + +======================================================================= + +MIN_AECHAR + +Description: + MIN_AECHAR is the minimum AECHAR value. + +Definition: + + #define MIN_AECHAR 0 + +See Also: + MAX_AECHAR + MAX_INT8 + MAX_INT16 + MAX_INT32 + MAX_INT64 + MAX_UINT8 + MAX_UINT16 + MAX_UINT32 + MAX_UINT64 + MIN_INT8 + MIN_INT16 + MIN_INT32 + MIN_INT64 + +======================================================================= + +MAX_AECHAR + +Description: + MAX_AECHAR is the maximum AECHAR value. + +Definition: + + #define MAX_AECHAR 65535 + +See Also: + MIN_AECHAR + MAX_INT8 + MAX_INT16 + MAX_INT32 + MAX_INT64 + MAX_UINT8 + MAX_UINT16 + MAX_UINT32 + MAX_UINT64 + MIN_INT8 + MIN_INT16 + MIN_INT32 + MIN_INT64 + +======================================================================= +MACROS DOCUMENTATION +======================================================================= + +__STR__() + +Description: + The __STR__() makes a token into a string, used to string-ize things already + defined. + +Definition: + + #define __STR__(x) #x + +Parameters: + x: token to make into a string + +See Also: + __TOSTR__() + __FILE_LINE__ + +======================================================================= + +__TOSTR__() + +Description: + The __TOSTR__() makes a token's value into a string, used to string-ize things + already defined, used with __STR__. + +Definition: + + #define __TOSTR__(x) __STR__(x) + +Parameters: + x: token to evaluate and string-ize + +Evaluation Value: + the token's replacement as a string + +See Also: + __FILE_LINE__ + __STR__() + +======================================================================= + +__FILE_LINE__ + +Description: + The compiler's __FILE__ (a string) and __LINE__ (an integer) are pasted + together as a single string with a ":" between. + +Definition: + + #define __FILE_LINE__ __FILE__ ":" __TOSTR__(__LINE__) + +Evaluation Value: + __FILE__":""__LINE__" + +See Also: + __STR__() + __TOSTR__() + +======================================================================= +*/ + +#endif /* #ifndef AEESTDDEF_H */ + diff --git a/include/AEEStdErr.h b/include/AEEStdErr.h new file mode 100644 index 0000000..c93ac49 --- /dev/null +++ b/include/AEEStdErr.h @@ -0,0 +1,225 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 AEESTDERR_H +#define AEESTDERR_H + +// +// Basic Error Codes +// +// + +#define AEE_SUCCESS 0 // no error +#define AEE_EFAILED 1 // general failure +#define AEE_ENOMEMORY 2 // insufficient RAM +#define AEE_ECLASSNOTSUPPORT 3 // specified class unsupported +#define AEE_EVERSIONNOTSUPPORT 4 // version not supported +#define AEE_EALREADYLOADED 5 // object already loaded +#define AEE_EUNABLETOLOAD 6 // unable to load object/applet +#define AEE_EUNABLETOUNLOAD 7 // unable to unload object/applet +#define AEE_EALARMPENDING 8 // alarm is pending +#define AEE_EINVALIDTIME 9 // invalid time +#define AEE_EBADCLASS 10 // NULL class object +#define AEE_EBADMETRIC 11 // invalid metric specified +#define AEE_EEXPIRED 12 // App/Component Expired +#define AEE_EBADSTATE 13 // invalid state +#define AEE_EBADPARM 14 // invalid parameter +#define AEE_ESCHEMENOTSUPPORTED 15 // invalid URL scheme +#define AEE_EBADITEM 16 // invalid item +#define AEE_EINVALIDFORMAT 17 // invalid format +#define AEE_EINCOMPLETEITEM 18 // incomplete item +#define AEE_ENOPERSISTMEMORY 19 // insufficient flash +#define AEE_EUNSUPPORTED 20 // API is not supported +#define AEE_EPRIVLEVEL 21 // privileges are insufficient for this operation +#define AEE_ERESOURCENOTFOUND 22 +#define AEE_EREENTERED 23 +#define AEE_EBADTASK 24 +#define AEE_EALLOCATED 25 // App/Module left memory allocated when released +#define AEE_EALREADY 26 // operation is already in progress +#define AEE_EADSAUTHBAD 27 // ADS mutual authorization failed +#define AEE_ENEEDSERVICEPROG 28 // need service programming +#define AEE_EMEMPTR 29 // bad memory pointer +#define AEE_EHEAP 30 // heap corruption +#define AEE_EIDLE 31 // context (system, interface, etc.) is idle +#define AEE_EITEMBUSY 32 // context (system, interface, etc.) is busy +#define AEE_EBADSID 33 // invalid subscriber ID +#define AEE_ENOTYPE 34 // no type detected/found +#define AEE_ENEEDMORE 35 // need more data/info +#define AEE_EADSCAPS 36 // ADS Capabilities do not match those required for phone +#define AEE_EBADSHUTDOWN 37 // App failed to close properly +#define AEE_EBUFFERTOOSMALL 38 // destination buffer given is too small +#define AEE_ENOSUCH 39 // no such name/port/socket/service exists or valid +#define AEE_EACKPENDING 40 // ACK pending on application +#define AEE_ENOTOWNER 41 // not an owner authorized to perform the operation +#define AEE_EINVALIDITEM 42 // current item is invalid +#define AEE_ENOTALLOWED 43 // not allowed to perform the operation +#define AEE_EBADHANDLE 44 // invalid handle +#define AEE_EOUTOFHANDLES 45 // out of handles +#define AEE_EINTERRUPTED 46 // waitable call is interrupted +#define AEE_ENOMORE 47 // no more items available -- reached end +#define AEE_ECPUEXCEPTION 48 // a CPU exception occurred +#define AEE_EREADONLY 49 // Cannot change read-only object or parameter +// a moratorium on adding to AEEStdErr.h is in effect, 50 and later are +// already spoken for + +#define AEE_EWOULDBLOCK 516 // Operation would block if not non-blocking; wait and try again + +/* +============================================================================ + ERRORS DOCUMENTATION +============================================================================== + +Error Codes + +Description: +This topic lists the categories of error codes that Brew MP returns. The topic for each +category of error code includes the name of each error, the code that is associated with +the error, and a description of the error. + +===H2> +List of Error Code Types +===/H2> +===p> +The categories of error codes include: ~ +~ + +AddrBook error codes ~ +AddrInfo error codes ~ +AEE_IS_REMOTE_ERR(): ~ +AEE_IS_REMOTE_ERR_PRE(): ~ +Basic AEE Error Codes ~ +Database error codes ~ +dbc Error Codes ~ +DNS Resolver error codes ~ +File error codes ~ +FS AEE Error Codes ~ +ICamera error codes ~ +ICMP error codes ~ +ILicenseSystem Error Codes ~ +Indeterminate errors: (transport failure) ~ +ISQL Error Codes ~ +ISVGDOM Error Codes: ~ +ISSL error codes ~ +IX509Chain error codes ~ +ModCollector Errors ~ +ModInstallerCntx Errors ~ +ModMover Errors ~ +Multimedia error codes ~ +Network AEE error codes ~ +Network subsystem error codes ~ +pim_IMessageStore Error Codes ~ +pim_IRecordStore Error Codes ~ +Port AEE Error Codes ~ +PosDet error codes ~ +Post-invocation errors: (remote errors) ~ +Pre-invocation errors: (remote errors) ~ +QoS error codes ~ +Remote error codes: ~ +SSL error codes ~ +VOCODER error codes ~ +VolumeDB Errors ~ +Web error codes ~ + +* + +================================================================== +Basic AEE Error Codes + +Description: +This section lists the set of basic AEE errors returned, the codes associated +with the errors, and descriptions of the errors. + +Definition: + +Error Code Description + +AEE_SUCCESS 0 operation Successful +AEE_EFAILED 1 general failure +AEE_ENOMEMORY 2 insufficient RAM +AEE_ECLASSNOTSUPPORT 3 specified class unsupported +AEE_EVERSIONNOTSUPPORT 4 version not supported +AEE_EALREADYLOADED 5 object already loaded +AEE_EUNABLETOLOAD 6 unable to load object/applet +AEE_EUNABLETOUNLOAD 7 unable to unload object/applet +AEE_EALARMPENDING 8 alarm is pending +AEE_EINVALIDTIME 9 invalid time +AEE_EBADCLASS 10 NULL class object +AEE_EBADMETRIC 11 invalid metric specified +AEE_EEXPIRED 12 Application/Component Expired +AEE_EBADSTATE 13 invalid state +AEE_EBADPARM 14 invalid parameter +AEE_ESCHEMENOTSUPPORTED 15 invalid URL scheme +AEE_EBADITEM 16 invalid item +AEE_EINVALIDFORMAT 17 invalid format +AEE_EINCOMPLETEITEM 18 incomplete item +AEE_ENOPERSISTMEMORY 19 insufficient flash +AEE_EUNSUPPORTED 20 API is not supported +AEE_EPRIVLEVEL 21 application privileges are insufficient for this operation +AEE_ERESOURCENOTFOUND 22 unable to find specified resource +AEE_EREENTERED 23 non re-entrant API re-entered +AEE_EBADTASK 24 API called in wrong task context +AEE_EALLOCATED 25 Application/Module left memory allocated when released +AEE_EALREADY 26 operation is already in progress +AEE_EADSAUTHBAD 27 ADS mutual authorization failed +AEE_ENEEDSERVICEPROG 28 need service programming +AEE_EMEMPTR 29 bad memory pointer +AEE_EHEAP 30 heap corruption +AEE_EIDLE 31 context (system, interface, etc.) is idle +AEE_EITEMBUSY 32 context (system, interface, etc.) is busy +AEE_EBADSID 33 invalid subscriber ID +AEE_ENOTYPE 34 no type detected/found +AEE_ENEEDMORE 35 need more data/info +AEE_EADSCAPS 36 capabilities do not match those required +AEE_EBADSHUTDOWN 37 application failed to close properly +AEE_EBUFFERTOOSMALL 38 destination buffer given is too small +AEE_ENOSUCH 39 no such name/port/socket/service exists or valid +AEE_EACKPENDING 40 ACK pending on application +AEE_ENOTOWNER 41 not an owner authorized to perform the operation +AEE_EINVALIDITEM 42 current item is invalid +AEE_ENOTALLOWED 43 not allowed to perform the operation +AEE_EBADHANDLE 44 invalid handle +AEE_EOUTOFHANDLES 45 out of handles +AEE_EINTERRUPTED 46 waitable call is interrupted +AEE_ENOMORE 47 no more items available -- reached end +AEE_ECPUEXCEPTION 48 a CPU exception occurred +AEE_EREADONLY 49 cannot change read-only object or parameter +AEE_EWOULDBLOCK 516 operation would block if not non-blocking; wait and try again + +Comments: +These Brew MP error codes have an up-to-date naming convention, and replace older BREW error +codes that use a naming convention that did not include the "AEE_" prefix. + +See Also: + Error Codes + +================================================================== +*/ +#endif /* #ifndef AEESTDERR_H */ + diff --git a/include/AEEVaList.h b/include/AEEVaList.h new file mode 100644 index 0000000..3bf3204 --- /dev/null +++ b/include/AEEVaList.h @@ -0,0 +1,115 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 AEEVALIST_H +#define AEEVALIST_H + +#if defined(__ARMCC_VERSION) || (defined(__GNUC__) && defined(__arm__)) + +#if (defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 200000 && !defined(__APCS_ADSABI)) || \ + (defined(__GNUC__) && defined(__arm__) && defined(__ARM_EABI__)) + +# define __AEEVA_ATPCS 0 + +#else + +# define __AEEVA_ATPCS 1 + +#endif + +typedef void *AEEVaList; + +#define __AEEVA_ARGALIGN(t) (((char*)(&((struct{char c;t x;}*)1)->x))-((char*)1)) +#define __AEEVA_ARGSIZE(t) ((sizeof(t)+sizeof(int)-1) & ~(sizeof(int)-1)) + +static __inline void __cpy(char *d, const char *s, int len) +{ + while (len-- > 0) + *d++ = *s++; +} + +static __inline AEEVaList __AEEVa_Arg(AEEVaList args, void *pv, int nVSize, + int nArgSize, int nArgAlign) +{ + int nArgs = (int)args & ~1; + char *pcArgs = (char *)args; + int bATPCS = (int)args & 1; + int nArgsOffset = 0; + int nVOffset = 0; + + if (!bATPCS) /* caller was compiled with AAPCS */ + { + + if (nArgAlign > (int)sizeof(int)) + { + nArgAlign--; /* make a mask */ + pcArgs += ((nArgs + nArgAlign) & (int)~(unsigned)nArgAlign) - nArgs; + /* move pv to next alignment */ + } + } + +#if defined(AEE_BIGENDIAN) + if (nArgSize < (int)sizeof(int)) + { + nArgsOffset = (int)sizeof(int) - nArgSize; + } + nVOffset = nVSize - nArgSize; +#else + (void)nVSize; +#endif /* AEE_BIGENDIAN */ + + __cpy((char *)pv + nVOffset, (pcArgs - bATPCS) + nArgsOffset, nArgSize); + + /* round up */ + nArgSize = (nArgSize + (int)sizeof(int) - 1) & ~((int)sizeof(int) - 1); + + return pcArgs + nArgSize; /* increment va */ +} + +#define AEEVA_START(va,v) ((va) = (char*)&(v) + __AEEVA_ARGSIZE(v) + __AEEVA_ATPCS) +#define AEEVA_ARG(va,v,t) ((void)((va) = __AEEVa_Arg(va,&v,sizeof(v),sizeof(t),__AEEVA_ARGALIGN(t)))) +#define AEEVA_END(va) ((va) = (AEEVaList)0) +#define AEEVA_COPY(dest, src) ((void)((dest) = (src))) + +#else /* defined(__ARMCC_VERSION) || (defined(__GNUC__) && defined(__arm__)) */ + +#include <stdarg.h> + +typedef va_list AEEVaList; + +#define AEEVA_START(va,v) (va_start((va), (v))) +#define AEEVA_ARG(va,v,t) ((v) = va_arg((va),t)) +#define AEEVA_END(va) (va_end((va))) +#define AEEVA_COPY(dest, src) (va_copy((dest),(src))) + +#endif/* defined(__ARMCC_VERSION) || (defined(__GNUC__) && defined(__arm__)) */ + +#endif /* #ifndef AEEVALIST_H */ + diff --git a/include/AEEatomic.h b/include/AEEatomic.h new file mode 100644 index 0000000..2911455 --- /dev/null +++ b/include/AEEatomic.h @@ -0,0 +1,197 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 AEEATOMIC_H +#define AEEATOMIC_H +/* +======================================================================= + +FILE: AEEatomic.h + +SERVICES: atomic + +DESCRIPTION: Fast Atomic ops + +======================================================================= +*/ + +#include "AEEStdDef.h" + +#ifdef __cplusplus +extern "C" { +#endif /* #ifdef __cplusplus */ + +uint32 atomic_Add(uint32 *volatile puDest, int nAdd); +uint32 atomic_Exchange(uint32 *volatile puDest, uint32 uVal); +uint32 atomic_CompareAndExchange(uint32 *volatile puDest, uint32 uExchange, uint32 uCompare); +uint32 atomic_CompareOrAdd(uint32 *volatile puDest, uint32 uCompare, int nAdd); + +#ifdef __cplusplus +} +#endif /* #ifdef __cplusplus */ + +/*===================================================================== +INTERFACE DOCUMENTATION +======================================================================= +atomic Interface + + The atomic interface provides fast "atomic" operations. The + operations are defined to be atomic with respect to each other. + +======================================================================= + +======================================================================= + +atomic_Add() + +Description: + + Performs an atomic sum operation. + +Prototype: + + uint32 atomic_Add(uint32* puDest, int nInc); + +Parameters: + puDest [in|out] : Points to unsigned number to add nInc and save + nInc : increment + +Return Value: + result. + +Comments: + None + +Side Effects: + None + +See Also: + None + +======================================================================= + +atomic_Exchange() + +Description: + + Atomic exchange of 32bit value. Performs an atomic operation of : + write uVal to *puDest + return the previous value in *puDest + +Prototype: + + uint32 atomic_Exchange(uint32* puDest, uint32 uVal); + +Parameters: + puDest [in|out] : Points to unsigned number to be exchanged + uVal : new value to write. + +Return Value: + previous value at *puDest. + +Comments: + None + +Side Effects: + May cause exception if puDest is not a 32 bit aligned address. + +See Also: + None +======================================================================= + +atomic_CompareAndExchange() + +Description: + + Performs an atomic operation of : + if (*puDest == uCompare) { + *puDest = uExchange; + } + + returns the previous value in *puDest + +Prototype: + + uint32 atomic_CompareAndExchange(uint32 *puDest, uint32 uExchange, + uint32 uCompare); + +Parameters: + puDest [in|out] : Points to unsigned number. + uExchange : A new value to write to *puDest + uCompare : Comparand + +Return Value: + previous value at *puDest. + +Comments: + None + +Side Effects: + May cause exception if puDest is not a 32 bit aligned address. + +See Also: + None + +======================================================================= +atomic_CompareOrAdd() + +Description: + + Performs an atomic operation of : + if (*puDest != uCompare) { + *puDest += nAdd; + } + + returns the new value in *puDest + +Prototype: + + uint32 atomic_CompareOrAdd(uint32 *puDest, uint32 uCompare, int nAdd); + +Parameters: + puDest [in|out] : Points to unsigned number. + uCompare : Comparand + nAdd : Add to *puDest + +Return Value: + new value at *puDest. + +Comments: + None + +Side Effects: + May cause exception if puDest is not a 32 bit aligned address. + +See Also: + None +=======================================================================*/ + +#endif /* #ifndef AEEATOMIC_H */ + diff --git a/include/AEEstd.h b/include/AEEstd.h new file mode 100644 index 0000000..2cfc653 --- /dev/null +++ b/include/AEEstd.h @@ -0,0 +1,2609 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 AEESTD_H +#define AEESTD_H +/*==================================================================== + +DESCRIPTION: Standard library; general-purpose utility functions. + +====================================================================*/ +#include "AEEVaList.h" +#include "AEEStdDef.h" + +#define STD_CONSTRAIN( val, min, max ) (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val)) +#define STD_BETWEEN( val, minGE, maxLT ) \ + ( (unsigned long)((unsigned long)(val) - (unsigned long)(minGE)) < \ + (unsigned long)((unsigned long)(maxLT) - (unsigned long)(minGE)) ) +#define STD_ARRAY_SIZE(a) ((int)((sizeof((a))/sizeof((a)[0])))) +#define STD_ARRAY_MEMBER(p,a) (((p) >= (a)) && ((p) < ((a) + STD_ARRAY_SIZE(a)))) + +#define STD_SIZEOF(x) ((int)sizeof(x)) +#define STD_OFFSETOF(type,member) (((char*)(&((type*)1)->member))-((char*)1)) + +#define STD_RECOVER_REC(type,member,p) ((void)((p)-&(((type*)1)->member)),\ + (type*)(void*)(((char*)(void*)(p))-STD_OFFSETOF(type,member))) +#define STD_MIN(a,b) ((a)<(b)?(a):(b)) +#define STD_MAX(a,b) ((a)>(b)?(a):(b)) +//lint -emacro(545,STD_ZEROAT) +#define STD_ZEROAT(p) std_memset((p), 0, sizeof(*p)) + +#define _STD_BITS_PER(bits) (8*sizeof((bits)[0])) + +#define STD_BIT_SET(bits, ix) ((bits)[(ix)/_STD_BITS_PER((bits))] |= 0x1<<((ix) & (_STD_BITS_PER((bits))-1))) +#define STD_BIT_CLEAR(bits, ix) ((bits)[(ix)/_STD_BITS_PER((bits))] &= ~(0x1<<((ix) & (_STD_BITS_PER((bits))-1)))) +#define STD_BIT_TEST(bits, ix) ((bits)[(ix)/_STD_BITS_PER((bits))] & (0x1<<((ix) & (_STD_BITS_PER((bits))-1)))) + +// +// Error codes +// +#define STD_NODIGITS 1 +#define STD_NEGATIVE 2 +#define STD_OVERFLOW 3 +#define STD_BADPARAM 4 +#define STD_UNDERFLOW 5 + +#ifdef __cplusplus +extern "C" { +#endif /* #ifdef __cplusplus */ + +//Version function +extern int std_getversion(char *pcDst, int nDestSize); + +//String functions +extern int std_strlen(const char *s); +extern int std_strcmp(const char *s1, const char *s2); +extern int std_strncmp(const char *s1, const char *s2, int n); +extern int std_stricmp(const char *s1, const char *s2); +extern int std_strnicmp(const char *s1, const char *s2, int n); +extern int std_strlcpy(char *pcDst, const char *pszSrc, int nDestSize); +extern int std_strlcat(char *pcDst, const char *pszSrc, int nDestSize); +extern char *std_strstr(const char *pszString, const char *pszSearch); + +//Character functions +extern char std_tolower(char c); +extern char std_toupper(char c); + +// Mem functions +extern void *std_memset(void *p, int c, int nLen); +extern void *std_memmove(void *pTo, const void *cpFrom, int nLen); +extern int std_memcmp(const void *a, const void *b, int length); +extern void *std_memchr(const void *s, int c, int n); +extern void *std_memstr(const char *cpHaystack, const char *cpszNeedle, int nHaystackLen); +extern void *std_memrchr(const void *s, int c, int n); +extern void *std_memrchrbegin(const void *p, int c, int nLen); +extern void *std_memchrend(const void *cpcSrch, int c, int nLen); +extern void *std_memchrsend(const void *cpSrch, const char *cpszChars, int nLen); + +//Other String functions +extern char *std_strchr(const char *s, int c); +extern char *std_strchrs(const char *sSrch, const char *sChars); +extern char *std_strrchr(const char *s, int c); +extern char *std_strchrend(const char *cpszSrch, char c); +extern char *std_strchrsend(const char *s, const char *cpszSrch); +extern char *std_strends(const char *cpsz, const char *cpszSuffix); +extern char *std_striends(const char *cpsz, const char *cpszSuffix); +extern char *std_strbegins(const char *cpsz, const char *cpszPrefix); +extern char *std_stribegins(const char *cpsz, const char *cpszPrefix); +extern int std_strcspn(const char *s, const char *cpszSrch); +extern int std_strspn(const char *s, const char *cpszSrch); + +//Wide char string functions +extern int std_wstrlen(const AECHAR *s); +extern int std_wstrlcpy(AECHAR *pcDst, const AECHAR *pszSrc, int nDestSize); +extern int std_wstrlcat(AECHAR *pcDst, const AECHAR *pszSrc, int nDestSize); +extern int std_wstrncmp(const AECHAR *s1, const AECHAR *s2, int nLen); +extern int std_wstrcmp(const AECHAR *s1, const AECHAR *s2); +extern AECHAR *std_wstrchr(const AECHAR *cpwszText, AECHAR ch); +extern AECHAR *std_wstrrchr(const AECHAR *cpwszText, AECHAR ch); + +//Path functions +extern int std_makepath(const char *cpszDir, + const char *cpszFile, + char *pszDest, int nDestSize); +extern char *std_splitpath(const char *cpszPath, const char *cpszDir); +extern char *std_cleanpath(char *pszPath); +extern char *std_basename(const char *pszPath); + +//Inet functions, number functions +extern uint32 std_scanul(const char *pchBuf, int nRadix, + const char **ppchEnd, int *pnError); +extern uint64 std_scanull(const char *pchBuf, int nRadix, + const char **ppchEnd, int *pnError); +extern double std_scand(const char *pchBuf, const char **ppchEnd); + +// Rand functions +extern unsigned std_rand_next(unsigned uRand); +extern uint32 std_rand(uint32 uSeed, byte *pDest, int nSize); + + +// printf functions +extern int std_vstrlprintf(char *pszDest, int nDestSize, + const char *pszFmt, AEEVaList args); + +extern int std_strlprintf(char *pszDest, int nDestSize, + const char *pszFmt, ...); + +extern int std_vsnprintf(char *pszDest, int nDestSize, + const char *cpszFmt, AEEVaList args); + +extern int std_snprintf(char *pszDest, int nDestSize, + const char *pszFmt, ...); + +// endian swapping functions +extern int std_CopyLE(void *pvDest, int nDestSize, + const void *pvSrc, int nSrcSize, + const char *pszFields); + +extern int std_CopyBE(void *pvDest, int nDestSize, + const void *pvSrc, int nSrcSize, + const char *pszFields); + +// sorting utilities +extern void std_qsort(void *pElems, int nNumElems, int nElemWidth, + int (*pfnCompare)(void *, const void *, const void *), + void *pCompareCx); + +extern int std_bisect(const void *pElems, int nNumElems, int nElemWidth, + const void *pElem, + int (*pfnCompare)(void *, const void *, const void *), + void *pCompareCx); + +extern void std_merge(void *vpDst, int nDst, + const void *vpA, int nA, + const void *vpB, int nB, + int nElemWidth, + int (*pfnCompare)(void *, const void *, const void *), + void *pCompareCx); + +extern int std_uniq(void *vpElems, int nNumElems, int nElemWidth, + int (*pfnCompare)(void *, const void *, const void *), + void *pCompareCx); + +#ifdef __cplusplus +} +#endif /* #ifdef __cplusplus */ + + +#define STD_SWAPS(us) \ + ((((us) & 0xff) << 8) + (((us) & 0xff00) >> 8)) + + +static __inline unsigned short std_swaps(unsigned short us) +{ + return STD_SWAPS(us); +} + +/* note, STD_SWAPL() requires that ul be an l-value, and destroyable. + this macro is not intended for use outside AEEstd.h */ +#define STD_SWAPL(ul) \ + (((ul) = (((ul) & 0x00ff00ff) << 8) | (((ul)>>8) & 0x00ff00ff)),(((ul) >> 16) | ((ul) << 16))) + +static __inline unsigned long std_swapl(unsigned long ul) +{ + return STD_SWAPL(ul); +} + +#ifdef AEE_BIGENDIAN +# define STD_HTONL(u) (u) +# define STD_HTONS(u) (u) +# define STD_HTOLEL(u) (STD_SWAPL(u)) +# define STD_HTOLES(u) (STD_SWAPS(u)) +#else +# define STD_HTONL(u) (STD_SWAPL(u)) +# define STD_HTONS(u) (STD_SWAPS(u)) +# define STD_HTOLEL(u) (u) +# define STD_HTOLES(u) (u) +#endif + +static __inline unsigned short std_letohs(unsigned short us) +{ + return STD_HTOLES(us); +} + +static __inline unsigned short std_htoles(unsigned short us) +{ + return STD_HTOLES(us); +} + +static __inline unsigned long std_letohl(unsigned long ul) +{ + return STD_HTOLEL(ul); +} + +static __inline unsigned long std_htolel(unsigned long ul) +{ + return STD_HTOLEL(ul); +} + +static __inline unsigned short std_ntohs(unsigned short us) +{ + return STD_HTONS(us); +} + +static __inline unsigned short std_htons(unsigned short us) +{ + return STD_HTONS(us); +} + +static __inline unsigned long std_ntohl(unsigned long ul) +{ + return STD_HTONL(ul); +} + +static __inline unsigned long std_htonl(unsigned long ul) +{ + return STD_HTONL(ul); +} + + +#undef STD_HTONL // private macro; not exported as a supported API +#undef STD_HTONS // private macro; not exported as a supported API +#undef STD_HTOLEL // private macro; not exported as a supported API +#undef STD_HTOLES // private macro; not exported as a supported API +#undef STD_SWAPS // private macro; not exported as a supported API +#undef STD_SWAPL // private macro; not exported as a supported API + + +/* +======================================================================= +MACROS DOCUMENTATION +======================================================================= + +STD_CONTSTRAIN() + +Description: + STD_CONTSTRAIN() constrains a number to be between two other numbers. + +Definition: + STD_CONSTRAIN( val, min, max ) \ + (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val)) + +Parameters: + val: number to constrain + min: number to stay greater than or equal to + max: number to stay less than or equal to + +Evaluation Value: + the constrained number + +======================================================================= + +STD_BETWEEN() + +Description: + STD_BETWEEN() tests whether a number is between two other numbers. + +Definition: + STD_BETWEEN( val, minGE, maxLT ) \ + ((unsigned)((unsigned)(val) - (unsigned)(minGE)) < \ + (unsigned)((unsigned)(maxLT) - (unsigned)(minGE))) + +Parameters: + val: value to test + minGE: lower bound + maxLT: upper bound + +Evaluation Value: + 1 if val >= minGE and val < maxLT + +======================================================================= + +STD_ARRAY_SIZE() + +Description: + STD_ARRAY_SIZE() gives the number of elements in a statically allocated array. + +Definition: + STD_ARRAY_SIZE(a) (sizeof((a))/sizeof((a)[0])) + +Parameters: + a: array to test + +Evaluation Value: + number of elements in a + +======================================================================= + +STD_ARRAY_MEMBER() + +Description: + STD_ARRAY_MEMBER() tests whether an item is a member of a statically allocated array. + +Definition: + STD_ARRAY_MEMBER(p,a) (((p) >= (a)) && ((p) < ((a) + STD_ARRAY_SIZE(a)))) + +Parameters: + p: item to test + a: array to check + +Evaluation Value: + 1 if p is in a + +======================================================================= + +STD_OFFSETOF() + +Description: + STD_OFFSETOF() gives the offset of member of a struct. + +Definition: + STD_OFFSETOF(type,member) (((char *)(&((type *)0)->member))-((char *)0)) + +Parameters: + type: structured type + member: name of member in the struct + +Evaluation Value: + offset of member (in bytes) in type + +======================================================================= + +STD_RECOVER_REC() + +Description: + STD_RECOVER_REC() provides a safe cast from a pointer to a member + of a struct to a pointer to the containing struct + +Definition: + STD_RECOVER_REC(type,member,p) ((type*)(((char*)(p))-STD_OFFSETOF(type,member))) + +Parameters: + type: structured type + member: name of member in the struct + p: pointer to the member of the struct + +Evaluation Value: + a pointer of type type to the containing struct + +======================================================================= + +STD_MIN() + +Description: + STD_MIN() finds the smaller of two values. + +Definition: + STD_MIN(a,b) ((a)<(b)?(a):(b)) + +Parameters: + a, b: values to compare + +Evaluation Value: + smaller of a and b + +======================================================================= + +STD_MAX() + +Description: + STD_MAX() finds the larger of two values. + +Definition: + STD_MAX(a,b) ((a)>(b)?(a):(b)) + +Parameters: + a, b: values to compare + +Evaluation Value: + larger of a and b + +======================================================================= + +STD_ZEROAT() + +Description: + STD_ZEROAT() zero-initializes the contents of a typed chunk of memory. + +Definition: + STD_ZEROAT(p) std_memset((p), 0, sizeof(*p)) + +Parameters: + p: the chunk to initialize + +Evaluation Value: + p + +======================================================================= + +STD_BIT_SET() + +Description: + STD_BIT_SET(bits, ix) sets the bit in the memory stored in bits at + index ix + +Parameters: + bits: the memory address holding the bits + ix: the index of the bit to set; + +======================================================================= + +STD_BIT_CLEAR() + +Description: + STD_BIT_CLEAR(bits, ix) clears the bit in the memory stored in bits + at index ix + +Parameters: + bits: the memory address holding the bits + ix: the index of the bit to clear + +======================================================================= + +STD_BIT_TEST() + +Description: + STD_BIT_TEST(bits, ix) returns the bit in the memory stored in bits + at index ix + +Parameters: + bits: the memory address holding the bits + ix: the index of the bit to test + +Evaluation Value: + 0x1 if set 0x0 if not set + +===================================================================== +INTERFACES DOCUMENTATION +======================================================================= + +std Interface + +Description: + This library provides a set of general-purpose utility functions. + Functionality may overlap that of a subset of the C standard library, but + this library differs in a few respects: + + - Functions are fully reentrant and avoid use of static variables. + + - The library can be supported consistently across all environments. + Compiler-supplied libraries sometimes behave inconsistently and are + unavailable in some environments. + + - Omits "unsafe" functions. C standard library includes many functions + that are best avoided entirely: strcpy, strcat, strtok, etc. + + +======================================================================= + +std_getversion() + +Description: + + The std_getversion() copies the stdlib version to pcDst. This function + takes the size of the destination buffer as an argument and guarantees + to zero-terminate the result and not to overflow the nDestSize size. + + This function copies up to size-1 characters from the stdlib version + string to pcDest and NUL-terminates the pcDest string. + +Prototype: + int std_getversion(char *pcDst, int nDestSize) + + +Parameters: + pcDst : Destination string + nDestSize: Size of the destination buffer in bytes + +Return Value: + + Returns the length of the version string (in characters). + +======================================================================= + +std_strlen() + +Description: + The std_strlen() computes the length of the given string. + +Prototype: + int std_strlen(const char *cpszStr) + +Parameters: + cpszStr : String whose length will be computed + +Return Value: + Length of the string in characters that precede the terminating NULL character. + +======================================================================= + +std_strcmp() + +Description: + The std_strcmp() compares two NUL-terminated character strings. + Comparison is strictly by byte values with no character set + interpretation. + +Prototype: + + int std_strcmp(const char *s1, const char *s2); + +Parameters: + s1, s2: strings to compare + +Return Value: + 0 if strings are the same ~ + < 0 if s1 is less than s2 ~ + > 0 if s1 is greater than s2 + +See Also: + std_wstrcmp + +======================================================================= + +std_strncmp() + +Description: + The std_strncmp() compares at most n bytes of two NUL-terminated character strings. + +Prototype: + + int std_strncmp(const char *s1, const char *s2, int n); + +Parameters: + s1, s2: strings to compare + n: maximum number of bytes to compare. if either s1 or s2 is + shorter than n, the function terminates there + +Return Value: + 0 if strings are the same ~ + < 0 if s1 is less than s2 ~ + > 0 if s1 is greater than s2 + +See Also: + std_wstrncmp + +======================================================================= + +std_stricmp() + +Description: + The std_stricmp() compares two NUL-terminated character strings, case-folding any + ASCII characters. + +Prototype: + + int std_stricmp(const char *s1, const char *s2); + +Parameters: + s1, s2: strings to compare + +Return Value: + 0 if strings are the same ~ + < 0 if s1 is less than s2 ~ + > 0 if s1 is greater than s2 + +======================================================================= + +std_strnicmp() + +Description: + The std_strnicmp() compares at most n bytes of 2 NUL-terminated character strings, + case-folding any ASCII characters. + +Prototype: + + int std_strnicmp(const char *s1, const char *s2, int n); + +Parameters: + s1, s2: strings to compare + n: maximum number of bytes to compare. if either s1 or s2 is + shorter than n, the function terminates there + +Return Value: + 0 if strings are the same ~ + < 0 if s1 is less than s2 ~ + > 0 if s1 is greater than s2 + +======================================================================= + +std_strlcpy() + +Description: + + The std_strlcpy() copies pszSrc string to the pcDst. It is a safer + alternative to strcpy() or strncpy(). This function takes the size of the + destination buffer as an argument and guarantees to NUL-terminate the + result and not to overflow the nDestSize size. + + This function copies up to nDestSize-1 characters from the pszSrc string + to pcDest and NUL-terminates the pcDest string. + +Prototype: + int std_strlcpy(char *pcDst, const char *pszSrc, int nDestSize) + +Parameters: + pcDst : Destination string + pcSrc : Source string + nDestSize: Size of the destination buffer in bytes + +Return Value: + + Returns the length of the string (in characters) it tried to create, + which is same as length of pszSrc. + + Example: + + { + char buf[64]; + if (std_strlcpy(buf, file_name, STD_ARRAY_SIZE(buf) >= + STD_ARRAY_SIZE(buf)) { + //Truncated -- Handle overflow.... + } + } + +Comment: + + Unlike strlcpy, std_strlcpy accepts an integer size and does nothing when a + negative value is passed. When passing valid sizes for objects on our + supported platforms, this should not result in any observed difference. + However, calling strlcpy() with UINT_MAX will result in the entire source + string being copied, whereas std_strlcpy() will do nothing. Passing INT_MAX + to str_strlcpy() will achieve the same result (although both these cases are + bad practice since they defeat bounds checking). + + +======================================================================= + +std_strlcat() + +Description: + + The std_strlcat() function concatenates a string to a string already + residing in a buffer. It is a safer alternative to strcat() or strncat(). + This function takes the size of the destination buffer as an argument and + guarantees not to create an improperly terminated string and not to + overflow the nDestSize size. + + This function appends pszSrc to pcDst, copying at most nDestSize minus + the length of the string in pcDest minus 1 bytes, always NUL-terminating + the result. + + For compatibility with "strlcat()", std_strlcat() does *not* zero-terminate + the destination buffer in cases where the buffer lacks termination on entry + to the function. Do not rely on std_strlcat() to zero-terminate a buffer + that is not already zero-terminated; instead ensure that the buffer is + properly initialized using std_strlcpy() or some other means. + +Prototype: + + int std_strlcat(char *pcDst, const char *pszSrc, int nDestSize) + +Parameters: + + pcDst : Destination string + pcSrc : Source string + nDestSize: Size of the destination buffer in bytes + +Return Value: + + Returns the length of the string (in characters) it tried to create, + which is same as length of pszSrc plus the length of pszDest. + + Example: + + { + char buf[64]; + if (std_strlcat(buf, file_name, STD_ARRAY_SIZE(buf) >= + STD_ARRAY_SIZE(buf)) { + //Truncated -- Handle overflow.... + } + } + + +======================================================================= + +std_strstr() + +Description: + The std_strstr() finds the first occurrence of a substring in a string. + +Prototype: + + char * std_strstr(const char *pszString, const char *pszSearch); + +Parameters: + pszString: string to search + pszSearch: sub string to search for + +Return Value: + A pointer to the first character in the first occurrence of the substring if found, NULL otherwise + +======================================================================= + +std_tolower() + +Description: + The std_tolower() converts an uppercase letter to the corresponding + lowercase letter. + +Prototype: + char std_tolower(char c); + +Parameters: + c: A character. + +Return Value: + the corresponding lowercase letter if c is an ASCII character whose + value is representable as an uppercase letter, else the same character + c is returned. + +======================================================================= + +std_toupper() + +Description: + The std_toupper() converts an lowercase letter to the corresponding + uppercase letter. + +Prototype: + char std_toupper(char c); + +Parameters: + c: is a character. + +Return Value: + The corresponding uppercase letter if c is an ASCII character whose + value is representable as an lowercase letter; else the same character + c is returned. + +======================================================================= + +std_memset() + +Description: + The std_memset() sets each byte in a block of memory to a value. + +Prototype: + + void *std_memset(void *p, int c, int nLen); + +Parameters: + p: memory block to set + c: value to set each byte to + nLen: size of p in bytes + +Return Value: + p + +======================================================================= + +std_memmove() + +Description: + The std_memmove() copies a block of memory from one buffer to another. + +Prototype: + + void *std_memmove(void *pTo, const void *cpFrom, int nLen); + +Parameters: + pTo: destination buffer + cpFrom: source buffer + nLen: number of bytes to copy + +Return Value: + pTo + +======================================================================= + +std_memcmp() + +Description: + The std_memcmp() compares two memory buffers, byte-wise. + +Prototype: + + int std_memcmp(const void *a, const void *b, int length); + +Parameters: + a, b: buffers to compare + length: number of bytes to compare + +Return Value: + 0 if buffers are the same for nLength ~ + < 0 if a is less than b ~ + > 0 if a is greater than b + +======================================================================= + +std_memchr() + +Description: + The std_memchr() finds the first occurrence of a character in a memory + buffer. + +Prototype: + + void *std_memchr(const void* s, int c, int n); + +Parameters: + s: buffer to search + c: value of byte to look for + n: size of s in bytes + +Return Value: + A pointer to the occurrence of c. NULL if not found. + +======================================================================= + +std_memstr() + +Description: + The std_memstr() finds the first occurrence of a substring in a memory + buffer. + +Prototype: + + void *std_memstr(const char* cpHaystack, const char* cpszNeedle, + int nHaystackLen); + +Parameters: + cpHaystack: buffer to search + cpszNeedle: NUL-terminated string to search for + nHaystackLen: size of cpHaystack in bytes + +Return Value: + a pointer to the first occurrence of cpszNeedle if found, + NULL otherwise + +Comments: + None + +Side Effects: + None + +See Also: + None + +======================================================================= + +std_memrchr() + +Description: + + The std_memrchr() finds the last occurrence of a character in a memory + buffer. + +Prototype: + + void *std_memrchr(const void* s, int c, int n); + +Parameters: + s: buffer to search + c: value of byte to look for + n: size of s in bytes + +Return Value: + a pointer to the last occurrence of c, NULL if not found + +======================================================================= + +std_memrchrbegin() + +Description: + The std_memrchrbegin() finds the last occurrence of a character in a + memory buffer. + +Prototype: + + void *std_memrchrbegin(const void* s, int c, int n); + +Parameters: + s: buffer to search + c: value of byte to look for + n: size of s in bytes + +Return Value: + a pointer to the last occurrence of c, or s if not found + +======================================================================= + +std_memchrend() + +Description: + The std_memchrend() finds the first occurrence of a character in a + memory buffer. + +Prototype: + + void *std_memchrend(const void* s, int c, int n); + +Parameters: + s: buffer to search + c: value of byte to look for + n: size of s in bytes + +Return Value: + a pointer to the occurrence of c, s + n if not found + +======================================================================= +std_memchrsend() + +Description: + The std_memchrsend() finds the first occurrence of any character in a + NUL-terminated list of characters in a memory buffer. + +Prototype: + + void *std_memchrend(const void* s, const char* cpszChars, int n); + +Parameters: + s: buffer to search + cpszChars: characters to look for + n: size of s in bytes + +Return Value: + a pointer to the first occurrence of one of cpszChars, s + n if not found + +======================================================================= + +std_strchr() + +Description: + The std_strchr() finds the first occurrence of a character in a + NUL-terminated string. + +Prototype: + + char *std_strchr(const char* s, int c); + +Parameters: + s: string to search + c: char to search for + +Return Value: + pointer to first occurrence, NULL if not found + +See Also: + std_wstrchr + +======================================================================= + +std_strchrs() + +Description: + The std_strchrs() searches s, a NUL-terminated string, for the first + occurrence of any characters in cpszSrch, a NUL-terminated list of + characters. + +Prototype: + + char *std_strchrs(const char* s, const char *cpszSrch); + +Parameters: + s: string to search + cpszSrch: a list of characters to search for + +Return Value: + first occurrence of any of cpszSrch, NULL if not found + +======================================================================= + +std_strrchr() + +Description: + The std_strrchr() finds the last occurrence of a character in a + NUL-terminated string. + +Prototype: + + char *std_strrchr(const char* s, int c); + +Parameters: + s: string to search + c: char to search for + +Return Value: + pointer to last occurrence, NULL if not found + +See Also: + std_wstrrchr + +======================================================================= + +std_strchrend() + +Description: + The std_strchrend() finds the first occurrence of a character in a + NUL-terminated string. + +Prototype: + + char *std_strchrend(const char* s, int c); + +Parameters: + s: string to search + c: char to search for + +Return Value: + pointer to first occurrence, s + std_strlen(s) if not found + +======================================================================= + +std_strchrsend() + +Description: + The std_strchrsend() searches s, a NUL-terminated string, for the first + occurrence of any characters in cpszSrch, a NUL-terminated list of + characters. + +Prototype: + + char *std_strchrsend(const char* s, const char* cpszSrch); + +Parameters: + s: string to search + cpszSrch: a list of characters to search for + +Return Value: + first occurrence of any of cpszSrch or s+strlen(s) if not found + +======================================================================= + +std_strends() + +Description: + The std_strends() tests whether a string ends in a particular suffix. + +Prototype: + + char *std_strends(const char* cpsz, const char* cpszSuffix); + +Parameters: + cpsz: string to test + cpszSuffix: suffix to test for + +Return Value: + the first character of cpsz+std_strlen(cpsz)-std_strlen(cpszSuffix) + if cpsz ends with cpszSuffix. NULL otherwise. + +======================================================================= + +std_striends() + +Description: + The std_striends() tests whether a string ends in a particular suffix, + case-folding ASCII characters. + +Prototype: + + char *std_striends(const char* cpsz, const char* cpszSuffix); + +Parameters: + cpsz: string to test + cpszSuffix: suffix to test for + +Return Value: + the first character of cpsz+std_strlen(cpsz)-std_strlen(cpszSuffix) + if cpsz ends with cpszSuffix. NULL otherwise. + +======================================================================= + +std_strbegins() + +Description: + The std_strbegins() tests whether a string begins with a particular + prefix string. + +Prototype: + + char *std_strbegins(const char* cpsz, const char* cpszPrefix); + +Parameters: + cpsz: string to test + cpszPrefix: prefix to test for + +Return Value: + cpsz + std_strlen(cpszPrefix) if cpsz does begin with cpszPrefix, + NULL otherwise + +======================================================================= + +std_stribegins() + +Description: + The std_stribegins() tests whether a string begins with a particular + prefix string, case-folding ASCII characters. + +Prototype: + + char *std_stribegins(const char* cpsz, const char* cpszPrefix); + +Parameters: + cpsz: string to test + cpszPrefix: prefix to test for + +Return Value: + cpsz + std_strlen(cpszPrefix) if cpsz does begin with cpszPrefix, + NULL otherwise + + +======================================================================= + +std_strcspn() + +Description: + The std_strcspn() function searches s, a NUL-terminated string, for + the first occurrence of any characters in cpszSrch, a NUL-terminated + list of characters. This function returns the length of the longest + initial substring of s which consists of characters not present in + cpszSrch. + +Prototype: + + int std_strcspn(const char* s, const char* cpszSrch); + +Parameters: + s: string to search + cpszSrch: a list of characters to search for + +Return Value: + The index into the string s of the first occurrence of any of the + characters in cpszSrch. If no match is found, then index of the + terminating NUL character is returned. + +See Also: + std_strspn, std_strchr, std_strchrs + +======================================================================= + +std_strspn() + +Description: + The std_strspn() functions searches s, a NUL-terminated string, for + the first occurrence of a character that matches none of the + characters in cpszSrch, a NUL-terminated list of characters. This + function returns the length of the longest initial substring of s + which consists of characters present in cpszSrch. + +Prototype: + + int std_strspn(const char* s, const char* cpszSrch); + +Parameters: + s: string to search + cpszSrch: a list of characters to search for + +Return Value: + The index into the string s of the first occurrence of any character + that matches none of the characters in cpszSrch. If all characters + in s are present in cpszSrch, the index of the terminating NUL + character is returned. + +See Also: + std_strcspn, std_strchr, std_strchrs + +======================================================================= + +std_wstrlcpy() + +Description: + + The std_wstrlcpy() function copies a string. It is equivalent to + str_strlcpy() except that it operates on wide (16-bit) character strings. + See std_strlcpy() for details. + + +Prototype: + + int std_wstrlcpy(AECHAR *pcDest, const AECHAR *pszSrc, int nDestSize); + +Parameters: + pcDst: destination string + pszSrc: source string + int nDestSize: size of pcDest __in AECHARs__ + +Return Value: + Returns the length of the string (in AECHARs) it tried to create, + which is same as length of pszSrc. + + Example: + + { + AECHAR buf[64]; + if (std_wstrlcpy(buf, file_name, STD_ARRAY_SIZE(buf)) >= + STD_ARRAY_SIZE(buf)) { + //Truncated -- Handle overflow.... + } + } + +See Also: + std_wstrlcat + +======================================================================= + +std_wstrlcat() + +Description: + + The std_wstrlcat() function concatenates two strings. It is equivalent to + std_strlcat() except that it operates on wide (16-bit) character strings. + See std_strlcat() for more information. + +Prototype: + int std_wstrlcat(AECHAR *pcDst, const AECHAR *pszSrc, int nDestSize) + +Parameters: + pcDst[out]: Destination string + pcSrc : Source string + nDestSize: Size of the destination buffer in AECHARs + +Return Value: + Returns the length of the string (in AECHARs) it tried to create, + which is same as length of pszSrc + the length of pszDest. + + Example: + + { + char buf[64]; + if (std_wstrlcat(buf, file_name, STD_ARRAY_SIZE(buf)) >= + STD_ARRAY_SIZE(buf)) { + //Truncated -- Handle overflow.... + } + } + +See Also: + std_wstrlcpy + +======================================================================= + +std_wstrncmp() + +Description: + + The std_wstrncmp() function compares up to a specified number of bytes + in two NUL-terminated strings. It is equivalent to std_strncmp() except + that it operates on wide (16-bit) character strings. + +Prototype: + int std_wstrncmp(const AECHAR* s1, const AECHAR* s2, int nLen); + +Parameters: + s1, s2: strings to compare + n: maximum number of AECHARs to compare. if either s1 or s2 is + shorter than n, the function terminates there. + +Return Value: + 0 if strings are the same ~ + < 0 if s1 is less than s2 ~ + > 0 if s1 is greater than s2 + +See Also: + std_strncmp + +======================================================================= + +std_wstrcmp() + +Description: + The std_wstrcmp() compares two NUL-terminated strings. It is equivalent + to std_strncmp() except that it operates on wide (16-bit) character + strings. Comparison is strictly by byte values with no character set + interpretation. + +Prototype: + + int std_wstrcmp(const AECHAR* s1, const AECHAR* s2); + +Parameters: + s1, s2: strings to compare + +Return Value: + 0 if strings are the same ~ + < 0 if s1 is less than s2 ~ + > 0 if s1 is greater than s2 + +See Also: + std_strcmp + +======================================================================= + +std_wstrchr() + +Description: + This function is the wide string counterpart of std_strchr(). + The std_wstrchr() finds the first occurrence of a character in a + NUL-terminated wide (16-bit) character string. + +Prototype: + + AECHAR* std_wstrchr(const AECHAR* s, AECHAR ch); + +Parameters: + s: string to search + ch: char to search for + +Return Value: + pointer to first occurrence, NULL if not found + +See Also: + std_strchr + +======================================================================= + +std_wstrrchr() + +Description: + This function is the wide string counterpart of std_strrchr(). + The std_wstrrchr() finds the last occurrence of a character in a + NUL-terminated wide (16-bit) character string. + +Prototype: + + AECHAR* std_wstrrchr(const AECHAR* s, AECHAR ch); + +Parameters: + s: string to search + ch: char to search for + +Return Value: + pointer to last occurrence, NULL if not found + +See Also: + std_strrchr + +======================================================================= + +std_makepath() + +Description: + The std_makepath() constructs a path from a directory portion and a file + portion, using forward slashes, adding necessary slashes and deleting extra + slashes. This function guarantees NUL-termination of pszDest + +Prototype: + + int std_makepath(const char *cpszDir, const char *cpszFile, + char *pszDest, int nDestSize) + +Parameters: + cpszDir: directory part + cpszFile: file part + pszDest: output buffer + nDestSize: size of output buffer in bytes + +Return Value: + the required length to construct the path, not including + NUL-termination + +Comments: + The following list of examples shows the strings returned by + std_makepath() for different paths. + +Example: + + cpszDir cpszFile std_makepath() + "" "" "" + "" "/" "" + "/" "" "/" + "/" "/" "/" + "/" "f" "/f" + "/" "/f" "/f" + "d" "f" "d/f" + "d/" "f" "d/f" + "d" "/f" "d/f" + "d/" "/f" "d/f" + +See Also: + std_splitpath + +======================================================================= + +std_splitpath() + +Description: + The std_splitpath() finds the filename part of a path given an inclusive + directory, tests for cpszPath being in cpszDir. The forward slashes are + used as directory delimiters. + +Prototype: + + char *std_splitpath(const char *cpszPath, const char *cpszDir); + +Parameters: + cpszPath: path to test for inclusion + cpszDir: directory that cpszPath might be in + +Return Value: + the part of cpszPath that actually falls beneath cpszDir, NULL if + cpszPath is not under cpszDir + +Comments: + The std_splitpath() is similar to std_strbegins(), but it ignores trailing + slashes on cpszDir, and it returns a pointer to the first character of + the subpath. + + The return value of std_splitpath() will never begin with a '/'. + + The following list of examples shows the strings returned by + std_splitpath() for different paths. + +Example: + cpszPath cpszDir std_splitpath() + "" "" "" + "" "/" "" + "/" "" "" + "/" "/" "" + "/d" "d" null + "/d" "/" "d" + "/d/" "/d" "" + "/d/f" "/" "d/f" + "/d/f" "/d" "f" + "/d/f" "/d/" "f" + +See Also: + std_makepath + +======================================================================= + +std_cleanpath() + +Description: + The std_cleanpath() removes double slashes, ".", and ".." from + slash-delimited paths,. It operates in-place. + +Prototype: + + char *std_cleanpath(char *pszPath); + +Parameters: + pszPath[in/out]: path to "clean" + +Return Value: + pszPath + +Comments: + Passing an "fs:/" path to this function may produce undesirable + results. This function assumes '/' is the root. + +Examples: + pszPath std_cleanpath() + "", "", + "/", "/", + + // here"s, mostly alone + "./", "/", + "/.", "/", + "/./", "/", + + // "up"s, mostly alone + "..", "", + "/..", "/", + "../", "/", + "/../", "/", + + // fun with x + "x/.", "x", + "x/./", "x/", + "x/..", "", + "/x/..", "/", + "x/../", "/", + "/x/../", "/", + "/x/../..", "/", + "x/../..", "", + "x/../../", "/", + "x/./../", "/", + "x/././", "x/", + "x/.././", "/", + "x/../.", "", + "x/./..", "", + "../x", "/x", + "../../x", "/x", + "/../x", "/x", + "./../x", "/x", + + // double slashes + "//", "/", + "///", "/", + "////", "/", + "x//x", "x/x", + + +Side Effects: + None + +See Also: + None + + +======================================================================= + +std_basename() + +Description: + The std_basename() returns the filename part of a string, + assuming '/' delimited filenames. + +Prototype: + + char *std_basename(const char *cpszPath); + +Parameters: + cpszPath: path of interest + +Return Value: + pointer into cpszPath that denotes part of the string immediately + following the last '/' + +Examples: + cpszPath std_basename() + "" "" + "/" "" + "x" "x" + "/x" "x" + "y/x" "x" + "/y/x" "x" + + See Also: + None + +======================================================================= + +std_rand_next() + +Description: + The std_rand_next() generates pseudo-random bytes. + +Prototype: + + unsigned std_rand_next(unsigned uRand); + +Parameters: + uRand: a seed for the pseudo-random generator + +Return Value: + the next value in the generator from uRand + +Comments: + for best results, this function should be called with its last + generated output. + + This is an example of code to generate 256 bytes of pseudo-random data. + + This is not crypto quality and should not be used for key generation + and the like. + +Example: + { + unsigned rand_buf[256/sizeof(unsigned)]; + int i; + unsigned uLast = std_rand_next(uCurrentTime); + for (i = 0; i < STD_ARRAY_SIZE(rand_buf); i++) { + rand_buf[i] = (uLast = std_rand_next(uLast)); + } + } + +See Also: + std_rand() + +======================================================================= + +std_rand() + +Description: + The std_rand() functions generates pseudo-random bytes and places it + in an output buffer of specified size. + +Prototype: + + uint32 std_rand(uint32 uSeed, byte* pDest, int nSize); + +Parameters: + uSeed: A seed for the pseudo-random generator + pDest: The output buffer where the random bytes are placed. + nSize: The size in bytes of pDest. + +Return Value: + The new seed value that can be used in a subsequent call to + std_rand(). + +Comments: + + std_rand() is a linear congruent psuedo-random number generator that + is seeded using the input seed. This makes the ouput predictable if + you can determine (or influence) the seed value used. Furthermore, + the random sequence of bytes generated by two different calls to this + function will be identical if both the calls use the same seed value. + + This is not crypto quality and should not be used for key generation + and other cryptographic uses. + +See Also: + std_rand_next() + +======================================================================= + +std_CopyLE() + +Description: + + The std_CopyLE() function copies data while translating numeric values + between host byte ordering and "little endian" byte ordering. + + pvDest and pvSrc are NOT required to be 16 or 32-bit word aligned. + + Behavior is undefined when the destination and source arrays overlap, + except in the special case where pvDest and pvSrc are equal. In that case, + std_CopyLE() modifies the buffer in-place. + + When the target byte ordering (little endian) matches the host byte + ordering, in-place translations reduce to a no-op, and copies are + delegated directly to std_memmove(). + + +Prototype: + int std_CopyLE(void *pvDest, int nDestSize, + const void *pvSrc, int nSrcSize, + const char *pszFields); + +Parameters: + pvDest: Pointer to destination buffer. + nDestSize: Size of the destination buffer. + pvSrc: Pointer to buffer containing source data. + nSrcSize: Size of source data. + pszFields: Description of the fields that comprise the source data. + + Each field size is given by a positive decimal integer or one of + the following characters: "S", "L", "Q", or "*". The letters + denote fields that should be converted to the desired byte + ordering: + +===pre> + S : a 2 byte (16 bit) value. + L : a 4 byte (32 bit) value. + Q : a 8 byte (64 bit) value. +===/pre> + + An integer gives a number of bytes and "*" represents the + remainder of the pvSrc[] buffer. No reordering is performed on + data in these fields. + + Comparisons are case-sensitive. Behavior is undefined when + other characters are supplied in pszFields. + + For example: "L12S*" would be appropriate to copy a structure + containing a uint32 followed by a 12 byte character array, + followed by a uint16, followed by an arbitrary amount of + character data. + + If nSrcSize is greater than the structure size (total of all the + sizes in pszFields[]) then pvSrc[] is treated as an array of + structures, each of which is described by pszFields. + +Return Value: + + The number of bytes actually copied or translated in-place. This will be + the smaller of nDestSize and nSrcSize, or zero if one of them are negative. + + +======================================================================= + +std_CopyBE() + +Description: + + The std_CopyBE() function has the same semantics as std_CopyLE() except it + copies between host byte ordering and big-endian ("network") byte order. + + See std_CopyLE() for more details. + + +Prototype: + void *std_CopyBE(void *pvDest, const void *pvSrc, + int cbDest, int nItems, const char *pszFields); + +Parameters: + pvDest: Pointer to destination buffer. + nDestSize: Size of the destination buffer. + pvSrc: Pointer to buffer containing source data. + nSrcSize: Size of source data. + pszFields: Description of the fields that comprise the source data, + as defined in std_CopyLE. + +Return Value: + + The number of bytes actually copied or translated in-place. This will be + the smaller of nDestSize and nSrcSize, or zero if one of them are negative. + +======================================================================= + +std_swapl() + +Description: + The std_swapl() changes endianness of an unsigned long. + +Prototype: + + unsigned long std_swapl(unsigned long ul) + +Parameters: + ul: input unsigned long + +Return Value: + ul, reversed in byte-ordering + +======================================================================= + +std_swaps() + +Description: + The std_swaps() changes endianness of an unsigned short. + +Prototype: + + unsigned short std_swaps(unsigned short us) + +Parameters: + us: input unsigned short + +Return Value: + us, reversed in byte-ordering + +======================================================================= + +std_letohs() + +Description: + The std_letohs() changes a short from little-endian to host byte order. + +Prototype: + + unsigned short std_letohs(unsigned short us) + +Parameters: + us: short to convert + +Return Value: + us converted from little-endian to host byte order. If the + host is little endian, just returns us + +======================================================================= + +std_htoles() + +Description: + The std_htoles() converts a short from host byte-order to little-endian. + +Prototype: + + unsigned short std_htoles(unsigned short us) + +Parameters: + us: short to convert + +Return Value: + us converted from host byte order to little-endian. If the + host is little endian, just returns us + +======================================================================= + +std_letohl() + +Description: + The std_letohl() changes a long from little-endian to host byte order. + +Prototype: + + unsigned long std_letohl(unsigned long ul) + +Parameters: + ul: long to convert + +Return Value: + ul converted from little-endian to host byte order. If the + host is little endian, just returns ul + +======================================================================= + +std_htolel() + +Description: + The std_htolel() converts a long from host byte-order to little-endian. + +Prototype: + + unsigned long std_htolel(unsigned long ul) + +Parameters: + ul: long to convert + +Return Value: + ul converted from host byte order to little-endian. If the + host is little endian, just returns ul. + + +======================================================================= + +std_ntohs() + +Description: + The std_ntohs() changes a short from big-endian to host byte order. + +Prototype: + + unsigned short std_ntohs(unsigned short us) + +Parameters: + us: short to convert + +Return Value: + us converted from big-endian to host byte order. If the + host is big endian, just returns us. + +======================================================================= + +std_htons() + +Description: + The std_htons() converts a short from host byte-order to big-endian. + +Prototype: + + unsigned short std_htons(unsigned short us) + +Parameters: + us: short to convert + +Return Value: + us converted from host byte order to big-endian. If the + host is big endian, just returns us. + +======================================================================= + +std_ntohl() + +Description: + The std_ntohl() changes a long from big-endian to host byte order. + +Prototype: + + unsigned long std_ntohl(unsigned long ul) + +Parameters: + ul: long to convert + +Return Value: + ul converted from big-endian to host byte order. If the + host is big endian, just returns ul. + +======================================================================= + +std_htonl() + +Description: + The std_htonl() converts a long from host byte-order to big-endian. + +Prototype: + + unsigned long std_htonl(unsigned long ul) + +Parameters: + ul: long to convert + +Return Value: + ul converted from host byte order to big-endian. If the + host is big endian, just returns ul. + + +======================================================================= + +std_strlprintf() + +Description: + + The functions std_strlprintf() and std_vstrlprintf() write formatted + output to a string. These functions guarantee NUL-termination of + the output buffer when its size is greater than zero. + + A format string is copied to the output buffer, except for conversion + specifiers contained within the format string. Conversion specifiers + begin with a "%" and specify some action that consumes an argument from + the argument list. + + Conversion specifiers have the following form: +===pre> + %[FLAGS] [WIDTH] [.PRECISION] [TYPE] CONV +===/pre> + + CONV is the only required field. It is always a single character, + and determines the action to be taken. Supported values are: + +===pre> + CONV | Description + ======|======================================================= + c | Output a single character. + | + s | Output a NUL-terminated single-byte character string. + | + d, i | Ouptut a signed decimal integer. + | + u | Output an unsigned decimal integer. + | + o | Output an unsigned octal integer. + | + x | Output an unsigned hexadecimal integer, using + | lower case digits. + | + X | Output an unsigned hexadecimal integer, using + | upper case digits. + | + p | Output a pointer value as eight hexadecimal digits, + | using upper case digits. +===/pre> + + The next argument from the argument list supplies the value to be + formatted and output. + + FLAGS, WIDTH, and PRECISION can modify the formatting of the value. + + FLAGS consists of one or more of the following characters: + +===pre> + Flag | Meaning + =====|================================================================= + + | Prefix positive numbers with "+" (%d and %i only). + -----|----------------------------------------------------------------- + - | When padding to meet WIDTH, pad on the right. + -----|----------------------------------------------------------------- + 0 | Pad with '0' characters when padding on the left to meet WIDTH. + -----|----------------------------------------------------------------- + blank| Prefix positive numbers with " " (%d and %i only). + space| + -----|----------------------------------------------------------------- + # | With %x or %X: prefixes non-zero values with "0x"/"0X". + | With %o, ensure the value begins with "0" (increasing PRECISION + | if necessary). + | Ignored for all other CONV specifiers. + -----|----------------------------------------------------------------- +===/pre> + + WIDTH is an unsigned decimal integer or the character "*". + + WIDTH gives the minimum number of characters to be written. The + formatted value will be padded with spaces until the minimum size is + met; it never causes a value to be truncated The sign of the WIDTH + integer selects between left and right padding. Padding will be on + the left unless the "-" flag is specified. + + When "*" is used, an 'int' argument is consumed from the argument + list and used as the WIDTH. A negative argument specifies padding on + the right, and its absolute value gives the amount of padding. + + If the "0" flags is specified, any padding on the left will consist + of "0" characters. An exception to this rule is that the "0" flag is + ignored when precision is specified for a numeric value. + + PRECISION is a non-negative decimal integer or "*" preceded by ".". + + When PRECISION accompanies any of the numeric conversions, it + specifies the minimum number of digits to output. Values are padded + on the left with '0' to meet the specified size. PRECISION defaults + to 1 for numbers. + + When PRECISION accompanies other conversions, it specifies the + maximum number of characters from the value to output. The value + will be truncated to ensure that at most PRECISION characters are + output. + + TYPE provides information about the type of arguments. This is used + to determine the size of integer arguments. Values larger than 'int' + can be properly obtained from the argument list. Their behavior + should be considered undefined for CONV operations other than integer + formatting. + +===pre> + TYPE | Meaning + =======|===================== + hh | sizeof(char) + -------|--------------------- + h | sizeof(short) + -------|--------------------- + l | sizeof(long) + -------|--------------------- + L, ll | sizeof(long long) + -------|--------------------- + j | sizeof(int64) + -------|--------------------- + z | sizeof(size_t) + -------|--------------------- +===/pre> + + For 64-bit integers, "ll" may be the most widely-supported type + specifier in other printf implementation, but "j" has been introduced + in ISO C99. This implementation supports both. + + Note that arguments to variadic functions are promoted to 'int' when + smaller than 'int', so 'h' and 'hh' have no observable effect. + Static analysis tools that understand standard format string syntax + may use this information for other purposes. + +Prototype: + + int std_strlprintf(char *pszDest, int nDestSize, + const char *pszFmt, ...); +Parameters: + pszDest [out]: output buffer, where output will be placed + nDestSize: size of pszDest in bytes + pszFmt: format string + +Return Value: + + The size required to hold the entire untruncated output, NOT + including NUL-termination. + +Comments: + + Notable omissions from std_strlprintf() are lack of support for + floating point and lack of support for "%n". + +Side Effects: + None + +See Also: + None + +======================================================================= + +std_vstrlprintf() + +Description: + + The std_vstrlprintf() is documented with std_strlprintf(), it's the + vector form of std_strlprintf(). See std_strlprintf() for a + more complete description. + +Prototype: + int std_vstrlprintf(char *pszDest, int nDestSize, + const char *pszFmt, AEEVaList args); + +Parameters: + pszDest [out]: output buffer, where output will be placed + nDestSize: size of pszDest in bytes + pszFmt: format string + args: arguments + + +======================================================================= + +std_snprintf() + +Description: + + The functions std_snprintf() and std_vsnprintf() are similar to + std_strlprintf and std_vstrlprintf that write formatted output to a + string. Unlike std_strlprintf, std_snprintf also support the floating + point conversion specifiers. These functions guarantee NUL-termination + of the output buffer when its size is greater than zero. + + A format string is copied to the output buffer, except for conversion + specifiers contained within the format string. Conversion specifiers + begin with a "%" and specify some action that consumes an argument from + the argument list. + + Conversion specifiers have the following form: +===pre> + %[FLAGS] [WIDTH] [.PRECISION] [TYPE] CONV +===/pre> + + CONV is the only required field. It is always a single character, + and determines the action to be taken. For a detailed description of + conversion sepcifiers, please refer to the documentation of + std_strlprintf(). Here. we only provide description of these fields + as it applies to the additional CONV values supported by + std_snprintf(). + + In addition to the values for CONV supported by std_strlprintf, this + function supports the following values: + +===pre> + CONV | Description + ======|======================================================= + e, E | Outputs a double value representing a floating point + | number in the style [-]d.ddd e±dd, where there is one + | digit (which is nonzero if the argument is nonzero) + | before the decimal-point character and the number of + | digits after it is equal to the precision. If the + | precision is missing, it is taken as 6. If the precision + | is zero and the # flag is not specified, no decimal-point + | character appears. The value is rounded to the appropriate + | number of digits. The E conversion specifier produces a + | number with E instead of e introducing the exponent. The + | exponent always contains at least two digits, and only as + | many more digits as necessary to represent the exponent. + | If the value is zero, the exponent is zero. + | + f, F | Outputs a double value representing a floating point + | number in the style [-]ddd.ddd, where the number of + | digits after the decimal-point character is equal to the + | precision specification. If the precision is missing, it + | is taken as 6. If the precision is zero and the # flag is + | not specified, no decimal-point character appears. If a + | decimal-point character appears, at least one digit + | appears before it. The value is rounded to the appropriate + | number of digits. + | + g, G | Outputs a double value representing a floating point + | number in the style f or e (or in style F or E in the case + | of a G conversion specifier), with the precision specifying + | the number of significant digits. If the precision is zero, + | it is taken as 1. The style used depends on the value + | converted. Style e (or E) is used only if the exponent + | resulting from such a conversion is less than -4 or greater + | than or equal to the precision. Trailing zeros are removed + | from the fractional portion of the result unless the # flag + | is specified; a decimal-point character appears only if it + | is followed by a digit. + | + a, A | Outputs a double value representing a floating point + | number in the style [-]0xh.hhhh p±d, where there is one + | non-zero hexadecimal digit before the decimal-point + | character and the number of hexadecimal digits after it is + | equal to the precision. If the precision is missing then + | the precision is assumed to be sufficient for an exact + | representation of the value, except that trailing zeros + | may be omitted. If the precision is zero and the # flag is + | not specified, no decimal point character appears. The + | letters 'abcdef' are used for '%a' conversion and the + | letters ABCDEF for '%A' conversion. The '%A' conversion + | specifier produces a number with 'X' and 'P' instead of 'x' + | and 'p'. The exponent always contains at least one digit, + | and only as many more digits as necessary to represent the + | decimal exponent of 2. If the value is zero, the exponent + | is zero. + | +===/pre> + + For 'e', 'f', 'g' and 'a' convervsion specifiers, a double argument + representing an infinity is converted in to the style '[-]inf' and + a double argument representing a NaN is converted in to the stlye + 'nan'. The 'E', 'F', 'G' and 'A' conversion specifiers result in + 'INF' or 'NAN' instead of 'inf' or 'nan', respectively. + +Prototype: + + int std_snprintf(char *pszDest, int nDestSize, + const char *pszFmt, ...); +Parameters: + pszDest [out]: output buffer, where output will be placed + nDestSize: size of pszDest in bytes + pszFmt: format string + +Return Value: + + The size required to hold the entire untruncated output, NOT + including NUL-termination. + +Comments: + + Notable omissions from std_strlprintf() lack of support for "%n". + +Side Effects: + None + +See Also: + std_strlprintf() + +======================================================================= + +std_vsnprintf() + +Description: + + The std_vsnprintf() is documented with std_snprintf(), it's the + vector form of std_snprintf(). See std_snprintf() for a more complete + description. + +Prototype: + int std_vsnprintf(char *pszDest, int nDestSize, + const char *pszFmt, AEEVaList args); + +Parameters: + pszDest [out]: output buffer, where output will be placed + nDestSize: size of pszDest in bytes + pszFmt: format string + args: arguments + + +======================================================================= + +std_scanul() + +Description: + + The std_scanul() converts an ASCII representation of a number to an unsigned + long. It expects strings that match the following pattern: +===pre> + spaces [+|-] digits +===/pre> + + 'Spaces' is zero or more ASCII space or tab characters. + + 'Digits' is any number of digits valid in the radix. Letters 'A' through + 'Z' are treated as digits with values 10 through 35. 'Digits' may begin + with "0x" when a radix of 0 or 16 is specified. + + Upper and lower case letters can be used interchangeably. + + +Prototype: + + uint32 std_scanul( const char *pchBuf, int nRadix, const char **ppchEnd, + int *pnError) + +Parameters: + + pchBuf [in] : the start of the string to scan. + + nRadix [in] : the numeric radix (or base) of the number. Valid values are + 2 through 36 or zero, which implies auto-detection. + Auto-detection examines the digits field. If it begins with + "0x", radix 16 is selected. Otherwise, if it begins with + "0" radix 8 is selected. Otherwise, radix 10 is selected. + + ppchEnd [out] : if ppchEnd is not NULL, *ppchEnd points to the first + character that did not match the expected pattern shown + above, except on STD_BADPARAM and STD_OVERFLOW when it is + set to the start of the string. + + pnError [out] : If pnError is not NULL, *pnError holds the error code, + which is one of the following: +~ + 0 : Numeric value is from 0 to MAX_UINT32. + + STD_NEGATIVE : The scanned value was negative and its absolute value was + from 1 to MAX_UINT32. The result is the negated value + (cast to a uint32). + + STD_NODIGITS : No digits were found. The result is zero. + + STD_OVERFLOW : The absolute value exceeded MAX_UINT32. The result + is set to MAX_UINT32 and *ppchEnd is set to pchBuf. + + STD_BADPARAM : An improper value for nRadix was received. The result + is set to zero, and *ppchEnd is set to pchBuf. +* + +Return Value: + + The converted numeric result. + +Comments: + + The std_scanul() is similar to ANSI C's strtoul() but differs in the following + respects: + + 1. It returns an error/success code. strtoul() results are ambiguous + unless the caller sets errno to zero before calling it. + + 2. std_scanul() is free of references to current locale and errno. Some + strtoul() implementations use locale; some don't. + + 3. It provides more complete reporting of range underflow. strtoul() + does not distinguish between "-1" and "0xFFFFFFFF", and underflow is + poorly defined. + + 4. std_scanul() reports a "no digits" error code to distinguish "0" from + whitespace, "+", etc.. + +See Also: + + std_scanull() + +======================================================================= + +std_scanull() + +Description: + + The std_scanull() converts an ASCII representation of a number to an + unsigned long long. It expects strings that match the following pattern: +===pre> + spaces [+|-] digits +===/pre> + + 'Spaces' is zero or more ASCII space or tab characters. + + 'Digits' is any number of digits valid in the radix. Letters 'A' through + 'Z' are treated as digits with values 10 through 35. 'Digits' may begin + with "0x" when a radix of 0 or 16 is specified. + + Upper and lower case letters can be used interchangeably. + + +Prototype: + + uint64 std_scanull(const char *pchBuf, int nRadix, const char **ppchEnd, + int *pnError) + +Parameters: + + pchBuf [in] : the start of the string to scan. + + nRadix [in] : the numeric radix (or base) of the number. Valid values are + 2 through 36 or zero, which implies auto-detection. + Auto-detection examines the digits field. If it begins with + "0x", radix 16 is selected. Otherwise, if it begins with + "0" radix 8 is selected. Otherwise, radix 10 is selected. + + ppchEnd [out] : if ppchEnd is not NULL, *ppchEnd points to the first + character that did not match the expected pattern shown + above, except on STD_BADPARAM and STD_OVERFLOW when it is + set to the start of the string. + + pnError [out] : If pnError is not NULL, *pnError holds the error code, + which is one of the following: +~ + 0 : Numeric value is from 0 to MAX_UINT64. + + STD_NEGATIVE : The scanned value was negative and its absolute value was + from 1 to MAX_UINT64. The result is the negated value + (cast to a uint64). + + STD_NODIGITS : No digits were found. The result is zero. + + STD_OVERFLOW : The absolute value exceeded MAX_UINT64. The result + is set to MAX_UINT64 and *ppchEnd is set to pchBuf. + + STD_BADPARAM : An improper value for nRadix was received. The result + is set to zero, and *ppchEnd is set to pchBuf. +* + +Return Value: + + The converted numeric result. + +Comments: + + The std_scanull() is similar to ANSI C's strtoull() but differs in the following + respects: + + 1. It returns an error/success code. strtoull() results are ambiguous + unless the caller sets errno to zero before calling it. + + 2. std_scanull() is free of references to current locale and errno. Some + strtoull() implementations use locale; some don't. + + 3. It provides more complete reporting of range underflow. strtoul() + does not distinguish between "-1" and "0xFFFFFFFFFFFFFFFF", and underflow + is poorly defined. + + 4. std_scanull() reports a "no digits" error code to distinguish "0" from + whitespace, "+", etc.. + +See Also: + + std_scanul() + +======================================================================= + +std_qsort() + +Description: + + An implementation of the quicksort algorithm, a massively recursive, + in-place sorting algorithm for an array. + + The contents of the array are sorted in ascending order according to + the comparison function pointed to by pfnCompare. + + pfnCompare must return a value less than, equal to, or + greater than zero if the first argument is considered to be + less than, equal to, or greater than the second, respectively. + + std_qsort() is not a stable sort. + +Prototype: + void std_qsort(void* pElems, int nNumElems, int nElemWidth, + int (*pfnCompare)(void*, const void*, const void*), + void* pCompareCx); + + +Parameters: + pElems: array of elements to be sorted in place. It's size + must be nNumElems * nElemWidth in bytes. + nNumElems: number of elements in pElems + nElemWidth: the width, in bytes of each element of pElems + pfnCompare: callback comparison function, should return 0, less than + zero or greater than zero if the left comparand is equal to, less + than, or greater than, the right comparand, respectively. + pCompareCx: the context passed as the first parameter by pfnCompare + +Return Value: + None + +Comments: + If nElemWidth is 2, 4, or 8, pElems is accessed internally as + integer values for the purposes of reading and writing elements. + Therefore, pElems must be aligned on a memory boundary compatible + with integer access of the array elements. I.e. if you pass 4 as + nElemWidth, *(int*)pElems must succeed. + +======================================================================= + +std_bisect() + +Description: + + Find an element in a sorted array of elements. Uses a binary + search. + +Prototype: + int std_bisect(const void* pElems, int nNumElems, int nElemWidth, + const void* pElemFind, + int (*pfnCompare)(void*, const void*, const void*), + void* pCompareCx); + +Parameters: + pElems: array of elements to be searched. It's size + must be nNumElems * nElemWidth in bytes. + nNumElems: number of elements in pElems + nElemWidth: the width, in bytes of each element of pElems + pElemFind: the element value to find in the array + pfnCompare: callback comparison function, should return 0, less than + zero or greater than zero if the left comparand is equal to, less + than, or greater than, the right comparand, respectively. + pCompareCx: the context passed as the first parameter by pfnCompare + +Return Value: + index of the element such that pElems[index] <= elem < pElems[index + 1] + nNumElems if elem is greater than all the elements in the list + 0 if the elem is less than or equal to the all the elements in the list + +======================================================================= + +std_merge() + +Description: + + Merge two sorted arrays into another array. + +Prototype: + void std_merge(void* vpDst, int nDst, + const void* vpA, int nA, + const void* vpB, int nB, + int nElemWidth, + int (*pfnCompare)(void*, const void*, const void*), + void* pCompareCx); + +Parameters: + vpDst: destination array. It's size must be nDst * nElemWidth in bytes. + nDst: number of elements that vpDst can accomodate + vpA: array of elements to be merged, it's size must be nA * nElemWidth + in bytes. + nA: number of elements in vpA + vpB: array of elements to be merged, it's size must be nB * nElemWidth + in bytes. + nB: number of elements in vpB + nElemWidth: the width, in bytes of each element of pElems + pfnCompare: callback comparison function, should return 0, less than + zero or greater than zero if the left comparand is equal to, less + than, or greater than, the right comparand, respectively. + pCompareCx: the context passed as the first parameter by pfnCompare + +Return Value: + none + +======================================================================= + +std_uniq() + +Description: + Removes duplicate entries from a sorted array. + +Prototype: + int std_uniq(void* vpElems, int nNumElems, int nElemWidth, + int (*pfnCompare)(void*, const void*, const void*), + void* pCompareCx); + +Parameters: + pElems: array of elements to be searched. It's size + must be nNumElems * nElemWidth in bytes. + nNumElems: number of elements in pElems + nElemWidth: the width, in bytes of each element of pElems + pfnCompare: callback comparison function, should return 0, less than + zero or greater than zero if the left comparand is equal to, less + than, or greater than, the right comparand, respectively. + pCompareCx: the context passed as the first parameter by pfnCompare + +Return Value: + the number of uniq elements left in vpElems + +======================================================================= + +std_scand() + +Description: + + The std_scand() converts the initial portion of an input ASCII string + to it's corresponding floating point value. It expects the input + string to match the following pattern: +===pre> + <Spaces><Subject String><Rest Of The String> +===/pre> + + 'Spaces' - is zero or more ASCII space or tab characters. + 'Subject String' - is the part of the input string that represents a + valid floating point constant. + 'Rest Of The String' - is the remaining sequence of one or more + characters including the terminating null + character of the input string. + + A valid subject string can be one of the following: + -- <NAN>, ignoring case. This is interpreted as a quiet NAN. + -- [+|-]<INF|INFINITY>, ignoring case. This is interpreted as an + infinity. + -- [+|-]<Valid Floating Point Number> + + In general, a valid floating poing number can either be a decimal + number or an hexadecimal number, and has the following form: + <Integral Part>[.[<Fractional Part>]][<Exponent>] + where the intergral, fractional and the exponent part may consist of + sequence of valid decimal or hexadecimal digits. More specifically: + + For a decimal floating point number: + 'Integral Part' - <Decimal Digits> + 'Fractional Part' - <Decimal Digits> + 'Exponent' - <e|E><Decimal Digits> + For a hexadecimal floating point number: + 'Integral Part' - <Hexadecimal Digits> + 'Fractional Part' - <Hexadecimal Digits> + 'Exponent' - <p|P><Decimal Digits> + + where: + 'Decimal Digits' - is any number of digits in the range [0,10]. + 'Hexadecimal Digits' - is any number of digits in the range [0,10] + or the alphabets A through F. + 'e','E','p','P' - represent the exponent characters + +Prototype: + + double std_scand(const char *pchBuf, const char **ppchEnd); + +Parameters: + + pchBuf [in] : the start of the string to scan. + + ppchEnd [out] : if ppchEnd is not NULL, *ppchEnd points to the first + character after the parsed number. + +Return Value: + + This function returns the converted numeric result. If the string + does not contain a valid floating point number then the function + returns zero. If the converted value is outside the range of + representable values (overflow), [-]INFINITY is + returned. In case of an underflow, the function returns zero. + +=======================================================================*/ + +#endif // AEESTD_H + + diff --git a/include/adsp_current_process.h b/include/adsp_current_process.h new file mode 100644 index 0000000..7be2948 --- /dev/null +++ b/include/adsp_current_process.h @@ -0,0 +1,76 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 _ADSP_CURRENT_PROCESS_H +#define _ADSP_CURRENT_PROCESS_H +#ifndef __QAIC_HEADER +#define __QAIC_HEADER(ff) ff +#endif //__QAIC_HEADER + +#ifndef __QAIC_HEADER_EXPORT +#define __QAIC_HEADER_EXPORT +#endif // __QAIC_HEADER_EXPORT + +#ifndef __QAIC_HEADER_ATTRIBUTE +#define __QAIC_HEADER_ATTRIBUTE +#endif // __QAIC_HEADER_ATTRIBUTE + +#ifndef __QAIC_IMPL +#define __QAIC_IMPL(ff) ff +#endif //__QAIC_IMPL + +#ifndef __QAIC_IMPL_EXPORT +#define __QAIC_IMPL_EXPORT +#endif // __QAIC_IMPL_EXPORT + +#ifndef __QAIC_IMPL_ATTRIBUTE +#define __QAIC_IMPL_ATTRIBUTE +#endif // __QAIC_IMPL_ATTRIBUTE +#ifdef __cplusplus +extern "C" { +#endif +#if !defined(__QAIC_STRING1_OBJECT_DEFINED__) && !defined(__STRING1_OBJECT__) +#define __QAIC_STRING1_OBJECT_DEFINED__ +#define __STRING1_OBJECT__ +typedef struct _cstring1_s +{ + char *data; + int dataLen; +} _cstring1_t; + +#endif /* __QAIC_STRING1_OBJECT_DEFINED__ */ +__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_current_process_exit)(void) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_current_process_thread_exit)(void) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_current_process_set_logging_params)(unsigned short mask, const _cstring1_t *filesToLog, int filesToLogLen) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_current_process_getASID)(unsigned int *asid) __QAIC_HEADER_ATTRIBUTE; +#ifdef __cplusplus +} +#endif +#endif //_ADSP_CURRENT_PROCESS_H diff --git a/include/adsp_default_listener.h b/include/adsp_default_listener.h new file mode 100644 index 0000000..e9351e5 --- /dev/null +++ b/include/adsp_default_listener.h @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 _ADSP_DEFAULT_LISTENER_H +#define _ADSP_DEFAULT_LISTENER_H +#ifndef __QAIC_HEADER +#define __QAIC_HEADER(ff) ff +#endif //__QAIC_HEADER + +#ifndef __QAIC_HEADER_EXPORT +#define __QAIC_HEADER_EXPORT +#endif // __QAIC_HEADER_EXPORT + +#ifndef __QAIC_HEADER_ATTRIBUTE +#define __QAIC_HEADER_ATTRIBUTE +#endif // __QAIC_HEADER_ATTRIBUTE + +#ifndef __QAIC_IMPL +#define __QAIC_IMPL(ff) ff +#endif //__QAIC_IMPL + +#ifndef __QAIC_IMPL_EXPORT +#define __QAIC_IMPL_EXPORT +#endif // __QAIC_IMPL_EXPORT + +#ifndef __QAIC_IMPL_ATTRIBUTE +#define __QAIC_IMPL_ATTRIBUTE +#endif // __QAIC_IMPL_ATTRIBUTE +#ifdef __cplusplus +extern "C" { +#endif +__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_default_listener_register)(void) __QAIC_HEADER_ATTRIBUTE; +#ifdef __cplusplus +} +#endif +#endif //_ADSP_DEFAULT_LISTENER_H diff --git a/include/adsp_listener.h b/include/adsp_listener.h new file mode 100644 index 0000000..a307400 --- /dev/null +++ b/include/adsp_listener.h @@ -0,0 +1,79 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 _ADSP_LISTENER_H +#define _ADSP_LISTENER_H +#include "AEEStdDef.h" +#ifndef __QAIC_HEADER +#define __QAIC_HEADER(ff) ff +#endif //__QAIC_HEADER + +#ifndef __QAIC_HEADER_EXPORT +#define __QAIC_HEADER_EXPORT +#endif // __QAIC_HEADER_EXPORT + +#ifndef __QAIC_HEADER_ATTRIBUTE +#define __QAIC_HEADER_ATTRIBUTE +#endif // __QAIC_HEADER_ATTRIBUTE + +#ifndef __QAIC_IMPL +#define __QAIC_IMPL(ff) ff +#endif //__QAIC_IMPL + +#ifndef __QAIC_IMPL_EXPORT +#define __QAIC_IMPL_EXPORT +#endif // __QAIC_IMPL_EXPORT + +#ifndef __QAIC_IMPL_ATTRIBUTE +#define __QAIC_IMPL_ATTRIBUTE +#endif // __QAIC_IMPL_ATTRIBUTE +#ifdef __cplusplus +extern "C" { +#endif +#define _const_adsp_listener_handle 3 +typedef struct _adsp_listener_buffer__seq_uint8 _adsp_listener_buffer__seq_uint8; +typedef _adsp_listener_buffer__seq_uint8 adsp_listener_buffer; +struct _adsp_listener_buffer__seq_uint8 +{ + uint8 *data; + int dataLen; +}; +typedef uint32 adsp_listener_remote_handle; +typedef uint32 adsp_listener_invoke_ctx; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_listener_next_invoke)(adsp_listener_invoke_ctx prevCtx, int prevResult, const adsp_listener_buffer *outBufs, int outBufsLen, adsp_listener_invoke_ctx *ctx, adsp_listener_remote_handle *handle, uint32 *sc, adsp_listener_buffer *inBuffers, int inBuffersLen, int *inBufLenReq, int inBufLenReqLen, int *routBufLenReq, int routBufLenReqLen) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_listener_invoke_get_in_bufs)(adsp_listener_invoke_ctx ctx, adsp_listener_buffer *inBuffers, int inBuffersLen) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_listener_init)(void) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_listener_init2)(void) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_listener_next2)(adsp_listener_invoke_ctx prevCtx, int prevResult, const uint8 *prevbufs, int prevbufsLen, adsp_listener_invoke_ctx *ctx, adsp_listener_remote_handle *handle, uint32 *sc, uint8 *bufs, int bufsLen, int *bufsLenReq) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_listener_get_in_bufs2)(adsp_listener_invoke_ctx ctx, int offset, uint8 *bufs, int bufsLen, int *bufsLenReq) __QAIC_HEADER_ATTRIBUTE; +#ifdef __cplusplus +} +#endif +#endif //_ADSP_LISTENER_H diff --git a/include/apps_mem.h b/include/apps_mem.h new file mode 100644 index 0000000..f92a754 --- /dev/null +++ b/include/apps_mem.h @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 _APPS_MEM_H +#define _APPS_MEM_H +#include "AEEStdDef.h" +#ifndef __QAIC_HEADER +#define __QAIC_HEADER(ff) ff +#endif //__QAIC_HEADER + +#ifndef __QAIC_HEADER_EXPORT +#define __QAIC_HEADER_EXPORT +#endif // __QAIC_HEADER_EXPORT + +#ifndef __QAIC_HEADER_ATTRIBUTE +#define __QAIC_HEADER_ATTRIBUTE +#endif // __QAIC_HEADER_ATTRIBUTE + +#ifndef __QAIC_IMPL +#define __QAIC_IMPL(ff) ff +#endif //__QAIC_IMPL + +#ifndef __QAIC_IMPL_EXPORT +#define __QAIC_IMPL_EXPORT +#endif // __QAIC_IMPL_EXPORT + +#ifndef __QAIC_IMPL_ATTRIBUTE +#define __QAIC_IMPL_ATTRIBUTE +#endif // __QAIC_IMPL_ATTRIBUTE +#ifdef __cplusplus +extern "C" { +#endif +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_mem_request_map)(int heapid, uint32 ion_flags, uint32 rflags, uint32 vin, int32 len, uint32 *vapps, uint32 *vadsp) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_mem_request_unmap)(uint32 vadsp, int32 len) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_mem_request_map64)(int heapid, uint32 ion_flags, uint32 rflags, uint64 vin, int64 len, uint64 *vapps, uint64 *vadsp) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_mem_request_unmap64)(uint64 vadsp, int64 len) __QAIC_HEADER_ATTRIBUTE; +#ifdef __cplusplus +} +#endif +#endif //_APPS_MEM_H diff --git a/include/apps_remotectl.h b/include/apps_remotectl.h new file mode 100644 index 0000000..41539e2 --- /dev/null +++ b/include/apps_remotectl.h @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 _APPS_REMOTECTL_H +#define _APPS_REMOTECTL_H +#include "AEEStdDef.h" +#ifndef __QAIC_HEADER +#define __QAIC_HEADER(ff) ff +#endif //__QAIC_HEADER + +#ifndef __QAIC_HEADER_EXPORT +#define __QAIC_HEADER_EXPORT +#endif // __QAIC_HEADER_EXPORT + +#ifndef __QAIC_HEADER_ATTRIBUTE +#define __QAIC_HEADER_ATTRIBUTE +#endif // __QAIC_HEADER_ATTRIBUTE + +#ifndef __QAIC_IMPL +#define __QAIC_IMPL(ff) ff +#endif //__QAIC_IMPL + +#ifndef __QAIC_IMPL_EXPORT +#define __QAIC_IMPL_EXPORT +#endif // __QAIC_IMPL_EXPORT + +#ifndef __QAIC_IMPL_ATTRIBUTE +#define __QAIC_IMPL_ATTRIBUTE +#endif // __QAIC_IMPL_ATTRIBUTE +#ifdef __cplusplus +extern "C" { +#endif +#if !defined(__QAIC_STRING1_OBJECT_DEFINED__) && !defined(__STRING1_OBJECT__) +#define __QAIC_STRING1_OBJECT_DEFINED__ +#define __STRING1_OBJECT__ +typedef struct _cstring1_s +{ + char *data; + int dataLen; +} _cstring1_t; + +#endif /* __QAIC_STRING1_OBJECT_DEFINED__ */ +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_remotectl_open)(const char *name, int *handle, char *dlerror, int dlerrorLen, int *nErr) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_remotectl_close)(int handle, char *dlerror, int dlerrorLen, int *nErr) __QAIC_HEADER_ATTRIBUTE; +#ifdef __cplusplus +} +#endif +#endif //_APPS_REMOTECTL_H diff --git a/include/apps_std.h b/include/apps_std.h new file mode 100644 index 0000000..72a68f6 --- /dev/null +++ b/include/apps_std.h @@ -0,0 +1,170 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 _APPS_STD_H +#define _APPS_STD_H +#include "AEEStdDef.h" +#ifndef __QAIC_HEADER +#define __QAIC_HEADER(ff) ff +#endif //__QAIC_HEADER + +#ifndef __QAIC_HEADER_EXPORT +#define __QAIC_HEADER_EXPORT +#endif // __QAIC_HEADER_EXPORT + +#ifndef __QAIC_HEADER_ATTRIBUTE +#define __QAIC_HEADER_ATTRIBUTE +#endif // __QAIC_HEADER_ATTRIBUTE + +#ifndef __QAIC_IMPL +#define __QAIC_IMPL(ff) ff +#endif //__QAIC_IMPL + +#ifndef __QAIC_IMPL_EXPORT +#define __QAIC_IMPL_EXPORT +#endif // __QAIC_IMPL_EXPORT + +#ifndef __QAIC_IMPL_ATTRIBUTE +#define __QAIC_IMPL_ATTRIBUTE +#endif // __QAIC_IMPL_ATTRIBUTE +#ifdef __cplusplus +extern "C" { +#endif +#if !defined(__QAIC_STRING1_OBJECT_DEFINED__) && !defined(__STRING1_OBJECT__) +#define __QAIC_STRING1_OBJECT_DEFINED__ +#define __STRING1_OBJECT__ +typedef struct _cstring1_s +{ + char *data; + int dataLen; +} _cstring1_t; + +#endif /* __QAIC_STRING1_OBJECT_DEFINED__ */ +/** + * standard library functions remoted from the apps to the dsp + */ +typedef int apps_std_FILE; +enum apps_std_SEEK +{ + APPS_STD_SEEK_SET, + APPS_STD_SEEK_CUR, + APPS_STD_SEEK_END, + _32BIT_PLACEHOLDER_apps_std_SEEK = 0x7fffffff +}; +typedef enum apps_std_SEEK apps_std_SEEK; +/** + * @retval, if operation fails errno is returned + */ +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fopen)(const char *name, const char *mode, apps_std_FILE *psout) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_freopen)(apps_std_FILE sin, const char *name, const char *mode, apps_std_FILE *psout) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fflush)(apps_std_FILE sin) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fclose)(apps_std_FILE sin) __QAIC_HEADER_ATTRIBUTE; +/** + * @param, bEOF, if read or write bytes <= bufLen bytes then feof() is called + * and the result is returned in bEOF, otherwise bEOF is set to 0. + * @retval, if read or write return 0 for non zero length buffers, ferror is checked + * and a non zero value is returned in case of error with no rout parameters + */ +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fread)(apps_std_FILE sin, byte *buf, int bufLen, int *bytesRead, int *bEOF) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fwrite)(apps_std_FILE sin, const byte *buf, int bufLen, int *bytesWritten, int *bEOF) __QAIC_HEADER_ATTRIBUTE; +/** + * @param, pos, this buffer is filled up to MIN(posLen, sizeof(fpos_t)) + * @param, posLenReq, returns sizeof(fpos_t) + * @retval, if operation fails errno is returned + */ +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fgetpos)(apps_std_FILE sin, byte *pos, int posLen, int *posLenReq) __QAIC_HEADER_ATTRIBUTE; +/** + * @param, if size of pos doesn't match the system size an error is returned. + * fgetpos can be used to query the size of fpos_t + * @retval, if operation fails errno is returned + */ +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fsetpos)(apps_std_FILE sin, const byte *pos, int posLen) __QAIC_HEADER_ATTRIBUTE; +/** + * @retval, if operation fails errno is returned + */ +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_ftell)(apps_std_FILE sin, int *pos) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fseek)(apps_std_FILE sin, int offset, apps_std_SEEK whence) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_flen)(apps_std_FILE sin, uint64 *len) __QAIC_HEADER_ATTRIBUTE; +/** + * @retval, only fails if transport fails + */ +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_rewind)(apps_std_FILE sin) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_feof)(apps_std_FILE sin, int *bEOF) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_ferror)(apps_std_FILE sin, int *err) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_clearerr)(apps_std_FILE sin) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_print_string)(const char *str) __QAIC_HEADER_ATTRIBUTE; +/** + * @param val, must contain space for NULL + * @param valLenReq, length required with NULL + * @retval, if fails errno is returned + */ +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_getenv)(const char *name, char *val, int valLen, int *valLenReq) __QAIC_HEADER_ATTRIBUTE; +/** + * @retval, if fails errno is returned + */ +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_setenv)(const char *name, const char *val, int override) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_unsetenv)(const char *name) __QAIC_HEADER_ATTRIBUTE; +/** + * This function will try to open a file given directories in envvarname separated by + * delim. + * so given environment variable FOO_PATH=/foo;/bar + * fopen_wth_env("FOO_PATH", ";", "path/to/file", "rw", &out); + * will try to open /foo/path/to/file, /bar/path/to/file + * if the variable is unset, it will open the file directly + * + * @param envvarname, name of the environment variable containing the path + * @param delim, delimiator string, such as ";" + * @param name, name of the file + * @param mode, mode + * @param psout, output handle + * @retval, 0 on success errno or -1 on failure + */ +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fopen_with_env)(const char *envvarname, const char *delim, const char *name, const char *mode, apps_std_FILE *psout) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fgets)(apps_std_FILE sin, byte *buf, int bufLen, int *bEOF) __QAIC_HEADER_ATTRIBUTE; +/** + * This method will return the paths that are searched when looking for a file. + * The paths are defined by the environment variable (separated by delimiters) + * that is passed to the method. + * + * @param envvarname, name of the environment variable containing the path + * @param delim, delimiator string, such as ";" + * @param name, name of the file + * @param paths, Search paths + * @param numPaths, Actual number of paths found + * @param maxPathLen, The max path length + * @retval, 0 on success errno or -1 on failure + * + */ +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_get_search_paths_with_env)(const char *envvarname, const char *delim, _cstring1_t *paths, int pathsLen, uint32 *numPaths, uint16 *maxPathLen) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fileExists)(const char *path, boolean *exists) __QAIC_HEADER_ATTRIBUTE; +#ifdef __cplusplus +} +#endif +#endif //_APPS_STD_H diff --git a/include/fastrpc_apps_user.h b/include/fastrpc_apps_user.h new file mode 100644 index 0000000..31b4a1b --- /dev/null +++ b/include/fastrpc_apps_user.h @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 FASTRPC_APPS_USER_H +#define FASTRPC_APPS_USER_H + +#include <assert.h> +#include <fcntl.h> +#include <asm/ioctl.h> +#include <errno.h> +#endif //FASTRPC_APPS_USER_H diff --git a/include/fastrpc_internal.h b/include/fastrpc_internal.h new file mode 100644 index 0000000..0e42595 --- /dev/null +++ b/include/fastrpc_internal.h @@ -0,0 +1,312 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 FASTRPC_INTERNAL_H +#define FASTRPC_INTERNAL_H + +#include "remote64.h" +#include "verify.h" +#include "AEEstd.h" +#include <linux/types.h> + +#define FASTRPC_IOCTL_ALLOC_DMA_BUFF _IOWR('R', 1, struct fastrpc_alloc_dma_buf) +#define FASTRPC_IOCTL_FREE_DMA_BUFF _IOWR('R', 2, uint32_t) +#define FASTRPC_IOCTL_INVOKE _IOWR('R', 3, struct fastrpc_invoke) +#define FASTRPC_IOCTL_INIT_ATTACH _IO('R', 4) +#define FASTRPC_IOCTL_INIT_CREATE _IOWR('R', 5, struct fastrpc_init_create) +#define FASTRPC_IOCTL_MMAP _IOWR('R', 6, struct fastrpc_ioctl_mmap) +#define FASTRPC_IOCTL_MUNMAP _IOWR('R', 7, struct fastrpc_ioctl_munmap) +#define FASTRPC_IOCTL_SETMODE _IOWR('R', 8, uint32) + +#if !(defined __qdsp6__) && !(defined __hexagon__) +static __inline uint32 Q6_R_cl0_R(uint32 num) +{ + int ii; + for (ii = 31; ii >= 0; --ii) + { + if (num & (1 << ii)) + { + return 31 - ii; + } + } + return 0; +} +#else +#include "hexagon_protos.h" +#include <types.h> +#endif + +struct fastrpc_invoke_args { + __u64 ptr; + __u64 length; + __s32 fd; + __u32 reserved; +}; + +struct fastrpc_invoke { + __u32 handle; + __u32 sc; + __u64 args; +}; + +struct fastrpc_init_create { + __u32 filelen; /* elf file length */ + __s32 filefd; /* fd for the file */ + __u32 attrs; + __u32 siglen; + __u64 file; /* pointer to elf file */ +}; + +struct fastrpc_alloc_dma_buf { + __s32 fd; /* fd */ + __u32 flags; /* flags to map with */ + __u64 size; /* size */ +}; + +struct fastrpc_ioctl_munmap +{ + uintptr_t vaddrout; /* optional virtual address, if non zero, dsp will use vaaddrin */ + ssize_t size; /* size */ +}; + +struct fastrpc_ioctl_mmap +{ + int fd; /* ion handle */ + uint32 flags; /* flags to map with */ + uintptr_t vaddrin; /* virtual address */ + ssize_t size; /* size */ + uintptr_t vaddrout; /* dsps virtual address */ +}; + +#define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp" + +struct smq_null_invoke32 +{ + uint32_t ctx; //! invoke caller context + remote_handle handle; //! handle to invoke + uint32_t sc; //! scalars structure describing the rest of the data +}; + +struct smq_null_invoke +{ + uint64_t ctx; //! invoke caller context + remote_handle handle; //! handle to invoke + uint32_t sc; //! scalars structure describing the rest of the data +}; + +typedef uint32_t smq_invoke_buf_phy_addr; + +struct smq_phy_page +{ + uint64_t addr; //! physical address + int64_t size; //! size +}; + +struct smq_phy_page32 +{ + uint32_t addr; //! physical address + uint32_t size; //! size +}; + +struct smq_invoke_buf +{ + int num; + int pgidx; +}; + +struct smq_invoke32 +{ + struct smq_null_invoke32 header; + struct smq_phy_page32 page; //! remote arg and list of pages address +}; + +struct smq_invoke +{ + struct smq_null_invoke header; + struct smq_phy_page page; //! remote arg and list of pages address +}; + +struct smq_msg32 +{ + uint32_t pid; + uint32_t tid; + struct smq_invoke32 invoke; +}; + +struct smq_msg +{ + uint32_t pid; + uint32_t tid; + struct smq_invoke invoke; +}; + +struct smq_msg_u +{ + union + { + struct smq_msg32 msg32; + struct smq_msg msg64; + } msg; + int size; +}; + +struct smq_invoke_rsp32 +{ + uint32_t ctx; //! invoke caller context + int nRetVal; //! invoke return value +}; + +struct smq_invoke_rsp +{ + uint64_t ctx; //! invoke caller context + int nRetVal; //! invoke return value +}; + +struct smq_invoke_rsp_u +{ + union + { + struct smq_invoke_rsp32 rsp32; + struct smq_invoke_rsp rsp64; + } rsp; + int size; +}; + +static __inline void to_smq_msg(uint32 mode, struct smq_msg_u *msg, struct smq_msg *msg64) +{ + if (0 == mode) + { + msg64->pid = msg->msg.msg32.pid; + msg64->tid = msg->msg.msg32.tid; + msg64->invoke.header.ctx = msg->msg.msg32.invoke.header.ctx; + msg64->invoke.header.handle = msg->msg.msg32.invoke.header.handle; + msg64->invoke.header.sc = msg->msg.msg32.invoke.header.sc; + msg64->invoke.page.addr = msg->msg.msg32.invoke.page.addr; + msg64->invoke.page.size = msg->msg.msg32.invoke.page.size; + } + else + { + std_memmove(msg64, &msg->msg.msg64, sizeof(*msg64)); + } +} + +static __inline void to_smq_invoke_rsp(uint32 mode, uint64 ctx, int nRetVal, struct smq_invoke_rsp_u *rsp) +{ + if (0 == mode) + { + rsp->rsp.rsp32.ctx = (uint32)ctx; + rsp->rsp.rsp32.nRetVal = nRetVal; + rsp->size = sizeof(rsp->rsp.rsp32); + } + else + { + rsp->rsp.rsp64.ctx = ctx; + rsp->rsp.rsp64.nRetVal = nRetVal; + rsp->size = sizeof(rsp->rsp.rsp64); + } +} + +static __inline struct smq_invoke_buf *to_smq_invoke_buf_start(uint32 mode, void *virt, uint32 sc) +{ + struct smq_invoke_buf *buf; + int len = REMOTE_SCALARS_LENGTH(sc); + if (0 == mode) + { + remote_arg *pra = (remote_arg *)virt; + buf = (struct smq_invoke_buf *)(&pra[len]); + } + else + { + remote_arg64 *pra = (remote_arg64 *)virt; + buf = (struct smq_invoke_buf *)(&pra[len]); + } + return buf; +} + +static __inline struct smq_invoke_buf *smq_invoke_buf_start(uint32 mode, void *pv, uint32 sc) +{ + int len = REMOTE_SCALARS_LENGTH(sc); + if (0 == mode) + { + remote_arg *pra = (remote_arg *)pv; + return (struct smq_invoke_buf *)(&pra[len]); + } + else + { + remote_arg64 *pra = (remote_arg64 *)pv; + return (struct smq_invoke_buf *)(&pra[len]); + } +} + +static __inline struct smq_phy_page *smq_phy_page_start(uint32 sc, struct smq_invoke_buf *buf) +{ + int nTotal = REMOTE_SCALARS_INBUFS(sc) + REMOTE_SCALARS_OUTBUFS(sc); + return (struct smq_phy_page *)(&buf[nTotal]); +} + +//! size of the out of band data +static __inline int smq_data_size(uint32 mode, uint32 sc, int nPages) +{ + struct smq_invoke_buf *buf = smq_invoke_buf_start(mode, 0, sc); + struct smq_phy_page *page = smq_phy_page_start(sc, buf); + return (int)(uintptr_t)(&(page[nPages])); +} + +static __inline void to_smq_data(uint32 mode, uint32 sc, int nPages, void *pv, remote_arg64 *rpra) +{ + if (0 == mode) + { + struct smq_phy_page *page; + struct smq_phy_page32 *page32; + remote_arg *pra = (remote_arg *)pv; + int ii, len; + len = REMOTE_SCALARS_LENGTH(sc); + for (ii = 0; ii < len; ++ii) + { + rpra[ii].buf.pv = (uint64)(uintptr_t)pra[ii].buf.pv; + rpra[ii].buf.nLen = pra[ii].buf.nLen; + } + len = REMOTE_SCALARS_INBUFS(sc) + REMOTE_SCALARS_OUTBUFS(sc); + std_memmove(&rpra[ii], &pra[ii], len * sizeof(struct smq_invoke_buf)); + page = (struct smq_phy_page *)((struct smq_invoke_buf *)&rpra[ii] + len); + page32 = (struct smq_phy_page32 *)((struct smq_invoke_buf *)&pra[ii] + len); + for (ii = 0; ii < nPages; ++ii) + { + page[ii].addr = page32[ii].addr; + page[ii].size = page32[ii].size; + } + } + else + { + std_memmove(rpra, pv, smq_data_size(mode, sc, nPages)); + } +} + +#endif // FASTRPC_INTERNAL_H diff --git a/include/listener.h b/include/listener.h new file mode 100644 index 0000000..b85a8e2 --- /dev/null +++ b/include/listener.h @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 LISTENER_H +#define LISTENER_H + +#include <pthread.h> +#include <dlfcn.h> +#include "pthread_rw_mutex.h" + +#define MSG(a, b, c) printf(__FILE_LINE__ ":" c ) +#define MSG_1(a, b, c, d) printf(__FILE_LINE__ ":" c , d) +#define MSG_2(a, b, c, d, e) printf(__FILE_LINE__ ":" c , d, e) +#define MSG_3(a, b, c, d, e, f) printf(__FILE_LINE__ ":" c , d, e, f) +#define MSG_4(a, b, c, d, e, f,g) printf(__FILE_LINE__ ":" c , d, e, f, g) + +#define DLW_RTLD_NOW RTLD_NOW +#define dlw_Open dlopen +#define dlw_Sym dlsym +#define dlw_Close dlclose +#define dlw_Error dlerror + +#endif diff --git a/include/listener_buf.h b/include/listener_buf.h new file mode 100644 index 0000000..757aae1 --- /dev/null +++ b/include/listener_buf.h @@ -0,0 +1,143 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 LISTENER_BUF_H +#define LISTENER_BUF_H + +#include "sbuf.h" +#include "remote.h" +#include "verify.h" + +static __inline void pack_in_bufs(struct sbuf *buf, remote_arg *pra, int nBufs) +{ + int ii; + uint32_t len; + C_ASSERT(sizeof(len) == 4); + for (ii = 0; ii < nBufs; ++ii) + { + len = (uint32_t)pra[ii].buf.nLen; + sbuf_write(buf, (uint8 *)&len, 4); + if (len) + { + sbuf_align(buf, 8); + sbuf_write(buf, pra[ii].buf.pv, len); + } + } +} + +void pack_out_lens(struct sbuf *buf, remote_arg *pra, int nBufs) +{ + int ii; + uint32_t len; + C_ASSERT(sizeof(len) == 4); + for (ii = 0; ii < nBufs; ++ii) + { + len = (uint32_t)pra[ii].buf.nLen; + sbuf_write(buf, (uint8 *)&len, 4); + } +} + +void unpack_in_bufs(struct sbuf *buf, remote_arg *pra, int nBufs) +{ + int ii; + uint32_t len; + C_ASSERT(sizeof(len) == 4); + for (ii = 0; ii < nBufs; ++ii) + { + sbuf_read(buf, (uint8 *)&len, 4); + pra[ii].buf.nLen = len; + if (pra[ii].buf.nLen) + { + sbuf_align(buf, 8); + if ((int)pra[ii].buf.nLen <= sbuf_left(buf)) + { + pra[ii].buf.pv = sbuf_head(buf); + } + sbuf_advance(buf, pra[ii].buf.nLen); + } + } +} + +void unpack_out_lens(struct sbuf *buf, remote_arg *pra, int nBufs) +{ + int ii; + uint32_t len; + C_ASSERT(sizeof(len) == 4); + for (ii = 0; ii < nBufs; ++ii) + { + sbuf_read(buf, (uint8 *)&len, 4); + pra[ii].buf.nLen = len; + } +} + +//map out buffers on the hlos side to the remote_arg array +//dst is the space required for buffers we coun't map from the adsp +void pack_out_bufs(struct sbuf *buf, remote_arg *pra, int nBufs) +{ + int ii; + uint32_t len; + C_ASSERT(sizeof(len) == 4); + for (ii = 0; ii < nBufs; ++ii) + { + len = (uint32_t)pra[ii].buf.nLen; + sbuf_write(buf, (uint8 *)&len, 4); + if (pra[ii].buf.nLen) + { + sbuf_align(buf, 8); + if ((int)pra[ii].buf.nLen <= sbuf_left(buf)) + { + pra[ii].buf.pv = sbuf_head(buf); + } + sbuf_advance(buf, pra[ii].buf.nLen); + } + } +} + +//on the aDSP copy the data from buffers we had to copy to the local remote_arg structure +static __inline int unpack_out_bufs(struct sbuf *buf, remote_arg *pra, int nBufs) +{ + int ii, nErr = 0; + uint32_t len; + C_ASSERT(sizeof(len) == 4); + for (ii = 0; ii < nBufs; ++ii) + { + sbuf_read(buf, (uint8 *)&len, 4); + VERIFY(len == pra[ii].buf.nLen); + if (pra[ii].buf.nLen) + { + sbuf_align(buf, 8); + sbuf_read(buf, pra[ii].buf.pv, pra[ii].buf.nLen); + } + } +bail: + return nErr; +} + +#endif diff --git a/include/mod_table_imp.h b/include/mod_table_imp.h new file mode 100644 index 0000000..80a0f7b --- /dev/null +++ b/include/mod_table_imp.h @@ -0,0 +1,500 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 MOD_TABLE_IMP_H +#define MOD_TABLE_IMP_H +#include "remote.h" +#include "uthash.h" +#include "verify.h" +#include "AEEstd.h" +#include "qtest_stdlib.h" + +/** + * structure for the mod table + * + * you need to define a rw_mutex type and its read/write lock/unlock api's + * which are under the RW_MUTEX namespace. + * + * this library defines 2 functions for opening modules, open_static and + * open_dynamic. Both return a handle that should be closed via close. + * + * you can also register a const handle, an invoke function for a known handle + * value. since handle keys are allocated, you should pick handle values that are + * not going to be returned by malloc (0, or odd). + */ +struct static_mod_table +{ + RW_MUTEX_T mut; + struct static_mod *staticMods; + struct const_mod *constMods; + boolean bInit; +}; + +struct open_mod_table +{ + RW_MUTEX_T mut; + struct open_mod *openMods; + struct static_mod_table *smt; +}; + + +typedef int (*invoke_fn)(uint32, remote_arg *); +struct static_mod +{ + invoke_fn invoke_func_ptr; + UT_hash_handle hh; + char name[1]; +}; + +struct const_mod +{ + invoke_fn invoke_func_ptr; + uint32 key; + UT_hash_handle hh; + char name[1]; +}; + + +struct open_mod +{ + void *dlhandle; + invoke_fn invoke_func_ptr; + uint32 key; + UT_hash_handle hh; + char name[1]; +}; + +static int static_mod_table_ctor_imp(struct static_mod_table *me) +{ + if (me->bInit == 0) + { + RW_MUTEX_CTOR(me->mut); + me->staticMods = 0; + me->bInit = 1; + } + return 0; +} + +static void static_mod_table_dtor_imp(struct static_mod_table *me) +{ + struct static_mod *sm, *stmp; + struct const_mod *dm, *ftmp; + if (me->bInit != 0) + { + if (me->staticMods || me->constMods) + { + RW_MUTEX_LOCK_WRITE(me->mut); + HASH_ITER(hh, me->staticMods, sm, stmp) + { + HASH_DEL(me->staticMods, sm); + FREE(sm); + } + HASH_ITER(hh, me->constMods, dm, ftmp) + { + HASH_DEL(me->constMods, dm); + FREE(dm); + } + RW_MUTEX_UNLOCK_WRITE(me->mut); + } + RW_MUTEX_DTOR(me->mut); + me->staticMods = 0; + me->bInit = 0; + } +} + +static int open_mod_table_ctor_imp(void *ctx, void *data) +{ + struct open_mod_table *me = (struct open_mod_table *)data; + RW_MUTEX_CTOR(me->mut); + me->openMods = 0; + me->smt = (struct static_mod_table *) ctx; + return 0; +} + +static void open_mod_table_dtor_imp(void *data) +{ + struct open_mod_table *me = (struct open_mod_table *)data; + struct open_mod *dm, *ftmp; + if (me->openMods) + { + RW_MUTEX_LOCK_WRITE(me->mut); + HASH_ITER(hh, me->openMods, dm, ftmp) + { + HASH_DEL(me->openMods, dm); + if (dm->dlhandle) + { + dlw_Close(dm->dlhandle); + } + FREE(dm); + } + RW_MUTEX_UNLOCK_WRITE(me->mut); + } + RW_MUTEX_DTOR(me->mut); + me->openMods = 0; +} + +static int open_mod_table_open_static(struct open_mod_table *me, const char *in_name, remote_handle *handle) +{ + int nErr = 0; + struct static_mod *sm = 0; + struct open_mod *dm = 0, *dmOld = 0; + int len = std_strlen(in_name); + RW_MUTEX_LOCK_READ(me->mut); + HASH_FIND_STR(me->smt->staticMods, in_name, sm); + RW_MUTEX_UNLOCK_READ(me->mut); + VERIFY(0 != sm); + VERIFY(0 != (dm = ((struct open_mod *)CALLOC(1, sizeof(struct open_mod) + len + 1)))); + std_strlcpy(dm->name, sm->name, len + 1); + dm->invoke_func_ptr = sm->invoke_func_ptr; + dm->key = (uint32)(uintptr_t)dm; + + RW_MUTEX_LOCK_WRITE(me->mut); + do + { + HASH_FIND_INT(me->openMods, &dm->key, dmOld); + if (dmOld) + { + dm->key++; + } + } + while (dmOld); + HASH_ADD_INT(me->openMods, key, dm); + RW_MUTEX_UNLOCK_WRITE(me->mut); + + *handle = dm->key; +bail: + return nErr; +} + + +static int static_mod_table_register_static_imp(struct static_mod_table *me, const char *in_name, int(*pfn)(uint32 sc, remote_arg *pra)) +{ + int nErr = 0; + struct static_mod *sm = 0; + int len = std_strlen(in_name) + 1; + VERIFY(0 != (sm = ((struct static_mod *)CALLOC(1, sizeof(struct static_mod) + len)))); + std_strlcpy(sm->name, in_name, len); + sm->invoke_func_ptr = pfn; + RW_MUTEX_LOCK_WRITE(me->mut); + HASH_ADD_STR(me->staticMods, name, sm); + RW_MUTEX_UNLOCK_WRITE(me->mut); +bail: + if (nErr) + { + FREEIF(sm); + } + return nErr; +} + +static int static_mod_table_register_const_handle_imp(struct static_mod_table *me, remote_handle handle, const char *in_name, int(*pfn)(uint32 sc, remote_arg *pra)) +{ + int nErr = 0; + int len = std_strlen(in_name) + 1; + struct const_mod *dm = 0, *dmOld; + VERIFY(0 != (dm = ((struct const_mod *)CALLOC(1, sizeof(struct open_mod) + len)))); + dm->key = (uint32)handle; + dm->invoke_func_ptr = pfn; + std_strlcpy(dm->name, in_name, len); + + RW_MUTEX_LOCK_WRITE(me->mut); + HASH_FIND_INT(me->constMods, &handle, dmOld); + if (dmOld == 0) + { + HASH_ADD_INT(me->constMods, key, dm); + } + RW_MUTEX_UNLOCK_WRITE(me->mut); + nErr = dmOld != 0 ? -1 : nErr; + +bail: + if (nErr) + { + FREEIF(dm); + } + return nErr; +} + +#define FILE_PREFIX "file://" +#define FILE_PREFIX_LEN 7 +static int open_mod_table_open_dynamic(struct open_mod_table *me, const char *in_name, remote_handle *handle, char *dlStr, int dlerrorLen, int *pdlErr) +{ + int nErr = 0, dlErr = 0; + struct open_mod *dm = 0, *dmOld; + int i, len, snlen; + int name_len = std_strlen(in_name); + char *pSoName = 0; + char *pTestName = 0; + char *pQchar = 0; + + len = name_len + STD_MAX(sizeof("_skel_invoke"), sizeof("lib_skel.so")); + VERIFY(0 != (dm = ((struct open_mod *)CALLOC(1, sizeof(struct open_mod) + len)))); + + pSoName = std_strstr(in_name, FILE_PREFIX); + if (pSoName == in_name) + { + pSoName += FILE_PREFIX_LEN; + std_strlcpy(dm->name, pSoName, name_len); + pQchar = std_strchr(dm->name, '?'); + VERIFY(NULL != pQchar); + *pQchar = '\0'; + pTestName = pQchar + 1; + VERIFY(NULL != pTestName); + snlen = std_strlen(dm->name); + } + else + { + snlen = std_snprintf(dm->name, len, "lib%s_skel.so", in_name); + } + + VERIFY(len > snlen); + + dm->dlhandle = dlw_Open(dm->name, DLW_RTLD_NOW); + if (0 != (nErr = (dlErr = dm->dlhandle == 0 ? -5 : 0))) + { + goto bail; + } + + if (pTestName) + { + snlen = std_snprintf(dm->name, len, "%s_skel_invoke", pTestName); + } + else + { + snlen = std_snprintf(dm->name, len, "%s_skel_invoke", in_name); + } + VERIFY(len > snlen); + + dm->invoke_func_ptr = (invoke_fn) dlw_Sym(dm->dlhandle, dm->name); + VERIFY(0 == (dlErr = dm->invoke_func_ptr == 0 ? -1 : 0)); + + dm->key = (uint32)(uintptr_t)dm; + RW_MUTEX_LOCK_WRITE(me->mut); + do + { + HASH_FIND_INT(me->openMods, &dm->key, dmOld); + if (dmOld) + { + dm->key++; + } + } + while (dmOld); + RW_MUTEX_LOCK_WRITE(me->smt->mut); + HASH_FIND_INT(me->smt->constMods, &dm->key, dmOld); + RW_MUTEX_UNLOCK_WRITE(me->smt->mut); + if (dmOld == 0) + { + HASH_ADD_INT(me->openMods, key, dm); + } + RW_MUTEX_UNLOCK_WRITE(me->mut); + nErr = dmOld != 0 ? -1 : nErr; + if (nErr == 0) + { + *handle = dm->key; + std_strlcpy(dm->name, in_name, name_len); + } +bail: + if (nErr) + { + if (dlErr) + { + const char *dlerr = dlw_Error(); + if (dlerr != 0) + { + std_strlcpy(dlStr, dlerr, dlerrorLen); + } + nErr = 0; + } + if (pdlErr) + { + *pdlErr = dlErr; + } + if (dm && dm->dlhandle) + { + dlw_Close(dm->dlhandle); + } + FREEIF(dm); + } + return nErr; +} + +static int open_mod_table_open_imp(struct open_mod_table *me, const char *in_name, remote_handle *handle, char *dlerr, int dlerrorLen, int *pdlErr) +{ + int nErr = 0, dlErr = 0; + if (pdlErr) + { + *pdlErr = 0; + } + + VERIFY(0 == open_mod_table_open_dynamic(me, in_name, handle, dlerr, dlerrorLen, &dlErr)); + if (dlErr != 0) + { + if (0 != open_mod_table_open_static(me, in_name, handle)) + { + if (pdlErr) + { + *pdlErr = dlErr; + } + } + } +bail: + return nErr; +} +static int open_mod_table_close_imp(struct open_mod_table *me, remote_handle handle, char *errStr, int errStrLen, int *pdlErr) +{ + int nErr = 0; + struct open_mod *dm = 0; + int dlErr = 0; + // First ensure that the handle is valid + RW_MUTEX_LOCK_READ(me->mut); + HASH_FIND_INT(me->openMods, &handle, dm); + RW_MUTEX_UNLOCK_READ(me->mut); + + VERIFY(dm != NULL); + + if (dm) + { + // Try to close the library + RW_MUTEX_LOCK_WRITE(me->mut); + HASH_DEL(me->openMods, dm); + RW_MUTEX_UNLOCK_WRITE(me->mut); + if (dm->dlhandle) + { + dlErr = dlw_Close(dm->dlhandle); + } + FREE(dm); + } + +bail: + if (dlErr) + { + const char *error = dlw_Error(); + nErr = dlErr; + if (error != 0) + { + std_strlcpy(errStr, error, errStrLen); + } + } + if (pdlErr) + { + *pdlErr = dlErr; + } + return nErr; +} + +static invoke_fn open_mod_table_handle_to_invoke(struct open_mod_table *me, remote_handle handle) +{ + struct open_mod *om = 0; + struct const_mod *cm = 0; + invoke_fn pfn = 0; + RW_MUTEX_LOCK_READ(me->mut); + HASH_FIND_INT(me->openMods, &handle, om); + if (0 != om) + { + pfn = om->invoke_func_ptr; + } + RW_MUTEX_UNLOCK_READ(me->mut); + if (pfn == 0) + { + RW_MUTEX_LOCK_READ(me->smt->mut); + HASH_FIND_INT(me->smt->constMods, &handle, cm); + if (0 != cm) + { + pfn = cm->invoke_func_ptr; + } + RW_MUTEX_UNLOCK_READ(me->smt->mut); + } + return pfn; +} + +static int open_mod_table_handle_invoke(struct open_mod_table *me, remote_handle handle, uint32 sc, remote_arg *pra) +{ + int nErr = 0; + invoke_fn invoke_func_ptr; + VERIFY(0 != (invoke_func_ptr = open_mod_table_handle_to_invoke(me, handle))); + VERIFY(0 == (nErr = invoke_func_ptr(sc, pra))); +bail: + return nErr; +} + +struct mod_table +{ + struct static_mod_table smt; + struct open_mod_table omt; +}; + +static __inline int mod_table_ctor_imp(struct mod_table *mt) +{ + int nErr = 0; + VERIFY(0 == static_mod_table_ctor_imp(&mt->smt)); + VERIFY(0 == open_mod_table_ctor_imp(&mt->smt, &mt->omt)); +bail: + return nErr; +} + +static __inline void mod_table_dtor_imp(struct mod_table *mt) +{ + open_mod_table_dtor_imp(&mt->omt); + static_mod_table_dtor_imp(&mt->smt); +} + +static __inline int mod_table_open_dynamic(struct mod_table *me, const char *in_name, remote_handle *handle, char *dlStr, int dlerrorLen, int *pdlErr) +{ + return open_mod_table_open_dynamic(&me->omt, in_name, handle, dlStr, dlerrorLen, pdlErr); +} + +static __inline int mod_table_close_imp(struct mod_table *me, remote_handle handle, char *errStr, int errStrLen, int *pdlErr) +{ + return open_mod_table_close_imp(&me->omt, handle, errStr, errStrLen, pdlErr); +} + +static __inline int mod_table_open_static(struct mod_table *me, const char *in_name, remote_handle *handle) +{ + return open_mod_table_open_static(&me->omt, in_name, handle); +} + +static __inline int mod_table_register_static_imp(struct mod_table *me, const char *in_name, int(*pfn)(uint32 sc, remote_arg *pra)) +{ + return static_mod_table_register_static_imp(&me->smt, in_name, pfn); +} + +static __inline int mod_table_handle_invoke(struct mod_table *me, remote_handle handle, uint32 sc, remote_arg *pra) +{ + return open_mod_table_handle_invoke(&me->omt, handle, sc, pra); +} + +static __inline int mod_table_register_const_handle_imp(struct mod_table *me, remote_handle handle, const char *in_name, int(*pfn)(uint32 sc, remote_arg *pra)) +{ + return static_mod_table_register_const_handle_imp(&me->smt, handle, in_name, pfn); +} + +static __inline int mod_table_open_imp(struct mod_table *me, const char *in_name, remote_handle *handle, char *dlerr, int dlerrorLen, int *pdlErr) +{ + return open_mod_table_open_imp(&me->omt, in_name, handle, dlerr, dlerrorLen, pdlErr); +} +#endif // MOD_TABLE_IMP_H diff --git a/include/pthread_rw_mutex.h b/include/pthread_rw_mutex.h new file mode 100644 index 0000000..b3947d6 --- /dev/null +++ b/include/pthread_rw_mutex.h @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 PTHREAD_RW_MUTEX_H +#define PTHREAD_RW_MUTEX_H + +#include <pthread.h> +#include <stdlib.h> +#include <stdio.h> + +/* asserts may be compiled out, this should always be present */ +#define ABORT_FAIL( ff ) \ + do {\ + if(! (ff) ) {\ + fprintf(stderr, "assertion \"%s\" failed: file \"%s\", line %d\n", #ff, __FILE__, __LINE__);\ + abort();\ + }\ + } while(0) + +#define RW_MUTEX_T pthread_rwlock_t +#define RW_MUTEX_CTOR(mut) ABORT_FAIL(0 == pthread_rwlock_init( & (mut), 0)) +#define RW_MUTEX_LOCK_READ(mut) ABORT_FAIL(0 == pthread_rwlock_rdlock( & (mut))) + +#define RW_MUTEX_UNLOCK_READ(mut) ABORT_FAIL(0 == pthread_rwlock_unlock( & (mut))) + +#define RW_MUTEX_LOCK_WRITE(mut) ABORT_FAIL(0 == pthread_rwlock_wrlock( & (mut))) + +#define RW_MUTEX_UNLOCK_WRITE(mut) ABORT_FAIL(0 == pthread_rwlock_unlock( & (mut))) + +#define RW_MUTEX_DTOR(mut) ABORT_FAIL(0 == pthread_rwlock_destroy( & (mut))) + + +#endif //PTHREAD_RW_MUTEX_H diff --git a/include/qtest_stdlib.h b/include/qtest_stdlib.h new file mode 100644 index 0000000..315c261 --- /dev/null +++ b/include/qtest_stdlib.h @@ -0,0 +1,123 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 QTEST_STDLIB_H +#define QTEST_STDLIB_H + +#include <assert.h> + +#define FREEIF(pv) \ + do {\ + if(pv) { \ + void* tmp = (void*)pv;\ + pv = 0;\ + FREE(tmp);\ + } \ + } while(0) + +#ifndef QASSERT +#define QASSERT(st) assert(st) +#endif + +#ifndef QTEST +//default implementation for stdlib +#include <stdlib.h> + + +#define IF_QTEST(vv) (void)0 + +#ifndef QASSERT +#define QASSERT(st) (void)0 +#endif + +#ifndef MALLOC +#define MALLOC malloc +#endif + +#ifndef CALLOC +#define CALLOC calloc +#endif + +#ifndef FREE +#define FREE free +#endif + +#ifndef REALLOC +#define REALLOC realloc +#endif + +#define qtest_set_failure_mask(mask) (void)mask +#define qtest_get_failure_mask(mask) (void)mask +#define qtest_set_pass_count(cnt) (void)cnt +#define qtest_done() (void)0 +#define qtest_test_failure() 0 +#define qtest_atexit(pfn,ctx) (void)pfn; (void)ctx + +#else // QTEST + +#include "AEEStdDef.h" + +#define IF_QTEST(vv) do {\ + vv \ +} while (0) + +//causes alloc to fail when mask & 0x1 is true +//each test shifts the mask to the right +void qtest_set_failure_mask(uint32 mask); +void qtest_get_failure_mask(uint32 *mask); + +//causes alloc to fail when count == 0 +//each test decrements the count +void qtest_set_pass_count(int count); + +//returns 0 if succeeds and shifts the mask +//usefull for generating controlled failures in functions +int qtest_test_failure(void); + +void qtest_atexit(void (*pfnAtExit)(void *pCtx), void *pvCxt); + +void qtest_done(void); + +void *qtest_malloc(const char *name, int sz); + +void *qtest_calloc(const char *name, int cnt, int sz); + +void *qtest_realloc(const char *name, void *ptr, int sz); + +void qtest_free(const char *name, void *rv); + + +#define MALLOC(sz) qtest_malloc(__FILE_LINE__, sz) +#define CALLOC(cnt, sz) qtest_calloc(__FILE_LINE__, cnt, sz) +#define REALLOC(ptr, sz) qtest_realloc(__FILE_LINE__, ptr, sz) +#define FREE(ptr) qtest_free(__FILE_LINE__, ptr) + +#endif //QTEST +#endif //QTEST_STDLIB_H diff --git a/include/remote.h b/include/remote.h new file mode 100644 index 0000000..37670bd --- /dev/null +++ b/include/remote.h @@ -0,0 +1,186 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 REMOTE_H +#define REMOTE_H + +#include <stdint.h> +#include <sys/types.h> + +typedef uint32_t remote_handle; + +typedef struct +{ + void *pv; + size_t nLen; +} remote_buf; + +typedef union +{ + remote_buf buf; + remote_handle h; +} remote_arg; + +/*Retrives method attribute from the scalars parameter*/ +#define REMOTE_SCALARS_METHOD_ATTR(dwScalars) (((dwScalars) >> 29) & 0x7) + +/*Retrives method index from the scalars parameter*/ +#define REMOTE_SCALARS_METHOD(dwScalars) (((dwScalars) >> 24) & 0x1f) + +/*Retrives number of input buffers from the scalars parameter*/ +#define REMOTE_SCALARS_INBUFS(dwScalars) (((dwScalars) >> 16) & 0x0ff) + +/*Retrives number of output buffers from the scalars parameter*/ +#define REMOTE_SCALARS_OUTBUFS(dwScalars) (((dwScalars) >> 8) & 0x0ff) + +/*Retrives number of input handles from the scalars parameter*/ +#define REMOTE_SCALARS_INHANDLES(dwScalars) (((dwScalars) >> 4) & 0x0f) + +/*Retrives number of output handles from the scalars parameter*/ +#define REMOTE_SCALARS_OUTHANDLES(dwScalars) ((dwScalars) & 0x0f) + +#define REMOTE_SCALARS_MAKEX(nAttr,nMethod,nIn,nOut,noIn,noOut) \ + ((((uint32_t) (nAttr) & 0x7) << 29) | \ + (((uint32_t) (nMethod) & 0x1f) << 24) | \ + (((uint32_t) (nIn) & 0xff) << 16) | \ + (((uint32_t) (nOut) & 0xff) << 8) | \ + (((uint32_t) (noIn) & 0x0f) << 4) | \ + ((uint32_t) (noOut) & 0x0f)) + +#define REMOTE_SCALARS_MAKE(nMethod,nIn,nOut) REMOTE_SCALARS_MAKEX(0,nMethod,nIn,nOut,0,0) + +#define REMOTE_SCALARS_LENGTH(sc) (REMOTE_SCALARS_INBUFS(sc) +\ + REMOTE_SCALARS_OUTBUFS(sc) +\ + REMOTE_SCALARS_INHANDLES(sc) +\ + REMOTE_SCALARS_OUTHANDLES(sc)) + +#ifndef __QAIC_REMOTE +#define __QAIC_REMOTE(ff) ff +#endif //__QAIC_REMOTE + +#ifndef __QAIC_REMOTE_EXPORT +#ifdef _WIN32 +#define __QAIC_REMOTE_EXPORT __declspec(dllexport) +#else //_WIN32 +#define __QAIC_REMOTE_EXPORT +#endif //_WIN32 +#endif //__QAIC_REMOTE_EXPORT + +#ifndef __QAIC_REMOTE_ATTRIBUTE +#define __QAIC_REMOTE_ATTRIBUTE +#endif + +/* All other values are reserved */ + +/* opens a remote_handle "name" + * returns 0 on success + */ +__QAIC_REMOTE_EXPORT int __QAIC_REMOTE(remote_handle_open)(const char *name, remote_handle *ph) __QAIC_REMOTE_ATTRIBUTE; + +/* invokes the remote handle + * see retrive macro's on dwScalars format + * pra, contains the arguments in the following order, inbufs, outbufs, inhandles, outhandles. + * implementors should ignore and pass values asis that the transport doesn't understand. + */ +__QAIC_REMOTE_EXPORT int __QAIC_REMOTE(remote_handle_invoke)(remote_handle h, uint32_t dwScalars, remote_arg *pra) __QAIC_REMOTE_ATTRIBUTE; + +/* closes the remote handle + */ +__QAIC_REMOTE_EXPORT int __QAIC_REMOTE(remote_handle_close)(remote_handle h) __QAIC_REMOTE_ATTRIBUTE; + +/* map memory to the remote domain + * + * @param fd, fd assosciated with this memory + * @param flags, flags to be used for the mapping + * @param vaddrin, input address + * @param size, size of buffer + * @param vaddrout, output address + * @retval, 0 on success + */ +__QAIC_REMOTE_EXPORT int __QAIC_REMOTE(remote_mmap)(int fd, uint32_t flags, uint32_t vaddrin, int size, uint32_t *vaddrout) __QAIC_REMOTE_ATTRIBUTE; + +/* unmap memory from the remote domain + * + * @param vaddrout, remote address mapped + * @param size, size to unmap. Unmapping a range partially may not be supported. + * @retval, 0 on success, may fail if memory is still mapped + */ +__QAIC_REMOTE_EXPORT int __QAIC_REMOTE(remote_munmap)(uint32_t vaddrout, int size) __QAIC_REMOTE_ATTRIBUTE; + +/* Register a file descriptor for a buffer. This is only valid on + * android with ION allocated memory. Users of fastrpc should register + * a buffer allocated with ION to enable sharing that buffer to the + * dsp via the smmu. Some versions of libadsprpc.so lack this + * function, so users should set this symbol as weak. + * + * #pragma weak remote_register_buf + * + * @param buf, virtual address of the buffer + * @param size, size to of the buffer + * @fd, the file descriptor, callers can use -1 to deregister. + */ +__QAIC_REMOTE_EXPORT void __QAIC_REMOTE(remote_register_buf)(void *buf, int size, int fd) __QAIC_REMOTE_ATTRIBUTE; + +/* + * This is the default mode for the driver. While the driver is in parallel + * mode it will try to invalidate output buffers after it transfers control + * to the dsp. This allows the invalidate operations to overlap with the + * dsp processing the call. This mode should be used when output buffers + * are only read on the application processor and only written on the aDSP. + */ +#define REMOTE_MODE_PARALLEL 0 + +/* + * When operating in SERIAL mode the driver will invalidate output buffers + * before calling into the dsp. This mode should be used when output + * buffers have been written to somewhere besides the aDSP. + */ +#define REMOTE_MODE_SERIAL 1 + +/* + * Internal transport prefix + */ +#define ITRANSPORT_PREFIX "'\":;./\\" + +/* + * Set the mode of operation. + * + * Some versions of libadsprpc.so lack this function, so users should set + * this symbol as weak. + * + * #pragma weak remote_set_mode + * + * @param mode, the mode + * @retval, 0 on success + */ +__QAIC_REMOTE_EXPORT int __QAIC_REMOTE(remote_set_mode)(uint32_t mode) __QAIC_REMOTE_ATTRIBUTE; + + +#endif // REMOTE_H diff --git a/include/remote64.h b/include/remote64.h new file mode 100644 index 0000000..e16b255 --- /dev/null +++ b/include/remote64.h @@ -0,0 +1,83 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 REMOTE64_H +#define REMOTE64_H + +#include "remote.h" + +typedef struct +{ + uint64_t pv; + int64_t nLen; +} remote_buf64; + +typedef union +{ + remote_buf64 buf; + remote_handle h; +} remote_arg64; + +#ifndef __QAIC_REMOTE +#define __QAIC_REMOTE(ff) ff +#endif //__QAIC_REMOTE + +#ifndef __QAIC_REMOTE_EXPORT +#ifdef _WIN32 +#define __QAIC_REMOTE_EXPORT __declspec(dllexport) +#else //_WIN32 +#define __QAIC_REMOTE_EXPORT +#endif //_WIN32 +#endif //__QAIC_REMOTE_EXPORT + +#ifndef __QAIC_REMOTE_ATTRIBUTE +#define __QAIC_REMOTE_ATTRIBUTE +#endif + +/* map memory to the remote domain + * + * @param fd, fd associated with this memory + * @param flags, flags to be used for the mapping + * @param vaddrin, input address + * @param size, size of buffer + * @param vaddrout, output address + * @retval, 0 on success + */ +__QAIC_REMOTE_EXPORT int __QAIC_REMOTE(remote_mmap64)(int fd, uint32_t flags, uintptr_t vaddrin, int64_t size, uintptr_t *vaddrout) __QAIC_REMOTE_ATTRIBUTE; + +/* unmap memory from the remote domain + * + * @param vaddrout, remote address mapped + * @param size, size to unmap. Unmapping a range partially may not be supported. + * @retval, 0 on success, may fail if memory is still mapped + */ +__QAIC_REMOTE_EXPORT int __QAIC_REMOTE(remote_munmap64)(uintptr_t vaddrout, int64_t size) __QAIC_REMOTE_ATTRIBUTE; + +#endif // REMOTE64_H diff --git a/include/remotectl.h b/include/remotectl.h new file mode 100644 index 0000000..1b4b2ff --- /dev/null +++ b/include/remotectl.h @@ -0,0 +1,77 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 _REMOTECTL_H +#define _REMOTECTL_H +#include "AEEStdDef.h" +#ifndef __QAIC_HEADER +#define __QAIC_HEADER(ff) ff +#endif //__QAIC_HEADER + +#ifndef __QAIC_HEADER_EXPORT +#define __QAIC_HEADER_EXPORT +#endif // __QAIC_HEADER_EXPORT + +#ifndef __QAIC_HEADER_ATTRIBUTE +#define __QAIC_HEADER_ATTRIBUTE +#endif // __QAIC_HEADER_ATTRIBUTE + +#ifndef __QAIC_IMPL +#define __QAIC_IMPL(ff) ff +#endif //__QAIC_IMPL + +#ifndef __QAIC_IMPL_EXPORT +#define __QAIC_IMPL_EXPORT +#endif // __QAIC_IMPL_EXPORT + +#ifndef __QAIC_IMPL_ATTRIBUTE +#define __QAIC_IMPL_ATTRIBUTE +#endif // __QAIC_IMPL_ATTRIBUTE +#ifdef __cplusplus +extern "C" { +#endif +#if !defined(__QAIC_STRING1_OBJECT_DEFINED__) && !defined(__STRING1_OBJECT__) +#define __QAIC_STRING1_OBJECT_DEFINED__ +#define __STRING1_OBJECT__ +typedef struct _cstring1_s +{ + char *data; + int dataLen; +} _cstring1_t; + +#endif /* __QAIC_STRING1_OBJECT_DEFINED__ */ +#define _const_remotectl_handle 0 +__QAIC_HEADER_EXPORT int __QAIC_HEADER(remotectl_open)(const char *name, int *handle, char *dlerror, int dlerrorLen, int *nErr) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(remotectl_close)(int handle, char *dlerror, int dlerrorLen, int *nErr) __QAIC_HEADER_ATTRIBUTE; +__QAIC_HEADER_EXPORT int __QAIC_HEADER(remotectl_grow_heap)(uint32 phyAddr, uint32 nSize) __QAIC_HEADER_ATTRIBUTE; +#ifdef __cplusplus +} +#endif +#endif //_REMOTECTL_H diff --git a/include/rpcmem.h b/include/rpcmem.h new file mode 100644 index 0000000..82de2d1 --- /dev/null +++ b/include/rpcmem.h @@ -0,0 +1,138 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 RPCMEM_H +#define RPCMEM_H + +#include "AEEStdDef.h" + +/** + * RPCMEM_DEFAULT_HEAP + * Dynamicaly select the heap to use. This should be ok for most usecases. + */ +#define RPCMEM_DEFAULT_HEAP -1 + + +/** + * RPCMEM_DEFAULT_FLAGS should allocate memory with the same properties + * as the ION_FLAG_CACHED flag + */ +#ifdef ION_FLAG_CACHED +#define RPCMEM_DEFAULT_FLAGS ION_FLAG_CACHED +#else +#define RPCMEM_DEFAULT_FLAGS 1 +#endif + +/** + * RPCMEM_FLAG_UNCACHED + * ION_FLAG_CACHED should be defined as 1 + */ +#define RPCMEM_FLAG_UNCACHED 0 +#define RPCMEM_FLAG_CACHED RPCMEM_DEFAULT_FLAGS + +/** + * examples: + * + * heap 22, uncached, 1kb + * rpcmem_alloc(22, 0, 1024); + * rpcmem_alloc(22, RPCMEM_FLAG_UNCACHED, 1024); + * + * heap 21, cached, 2kb + * rpcmem_alloc(21, RPCMEM_FLAG_CACHED, 2048); + * #include <ion.h> + * rpcmem_alloc(21, ION_FLAG_CACHED, 2048); + * + * just give me the defaults, 2kb + * rpcmem_alloc(RPCMEM_DEFAULT_HEAP, RPCMEM_DEFAULT_FLAGS, 2048); + * rpcmem_alloc_def(2048); + * + * give me the default flags, but from heap 18, 4kb + * rpcmem_alloc(18, RPCMEM_DEFAULT_FLAGS, 4096); + * + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * call once to initialize the library + */ +void rpcmem_init(void); +/** + * call once for cleanup + */ +void rpcmem_deinit(void); + +/** + * Allocate via ION a buffer of size + * @heapid, the heap id to use + * @flags, ion flags to use to when allocating + * @size, the buffer size to allocate + * @retval, 0 on failure, pointer to buffer on success + * + * For example: + * buf = rpcmem_alloc(RPCMEM_DEFAULT_HEAP, RPCMEM_DEFAULT_FLAGS, size); + */ + +void *rpcmem_alloc(int heapid, uint32 flags, int size); + +/** + * allocate with default settings + */ +#if !defined(WINNT) && !defined (_WIN32_WINNT) +__attribute__((unused)) +#endif +static __inline void *rpcmem_alloc_def(int size) +{ + return rpcmem_alloc(RPCMEM_DEFAULT_HEAP, RPCMEM_DEFAULT_FLAGS, size); +} + +/** + * free buffer, ignores invalid buffers + */ +void rpcmem_free(void *po); + +/** + * returns associated fd + */ +int rpcmem_to_fd(void *po); + +#ifdef __cplusplus +} +#endif + +/** these are deprecated + */ +#define RPCMEM_HEAP_DEFAULT 0x80000000 +#define RPCMEM_HEAP_NOREG 0x40000000 +#define RPCMEM_HEAP_UNCACHED 0x20000000 + +#endif //RPCMEM_H diff --git a/include/sbuf.h b/include/sbuf.h new file mode 100644 index 0000000..611f535 --- /dev/null +++ b/include/sbuf.h @@ -0,0 +1,158 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 SBUF_H +#define SBUF_H + +#include "AEEStdDef.h" +#include "AEEstd.h" +#include <string.h> + +/** + * lightweight serialize/deserialize buffer. + + For example + + struct sbuf; + //initialize empty buffer; + sbuf_init(&sbuf, 0, 0, 0); + + //fill it with data + sbuf_align(&sbuf, 8); + sbuf_write(&sbuf, ptr1, 10); + sbuf_align(&sbuf, 8); + sbuf_write(&sbuf, ptr2, 20); + + //allocate the memory needed + mem = malloc(sbuf_needed(&sbuf)); + + //initialize with the data + sbuf_init(&sbuf, 0, mem, sbuf_needed(&sbuf)); + + //fill it with data, since it has memory, it will actually copy + sbuf_align(&sbuf, 8); + sbuf_write(&sbuf, ptr1, 10); + sbuf_align(&sbuf, 8); + sbuf_write(&sbuf, ptr2, 20); + + See sbuf_q.h for more examples + */ + + +struct sbuf +{ + uint8 *buf; //start of valid memory + uint8 *bufEnd; //end of valid memory + uint8 *bufStart; //start with optinal offset from valid mem + uint8 *bufCur; //current buffer, could be outside of valid range (greater then bufEnd) +}; + +static __inline void sbuf_init(struct sbuf *buf, int offset, uint8 *data, int dataLen) +{ + buf->buf = data; + buf->bufStart = buf->bufCur = data - offset; + buf->bufEnd = data + dataLen; +} + +static __inline void sbuf_advance(struct sbuf *buf, int len) +{ + buf->bufCur += len; +} + +//needed for everything from the start (with the offset) to the end (past the current valid memory end) +static __inline int sbuf_needed(struct sbuf *buf) +{ + return buf->bufCur - buf->bufStart; +} + +//space left in buffer, a negative value indicates overflow +//a positive value includes the offset +static __inline int sbuf_left(struct sbuf *buf) +{ + return buf->bufEnd - buf->bufCur; +} + +static __inline uint8 *sbuf_head(struct sbuf *buf) +{ + return buf->bufCur; +} + + +//advances the head pointer so the "needed" is aligned to the align value +#define _SBUF_ALIGN(x, y) (((x) + ((y)-1)) & ~((y)-1)) +static __inline void sbuf_align(struct sbuf *buf, uint32 align) +{ + sbuf_advance(buf, _SBUF_ALIGN(sbuf_needed(buf), align) - sbuf_needed(buf)); +} + + +static __inline void sbuf_write(struct sbuf *buf, uint8 *src, int srcLen) +{ + if (buf->bufCur + srcLen > buf->buf) + { + int writeLen; + if (buf->bufCur < buf->buf) + { + int len = buf->buf - buf->bufCur; + srcLen -= len; + src += len; + sbuf_advance(buf, len); + } + writeLen = STD_MIN(srcLen, sbuf_left(buf)); + if (writeLen > 0) + { + memmove(buf->bufCur, src, writeLen); + } + } + sbuf_advance(buf, srcLen); +} + +static __inline void sbuf_read(struct sbuf *buf, uint8 *dst, int dstLen) +{ + if (buf->bufCur + dstLen > buf->buf) + { + int readLen; + if (buf->bufCur < buf->buf) + { + int len = buf->buf - buf->bufCur; + dstLen -= len; + dst += len; + sbuf_advance(buf, len); + } + readLen = STD_MIN(dstLen, sbuf_left(buf)); + if (readLen > 0) + { + memmove(dst, buf->bufCur, readLen); + } + } + sbuf_advance(buf, dstLen); +} + +#endif diff --git a/include/shared.h b/include/shared.h new file mode 100644 index 0000000..b05742f --- /dev/null +++ b/include/shared.h @@ -0,0 +1,77 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 SHARED_H +#define SHARED_H + +#ifdef _WIN32 +#include <windows.h> + +typedef int __so_cb(void); +static __so_cb *__so_get_ctor(); +static __so_cb *__so_get_dtor(); + +typedef void __so_func(void); +static void __so_ctor() +{ + (void)(__so_get_ctor())(); +} + +static void __so_dtor() +{ + (void)(__so_get_dtor())(); +} + +#pragma data_seg(".CRT$XIU") +static __so_func *__autostart[] = { (__so_func *)__so_ctor }; +#pragma data_seg(".CRT$XPU") +static __so_func *__autoexit[] = { (__so_func *)__so_dtor }; +#pragma data_seg() + +#define SHARED_OBJECT_API_ENTRY(ctor, dtor)\ + static __so_cb *__so_get_ctor() { return (__so_cb*)ctor; }\ + static __so_cb *__so_get_dtor() { return (__so_cb*)dtor; } + +#else //better be gcc + +#define SHARED_OBJECT_API_ENTRY(ctor, dtor)\ +__attribute__((constructor)) \ +static void __ctor__##ctor(void) {\ + (void)ctor();\ +}\ +\ +__attribute__((destructor))\ +static void __dtor__##dtor(void) {\ + (void)dtor();\ +} + +#endif //ifdef _WIN32 + +#endif // SHARED_H diff --git a/include/uthash.h b/include/uthash.h new file mode 100644 index 0000000..73f5006 --- /dev/null +++ b/include/uthash.h @@ -0,0 +1,915 @@ +/* +Copyright (c) 2003-2011, Troy D. Hanson http://uthash.sourceforge.net +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. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE 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 UTHASH_H +#define UTHASH_H + +#include <string.h> /* memcmp,strlen */ +#include <stddef.h> /* ptrdiff_t */ +#include <stdlib.h> /* exit() */ + +/* These macros use decltype or the earlier __typeof GNU extension. + As decltype is only available in newer compilers (VS2010 or gcc 4.3+ + when compiling c++ source) this code uses whatever method is needed + or, for VS2008 where neither is available, uses casting workarounds. */ +#ifdef _MSC_VER /* MS compiler */ +#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ +#define DECLTYPE(x) (decltype(x)) +#else /* VS2008 or older (or VS2010 in C mode) */ +#define NO_DECLTYPE +#define DECLTYPE(x) +#endif +#else /* GNU, Sun and other compilers */ +#define DECLTYPE(x) (__typeof(x)) +#endif + +#ifdef NO_DECLTYPE +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + char **_da_dst = (char**)(&(dst)); \ + *_da_dst = (char*)(src); \ +} while(0) +#else +#define DECLTYPE_ASSIGN(dst,src) \ +do { \ + (dst) = DECLTYPE(dst)(src); \ +} while(0) +#endif + +/* a number of the hash function use uint32_t which isn't defined on win32 */ +#ifdef _MSC_VER +typedef unsigned int uint32_t; +typedef unsigned char uint8_t; +#else +#include <inttypes.h> /* uint32_t */ +#endif + +#define UTHASH_VERSION 1.9.4 + +#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */ +#define uthash_malloc(sz) malloc(sz) /* malloc fcn */ +#define uthash_free(ptr,sz) free(ptr) /* free fcn */ + +#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */ +#define uthash_expand_fyi(tbl) /* can be defined to log expands */ + +/* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */ +#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */ +#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */ + +/* calculate the element whose hash handle address is hhe */ +#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho))) + +#define HASH_FIND(hh,head,keyptr,keylen,out) \ +do { \ + unsigned _hf_bkt,_hf_hashv; \ + out=NULL; \ + if (head) { \ + HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \ + if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \ + HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \ + keyptr,keylen,out); \ + } \ + } \ +} while (0) + +#ifdef HASH_BLOOM +#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM) +#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0) +#define HASH_BLOOM_MAKE(tbl) \ +do { \ + (tbl)->bloom_nbits = HASH_BLOOM; \ + (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \ + if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \ + memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \ + (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \ +} while (0); + +#define HASH_BLOOM_FREE(tbl) \ +do { \ + uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \ +} while (0); + +#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8))) +#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8))) + +#define HASH_BLOOM_ADD(tbl,hashv) \ + HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) + +#define HASH_BLOOM_TEST(tbl,hashv) \ + HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1))) + +#else +#define HASH_BLOOM_MAKE(tbl) +#define HASH_BLOOM_FREE(tbl) +#define HASH_BLOOM_ADD(tbl,hashv) +#define HASH_BLOOM_TEST(tbl,hashv) (1) +#endif + +#define HASH_MAKE_TABLE(hh,head) \ +do { \ + (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \ + sizeof(UT_hash_table)); \ + if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \ + memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \ + (head)->hh.tbl->tail = &((head)->hh); \ + (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \ + (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \ + (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \ + (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \ + memset((head)->hh.tbl->buckets, 0, \ + HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \ + HASH_BLOOM_MAKE((head)->hh.tbl); \ + (head)->hh.tbl->signature = HASH_SIGNATURE; \ +} while(0) + +#define HASH_ADD(hh,head,fieldname,keylen_in,add) \ + HASH_ADD_KEYPTR(hh,head,&add->fieldname,keylen_in,add) + +#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \ +do { \ + unsigned _ha_bkt; \ + (add)->hh.next = NULL; \ + (add)->hh.key = (char*)keyptr; \ + (add)->hh.keylen = keylen_in; \ + if (!(head)) { \ + head = (add); \ + (head)->hh.prev = NULL; \ + HASH_MAKE_TABLE(hh,head); \ + } else { \ + (head)->hh.tbl->tail->next = (add); \ + (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \ + (head)->hh.tbl->tail = &((add)->hh); \ + } \ + (head)->hh.tbl->num_items++; \ + (add)->hh.tbl = (head)->hh.tbl; \ + HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \ + (add)->hh.hashv, _ha_bkt); \ + HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \ + HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \ + HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \ + HASH_FSCK(hh,head); \ +} while(0) + +#define HASH_TO_BKT( hashv, num_bkts, bkt ) \ +do { \ + bkt = ((hashv) & ((num_bkts) - 1)); \ +} while(0) + +/* delete "delptr" from the hash table. + * "the usual" patch-up process for the app-order doubly-linked-list. + * The use of _hd_hh_del below deserves special explanation. + * These used to be expressed using (delptr) but that led to a bug + * if someone used the same symbol for the head and deletee, like + * HASH_DELETE(hh,users,users); + * We want that to work, but by changing the head (users) below + * we were forfeiting our ability to further refer to the deletee (users) + * in the patch-up process. Solution: use scratch space to + * copy the deletee pointer, then the latter references are via that + * scratch pointer rather than through the repointed (users) symbol. + */ +#define HASH_DELETE(hh,head,delptr) \ +do { \ + unsigned _hd_bkt; \ + struct UT_hash_handle *_hd_hh_del; \ + if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ + HASH_BLOOM_FREE((head)->hh.tbl); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + head = NULL; \ + } else { \ + _hd_hh_del = &((delptr)->hh); \ + if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \ + (head)->hh.tbl->tail = \ + (UT_hash_handle*)((char*)((delptr)->hh.prev) + \ + (head)->hh.tbl->hho); \ + } \ + if ((delptr)->hh.prev) { \ + ((UT_hash_handle*)((char*)((delptr)->hh.prev) + \ + (head)->hh.tbl->hho))->next = (delptr)->hh.next; \ + } else { \ + DECLTYPE_ASSIGN(head,(delptr)->hh.next); \ + } \ + if (_hd_hh_del->next) { \ + ((UT_hash_handle*)((char*)_hd_hh_del->next + \ + (head)->hh.tbl->hho))->prev = \ + _hd_hh_del->prev; \ + } \ + HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \ + HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \ + (head)->hh.tbl->num_items--; \ + } \ + HASH_FSCK(hh,head); \ +} while (0) + +/* use this function to delete an item from a table only if its in that table */ +#define HASH_DELETE_IF(hh,group,ptr) \ +do {\ + if(ptr && group && ptr->hh.tbl) { \ + HASH_DELETE(hh,group,ptr); \ + ptr->hh.tbl = 0;\ + } \ +} while(0) + +/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */ +#define HASH_FIND_STR(head,findstr,out) \ + HASH_FIND(hh,head,findstr,strlen(findstr),out) +#define HASH_ADD_STR(head,strfield,add) \ + HASH_ADD(hh,head,strfield,strlen(add->strfield),add) +#define HASH_FIND_INT(head,findint,out) \ + HASH_FIND(hh,head,findint,sizeof(int),out) +#define HASH_ADD_INT(head,intfield,add) \ + HASH_ADD(hh,head,intfield,sizeof(int),add) +#define HASH_FIND_PTR(head,findptr,out) \ + HASH_FIND(hh,head,findptr,sizeof(void *),out) +#define HASH_ADD_PTR(head,ptrfield,add) \ + HASH_ADD(hh,head,ptrfield,sizeof(void *),add) +#define HASH_DEL(head,delptr) \ + HASH_DELETE(hh,head,delptr) + +/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined. + * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined. + */ +#ifdef HASH_DEBUG +#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0) +#define HASH_FSCK(hh,head) \ +do { \ + unsigned _bkt_i; \ + unsigned _count, _bkt_count; \ + char *_prev; \ + struct UT_hash_handle *_thh; \ + if (head) { \ + _count = 0; \ + for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \ + _bkt_count = 0; \ + _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \ + _prev = NULL; \ + while (_thh) { \ + if (_prev != (char*)(_thh->hh_prev)) { \ + HASH_OOPS("invalid hh_prev %p, actual %p\n", \ + _thh->hh_prev, _prev ); \ + } \ + _bkt_count++; \ + _prev = (char*)(_thh); \ + _thh = _thh->hh_next; \ + } \ + _count += _bkt_count; \ + if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \ + HASH_OOPS("invalid bucket count %d, actual %d\n", \ + (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \ + } \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("invalid hh item count %d, actual %d\n", \ + (head)->hh.tbl->num_items, _count ); \ + } \ + /* traverse hh in app order; check next/prev integrity, count */ \ + _count = 0; \ + _prev = NULL; \ + _thh = &(head)->hh; \ + while (_thh) { \ + _count++; \ + if (_prev !=(char*)(_thh->prev)) { \ + HASH_OOPS("invalid prev %p, actual %p\n", \ + _thh->prev, _prev ); \ + } \ + _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \ + _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \ + (head)->hh.tbl->hho) : NULL ); \ + } \ + if (_count != (head)->hh.tbl->num_items) { \ + HASH_OOPS("invalid app item count %d, actual %d\n", \ + (head)->hh.tbl->num_items, _count ); \ + } \ + } \ +} while (0) +#else +#define HASH_FSCK(hh,head) +#endif + +/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to + * the descriptor to which this macro is defined for tuning the hash function. + * The app can #include <unistd.h> to get the prototype for write(2). */ +#ifdef HASH_EMIT_KEYS +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \ +do { \ + unsigned _klen = fieldlen; \ + write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \ + write(HASH_EMIT_KEYS, keyptr, fieldlen); \ +} while (0) +#else +#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) +#endif + +/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */ +#ifdef HASH_FUNCTION +#define HASH_FCN HASH_FUNCTION +#else +#define HASH_FCN HASH_JEN +#endif + +/* The Bernstein hash function, used in Perl prior to v5.6 */ +#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _hb_keylen=keylen; \ + char *_hb_key=(char*)(key); \ + (hashv) = 0; \ + while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \ + bkt = (hashv) & (num_bkts-1); \ +} while (0) + + +/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at + * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */ +#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _sx_i; \ + char *_hs_key=(char*)(key); \ + hashv = 0; \ + for(_sx_i=0; _sx_i < keylen; _sx_i++) \ + hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \ + bkt = hashv & (num_bkts-1); \ +} while (0) + +#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _fn_i; \ + char *_hf_key=(char*)(key); \ + hashv = 2166136261UL; \ + for(_fn_i=0; _fn_i < keylen; _fn_i++) \ + hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \ + bkt = hashv & (num_bkts-1); \ +} while(0); + +#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _ho_i; \ + char *_ho_key=(char*)(key); \ + hashv = 0; \ + for(_ho_i=0; _ho_i < keylen; _ho_i++) { \ + hashv += _ho_key[_ho_i]; \ + hashv += (hashv << 10); \ + hashv ^= (hashv >> 6); \ + } \ + hashv += (hashv << 3); \ + hashv ^= (hashv >> 11); \ + hashv += (hashv << 15); \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +#define HASH_JEN_MIX(a,b,c) \ +do { \ + a -= b; a -= c; a ^= ( c >> 13 ); \ + b -= c; b -= a; b ^= ( a << 8 ); \ + c -= a; c -= b; c ^= ( b >> 13 ); \ + a -= b; a -= c; a ^= ( c >> 12 ); \ + b -= c; b -= a; b ^= ( a << 16 ); \ + c -= a; c -= b; c ^= ( b >> 5 ); \ + a -= b; a -= c; a ^= ( c >> 3 ); \ + b -= c; b -= a; b ^= ( a << 10 ); \ + c -= a; c -= b; c ^= ( b >> 15 ); \ +} while (0) + +#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \ +do { \ + unsigned _hj_i,_hj_j,_hj_k; \ + char *_hj_key=(char*)(key); \ + hashv = 0xfeedbeef; \ + _hj_i = _hj_j = 0x9e3779b9; \ + _hj_k = keylen; \ + while (_hj_k >= 12) { \ + _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \ + + ( (unsigned)_hj_key[2] << 16 ) \ + + ( (unsigned)_hj_key[3] << 24 ) ); \ + _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \ + + ( (unsigned)_hj_key[6] << 16 ) \ + + ( (unsigned)_hj_key[7] << 24 ) ); \ + hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \ + + ( (unsigned)_hj_key[10] << 16 ) \ + + ( (unsigned)_hj_key[11] << 24 ) ); \ + \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + \ + _hj_key += 12; \ + _hj_k -= 12; \ + } \ + hashv += keylen; \ + switch ( _hj_k ) { \ + case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \ + case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \ + case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \ + case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \ + case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \ + case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \ + case 5: _hj_j += _hj_key[4]; \ + case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \ + case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \ + case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \ + case 1: _hj_i += _hj_key[0]; \ + } \ + HASH_JEN_MIX(_hj_i, _hj_j, hashv); \ + bkt = hashv & (num_bkts-1); \ +} while(0) + +/* The Paul Hsieh hash function */ +#undef get16bits +#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ + || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) +#define get16bits(d) (*((const uint16_t *) (d))) +#endif + +#if !defined (get16bits) +#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \ + +(uint32_t)(((const uint8_t *)(d))[0]) ) +#endif +#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \ +do { \ + char *_sfh_key=(char*)(key); \ + uint32_t _sfh_tmp, _sfh_len = keylen; \ + \ + int _sfh_rem = _sfh_len & 3; \ + _sfh_len >>= 2; \ + hashv = 0xcafebabe; \ + \ + /* Main loop */ \ + for (;_sfh_len > 0; _sfh_len--) { \ + hashv += get16bits (_sfh_key); \ + _sfh_tmp = (get16bits (_sfh_key+2) << 11) ^ hashv; \ + hashv = (hashv << 16) ^ _sfh_tmp; \ + _sfh_key += 2*sizeof (uint16_t); \ + hashv += hashv >> 11; \ + } \ + \ + /* Handle end cases */ \ + switch (_sfh_rem) { \ + case 3: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 16; \ + hashv ^= _sfh_key[sizeof (uint16_t)] << 18; \ + hashv += hashv >> 11; \ + break; \ + case 2: hashv += get16bits (_sfh_key); \ + hashv ^= hashv << 11; \ + hashv += hashv >> 17; \ + break; \ + case 1: hashv += *_sfh_key; \ + hashv ^= hashv << 10; \ + hashv += hashv >> 1; \ + } \ + \ + /* Force "avalanching" of final 127 bits */ \ + hashv ^= hashv << 3; \ + hashv += hashv >> 5; \ + hashv ^= hashv << 4; \ + hashv += hashv >> 17; \ + hashv ^= hashv << 25; \ + hashv += hashv >> 6; \ + bkt = hashv & (num_bkts-1); \ +} while(0); + +#ifdef HASH_USING_NO_STRICT_ALIASING +/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads. + * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error. + * MurmurHash uses the faster approach only on CPU's where we know it's safe. + * + * Note the preprocessor built-in defines can be emitted using: + * + * gcc -m64 -dM -E - < /dev/null (on gcc) + * cc -## a.c (where a.c is a simple test file) (Sun Studio) + */ +#if (defined(__i386__) || defined(__x86_64__)) +#define MUR_GETBLOCK(p,i) p[i] +#else /* non intel */ +#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0) +#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1) +#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2) +#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3) +#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL)) +#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__)) +#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8)) +#else /* assume little endian non-intel */ +#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24)) +#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16)) +#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8)) +#endif +#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \ + (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \ + (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \ + MUR_ONE_THREE(p)))) +#endif +#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r)))) +#define MUR_FMIX(_h) \ +do { \ + _h ^= _h >> 16; \ + _h *= 0x85ebca6b; \ + _h ^= _h >> 13; \ + _h *= 0xc2b2ae35l; \ + _h ^= _h >> 16; \ +} while(0) + +#define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \ +do { \ + const uint8_t *_mur_data = (const uint8_t*)(key); \ + const int _mur_nblocks = (keylen) / 4; \ + uint32_t _mur_h1 = 0xf88D5353; \ + uint32_t _mur_c1 = 0xcc9e2d51; \ + uint32_t _mur_c2 = 0x1b873593; \ + const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \ + int _mur_i; \ + for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) { \ + uint32_t _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + \ + _mur_h1 ^= _mur_k1; \ + _mur_h1 = MUR_ROTL32(_mur_h1,13); \ + _mur_h1 = _mur_h1*5+0xe6546b64; \ + } \ + const uint8_t *_mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4); \ + uint32_t _mur_k1=0; \ + switch((keylen) & 3) { \ + case 3: _mur_k1 ^= _mur_tail[2] << 16; \ + case 2: _mur_k1 ^= _mur_tail[1] << 8; \ + case 1: _mur_k1 ^= _mur_tail[0]; \ + _mur_k1 *= _mur_c1; \ + _mur_k1 = MUR_ROTL32(_mur_k1,15); \ + _mur_k1 *= _mur_c2; \ + _mur_h1 ^= _mur_k1; \ + } \ + _mur_h1 ^= (keylen); \ + MUR_FMIX(_mur_h1); \ + hashv = _mur_h1; \ + bkt = hashv & (num_bkts-1); \ +} while(0) +#endif /* HASH_USING_NO_STRICT_ALIASING */ + +/* key comparison function; return 0 if keys equal */ +#define HASH_KEYCMP(a,b,len) memcmp(a,b,len) + +/* iterate over items in a known bucket to find desired item */ +#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \ +do { \ + if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \ + else out=NULL; \ + while (out) { \ + if (out->hh.keylen == keylen_in) { \ + if ((HASH_KEYCMP(out->hh.key,keyptr,keylen_in)) == 0) break; \ + } \ + if (out->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,out->hh.hh_next)); \ + else out = NULL; \ + } \ +} while(0) + +/* add an item to a bucket */ +#define HASH_ADD_TO_BKT(head,addhh) \ +do { \ + head.count++; \ + (addhh)->hh_next = head.hh_head; \ + (addhh)->hh_prev = NULL; \ + if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \ + (head).hh_head=addhh; \ + if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \ + && (addhh)->tbl->noexpand != 1) { \ + HASH_EXPAND_BUCKETS((addhh)->tbl); \ + } \ +} while(0) + +/* remove an item from a given bucket */ +#define HASH_DEL_IN_BKT(hh,head,hh_del) \ + (head).count--; \ + if ((head).hh_head == hh_del) { \ + (head).hh_head = hh_del->hh_next; \ + } \ + if (hh_del->hh_prev) { \ + hh_del->hh_prev->hh_next = hh_del->hh_next; \ + } \ + if (hh_del->hh_next) { \ + hh_del->hh_next->hh_prev = hh_del->hh_prev; \ + } + +/* Bucket expansion has the effect of doubling the number of buckets + * and redistributing the items into the new buckets. Ideally the + * items will distribute more or less evenly into the new buckets + * (the extent to which this is true is a measure of the quality of + * the hash function as it applies to the key domain). + * + * With the items distributed into more buckets, the chain length + * (item count) in each bucket is reduced. Thus by expanding buckets + * the hash keeps a bound on the chain length. This bounded chain + * length is the essence of how a hash provides constant time lookup. + * + * The calculation of tbl->ideal_chain_maxlen below deserves some + * explanation. First, keep in mind that we're calculating the ideal + * maximum chain length based on the *new* (doubled) bucket count. + * In fractions this is just n/b (n=number of items,b=new num buckets). + * Since the ideal chain length is an integer, we want to calculate + * ceil(n/b). We don't depend on floating point arithmetic in this + * hash, so to calculate ceil(n/b) with integers we could write + * + * ceil(n/b) = (n/b) + ((n%b)?1:0) + * + * and in fact a previous version of this hash did just that. + * But now we have improved things a bit by recognizing that b is + * always a power of two. We keep its base 2 log handy (call it lb), + * so now we can write this with a bit shift and logical AND: + * + * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0) + * + */ +#define HASH_EXPAND_BUCKETS(tbl) \ +do { \ + unsigned _he_bkt; \ + unsigned _he_bkt_i; \ + struct UT_hash_handle *_he_thh, *_he_hh_nxt; \ + UT_hash_bucket *_he_new_buckets, *_he_newbkt; \ + _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \ + 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \ + memset(_he_new_buckets, 0, \ + 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \ + tbl->ideal_chain_maxlen = \ + (tbl->num_items >> (tbl->log2_num_buckets+1)) + \ + ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \ + tbl->nonideal_items = 0; \ + for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \ + { \ + _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \ + while (_he_thh) { \ + _he_hh_nxt = _he_thh->hh_next; \ + HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \ + _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \ + if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \ + tbl->nonideal_items++; \ + _he_newbkt->expand_mult = _he_newbkt->count / \ + tbl->ideal_chain_maxlen; \ + } \ + _he_thh->hh_prev = NULL; \ + _he_thh->hh_next = _he_newbkt->hh_head; \ + if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \ + _he_thh; \ + _he_newbkt->hh_head = _he_thh; \ + _he_thh = _he_hh_nxt; \ + } \ + } \ + uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \ + tbl->num_buckets *= 2; \ + tbl->log2_num_buckets++; \ + tbl->buckets = _he_new_buckets; \ + tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \ + (tbl->ineff_expands+1) : 0; \ + if (tbl->ineff_expands > 1) { \ + tbl->noexpand=1; \ + uthash_noexpand_fyi(tbl); \ + } \ + uthash_expand_fyi(tbl); \ +} while(0) + + +/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */ +/* Note that HASH_SORT assumes the hash handle name to be hh. + * HASH_SRT was added to allow the hash handle name to be passed in. */ +#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn) +#define HASH_SRT(hh,head,cmpfcn) \ +do { \ + unsigned _hs_i; \ + unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \ + struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \ + if (head) { \ + _hs_insize = 1; \ + _hs_looping = 1; \ + _hs_list = &((head)->hh); \ + while (_hs_looping) { \ + _hs_p = _hs_list; \ + _hs_list = NULL; \ + _hs_tail = NULL; \ + _hs_nmerges = 0; \ + while (_hs_p) { \ + _hs_nmerges++; \ + _hs_q = _hs_p; \ + _hs_psize = 0; \ + for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \ + _hs_psize++; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + if (! (_hs_q) ) break; \ + } \ + _hs_qsize = _hs_insize; \ + while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \ + if (_hs_psize == 0) { \ + _hs_e = _hs_q; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_qsize--; \ + } else if ( (_hs_qsize == 0) || !(_hs_q) ) { \ + _hs_e = _hs_p; \ + _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ + ((void*)((char*)(_hs_p->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_psize--; \ + } else if (( \ + cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \ + DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \ + ) <= 0) { \ + _hs_e = _hs_p; \ + _hs_p = (UT_hash_handle*)((_hs_p->next) ? \ + ((void*)((char*)(_hs_p->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_psize--; \ + } else { \ + _hs_e = _hs_q; \ + _hs_q = (UT_hash_handle*)((_hs_q->next) ? \ + ((void*)((char*)(_hs_q->next) + \ + (head)->hh.tbl->hho)) : NULL); \ + _hs_qsize--; \ + } \ + if ( _hs_tail ) { \ + _hs_tail->next = ((_hs_e) ? \ + ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \ + } else { \ + _hs_list = _hs_e; \ + } \ + _hs_e->prev = ((_hs_tail) ? \ + ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \ + _hs_tail = _hs_e; \ + } \ + _hs_p = _hs_q; \ + } \ + _hs_tail->next = NULL; \ + if ( _hs_nmerges <= 1 ) { \ + _hs_looping=0; \ + (head)->hh.tbl->tail = _hs_tail; \ + DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \ + } \ + _hs_insize *= 2; \ + } \ + HASH_FSCK(hh,head); \ + } \ +} while (0) + +/* This function selects items from one hash into another hash. + * The end result is that the selected items have dual presence + * in both hashes. There is no copy of the items made; rather + * they are added into the new hash through a secondary hash + * hash handle that must be present in the structure. */ +#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \ +do { \ + unsigned _src_bkt, _dst_bkt; \ + void *_last_elt=NULL, *_elt; \ + UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \ + ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \ + if (src) { \ + for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \ + for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \ + _src_hh; \ + _src_hh = _src_hh->hh_next) { \ + _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \ + if (cond(_elt)) { \ + _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \ + _dst_hh->key = _src_hh->key; \ + _dst_hh->keylen = _src_hh->keylen; \ + _dst_hh->hashv = _src_hh->hashv; \ + _dst_hh->prev = _last_elt; \ + _dst_hh->next = NULL; \ + if (_last_elt_hh) { _last_elt_hh->next = _elt; } \ + if (!dst) { \ + DECLTYPE_ASSIGN(dst,_elt); \ + HASH_MAKE_TABLE(hh_dst,dst); \ + } else { \ + _dst_hh->tbl = (dst)->hh_dst.tbl; \ + } \ + HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \ + HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \ + (dst)->hh_dst.tbl->num_items++; \ + _last_elt = _elt; \ + _last_elt_hh = _dst_hh; \ + } \ + } \ + } \ + } \ + HASH_FSCK(hh_dst,dst); \ +} while (0) + +#define HASH_CLEAR(hh,head) \ +do { \ + if (head) { \ + uthash_free((head)->hh.tbl->buckets, \ + (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \ + uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \ + (head)=NULL; \ + } \ +} while(0) + +#ifdef NO_DECLTYPE +#define HASH_ITER(hh,head,el,tmp) \ +for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \ + el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL)) +#else +#define HASH_ITER(hh,head,el,tmp) \ +for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \ + el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL)) +#endif + +/* obtain a count of items in the hash */ +#define HASH_COUNT(head) HASH_CNT(hh,head) +#define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0) + +typedef struct UT_hash_bucket +{ + struct UT_hash_handle *hh_head; + unsigned count; + + /* expand_mult is normally set to 0. In this situation, the max chain length + * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If + * the bucket's chain exceeds this length, bucket expansion is triggered). + * However, setting expand_mult to a non-zero value delays bucket expansion + * (that would be triggered by additions to this particular bucket) + * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH. + * (The multiplier is simply expand_mult+1). The whole idea of this + * multiplier is to reduce bucket expansions, since they are expensive, in + * situations where we know that a particular bucket tends to be overused. + * It is better to let its chain length grow to a longer yet-still-bounded + * value, than to do an O(n) bucket expansion too often. + */ + unsigned expand_mult; + +} UT_hash_bucket; + +/* random signature used only to find hash tables in external analysis */ +#define HASH_SIGNATURE 0xa0111fe1 +#define HASH_BLOOM_SIGNATURE 0xb12220f2 + +typedef struct UT_hash_table +{ + UT_hash_bucket *buckets; + unsigned num_buckets, log2_num_buckets; + unsigned num_items; + struct UT_hash_handle *tail; /* tail hh in app order, for fast append */ + ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */ + + /* in an ideal situation (all buckets used equally), no bucket would have + * more than ceil(#items/#buckets) items. that's the ideal chain length. */ + unsigned ideal_chain_maxlen; + + /* nonideal_items is the number of items in the hash whose chain position + * exceeds the ideal chain maxlen. these items pay the penalty for an uneven + * hash distribution; reaching them in a chain traversal takes >ideal steps */ + unsigned nonideal_items; + + /* ineffective expands occur when a bucket doubling was performed, but + * afterward, more than half the items in the hash had nonideal chain + * positions. If this happens on two consecutive expansions we inhibit any + * further expansion, as it's not helping; this happens when the hash + * function isn't a good fit for the key domain. When expansion is inhibited + * the hash will still work, albeit no longer in constant time. */ + unsigned ineff_expands, noexpand; + + uint32_t signature; /* used only to find hash tables in external analysis */ +#ifdef HASH_BLOOM + uint32_t bloom_sig; /* used only to test bloom exists in external analysis */ + uint8_t *bloom_bv; + char bloom_nbits; +#endif + +} UT_hash_table; + +typedef struct UT_hash_handle +{ + struct UT_hash_table *tbl; + void *prev; /* prev element in app order */ + void *next; /* next element in app order */ + struct UT_hash_handle *hh_prev; /* previous hh in bucket order */ + struct UT_hash_handle *hh_next; /* next hh in bucket order */ + void *key; /* ptr to enclosing struct's key */ + unsigned keylen; /* enclosing struct's key len */ + unsigned hashv; /* result of hash-fcn(key) */ +} UT_hash_handle; + +#endif /* UTHASH_H */ diff --git a/include/verify.h b/include/verify.h new file mode 100644 index 0000000..663d496 --- /dev/null +++ b/include/verify.h @@ -0,0 +1,131 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 VERIFY_H +#define VERIFY_H + + +#ifndef _WIN32 +#define C_ASSERT(test) \ + switch(0) {\ + case 0:\ + case test:;\ + } +#endif // _WIN32 + +#ifndef __V_STR__ +#define __V_STR__(x) #x ":" +#endif //__STR__ +#ifndef __V_TOSTR__ +#define __V_TOSTR__(x) __V_STR__(x) +#endif // __TOSTR__ +#ifndef __V_FILE_LINE__ +#define __V_FILE_LINE__ __FILE__ ":" __V_TOSTR__(__LINE__) +#endif /*__FILE_LINE__*/ + +#if (defined __hexagon__) || (defined __qdsp6__) +/* q6 */ + +#ifdef VERIFY_PRINT_INFO +#define FARF_VERIFY_LOW 1 +#define FARF_VERIFY_LOW_LEVEL HAP_LEVEL_LOW +#define VERIFY_IPRINTF(args...) FARF(VERIFY_LOW, args) +#endif + +#ifdef VERIFY_PRINT_ERROR +#define FARF_VERIFY_ERROR 1 +#define FARF_VERIFY_ERROR_LEVEL HAP_LEVEL_ERROR +#define VERIFY_EPRINTF(args...) FARF(VERIFY_ERROR, args) +#endif + +#if (defined VERIFY_PRINT_INFO) || (defined VERIFY_PRINT_ERROR) +#include "HAP_farf.h" +#endif + +/* end q6 */ +#elif (defined USE_SYSLOG) +/* syslog */ +#if (defined VERIFY_PRINT_INFO) || (defined VERIFY_PRINT_ERROR) +#include <syslog.h> +#endif + +#ifdef VERIFY_PRINT_INFO +#define VERIFY_IPRINTF(format, ...) syslog(LOG_USER|LOG_INFO, __V_FILE_LINE__ format, ##__VA_ARGS__) +//#define VERIFY_IPRINTF(format, ...) printf(__V_FILE_LINE__ format "\n", ##__VA_ARGS__) +#endif + +#ifdef VERIFY_PRINT_ERROR +//#define VERIFY_EPRINTF(format, ...) printf(__V_FILE_LINE__ format "\n", ##__VA_ARGS__) +#define VERIFY_EPRINTF(format, ...) syslog(LOG_USER|LOG_ERR, __V_FILE_LINE__ format, ##__VA_ARGS__) +#endif + +/* end syslog */ +#else +/* generic */ + +#if (defined VERIFY_PRINT_INFO) || (defined VERIFY_PRINT_ERROR) +#include <stdio.h> +#endif + +#ifdef VERIFY_PRINT_INFO +#define VERIFY_IPRINTF(format, ...) printf(__V_FILE_LINE__ format "\n", ##__VA_ARGS__) +#endif + +#ifdef VERIFY_PRINT_ERROR +#define VERIFY_EPRINTF(format, ...) printf(__V_FILE_LINE__ format "\n", ##__VA_ARGS__) +#endif + +/* end generic */ +#endif + +#ifndef VERIFY_PRINT_INFO +#define VERIFY_IPRINTF(format, ...) (void)0 +#endif + +#ifndef VERIFY_PRINT_ERROR +#define VERIFY_EPRINTF(format, ...) (void)0 +#endif + +#ifndef VERIFY +#define VERIFY(val) \ + do {\ + VERIFY_IPRINTF(":info: calling: %s", #val);\ + if(0 == (val)) {\ + nErr = nErr == 0 ? -1 : nErr;\ + VERIFY_EPRINTF(":error: %d: %s", nErr, #val);\ + goto bail;\ + } else {\ + VERIFY_IPRINTF(":info: passed: %s", #val);\ + }\ + } while(0) +#endif //VERIFY + +#endif //VERIFY_H + diff --git a/include/version.h b/include/version.h new file mode 100644 index 0000000..f89814d --- /dev/null +++ b/include/version.h @@ -0,0 +1,129 @@ +/* +* Copyright (c) 2017, The Linux Foundation. All rights reserved. +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1. Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2. 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. +* +* 3. Neither the name of the copyright holder 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 VERSION_H +#define VERSION_H +/*=========================================================================== + +FILE: version.h + +GENERAL DESCRIPTION: + Definitions for versioning + +===========================================================================*/ + +#if !defined(VERSION_CL) +#define VERSION_CL "?" +#endif + +#if !defined(VERSION_PROD) +#define VERSION_PROD "unknown" +#endif + +#if !defined(VERSION_BRANCH) +#define VERSION_BRANCH "?" +#endif + +#if !defined(VERSION_NUM) +#define VERSION_NUM "?.?.?.?" +#endif + +#define VERSION_STRING \ + VERSION_PROD " " \ + VERSION_NUM " " \ + "(br=" VERSION_BRANCH "; cl=" VERSION_CL ")" + +/* +======================================================================= +MACROS DOCUMENTATION +======================================================================= + +VERSION_MAJOR + +Description: + Defines the major release number of the version. + +Comments: + It has to be a valid numerical value +======================================================================= + +VERSION_MINOR + +Description: + Defines the minor release number of the version. + +Comments: + It has to be a valid numerical value +======================================================================= + +VERSION_MAINT + +Description: + Defines the maintenance release of the version. + +Comments: + It has to be a valid numerical value +======================================================================= + +VERSION_BUILD + +Description: + Defines the build ID of the version. + +Comments: + It has to be a valid numerical value +======================================================================= + +VERSION_STRING + +Description: + Defines the version string that specifies the version number. + +Definition: + + #define VERSION_STRING "a.b.c.d (name=value;name=value;...)" + where a=major release number + b=minor release number + c=maintenance release number + d=build number + + name=value pair provides additional information about the build. + Example: + patch/feature=comma separated list of features/patches that have been installed. + br=p4 branch that was used for the build + cl=p4 change list number + machine=hostname of the machine that was used for the build. + +Comments: + +======================================================================= +*/ + +#endif // VERSION_H |