//| Copyright: (C) 2009-2020 Kevin Larke //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file. #include "cmPrefix.h" #include "cmGlobal.h" #include "cmRpt.h" #include "cmErr.h" #include "cmCtx.h" #include "cmMem.h" #include "cmMallocDebug.h" #include "cmLinkedHeap.h" #include "cmSerialize.h" #define cmSrVersion (0) #ifdef cmBIG_ENDIAN #define _cmSrSwap16(v) (v) #define _cmSrSwap32(v) (v) #define _cmSrSwapFl (0) #else #define _cmSrSwap16(v) (v) #define _cmSrSwap32(v) (v) #define _cmSrSwapFl (1) #endif typedef struct { const char* label; unsigned typeId; unsigned byteCnt; bool swapFl; } _cmSrPrim_t; struct _cmSrStruct_str; // structure field desc record typedef struct _cmSrField_str { const _cmSrPrim_t* primPtr; struct _cmSrStruct_str* structPtr; bool arrayFl; struct _cmSrField_str* linkPtr; } _cmSrField_t; // structure description record typedef struct _cmSrStruct_str { unsigned typeId; _cmSrField_t* fieldList; struct _cmSrStruct_str* linkPtr; } _cmSrStruct_t; // state records track the format for read/write operations typedef struct _cmSrState_str { _cmSrStruct_t* structPtr; // this states current structure _cmSrField_t* fieldPtr; // this states current field struct _cmSrState_str* linkPtr; // prev state on stack unsigned arrayCnt; // array count for this struct array unsigned arrayIdx; // current array index for this struct array } _cmSrState_t; // data records are formed by each write operation typedef struct _cmSrData_str { unsigned typeId; unsigned eleCnt; unsigned byteCnt; void* dataPtr; bool arrayFl; bool swapFl; struct _cmSrData_str* linkPtr; } _cmSrData_t; typedef struct { cmErr_t err; cmLHeapH_t lhH; _cmSrStruct_t* structList; _cmSrState_t* wrStackPtr; _cmSrData_t* wrDataList; char* wrDataBufPtr; unsigned wrDataBufByteCnt; _cmSrState_t* rdStackPtr; const void* rdDataBufPtr; unsigned rdDataBufByteCnt; const char* rdCursorPtr; unsigned rdVersion; unsigned rdFlags; cmSrRC_t lastRC; } _cmSr_t; _cmSrPrim_t _cmSrPrimArray[] = { {"char", kCharSrId, sizeof(char), false }, {"uchar", kUCharSrId, sizeof(char), false }, {"short", kShortSrId, sizeof(short), true }, {"ushort", kUShortSrId, sizeof(unsigned short), true }, {"int", kIntSrId, sizeof(int), true }, {"uint", kUIntSrId, sizeof(unsigned), true }, {"long", kLongSrId, sizeof(long), true }, {"ulong", kLongSrId, sizeof(unsigned long), true }, {"float", kFloatSrId, sizeof(float), false }, {"double", kDoubleSrId, sizeof(double), false }, {"bool", kBoolSrId, sizeof(bool), sizeof(bool)>1 }, {"", kInvalidSrId, 0, false } }; cmSrH_t cmSrNullHandle = { NULL }; void _cmSrPrint( _cmSr_t* p, const char* fmt, ... ) { va_list vl; va_start(vl,fmt); //p->rptFuncPtr(p->rptUserPtr,fmt,vl); cmRptVPrintf( p->err.rpt, fmt, vl ); va_end(vl); } /* cmSrRC_t _cmSrErrorV( cmSrRC_t rc, _cmSr_t* p, const char* fmt, va_list vl ) { const int bufCharCnt = 511; char buf[bufCharCnt+1]; snprintf(buf,bufCharCnt,"Serializer Error code:%i ",rc); unsigned n = strlen(buf); vsnprintf(buf+n,bufCharCnt-n,fmt,vl); buf[bufCharCnt]=0; _cmSrPrint(p,"%s\n",buf); p->lastRC = rc; return rc; } */ cmSrRC_t _cmSrError( cmSrRC_t rc, _cmSr_t* p, const char* fmt, ... ) { va_list vl; va_start(vl,fmt); cmErrVMsg(&p->err,rc,fmt,vl); va_end(vl); return rc; } _cmSr_t* _cmSrHandleToPtr( cmSrH_t h ) { assert( h.h != NULL ); return (_cmSr_t*)h.h; } const _cmSrPrim_t* _cmSrIdToPrimPtr( unsigned primId ) { unsigned i; for(i=0; _cmSrPrimArray[i].typeId != kInvalidSrId; ++i) if( _cmSrPrimArray[i].typeId == primId ) return _cmSrPrimArray + i; return NULL; } _cmSrStruct_t* _cmSrIdToStructPtr( _cmSr_t* p, unsigned typeId ) { _cmSrStruct_t* sp = p->structList; for(; sp != NULL; sp = sp->linkPtr ) if( sp->typeId == typeId ) return sp; return NULL; } void _cmSrClearStructList( _cmSr_t* p ) { _cmSrStruct_t* csp = p->structList; while( csp != NULL ) { _cmSrStruct_t* nsp = csp->linkPtr; _cmSrField_t* cfp = csp->fieldList; while( cfp != NULL ) { _cmSrField_t* nfp = cfp->linkPtr; cmLHeapFree(p->lhH,cfp); cfp = nfp; } cmLHeapFree(p->lhH,csp); csp = nsp; } p->structList = NULL; } void _cmSrClearDataList( _cmSr_t* p ) { _cmSrData_t* cdp = p->wrDataList; while( cdp != NULL ) { _cmSrData_t* ndp = cdp->linkPtr; cmLHeapFree( p->lhH, cdp ); cdp = ndp; } p->wrDataList = NULL; } cmSrRC_t _cmSrPopStateStack( _cmSr_t* p, _cmSrState_t** stackPtrPtr ) { cmSrRC_t rc = kOkSrRC; _cmSrState_t* stackPtr = *stackPtrPtr; _cmSrState_t* sp = stackPtr; assert( sp != NULL ); stackPtr = sp->linkPtr; if( sp->arrayCnt != cmInvalidCnt && sp->arrayIdx != sp->arrayCnt ) rc = _cmSrError( kFormatViolationSrRC, p, "A type %i structure array field promised %i elements but only %i written.",sp->structPtr->typeId,sp->arrayCnt,sp->arrayIdx); cmLHeapFree(p->lhH,sp); *stackPtrPtr = stackPtr; return rc; } void _cmSrClearStateStack( _cmSr_t* p, _cmSrState_t** stackPtrPtr ) { while( *stackPtrPtr != NULL ) if( _cmSrPopStateStack( p, stackPtrPtr ) != kOkSrRC ) break; } cmSrRC_t _cmSrFree( _cmSr_t* p ) { cmSrRC_t rc = kOkSrRC; _cmSrClearDataList(p); _cmSrClearStateStack(p,&p->wrStackPtr); _cmSrClearStateStack(p,&p->rdStackPtr); cmMemPtrFree(&p->wrDataBufPtr); cmLHeapDestroy( &p->lhH ); cmMemPtrFree(&p); return rc; } cmSrRC_t cmSrAlloc( cmSrH_t* hp, cmCtx_t* ctx ) { cmSrRC_t rc = kOkSrRC; _cmSr_t* p = cmMemAllocZ( _cmSr_t, 1 ); cmErrSetup(&p->err,&ctx->rpt,"Serializer"); p->structList = NULL; p->lastRC = kOkSrRC; if( cmLHeapIsValid( p->lhH = cmLHeapCreate(1024,ctx)) == false ) { rc = _cmSrError( kLHeapFailSrRC, p, "Linked heap initialization failed."); goto errLabel; } hp->h = p; errLabel: return rc; } cmSrRC_t cmSrFree( cmSrH_t* hp ) { cmSrRC_t rc = kOkSrRC; _cmSr_t* p = NULL; if( hp == NULL ) return kOkSrRC; if( cmSrIsValid(*hp) == false ) return kOkSrRC; p = _cmSrHandleToPtr(*hp); if(( rc = _cmSrFree(p)) != kOkSrRC ) goto errLabel; hp->h = NULL; errLabel: return rc; } bool cmSrIsValid( cmSrH_t h ) { return h.h != NULL; } cmSrRC_t cmSrLastErrorCode( cmSrH_t h ) { _cmSr_t* p = _cmSrHandleToPtr(h); return p->lastRC; } cmSrRC_t cmSrGetAndClearLastErrorCode( cmSrH_t h ) { _cmSr_t* p = _cmSrHandleToPtr(h); cmSrRC_t rc = p->lastRC; p->lastRC = kOkSrRC; return rc; } cmSrRC_t cmSrFmtReset( cmSrH_t h ) { _cmSr_t* p = _cmSrHandleToPtr(h); _cmSrClearStructList(p); p->lastRC = kOkSrRC; return cmSrWrReset(h); } cmSrRC_t cmSrFmtDefineStruct( cmSrH_t h, unsigned structTypeId ) { cmSrRC_t rc = kOkSrRC; _cmSr_t* p = _cmSrHandleToPtr(h); _cmSrStruct_t* structPtr = NULL; assert( structTypeId >= kStructSrId ); if( p->lastRC != kOkSrRC ) return p->lastRC; if( structTypeId < kStructSrId ) { rc = _cmSrError( kParamErrSrRC, p, "The structure type id %i is no greater than or equal to %i. (kStructSrId)",structTypeId,kStructSrId ); goto errLabel; } if( _cmSrIdToStructPtr( p, structTypeId ) != NULL) { rc = _cmSrError( kParamErrSrRC, p, "The structure type id %i is already in use.",structTypeId ); goto errLabel; } if(( structPtr = (_cmSrStruct_t*)cmLHeapAllocZ( p->lhH, sizeof(_cmSrStruct_t))) == NULL ) { rc = _cmSrError( kLHeapFailSrRC, p, "New structure allocate failed."); goto errLabel; } structPtr->typeId = structTypeId; structPtr->linkPtr = p->structList; p->structList = structPtr; errLabel: return rc; } cmSrRC_t _cmSrFmtField( cmSrH_t h, unsigned typeId, bool arrayFl ) { cmSrRC_t rc = kOkSrRC; _cmSrStruct_t* structPtr = NULL; const _cmSrPrim_t* primPtr = NULL; _cmSrField_t* fieldPtr = NULL; _cmSrField_t* cfp = NULL; _cmSrField_t* pfp = NULL; _cmSr_t* p = _cmSrHandleToPtr(h); if( p->lastRC != kOkSrRC ) return p->lastRC; if( typeId >= kStructSrId ) { if(( structPtr = _cmSrIdToStructPtr( p, typeId )) == NULL ) { rc = _cmSrError( kParamErrSrRC, p, "The structure associated with the type id %i could not be found.",typeId); goto errLabel; } } else { if( (typeId==kInvalidSrId) || ((primPtr = _cmSrIdToPrimPtr( typeId )) == NULL) ) { rc = _cmSrError( kParamErrSrRC, p, "Type primitive type id %i is not valid.",typeId); goto errLabel; } } if(( fieldPtr = (_cmSrField_t*)cmLHeapAllocZ( p->lhH, sizeof(_cmSrField_t))) == NULL ) { rc = _cmSrError( kLHeapFailSrRC, p, "Field allocation failed for type %i.",typeId ); goto errLabel; } fieldPtr->primPtr = primPtr; fieldPtr->structPtr = structPtr; fieldPtr->arrayFl = arrayFl; pfp = NULL; cfp = p->structList->fieldList; for(; cfp != NULL; cfp = cfp->linkPtr ) pfp = cfp; if( pfp == NULL ) p->structList->fieldList = fieldPtr; else pfp->linkPtr = fieldPtr; errLabel: return rc; } cmSrRC_t cmSrFmtStruct( cmSrH_t h, unsigned id ) { return _cmSrFmtField(h,id, false); } cmSrRC_t cmSrFmtChar( cmSrH_t h ) { return _cmSrFmtField(h,kCharSrId, false); } cmSrRC_t cmSrFmtUChar( cmSrH_t h ) { return _cmSrFmtField(h,kUCharSrId, false); } cmSrRC_t cmSrFmtShort( cmSrH_t h ) { return _cmSrFmtField(h,kShortSrId, false); } cmSrRC_t cmSrFmtUShort( cmSrH_t h ) { return _cmSrFmtField(h,kUShortSrId, false); } cmSrRC_t cmSrFmtLong( cmSrH_t h ) { return _cmSrFmtField(h,kLongSrId, false); } cmSrRC_t cmSrFmtULong( cmSrH_t h ) { return _cmSrFmtField(h,kULongSrId, false); } cmSrRC_t cmSrFmtInt( cmSrH_t h ) { return _cmSrFmtField(h,kIntSrId, false); } cmSrRC_t cmSrFmtUInt( cmSrH_t h ) { return _cmSrFmtField(h,kUIntSrId, false); } cmSrRC_t cmSrFmtFloat( cmSrH_t h ) { return _cmSrFmtField(h,kFloatSrId, false); } cmSrRC_t cmSrFmtDouble( cmSrH_t h ) { return _cmSrFmtField(h,kDoubleSrId, false); } cmSrRC_t cmSrFmtBool( cmSrH_t h ) { return _cmSrFmtField(h,kBoolSrId, false); } cmSrRC_t cmSrFmtStructV( cmSrH_t h, unsigned id ){ return _cmSrFmtField(h,id, true); } cmSrRC_t cmSrFmtCharV( cmSrH_t h ) { return _cmSrFmtField(h,kCharSrId, true); } cmSrRC_t cmSrFmtUCharV( cmSrH_t h ) { return _cmSrFmtField(h,kUCharSrId, true); } cmSrRC_t cmSrFmtShortV( cmSrH_t h ) { return _cmSrFmtField(h,kShortSrId, true); } cmSrRC_t cmSrFmtUShortV( cmSrH_t h ) { return _cmSrFmtField(h,kUShortSrId, true); } cmSrRC_t cmSrFmtLongV( cmSrH_t h ) { return _cmSrFmtField(h,kLongSrId, true); } cmSrRC_t cmSrFmtULongV( cmSrH_t h ) { return _cmSrFmtField(h,kULongSrId, true); } cmSrRC_t cmSrFmtIntV( cmSrH_t h ) { return _cmSrFmtField(h,kIntSrId, true); } cmSrRC_t cmSrFmtUIntV( cmSrH_t h ) { return _cmSrFmtField(h,kUIntSrId, true); } cmSrRC_t cmSrFmtFloatV( cmSrH_t h ) { return _cmSrFmtField(h,kFloatSrId, true); } cmSrRC_t cmSrFmtDoubleV( cmSrH_t h ) { return _cmSrFmtField(h,kDoubleSrId, true); } cmSrRC_t cmSrFmtBoolV( cmSrH_t h ) { return _cmSrFmtField(h,kBoolSrId, true); } cmSrRC_t cmSrDefFmt( cmSrH_t h, unsigned structTypeId, ... ) { cmSrRC_t rc = kOkSrRC; va_list vl; va_start(vl,structTypeId); if((rc = cmSrFmtDefineStruct( h, structTypeId )) != kOkSrRC ) goto errLabel; unsigned typeId = kCharSrId; while( typeId != kInvalidSrId ) { typeId = va_arg(vl,unsigned); if( typeId == kInvalidSrId ) break; bool arrayFl = cmIsFlag(typeId,kArraySrFl); typeId = cmClrFlag(typeId,kArraySrFl); if(( rc = _cmSrFmtField(h,typeId,arrayFl)) != kOkSrRC ) goto errLabel; } errLabel: va_end(vl); return rc; } cmSrRC_t cmSrFmtPrint( cmSrH_t h ) { _cmSr_t* p = _cmSrHandleToPtr(h); cmSrRC_t rc = kOkSrRC; const _cmSrStruct_t* sp = p->structList; for(; sp != NULL; sp = sp->linkPtr ) { _cmSrPrint( p, "struct: %i", sp->typeId ); unsigned indent = 2; const _cmSrField_t* fp = sp->fieldList; for(; fp != NULL; fp = fp->linkPtr ) { unsigned i; char sp[ indent+1 ]; sp[indent]=0; for(i=0; iprimPtr != NULL ) _cmSrPrint( p, "%s prim: %i %s%s", sp, fp->primPtr->byteCnt, fp->primPtr->label, fp->arrayFl?"[]":"" ); else { _cmSrPrint( p, "%s struct: %i %s", sp, fp->structPtr->typeId, fp->arrayFl?"[]":"" ); indent += 2; } } } _cmSrPrint(p,"\n"); return rc; } cmSrRC_t _cmSrPushStateStack( _cmSr_t* p, unsigned structTypeId, _cmSrState_t** stackPtrPtr ) { cmSrRC_t rc = kOkSrRC; _cmSrStruct_t* refStructPtr; _cmSrState_t* stackPtr = *stackPtrPtr; // if this is the base structure then the wr stack will be empty if( stackPtr == NULL ) refStructPtr = p->structList; else { // the wr stack contains members so this structure type should be the same as the current field type assert( stackPtr->fieldPtr != NULL ); refStructPtr = stackPtr->fieldPtr->structPtr; } // no reference structure exists if( refStructPtr == NULL ) { // if the write state stack is empty then the structList must also be empty if( stackPtr == NULL ) { rc = _cmSrError( kFormatViolationSrRC, p, "Cannot write data without first providing the data format."); goto errLabel; } else { // the data format has been described but the current format field is not a structure assert( stackPtr->fieldPtr->primPtr != NULL ); rc = _cmSrError( kFormatViolationSrRC, p, "Format violation. Expected primitive type:'%s'.", cmStringNullGuard(stackPtr->fieldPtr->primPtr->label )); goto errLabel; } } // if wrong type of structure if( refStructPtr->typeId != structTypeId ) { rc = _cmSrError( kFormatViolationSrRC, p, "Format violation. Expected structure type:%i instead of structure type:%i.",refStructPtr->typeId,structTypeId ); goto errLabel; } // allocate the new structure state _cmSrState_t* wsp = (_cmSrState_t*)cmLHeapAllocZ( p->lhH, sizeof(_cmSrState_t)); assert( wsp != NULL ); // push the new structure state on the stack wsp->structPtr = refStructPtr; wsp->fieldPtr = NULL; wsp->linkPtr = stackPtr; wsp->arrayCnt = cmInvalidCnt; wsp->arrayIdx = cmInvalidIdx; stackPtr = wsp; *stackPtrPtr = stackPtr; errLabel: return rc; } cmSrRC_t cmSrWrReset( cmSrH_t h ) { cmSrRC_t rc = kOkSrRC; _cmSr_t* p = _cmSrHandleToPtr(h); _cmSrClearStateStack(p,&p->wrStackPtr); p->wrStackPtr = NULL; _cmSrClearDataList(p); cmMemPtrFree(&p->wrDataBufPtr); p->wrDataBufByteCnt = 0; return rc; } cmSrRC_t _cmSrOnStruct( _cmSr_t* p, unsigned structTypeId, _cmSrState_t** stackPtrPtr ) { cmSrRC_t rc = kOkSrRC; if( p->lastRC != kOkSrRC ) return p->lastRC; if((rc = _cmSrPushStateStack(p,structTypeId,stackPtrPtr)) != kOkSrRC ) goto errLabel; _cmSrState_t* stackPtr = *stackPtrPtr; // the base structure is never an array so it's linkPtr is NULL if( stackPtr->linkPtr != NULL ) { stackPtr->linkPtr->arrayIdx += 1; if( stackPtr->linkPtr->arrayIdx > stackPtr->linkPtr->arrayCnt ) { rc = _cmSrError( kFormatViolationSrRC, p, "The structure array is out of bounds (array count:%i).",stackPtr->linkPtr->arrayIdx ); goto errLabel; } } *stackPtrPtr = stackPtr; errLabel: return rc; } cmSrRC_t cmSrWrStructBegin( cmSrH_t h, unsigned structTypeId ) { _cmSr_t* p = _cmSrHandleToPtr(h); return _cmSrOnStruct( p, structTypeId, &p->wrStackPtr ); } cmSrRC_t cmSrWrStructEnd( cmSrH_t h ) { _cmSr_t* p = _cmSrHandleToPtr(h); assert( p->wrStackPtr != NULL ); if( p->lastRC != kOkSrRC ) return p->lastRC; return _cmSrPopStateStack(p, &p->wrStackPtr); } cmSrRC_t _cmSrWrField( cmSrH_t h, unsigned typeId, const void* dataPtr, unsigned eleCnt ) { cmSrRC_t rc = kOkSrRC; _cmSr_t* p = _cmSrHandleToPtr(h); _cmSrField_t* refFieldPtr = NULL; unsigned refTypeId = cmInvalidId; unsigned dataByteCnt = 0; _cmSrData_t* dataRecdPtr = NULL; bool swapFl = false; if( p->lastRC != kOkSrRC ) return p->lastRC; // verify the write stack exists if( p->wrStackPtr == NULL ) { rc = _cmSrError( kFormatViolationSrRC, p, "The reference format is unexpectedly empty."); goto errLabel; } // // advance the current field // // if cur state fieldPtr is NULL then this is the first field in a structure if( p->wrStackPtr->fieldPtr == NULL ) p->wrStackPtr->fieldPtr = p->wrStackPtr->structPtr->fieldList; else p->wrStackPtr->fieldPtr = p->wrStackPtr->fieldPtr->linkPtr; // verify that a reference field exists refFieldPtr = p->wrStackPtr->fieldPtr; if( refFieldPtr == NULL ) { rc = _cmSrError( kFormatViolationSrRC, p, "The format reference structure has run out of fields."); goto errLabel; } // validate the array status of this field if( refFieldPtr->arrayFl==false && eleCnt>1 ) { rc = _cmSrError( kFormatViolationSrRC, p, "The format reference indicates that this field is not an array however an array element count (%i) was given.",eleCnt); goto errLabel; } // get the reference type id refTypeId = refFieldPtr->primPtr == NULL ? refFieldPtr->structPtr->typeId : refFieldPtr->primPtr->typeId; // verify that the type being written matches the reference type if( refTypeId != typeId ) { const char* refLbl = "struct"; const char* cmtLbl = refLbl; if( refFieldPtr->primPtr != NULL ) refLbl = refFieldPtr->primPtr->label; if( typeId < kStructSrId ) cmtLbl = _cmSrIdToPrimPtr( typeId )->label; rc = _cmSrError( kFormatViolationSrRC, p, "Format violation: Exepected type %i (%s) but received %i (%s).", refTypeId,refLbl,typeId,cmtLbl); goto errLabel; } if( typeId < kStructSrId ) { dataByteCnt += refFieldPtr->primPtr->byteCnt * eleCnt; swapFl = refFieldPtr->primPtr->swapFl && _cmSrSwapFl; } else { p->wrStackPtr->arrayCnt = eleCnt; p->wrStackPtr->arrayIdx = 0; } dataRecdPtr = (_cmSrData_t*)cmLHeapAllocZ( p->lhH, sizeof(_cmSrData_t) + dataByteCnt ); // iniit the new data recd dataRecdPtr->typeId = typeId; dataRecdPtr->eleCnt = eleCnt; dataRecdPtr->byteCnt = dataByteCnt; dataRecdPtr->arrayFl = refFieldPtr->arrayFl; dataRecdPtr->swapFl = swapFl; dataRecdPtr->linkPtr = NULL; dataRecdPtr->dataPtr = dataRecdPtr + 1; if( dataByteCnt > 0 ) memcpy( dataRecdPtr->dataPtr, dataPtr, dataByteCnt ); // link the new data recd to the end of the data chain _cmSrData_t* dp = p->wrDataList; for(; dp != NULL; dp = dp->linkPtr ) if( dp->linkPtr == NULL ) break; if( p->wrDataList == NULL ) p->wrDataList = dataRecdPtr; else dp->linkPtr = dataRecdPtr; errLabel: return rc; } cmSrRC_t cmSrWrStruct( cmSrH_t h, unsigned structTypeId, unsigned eleCnt ) { return _cmSrWrField(h,structTypeId,NULL,eleCnt); } cmSrRC_t cmSrWrChar( cmSrH_t h, char val ) { return _cmSrWrField(h,kCharSrId,&val,1); } cmSrRC_t cmSrWrUChar( cmSrH_t h, unsigned char val ) { return _cmSrWrField(h,kUCharSrId,&val,1); } cmSrRC_t cmSrWrShort( cmSrH_t h, short val ) { return _cmSrWrField(h,kShortSrId,&val,1); } cmSrRC_t cmSrWrUShort( cmSrH_t h, unsigned short val ) { return _cmSrWrField(h,kUShortSrId,&val,1); } cmSrRC_t cmSrWrLong( cmSrH_t h, long val ) { return _cmSrWrField(h,kLongSrId,&val,1); } cmSrRC_t cmSrWrULong( cmSrH_t h, unsigned long val ) { return _cmSrWrField(h,kULongSrId,&val,1); } cmSrRC_t cmSrWrInt( cmSrH_t h, int val ) { return _cmSrWrField(h,kIntSrId,&val,1); } cmSrRC_t cmSrWrUInt( cmSrH_t h, unsigned val ) { return _cmSrWrField(h,kUIntSrId,&val,1); } cmSrRC_t cmSrWrFloat( cmSrH_t h, float val ) { return _cmSrWrField(h,kFloatSrId,&val,1); } cmSrRC_t cmSrWrDouble( cmSrH_t h, double val ) { return _cmSrWrField(h,kDoubleSrId,&val,1); } cmSrRC_t cmSrWrBool( cmSrH_t h, bool val ) { return _cmSrWrField(h,kBoolSrId,&val,1); } cmSrRC_t cmSrWrStr( cmSrH_t h, const char* val ) { const char* ns = ""; if( val == NULL ) val = ns; return _cmSrWrField(h,kCharSrId,val,strlen(val)+1); } cmSrRC_t _cmSrWrArrayField( cmSrH_t h, unsigned typeId, const void* val, unsigned eleCnt ) { if( val == NULL || eleCnt == 0 ) { val = NULL; eleCnt = 0; } return _cmSrWrField(h,typeId,val,eleCnt); } cmSrRC_t cmSrWrCharV( cmSrH_t h, const char* val, unsigned eleCnt ) { return _cmSrWrArrayField(h,kCharSrId,val,eleCnt); } cmSrRC_t cmSrWrUCharV( cmSrH_t h, const unsigned char* val, unsigned eleCnt ) { return _cmSrWrArrayField(h,kUCharSrId,val,eleCnt); } cmSrRC_t cmSrWrShortV( cmSrH_t h, const short* val, unsigned eleCnt ) { return _cmSrWrArrayField(h,kShortSrId,val,eleCnt); } cmSrRC_t cmSrWrUShortV( cmSrH_t h, const unsigned short* val, unsigned eleCnt ) { return _cmSrWrArrayField(h,kUShortSrId,val,eleCnt); } cmSrRC_t cmSrWrLongV( cmSrH_t h, const long* val, unsigned eleCnt ) { return _cmSrWrArrayField(h,kLongSrId,val,eleCnt); } cmSrRC_t cmSrWrULongV( cmSrH_t h, const unsigned long* val, unsigned eleCnt ) { return _cmSrWrArrayField(h,kULongSrId,val,eleCnt); } cmSrRC_t cmSrWrIntV( cmSrH_t h, const int* val, unsigned eleCnt ) { return _cmSrWrArrayField(h,kIntSrId,val,eleCnt); } cmSrRC_t cmSrWrUIntV( cmSrH_t h, const unsigned* val, unsigned eleCnt ) { return _cmSrWrArrayField(h,kUIntSrId,val,eleCnt); } cmSrRC_t cmSrWrFloatV( cmSrH_t h, const float* val, unsigned eleCnt ) { return _cmSrWrArrayField(h,kFloatSrId,val,eleCnt); } cmSrRC_t cmSrWrDoubleV( cmSrH_t h, const double* val, unsigned eleCnt ) { return _cmSrWrArrayField(h,kDoubleSrId,val,eleCnt); } cmSrRC_t cmSrWrBoolV( cmSrH_t h, const bool* val, unsigned eleCnt ) { return _cmSrWrArrayField(h,kBoolSrId,val,eleCnt); } void _cmSrCopyDataToBuf( void* dstPtr, const void* srcPtr, unsigned byteCnt, unsigned typeId, bool swapFl, unsigned eleCnt ) { if( !swapFl ) { memcpy(dstPtr,srcPtr,byteCnt); return; } switch( typeId ) { case kShortSrId: case kUShortSrId: { unsigned i; const short* sp = (const short*)srcPtr; short* dp = (short*)dstPtr; for(i=0; iwrDataList;; assert( bufByteCntPtr != NULL ); *bufByteCntPtr = 0; p->wrDataBufByteCnt = 2 * sizeof(unsigned); // header words if( p->lastRC != kOkSrRC ) return NULL; // determine the data buf size for(; cdp!=NULL; cdp = cdp->linkPtr ) { // include spcme for structure type id if( cdp->typeId >= kStructSrId ) p->wrDataBufByteCnt += sizeof(unsigned); // include spcme for array element count if( cdp->arrayFl ) p->wrDataBufByteCnt += sizeof(unsigned); // include spcme for cmtual data p->wrDataBufByteCnt += cdp->byteCnt; } // allocate the data buffer p->wrDataBufPtr = cmMemResizeZ( char, p->wrDataBufPtr, p->wrDataBufByteCnt ); cdp = p->wrDataList; char* dp = p->wrDataBufPtr; char* ep = dp + p->wrDataBufByteCnt; // header version *(unsigned*)dp = _cmSrSwap32(cmSrVersion); dp += sizeof(unsigned); // header flags *(unsigned*)dp = _cmSrSwap32(0); dp += sizeof(unsigned); // fill the data buffer for(; cdp!=NULL; cdp=cdp->linkPtr) { // structure data records contain only the typeId and optionally an array count if( cdp->typeId >= kStructSrId ) { *((unsigned*)dp) = _cmSrSwap32(cdp->typeId); dp += sizeof(unsigned); assert(dp <= ep); } // array data elements begin with a element count if( cdp->arrayFl ) { *((unsigned*)dp) = _cmSrSwap32(cdp->eleCnt); dp += sizeof(unsigned); assert(dp <= ep); } // copy data into buf if( cdp->byteCnt > 0 ) { assert( cdp->typeId < kStructSrId ); _cmSrCopyDataToBuf(dp, cdp->dataPtr, cdp->byteCnt, cdp->typeId, cdp->swapFl, cdp->eleCnt ); //memcpy( dp, cdp->dataPtr, cdp->byteCnt ); dp += cdp->byteCnt; assert(dp <= ep); } } *bufByteCntPtr = p->wrDataBufByteCnt; _cmSrClearDataList(p); return p->wrDataBufPtr; } void* cmSrWrGetBuf( cmSrH_t h, unsigned* bufByteCntPtr ) { _cmSr_t* p = _cmSrHandleToPtr(h); assert( bufByteCntPtr != NULL); *bufByteCntPtr = p->wrDataBufByteCnt; return p->wrDataBufPtr; } unsigned _cmSrProcUInt( _cmSr_t* p ) { unsigned val = _cmSrSwap32(*(unsigned*)p->rdCursorPtr); *(unsigned*)p->rdCursorPtr = val; p->rdCursorPtr += sizeof(unsigned); return val; } cmSrRC_t _cmSrProcBuf( _cmSr_t* p, _cmSrStruct_t* structPtr ) { cmSrRC_t rc = kOkSrRC; const _cmSrField_t* cfp = structPtr->fieldList; for(; cfp != NULL; cfp = cfp->linkPtr ) { unsigned eleCnt = 1; // if this is a structure if( cfp->structPtr != NULL ) { unsigned structTypeId = _cmSrProcUInt(p); if( structTypeId != cfp->structPtr->typeId ) { rc = _cmSrError( kFormatViolationSrRC, p, "Expected type id:%i encountered type id:%i",cfp->structPtr->typeId,structTypeId); goto errLabel; } } // if this is an array if( cfp->arrayFl ) eleCnt = _cmSrProcUInt(p); // if this is a primitive type if( cfp->primPtr != NULL ) { unsigned dataByteCnt = eleCnt * cfp->primPtr->byteCnt; _cmSrCopyDataToBuf( (void*)p->rdCursorPtr, p->rdCursorPtr, dataByteCnt, cfp->primPtr->typeId, cfp->primPtr->swapFl & _cmSrSwapFl, eleCnt ); p->rdCursorPtr += dataByteCnt; } else // this is a structure type { unsigned i; for(i=0; istructPtr)) != kOkSrRC ) goto errLabel; } } errLabel: return rc; } cmSrRC_t cmSrRdProcessBuffer( cmSrH_t h, void* buf, unsigned bufByteCnt ) { cmSrRC_t rc = kOkSrRC; _cmSr_t* p = _cmSrHandleToPtr(h); p->rdDataBufPtr = buf; p->rdDataBufByteCnt = bufByteCnt; p->rdCursorPtr = buf; // process the header _cmSrProcUInt(p); _cmSrProcUInt(p); if((rc = _cmSrProcBuf(p,p->structList)) != kOkSrRC ) goto errLabel; errLabel: return rc; } cmSrRC_t cmSrRdSetup( cmSrH_t h, const void* buf, unsigned bufByteCnt ) { cmSrRC_t rc = kOkSrRC; _cmSr_t* p = _cmSrHandleToPtr(h); p->rdDataBufPtr = buf; p->rdDataBufByteCnt = bufByteCnt; p->rdCursorPtr = buf; _cmSrClearStateStack(p,&p->rdStackPtr); p->rdStackPtr = NULL; // buffer must at least contain a header assert( bufByteCnt >= 2 * sizeof(unsigned) ); p->rdVersion = (*(unsigned*)p->rdCursorPtr); p->rdCursorPtr += sizeof(unsigned); p->rdFlags = (*(unsigned*)p->rdCursorPtr); p->rdCursorPtr += sizeof(unsigned); return rc; } cmSrRC_t cmSrRdStructBegin( cmSrH_t h, unsigned structTypeId ) { _cmSr_t* p = _cmSrHandleToPtr(h); return _cmSrOnStruct( p, structTypeId, &p->rdStackPtr ); } cmSrRC_t cmSrRdStructEnd( cmSrH_t h ) { _cmSr_t* p = _cmSrHandleToPtr(h); assert( p->rdStackPtr != NULL ); if( p->lastRC != kOkSrRC ) return p->lastRC; return _cmSrPopStateStack(p,&p->rdStackPtr); } cmSrRC_t _cmSrRead( _cmSr_t* p, unsigned typeId, const void** dataPtrPtr, unsigned* dataByteCntPtr, unsigned* eleCntPtr ) { cmSrRC_t rc = kOkSrRC; _cmSrField_t* refFieldPtr = NULL; unsigned refTypeId = cmInvalidId; unsigned eleCnt = 1; if( eleCntPtr != NULL ) *eleCntPtr = 0; if( dataByteCntPtr != NULL ) *dataByteCntPtr = 0; if( dataPtrPtr != NULL ) *dataPtrPtr = NULL; if( p->lastRC != kOkSrRC ) return p->lastRC; // verify the write stack exists - all fields exists inside structures so the stack must have at least one element if( p->rdStackPtr == NULL ) { rc = _cmSrError( kFormatViolationSrRC, p, "The reference format is unexpectedly empty."); goto errLabel; } // // advance the current field // // if cur state fieldPtr is NULL then this is the first field in a structure if( p->rdStackPtr->fieldPtr == NULL ) p->rdStackPtr->fieldPtr = p->rdStackPtr->structPtr->fieldList; else p->rdStackPtr->fieldPtr = p->rdStackPtr->fieldPtr->linkPtr; // verify that a reference field exists refFieldPtr = p->rdStackPtr->fieldPtr; if( refFieldPtr == NULL ) { rc = _cmSrError( kFormatViolationSrRC, p, "The format reference structure has run out of fields."); goto errLabel; } // get the reference type id refTypeId = refFieldPtr->primPtr == NULL ? refFieldPtr->structPtr->typeId : refFieldPtr->primPtr->typeId; // verify that the type being written matches the reference type if( refTypeId != typeId ) { const char* refLbl = "struct"; const char* cmtLbl = refLbl; if( refFieldPtr->primPtr != NULL ) refLbl = refFieldPtr->primPtr->label; if( typeId < kStructSrId ) cmtLbl = _cmSrIdToPrimPtr( typeId )->label; rc = _cmSrError( kFormatViolationSrRC, p, "Format violation: Exepected type %i (%s) but received %i (%s).", refTypeId,refLbl,typeId,cmtLbl); goto errLabel; } // if this is a primitive type if( typeId < kStructSrId ) { unsigned byteCnt = refFieldPtr->primPtr->byteCnt; if( refFieldPtr->arrayFl ) { eleCnt = *(unsigned*)p->rdCursorPtr; byteCnt *= eleCnt; p->rdCursorPtr += sizeof(unsigned); if( eleCntPtr == NULL ) { rc = _cmSrError( kFormatViolationSrRC, p, "A scalar read was performed where an array was expected. type:%s array count:%i.",refFieldPtr->primPtr->label,eleCnt); goto errLabel; } *eleCntPtr = eleCnt; } *dataPtrPtr = p->rdCursorPtr; *dataByteCntPtr = byteCnt; p->rdCursorPtr += byteCnt; } else // this is a structure type { unsigned structTypeId = structTypeId = *(unsigned*)p->rdCursorPtr; p->rdCursorPtr += sizeof(unsigned); if( refFieldPtr->arrayFl ) { eleCnt = *(unsigned*)p->rdCursorPtr; p->rdCursorPtr += sizeof(unsigned); } p->rdStackPtr->arrayCnt = eleCnt; p->rdStackPtr->arrayIdx = 0; assert(eleCntPtr != NULL ); *eleCntPtr = eleCnt; } errLabel: return rc; } cmSrRC_t cmSrReadStruct( cmSrH_t h, unsigned structTypeId, unsigned* arrayCnt ) { _cmSr_t* p = _cmSrHandleToPtr(h); return _cmSrRead(p, structTypeId, NULL, NULL, arrayCnt ); } cmSrRC_t _cmSrReadScalar( cmSrH_t h, unsigned typeId, void* valPtr, unsigned scalarByteCnt ) { cmSrRC_t rc = kOkSrRC; _cmSr_t* p = _cmSrHandleToPtr(h); const void* dataPtr = NULL; unsigned dataByteCnt = 0; if((rc= _cmSrRead(p,typeId, &dataPtr, &dataByteCnt, NULL )) != kOkSrRC ) return rc; memcpy(valPtr,dataPtr,dataByteCnt); return rc; } cmSrRC_t _cmSrReadV( cmSrH_t h, unsigned typeId, const void** valPtrPtr, unsigned scalarByteCnt, unsigned* eleCntPtr ) { cmSrRC_t rc = kOkSrRC; _cmSr_t* p = _cmSrHandleToPtr(h); unsigned dataByteCnt = 0; if((rc= _cmSrRead(p,typeId, valPtrPtr, &dataByteCnt, eleCntPtr )) != kOkSrRC ) return rc; assert( dataByteCnt == scalarByteCnt * (*eleCntPtr)); return rc; } cmSrRC_t cmSrReadChar( cmSrH_t h, char* valPtr ) { return _cmSrReadScalar( h, kCharSrId, valPtr, sizeof(char)); } cmSrRC_t cmSrReadUChar( cmSrH_t h, unsigned char* valPtr ) { return _cmSrReadScalar( h, kUCharSrId, valPtr, sizeof(unsigned char)); } cmSrRC_t cmSrReadShort( cmSrH_t h, short* valPtr ) { return _cmSrReadScalar( h, kShortSrId, valPtr, sizeof(short)); } cmSrRC_t cmSrReadUShort( cmSrH_t h, unsigned short* valPtr ) { return _cmSrReadScalar( h, kUShortSrId, valPtr, sizeof(unsigned short)); } cmSrRC_t cmSrReadLong( cmSrH_t h, long* valPtr) { return _cmSrReadScalar( h, kLongSrId, valPtr, sizeof(long)); } cmSrRC_t cmSrReadULong( cmSrH_t h, unsigned long* valPtr ) { return _cmSrReadScalar( h, kULongSrId, valPtr, sizeof(unsigned long)); } cmSrRC_t cmSrReadInt( cmSrH_t h, int* valPtr) { return _cmSrReadScalar( h, kIntSrId, valPtr, sizeof(int)); } cmSrRC_t cmSrReadUInt( cmSrH_t h, unsigned* valPtr ) { return _cmSrReadScalar( h, kUIntSrId, valPtr, sizeof(unsigned int)); } cmSrRC_t cmSrReadFloat( cmSrH_t h, float* valPtr ) { return _cmSrReadScalar( h, kFloatSrId, valPtr, sizeof(float)); } cmSrRC_t cmSrReadDouble( cmSrH_t h, double* valPtr ) { return _cmSrReadScalar( h, kDoubleSrId, valPtr, sizeof(double)); } cmSrRC_t cmSrReadBool( cmSrH_t h, bool* valPtr ) { return _cmSrReadScalar( h, kBoolSrId, valPtr, sizeof(bool)); } cmSrRC_t cmSrReadCharV( cmSrH_t h, char** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kCharSrId, (const void**)valPtrPtr, sizeof(char), eleCntPtr); } cmSrRC_t cmSrReadUCharV( cmSrH_t h, unsigned char** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kUCharSrId, (const void**)valPtrPtr, sizeof(unsigned char), eleCntPtr); } cmSrRC_t cmSrReadShortV( cmSrH_t h, short** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kShortSrId, (const void**)valPtrPtr, sizeof(short), eleCntPtr); } cmSrRC_t cmSrReadUShortV( cmSrH_t h, unsigned short** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kUShortSrId, (const void**)valPtrPtr, sizeof(unsigned short), eleCntPtr); } cmSrRC_t cmSrReadLongV( cmSrH_t h, long** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kLongSrId, (const void**)valPtrPtr, sizeof(long), eleCntPtr); } cmSrRC_t cmSrReadULongV( cmSrH_t h, unsigned long** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kULongSrId, (const void**)valPtrPtr, sizeof(unsigned long), eleCntPtr); } cmSrRC_t cmSrReadIntV( cmSrH_t h, int** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kIntSrId, (const void**)valPtrPtr, sizeof(int), eleCntPtr); } cmSrRC_t cmSrReadUIntV( cmSrH_t h, unsigned** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kUIntSrId, (const void**)valPtrPtr, sizeof(unsigned int), eleCntPtr); } cmSrRC_t cmSrReadFloatV( cmSrH_t h, float** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kFloatSrId, (const void**)valPtrPtr, sizeof(float), eleCntPtr); } cmSrRC_t cmSrReadDoubleV( cmSrH_t h, double** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kDoubleSrId, (const void**)valPtrPtr, sizeof(double), eleCntPtr); } cmSrRC_t cmSrReadBoolV( cmSrH_t h, bool** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kBoolSrId, (const void**)valPtrPtr, sizeof(bool), eleCntPtr); } cmSrRC_t cmSrReadCharCV( cmSrH_t h, const char** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kCharSrId, (const void**)valPtrPtr, sizeof(char), eleCntPtr); } cmSrRC_t cmSrReadUCharCV( cmSrH_t h, const unsigned char** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kUCharSrId, (const void**)valPtrPtr, sizeof(unsigned char), eleCntPtr); } cmSrRC_t cmSrReadShortCV( cmSrH_t h, const short** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kShortSrId, (const void**)valPtrPtr, sizeof(short), eleCntPtr); } cmSrRC_t cmSrReadUShortCV( cmSrH_t h, const unsigned short** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kUShortSrId, (const void**)valPtrPtr, sizeof(unsigned short), eleCntPtr); } cmSrRC_t cmSrReadLongCV( cmSrH_t h, const long** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kLongSrId, (const void**)valPtrPtr, sizeof(long), eleCntPtr); } cmSrRC_t cmSrReadULongCV( cmSrH_t h, const unsigned long** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kULongSrId, (const void**)valPtrPtr, sizeof(unsigned long), eleCntPtr); } cmSrRC_t cmSrReadIntCV( cmSrH_t h, const int** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kIntSrId, (const void**)valPtrPtr, sizeof(int), eleCntPtr); } cmSrRC_t cmSrReadUIntCV( cmSrH_t h, const unsigned** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kUIntSrId, (const void**)valPtrPtr, sizeof(unsigned int), eleCntPtr); } cmSrRC_t cmSrReadFloatCV( cmSrH_t h, const float** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kFloatSrId, (const void**)valPtrPtr, sizeof(float), eleCntPtr); } cmSrRC_t cmSrReadDoubleCV( cmSrH_t h, const double** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kDoubleSrId, (const void**)valPtrPtr, sizeof(double), eleCntPtr); } cmSrRC_t cmSrReadBoolCV( cmSrH_t h, const bool** valPtrPtr, unsigned* eleCntPtr ) { return _cmSrReadV( h, kBoolSrId, (const void**)valPtrPtr, sizeof(bool), eleCntPtr); } unsigned cmSrRdStruct( cmSrH_t h, unsigned structTypeId ) { unsigned eleCnt; return cmSrReadStruct(h,structTypeId,&eleCnt) == kOkSrRC ? eleCnt : cmInvalidCnt; } char cmSrRdChar( cmSrH_t h ) { char val; return cmSrReadChar(h,&val) == kOkSrRC ? val : 0; } unsigned char cmSrRdUChar( cmSrH_t h ) { unsigned char val; return cmSrReadUChar(h,&val) == kOkSrRC ? val : 0; } short cmSrRdShort( cmSrH_t h ) { short val; return cmSrReadShort(h,&val) == kOkSrRC ? val : 0; } unsigned short cmSrRdUShort( cmSrH_t h ) { unsigned short val; return cmSrReadUShort(h,&val) == kOkSrRC ? val : 0; } long cmSrRdLong( cmSrH_t h ) { long val; return cmSrReadLong(h,&val) == kOkSrRC ? val : 0; } unsigned long cmSrRdULong( cmSrH_t h ) { unsigned long val; return cmSrReadULong(h,&val) == kOkSrRC ? val : 0; } int cmSrRdInt( cmSrH_t h ) { int val; return cmSrReadInt(h,&val) == kOkSrRC ? val : 0; } unsigned int cmSrRdUInt( cmSrH_t h ) { unsigned val; return cmSrReadUInt(h,&val) == kOkSrRC ? val : 0; } float cmSrRdFloat( cmSrH_t h ) { float val; return cmSrReadFloat(h,&val) == kOkSrRC ? val : 0; } double cmSrRdDouble( cmSrH_t h ) { double val; return cmSrReadDouble(h,&val) == kOkSrRC ? val : 0; } bool cmSrRdBool( cmSrH_t h ) { bool val; return cmSrReadBool(h,&val) == kOkSrRC ? val : 0; } char* cmSrRdCharV( cmSrH_t h, unsigned* eleCntPtr) { char* valPtr; return cmSrReadCharV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } unsigned char* cmSrRdUCharV( cmSrH_t h, unsigned* eleCntPtr) { unsigned char* valPtr; return cmSrReadUCharV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } short* cmSrRdShortV( cmSrH_t h, unsigned* eleCntPtr) { short* valPtr; return cmSrReadShortV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } unsigned short* cmSrRdUShortV( cmSrH_t h, unsigned* eleCntPtr) { unsigned short* valPtr; return cmSrReadUShortV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } long* cmSrRdLongV( cmSrH_t h, unsigned* eleCntPtr) { long* valPtr; return cmSrReadLongV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } unsigned long* cmSrRdULongV( cmSrH_t h, unsigned* eleCntPtr) { unsigned long* valPtr; return cmSrReadULongV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } int* cmSrRdIntV( cmSrH_t h, unsigned* eleCntPtr) { int* valPtr; return cmSrReadIntV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } unsigned int* cmSrRdUIntV( cmSrH_t h, unsigned* eleCntPtr) { unsigned* valPtr; return cmSrReadUIntV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } float* cmSrRdFloatV( cmSrH_t h, unsigned* eleCntPtr) { float* valPtr; return cmSrReadFloatV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } double* cmSrRdDoubleV( cmSrH_t h, unsigned* eleCntPtr) { double* valPtr; return cmSrReadDoubleV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } bool* cmSrRdBoolV( cmSrH_t h, unsigned* eleCntPtr) { bool* valPtr; return cmSrReadBoolV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } const char* cmSrRdCharCV( cmSrH_t h, unsigned* eleCntPtr) { const char* valPtr; return cmSrReadCharCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } const unsigned char* cmSrRdUCharCV( cmSrH_t h, unsigned* eleCntPtr) { const unsigned char* valPtr; return cmSrReadUCharCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } const short* cmSrRdShortCV( cmSrH_t h, unsigned* eleCntPtr) { const short* valPtr; return cmSrReadShortCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } const unsigned short* cmSrRdUShortCV( cmSrH_t h, unsigned* eleCntPtr) { const unsigned short* valPtr; return cmSrReadUShortCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } const long* cmSrRdLongCV( cmSrH_t h, unsigned* eleCntPtr) { const long* valPtr; return cmSrReadLongCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } const unsigned long* cmSrRdULongCV( cmSrH_t h, unsigned* eleCntPtr) { const unsigned long* valPtr; return cmSrReadULongCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } const int* cmSrRdIntCV( cmSrH_t h, unsigned* eleCntPtr) { const int* valPtr; return cmSrReadIntCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } const unsigned int* cmSrRdUIntCV( cmSrH_t h, unsigned* eleCntPtr) { const unsigned* valPtr; return cmSrReadUIntCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } const float* cmSrRdFloatCV( cmSrH_t h, unsigned* eleCntPtr) { const float* valPtr; return cmSrReadFloatCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } const double* cmSrRdDoubleCV( cmSrH_t h, unsigned* eleCntPtr) { const double* valPtr; return cmSrReadDoubleCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } const bool* cmSrRdBoolCV( cmSrH_t h, unsigned* eleCntPtr) { const bool* valPtr; return cmSrReadBoolCV(h,&valPtr,eleCntPtr) == kOkSrRC ? valPtr : NULL; } // // cmSrTest() is a serializer example function. // cmSrRC_t cmSrTest( cmCtx_t* ctx ) { unsigned i,j,k; cmSrRC_t rc = kOkSrRC; cmSrH_t h; unsigned bufByteCnt; const void* bufPtr; enum { kVectSrId = kStructSrId, // nested structure id kVectArrSrId // outer structure id }; // nested structure typedef struct { float* data; unsigned cnt; } vect; // outer structure typedef struct { unsigned cnt; vect* vectArray; } vectArray; float vd0[] = { 0, 1, 2, 3, 4}; float vd1[] = { 10, 11, 12 }; unsigned vn = 2; vect v[] = { {vd0,5}, {vd1,3} }; vectArray va = { vn, v }; if(( rc = cmSrAlloc( &h, ctx )) != kOkSrRC ) goto errLabel; // repeat format processes to test cmSrFormatReset() for(k=0; k<2; ++k) { cmSrFmtReset(h); // Define the format of nested structures first // // Long Form: // cmSrFmtDefineStruct(h,kVectSrId); // cmSrFmtFloatV(h ); // cmSrFmtUInt(h ); // // Short Form: cmSrDefFmt(h, kVectSrId, kFloatVSrId, kUIntSrId, kInvalidSrId ); // Define the format of the outer structure last // // Long Form: // cmSrFmtDefineStruct(h,kVectArrSrId); // cmSrFmtUInt(h ); // cmSrFmtStructV(h, kVectSrId ); // // Short Form: cmSrDefFmt(h, kVectArrSrId, kUIntSrId, kVectSrId | kArraySrFl, kInvalidSrId ); cmSrFmtPrint(h); // repeat write process to test cmSrWrReset() for(j=0; j<2; ++j) { cmSrWrReset(h); cmSrWrStructBegin( h, kVectArrSrId ); cmSrWrUInt( h, vn ); cmSrWrStruct( h, kVectSrId, vn ); for(i=0; i