/* wmInstanceLib.c - WindManage Instance library */ /* * Copyright (c) 2004-2007, 2010-2013 Wind River Systems, Inc. * * The right to copy, distribute, modify or otherwise make use * of this software may be licensed only pursuant to the terms * of an applicable Wind River license agreement. */ /* modification history -------------------- 01g,08apr13,r_w fix coverity issues for defect WIND00411995 01f,17may12,h_l replace NO_STRING with NULL_STRING (WIND00032212) 01e,03mar11,r_w prevent from accessing illegal address.defect WIND00255070 01d,29apr10,m_z eliminate compile warning 01c,29jan10,m_z VxWorks 64-bit support (WIND00193649) 01b,24feb07,msa Correct the apigen comments so they match the actual routines and correct any apigen errors that may occur. 01a,04may04,dlr derived from wmOidLib.c, adapted to string Instances */ /* DESCRIPTION This module contains support routines string-based instance manipulation. All string instance sizes include the termination character. This library does support base instances for the tables. They are not yet used, but are reserved for heirarchical WindMarks in the future. NOTE that termination character of the base Instance must be accounted for when merging or comparing Instances. INCLUDE FILES: wm.h */ /* includes */ #include "wm.h" #ifndef _WRS_CONFIG_LP64 int wmInstanceMax #else long wmInstanceMax #endif ( WM_INSTANCE_T inst ); #ifdef __WM_DEBUG__ LOCAL BOOL debugEnabled = FALSE; void wmInstanceDebug ( WM_INSTANCE_T inst, sbyte * pMsg ) { if (! debugEnabled) return; wmInstancePrint(inst, pMsg); } void wmInstanceDebugEnable ( BOOL enable ) { debugEnabled = enable; } #endif /* __WM_DEBUG__ */ /************************************************************************** * * wmInstanceMax - max possible of Instance in bytes * * * RETURNS:\is *\i ERROR_GENERAL_NOT_FOUND *\i OK *\ie * * NOMANUAL */ #ifndef _WRS_CONFIG_LP64 int wmInstanceMax #else long wmInstanceMax #endif ( WM_INSTANCE_T inst ) { return (long)wmBufferMaxGet(inst); } /************************************************************************** * * wmInstanceLen - length of Instance in bytes (the terminator is counted) * * * RETURNS:\is *\i ERROR_GENERAL_NOT_FOUND *\i OK *\ie * * NOMANUAL */ #ifndef _WRS_CONFIG_LP64 int wmInstanceLen #else long wmInstanceLen #endif ( WM_INSTANCE_T inst ) { return (long)wmBufferUsedGet(inst); } /************************************************************************** * * wmInstancePrint - print ascii Instance w/ message * * * RETURNS:\is *\i ERROR_GENERAL_NOT_FOUND *\i OK *\ie * * NOMANUAL */ void wmInstancePrint ( WM_INSTANCE_T pInstance, sbyte * pMsg ) { sbyte temp[256]; if (OK != wmInstanceStringGet(pInstance, temp, sizeof(temp))) strcpy(temp, "(empty)"); if (NULL == pMsg) printf("%s\n", temp); else printf("%s %s\n", pMsg, temp); } /************************************************************************** * * wmInstanceFromString - create inst from an ascii string * * This routine copys the string-based instance into the provided buffer, * * If is greater than the storage required, the buffer size is * increased to . * * * RETURNS:\is *\i inst buffer pointer *\i NULL *\ie * * NOMANUAL */ WM_BUFFER_T * wmInstanceFromString ( sbyte * pString, /* ascii version of inst */ #ifndef _WRS_CONFIG_LP64 int msize /* optional max buffer size in bytes */ #else long msize /* optional max buffer size in bytes */ #endif ) { WM_BUFFER_T * pInst; #ifndef _WRS_CONFIG_LP64 int len = 1; #else long len = 1; #endif if (NULL_STRING(pString)) return NULL; #ifndef _WRS_CONFIG_LP64 len = (int)strlen(pString) + 1; /* Count the terminator */ #else len = (long)strlen(pString) + 1; /* Count the terminator */ #endif if (msize < len) msize = len; /* set size of buffer to ask for */ /* create an Instance buffer */ #ifndef _WRS_CONFIG_LP64 pInst = wmBufferCreate (NULL, (unsigned int)msize, pString, DATATYPE_STRING_K, TRUE); #else pInst = wmBufferCreate (NULL, (unsigned long)msize, pString, DATATYPE_STRING_K, TRUE); #endif if (NULL == pInst) return NULL; #ifndef _WRS_CONFIG_LP64 pInst->Used = (ubyte4)len; #else pInst->Used = (ubyte8)len; #endif return (pInst); } /************************************************************************** * * wmInstanceStringSet - update inst with an ascii string inst * * This routine simply copies/appends a string-based instance * * RETURNS:\is *\i OK or ERROR *\ie * * NOMANUAL */ STATUS wmInstanceStringSet ( WM_INSTANCE_T pInstance, sbyte * pString, BOOL append ) { char * pInst; #ifndef _WRS_CONFIG_LP64 int max; int used; unsigned int len; #else long max; long used; unsigned long len; #endif if ((NULL == pString) || (NULL == pInstance)) return wmError(ERROR_GENERAL_NO_DATA, "no data"); #ifndef _WRS_CONFIG_LP64 max = (int)wmBufferMaxGet(pInstance); used = (int)wmBufferUsedGet(pInstance); #else max = (long)wmBufferMaxGet(pInstance); used = (long)wmBufferUsedGet(pInstance); #endif pInst = wmBufferDataGet(pInstance); if (NULL == pInst) { wmBufferUpdate(pInstance, NULL, 256, 0, FALSE); #ifndef _WRS_CONFIG_LP64 max = (int)wmBufferMaxGet(pInstance); #else max = (long)wmBufferMaxGet(pInstance); #endif pInst = wmBufferDataGet(pInstance); } else { if (append) pInst += used; else used = 0; } strcpy(pInst, pString); /* max !!! */ len = strlen(pString) + 1; /* count the terminator */ #ifndef _WRS_CONFIG_LP64 wmBufferUsedSet(pInstance, ((ubyte4)used + len)); #else wmBufferUsedSet(pInstance, ((ubyte8)used + len)); #endif return OK; } /************************************************************************** * * wmInstanceAppend - append one buffer onto another * * * RETURNS: ERROR or OK * * NOMANUAL */ STATUS wmInstanceAppend ( WM_INSTANCE_T pDestInst, WM_INSTANCE_T pAddInst ) { #ifndef _WRS_CONFIG_LP64 /* ubyte4 destLen;*/ ubyte4 addLen; /* ubyte4 total;*/ #else /* ubyte8 destLen;*/ ubyte8 addLen; /* ubyte8 total;*/ #endif /*sbyte * pDest;*/ sbyte * pAdd; if (NULL == pDestInst || NULL == pAddInst) return wmError(ERROR_GENERAL_NO_DATA, "wmInstanceAppend: null arg(s)"); /*pDest = wmBufferDataGet(pDestInst);*/ pAdd = wmBufferDataGet(pAddInst); /* total = wmBufferMaxGet(pDestInst); destLen = wmBufferUsedGet(pDestInst);*/ addLen = wmBufferUsedGet(pAddInst); /* wmBufferAppend will skip terminator in the Dest string instance buffer */ return wmBufferAppend(pDestInst, pAdd, addLen); } /************************************************************************** * * wmInstanceEqual - compare 2 insts * * RETURNS: TRUE if same * * NOMANUAL */ BOOL wmInstanceEqual ( WM_INSTANCE_T orig, WM_INSTANCE_T test ) { #ifndef _WRS_CONFIG_LP64 ubyte4 destLen; ubyte4 addLen; #else ubyte8 destLen; ubyte8 addLen; #endif sbyte * pDest; sbyte * pAdd; pDest = wmBufferDataGet(orig); pAdd = wmBufferDataGet(test); if (NULL == pDest || NULL == pAdd) return FALSE; destLen = wmBufferUsedGet(orig); addLen = wmBufferUsedGet(test); /* make sure there's enough space (fix later: just resize) */ if (addLen != destLen) return FALSE; return (0 == memcmp(pDest, pAdd, addLen)); } /************************************************************************** * * wmInstanceCmp - compare 2 insts * * RETURNS: * * NOMANUAL */ int wmInstanceCmp ( WM_INSTANCE_T orig, WM_INSTANCE_T test ) { #ifndef _WRS_CONFIG_LP64 ubyte4 i; ubyte4 origLen; ubyte4 testLen; #else ubyte8 i; ubyte8 origLen; ubyte8 testLen; #endif ubyte * pOrig; ubyte * pTest; pOrig = wmBufferDataGet(orig); pTest = wmBufferDataGet(test); if (NULL == pTest || NULL == pOrig) return 0; origLen = wmBufferUsedGet(orig) - 1; /* skip terminators */ testLen = wmBufferUsedGet(test) - 1; for (i = 0; (i < origLen) && (i < testLen); i++, pOrig++, pTest++) { if (*pOrig < *pTest) return -1; if (*pOrig > *pTest) return 1; } /* so far they are the same */ if (origLen < testLen) return -1; if (origLen > testLen) return 1; return 0; } /************************************************************************** * * wmInstanceTruncate - truncate inst * * * RETURNS: ERROR or OK * * NOMANUAL */ STATUS wmInstanceTruncate ( WM_INSTANCE_T inst, #ifndef _WRS_CONFIG_LP64 sbyte4 length /* in bytes */ #else sbyte8 length /* in bytes */ #endif ) { sbyte * pData; #ifndef _WRS_CONFIG_LP64 ubyte4 used; ubyte4 max; #else ubyte8 used; ubyte8 max; #endif pData = wmBufferDataGet (inst); max = wmBufferMaxGet (inst); used = wmBufferUsedGet (inst); pData += length; #ifndef _WRS_CONFIG_LP64 if (length > (sbyte4)used) #else if (length > (sbyte8)used) #endif return wmError(ERROR_GENERAL_ILLEGAL_VALUE, "wmInstanceTruncate: length too long"); /* nothing to do */ #ifndef _WRS_CONFIG_LP64 if (length == (sbyte4)used) #else if (length == (sbyte8)used) #endif return OK; #ifndef _WRS_CONFIG_LP64 memset(pData, 0, (max - (ubyte4)length)); /* the zero's double as the string terminator */ wmBufferUsedSet(inst, (ubyte4)length); #else memset(pData, 0, (max - (ubyte8)length)); /* the zero's double as the string terminator */ wmBufferUsedSet(inst, (ubyte8)length); #endif return OK; } /************************************************************************** * * wmInstanceSuffix - create new buffer containing unique instance suffix * * * RETURNS: buffer with suffix only * * NOMANUAL */ WM_INSTANCE_T wmInstanceSuffix ( WM_INSTANCE_T pBaseInst, WM_INSTANCE_T pFullInst ) { WM_INSTANCE_T pSuffix; #ifndef _WRS_CONFIG_LP64 ubyte4 baseLen; ubyte4 fullLen; ubyte4 index; #else ubyte8 baseLen; ubyte8 fullLen; ubyte8 index; #endif sbyte * pBase; sbyte * pFull; if (NULL == pBaseInst || NULL == pFullInst) return NULL; pBase = wmBufferDataGet (pBaseInst); pFull = wmBufferDataGet (pFullInst); baseLen = wmBufferUsedGet (pBaseInst); fullLen = wmBufferUsedGet (pFullInst); if (baseLen >= fullLen) return NULL; /* Skip the zero terminator */ if (0 < baseLen) baseLen--; /* base should match beginning of full */ if (0 != baseLen) for (index = baseLen; index > 0; index --, pBase++, pFull++) { if (*pBase != *pFull) return NULL; } /* only create suffix if it doesn't already exist */ fullLen -= baseLen; pSuffix = wmBufferCreate(NULL, fullLen, pFull, wmBufferTypeGet(pFullInst), TRUE); return pSuffix; } /************************************************************************** * * wmInstanceScalerSet - there is currently no definition for non-OID scalars * * RETURNS: OK * * * NOMANUAL */ #if 0 void wmInstanceScalerSet ( WM_INSTANCE_T inst ) { int zero = 0; wmBufferAppend(inst, &zero, sizeof(zero)); } /* return if scaler */ BOOL wmInstanceScaler ( WM_INSTANCE_T inst ) { int * pData; int size; if (0 >= (size = wmBufferUsedGet(inst))) return FALSE; pData = wmBufferDataGet(inst); pData += size; return (*pData == 0); } #endif /* 0 */ /************************************************************************** * * wmInstanceStringGet - create ascii version of inst * * * RETURNS:\is *\i ERROR_GENERAL_NOT_FOUND *\i OK *\ie * * NOMANUAL */ STATUS wmInstanceStringGet ( WM_INSTANCE_T inst, sbyte * pString, #ifndef _WRS_CONFIG_LP64 sbyte4 strLen #else sbyte8 strLen #endif ) { int * pData; #ifndef _WRS_CONFIG_LP64 sbyte4 instLen; #else sbyte8 instLen; #endif if (wmInstanceBad(inst)) return wmError(ERROR_GENERAL_INVALID, "wmInstanceStringGet: bad inst"); pData = wmBufferDataGet (inst); #ifndef _WRS_CONFIG_LP64 instLen = (sbyte4)wmBufferUsedGet (inst); #else instLen = (sbyte8)wmBufferUsedGet (inst); #endif if (NULL == pData || 1 > instLen) return wmError(ERROR_GENERAL_NO_DATA, "wmInstanceStringGet: no data"); if (strLen < instLen) /* string terminators are already included in these sizes */ return wmError(ERROR_GENERAL_NO_DATA, "wmInstanceStringGet: dest buffer too small"); strcpy(pString, (char *) pData); return OK; } /************************************************************************** * * wmInstanceValid - does Instance contain valid data * * * RETURNS:\is *\i ERROR *\i OK *\ie * * NOMANUAL */ STATUS wmInstanceValid ( WM_INSTANCE_T inst ) { if (wmInvalid(inst)) return wmError(ERROR_GENERAL_INVALID, "wmInstanceInvalid: bad Instance"); if (wmInvalid(wmBufferDataGet(inst))) return wmError(ERROR_GENERAL_INVALID, "wmInstanceInvalid: bad data"); return OK; } /************************************************************************** * * wmBufferSuffix - copy unique portion of buffer * * RETURNS: N/A * * * NOMANUAL */ STATUS wmBufferInstSuffix ( WM_BUFFER_T * pRoot, /* [in] root buffer */ WM_BUFFER_T * pFull, /* [in] complete buffer */ WM_BUFFER_T * pSuffix /* [in/out] portion complete root lacks */ ) { sbyte * pRootData = NULL; sbyte * pFullData = NULL; #ifndef _WRS_CONFIG_LP64 ubyte4 rootLen; ubyte4 fullLen; #else ubyte8 rootLen; ubyte8 fullLen; #endif pRootData = wmBufferDataGet(pRoot); pFullData = wmBufferDataGet(pFull); if((NULL == pRootData)||(NULL == pFullData)) { wmInstancePrint(pRoot, "root"); wmInstancePrint(pFull, "full"); return ERROR; } rootLen = wmBufferUsedGet(pRoot) - 1; /* don't count the zero terminator here */ fullLen = wmBufferUsedGet(pFull); if (memcmp(pRootData, pFullData, rootLen) != 0) { wmInstancePrint(pRoot, "root"); wmInstancePrint(pFull, "full"); return ERROR; } return wmBufferUpdate (pSuffix, &pFullData[rootLen], fullLen - rootLen, wmBufferTypeGet(pFull), TRUE); } /* eof wmInstanceLib.c */