From 72b65a19049b1fd1e615d2b2d16fb2245e8577cb Mon Sep 17 00:00:00 2001 From: kevin Date: Tue, 5 Nov 2013 12:52:07 -0800 Subject: [PATCH 01/23] cmScore.h/c : Initial implementation of cmScoreFileFromMidi(). --- app/cmScore.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++ app/cmScore.h | 7 ++- 2 files changed, 132 insertions(+), 2 deletions(-) diff --git a/app/cmScore.c b/app/cmScore.c index b531a30..3351264 100644 --- a/app/cmScore.c +++ b/app/cmScore.c @@ -1955,6 +1955,133 @@ void cmScorePrint( cmScH_t h, cmRpt_t* rpt ) } } +cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* scoreFn ) +{ + cmScRC_t rc = kOkScRC; + cmMidiFileH_t mfH = cmMidiFileNullHandle; + cmCsvH_t csvH = cmCsvNullHandle; + cmErr_t err; + + cmErrSetup(&err,&ctx->rpt,"MIDI to Score"); + + if( cmMidiFileOpen(midiFn, &mfH, ctx ) != kOkMfRC ) + return cmErrMsg(&err,kMidiFileFailScRC,"Unable to open the MIDI file '%s'.",midiFn); + + if( cmCsvInitialize(&csvH,ctx) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Unable to initialize the CSV file: '%s'.",scoreFn); + goto errLabel; + } + + // Convert the track message 'dtick' field to delta-microseconds. + cmMidiFileTickToMicros(mfH); + + unsigned msgCnt = cmMidiFileMsgCount(mfH); + unsigned i; + const cmMidiTrackMsg_t** tmpp = cmMidiFileMsgArray(mfH); + double acc_secs = 0; + for(i=0; idtick / 1000000.0; + + acc_secs += dsecs; + + if( tmp->status == 0xff ) + opStr = cmMidiMetaStatusToLabel(tmp->metaId); + else + { + opStr = cmMidiStatusToLabel(tmp->status); + if( cmMidiIsChStatus( tmp->status ) ) + { + midiCh = tmp->u.chMsgPtr->ch; + d0 = tmp->u.chMsgPtr->d0; + d1 = tmp->u.chMsgPtr->d1; + } + } + + if( cmCsvAppendRow(csvH, &cp, cmCsvInsertSymUInt(csvH,i), kIntCsvTFl, lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting 'id' column in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + + if( cmCsvInsertUIntColAfter(csvH, cp, &cp, tmp->trkIdx, lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting 'trk' column in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + + if( cmCsvInsertUIntColAfter(csvH, cp, &cp, 0, lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting 'evt' column in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + + if( cmCsvInsertTextColAfter(csvH, cp, &cp, opStr, lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting 'opcode' column in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + + if( cmCsvInsertDoubleColAfter(csvH, cp, &cp, dsecs, lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting 'dticks' column in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + + if( cmCsvInsertDoubleColAfter(csvH, cp, &cp, acc_secs, lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting 'micros' column in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + + if( cmCsvInsertUIntColAfter(csvH, cp, &cp, tmp->status, lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting 'status' column in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + + if( cmCsvInsertUIntColAfter(csvH, cp, &cp, tmp->metaId, lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting 'meta' column in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + + if( cmCsvInsertUIntColAfter(csvH, cp, &cp, midiCh, lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting 'ch' column in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + + if( cmCsvInsertUIntColAfter(csvH, cp, &cp, d0, lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting 'd0' column in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + + if( cmCsvInsertUIntColAfter(csvH, cp, &cp, d1, lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting 'd1' column in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + + + } + + errLabel: + cmMidiFileClose(&mfH); + cmCsvFinalize(&csvH); + + return rc; +} + void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn ) { cmScH_t h = cmScNullHandle; diff --git a/app/cmScore.h b/app/cmScore.h index 3c9e680..2f36a8f 100644 --- a/app/cmScore.h +++ b/app/cmScore.h @@ -12,8 +12,8 @@ extern "C" { kSyntaxErrScRC, kInvalidIdxScRC, kTimeLineFailScRC, - kInvalidDynRefCntScRC - + kInvalidDynRefCntScRC, + kMidiFileFailScRC }; enum @@ -235,6 +235,9 @@ extern "C" { void cmScorePrint( cmScH_t h, cmRpt_t* rpt ); + // Generate a new score file from a MIDI file. + cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const cmChar_t* scoreFn ); + void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn ); From 6bc6511d8f4079f54707d9d6233255da5fea87cf Mon Sep 17 00:00:00 2001 From: kevin Date: Tue, 5 Nov 2013 12:52:23 -0800 Subject: [PATCH 02/23] cmMidiFile.h : Added comments. --- cmMidiFile.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmMidiFile.h b/cmMidiFile.h index 4f7463a..15a61dd 100644 --- a/cmMidiFile.h +++ b/cmMidiFile.h @@ -64,7 +64,7 @@ extern "C" { { unsigned uid; // uid's are unique among all msg's in the file unsigned dtick; // delta ticks - unsigned atick; + unsigned atick; // accumulated ticks cmMidiByte_t status; // ch msg's have the channel value removed (it is stored in u.chMsgPtr->ch) cmMidiByte_t metaId; // unsigned short trkIdx; // From 9181a5d804bf79e3e10ca8621a3ac5aba465734b Mon Sep 17 00:00:00 2001 From: kevin Date: Tue, 5 Nov 2013 14:32:59 -0800 Subject: [PATCH 03/23] cmScore.c : Completed implementation of cmScoreFileFromMidi(). --- app/cmScore.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 90 insertions(+), 9 deletions(-) diff --git a/app/cmScore.c b/app/cmScore.c index 3351264..a90a1cc 100644 --- a/app/cmScore.c +++ b/app/cmScore.c @@ -1961,6 +1961,7 @@ cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const c cmMidiFileH_t mfH = cmMidiFileNullHandle; cmCsvH_t csvH = cmCsvNullHandle; cmErr_t err; + cmChar_t* titles[] = {"id","trk","evt","opcode","dticks","micros","status","meta","ch","d0","d1","arg0","arg1","bar","skip","even","grace","tempo","t frac","dyn","section","remark", NULL }; cmErrSetup(&err,&ctx->rpt,"MIDI to Score"); @@ -1976,25 +1977,56 @@ cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const c // Convert the track message 'dtick' field to delta-microseconds. cmMidiFileTickToMicros(mfH); + unsigned msgCnt = cmMidiFileMsgCount(mfH); unsigned i; const cmMidiTrackMsg_t** tmpp = cmMidiFileMsgArray(mfH); double acc_secs = 0; + unsigned lexTId = 0; + cmCsvCell_t* cp = NULL; + + + if( cmCsvAppendRow(csvH, &cp, cmCsvInsertSymText(csvH,titles[0]), kStrCsvTFl, lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting 'id' column in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + + for(i=1; titles[i]!=NULL; ++i) + { + if( cmCsvInsertTextColAfter(csvH, cp, &cp, titles[i], lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting column index '%i' label in '%s'.",i,cmStringNullGuard(scoreFn)); + goto errLabel; + } + + } + + + for(i=0; idtick / 1000000.0; - + unsigned metaId = 0; + double dsecs = (double)tmp->dtick / 1000000.0; + acc_secs += dsecs; - if( tmp->status == 0xff ) - opStr = cmMidiMetaStatusToLabel(tmp->metaId); + if( tmp->status == kMetaStId ) + { + opStr = cmMidiMetaStatusToLabel(tmp->metaId); + metaId = tmp->metaId; + + switch( tmp->metaId ) + { + case kTempoMdId: + d0 = tmp->u.iVal; + } + } else { opStr = cmMidiStatusToLabel(tmp->status); @@ -2006,6 +2038,12 @@ cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const c } } + cp = NULL; + + // skip note-off messages + if( tmp->status == kNoteOffMdId ) + continue; + if( cmCsvAppendRow(csvH, &cp, cmCsvInsertSymUInt(csvH,i), kIntCsvTFl, lexTId ) != kOkCsvRC ) { cmErrMsg(&err,kCsvFailScRC,"Error inserting 'id' column in '%s'.",cmStringNullGuard(scoreFn)); @@ -2042,13 +2080,13 @@ cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const c goto errLabel; } - if( cmCsvInsertUIntColAfter(csvH, cp, &cp, tmp->status, lexTId ) != kOkCsvRC ) + if( cmCsvInsertHexColAfter(csvH, cp, &cp, tmp->status, lexTId ) != kOkCsvRC ) { cmErrMsg(&err,kCsvFailScRC,"Error inserting 'status' column in '%s'.",cmStringNullGuard(scoreFn)); goto errLabel; } - if( cmCsvInsertUIntColAfter(csvH, cp, &cp, tmp->metaId, lexTId ) != kOkCsvRC ) + if( cmCsvInsertUIntColAfter(csvH, cp, &cp, metaId, lexTId ) != kOkCsvRC ) { cmErrMsg(&err,kCsvFailScRC,"Error inserting 'meta' column in '%s'.",cmStringNullGuard(scoreFn)); goto errLabel; @@ -2072,9 +2110,52 @@ cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const c goto errLabel; } + switch( tmp->status ) + { + case kNoteOnMdId: + if( cmCsvInsertTextColAfter(csvH, cp, &cp, cmMidiToSciPitch(tmp->u.chMsgPtr->d0,NULL,0), lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting 'opcode' column in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + + case kMetaStId: + switch( tmp->metaId ) + { + case kTimeSigMdId: + if( cmCsvInsertUIntColAfter(csvH, cp, &cp, tmp->u.timeSigPtr->num, lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting time sign. numerator column in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + + if( cmCsvInsertUIntColAfter(csvH, cp, &cp, tmp->u.timeSigPtr->den, lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting time sign. denominator column in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + break; + + case kTempoMdId: + if( cmCsvInsertUIntColAfter(csvH, cp, &cp, 60000000/tmp->u.iVal, lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting 'tempo' in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + break; + } + + } + } + if( cmCsvWrite(csvH,scoreFn) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"The score output file '%s' could not be written.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + errLabel: cmMidiFileClose(&mfH); cmCsvFinalize(&csvH); From e5ee6432c1f28e86da35e840a5e6d8ac85795e43 Mon Sep 17 00:00:00 2001 From: kevin Date: Tue, 5 Nov 2013 14:34:22 -0800 Subject: [PATCH 04/23] cmCsv.h/c : Added cmCsvInsertSymHex(),cmCsvSetCellHex(), and cmInsertHexColAfter(). Also fixed bug in the cmCsvInsertXXXColAfter() where the return cell pointer was not correctly set. --- cmCsv.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- cmCsv.h | 4 ++++ 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/cmCsv.c b/cmCsv.c index 5b594e3..e18373e 100644 --- a/cmCsv.c +++ b/cmCsv.c @@ -729,6 +729,20 @@ unsigned cmCsvInsertSymUInt( cmCsvH_t h, unsigned v ) return cmInvalidId; } +unsigned cmCsvInsertSymHex( cmCsvH_t h, unsigned v ) +{ + const char* fmt = "0x%x"; + unsigned n = snprintf(NULL,0,fmt,v)+1; + char buf[n]; + + buf[0]= 0; + if( snprintf(buf,n,fmt,v) == n-1 ) + return cmCsvInsertSymText(h,buf); + + _cmCsvError(_cmCsvHandleToPtr(h),kDataCvtErrCsvRC,"The unsigned int 0x%x could not be converted to text.",v); + return cmInvalidId; +} + unsigned cmCsvInsertSymFloat( cmCsvH_t h, float v ) { const char* fmt = "%f"; @@ -812,6 +826,24 @@ cmCsvRC_t cmCsvSetCellUInt( cmCsvH_t h, unsigned row, unsigned col, unsigned return kOkCsvRC; } +cmCsvRC_t cmCsvSetCellHex( cmCsvH_t h, unsigned row, unsigned col, unsigned v ) +{ + cmCsvCell_t* cp; + unsigned symId; + + if((cp = _cmCsvCellPtr(h,row,col)) == NULL ) + return cmErrLastRC(&_cmCsvHandleToPtr(h)->err); + + if((symId = cmCsvInsertSymHex(h,v)) == cmInvalidId ) + return cmErrLastRC(&_cmCsvHandleToPtr(h)->err); + + cp->symId = symId; + cp->flags &= !kTypeTMask; + cp->flags |= kIntCsvTFl; + + return kOkCsvRC; +} + cmCsvRC_t cmCsvSetCellFloat( cmCsvH_t h, unsigned row, unsigned col, float v ) { cmCsvCell_t* cp; @@ -985,7 +1017,7 @@ cmCsvRC_t cmCsvInsertTextColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCs cmCsvCell_t* ncp; if( cellPtrPtr != NULL ) - cellPtrPtr = NULL; + *cellPtrPtr = NULL; if((rc = cmCsvInsertColAfter(h, leftCellPtr, &ncp, cmInvalidId, 0, lexTId )) == kOkCsvRC ) if((rc = cmCsvSetCellText(h, ncp->row, ncp->col, text )) == kOkCsvRC ) @@ -1001,7 +1033,7 @@ cmCsvRC_t cmCsvInsertIntColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCs cmCsvCell_t* ncp; if( cellPtrPtr != NULL ) - cellPtrPtr = NULL; + *cellPtrPtr = NULL; if((rc = cmCsvInsertColAfter(h, leftCellPtr, &ncp, cmInvalidId, 0, lexTId )) == kOkCsvRC ) if((rc = cmCsvSetCellInt(h, ncp->row, ncp->col, val )) == kOkCsvRC ) @@ -1017,7 +1049,7 @@ cmCsvRC_t cmCsvInsertUIntColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCs cmCsvCell_t* ncp; if( cellPtrPtr != NULL ) - cellPtrPtr = NULL; + *cellPtrPtr = NULL; if((rc = cmCsvInsertColAfter(h, leftCellPtr, &ncp, cmInvalidId, 0, lexTId )) == kOkCsvRC ) if((rc = cmCsvSetCellUInt(h, ncp->row, ncp->col, val )) == kOkCsvRC ) @@ -1027,13 +1059,29 @@ cmCsvRC_t cmCsvInsertUIntColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCs return rc; } +cmCsvRC_t cmCsvInsertHexColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, unsigned val, unsigned lexTId ) +{ + cmCsvRC_t rc; + cmCsvCell_t* ncp; + + if( cellPtrPtr != NULL ) + *cellPtrPtr = NULL; + + if((rc = cmCsvInsertColAfter(h, leftCellPtr, &ncp, cmInvalidId, 0, lexTId )) == kOkCsvRC ) + if((rc = cmCsvSetCellHex(h, ncp->row, ncp->col, val )) == kOkCsvRC ) + if( cellPtrPtr != NULL ) + *cellPtrPtr = ncp; + + return rc; +} + cmCsvRC_t cmCsvInsertFloatColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, float val, unsigned lexTId ) { cmCsvRC_t rc; cmCsvCell_t* ncp; if( cellPtrPtr != NULL ) - cellPtrPtr = NULL; + *cellPtrPtr = NULL; if((rc = cmCsvInsertColAfter(h, leftCellPtr, &ncp, cmInvalidId, 0, lexTId )) == kOkCsvRC ) if((rc = cmCsvSetCellFloat(h, ncp->row, ncp->col, val )) == kOkCsvRC ) @@ -1049,7 +1097,7 @@ cmCsvRC_t cmCsvInsertDoubleColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCs cmCsvCell_t* ncp; if( cellPtrPtr != NULL ) - cellPtrPtr = NULL; + *cellPtrPtr = NULL; if((rc = cmCsvInsertColAfter(h, leftCellPtr, &ncp, cmInvalidId, 0, lexTId )) == kOkCsvRC ) if((rc = cmCsvSetCellDouble(h, ncp->row, ncp->col, val )) == kOkCsvRC ) diff --git a/cmCsv.h b/cmCsv.h index d3b7b06..e686c1c 100644 --- a/cmCsv.h +++ b/cmCsv.h @@ -109,13 +109,16 @@ extern "C" { unsigned cmCsvInsertSymText( cmCsvH_t h, const char* text ); unsigned cmCsvInsertSymInt( cmCsvH_t h, int v ); unsigned cmCsvInsertSymUInt( cmCsvH_t h, unsigned v ); + unsigned cmCsvInsertSymHex( cmCsvH_t h, unsigned v ); unsigned cmCsvInsertSymFloat( cmCsvH_t h, float v ); unsigned cmCsvInsertSymDouble( cmCsvH_t h, double v ); + // Set the value associated with a cell. cmCsvRC_t cmCsvSetCellText( cmCsvH_t h, unsigned row, unsigned col, const char* text ); cmCsvRC_t cmCsvSetCellInt( cmCsvH_t h, unsigned row, unsigned col, int v ); cmCsvRC_t cmCsvSetCellUInt( cmCsvH_t h, unsigned row, unsigned col, unsigned v ); + cmCsvRC_t cmCsvSetCellHex( cmCsvH_t h, unsigned row, unsigned col, unsigned v ); cmCsvRC_t cmCsvSetCellFloat( cmCsvH_t h, unsigned row, unsigned col, float v ); cmCsvRC_t cmCsvSetCellDouble( cmCsvH_t h, unsigned row, unsigned col, double v ); @@ -134,6 +137,7 @@ extern "C" { cmCsvRC_t cmCsvInsertTextColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, const char* val, unsigned lexTId ); cmCsvRC_t cmCsvInsertIntColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, int val, unsigned lexTId ); cmCsvRC_t cmCsvInsertUIntColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, unsigned val, unsigned lexTId ); + cmCsvRC_t cmCsvInsertHexColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, unsigned val, unsigned lexTId ); cmCsvRC_t cmCsvInsertFloatColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, float val, unsigned lexTId ); cmCsvRC_t cmCsvInsertDoubleColAfter( cmCsvH_t h, cmCsvCell_t* leftCellPtr, cmCsvCell_t** cellPtrPtr, double val, unsigned lexTId ); From 0debd730a686199fb3017d87097b371876be4c0a Mon Sep 17 00:00:00 2001 From: kevin Date: Tue, 5 Nov 2013 14:37:38 -0800 Subject: [PATCH 05/23] cmData.c : Initial implementation of cmDataSerialize(). --- cmData.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/cmData.c b/cmData.c index b5725d0..8abb797 100644 --- a/cmData.c +++ b/cmData.c @@ -2161,10 +2161,28 @@ char* _cmDataSerializeWrite( cmData_t* np, char* dp, const char* ep ) return dp; } +char* _cmDataSerialize( const cmData_t* p, char* buf, const char* ep ) +{ + + buf = _cmDataSerializeWrite(p,buf,ep); + + // if this data type has a child then write the child + if( kMinStructDtId <= p->tid && p->tid <= kMaxStructDtId && p->u.child != NULL ) + buf = _cmDataSerialize(p->u.child,buf,ep); + + // if this data type has siblings then write sibings + cmData_t* dp = p->u.child; + for(; dp != NULL; dp=dp->sibling ) + buf = cmDataSerialize(dp->sibling,buf,ep); + + return buf; +} + cmDtRC_t cmDataSerialize( const cmData_t* p, void* buf, unsigned bufByteCnt ) { - - + const char* ep = (char*)p + bufByteCnt; + buf = _cmDataSerialize(p,buf,bufByteCnt); + assert( buf <= ep ); return kOkDtRC; } From 07b0ca3bbba5767670138dc1c9e14e8ab848c4ac Mon Sep 17 00:00:00 2001 From: kevin Date: Wed, 13 Nov 2013 11:53:20 -0500 Subject: [PATCH 06/23] cmGrPage.h : Added comment to cmGrLabelFunc_t. --- cmGrPage.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmGrPage.h b/cmGrPage.h index 1f71873..6d7fd40 100644 --- a/cmGrPage.h +++ b/cmGrPage.h @@ -60,7 +60,11 @@ extern "C" { // Draw the page. void cmGrPageDraw( cmGrPgH_t h, cmGrDcH_t dcH ); + // Label callback functions are used to translate numeric axis values to + // text strings. Multiple label callback functions can be registered with + // a page and then assigned to a given view axis via cmGrViewSetLabelFunc(). typedef void (*cmGrLabelFunc_t)( void* arg, cmChar_t* label, unsigned labelCharCnt, cmGrV_t value ); + // Returns id of the new page label function. unsigned cmGrPageLabelFuncRegister( cmGrPgH_t h, cmGrLabelFunc_t func, void* arg, const cmChar_t* label ); unsigned cmGrPageLabelFuncCount( cmGrPgH_t h ); From 9928dc4f4a3d6bae89dbfaee885b46d69b30d4d8 Mon Sep 17 00:00:00 2001 From: kpl Date: Thu, 14 Nov 2013 09:16:50 -0800 Subject: [PATCH 07/23] cmData.h/c : Inital implementation of cmDataParser. --- cmData.c | 227 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- cmData.h | 12 +++ 2 files changed, 238 insertions(+), 1 deletion(-) diff --git a/cmData.c b/cmData.c index b5725d0..45b52bc 100644 --- a/cmData.c +++ b/cmData.c @@ -5,6 +5,8 @@ #include "cmMem.h" #include "cmMallocDebug.h" #include "cmData.h" +#include "cmLex.h" +#include "cmStack.h" cmDtRC_t _cmDataErrNo = kOkDtRC; @@ -2061,7 +2063,10 @@ cmDtRC_t cmDataRecdParseId(cmData_t* p, cmErr_t* err, unsigned errRC, ... ) -//---------------------------------------------------------------------------- +//============================================================================ +//============================================================================ +//============================================================================ + unsigned _cmDataSerializeNodeByteCount( const cmData_t* p ) { unsigned n = 0; @@ -2173,6 +2178,226 @@ cmDtRC_t cmDataDeserialize( const void* buf, unsigned bufByteCnt, cmData_t** pp return kOkDtRC; } +//============================================================================ +//============================================================================ +//============================================================================ +#ifdef NOT_DEF +enum +{ + kLCurlyLexTId = kUserLexTId + 1, + kRCurlyLexTId, + kLParenLexTId, + kRParenLexTId, + kLBrackLexTId, + kRBrackLexTId, + kColonLexTId, + kCommaLexTId, +}; + +typedef struct +{ + unsigned id; + const cmChar_t* label; +} cmDtToken_t; + +cmDtToken_t _cmDtTokenArray[] = +{ + { kLCurlyLexTId, "{" }, + { kRCurlyLexTId, "}" }, + { kLBrackLexTId, "[" }, + { kRBrackLexTId, "]" }, + { kLParenLexTId, "(" }, + { kRParenLexTId, ")" }, + { kColonLexTId, ":" }, + { kCommaLexTId, "," }, + { kErrorLexTId,""} + +}; + +typedef struct +{ + cmErr_t err; + cmLexH lexH; + cmStackH_t stH; + +} cmDataParser_t; + +typedef struct +{ + unsigned tokId; +} cmDataStEle_t; + +cmDataParserH_t cmDataParserNullHandle = cmSTATIC_NULL_HANDLE; + +cmDataParser_t* _cmDataParserHandleToPtr( cmDataParserH_t h ) +{ + cmDataParser_t* p = (cmDataParser_t*)h.h; + assert( p!= NULL ); + return p; +} + +cmDtRC_t _cmDataParserDestroy( cmDataParser_t* p ) +{ + if( cmLexFinal(&p->lexH) != kOkLexRC ) + cmErrMsg(&p->err,kLexFailedDtRC,"Lexer release failed."); + + if( cmStackFree(&p->stH) != kOkStRC ) + cmErrMsg(&p->err,kParserStackFailDtRC,"The data object parser stack release failed."); + + return kOkDtRC; +} + +cmDtRC_t cmDataParserCreate( cmCtx_t* ctx, cmDataParserH_t* hp ) +{ + cmDtRC_t rc; + unsigned i; + + if((rc = cmDataParserDestroy(hp)) != kOkDtRC ) + return rc; + + cmDataParser_t* p = cmMemAllocZ(cmDataParser_t,1); + + cmErrSetup(&p->err,&ctx->err,"Data Parser"); + + if(cmLexIsValid(p->lexH = cmLexInit(NULL,0,0,err->rpt))==false) + { + rc = cmErrMsg(err, kLexFailDtRC, "The data object parser lexer create failed."); + goto errLabel; + } + + for(i=0; cmDtTokeyArray[i].id!=kErrorLexTId; ++i) + if( cmLexRegisterToken(p->lexH, cmDtTokenArray[i].id, cmDtTokenArray[i].label) != kOkLexRC ) + { + rc = cmErrMsg(&p->err,kLexFailDtRC,"The data object parser lexer could not register the '%s' token.",cmDtTokenArray[i].label); + goto errLabel; + } + + if( cmStackAlloc(ctx, &p->stH, 1024, 1024, sizeof(cmDataStEle_t)) != kOkStRC ) + { + rc = cmErrMsg(&p->err,kParseStackFailDtRC,"The data object parser stack create failed."); + goto errLabel; + } + + hp->h = p; + + errLabel: + if( rc != kOkDtRC ) + _cmDataParserDestroy(p); + + return kOkDtRC; +} + +cmDtRC_t cmDataParserDestroy( cmErr_t* err, cmDataParserH_t* hp ) +{ + cmDtRC_t rc=kOkDtRC; + + if( hp==NULL || cmDataParserIsValid(*hp)==false ) + return rc; + + cmDataParser_t* p = _cmDataParserHandleToPtr(*hp); + + if((rc = _cmDataParserDestroy(p)) != kOkDtRC ) + return rc; + + hp->h = NULL; + + return kOkDtRC; +} + + +bool cmDataParserIsValid( cmDataParserH_t h ) +{ return h.h != NULL; } + + +cmDtRC_t _cmDataLexErrorV( cmErr_t* err, cmLexH_t lexH, const cmChar_t* fmt, va_list vl ) +{ + +} + +cmDtRC_t _cmDataLexError( cmErr_t* err, cmLexH_t lexH, const cmChar_t* fmt, ... ) +{ + va_list vl; + va_start(vl,fmt); + cmDtRC_t rc, _cmDataLexErrorV(err,lexH,fmt,vl); + va_end(vl); + return rc; +} + +// { +// id0 : scalar_value +// id1 : ( heterogenous, array, value ) +// id2 : [ homogeneous array values ] +// id3 : +// } + +enum +{ + kRecdStateId, + kFieldValueStateId, + kArrayValueStateId +}; + +cmDtRC_t cmDataParserExec( cmDataParserH_t h, const cmChar_t* text, cmData_t** pp ) +{ + cmDtRC_t rc = kOkDtRC; + unsigned tokenId; + + cmDataParser_t* p = _cmDataParserHandleToPtr(h); + cmData_t* d = cmRecdAlloc(NULL); + + + if( cmLexSetTextBuffer(p->lexH,text,strlen(text)) != kOkLexRC ) + return cmErrMsg(&p->err,kLexFailDtRC,"The data object lexer failed during reset."); + + while((tokenId = cmLexGetNextToken(p->lexH)) != kEofLexTId ) + { + case kRealLexTId: // real number (contains a decimal point or is in scientific notation) + break; + + case kIntLexTId: // decimal integer + break; + + case kHexLexTId: // hexidecimal integer + break; + + case kIdentLexTId: // identifier + break; + + case kQStrLexTId: // quoted string + break; + + case kLCurlyLexTId + case kRCurlyLexTId: + case kLParenLexTId: + case kRParenLexTId: + case kLBrackLexTId: + case kRBrackLexTId: + case kColonLexTId: + case kCommaLexTId: + + + case kBlockCmtLexTId: // block comment + case kLineCmtLexTId: // line comment + case kErrorLexTId: // the lexer was unable to identify the current token + case kUnknownLexTId: // the token is of an unknown type (only used when kReturnUnknownLexFl is set) + case kEofLexTId: // the lexer reached the end of input + case kSpaceLexTId: // white space + { + rc = cmErrMsg(err,kLexFailDtRC,"The data object lexer failed with an unexpected token '%s' on line '%i'.",cmLexIdToLabel(lexH,tokenId),cmLexCurrentLineNumber(lexH)); + goto errLabel; + } + + } + + errLabel: + return rc; +} + +#endif +//============================================================================ +//============================================================================ +//============================================================================ + #define parr(rpt,fmt,arr,n) do{int i=0; cmRptPrintf(rpt,"[ "); for(;i Date: Thu, 14 Nov 2013 16:44:34 -0500 Subject: [PATCH 08/23] cmStack.h : Added comments. --- cmStack.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmStack.h b/cmStack.h index 63d06db..189acc2 100644 --- a/cmStack.h +++ b/cmStack.h @@ -42,12 +42,15 @@ extern "C" { const void* cmStackTop( cmStackH_t h ); // Set the value of 'dataEleCnt' elements on the stack. + // The top element is at index cmStackCount() - 1. cmStRC_t cmStackSet( cmStackH_t h, unsigned index, const void* data, unsigned dataEleCnt ); // Copy 'dataEleCnt' elements into the buffer pointed to by 'data'. + // The top element is at index cmStackCount() - 1. cmStRC_t cmStackGetN( cmStackH_t h, unsigned index, void* data, unsigned dataEleCnt ); // Return a pointer to a single element on the stack. + // The top element is at index cmStackCount() - 1. const void* cmStackGet( cmStackH_t h, unsigned index ); // Convert the internal representation of the stack to a linear array and return From 1a70a5afa068e024fd8324028c6fdeb7be2945b8 Mon Sep 17 00:00:00 2001 From: kevin Date: Thu, 14 Nov 2013 16:45:01 -0500 Subject: [PATCH 09/23] cmData.h/c : Completed initial implementation of cmDataParser. --- cmData.c | 576 ++++++++++++++++++++++++++++++++++++++++++++++++------- cmData.h | 17 +- 2 files changed, 516 insertions(+), 77 deletions(-) diff --git a/cmData.c b/cmData.c index 45b52bc..0791a3e 100644 --- a/cmData.c +++ b/cmData.c @@ -4,8 +4,10 @@ #include "cmCtx.h" #include "cmMem.h" #include "cmMallocDebug.h" +#include "cmLinkedHeap.h" #include "cmData.h" #include "cmLex.h" +#include "cmText.h" #include "cmStack.h" cmDtRC_t _cmDataErrNo = kOkDtRC; @@ -668,20 +670,26 @@ cmData_t* cmDataSetDoublePtr( cmData_t* p, double* vp, unsigned cnt ) // Set the value of an existing array based data object. // Allocate the internal array and copy the array into it. -cmData_t* cmDataSetStrAlloc( cmData_t* p, const cmChar_t* s ) +cmData_t* cmDataSetStrAllocN( cmData_t* p, const cmChar_t* s, unsigned charCnt ) { if( cmIsFlag(p->flags,kDynPtrDtFl) ) - cmMemResizeStr(p->u.z,s); + cmMemResizeStrN(p->u.z,s,charCnt); else { _cmDataFreeArray(p); - p->u.z = cmMemAllocStr(s); + p->u.z = cmMemAllocStrN(s,charCnt); } p->tid = kStrDtId; p->flags = cmSetFlag(p->flags,kDynPtrDtFl); return p; } +cmData_t* cmDataSetStrAlloc( cmData_t* p, const cmChar_t* s ) +{ return cmDataSetStrAllocN(p,s,strlen(s)); } + +cmData_t* cmDataSetConstStrAllocN( cmData_t* p, const cmChar_t* s, unsigned charCnt ) +{ return cmDataSetStrAllocN(p,s,charCnt); } + cmData_t* cmDataSetConstStrAlloc( cmData_t* p, const cmChar_t* s ) { return cmDataSetStrAlloc(p,s); } @@ -697,6 +705,7 @@ cmData_t* cmDataSetCharAllocPtr( cmData_t* p, const char* vp, unsigned cnt ) _cmDataFreeArray(p); p->u.cp = cmMemAlloc(char, cnt ); } + memcpy(p->u.cp,vp,sizeof(char)*cnt); p->tid = kCharPtrDtId; p->flags = cmSetFlag(p->flags,kDynPtrDtFl); @@ -1034,6 +1043,14 @@ cmData_t* cmDataStrAlloc( cmData_t* parent, cmChar_t* str ) return p; } +cmData_t* cmDataConstStrAllocN( cmData_t* parent, const cmChar_t* str, unsigned charCnt ) +{ + cmData_t* p = _cmDataAllocNode(parent,kConstStrDtId); + cmDataSetConstStrAllocN(p,str,charCnt); + return p; +} + + cmData_t* cmDataConstStrAlloc( cmData_t* parent, const cmChar_t* str ) { cmData_t* p = _cmDataAllocNode(parent,kConstStrDtId); @@ -1460,6 +1477,15 @@ cmData_t* cmDataAllocPairLabel( cmData_t* parent, const cmChar_t *label, cmData_ cmDataAppendChild(p,value); return p; } + +cmData_t* cmDataAllocPairLabelN(cmData_t* parent, const cmChar_t* label, unsigned charCnt, cmData_t* value) +{ + cmData_t* p = _cmDataAllocNode(parent,kPairDtId); + cmDataConstStrAllocN(p,label,charCnt); + cmDataAppendChild(p,value); + return p; +} + //---------------------------------------------------------------------------- @@ -1759,7 +1785,7 @@ const cmChar_t* cmDataRecdKeyLabel( cmData_t* p, unsigned index ) return label; } -cmData_t* cmRecdMake( cmData_t* parent, cmData_t* p ) +cmData_t* cmDataRecdMake( cmData_t* parent, cmData_t* p ) { _cmDataFree(p); p->parent = parent; @@ -1769,10 +1795,10 @@ cmData_t* cmRecdMake( cmData_t* parent, cmData_t* p ) return p; } -cmData_t* cmRecdAlloc(cmData_t* parent) +cmData_t* cmDataRecdAlloc(cmData_t* parent) { return _cmDataAllocNode(parent,kRecordDtId); } -cmData_t* cmRecdAppendPair( cmData_t* p, cmData_t* pair ) +cmData_t* cmDataRecdAppendPair( cmData_t* p, cmData_t* pair ) { assert( p!=NULL && p->tid==kRecordDtId); cmDataAppendChild(p,pair); @@ -1822,7 +1848,7 @@ cmDtRC_t _cmDataRecdParseInputV(cmData_t* parent, unsigned idFl, va_list vl ) cmData_t* cmDataRecdAllocLabelV( cmData_t* parent, va_list vl ) { - cmData_t* p = cmRecdAlloc(parent); + cmData_t* p = cmDataRecdAlloc(parent); cmDtRC_t rc = _cmDataRecdParseInputV(p, false, vl ); if( rc != kOkDtRC ) { @@ -1843,7 +1869,7 @@ cmData_t* cmDataRecdAllocLabelA( cmData_t* parent, ... ) cmData_t* cmDataRecdAllocIdV( cmData_t* parent, va_list vl ) { - cmData_t* p = cmRecdAlloc(parent); + cmData_t* p = cmDataRecdAlloc(parent); cmDtRC_t rc = _cmDataRecdParseInputV(p, true, vl ); if( rc != kOkDtRC ) { @@ -2181,7 +2207,6 @@ cmDtRC_t cmDataDeserialize( const void* buf, unsigned bufByteCnt, cmData_t** pp //============================================================================ //============================================================================ //============================================================================ -#ifdef NOT_DEF enum { kLCurlyLexTId = kUserLexTId + 1, @@ -2196,7 +2221,7 @@ enum typedef struct { - unsigned id; + unsigned id; const cmChar_t* label; } cmDtToken_t; @@ -2222,10 +2247,6 @@ typedef struct } cmDataParser_t; -typedef struct -{ - unsigned tokId; -} cmDataStEle_t; cmDataParserH_t cmDataParserNullHandle = cmSTATIC_NULL_HANDLE; @@ -2239,10 +2260,10 @@ cmDataParser_t* _cmDataParserHandleToPtr( cmDataParserH_t h ) cmDtRC_t _cmDataParserDestroy( cmDataParser_t* p ) { if( cmLexFinal(&p->lexH) != kOkLexRC ) - cmErrMsg(&p->err,kLexFailedDtRC,"Lexer release failed."); + cmErrMsg(&p->err,kLexFailDtRC,"Lexer release failed."); if( cmStackFree(&p->stH) != kOkStRC ) - cmErrMsg(&p->err,kParserStackFailDtRC,"The data object parser stack release failed."); + cmErrMsg(&p->err,kParseStackFailDtRC,"The data object parser stack release failed."); return kOkDtRC; } @@ -2257,22 +2278,22 @@ cmDtRC_t cmDataParserCreate( cmCtx_t* ctx, cmDataParserH_t* hp ) cmDataParser_t* p = cmMemAllocZ(cmDataParser_t,1); - cmErrSetup(&p->err,&ctx->err,"Data Parser"); + cmErrSetup(&p->err,&ctx->rpt,"Data Parser"); - if(cmLexIsValid(p->lexH = cmLexInit(NULL,0,0,err->rpt))==false) + if(cmLexIsValid(p->lexH = cmLexInit(NULL,0,0,&ctx->rpt))==false) { - rc = cmErrMsg(err, kLexFailDtRC, "The data object parser lexer create failed."); + rc = cmErrMsg(&p->err, kLexFailDtRC, "The data object parser lexer create failed."); goto errLabel; } - for(i=0; cmDtTokeyArray[i].id!=kErrorLexTId; ++i) - if( cmLexRegisterToken(p->lexH, cmDtTokenArray[i].id, cmDtTokenArray[i].label) != kOkLexRC ) + for(i=0; _cmDtTokenArray[i].id != kErrorLexTId; ++i) + if( cmLexRegisterToken(p->lexH, _cmDtTokenArray[i].id, _cmDtTokenArray[i].label) != kOkLexRC ) { - rc = cmErrMsg(&p->err,kLexFailDtRC,"The data object parser lexer could not register the '%s' token.",cmDtTokenArray[i].label); + rc = cmErrMsg(&p->err,kLexFailDtRC,"The data object parser lexer could not register the '%s' token.",_cmDtTokenArray[i].label); goto errLabel; } - if( cmStackAlloc(ctx, &p->stH, 1024, 1024, sizeof(cmDataStEle_t)) != kOkStRC ) + if( cmStackAlloc(ctx, &p->stH, 1024, 1024, sizeof(cmData_t*)) != kOkStRC ) { rc = cmErrMsg(&p->err,kParseStackFailDtRC,"The data object parser stack create failed."); goto errLabel; @@ -2287,7 +2308,7 @@ cmDtRC_t cmDataParserCreate( cmCtx_t* ctx, cmDataParserH_t* hp ) return kOkDtRC; } -cmDtRC_t cmDataParserDestroy( cmErr_t* err, cmDataParserH_t* hp ) +cmDtRC_t cmDataParserDestroy( cmDataParserH_t* hp ) { cmDtRC_t rc=kOkDtRC; @@ -2309,19 +2330,6 @@ bool cmDataParserIsValid( cmDataParserH_t h ) { return h.h != NULL; } -cmDtRC_t _cmDataLexErrorV( cmErr_t* err, cmLexH_t lexH, const cmChar_t* fmt, va_list vl ) -{ - -} - -cmDtRC_t _cmDataLexError( cmErr_t* err, cmLexH_t lexH, const cmChar_t* fmt, ... ) -{ - va_list vl; - va_start(vl,fmt); - cmDtRC_t rc, _cmDataLexErrorV(err,lexH,fmt,vl); - va_end(vl); - return rc; -} // { // id0 : scalar_value @@ -2330,70 +2338,452 @@ cmDtRC_t _cmDataLexError( cmErr_t* err, cmLexH_t lexH, const cmChar_t* fmt, ... // id3 : // } + +// flags describing the expected next token enum { - kRecdStateId, - kFieldValueStateId, - kArrayValueStateId + kValueExpFl = 0x01, + kIdExpFl = 0x02, + kColonExpFl = 0x04, + kCommaExpFl = 0x08 }; +typedef struct +{ + cmData_t* dp; +} cmDataStEle_t; + +typedef struct +{ + cmDataParser_t* p; + cmData_t* cnp; + unsigned flags; + cmChar_t* tmpStr; + + unsigned arrayCnt; + void* arrayMem; + +} cmDataParserCtx_t; + +cmDtRC_t _cmDpSyntaxErrV( cmDataParserCtx_t* c, const cmChar_t* fmt, va_list vl ) +{ + cmChar_t* s0 = NULL; + s0 = cmTsVPrintfP(s0,fmt,vl); + cmDtRC_t rc = cmErrMsg(&c->p->err,kSyntaxErrDtRC,"Syntax error on line %i. %s",cmLexCurrentLineNumber(c->p->lexH),cmStringNullGuard(s0)); + cmMemFree(s0); + return rc; +} + +cmDtRC_t _cmDpSyntaxErr( cmDataParserCtx_t* c, const cmChar_t* fmt, ... ) +{ + va_list vl; + va_start(vl,fmt); + cmDtRC_t rc = _cmDpSyntaxErrV(c,fmt,vl); + va_end(vl); + return rc; +} + +cmDtRC_t _cmDpPopStack( cmDataParserCtx_t* c, cmData_t** pp ) +{ + const void* vp; + if((vp = cmStackTop(c->p->stH)) == NULL ) + return _cmDpSyntaxErr(c,"Stack underflow."); + + *pp = *(cmData_t**)vp; + + return kOkDtRC; +} + +cmDtRC_t _cmDpStoreArrayEle( cmDataParserCtx_t* c, void* dp, unsigned byteCnt ) +{ + char* vp = cmMemResize(char, c->cnp->u.vp, c->cnp->cnt+byteCnt); + + memcpy(vp + c->cnp->cnt,dp,byteCnt); + c->cnp->u.vp = vp; + c->cnp->cnt += byteCnt; + + c->flags = kValueExpFl | kCommaExpFl; + + return kOkDtRC; +} + +cmDtRC_t _cmDataParserOpenPair( cmDataParserCtx_t* c ) +{ + assert( c->cnp->tid == kRecordDtId ); + + cmData_t* nnp = cmDataAllocNull(NULL); + cmData_t* pnp = cmDataAllocPairLabelN( c->cnp, cmLexTokenText(c->p->lexH), cmLexTokenCharCount(c->p->lexH), nnp ); + + // store the current node + if( cmStackPush(c->p->stH, &c->cnp, 1 ) != kOkStRC ) + return _cmDpSyntaxErr(c,"Parser stack push failed."); + + // make the new pair the current node + c->cnp = pnp; + + // pair openings must be followed by a colon. + c->flags = kColonExpFl; + + return kOkDtRC; +} + +cmDtRC_t _cmDataParserClosePair( cmDataParserCtx_t* c ) +{ + cmDtRC_t rc; + + // make the pair's parent record the current node + if((rc = _cmDpPopStack(c, &c->cnp )) != kOkDtRC ) + return rc; + + // pairs only occur in records + if( c->cnp->tid != kRecordDtId ) + return _cmDpSyntaxErr(c,"A 'pair' end was found outside of a 'record'."); + + // pairs must be followed by id's or comma's + c->flags = kIdExpFl | kCommaExpFl; + + return rc; +} + +cmDtRC_t _cmDpStoreValue( cmDataParserCtx_t* c, cmData_t* np, const cmChar_t* typeLabel ) +{ + assert( np != NULL ); + + cmDtRC_t rc = kOkDtRC; + + switch( c->cnp->tid ) + { + case kPairDtId: + + // assign the new node as the value of the pair + cmDataPairSetValue(c->cnp,np); + + // close the values parent pair + rc = _cmDataParserClosePair(c); + break; + + case kListDtId: + cmDataAppendChild(c->cnp,np); + c->flags = kValueExpFl; + break; + + default: + rc = _cmDpSyntaxErr(c,"A '%s' value was found outside of a valid container.",typeLabel); + } + + c->flags |= kCommaExpFl; + + return rc; +} + +cmDtRC_t _cmDataParserReal( cmDataParserCtx_t* c ) +{ + cmDtRC_t rc = kOkDtRC; + double val = cmLexTokenDouble(c->p->lexH); + + if( c->cnp->tid == kVoidPtrDtId ) + rc = _cmDpStoreArrayEle(c,&val,sizeof(val)); + else + rc = _cmDpStoreValue(c,cmDataAllocDouble(NULL,val),"real"); + + return rc; +} + +cmDtRC_t _cmDataParserInt( cmDataParserCtx_t* c ) +{ + cmDtRC_t rc = kOkDtRC; + int val = cmLexTokenInt(c->p->lexH); + + if( c->cnp->tid == kVoidPtrDtId ) + rc = _cmDpStoreArrayEle(c,&val,sizeof(val)); + else + rc = _cmDpStoreValue(c,cmDataAllocInt(NULL,val),"int"); + + return rc; +} + +cmDtRC_t _cmDataParserString( cmDataParserCtx_t* c ) +{ + // if we are expecting a pair label + if( cmIsFlag(c->flags,kIdExpFl) ) + return _cmDataParserOpenPair(c); + + // otherwise a 'value' must be expected + if( cmIsNotFlag(c->flags,kValueExpFl) ) + return _cmDpSyntaxErr(c,"Unexpected string."); + + cmData_t* np = cmDataConstStrAllocN(NULL,cmLexTokenText(c->p->lexH), cmLexTokenCharCount(c->p->lexH)); + + return _cmDpStoreValue(c,np,"string"); +} + +cmDtRC_t _cmDataParserOpenRecd( cmDataParserCtx_t* c ) +{ + // records are values - so we must be expecting a value + if( cmIsFlag(c->flags,kValueExpFl) == false ) + return _cmDpSyntaxErr(c,"Unexpected '{'."); + + // store the current node + if( cmStackPush(c->p->stH, &c->cnp, 1 ) != kOkStRC ) + return _cmDpSyntaxErr(c,"Parser stack push failed."); + + // alloc a new record and make it the current node + if( (c->cnp = cmDataRecdAlloc(c->cnp)) == NULL ) + return _cmDpSyntaxErr(c,"'recd' allocate failed."); + + // new records must be followed by an id token. + c->flags = kIdExpFl; + + return kOkDtRC; +} + +cmDtRC_t _cmDataParserCloseRecd( cmDataParserCtx_t* c ) +{ + cmDtRC_t rc; + + // make the parent node the new curren node + if((rc = _cmDpPopStack(c,&c->cnp)) != kOkDtRC ) + return rc; + + switch( c->cnp->tid ) + { + case kPairDtId: + // if the parent node is a pair then close it + rc = _cmDataParserClosePair(c); + break; + + case kListDtId: + // parent node is a list - so expect another value + c->flags = kValueExpFl; + break; + + default: + return _cmDpSyntaxErr(c,"'records' may only be contained in other records or heterogenous arrays."); + + } + + c->flags |= kCommaExpFl; + + return rc; +} + +cmDtRC_t _cmDataParserOpenList( cmDataParserCtx_t* c ) +{ + // lists are values - so we must be expecting a value + if( cmIsFlag(c->flags,kValueExpFl) == false ) + return _cmDpSyntaxErr(c,"Unexpected '('."); + + // store the current node + if( cmStackPush(c->p->stH, &c->cnp, 1 ) != kOkStRC ) + return _cmDpSyntaxErr(c,"Parser stack push failed."); + + // create a new list + if( (c->cnp = cmDataListAlloc(c->cnp)) == NULL ) + return _cmDpSyntaxErr(c,"'list' allocate failed."); + + // new lists must be followed by a value + c->flags = kValueExpFl; + + return kOkDtRC; +} + +cmDtRC_t _cmDataParserCloseList( cmDataParserCtx_t* c ) +{ + cmDtRC_t rc; + + // make the list's parent the current node + if((rc = _cmDpPopStack(c,&c->cnp)) != kOkDtRC ) + return rc; + + switch( c->cnp->tid ) + { + case kPairDtId: + // if the list's parent is a pair then close it + rc = _cmDataParserClosePair(c); + break; + + case kListDtId: + // the list's parent is another list so expect a value + c->flags = kValueExpFl; + break; + + default: + return _cmDpSyntaxErr(c,"'lists' may only be contained in other records or lists."); + + } + + c->flags |= kCommaExpFl; + + return rc; +} + +cmDtRC_t _cmDataParserOpenArray( cmDataParserCtx_t* c ) +{ + + // arrays are values - so we must be expecting a value + if( cmIsFlag(c->flags,kValueExpFl) == false ) + return _cmDpSyntaxErr(c,"Unexpected '('."); + + // store the current node + if( cmStackPush(c->p->stH, &c->cnp, 1 ) != kOkStRC ) + return _cmDpSyntaxErr(c,"Parser stack push failed."); + + // create a new array + if( (c->cnp = cmDataSetVoidAllocPtr(c->cnp, NULL, 0 )) == NULL ) + return _cmDpSyntaxErr(c,"'array' allocate failed."); + + // new arrays must be followed by a value + c->flags = kValueExpFl; + + return kOkDtRC; + +} + +cmDtRC_t _cmDataParserCloseArray( cmDataParserCtx_t* c ) +{ + cmDtRC_t rc; + + // make the arrays parent the current node + if((rc = _cmDpPopStack(c,&c->cnp)) != kOkDtRC ) + return rc; + + switch( c->cnp->tid ) + { + + case kPairDtId: + // the arrays parent is a pair - so close it + rc = _cmDataParserClosePair(c); + break; + + case kListDtId: + // the arrays parent is a list - so expect a value + c->flags = kValueExpFl; + break; + + default: + return _cmDpSyntaxErr(c,"'arrays' may only be contained in other records or lists."); + + } + + c->flags |= kCommaExpFl; + + return rc; +} + +cmDtRC_t _cmDataParserOnColon( cmDataParserCtx_t* c ) +{ + // colons only follow field identifiers and are always followed by values. + if( cmIsFlag(c->flags,kColonExpFl) == false ) + return _cmDpSyntaxErr(c,"Unexpected colon."); + + c->flags = kValueExpFl; + + return kOkDtRC; +} + +cmDtRC_t _cmDataParserOnComma( cmDataParserCtx_t* c ) +{ + // comma's may be found in three places: + // 1) following field values + // 2) between list values + // 3) between array values + // comma's are always followed by values + if( cmIsFlag(c->flags,kCommaExpFl) == false ) + return _cmDpSyntaxErr(c, "Unexpected comma."); + + c->flags = kValueExpFl; + + return kOkDtRC; +} + + cmDtRC_t cmDataParserExec( cmDataParserH_t h, const cmChar_t* text, cmData_t** pp ) { cmDtRC_t rc = kOkDtRC; unsigned tokenId; - cmDataParser_t* p = _cmDataParserHandleToPtr(h); - cmData_t* d = cmRecdAlloc(NULL); - + cmDataParserCtx_t ctx; + cmDataParser_t* p = _cmDataParserHandleToPtr(h); + + ctx.cnp = NULL; // current node ptr + ctx.p = p; + ctx.flags = kValueExpFl; if( cmLexSetTextBuffer(p->lexH,text,strlen(text)) != kOkLexRC ) return cmErrMsg(&p->err,kLexFailDtRC,"The data object lexer failed during reset."); + cmStackClear(p->stH,false); + while((tokenId = cmLexGetNextToken(p->lexH)) != kEofLexTId ) { - case kRealLexTId: // real number (contains a decimal point or is in scientific notation) + switch(tokenId) + { + case kRealLexTId: // real number (contains a decimal point or is in scientific notation) + rc = _cmDataParserReal(&ctx); + break; + + case kIntLexTId: // decimal integer + rc = _cmDataParserInt(&ctx); + break; + + case kHexLexTId: // hexidecimal integer + rc = _cmDataParserInt(&ctx); + break; + + case kIdentLexTId: // identifiers are treated as strings + case kQStrLexTId: // quoted string + rc = _cmDataParserString(&ctx); + break; + + case kLCurlyLexTId: // a new record is starting + rc = _cmDataParserOpenRecd(&ctx); break; - case kIntLexTId: // decimal integer - break; + case kRCurlyLexTId: // the current record is finished + rc = _cmDataParserCloseRecd(&ctx); + break; - case kHexLexTId: // hexidecimal integer - break; + case kLParenLexTId: // a list is starting + rc = _cmDataParserOpenList(&ctx); + break; - case kIdentLexTId: // identifier - break; + case kRParenLexTId: // a list is finished + rc = _cmDataParserCloseList(&ctx); + break; - case kQStrLexTId: // quoted string - break; + case kLBrackLexTId: // an array is starting + rc = _cmDataParserOpenArray(&ctx); + break; - case kLCurlyLexTId - case kRCurlyLexTId: - case kLParenLexTId: - case kRParenLexTId: - case kLBrackLexTId: - case kRBrackLexTId: - case kColonLexTId: - case kCommaLexTId: + case kRBrackLexTId: // an array is ending + rc = _cmDataParserCloseArray(&ctx); + break; + case kColonLexTId: // the previous id was a field id + rc = _cmDataParserOnColon(&ctx); + break; - case kBlockCmtLexTId: // block comment - case kLineCmtLexTId: // line comment - case kErrorLexTId: // the lexer was unable to identify the current token - case kUnknownLexTId: // the token is of an unknown type (only used when kReturnUnknownLexFl is set) - case kEofLexTId: // the lexer reached the end of input - case kSpaceLexTId: // white space - { - rc = cmErrMsg(err,kLexFailDtRC,"The data object lexer failed with an unexpected token '%s' on line '%i'.",cmLexIdToLabel(lexH,tokenId),cmLexCurrentLineNumber(lexH)); - goto errLabel; - } + case kCommaLexTId: // comma sep. for array or fields + rc = _cmDataParserOnComma(&ctx); + break; + case kBlockCmtLexTId: // block comment + case kLineCmtLexTId: // line comment + case kErrorLexTId: // the lexer was unable to identify the current token + case kUnknownLexTId: // the token is of an unknown type (only used when kReturnUnknownLexFl is set) + case kEofLexTId: // the lexer reached the end of input + case kSpaceLexTId: // white space + { + rc = cmErrMsg(&p->err,kLexFailDtRC,"The data object lexer failed with an unexpected token '%s' on line '%i'.",cmLexIdToLabel(p->lexH,tokenId),cmLexCurrentLineNumber(p->lexH)); + goto errLabel; + } + } } errLabel: return rc; } -#endif //============================================================================ //============================================================================ //============================================================================ @@ -2487,10 +2877,54 @@ void _cmDataPrint( const cmData_t* p, cmRpt_t* rpt, unsigned indent ) void cmDataPrint( const cmData_t* p, cmRpt_t* rpt ) { _cmDataPrint(p,rpt,0); } + +cmDtRC_t cmDataParserTest( cmCtx_t* ctx ) +{ + cmDtRC_t rc = kOkDtRC; + cmDataParserH_t h = cmDataParserNullHandle; + cmErr_t err; + cmData_t* dp = NULL; + + const cmChar_t text[] = + { + "{ f0:1.23 f1:\"hey\" " + }; + + cmErrSetup(&err,&ctx->rpt,"Data Parser Tester"); + + if((rc = cmDataParserCreate(ctx, &h )) != kOkDtRC ) + { + rc = cmErrMsg(&err,rc,"Data parser create failed."); + goto errLabel; + } + + if( cmDataParserExec(h,text,&dp) != kOkDtRC ) + rc = cmErrMsg(&err,rc,"Data parser exec failed."); + else + { + cmDataPrint(dp,&ctx->rpt); + } + + errLabel: + if( cmDataParserDestroy( &h ) != kOkDtRC ) + { + rc = cmErrMsg(&err,rc,"Data parser destroy failed."); + goto errLabel; + } + + cmDataFree(dp); + + return rc; +} + + void cmDataTest( cmCtx_t* ctx ) { float farr[] = { 1.23, 45.6, 7.89 }; + cmDataParserTest(ctx); + return; + cmData_t* d0 = cmDataRecdAllocLabelA(NULL, "name",kConstStrDtId,"This is a string.", "id", kUIntDtId, 21, diff --git a/cmData.h b/cmData.h index 3498950..3456358 100644 --- a/cmData.h +++ b/cmData.h @@ -13,6 +13,7 @@ extern "C" { kMissingFieldDtRC, kLexFailDtRC, kParseStackFailDtRC, + kSyntaxErrDtRC, kEolDtRC }; @@ -66,8 +67,8 @@ extern "C" { kMinStructDtId, kListDtId = kMinStructDtId, // children nodes are array elements, cnt=child count - kPairDtId, // key/value pairs, cnt=2, first child is key, second is value - kRecordDtId, // children nodes are pairs, cnt=pair count + kPairDtId, // key/value pairs, cnt=2, first child is key, second is value + kRecordDtId, // children nodes are pairs, cnt=pair count kMaxStructDtId, kOptArgDtFl = 0x80000000 @@ -273,7 +274,9 @@ extern "C" { // These functions begin by releasing any resources help by *p // and then dynamically allocate the internal array and copy // the array data into it. + cmData_t* cmDataSetStrAllocN( cmData_t* p, const cmChar_t* s, unsigned charCnt ); cmData_t* cmDataSetStrAlloc( cmData_t* p, const cmChar_t* s ); + cmData_t* cmDataSetConstStrAllocN( cmData_t* p, const cmChar_t* s, unsigned charCnt ); cmData_t* cmDataSetConstStrAlloc( cmData_t* p, const cmChar_t* s ); cmData_t* cmDataSetVoidAllocPtr( cmData_t* p, const void* vp, unsigned cnt ); cmData_t* cmDataSetCharAllocPtr( cmData_t* p, const char* vp, unsigned cnt ); @@ -326,6 +329,7 @@ extern "C" { // and copy v[cnt] into it. cmData_t* cmDataStrAlloc( cmData_t* parent, cmChar_t* str ); cmData_t* cmDataConstStrAlloc( cmData_t* parent, const cmChar_t* str ); + cmData_t* cmDataConstStrAllocN( cmData_t* parent, const cmChar_t* str, unsigned charCnt ); cmData_t* cmDataCharAllocPtr( cmData_t* parent, const char* v, unsigned cnt ); cmData_t* cmDataUCharAllocPtr( cmData_t* parent, const unsigned char* v, unsigned cnt ); cmData_t* cmDataShortAllocPtr( cmData_t* parent, const short* v, unsigned cnt ); @@ -430,6 +434,7 @@ extern "C" { cmData_t* cmDataAllocPairId( cmData_t* parent, unsigned keyId, cmData_t* value ); // Dynamically allocate the label but link (w/o realloc) the value. + cmData_t* cmDataAllocPairLabelN(cmData_t* parent, const cmChar_t* label, unsigned charCnt, cmData_t* value); cmData_t* cmDataAllocPairLabel( cmData_t* parent, const cmChar_t* label, cmData_t* value ); //---------------------------------------------------------------------------- @@ -489,13 +494,13 @@ extern "C" { unsigned cmDataRecdKeyId( cmData_t* p, unsigned index ); const cmChar_t* cmDataRecdKeyLabel( cmData_t* p, unsigned index ); - cmData_t* cmRecdMake( cmData_t* parent, cmData_t* p ); - cmData_t* cmRecdAlloc( cmData_t* parent ); + cmData_t* cmDataRecdMake( cmData_t* parent, cmData_t* p ); + cmData_t* cmDataRecdAlloc( cmData_t* parent ); // Append a pair node by linking the pair node 'pair' to the record node 'p'. // 'pair' is simply linked to 'p' via cmDataAppendChild() no // reallocation or duplicattion takes place. - cmData_t* cmRecdAppendPair( cmData_t* p, cmData_t* pair ); + cmData_t* cmDataRecdAppendPair( cmData_t* p, cmData_t* pair ); // Var-args format: @@ -539,7 +544,7 @@ extern "C" { cmDtRC_t cmDataParserCreate( cmCtx_t* ctx, cmDataParserH_t* hp ); cmDtRC_t cmDataParserDestroy( cmDataParserH_t* hp ); bool cmDataParserIsValid( cmDataParserH_t h ); - cmDtRC_t cmDataParserExec( cmDataParserH_t h, cmChar_t* text, cmData_t** pp ); + cmDtRC_t cmDataParserExec( cmDataParserH_t h, const cmChar_t* text, cmData_t** pp ); //----------------------------------------------------------------------------- void cmDataPrint( const cmData_t* p, cmRpt_t* rpt ); From fd56025468a230316b74691c48b435a3283f2a39 Mon Sep 17 00:00:00 2001 From: kevin Date: Fri, 15 Nov 2013 08:52:26 -0500 Subject: [PATCH 10/23] cmData.c : Minor bug fixes to complete initial testing of cmDataParser. --- cmData.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/cmData.c b/cmData.c index 130de03..9387904 100644 --- a/cmData.c +++ b/cmData.c @@ -1373,8 +1373,7 @@ bool _cmDataPairIsValid( const cmData_t* p ) { assert( p->tid == kPairDtId ); - const cmData_t* cp = p->u.child; - bool fl = cp->u.child == NULL || cp->u.child->sibling == NULL || cp->u.child->sibling->sibling!=NULL; + bool fl = p->u.child == NULL || p->u.child->sibling == NULL || p->u.child->sibling->sibling!=NULL; return !fl; } @@ -2194,7 +2193,7 @@ char* _cmDataSerializeWrite( cmData_t* np, char* dp, const char* ep ) char* _cmDataSerialize( const cmData_t* p, char* buf, const char* ep ) { - + /* buf = _cmDataSerializeWrite(p,buf,ep); // if this data type has a child then write the child @@ -2207,13 +2206,17 @@ char* _cmDataSerialize( const cmData_t* p, char* buf, const char* ep ) buf = cmDataSerialize(dp->sibling,buf,ep); return buf; + */ + return NULL; } cmDtRC_t cmDataSerialize( const cmData_t* p, void* buf, unsigned bufByteCnt ) { + /* const char* ep = (char*)p + bufByteCnt; buf = _cmDataSerialize(p,buf,bufByteCnt); assert( buf <= ep ); + */ return kOkDtRC; } @@ -2283,6 +2286,8 @@ cmDtRC_t _cmDataParserDestroy( cmDataParser_t* p ) if( cmStackFree(&p->stH) != kOkStRC ) cmErrMsg(&p->err,kParseStackFailDtRC,"The data object parser stack release failed."); + cmMemFree(p); + return kOkDtRC; } @@ -2717,11 +2722,10 @@ cmDtRC_t _cmDataParserOnComma( cmDataParserCtx_t* c ) cmDtRC_t cmDataParserExec( cmDataParserH_t h, const cmChar_t* text, cmData_t** pp ) { - cmDtRC_t rc = kOkDtRC; - unsigned tokenId; - + cmDtRC_t rc = kOkDtRC; + cmDataParser_t* p = _cmDataParserHandleToPtr(h); + unsigned tokenId; cmDataParserCtx_t ctx; - cmDataParser_t* p = _cmDataParserHandleToPtr(h); ctx.cnp = NULL; // current node ptr ctx.p = p; @@ -2799,6 +2803,10 @@ cmDtRC_t cmDataParserExec( cmDataParserH_t h, const cmChar_t* text, cmData_t** p } errLabel: + + if( rc == kOkDtRC ) + *pp = ctx.cnp; + return rc; } @@ -2919,9 +2927,9 @@ cmDtRC_t cmDataParserTest( cmCtx_t* ctx ) if( cmDataParserExec(h,text,&dp) != kOkDtRC ) rc = cmErrMsg(&err,rc,"Data parser exec failed."); else - { - cmDataPrint(dp,&ctx->rpt); - } + if( dp != NULL ) + cmDataPrint(dp,&ctx->rpt); + errLabel: if( cmDataParserDestroy( &h ) != kOkDtRC ) From 2e1c77f15077f5bbff761f7d78e2d0795db7d7df Mon Sep 17 00:00:00 2001 From: kpl Date: Fri, 15 Nov 2013 16:44:05 -0800 Subject: [PATCH 11/23] cmData.h/c : Initial debugging and testing of cmDataParser. --- cmData.c | 241 +++++++++++++++++++++++++++++-------------------------- cmData.h | 6 ++ 2 files changed, 131 insertions(+), 116 deletions(-) diff --git a/cmData.c b/cmData.c index 9387904..8f96c4d 100644 --- a/cmData.c +++ b/cmData.c @@ -34,6 +34,9 @@ void _cmDataFreeArray( cmData_t* p ) void _cmDataFree( cmData_t* p ) { + if( p == NULL ) + return; + if( cmDataIsStruct(p) ) { cmData_t* cp = p->u.child; @@ -2391,9 +2394,12 @@ typedef struct cmDtRC_t _cmDpSyntaxErrV( cmDataParserCtx_t* c, const cmChar_t* fmt, va_list vl ) { cmChar_t* s0 = NULL; + cmChar_t* s1 = NULL; s0 = cmTsVPrintfP(s0,fmt,vl); - cmDtRC_t rc = cmErrMsg(&c->p->err,kSyntaxErrDtRC,"Syntax error on line %i. %s",cmLexCurrentLineNumber(c->p->lexH),cmStringNullGuard(s0)); + s1 = cmMemAllocStrN(cmLexTokenText(c->p->lexH),cmLexTokenCharCount(c->p->lexH)); + cmDtRC_t rc = cmErrMsg(&c->p->err,kSyntaxErrDtRC,"Syntax error on line %i column:%i token:'%s'. %s",cmLexCurrentLineNumber(c->p->lexH),cmLexCurrentColumnNumber(c->p->lexH),s1,cmStringNullGuard(s0)); cmMemFree(s0); + cmMemFree(s1); return rc; } @@ -2412,18 +2418,41 @@ cmDtRC_t _cmDpPopStack( cmDataParserCtx_t* c, cmData_t** pp ) if((vp = cmStackTop(c->p->stH)) == NULL ) return _cmDpSyntaxErr(c,"Stack underflow."); + if( cmStackPop(c->p->stH,1) != kOkStRC ) + return _cmDpSyntaxErr(c,"Stack pop failed."); + *pp = *(cmData_t**)vp; + //printf("pop: %p\n",*pp); + return kOkDtRC; } -cmDtRC_t _cmDpStoreArrayEle( cmDataParserCtx_t* c, void* dp, unsigned byteCnt ) +cmDtRC_t _cmDpPushStack( cmDataParserCtx_t* c, cmData_t* np ) { - char* vp = cmMemResize(char, c->cnp->u.vp, c->cnp->cnt+byteCnt); + //printf("push:%p\n",np); + + // store the current node + if( cmStackPush(c->p->stH, &np, 1 ) != kOkStRC ) + return _cmDpSyntaxErr(c,"Parser stack push failed."); + + return kOkDtRC; +} + +cmDtRC_t _cmDpStoreArrayEle( cmDataParserCtx_t* c, void* dp, unsigned eleByteCnt, unsigned tid ) +{ + if( c->cnp->tid == kVoidPtrDtId ) + c->cnp->tid = tid; + else + if( c->cnp->tid != tid ) + return _cmDpSyntaxErr(c,"Mixed types were detected in an array list."); + + unsigned newByteCnt = (c->cnp->cnt+1)*eleByteCnt; + char* vp = cmMemResizeP(char, c->cnp->u.vp, newByteCnt); - memcpy(vp + c->cnp->cnt,dp,byteCnt); + memcpy(vp + c->cnp->cnt*eleByteCnt,dp,eleByteCnt); c->cnp->u.vp = vp; - c->cnp->cnt += byteCnt; + c->cnp->cnt += 1; c->flags = kValueExpFl | kCommaExpFl; @@ -2432,14 +2461,17 @@ cmDtRC_t _cmDpStoreArrayEle( cmDataParserCtx_t* c, void* dp, unsigned byteCnt ) cmDtRC_t _cmDataParserOpenPair( cmDataParserCtx_t* c ) { + cmDtRC_t rc = kOkDtRC; + assert( c->cnp->tid == kRecordDtId ); + // create a pair with a 'null' value which will be replaced when the pair's value is parsed cmData_t* nnp = cmDataAllocNull(NULL); cmData_t* pnp = cmDataAllocPairLabelN( c->cnp, cmLexTokenText(c->p->lexH), cmLexTokenCharCount(c->p->lexH), nnp ); // store the current node - if( cmStackPush(c->p->stH, &c->cnp, 1 ) != kOkStRC ) - return _cmDpSyntaxErr(c,"Parser stack push failed."); + if((rc = _cmDpPushStack(c,c->cnp)) != kOkDtRC ) + return rc; // make the new pair the current node c->cnp = pnp; @@ -2447,7 +2479,7 @@ cmDtRC_t _cmDataParserOpenPair( cmDataParserCtx_t* c ) // pair openings must be followed by a colon. c->flags = kColonExpFl; - return kOkDtRC; + return rc; } cmDtRC_t _cmDataParserClosePair( cmDataParserCtx_t* c ) @@ -2492,6 +2524,11 @@ cmDtRC_t _cmDpStoreValue( cmDataParserCtx_t* c, cmData_t* np, const cmChar_t* ty default: rc = _cmDpSyntaxErr(c,"A '%s' value was found outside of a valid container.",typeLabel); + + // Free the new data node because it was not attached and will + // otherwise be lost + cmDataFree(np); + } c->flags |= kCommaExpFl; @@ -2501,26 +2538,45 @@ cmDtRC_t _cmDpStoreValue( cmDataParserCtx_t* c, cmData_t* np, const cmChar_t* ty cmDtRC_t _cmDataParserReal( cmDataParserCtx_t* c ) { - cmDtRC_t rc = kOkDtRC; - double val = cmLexTokenDouble(c->p->lexH); + cmDtRC_t rc = kOkDtRC; + bool floatFl = cmLexTokenIsSinglePrecision(c->p->lexH); + double dval; + float fval; - if( c->cnp->tid == kVoidPtrDtId ) - rc = _cmDpStoreArrayEle(c,&val,sizeof(val)); + if( floatFl ) + fval = cmLexTokenFloat(c->p->lexH); else - rc = _cmDpStoreValue(c,cmDataAllocDouble(NULL,val),"real"); + dval = cmLexTokenDouble(c->p->lexH); + + if( cmDataIsPtr(c->cnp) ) + { + if( floatFl ) + rc = _cmDpStoreArrayEle(c,&fval,sizeof(fval),kFloatPtrDtId); + else + rc = _cmDpStoreArrayEle(c,&dval,sizeof(dval),kDoublePtrDtId); + } + else + { + cmData_t* np = floatFl ? cmDataAllocFloat(NULL,fval) : cmDataAllocDouble(NULL,dval); + rc = _cmDpStoreValue(c,np,"real"); + } return rc; } cmDtRC_t _cmDataParserInt( cmDataParserCtx_t* c ) { - cmDtRC_t rc = kOkDtRC; - int val = cmLexTokenInt(c->p->lexH); + cmDtRC_t rc = kOkDtRC; + int val = cmLexTokenInt(c->p->lexH); + bool unsignedFl = cmLexTokenIsUnsigned(c->p->lexH); - if( c->cnp->tid == kVoidPtrDtId ) - rc = _cmDpStoreArrayEle(c,&val,sizeof(val)); + if( cmDataIsPtr(c->cnp) ) + rc = _cmDpStoreArrayEle(c,&val,sizeof(val),unsignedFl ? kUIntPtrDtId : kIntPtrDtId); else - rc = _cmDpStoreValue(c,cmDataAllocInt(NULL,val),"int"); + { + cmData_t* np = unsignedFl ? cmDataAllocUInt(NULL,val) : cmDataAllocInt(NULL,val); + rc = _cmDpStoreValue(c,np,"int"); + } return rc; } @@ -2542,155 +2598,102 @@ cmDtRC_t _cmDataParserString( cmDataParserCtx_t* c ) cmDtRC_t _cmDataParserOpenRecd( cmDataParserCtx_t* c ) { + cmDtRC_t rc = kOkDtRC; + // records are values - so we must be expecting a value if( cmIsFlag(c->flags,kValueExpFl) == false ) return _cmDpSyntaxErr(c,"Unexpected '{'."); // store the current node - if( cmStackPush(c->p->stH, &c->cnp, 1 ) != kOkStRC ) - return _cmDpSyntaxErr(c,"Parser stack push failed."); + if((rc = _cmDpPushStack(c,c->cnp)) != kOkDtRC ) + return rc; // alloc a new record and make it the current node - if( (c->cnp = cmDataRecdAlloc(c->cnp)) == NULL ) + if( (c->cnp = cmDataRecdAlloc(NULL)) == NULL ) return _cmDpSyntaxErr(c,"'recd' allocate failed."); // new records must be followed by an id token. c->flags = kIdExpFl; - return kOkDtRC; + return rc; +} + +cmDtRC_t _cmDataParserCloseContainer( cmDataParserCtx_t* c, const cmChar_t* typeLabelStr ) +{ + cmDtRC_t rc; + + cmData_t* np = c->cnp; + + // make the parent node the new current node + if((rc = _cmDpPopStack(c,&c->cnp)) != kOkDtRC ) + return rc; + + return _cmDpStoreValue(c,np,typeLabelStr); } cmDtRC_t _cmDataParserCloseRecd( cmDataParserCtx_t* c ) { - cmDtRC_t rc; + assert( c->cnp->tid == kRecordDtId ); - // make the parent node the new curren node - if((rc = _cmDpPopStack(c,&c->cnp)) != kOkDtRC ) - return rc; - - switch( c->cnp->tid ) - { - case kPairDtId: - // if the parent node is a pair then close it - rc = _cmDataParserClosePair(c); - break; - - case kListDtId: - // parent node is a list - so expect another value - c->flags = kValueExpFl; - break; - - default: - return _cmDpSyntaxErr(c,"'records' may only be contained in other records or heterogenous arrays."); - - } - - c->flags |= kCommaExpFl; - - return rc; + return _cmDataParserCloseContainer(c,"record"); } cmDtRC_t _cmDataParserOpenList( cmDataParserCtx_t* c ) { + cmDtRC_t rc = kOkDtRC; + // lists are values - so we must be expecting a value if( cmIsFlag(c->flags,kValueExpFl) == false ) return _cmDpSyntaxErr(c,"Unexpected '('."); // store the current node - if( cmStackPush(c->p->stH, &c->cnp, 1 ) != kOkStRC ) - return _cmDpSyntaxErr(c,"Parser stack push failed."); + if((rc = _cmDpPushStack(c,c->cnp)) != kOkDtRC ) + return rc; // create a new list - if( (c->cnp = cmDataListAlloc(c->cnp)) == NULL ) + if( (c->cnp = cmDataListAlloc(NULL)) == NULL ) return _cmDpSyntaxErr(c,"'list' allocate failed."); // new lists must be followed by a value c->flags = kValueExpFl; - return kOkDtRC; + return rc; } cmDtRC_t _cmDataParserCloseList( cmDataParserCtx_t* c ) { - cmDtRC_t rc; - - // make the list's parent the current node - if((rc = _cmDpPopStack(c,&c->cnp)) != kOkDtRC ) - return rc; - - switch( c->cnp->tid ) - { - case kPairDtId: - // if the list's parent is a pair then close it - rc = _cmDataParserClosePair(c); - break; - - case kListDtId: - // the list's parent is another list so expect a value - c->flags = kValueExpFl; - break; - - default: - return _cmDpSyntaxErr(c,"'lists' may only be contained in other records or lists."); - - } - - c->flags |= kCommaExpFl; - - return rc; + assert( c->cnp->tid == kListDtId ); + return _cmDataParserCloseContainer(c,"list"); } cmDtRC_t _cmDataParserOpenArray( cmDataParserCtx_t* c ) { + cmDtRC_t rc = kOkDtRC; // arrays are values - so we must be expecting a value if( cmIsFlag(c->flags,kValueExpFl) == false ) return _cmDpSyntaxErr(c,"Unexpected '('."); // store the current node - if( cmStackPush(c->p->stH, &c->cnp, 1 ) != kOkStRC ) - return _cmDpSyntaxErr(c,"Parser stack push failed."); + if((rc = _cmDpPushStack(c,c->cnp)) != kOkDtRC ) + return rc; // create a new array - if( (c->cnp = cmDataSetVoidAllocPtr(c->cnp, NULL, 0 )) == NULL ) + if( (c->cnp = cmDataVoidAllocPtr(NULL, NULL, 0 )) == NULL ) return _cmDpSyntaxErr(c,"'array' allocate failed."); // new arrays must be followed by a value c->flags = kValueExpFl; - return kOkDtRC; + return rc; } cmDtRC_t _cmDataParserCloseArray( cmDataParserCtx_t* c ) { - cmDtRC_t rc; - - // make the arrays parent the current node - if((rc = _cmDpPopStack(c,&c->cnp)) != kOkDtRC ) - return rc; + assert( cmDataIsPtr(c->cnp) ); - switch( c->cnp->tid ) - { - - case kPairDtId: - // the arrays parent is a pair - so close it - rc = _cmDataParserClosePair(c); - break; - - case kListDtId: - // the arrays parent is a list - so expect a value - c->flags = kValueExpFl; - break; - - default: - return _cmDpSyntaxErr(c,"'arrays' may only be contained in other records or lists."); - - } - - c->flags |= kCommaExpFl; - - return rc; + return _cmDataParserCloseContainer(c,"array"); } cmDtRC_t _cmDataParserOnColon( cmDataParserCtx_t* c ) @@ -2726,17 +2729,17 @@ cmDtRC_t cmDataParserExec( cmDataParserH_t h, const cmChar_t* text, cmData_t** p cmDataParser_t* p = _cmDataParserHandleToPtr(h); unsigned tokenId; cmDataParserCtx_t ctx; - - ctx.cnp = NULL; // current node ptr + cmData_t* root = cmDataRecdAlloc(NULL); + ctx.cnp = root; ctx.p = p; - ctx.flags = kValueExpFl; + ctx.flags = kIdExpFl; if( cmLexSetTextBuffer(p->lexH,text,strlen(text)) != kOkLexRC ) return cmErrMsg(&p->err,kLexFailDtRC,"The data object lexer failed during reset."); cmStackClear(p->stH,false); - while((tokenId = cmLexGetNextToken(p->lexH)) != kEofLexTId ) + while(rc==kOkDtRC && (tokenId = cmLexGetNextToken(p->lexH)) != kEofLexTId ) { switch(tokenId) { @@ -2745,9 +2748,6 @@ cmDtRC_t cmDataParserExec( cmDataParserH_t h, const cmChar_t* text, cmData_t** p break; case kIntLexTId: // decimal integer - rc = _cmDataParserInt(&ctx); - break; - case kHexLexTId: // hexidecimal integer rc = _cmDataParserInt(&ctx); break; @@ -2759,7 +2759,7 @@ cmDtRC_t cmDataParserExec( cmDataParserH_t h, const cmChar_t* text, cmData_t** p case kLCurlyLexTId: // a new record is starting rc = _cmDataParserOpenRecd(&ctx); - break; + break; case kRCurlyLexTId: // the current record is finished rc = _cmDataParserCloseRecd(&ctx); @@ -2806,7 +2806,13 @@ cmDtRC_t cmDataParserExec( cmDataParserH_t h, const cmChar_t* text, cmData_t** p if( rc == kOkDtRC ) *pp = ctx.cnp; + else + { + if( ctx.cnp != root ) + cmDataUnlinkAndFree(ctx.cnp); + cmDataUnlinkAndFree(root); + } return rc; } @@ -2913,7 +2919,10 @@ cmDtRC_t cmDataParserTest( cmCtx_t* ctx ) const cmChar_t text[] = { - "{ f0:1.23 f1:\"hey\" " + //0 1 2 3 + //0123456789012345678901234567890123 + "f0:1.23 f1:\"hey\" f2:( a b c ) f3:[ 0f 1f 2f ]" + //"f0:1.23 f1:\"hey\"" }; cmErrSetup(&err,&ctx->rpt,"Data Parser Tester"); diff --git a/cmData.h b/cmData.h index 3456358..38b3e5f 100644 --- a/cmData.h +++ b/cmData.h @@ -544,6 +544,12 @@ extern "C" { cmDtRC_t cmDataParserCreate( cmCtx_t* ctx, cmDataParserH_t* hp ); cmDtRC_t cmDataParserDestroy( cmDataParserH_t* hp ); bool cmDataParserIsValid( cmDataParserH_t h ); + + // Parse a text representation into a 'record' type. + // Note that the text is wrapped with implied curly braces + // (e.g. "{ text }"). The contents of the text should therefore + // fit the record syntax (e.g. the first token should be a + // 'pair' label. cmDtRC_t cmDataParserExec( cmDataParserH_t h, const cmChar_t* text, cmData_t** pp ); //----------------------------------------------------------------------------- From b4d99528f9df898ef9b3776f9f5cea8d2bdaded3 Mon Sep 17 00:00:00 2001 From: kpl Date: Fri, 15 Nov 2013 16:44:49 -0800 Subject: [PATCH 12/23] cmLex.h/c : Added cmLexTokenIsUnsigned() and cmLexTokenIsSignlePrecision(). --- cmLex.c | 173 +++++++++++++++++++++++++++----------------------------- cmLex.h | 15 ++++- 2 files changed, 96 insertions(+), 92 deletions(-) diff --git a/cmLex.c b/cmLex.c index 7e9eb89..0ea0f35 100644 --- a/cmLex.c +++ b/cmLex.c @@ -7,6 +7,12 @@ #include "cmMallocDebug.h" #include "cmFile.h" +enum +{ + kRealFloatLexFl = 0x01, + kIntUnsignedLexFl = 0x02 +}; + typedef struct { unsigned code; @@ -29,6 +35,7 @@ cmLexErrorRecd cmLexErrorArray[] = { kMemAllocErrLexRC, "An attempted memory allocation failed"}, { kEofRC, "The end of the input text was encountered (this is a normal condition not an error)"}, { kInvalidLexTIdLexRC, "An invalid token id was encountered."}, + { kSignErrorLexRC, "A signed integer has a 'u' or 'U' suffix."}, { kInvalidLexRC, "Unknown lexer error code." } }; @@ -75,6 +82,7 @@ typedef struct cmLex_str cmChar_t* textBuf; // text buf used by cmLexSetFile() + unsigned attrFlags; // used to store the int and real suffix type flags } cmLex; @@ -148,7 +156,7 @@ unsigned _cmLexRealMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cm unsigned i = 0; unsigned n = 0; // decimal point counter unsigned d = 0; // digit counter - bool fl = false; // true if this real includes an exponent + bool fl = false; // expo flag for(; i0 && i 0; + fl = e > 0; } - return i>1 && (n==1 || fl) ? i : 0; + // if at least one digit was found + if( d>0 ) + { + // Note that this path allows a string w/o a decimal pt to trigger a match. + + if(iattrFlags = cmSetFlag(p->attrFlags,kRealFloatLexFl); + ++i; + break; + } + + } + + // match w/o suffix return + if( d>0 && (fl || n==1 || cmIsFlag(p->attrFlags,kRealFloatLexFl)) ) + return i; + } + + return 0; // no-match return } unsigned _cmLexIntMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cmChar_t* keyStr ) { unsigned i = 0; bool signFl = false; + for(; iattrFlags = cmSetFlag(p->attrFlags,kIntUnsignedLexFl); + ++i; + } + break; + + default: + break; + } + } + + return i; } unsigned _cmLexHexMatcher( cmLex* p, const cmChar_t* cp, unsigned cn, const cmChar_t* keyStr ) @@ -387,23 +449,6 @@ cmLexH cmLexInit( const cmChar_t* cp, unsigned cn, unsigned flags, cmRpt_t* rpt _cmLexSetTextBuffer( p, cp, cn ); - /* - p->cp = (cn==0) ? NULL : cp; - p->cn = (cp==NULL) ? 0 : cn; - - p->ci = 0; - - - p->curTokenId = kErrorLexTId; - p->curTokenCharIdx = cmInvalidIdx; - p->curTokenCharCnt = 0; - - p->curLine = 0; - p->curCol = 0; - p->nextLine = 0; - p->nextCol = 0; - */ - int init_mfn = 10; p->mfp = cmMemAllocZ( cmLexMatcher, init_mfn ); p->mfn = init_mfn; @@ -537,70 +582,6 @@ cmRC_t cmLexSetFile( cmLexH h, const cmChar_t* fn ) return rc; } -/* -cmRC_t cmLexSetFile( cmLexH h, const cmChar_t* fn ) -{ - cmRC_t rc = kOkLexRC; - FILE* fp = NULL; - cmLex* p = _cmLexHandleToPtr(h); - unsigned n = 0; - - assert( fn != NULL && p != NULL ); - - // open the file - if((fp = fopen(fn,"rb")) == NULL ) - return _cmLexError(p,kFileOpenErrLexRC,"Unable to open the file:'%s'.",fn); - - // seek to the end - if( fseek(fp,0,SEEK_END) != 0 ) - { - rc= _cmLexError(p,kFileSeekErrLexRC,"Unable to seek to the end of '%s'.",fn); - goto errLabel; - } - - // get the length of the file - if( (n=ftell(fp)) == 0 ) - { - rc = _cmLexError(p,kFileOpenErrLexRC,"The file '%s' appears to be empty.",fn); - goto errLabel; - } - - // rewind the file - if( fseek(fp,0,SEEK_SET) != 0 ) - { - rc = _cmLexError(p,kFileSeekErrLexRC,"Unable to seek to the beginning of '%s'.",fn); - goto errLabel; - } - - // allocate the text buffer - if((p->textBuf = cmMemResizeZ( char, p->textBuf, n+1)) == NULL ) - { - rc = _cmLexError(p,kMemAllocErrLexRC,"Unable to allocate the text file buffer for:'%s'.",fn); - goto errLabel; - } - - // read the file into the text buffer - if( fread(p->textBuf,n,1,fp) != 1 ) - { - rc = _cmLexError(p,kFileReadErrLexRC,"File read failed on:'%s'.",fn); - goto errLabel; - } - - if((rc = _cmLexSetTextBuffer( p, p->textBuf, n )) != kOkLexRC ) - goto errLabel; - - errLabel: - - // close the file - if( fclose(fp) != 0 ) - { - rc = _cmLexError(p,kFileCloseErrLexRC,"File close failed on:'%s'.",fn); - goto errLabel; - } - - return rc; -} -*/ cmLexMatcher* _cmLexFindUserToken( cmLex* p, unsigned id, const cmChar_t* tokenStr ) { @@ -689,9 +670,9 @@ unsigned cmLexGetNextToken( cmLexH h ) p->curTokenId = kErrorLexTId; p->curTokenCharIdx = cmInvalidIdx; p->curTokenCharCnt = 0; + p->attrFlags = 0; - - // try each mater + // try each matcher for(; mimfi; ++mi) if( p->mfp[mi].enableFl ) { @@ -701,6 +682,7 @@ unsigned cmLexGetNextToken( cmLexH h ) else charCnt = p->mfp[mi].userPtr( p->cp + p->ci, p->cn - p->ci); + // notice if the matcher set the error code if( cmErrLastRC(&p->err) != kOkLexRC ) return kErrorLexTId; @@ -823,6 +805,19 @@ float cmLexTokenFloat( cmLexH h ) double cmLexTokenDouble( cmLexH h ) { return strtod( cmLexTokenText(h),NULL ); } + +bool cmLexTokenIsUnsigned( cmLexH h ) +{ + cmLex* p = _cmLexHandleToPtr(h); + return p->curTokenId == kIntLexTId && cmIsFlag(p->attrFlags,kIntUnsignedLexFl); +} + +bool cmLexTokenIsSinglePrecision( cmLexH h ) +{ + cmLex* p = _cmLexHandleToPtr(h); + return p->curTokenId == kRealLexTId && cmIsFlag(p->attrFlags,kRealFloatLexFl); +} + unsigned cmLexCurrentLineNumber( cmLexH h ) { cmLex* p = _cmLexHandleToPtr(h); diff --git a/cmLex.h b/cmLex.h index fcd80aa..5eed6aa 100644 --- a/cmLex.h +++ b/cmLex.h @@ -50,7 +50,8 @@ enum kMemAllocErrLexRC, //< 10 An attempted memory allocation failed kEofRC, //< 11 The end of the input text was encountered (this is a normal condition not an error) kInvalidLexTIdLexRC, //< 12 An invalid lex token id was encountered. - kInvalidLexRC //< 13 Sentinal value. + kSignErrorLexRC, //< 13 An signed integer has a 'u' or 'U' suffix." + kInvalidLexRC //< 1r Sentinal value. }; @@ -119,15 +120,23 @@ unsigned cmLexTokenCharCount( cmLexH h ); // Return the value of the current token as an integer. int cmLexTokenInt( cmLexH h ); -// Return the value of the current token as an integer. +// Return the value of the current token as an unsigned integer. unsigned cmLexTokenUInt( cmLexH h ); -// Return the value of the current token as an integer. +// Return the value of the current token as a float. float cmLexTokenFloat( cmLexH h ); // Return the value of the current token as a double. double cmLexTokenDouble( cmLexH h ); +// Return true if the current token is an int and it was suffixed +// with 'u' to indicate that it is unsigned. +bool cmLexTokenIsUnsigned( cmLexH h ); + +// Return true if the current token is a real and it was suffexed +// with 'f' to indicate that it is a single precision float. +bool cmLexTokenIsSinglePrecision( cmLexH h ); + // Return the line number associated with the current token unsigned cmLexCurrentLineNumber( cmLexH h ); From fd524952923445d6c379560ced74f7470ae45a62 Mon Sep 17 00:00:00 2001 From: kpl Date: Mon, 18 Nov 2013 22:28:06 -0800 Subject: [PATCH 13/23] cmDspBuiltIn.c : Added cmRecdPlayClassCons to _cmDspClassBuiltInArray[]. --- dsp/cmDspBuiltIn.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dsp/cmDspBuiltIn.c b/dsp/cmDspBuiltIn.c index d6642f2..90e9540 100644 --- a/dsp/cmDspBuiltIn.c +++ b/dsp/cmDspBuiltIn.c @@ -5418,6 +5418,7 @@ cmDspClassConsFunc_t _cmDspClassBuiltInArray[] = cmActiveMeasClassCons, cmAmSyncClassCons, cmNanoMapClassCons, + cmRecdPlayClassCons, NULL, }; From 8f4981728c548a4c66945d680f6447a4861c3cda Mon Sep 17 00:00:00 2001 From: kpl Date: Mon, 18 Nov 2013 22:30:27 -0800 Subject: [PATCH 14/23] cmDspKr.h/c : Added the cmDspRecdPlay object. The cmScoreInitialize() call in cmDspScore now is passed a valid symbol table handle. --- dsp/cmDspKr.c | 249 +++++++++++++++++++++++++++++++++++++++++++++++++- dsp/cmDspKr.h | 1 + 2 files changed, 249 insertions(+), 1 deletion(-) diff --git a/dsp/cmDspKr.c b/dsp/cmDspKr.c index f260354..178016b 100644 --- a/dsp/cmDspKr.c +++ b/dsp/cmDspKr.c @@ -572,7 +572,7 @@ cmDspRC_t _cmDspScoreReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* } if((tlFn = cmDspStrcz(inst, kFnScId )) != NULL ) - if( cmScoreInitialize(ctx->cmCtx, &p->scH, tlFn, cmDspSampleRate(ctx), dynRefArray, dynRefCnt, _cmDspScoreCb, p, cmSymTblNullHandle ) != kOkTlRC ) + if( cmScoreInitialize(ctx->cmCtx, &p->scH, tlFn, cmDspSampleRate(ctx), dynRefArray, dynRefCnt, _cmDspScoreCb, p, ctx->stH ) != kOkTlRC ) rc = cmErrMsg(&inst->classPtr->err, kInstResetFailDspRC, "Score file open failed."); errLabel: @@ -2264,3 +2264,250 @@ struct cmDspClass_str* cmNanoMapClassCons( cmDspCtx_t* ctx ) return &_cmNanoMapDC; } + +//========================================================================================================================================== +enum +{ + kChCntPrId, + kFnPrId, + kSecsPrId, + kFadeRatePrId, + kScLocIdxPrId, + kCmdPrId, + kInAudioBasePrId +}; + +cmDspClass_t _cmRecdPlayDC; + +typedef struct +{ + cmDspInst_t inst; + cmRecdPlay* rcdply; + cmScH_t scH; + unsigned onSymId; + unsigned offSymId; + unsigned audioOutBaseId; + unsigned chCnt; + unsigned scLocIdx; +} cmDspRecdPlay_t; + +cmDspRC_t _cmDspRecdPlayOpenScore( cmDspCtx_t* ctx, cmDspInst_t* inst ) +{ + cmDspRC_t rc =kOkDspRC; + const cmChar_t* fn; + + cmDspRecdPlay_t* p = (cmDspRecdPlay_t*)inst; + + p->scLocIdx = 0; + + + if((fn = cmDspStrcz(inst,kFnPrId)) == NULL || strlen(fn)==0 ) + return cmErrMsg(&inst->classPtr->err, kInvalidArgDspRC, "No score file name supplied."); + + if( cmScoreInitialize(ctx->cmCtx, &p->scH, fn, cmDspSampleRate(ctx), NULL, 0, NULL, NULL, ctx->stH ) != kOkScRC ) + return cmErrMsg(&inst->classPtr->err, kSubSysFailDspRC, "Unable to open the score '%s'.",fn); + + if( cmScoreIsValid(p->scH) ) + { + unsigned i; + unsigned markerCnt = cmScoreMarkerLabelCount(p->scH); + + if((p->rcdply = cmRecdPlayAlloc(ctx->cmProcCtx, NULL, cmDspSampleRate(ctx), markerCnt, p->chCnt, cmDspDouble(inst,kSecsPrId))) == NULL) + return cmErrMsg(&inst->classPtr->err,kSubSysFailDspRC,"Unable to create the internal recorder-player object."); + + for(i=0; ircdply,i, cmScoreMarkerLabelSymbolId(p->scH,i )); + + } + + return rc; +} + + +cmDspInst_t* _cmDspRecdPlayAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl ) +{ + + if( va_cnt < 1 ) + { + cmDspClassErr(ctx,classPtr,kVarArgParseFailDspRC,"The 'RecdPlay' constructor must have a count of input ports."); + return NULL; + } + + va_list vl1; + va_copy(vl1,vl); + + int chCnt = va_arg(vl,int); + unsigned audioOutBase = kInAudioBasePrId + chCnt; + + cmDspRecdPlay_t* p = cmDspInstAllocV(cmDspRecdPlay_t,ctx,classPtr,instSymId,id,storeSymId,va_cnt,vl1, + 1, "chs", kChCntPrId, 0,0, kUIntDsvFl | kReqArgDsvFl, "channel count.", + 1, "fn", kFnPrId, 0,0, kInDsvFl | kStrzDsvFl | kReqArgDsvFl, "Score file." , + 1, "secs", kSecsPrId, 0,0, kInDsvFl | kDoubleDsvFl | kReqArgDsvFl, "Initial fragment allocation in seconds.", + 1, "frate", kFadeRatePrId, 0,0, kInDsvFl | kDoubleDsvFl, "Fade rate in dB per second.", + 1, "index", kScLocIdxPrId, 0,0, kInDsvFl | kUIntDsvFl, "Score follower location index.", + 1, "cmd", kCmdPrId, 0,0, kInDsvFl | kSymDsvFl, "on=reset off=stop.", + chCnt, "in", kInAudioBasePrId,0,1, kInDsvFl | kAudioBufDsvFl, "Audio input", + chCnt, "out", audioOutBase, 0,1, kOutDsvFl | kAudioBufDsvFl, "Audio output", + 0 ); + + va_end(vl1); + + p->onSymId = cmSymTblId(ctx->stH,"on"); + p->offSymId = cmSymTblId(ctx->stH,"off"); + p->audioOutBaseId = audioOutBase; + p->chCnt = chCnt; + p->scLocIdx = 0; + + cmDspSetDefaultDouble(ctx,&p->inst, kSecsPrId, 0, 10.0 ); + cmDspSetDefaultDouble(ctx,&p->inst, kFadeRatePrId, 0, 1.0); + + return &p->inst; +} + +cmDspRC_t _cmDspRecdPlayFree(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt ) +{ + cmDspRC_t rc = kOkDspRC; + cmDspRecdPlay_t* p = (cmDspRecdPlay_t*)inst; + + cmRecdPlayFree(&p->rcdply); + + cmScoreFinalize(&p->scH); + return rc; +} + +cmDspRC_t _cmDspRecdPlayReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt ) +{ + cmDspApplyAllDefaults(ctx,inst); + + return _cmDspRecdPlayOpenScore(ctx,inst); +} + +cmDspRC_t _cmDspRecdPlayExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt ) +{ + cmDspRC_t rc = kOkDspRC; + + cmDspRecdPlay_t* p = (cmDspRecdPlay_t*)inst; + + const cmSample_t* x[ p->chCnt ]; + cmSample_t* y[ p->chCnt ]; + unsigned n; + unsigned i; + unsigned actChCnt = 0; + + for(i=0; ichCnt; ++i) + { + if( i==0 ) + n = cmDspAudioBufSmpCount(ctx,inst,kInAudioBasePrId+i,0); + else + { assert( n == cmDspAudioBufSmpCount(ctx,inst,kInAudioBasePrId+i,0)); } + + x[i] = cmDspAudioBuf(ctx,inst,kInAudioBasePrId+i,0); + + if( x[i] != NULL ) + { + y[i] = cmDspAudioBuf(ctx,inst,p->audioOutBaseId+i,0); + + if( y[i] != NULL ) + { + assert( n == cmDspAudioBufSmpCount(ctx,inst,p->audioOutBaseId+i,0)); + + cmVOS_Zero(y[i],n); + + actChCnt += 1; + } + + } + } + + cmRecdPlayExec(p->rcdply,x,y,actChCnt,n); + + return rc; +} + +cmDspRC_t _cmDspRecdPlayRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt ) +{ + cmDspRecdPlay_t* p = (cmDspRecdPlay_t*)inst; + + cmDspSetEvent(ctx,inst,evt); + + switch( evt->dstVarId ) + { + case kCmdPrId: + if( cmDspSymbol(inst,kCmdPrId) == p->onSymId ) + { + printf("rewind\n"); + cmRecdPlayRewind(p->rcdply); + p->scLocIdx = 0; + } + else + if( cmDspSymbol(inst,kCmdPrId) == p->offSymId ) + { + } + + break; + + case kScLocIdxPrId: + { + unsigned endScLocIdx = cmDspUInt(inst,kScLocIdxPrId) ; + + for(; p->scLocIdx<=endScLocIdx; p->scLocIdx+=1) + { + cmScoreLoc_t* loc = cmScoreLoc(p->scH, p->scLocIdx ); + cmScoreMarker_t* mp = loc->markList; + + for(; mp!=NULL; mp=mp->link) + switch( mp->markTypeId ) + { + case kRecdBegScMId: + printf("recd-beg\n"); + cmRecdPlayBeginRecord(p->rcdply, mp->labelSymId ); + break; + + case kRecdEndScMId: + printf("recd-end\n"); + cmRecdPlayEndRecord(p->rcdply, mp->labelSymId ); + break; + + case kPlayBegScMId: + printf("play-beg\n"); + cmRecdPlayBeginPlay(p->rcdply, mp->labelSymId ); + break; + + case kPlayEndScMId: + printf("recd-end\n"); + cmRecdPlayEndPlay(p->rcdply, mp->labelSymId ); + break; + + case kFadeScMId: + printf("fade-beg\n"); + cmRecdPlayBeginFade(p->rcdply, mp->labelSymId, cmDspDouble(inst,kFadeRatePrId) ); + break; + + default: + break; + } + } + + p->scLocIdx = endScLocIdx+1; + } + break; + } + + return kOkDspRC; +} + +struct cmDspClass_str* cmRecdPlayClassCons( cmDspCtx_t* ctx ) +{ + cmDspClassSetup(&_cmRecdPlayDC,ctx,"RecdPlay", + NULL, + _cmDspRecdPlayAlloc, + _cmDspRecdPlayFree, + _cmDspRecdPlayReset, + _cmDspRecdPlayExec, + _cmDspRecdPlayRecv, + NULL, + NULL, + "Score controlled live recorder/player"); + + return &_cmRecdPlayDC; +} diff --git a/dsp/cmDspKr.h b/dsp/cmDspKr.h index 454f85f..cbb0f04 100644 --- a/dsp/cmDspKr.h +++ b/dsp/cmDspKr.h @@ -16,6 +16,7 @@ extern "C" { struct cmDspClass_str* cmActiveMeasClassCons( cmDspCtx_t* ctx ); struct cmDspClass_str* cmAmSyncClassCons( cmDspCtx_t* ctx ); struct cmDspClass_str* cmNanoMapClassCons( cmDspCtx_t* ctx ); + struct cmDspClass_str* cmRecdPlayClassCons( cmDspCtx_t* ctx ); #ifdef __cplusplus } From 70dffe559b6ad17d81b3ff2b4cf3534ed5f497e8 Mon Sep 17 00:00:00 2001 From: kpl Date: Mon, 18 Nov 2013 22:31:19 -0800 Subject: [PATCH 15/23] cmScore.h/c : Added the concept of 'markers' to support locating live recd/play fragments. --- app/cmScore.c | 383 ++++++++++++++++++++++++++++++++++++++++++++------ app/cmScore.h | 38 ++++- 2 files changed, 371 insertions(+), 50 deletions(-) diff --git a/app/cmScore.c b/app/cmScore.c index a90a1cc..355fa41 100644 --- a/app/cmScore.c +++ b/app/cmScore.c @@ -6,6 +6,7 @@ #include "cmCtx.h" #include "cmMem.h" #include "cmMallocDebug.h" +#include "cmLinkedHeap.h" #include "cmMidi.h" #include "cmLex.h" #include "cmCsv.h" @@ -13,6 +14,7 @@ #include "cmMidiFile.h" #include "cmAudioFile.h" #include "cmTimeLine.h" +#include "cmText.h" #include "cmScore.h" #include "cmVectOpsTemplateMain.h" @@ -41,7 +43,8 @@ enum kFracColScIdx = 18, kDynColScIdx = 19, kSectionColScIdx = 20, - kRemarkColScIdx = 21 + kRecdPlayColScIdx = 21, + kRemarkColScIdx = 22 }; @@ -75,6 +78,15 @@ typedef struct cmScSet_str struct cmScSet_str* link; // } cmScSet_t; +typedef struct cmScMark_str +{ + cmMarkScMId_t cmdId; + unsigned labelSymId; + unsigned scoreIdx; + unsigned csvRowIdx; + struct cmScMark_str* link; +} cmScMark_t; + typedef struct { cmErr_t err; @@ -94,11 +106,15 @@ typedef struct cmScoreSection_t* sect; unsigned sectCnt; + unsigned* markLabelArray; // one symId per unique cmScoreMarker_t.labelSymId; + unsigned markLabelCnt; + unsigned sciPitchLexTId; // sci pitch and section id lexer token id's unsigned sectionLexTId; cmScSect_t* sectList; // lists used during parsing cmScSet_t* setList; + cmScMark_t* markList; cmScoreSet_t* sets; unsigned setCnt; @@ -313,6 +329,17 @@ unsigned _cmScLexSectionIdMatcher( const cmChar_t* cp, unsigned cn ) return 0; } +void _cmScFreeMarkList( cmScMark_t* markList ) +{ + cmScMark_t* mp = markList; + while( mp!=NULL ) + { + cmScMark_t* np = mp->link; + cmMemFree(mp); + mp = np; + } +} + void _cmScFreeSetList( cmScSet_t* setList ) { cmScSet_t* tp = setList; @@ -366,6 +393,8 @@ cmScRC_t _cmScFinalize( cmSc_t* p ) _cmScFreeSetList(p->setList); + _cmScFreeMarkList(p->markList); + if( p->loc != NULL ) { for(i=0; ilocCnt; ++i) @@ -373,12 +402,23 @@ cmScRC_t _cmScFinalize( cmSc_t* p ) cmMemFree(p->loc[i].evtArray); if( p->loc[i].begSectPtr != NULL ) cmMemFree(p->loc[i].begSectPtr->setArray); + + // free the marker list assoc'd with this location + cmScoreMarker_t* smp = p->loc[i].markList; + while( smp!=NULL ) + { + cmScoreMarker_t* np = smp->link; + cmMemFree(smp); + smp = np; + } + } cmMemFree(p->loc); } + cmMemPtrFree(&p->dynRefArray); - + cmMemFree(p->markLabelArray); cmMemFree(p->sect); cmMemFree(p->fn); cmMemFree(p->array); @@ -557,6 +597,79 @@ cmScRC_t _cmScParseAttr(cmSc_t* p, unsigned scoreIdx, const cmChar_t* text, unsi return kOkScRC; } +// Parse a record/playback string +cmScRC_t _cmScParseMarkers( cmSc_t* p, unsigned scoreIdx, const cmChar_t* text, unsigned rowIdx ) +{ + const cmChar_t* cp = text; + const cmChar_t* ip; + const cmChar_t* ep; + + // if no symbol table has been registered then don't bother storing markers. + // (NOTE - THIS IS A HACK BECAUSE THE SCORE OBJECT USED IN THE cmdIf DOES NOT HAVE + // A SYMBOL TABLE - WE COULD EASILY ADD ONE IF IT EVENTUALLY NEEDS ACCESS TO THE MARKERS + // - OR A SYMBOL TABLE COULD BE ADDED TO THE SCORE ITSELF.) + if( cmSymTblIsValid(p->stH) == false ) + return kOkScRC; + + // go to command/id space + if((ip = cmTextNextWhiteOrEosC(text)) == NULL ) + goto errLabel; + + // goto label + if((ip = cmTextNextNonWhiteC(ip)) == NULL ) + goto errLabel; + + // goto end of label + if((ep = cmTextNextWhiteOrEosC(ip)) == NULL ) + goto errLabel; + else + { + unsigned n = (ep-ip)+1; + cmChar_t markTextStr[n+1]; + strncpy(markTextStr,ip,n); + + // for each command code + // (there may be more than one character) + for(; *cp && !isspace(*cp); ++cp) + { + cmMarkScMId_t cmdId = kInvalidScMId; + + switch( *cp ) + { + case 'c': cmdId = kRecdBegScMId; break; + case 'e': cmdId = kRecdEndScMId; break; + case 'p': cmdId = kPlayBegScMId; break; + case 'd': cmdId = kPlayEndScMId; break; + case 'f': cmdId = kFadeScMId; break; + default: + return cmErrMsg(&p->err,kSyntaxErrScRC,"Unrecognized marker command character '%c' at row index %i.",*cp,rowIdx); + } + + cmScMark_t* mp = cmMemAllocZ(cmScMark_t,1); + mp->cmdId = cmdId; + mp->labelSymId = cmSymTblRegisterSymbol(p->stH,markTextStr); + mp->scoreIdx = scoreIdx; + mp->csvRowIdx = rowIdx; + + // insert the new mark at the end of the list + if( p->markList == NULL ) + p->markList = mp; + else + { + cmScMark_t* ep = p->markList; + while( ep->link != NULL ) + ep = ep->link; + + ep->link = mp; + } + } + } + return kOkScRC; + + errLabel: + return cmErrMsg(&p->err,kSyntaxErrScRC,"Invalid record/playback field ('%s') on row index:%i.",cmStringNullGuard(text),rowIdx); +} + void _cmScPrintSets( const cmChar_t* label, cmScSet_t* setList ) { printf("%s\n",label); @@ -598,7 +711,7 @@ cmScRC_t _cmScParseNoteOn( cmSc_t* p, unsigned rowIdx, cmScoreEvt_t* s, unsigned return cmErrMsg(&p->err,kSyntaxErrScRC,"Expected a scientific pitch value"); if((midiPitch = cmSciPitchToMidi(sciPitch)) == kInvalidMidiPitch) - return cmErrMsg(&p->err,kSyntaxErrScRC,"Unable to convert the scientific pitch '%s' to a MIDI value. "); + return cmErrMsg(&p->err,kSyntaxErrScRC,"Unable to convert the scientific pitch '%s' to a MIDI value. "); // it is possible that note delta-secs field is empty - so default to 0 if((secs = cmCsvCellDouble(p->cH, rowIdx, kSecsColScIdx )) == DBL_MAX) // Returns DBL_MAX on error. @@ -658,6 +771,14 @@ cmScRC_t _cmScParseNoteOn( cmSc_t* p, unsigned rowIdx, cmScoreEvt_t* s, unsigned durSecs = 0.25; + // parse the recd/play markers + if((attr = cmCsvCellText(p->cH,rowIdx,kRecdPlayColScIdx)) != NULL ) + { + if((rc = _cmScParseMarkers(p,scoreIdx,attr,rowIdx)) != kOkScRC ) + return rc; + } + + s->type = kNonEvtScId; s->secs = secs; s->pitch = midiPitch; @@ -870,6 +991,8 @@ cmScRC_t _cmScProcSets( cmSc_t* p ) } + + cmScRC_t _cmScProcSections( cmSc_t* p, cmScSect_t* sectList ) { cmScRC_t rc = kOkScRC; @@ -935,6 +1058,153 @@ cmScRC_t _cmScProcSections( cmSc_t* p, cmScSect_t* sectList ) return rc; } +const cmScoreLoc_t* _cmScFindMarkLoc( cmSc_t* p, cmMarkScMId_t cmdId, unsigned labelSymId, const cmScoreMarker_t** markRef ) +{ + unsigned i; + for(i=0; ilocCnt; ++i) + { + cmScoreMarker_t* smp = p->loc[i].markList; + for(; smp!=NULL; smp=smp->link) + { + if( smp->markTypeId==cmdId && smp->labelSymId==labelSymId ) + return p->loc + i; + + if( markRef != NULL ) + *markRef = smp; + } + } + return NULL; +} + +unsigned _cmScMarkerLabelIndex( cmSc_t* p, unsigned labelSymId ) +{ + unsigned i; + for(i=0; imarkLabelCnt; ++i) + if( p->markLabelArray[i] == labelSymId ) + return i; + + return cmInvalidIdx; +} + + +// Verify that the record/play begin/end and fade markers fall in the correct time order. +// (e.g. 'begin' must be before 'end' and 'fade' must be between and 'begin' and 'end'). +cmScRC_t _cmScValidateMarkers( cmSc_t* p ) +{ + cmScRC_t rc = kOkScRC; + unsigned i; + + for(i=0; ilocCnt; ++i) + { + cmScoreMarker_t* sm0p = p->loc[i].markList; + for(; sm0p!=NULL; sm0p=sm0p->link) + { + const cmScoreLoc_t* sl0p; + const cmScoreLoc_t* sl1p; + + switch( sm0p->markTypeId ) + { + case kRecdBegScMId: + if((sl0p = _cmScFindMarkLoc(p,kRecdEndScMId, sm0p->labelSymId, NULL )) == NULL ) + rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'record begin' marker at CSV row index %i does not have an associated 'record end' marker.",sm0p->csvRowIdx); + else + if( sl0p->index <= p->loc[i].index ) + rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'record end' marker comes before associated with the 'record begin' marker at CSV row index %i.",sm0p->csvRowIdx); + break; + + case kRecdEndScMId: + if((sl0p = _cmScFindMarkLoc(p,kRecdBegScMId, sm0p->labelSymId, NULL )) == NULL ) + rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'record end' marker at CSV row index %i does not have an associated 'record begin' marker.",sm0p->csvRowIdx); + else + if( sl0p->index > p->loc[i].index ) + rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'record begin' marker comes after the associated with the 'record end' marker at CSV row index %i.",sm0p->csvRowIdx); + break; + + case kFadeScMId: + if((sl0p = _cmScFindMarkLoc(p,kRecdBegScMId, sm0p->labelSymId, NULL )) == NULL ) + rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'fade' marker at CSV row index %i does not have an associated 'record begin' marker.",sm0p->csvRowIdx); + else + if((sl1p = _cmScFindMarkLoc(p,kRecdEndScMId, sm0p->labelSymId, NULL )) == NULL ) + rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'fade' marker at CSV row index %i does not have an associated 'record end' marker.",sm0p->csvRowIdx); + else + if( sl0p->index > p->loc[i].index || sl1p->index < p->loc[i].index ) + rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'fade' marker at CSV row index %i is not between it's associated 'record begin' and 'record end' markers.",sm0p->csvRowIdx); + break; + + case kPlayBegScMId: + if((sl0p = _cmScFindMarkLoc(p,kPlayEndScMId, sm0p->labelSymId, NULL )) == NULL ) + rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'play begin' marker at CSV row index %i does not have an associated 'play end' marker.",sm0p->csvRowIdx); + else + if( sl0p->index <= p->loc[i].index ) + rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'play end' marker comes before associated with the 'play begin' marker at CSV row index %i.",sm0p->csvRowIdx); + break; + + case kPlayEndScMId: + if((sl0p = _cmScFindMarkLoc(p,kPlayBegScMId, sm0p->labelSymId, NULL )) == NULL ) + rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'play end' marker at CSV row index %i does not have an associated 'play begin' marker.",sm0p->csvRowIdx); + else + if( sl0p->index > p->loc[i].index ) + rc = cmErrMsg(&p->err,kSyntaxErrScRC,"The 'play begin' marker comes after the associated with the 'play end' marker at CSV row index %i.",sm0p->csvRowIdx); + break; + + default: + break; + + } + } + } + + return rc; +} + + + +cmScRC_t _cmScProcMarkers( cmSc_t* p ) +{ + // for each marker in the p->markList + // (p->markList is created by _cmScParseMarkers() during CSV file parsing.) + cmScMark_t* mp = p->markList; + for(; mp!=NULL; mp=mp->link) + { + assert( mp->scoreIdx < p->cnt ); + + // get the score location assoc'd with this marker + unsigned locIdx = p->array[ mp->scoreIdx ].locIdx; + assert( locIdx < p->locCnt ); + + cmScoreLoc_t* slp = p->loc + locIdx; + + // create a cmScoreMarker record. + cmScoreMarker_t* smp = cmMemAllocZ(cmScoreMarker_t,1); + smp->markTypeId = mp->cmdId; + smp->labelSymId = mp->labelSymId; + smp->csvRowIdx = mp->csvRowIdx; + smp->scoreLocPtr = slp; + + // attach the new scoreMarker record to the assoc'd score loc. recd + if( slp->markList == NULL ) + slp->markList = smp; + else + { + cmScoreMarker_t* sm0p = slp->markList; + while( sm0p->link != NULL ) + sm0p = sm0p->link; + sm0p->link = smp; + } + + // if the id represented by this marker + if( _cmScMarkerLabelIndex(p,smp->labelSymId) == cmInvalidIdx ) + { + p->markLabelArray = cmMemResizeP(unsigned,p->markLabelArray,p->markLabelCnt+1); + p->markLabelArray[p->markLabelCnt] = smp->labelSymId; + p->markLabelCnt += 1; + } + } + + // validate the markers + return _cmScValidateMarkers(p); +} + cmScRC_t _cmScParseFile( cmSc_t* p, cmCtx_t* ctx, const cmChar_t* fn ) { cmScRC_t rc = kOkScRC; @@ -1164,6 +1434,9 @@ cmScRC_t cmScoreInitialize( cmCtx_t* ctx, cmScH_t* hp, const cmChar_t* fn, doubl if((rc = _cmScProcSections(p,p->sectList)) != kOkScRC ) goto errLabel; + if((rc = _cmScProcMarkers(p)) != kOkScRC ) + goto errLabel; + // load the dynamic reference array if( dynRefArray != NULL && dynRefCnt > 0) { @@ -1409,6 +1682,30 @@ unsigned cmScoreSetCount( cmScH_t h ) return p->setCnt; } +unsigned cmScoreMarkerLabelCount( cmScH_t h ) +{ + cmSc_t* p = _cmScHandleToPtr(h); + return p->markLabelCnt; +} + +unsigned cmScoreMarkerLabelSymbolId( cmScH_t h, unsigned idx ) +{ + cmSc_t* p = _cmScHandleToPtr(h); + assert( idx < p->markLabelCnt ); + return p->markLabelArray[idx]; +} + +const cmScoreMarker_t* cmScoreMarker( cmScH_t h, cmMarkScMId_t markMId, unsigned labelSymId ) +{ + cmSc_t* p = _cmScHandleToPtr(h); + const cmScoreMarker_t* smp = NULL; + if( _cmScFindMarkLoc(p, markMId, labelSymId, &smp ) == NULL ) + return NULL; + + return smp; +} + + cmScRC_t cmScoreSeqNotify( cmScH_t h ) { cmScRC_t rc = kOkScRC; @@ -1502,7 +1799,7 @@ void _cmScPerfSortTimes( unsigned *v, unsigned n ) fl = true; } } - --n; + --n; } } @@ -1568,13 +1865,13 @@ bool _cmScPerfEven(cmSc_t* p, cmScoreSet_t* stp, bool printMissFl) if(printFl) { /* - for(i=0; ieleCnt; ++i) - { + for(i=0; ieleCnt; ++i) + { printf("%i %i ",i,v[i]); if( i > 0 ) - printf("%i ", d[i-1]); + printf("%i ", d[i-1]); printf("\n"); - } + } */ printf("%s EVENESS:%f\n",sortFl?"SORTED ":"",stp->value); } @@ -2110,42 +2407,42 @@ cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const c goto errLabel; } - switch( tmp->status ) - { - case kNoteOnMdId: - if( cmCsvInsertTextColAfter(csvH, cp, &cp, cmMidiToSciPitch(tmp->u.chMsgPtr->d0,NULL,0), lexTId ) != kOkCsvRC ) - { - cmErrMsg(&err,kCsvFailScRC,"Error inserting 'opcode' column in '%s'.",cmStringNullGuard(scoreFn)); - goto errLabel; - } + switch( tmp->status ) + { + case kNoteOnMdId: + if( cmCsvInsertTextColAfter(csvH, cp, &cp, cmMidiToSciPitch(tmp->u.chMsgPtr->d0,NULL,0), lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting 'opcode' column in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } - case kMetaStId: - switch( tmp->metaId ) - { - case kTimeSigMdId: - if( cmCsvInsertUIntColAfter(csvH, cp, &cp, tmp->u.timeSigPtr->num, lexTId ) != kOkCsvRC ) - { - cmErrMsg(&err,kCsvFailScRC,"Error inserting time sign. numerator column in '%s'.",cmStringNullGuard(scoreFn)); - goto errLabel; - } + case kMetaStId: + switch( tmp->metaId ) + { + case kTimeSigMdId: + if( cmCsvInsertUIntColAfter(csvH, cp, &cp, tmp->u.timeSigPtr->num, lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting time sign. numerator column in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } - if( cmCsvInsertUIntColAfter(csvH, cp, &cp, tmp->u.timeSigPtr->den, lexTId ) != kOkCsvRC ) - { - cmErrMsg(&err,kCsvFailScRC,"Error inserting time sign. denominator column in '%s'.",cmStringNullGuard(scoreFn)); - goto errLabel; - } - break; + if( cmCsvInsertUIntColAfter(csvH, cp, &cp, tmp->u.timeSigPtr->den, lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting time sign. denominator column in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + break; - case kTempoMdId: - if( cmCsvInsertUIntColAfter(csvH, cp, &cp, 60000000/tmp->u.iVal, lexTId ) != kOkCsvRC ) - { - cmErrMsg(&err,kCsvFailScRC,"Error inserting 'tempo' in '%s'.",cmStringNullGuard(scoreFn)); - goto errLabel; - } - break; - } + case kTempoMdId: + if( cmCsvInsertUIntColAfter(csvH, cp, &cp, 60000000/tmp->u.iVal, lexTId ) != kOkCsvRC ) + { + cmErrMsg(&err,kCsvFailScRC,"Error inserting 'tempo' in '%s'.",cmStringNullGuard(scoreFn)); + goto errLabel; + } + break; + } - } + } } @@ -2157,10 +2454,10 @@ cmScRC_t cmScoreFileFromMidi( cmCtx_t* ctx, const cmChar_t* midiFn, const c } errLabel: - cmMidiFileClose(&mfH); - cmCsvFinalize(&csvH); + cmMidiFileClose(&mfH); + cmCsvFinalize(&csvH); - return rc; + return rc; } void cmScoreTest( cmCtx_t* ctx, const cmChar_t* fn ) diff --git a/app/cmScore.h b/app/cmScore.h index 2f36a8f..cccc7a4 100644 --- a/app/cmScore.h +++ b/app/cmScore.h @@ -36,12 +36,12 @@ extern "C" { // Flags used by cmScoreEvt_t.flags enum { - kEvenScFl = 0x01, // This note is marked for evenness measurement - kDynScFl = 0x02, // This note is marked for dynamics measurement - kTempoScFl = 0x04, // This note is marked for tempo measurement - kSkipScFl = 0x08, // This isn't a real event (e.g. tied note) skip over it - kGraceScFl = 0x10, // This is a grace note - kInvalidScFl = 0x20 // This note has a calculated time + kEvenScFl = 0x001, // This note is marked for evenness measurement + kDynScFl = 0x002, // This note is marked for dynamics measurement + kTempoScFl = 0x004, // This note is marked for tempo measurement + kSkipScFl = 0x008, // This isn't a real event (e.g. tied note) skip over it + kGraceScFl = 0x010, // This is a grace note + kInvalidScFl = 0x020 // This note has a calculated time }; @@ -103,7 +103,26 @@ extern "C" { double value; struct cmScoreSet_str* llink; // cmScoreLoc_t setList link } cmScoreSet_t; - + + typedef enum + { + kInvalidScMId, + kRecdBegScMId, + kRecdEndScMId, + kFadeScMId, + kPlayBegScMId, + kPlayEndScMId + } cmMarkScMId_t; + + // score markers + typedef struct cmScoreMarker_str + { + cmMarkScMId_t markTypeId; // marker type + unsigned labelSymId; // marker label + struct cmScoreLoc_str* scoreLocPtr; // score location of the marker + unsigned csvRowIdx; // score CSV file line assoc'd w/ this marker + struct cmScoreMarker_str* link; // cmScoreLoc_t.markList links + } cmScoreMarker_t; // All events which are simultaneous are collected into a single // cmScoreLoc_t record. @@ -116,6 +135,7 @@ extern "C" { unsigned barNumb; // Bar number this event is contained by. cmScoreSet_t* setList; // Set's which end on this time location (linked through cmScoreSet_t.llink) cmScoreSection_t* begSectPtr; // NULL if this location does not start a section + cmScoreMarker_t* markList; // List of markers assigned to this location } cmScoreLoc_t; typedef void (*cmScCb_t)( void* arg, const void* data, unsigned byteCnt ); @@ -170,6 +190,10 @@ extern "C" { // Return the count of sets. unsigned cmScoreSetCount( cmScH_t h ); + unsigned cmScoreMarkerLabelCount( cmScH_t h ); + unsigned cmScoreMarkerLabelSymbolId( cmScH_t h, unsigned idx ); + const cmScoreMarker_t* cmScoreMarker( cmScH_t h, cmMarkScMId_t markMId, unsigned labelSymId ); + // Make callbacks for all events in the score. The callbacks // contain cmScMsg_t records serialized as a byte stream. // Use cmScoreDecode() to convert the byte string to a From d64f92ac0319c078b17b5839300a0d749421cd28 Mon Sep 17 00:00:00 2001 From: kpl Date: Mon, 18 Nov 2013 22:31:58 -0800 Subject: [PATCH 16/23] Added the cmRecdPlay proc object. --- cmProc4.c | 247 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ cmProc4.h | 45 ++++++++++ 2 files changed, 292 insertions(+) diff --git a/cmProc4.c b/cmProc4.c index 7e63acc..b312df6 100644 --- a/cmProc4.c +++ b/cmProc4.c @@ -4132,3 +4132,250 @@ cmRC_t cmScModulatorDump( cmScModulator* p ) return rc; } + +//======================================================================================================================= +cmRecdPlay* cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs ) +{ + cmRecdPlay* op = cmObjAlloc(cmRecdPlay,c,p); + + if( cmRecdPlayInit(op,srate,fragCnt,chCnt,initFragSecs) != cmOkRC ) + cmRecdPlayFree(&op); + + return op; +} + +cmRC_t cmRecdPlayFree( cmRecdPlay** pp ) +{ + cmRC_t rc = cmOkRC; + if( pp==NULL || *pp==NULL ) + return rc; + + cmRecdPlay* p = *pp; + if((rc = cmRecdPlayFinal(p)) != cmOkRC ) + return rc; + + cmObjFree(pp); + return rc; + +} + +cmRC_t cmRecdPlayInit( cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs ) +{ + + cmRC_t rc; + + if((rc = cmRecdPlayFinal(p)) != cmOkRC ) + return rc; + + p->frags = cmMemAllocZ(cmRecdPlayFrag,fragCnt); + p->fragCnt = fragCnt; + p->srate = srate; + p->chCnt = chCnt; + p->initFragSecs = initFragSecs; + + return rc; +} + +cmRC_t cmRecdPlayFinal( cmRecdPlay* p ) +{ + unsigned i,j; + for(i=0; ifragCnt; ++i) + { + for(j=0; jchCnt; ++j) + cmMemFree(p->frags[i].chArray[j]); + + cmMemFree(p->frags[i].chArray); + } + cmMemFree(p->frags); + p->fragCnt=0; + p->chCnt=0; + return cmOkRC; +} + +cmRC_t cmRecdPlayRegisterFrag( cmRecdPlay* p, unsigned fragIdx, unsigned labelSymId ) +{ + assert( fragIdx < p->fragCnt ); + + unsigned i; + + p->frags[ fragIdx ].labelSymId = labelSymId; + + p->frags[ fragIdx ].chArray = cmMemResizeZ(cmSample_t*,p->frags[fragIdx].chArray,p->chCnt); + + for(i=0; ichCnt; ++i) + { + + p->frags[ fragIdx ].allocCnt = floor(p->initFragSecs * p->srate); + p->frags[ fragIdx ].chArray[i] = cmMemResizeZ(cmSample_t,p->frags[ fragIdx ].chArray[i],p->frags[fragIdx].allocCnt); + } + + return cmOkRC; +} + +cmRC_t cmRecdPlayRewind( cmRecdPlay* p ) +{ + unsigned i; + + while( p->plist != NULL ) + cmRecdPlayEndPlay(p,p->plist->labelSymId); + + while( p->rlist != NULL ) + cmRecdPlayEndRecord(p,p->plist->labelSymId); + + for(i=0; ifragCnt; ++i) + p->frags[i].playIdx = 0; + + return cmOkRC; +} + +cmRC_t cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId ) +{ + unsigned i; + + for(i=0; ifragCnt; ++i) + if( p->frags[i].labelSymId == labelSymId ) + { + // if the frag is not already on the recd list + if( p->frags[i].rlink == NULL ) + { + p->frags[i].recdIdx = 0; + p->frags[i].playIdx = 0; + p->frags[i].rlink = p->rlist; + p->rlist = p->frags + i; + } + + return cmOkRC; + } + + return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The fragment label symbol id '%i' not found for 'begin record'.",labelSymId); +} + +cmRC_t cmRecdPlayEndRecord( cmRecdPlay* p, unsigned labelSymId ) +{ + cmRecdPlayFrag* fp = p->rlist; + cmRecdPlayFrag* pp = NULL; + + for(; fp != NULL; fp=fp->rlink ) + { + if( fp->labelSymId == labelSymId ) + { + if( pp == NULL ) + p->rlist = fp->rlink; + else + pp->rlink = fp->rlink; + + fp->rlink = NULL; + + return cmOkRC; + } + + pp = fp; + } + + return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The fragment label symbol id '%i' not found for 'end record'.",labelSymId); +} + +cmRC_t cmRecdPlayBeginPlay( cmRecdPlay* p, unsigned labelSymId ) +{ + unsigned i; + + for(i=0; ifragCnt; ++i) + if( p->frags[i].labelSymId == labelSymId ) + { + // if the frag is not already on the play list + if( p->frags[i].plink == NULL ) + { + p->frags[i].playIdx = 0; + p->frags[i].fadeSmpIdx = 0; + p->frags[i].fadeDbPerSec = 0.0; + p->frags[i].plink = p->plist; + p->plist = p->frags + i; + } + + return cmOkRC; + } + + return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The fragment label symbol id '%i' not found for 'begin play'.",labelSymId); + +} + +cmRC_t cmRecdPlayEndPlay( cmRecdPlay* p, unsigned labelSymId ) +{ + cmRecdPlayFrag* fp = p->plist; + cmRecdPlayFrag* pp = NULL; + + for(; fp != NULL; fp=fp->plink ) + { + if( fp->labelSymId == labelSymId ) + { + if( pp == NULL ) + p->plist = fp->plink; + else + pp->plink = fp->plink; + + fp->plink = NULL; + + return cmOkRC; + } + + pp = fp; + } + + return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The fragment label symbol id '%i' not found for 'end play'.",labelSymId); +} + +cmRC_t cmRecdPlayBeginFade( cmRecdPlay* p, unsigned labelSymId, double fadeDbPerSec ) +{ + cmRecdPlayFrag* fp = p->plist; + + for(; fp != NULL; fp=fp->plink ) + if( fp->labelSymId == labelSymId ) + { + fp->fadeDbPerSec = -fabs(fadeDbPerSec); + return cmOkRC; + } + + return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The fragment label symbol id '%i' not found for 'fade begin'.",labelSymId); +} + + +cmRC_t cmRecdPlayExec( cmRecdPlay* p, const cmSample_t** iChs, cmSample_t** oChs, unsigned chCnt, unsigned smpCnt ) +{ + chCnt = cmMin(chCnt, p->chCnt); + + cmRecdPlayFrag* fp = p->rlist; + + for(; fp!=NULL; fp=fp->rlink) + { + assert( fp->recdIdx <= fp->allocCnt); + unsigned n = cmMin(fp->allocCnt - fp->recdIdx,smpCnt); + unsigned i; + for(i=0; ichCnt; ++i) + { + cmVOS_Copy(fp->chArray[i] + fp->recdIdx, n, iChs[i] ); + fp->recdIdx += n; + } + } + + fp = p->plist; + for(; fp!=NULL; fp=fp->rlink) + { + assert( fp->playIdx <= fp->recdIdx); + + double gain = pow(10.0,((fp->fadeSmpIdx / p->srate) * fp->fadeDbPerSec)/20.0); + unsigned n = cmMin(fp->recdIdx - fp->playIdx,smpCnt); + unsigned i; + + for(i=0; ichCnt; ++i) + { + cmVOS_MultVVS(oChs[i],n,fp->chArray[i] + fp->playIdx,gain); + fp->playIdx += n; + } + + // if a fade rate has been set then advance the fade phase + if(fp->fadeDbPerSec!=0.0) + fp->fadeSmpIdx += smpCnt; + } + + return cmOkRC; +} diff --git a/cmProc4.h b/cmProc4.h index 0dde90a..36b88d2 100644 --- a/cmProc4.h +++ b/cmProc4.h @@ -626,6 +626,51 @@ extern "C" { cmRC_t cmScModulatorExec( cmScModulator* p, unsigned scLocIdx ); cmRC_t cmScModulatorDump( cmScModulator* p ); + //======================================================================================================================= + + typedef struct cmRecdPlayFrag_str + { + unsigned labelSymId; // this fragments label + cmSample_t** chArray; // record buffer chArray[cmRecdPlay.chCnt][allocCnt] + unsigned allocCnt; // count of samples allocated to each channel + unsigned playIdx; // index of next sample to play + unsigned recdIdx; // index of next sample to receieve audio (count of full samples) + double fadeDbPerSec; // fade rate in dB per second + unsigned fadeSmpIdx; + struct cmRecdPlayFrag_str* rlink; // cmRecdPlay.rlist link + struct cmRecdPlayFrag_str* plink; // cmRecdPlay.plist link + } cmRecdPlayFrag; + + typedef struct + { + cmObj obj; + cmRecdPlayFrag* frags; // frags[fragCnt] fragment array + unsigned fragCnt; // count of fragments + double srate; // system sample rate + unsigned chCnt; // count of input and output audio channels + double initFragSecs; // size initial memory allocated to each frag in seconds + cmRecdPlayFrag* plist; // currently playing frags + cmRecdPlayFrag* rlist; // currently recording frags + } cmRecdPlay; + + + cmRecdPlay* cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs ); + cmRC_t cmRecdPlayFree( cmRecdPlay** pp ); + cmRC_t cmRecdPlayInit( cmRecdPlay* p, double srate, unsigned flagCnt, unsigned chCnt, double initFragSecs ); + cmRC_t cmRecdPlayFinal( cmRecdPlay* p ); + + cmRC_t cmRecdPlayRegisterFrag( cmRecdPlay* p, unsigned fragIdx, unsigned labelSymId ); + + cmRC_t cmRecdPlayRewind( cmRecdPlay* p ); + cmRC_t cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId ); + cmRC_t cmRecdPlayEndRecord( cmRecdPlay* p, unsigned labelSymId ); + cmRC_t cmRecdPlayBeginPlay( cmRecdPlay* p, unsigned labelSymId ); + cmRC_t cmRecdPlayEndPlay( cmRecdPlay* p, unsigned labelSymId ); + + cmRC_t cmRecdPlayBeginFade( cmRecdPlay* p, unsigned labelSymId, double fadeDbPerSec ); + + cmRC_t cmRecdPlayExec( cmRecdPlay* p, const cmSample_t** iChs, cmSample_t** oChs, unsigned chCnt, unsigned smpCnt ); + #ifdef __cplusplus } #endif From 691d0ef278ed6eb6a9837bb33ebe999c372da7b5 Mon Sep 17 00:00:00 2001 From: kpl Date: Mon, 18 Nov 2013 22:32:28 -0800 Subject: [PATCH 17/23] cmDspPgmKr.c : Added the cmDspRecdPlay object to the patch. --- dsp/cmDspPgmKr.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/dsp/cmDspPgmKr.c b/dsp/cmDspPgmKr.c index 1421061..ccbacd3 100644 --- a/dsp/cmDspPgmKr.c +++ b/dsp/cmDspPgmKr.c @@ -97,7 +97,8 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) double cmpWndMaxMs = 1000.0; double cmpWndMs = 200.0; - + double recdPlayInitAllocSecs = 10.0; + double recdPlayFadeRateDbPerSec = 4.0; memset(&r,0,sizeof(r)); cmErrSetup(&err,&cmCtx->rpt,"Kr Timeline"); @@ -122,6 +123,7 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) cmDspInst_t* mop = cmDspSysAllocInst(h,"MidiOut", NULL, 2, r.midiDevice,r.midiOutPort); cmDspInst_t* sfp = cmDspSysAllocInst(h,"ScFol", NULL, 1, r.scFn ); cmDspInst_t* amp = cmDspSysAllocInst(h,"ActiveMeas", NULL, 1, 100 ); + cmDspInst_t* rpp = cmDspSysAllocInst(h,"RecdPlay", NULL, 4, 2, r.scFn, recdPlayInitAllocSecs, recdPlayFadeRateDbPerSec ); cmDspInst_t* modp = cmDspSysAllocInst(h,"ScMod", NULL, 2, r.modFn, "m1" ); cmDspInst_t* asp = cmDspSysAllocInst(h,"AmSync", NULL, 0 ); @@ -173,14 +175,14 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) cmDspInst_t* kr00 = cmDspSysAllocInst(h, "Kr", NULL, 2, krWndSmpCnt, krHopFact ); cmDspInst_t* kr01 = cmDspSysAllocInst(h, "Kr", NULL, 2, krWndSmpCnt, krHopFact ); cmDspInst_t* fad0 = cmDspSysAllocInst(h, "Xfader", NULL, 3, xfadeChCnt, xfadeMs, xfadeInitFl ); - cmDspInst_t* mix0 = cmDspSysAllocInst(h, "AMix", NULL, 3, xfadeChCnt, mixGain, mixGain ); + cmDspInst_t* mix0 = cmDspSysAllocInst(h, "AMix", NULL, 4, xfadeChCnt+1, mixGain, mixGain, mixGain ); cmDspInst_t* cmp0 = cmDspSysAllocInst(h,"Compressor", NULL, 8, cmpBypassFl, cmpThreshDb, cmpRatio_num, cmpAtkMs, cmpRlsMs, cmpMakeup, cmpWndMs, cmpWndMaxMs ); cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut", NULL, 1, 0 ); cmDspInst_t* kr10 = cmDspSysAllocInst(h, "Kr", NULL, 2, krWndSmpCnt, krHopFact ); cmDspInst_t* kr11 = cmDspSysAllocInst(h, "Kr", NULL, 2, krWndSmpCnt, krHopFact ); cmDspInst_t* fad1 = cmDspSysAllocInst(h, "Xfader", NULL, 3, xfadeChCnt, xfadeMs, xfadeInitFl ); - cmDspInst_t* mix1 = cmDspSysAllocInst(h, "AMix", NULL, 3, xfadeChCnt, mixGain, mixGain ); + cmDspInst_t* mix1 = cmDspSysAllocInst(h, "AMix", NULL, 4, xfadeChCnt+1, mixGain, mixGain, mixGain ); cmDspInst_t* cmp1 = cmDspSysAllocInst(h,"Compressor", NULL, 8, cmpBypassFl, cmpThreshDb, cmpRatio_num, cmpAtkMs, cmpRlsMs, cmpMakeup, cmpWndMs, cmpWndMaxMs ); cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut", NULL, 1, 1 ); @@ -377,12 +379,14 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) cmDspSysConnectAudio(h, wtp, "out", au0Sw, "a-in-0" ); // wt -> sw cmDspSysConnectAudio(h, ai0p, "out", au0Sw, "a-in-1" ); // ain -> sw cmDspSysConnectAudio(h, ai0p, "out", mi0p, "in" ); + cmDspSysConnectAudio(h, au0Sw,"a-out", rpp, "in-0"); // sw -> rcdply cmDspSysConnectAudio(h, au0Sw,"a-out", kr00, "in" ); // sw -> kr cmDspSysConnectAudio(h, kr00, "out", fad0, "in-0"); // kr -> fad cmDspSysConnectAudio(h, fad0, "out-0", mix0, "in-0"); // fad -> mix cmDspSysConnectAudio(h, au0Sw,"a-out", kr01, "in" ); // sw -> kr cmDspSysConnectAudio(h, kr01, "out", fad0, "in-1"); // kr -> fad cmDspSysConnectAudio(h, fad0, "out-1", mix0, "in-1"); // fad -> mix + cmDspSysConnectAudio(h, rpp, "out-0", mix0, "in-2"); cmDspSysConnectAudio(h, mix0, "out", cmp0, "in"); // mix -> cmp cmDspSysConnectAudio(h, cmp0, "out", ao0p, "in" ); // cmp -> aout @@ -390,12 +394,14 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) cmDspSysConnectAudio(h, wtp, "out", au1Sw, "a-in-0" ); // wt -> kr cmDspSysConnectAudio(h, ai1p, "out", au1Sw, "a-in-1" ); cmDspSysConnectAudio(h, ai1p, "out", mi1p, "in" ); + cmDspSysConnectAudio(h, au1Sw,"a-out", rpp, "in-1"); // sw -> rcdply cmDspSysConnectAudio(h, au1Sw,"a-out", kr10, "in" ); cmDspSysConnectAudio(h, kr10, "out", fad1, "in-0"); cmDspSysConnectAudio(h, fad1, "out-0", mix1, "in-0"); cmDspSysConnectAudio(h, au1Sw,"a-out", kr11, "in" ); // wt -> kr cmDspSysConnectAudio(h, kr11, "out", fad1, "in-1"); cmDspSysConnectAudio(h, fad1, "out-1", mix1, "in-1"); + cmDspSysConnectAudio(h, rpp, "out-0", mix1, "in-2"); cmDspSysConnectAudio(h, mix1, "out", cmp1, "in"); cmDspSysConnectAudio(h, cmp1, "out", ao1p, "in" ); // comp -> aout @@ -435,6 +441,7 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) cmDspSysInstallCb(h, pts, "on", wtRt, "s-in", NULL ); cmDspSysInstallCb(h, wtRt,"s-out-0", wtp, "cmd", NULL ); cmDspSysInstallCb(h, pts, "on", modp, "cmd", NULL ); + cmDspSysInstallCb(h, pts, "on", rpp, "cmd", NULL ); cmDspSysInstallCb(h, onb, "sym", amCmd, "rewind",NULL ); cmDspSysInstallCb(h, onb, "out", achan0,"reset", NULL ); cmDspSysInstallCb(h, onb, "out", achan1,"reset", NULL ); @@ -491,7 +498,8 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) cmDspSysInstallCb(h, mip, "d0", sfp, "d0", NULL ); cmDspSysInstallCb(h, mip, "status", sfp, "status", NULL ); - // score follower to modulator and printers + // score follower to recd_play,modulator and printers + cmDspSysInstallCb(h, sfp, "out", rpp, "index", NULL ); cmDspSysInstallCb(h, sfp, "out", modp, "index", NULL ); cmDspSysInstallCb(h, sfp, "recent", prp, "in", NULL ); // report 'recent' but only act on 'max' loc index From b74e24a46bee3bd54284620302454cb1d0bd06e9 Mon Sep 17 00:00:00 2001 From: kpl Date: Mon, 18 Nov 2013 22:35:54 -0800 Subject: [PATCH 18/23] cmData.h/c: Initial rewrite of cmData to include the concept of homogeneous arrays as containers and leaf nodes. --- cmData.c | 1314 +++++++++++++++++++++++++++++++++++++++++++++++++++++- cmData.h | 472 +++++++++++++++++--- 2 files changed, 1730 insertions(+), 56 deletions(-) diff --git a/cmData.c b/cmData.c index 8f96c4d..d965ab9 100644 --- a/cmData.c +++ b/cmData.c @@ -10,6 +10,1318 @@ #include "cmText.h" #include "cmStack.h" +typedef struct +{ + cmDataTypeId_t typeId; + unsigned byteWidth; + const cmChar_t* label; +} cmDtTypeInfo_t; + +typedef struct +{ + cmDataContainerId_t id; + const cmChar_t* label; +} cmDtCntInfo_t; + +cmDtTypeInfo_t _cmDtTypeInfoArray[] = +{ + { kNullDtId, 0, "null" }, + { kUCharDtId, sizeof(unsigned char), "uchar" }, + { kCharDtId, sizeof(char), "char" }, + { kUShortDtId, sizeof(unsigned short), "ushort" }, + { kShortDtId, sizeof(short), "short" }, + { kUIntDtId, sizeof(unsigned int), "uint" }, + { kIntDtId, sizeof(int), "int" }, + { kULongDtId, sizeof(unsigned long), "ulong" }, + { kLongDtId, sizeof(long), "long" }, + { kFloatDtId, sizeof(float), "float" }, + { kDoubleDtId, sizeof(double), "double" }, + { kStrDtId, sizeof(char*), "string" }, + { kBlobDtId, sizeof(void*), "blob" }, + { kInvalidTypeDtId, 0, "" }, +}; + +cmDtCntInfo_t _cmDtCntInfoArray[] = +{ + { kScalarDtId, "scalar" }, + { kArrayDtId, "array" }, + { kListDtId, "list" }, + { kPairDtId, "pair" }, + { kRecordDtId, "record"}, + { kInvalidCntDtId,""} +}; + +cmData_t cmDataNull = { kInvalidTypeDtId,kInvalidCntDtId,0,NULL,NULL,0 }; + +cmDtRC_t _cmDtErrMsgV( const cmData_t* d, cmDtRC_t rc, const cmChar_t* fmt, va_list vl ) +{ + // REPLACE this with a global cmRpt call. + vprintf(fmt,vl); + return rc; +} + +cmDtRC_t _cmDtErrMsg( const cmData_t* d, cmDtRC_t rc, const cmChar_t* fmt, ... ) +{ + va_list vl; + va_start(vl,fmt); + rc = _cmDtErrMsgV(d,rc,fmt,vl); + va_end(vl); + return rc; +} + +const cmChar_t* cmDataTypeToLabel( cmDataTypeId_t tid ) +{ + unsigned i; + for(i=0; _cmDtTypeInfoArray[i].typeId!=kInvalidTypeDtId; ++i) + if( _cmDtTypeInfoArray[i].typeId == tid ) + return _cmDtTypeInfoArray[i].label; + return NULL; +} + +cmDataTypeId_t cmDataLabelToType( const cmChar_t* typeLabelStr ) +{ + unsigned i; + for(i=0; _cmDtTypeInfoArray[i].typeId!=kInvalidTypeDtId; ++i) + if( strcmp(_cmDtTypeInfoArray[i].label,typeLabelStr) == 0 ) + return _cmDtTypeInfoArray[i].typeId; + return kInvalidTypeDtId; +} + +unsigned cmDataByteWidth( cmDataTypeId_t tid ) +{ + unsigned i; + for(i=0; _cmDtTypeInfoArray[i].typeId!=kInvalidTypeDtId; ++i) + if( _cmDtTypeInfoArray[i].typeId == tid ) + return _cmDtTypeInfoArray[i].byteWidth; + return cmInvalidCnt; +} + +const cmChar_t* cmDataContainerIdToLabel( cmDataContainerId_t tid ) +{ + unsigned i; + for(i=0; _cmDtCntInfoArray[i].id!=kInvalidCntDtId; ++i) + if( _cmDtCntInfoArray[i].id == tid ) + return _cmDtCntInfoArray[i].label; + return NULL; +} + +cmDataContainerId_t cmDataLabelToContainerId( const cmChar_t* contLabelStr ) +{ + unsigned i; + for(i=0; _cmDtCntInfoArray[i].id!=kInvalidCntDtId; ++i) + if( strcmp(_cmDtCntInfoArray[i].label,contLabelStr) == 0 ) + return _cmDtCntInfoArray[i].id; + return kInvalidCntDtId; +} + +bool _cmDataIsDataOwner( const cmData_t* d ) +{ return cmIsFlag(d->flags,kFreeValueDtFl) && (d->cid==kArrayDtId || d->tid==kStrDtId || d->tid==kBlobDtId); } + + +cmDtRC_t _cmDataFreeData( cmData_t* d ) +{ + if( _cmDataIsDataOwner(d) ) + { + // A object marked with kFreeValueDtFl should never also be 'const. + // (??? is this true ???? ) + assert( cmIsNotFlag(d->flags,kConstValueDtFl) ); + + cmMemPtrFree(&d->u.vp); + } + + d->flags = cmClrFlag(d->flags,kFreeValueDtFl | kConstValueDtFl ); + d->tid = kNullDtId; // objects without data are always of type 'null'. + d->cnt = 0; + memset(&d->u,0,sizeof(d->u)); + return kOkDtRC; +} + +void _cmDataFree( cmData_t* p ) +{ + if( p == NULL ) + return; + + if( cmDataIsStruct(p) ) + { + cmData_t* cp = p->u.child; + for(; cp!=NULL; cp=cp->sibling) + _cmDataFree(cp); + } + + _cmDataFreeData(p); + + if( cmIsFlag(p->flags,kFreeObjDtFl) ) + cmMemFree(p); +} + +/* +cmData_t* _cmDataAllocNode( cmData_t* parent, cmDataFmtId_t tid ) +{ + cmData_t* p = cmMemAllocZ(cmData_t,1); + p->tid = tid; + p->flags = kDynObjDtFl; + p->parent = parent; + if( parent != NULL ) + return cmDataAppendChild(parent,p); + return p; +} +*/ + + +// Dynamically allocate a 'null' data object. +cmDtRC_t _cmDataNew(cmData_t* parent, cmData_t** ref) +{ + cmData_t* d = cmMemAllocZ(cmData_t,1); + d->tid = kNullDtId; // objects without data are of type 'null'. + d->cid = kScalarDtId; + d->flags = kFreeObjDtFl; + d->parent = parent; + d->cnt = 0; + + if( parent != NULL ) + cmDataAppendChild(parent,d); + + *ref = d; + return kOkDtRC; +} + + +bool cmDataIsConstObj( const cmData_t* d ) +{ return cmIsFlag(d->flags,kConstObjDtFl); } + +void cmDataEnableConstObj( cmData_t* d, bool enaFl ) +{ d->flags = cmEnaFlag(d->flags,kConstObjDtFl,enaFl); } + +bool cmDataIsConstValue( const cmData_t* d ) +{ return cmIsFlag(d->flags,kConstValueDtFl); } + +void cmDataEnableConstValue( cmData_t* d, bool enaFl ) +{ d->flags = cmEnaFlag(d->flags,kConstValueDtFl,enaFl); } + +bool cmDataIsFreeValue( const cmData_t* d ) +{ return cmIsFlag(d->flags,kFreeValueDtFl); } + +void cmDataEnableFreeValue( cmData_t* d, bool enaFl ) +{ d->flags = cmEnaFlag(d->flags,kFreeValueDtFl,enaFl); } + +bool cmDataIsLeaf( const cmData_t* d) +{ return d->cid == kScalarDtId || d->cid == kArrayDtId; } + +bool cmDataIsStruct( const cmData_t* d ) +{ return !cmDataIsLeaf(d); } + + +cmDtRC_t cmDataNewScalar( cmData_t* parent, cmDataTypeId_t tid, unsigned flags, void* vp, unsigned byteCnt, cmData_t** ref ) +{ + cmData_t* d = NULL; + cmDtRC_t rc; + + *ref = NULL; + + // create a scalar null object + if((rc = _cmDataNew(parent,&d)) != kOkDtRC ) + return rc; + + if( tid!=kStrDtId && tid!=kBlobDtId ) + { + // When used with scalars kFreeValueDtFl and kNoCopyDtFl only + // has meaning for strings and blobs - so clear these flags for other types. + flags = cmClrFlag(flags,kFreeValueDtFl | kNoCopyDtFl); + + // if this is not a blob or string then the byteCnt is reset + byteCnt = cmDataByteWidth(tid); + } + + + + // assign the value + if((rc = cmDataSetScalarValue(d,tid,vp,byteCnt,flags)) != kOkDtRC ) + return rc; + + // set the const flags for the new object + d->flags = cmSetFlag(d->flags, flags & (kConstValueDtFl | kConstObjDtFl)); + + *ref = d; + + return rc; +} + +cmDtRC_t cmDataNewNull( cmData_t* parent, unsigned flags, cmData_t** ref ) +{ return _cmDataNew(parent, ref); } +cmDtRC_t cmDataNewChar( cmData_t* parent, unsigned flags, char v, cmData_t** ref ) +{ return cmDataNewScalar(parent,kCharDtId,flags,&v,0,ref); } +cmDtRC_t cmDataNewUChar( cmData_t* parent, unsigned flags, unsigned char v, cmData_t** ref ) +{ return cmDataNewScalar(parent,kUCharDtId,flags,&v,0,ref); } +cmDtRC_t cmDataNewShort( cmData_t* parent, unsigned flags, short v, cmData_t** ref ) +{ return cmDataNewScalar(parent,kShortDtId,flags,&v,0,ref); } +cmDtRC_t cmDataNewUShort( cmData_t* parent, unsigned flags, unsigned short v, cmData_t** ref ) +{ return cmDataNewScalar(parent,kUShortDtId,flags,&v,0,ref); } +cmDtRC_t cmDataNewInt( cmData_t* parent, unsigned flags, int v, cmData_t** ref ) +{ return cmDataNewScalar(parent,kIntDtId,flags,&v,0,ref); } +cmDtRC_t cmDataNewUInt( cmData_t* parent, unsigned flags, unsigned int v, cmData_t** ref ) +{ return cmDataNewScalar(parent,kUIntDtId,flags,&v,0,ref); } +cmDtRC_t cmDataNewLong( cmData_t* parent, unsigned flags, long v, cmData_t** ref ) +{ return cmDataNewScalar(parent,kLongDtId,flags,&v,0,ref); } +cmDtRC_t cmDataNewULong( cmData_t* parent, unsigned flags, unsigned long v, cmData_t** ref ) +{ return cmDataNewScalar(parent,kULongDtId,flags,&v,0,ref); } +cmDtRC_t cmDataNewFloat( cmData_t* parent, unsigned flags, float v, cmData_t** ref ) +{ return cmDataNewScalar(parent,kFloatDtId,flags,&v,0,ref); } +cmDtRC_t cmDataNewDouble( cmData_t* parent, unsigned flags, double v, cmData_t** ref ) +{ return cmDataNewScalar(parent,kDoubleDtId,flags,&v,0,ref); } +cmDtRC_t cmDataNewStr( cmData_t* parent, unsigned flags, cmChar_t* v, cmData_t** ref ) +{ return cmDataNewScalar(parent,kStrDtId,flags,v,strlen(v)+1,ref); } +cmDtRC_t cmDataNewConstStr( cmData_t* parent, unsigned flags, const cmChar_t* v, cmData_t** ref ) +{ return cmDataNewScalar(parent,kStrDtId,flags | kConstValueDtFl, (void*)v,strlen(v)+1,ref); } +cmDtRC_t cmDataNewStrN( cmData_t* parent, unsigned flags, cmChar_t* v, unsigned charCnt, cmData_t** ref ) +{ return cmDataNewScalar(parent,kStrDtId,flags,v,charCnt+1,ref); } +cmDtRC_t cmDataNewConstStrN( cmData_t* parent, unsigned flags, const cmChar_t* v, unsigned charCnt, cmData_t** ref ) +{ return cmDataNewScalar(parent,kStrDtId,flags | kConstValueDtFl, (void*)v,charCnt+1,ref); } +cmDtRC_t cmDataNewBlob( cmData_t* parent, unsigned flags, void* v, unsigned byteCnt, cmData_t** ref ) +{ return cmDataNewScalar(parent,kBlobDtId,flags,v,byteCnt,ref); } +cmDtRC_t cmDataNewConstBlob( cmData_t* parent, unsigned flags, const void* v, unsigned byteCnt, cmData_t** ref ) +{ return cmDataNewScalar(parent,kBlobDtId,flags | kConstValueDtFl, (void*)v,byteCnt,ref); } + + +cmDtRC_t cmDataSetScalarValue( cmData_t* d, cmDataTypeId_t tid, void* vp, unsigned byteCnt, unsigned flags ) +{ + cmDtRC_t rc; + + // if the type of the object is changing + if( d->tid != tid || d->cid != kScalarDtId ) + { + // verify that it is legal to change the type of the object + if( cmIsFlag(d->flags,kConstObjDtFl) ) + return _cmDtErrMsg(d,kConstErrDtRC,"Const object violation."); + + // convert this to a scalar null object. + if((rc = _cmDataFreeData(d)) != kOkDtRC ) + return rc; + } + + // verify that it is legal to change the value of this object + if( cmIsFlag(d->flags,kConstValueDtFl) ) + return _cmDtErrMsg(d,kConstErrDtRC,"Const value violation."); + + switch( tid ) + { + case kInvalidTypeDtId: + return _cmDtErrMsg(d,kAssertErrDtRC,"Invalid data type."); + + case kNullDtId: // 'd' is already NULL. + break; + + case kUCharDtId: d->u.uc = *(unsigned char*)vp; break; + case kCharDtId: d->u.c = *(char*)vp; break; + case kUShortDtId: d->u.us = *(unsigned short*)vp; break; + case kShortDtId: d->u.s = *(short*)vp; break; + case kUIntDtId: d->u.ui = *(unsigned int*)vp; break; + case kIntDtId: d->u.i = *(int*)vp; break; + case kULongDtId: d->u.ul = *(unsigned long*)vp; break; + case kLongDtId: d->u.l = *(long*)vp; break; + case kFloatDtId: d->u.f = *(float*)vp; break; + case kDoubleDtId: d->u.d = *(double*)vp; break; + case kStrDtId: + case kBlobDtId: + { + cmChar_t* blankStr = ""; + + // strings must have a byteCnt of at least one + assert( tid==kBlobDtId || (tid==kStrDtId && byteCnt>0) ); + + // if a NULL source string is encountered then make it a 0 length string + if( d->tid==kStrDtId && vp==NULL ) + vp = blankStr; + + // if an empty blob was passed in then be sure it's src ptr is NULL and byteCnt==0 + if( d->tid==kBlobDtId && (vp==NULL || byteCnt==0) ) + { + if((rc = _cmDataFreeData(d)) != kOkDtRC ) + return rc; + + byteCnt = 0; + d->u.z = NULL; + break; + } + + // if the incoming string/blob should be internally duplicated + if( cmIsNotFlag(flags,kNoCopyDtFl) ) + { + + // allocate internal space to store the incoming data + if( (d->tid==kBlobDtId || d->tid == kStrDtId) && cmIsFlag(d->flags,kFreeValueDtFl) ) + d->u.z = cmMemResize(char,d->u.z,byteCnt); + else + d->u.z = cmMemAlloc(char,byteCnt); + + // store the source string/blob into the internal memory buffer + memcpy(d->u.z,vp,byteCnt); + + // by default the system now takes responsibility for freeing this buffer + d->flags |= kFreeValueDtFl; + } + else // the incoming string/blob pointer is simply being assigned w/o duplication + { + // free the objects previous value ... + if((rc = _cmDataFreeData(d)) != kOkDtRC ) + return rc; + + // and assign the new value (without reallocating the string) + d->u.z = vp; + + d->flags = cmEnaFlag(d->flags,kFreeValueDtFl,cmIsFlag(flags,kFreeValueDtFl)); + d->flags |= kNoCopyDtFl; + } + } + break; + + default: + break; + } + + // we can't set this above because the string type relies + // on knowing the previous type of the object + d->cid = kScalarDtId; + d->tid = tid; + d->cnt = byteCnt; + return rc; +} + +cmDtRC_t cmDataSetNull( cmData_t* d ) +{ return cmDataSetScalarValue(d, kNullDtId, NULL, 0, kNoFlagsDtFl ); } +cmDtRC_t cmDataSetChar( cmData_t* d, char v ) +{ return cmDataSetScalarValue(d, kCharDtId, &v, 0, kNoFlagsDtFl ); } +cmDtRC_t cmDataSetUChar( cmData_t* d, unsigned char v ) +{ return cmDataSetScalarValue(d, kUCharDtId, &v, 0, kNoFlagsDtFl ); } +cmDtRC_t cmDataSetShort( cmData_t* d, short v ) +{ return cmDataSetScalarValue(d, kShortDtId, &v, 0, kNoFlagsDtFl ); } +cmDtRC_t cmDataSetUShort( cmData_t* d, unsigned short v ) +{ return cmDataSetScalarValue(d, kUShortDtId, &v, 0, kNoFlagsDtFl ); } +cmDtRC_t cmDataSetInt( cmData_t* d, int v ) +{ return cmDataSetScalarValue(d, kIntDtId, &v, 0, kNoFlagsDtFl ); } +cmDtRC_t cmDataSetUInt( cmData_t* d, unsigned int v ) +{ return cmDataSetScalarValue(d, kUIntDtId, &v, 0, kNoFlagsDtFl ); } +cmDtRC_t cmDataSetLong( cmData_t* d, long v ) +{ return cmDataSetScalarValue(d, kLongDtId, &v, 0, kNoFlagsDtFl ); } +cmDtRC_t cmDataSetULong( cmData_t* d, unsigned long v ) +{ return cmDataSetScalarValue(d, kULongDtId, &v, 0, kNoFlagsDtFl ); } +cmDtRC_t cmDataSetFloat( cmData_t* d, float v ) +{ return cmDataSetScalarValue(d, kFloatDtId, &v, 0, kNoFlagsDtFl ); } +cmDtRC_t cmDataSetDouble( cmData_t* d, double v ) +{ return cmDataSetScalarValue(d, kDoubleDtId, &v, 0, kNoFlagsDtFl ); } +cmDtRC_t cmDataSetStr( cmData_t* d, unsigned flags, cmChar_t* v ) +{ return cmDataSetScalarValue(d, kStrDtId, v, v==NULL ? 1 : strlen(v)+1, flags ); } +cmDtRC_t cmDataSetConstStr( cmData_t* d, unsigned flags, const cmChar_t* v ) +{ return cmDataSetScalarValue(d, kStrDtId, (void*)v, v==NULL ? 1 : strlen(v)+1, flags |= kConstValueDtFl ); } +cmDtRC_t cmDataSetStrN( cmData_t* d, unsigned flags, cmChar_t* v, unsigned charCnt ) +{ return cmDataSetScalarValue(d, kStrDtId, (void*)v, v==NULL ? 1 : charCnt+1, flags); } +cmDtRC_t cmDataSetConstStrN( cmData_t* d, unsigned flags, const cmChar_t* v, unsigned charCnt ) +{ return cmDataSetScalarValue(d, kStrDtId, (void*)v, v==NULL ? 1 : charCnt+1, flags |= kConstValueDtFl); } +cmDtRC_t cmDataSetBlob( cmData_t* d, unsigned flags, void* v, unsigned byteCnt ) +{ return cmDataSetScalarValue(d, kBlobDtId, v, byteCnt, flags); } +cmDtRC_t cmDataSetConstBlob( cmData_t* d, unsigned flags, const void* v, unsigned byteCnt ) +{ return cmDataSetScalarValue(d, kBlobDtId, (void*)v, byteCnt, flags |= kConstValueDtFl); } + + + +cmDtRC_t cmDataChar( const cmData_t* d, char* v ) +{ + if( d->tid != kCharDtId ) + return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:char but encountered type:%s.",cmDataTypeToLabel(d->tid)); + *v = d->u.c; + return kOkDtRC; +} + +cmDtRC_t cmDataUChar( const cmData_t* d, unsigned char* v ) +{ + if( d->tid != kUCharDtId ) + return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:uchar but encountered type:%s.",cmDataTypeToLabel(d->tid)); + *v = d->u.uc; + return kOkDtRC; +} + +cmDtRC_t cmDataShort( const cmData_t* d, short* v ) +{ + if( d->tid != kShortDtId ) + return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:short but encountered type:%s.",cmDataTypeToLabel(d->tid)); + *v = d->u.s; + return kOkDtRC; +} + +cmDtRC_t cmDataUShort( const cmData_t* d, unsigned short* v ) +{ + if( d->tid != kUShortDtId ) + return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:ushort but encountered type:%s.",cmDataTypeToLabel(d->tid)); + *v = d->u.us; + return kOkDtRC; +} + +cmDtRC_t cmDataInt( const cmData_t* d, int* v ) +{ + if( d->tid != kIntDtId ) + return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:int but encountered type:%s.",cmDataTypeToLabel(d->tid)); + *v = d->u.i; + return kOkDtRC; +} + +cmDtRC_t cmDataUInt( const cmData_t* d, unsigned int* v ) +{ + if( d->tid != kUIntDtId ) + return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:uint but encountered type:%s.",cmDataTypeToLabel(d->tid)); + *v = d->u.ui; + return kOkDtRC; +} + +cmDtRC_t cmDataLong( const cmData_t* d, long* v ) +{ + if( d->tid != kLongDtId ) + return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:long but encountered type:%s.",cmDataTypeToLabel(d->tid)); + *v = d->u.l; + return kOkDtRC; +} + +cmDtRC_t cmDataULong( const cmData_t* d, unsigned long* v ) +{ + if( d->tid != kULongDtId ) + return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:ulong but encountered type:%s.",cmDataTypeToLabel(d->tid)); + *v = d->u.ul; + return kOkDtRC; +} + +cmDtRC_t cmDataFloat( const cmData_t* d, float* v ) +{ + if( d->tid != kFloatDtId ) + return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:float but encountered type:%s.",cmDataTypeToLabel(d->tid)); + *v = d->u.f; + return kOkDtRC; +} + +cmDtRC_t cmDataDouble( const cmData_t* d, double* v ) +{ + if( d->tid != kDoubleDtId ) + return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:double but encountered type:%s.",cmDataTypeToLabel(d->tid)); + *v = d->u.d; + return kOkDtRC; +} + +cmDtRC_t cmDataStr( const cmData_t* d, cmChar_t** v ) +{ + if( d->tid != kStrDtId ) + return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:string but encountered type:%s.",cmDataTypeToLabel(d->tid)); + + if( cmIsFlag(d->flags,kConstValueDtFl) ) + return _cmDtErrMsg(d,kConstErrDtRC,"A const string cannot return as a non-const string."); + + *v = d->u.z; + return kOkDtRC; +} + +cmDtRC_t cmDataConstStr( const cmData_t* d, const cmChar_t** v ) +{ + if( d->tid != kStrDtId ) + return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:string but encountered type:%s.",cmDataTypeToLabel(d->tid)); + + *v = d->u.z; + return kOkDtRC; +} + +cmDtRC_t cmDataBlob( const cmData_t* d, cmChar_t** v, unsigned* byteCntRef ) +{ + if( v != NULL ) + *v = NULL; + + if( byteCntRef != NULL ) + *byteCntRef = 0; + + if( d->tid != kBlobDtId ) + return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:string but encountered type:%s.",cmDataTypeToLabel(d->tid)); + + if( v != NULL ) + *v = d->u.z; + + if( byteCntRef != NULL ) + *byteCntRef = d->cnt; + + return kOkDtRC; +} + +cmDtRC_t cmDataConstBlob( const cmData_t* d, const cmChar_t** v, unsigned* byteCntRef ) +{ + if( v != NULL ) + *v = NULL; + + if( byteCntRef != NULL ) + *byteCntRef = 0; + + if( d->tid != kBlobDtId ) + return _cmDtErrMsg(d,kInvalidTypeDtRC,"Expected type:string but encountered type:%s.",cmDataTypeToLabel(d->tid)); + + if( v != NULL ) + *v = d->u.z; + + if( byteCntRef != NULL ) + *byteCntRef = d->cnt; + + return kOkDtRC; +} + + +cmDtRC_t cmDataGetUChar( const cmData_t* p, unsigned char* vp ) +{ + if( p->cid != kScalarDtId ) + return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value."); + + switch( p->tid ) + { + case kUCharDtId: *vp = p->u.uc; break; + case kCharDtId: *vp = (unsigned char)p->u.c; break; + case kUShortDtId: *vp = (unsigned char)p->u.us; break; + case kShortDtId: *vp = (unsigned char)p->u.s; break; + case kUIntDtId: *vp = (unsigned char)p->u.ui; break; + case kIntDtId: *vp = (unsigned char)p->u.i; break; + case kULongDtId: *vp = (unsigned char)p->u.ul; break; + case kLongDtId: *vp = (unsigned char)p->u.l; break; + case kFloatDtId: *vp = (unsigned char)p->u.f; break; + case kDoubleDtId: *vp = (unsigned char)p->u.d; break; + default: + return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'uchar'.",cmDataTypeToLabel(p->tid)); + } + return kOkDtRC; +} + +cmDtRC_t cmDataGetChar( const cmData_t* p, char* vp ) +{ + if( p->cid != kScalarDtId ) + return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value."); + + switch( p->tid ) + { + case kUCharDtId: *vp = (char)p->u.uc; break; + case kCharDtId: *vp = p->u.c; break; + case kUShortDtId: *vp = (char)p->u.us; break; + case kShortDtId: *vp = (char)p->u.s; break; + case kUIntDtId: *vp = (char)p->u.ui; break; + case kIntDtId: *vp = (char)p->u.i; break; + case kULongDtId: *vp = (char)p->u.ul; break; + case kLongDtId: *vp = (char)p->u.l; break; + case kFloatDtId: *vp = (char)p->u.f; break; + case kDoubleDtId: *vp = (char)p->u.d; break; + default: + return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'char'.",cmDataTypeToLabel(p->tid)); + } + return kOkDtRC; +} + +cmDtRC_t cmDataGetShort( const cmData_t* p, short* vp ) +{ + if( p->cid != kScalarDtId ) + return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value."); + + switch( p->tid ) + { + case kUCharDtId: *vp = (short)p->u.uc; break; + case kCharDtId: *vp = (short)p->u.c; break; + case kUShortDtId: *vp = (short)p->u.us; break; + case kShortDtId: *vp = p->u.s; break; + case kUIntDtId: *vp = (short)p->u.ui; break; + case kIntDtId: *vp = (short)p->u.i; break; + case kULongDtId: *vp = (short)p->u.ul; break; + case kLongDtId: *vp = (short)p->u.l; break; + case kFloatDtId: *vp = (short)p->u.f; break; + case kDoubleDtId: *vp = (short)p->u.d; break; + default: + return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'short'.",cmDataTypeToLabel(p->tid)); + + } + return kOkDtRC; +} + + +cmDtRC_t cmDataGetUShort( const cmData_t* p, unsigned short* vp ) +{ + if( p->cid != kScalarDtId ) + return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value."); + + switch( p->tid ) + { + case kUCharDtId: *vp = (unsigned short)p->u.uc; break; + case kCharDtId: *vp = (unsigned short)p->u.c; break; + case kUShortDtId: *vp = p->u.us; break; + case kShortDtId: *vp = (unsigned short)p->u.s; break; + case kUIntDtId: *vp = (unsigned short)p->u.ui; break; + case kIntDtId: *vp = (unsigned short)p->u.i; break; + case kULongDtId: *vp = (unsigned short)p->u.ul; break; + case kLongDtId: *vp = (unsigned short)p->u.l; break; + case kFloatDtId: *vp = (unsigned short)p->u.f; break; + case kDoubleDtId: *vp = (unsigned short)p->u.d; break; + default: + return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'ushort'.",cmDataTypeToLabel(p->tid)); + + } + return kOkDtRC; +} + +cmDtRC_t cmDataGetInt( const cmData_t* p, int* vp ) +{ + if( p->cid != kScalarDtId ) + return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value."); + + switch( p->tid ) + { + case kUCharDtId: *vp = (int)p->u.uc; break; + case kCharDtId: *vp = (int)p->u.c; break; + case kUShortDtId: *vp = (int)p->u.us; break; + case kShortDtId: *vp = (int)p->u.s; break; + case kUIntDtId: *vp = (int)p->u.ui; break; + case kIntDtId: *vp = p->u.i; break; + case kULongDtId: *vp = (int)p->u.ul; break; + case kLongDtId: *vp = (int)p->u.l; break; + case kFloatDtId: *vp = (int)p->u.f; break; + case kDoubleDtId: *vp = (int)p->u.d; break; + default: + return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'int'.",cmDataTypeToLabel(p->tid)); + + } + return kOkDtRC; +} + +cmDtRC_t cmDataGetUInt( const cmData_t* p, unsigned int* vp ) +{ + if( p->cid != kScalarDtId ) + return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value."); + + switch( p->tid ) + { + case kUCharDtId: *vp = (unsigned int)p->u.uc; break; + case kCharDtId: *vp = (unsigned int)p->u.c; break; + case kUShortDtId: *vp = (unsigned int)p->u.us; break; + case kShortDtId: *vp = (unsigned int)p->u.s; break; + case kUIntDtId: *vp = p->u.ui; break; + case kIntDtId: *vp = (unsigned int)p->u.i; break; + case kULongDtId: *vp = (unsigned int)p->u.ul; break; + case kLongDtId: *vp = (unsigned int)p->u.l; break; + case kFloatDtId: *vp = (unsigned int)p->u.f; break; + case kDoubleDtId: *vp = (unsigned int)p->u.d; break; + default: + return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'uint'.",cmDataTypeToLabel(p->tid)); + + } + return kOkDtRC; +} + +cmDtRC_t cmDataGetLong( const cmData_t* p, long* vp ) +{ + if( p->cid != kScalarDtId ) + return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value."); + + switch( p->tid ) + { + case kUCharDtId: *vp = (long)p->u.uc; break; + case kCharDtId: *vp = (long)p->u.c; break; + case kUShortDtId: *vp = (long)p->u.us; break; + case kShortDtId: *vp = (long)p->u.s; break; + case kUIntDtId: *vp = (long)p->u.ui; break; + case kIntDtId: *vp = (long)p->u.i; break; + case kULongDtId: *vp = (long)p->u.ul; break; + case kLongDtId: *vp = p->u.l; break; + case kFloatDtId: *vp = (long)p->u.f; break; + case kDoubleDtId: *vp = (long)p->u.d; break; + default: + return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'long'.",cmDataTypeToLabel(p->tid)); + + } + return kOkDtRC; +} + +cmDtRC_t cmDataGetULong( const cmData_t* p, unsigned long* vp ) +{ + if( p->cid != kScalarDtId ) + return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value."); + + switch( p->tid ) + { + case kUCharDtId: *vp = (unsigned long)p->u.uc; break; + case kCharDtId: *vp = (unsigned long)p->u.c; break; + case kUShortDtId: *vp = (unsigned long)p->u.us; break; + case kShortDtId: *vp = (unsigned long)p->u.s; break; + case kUIntDtId: *vp = (unsigned long)p->u.ui; break; + case kIntDtId: *vp = (unsigned long)p->u.i; break; + case kULongDtId: *vp = p->u.ul; break; + case kLongDtId: *vp = (unsigned long)p->u.l; break; + case kFloatDtId: *vp = (unsigned long)p->u.f; break; + case kDoubleDtId: *vp = (unsigned long)p->u.d; break; + default: + return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'ulong'.",cmDataTypeToLabel(p->tid)); + + } + return kOkDtRC; +} + +cmDtRC_t cmDataGetFloat( const cmData_t* p, float* vp ) +{ + if( p->cid != kScalarDtId ) + return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value."); + + switch( p->tid ) + { + case kUCharDtId: *vp = (float)p->u.uc; break; + case kCharDtId: *vp = (float)p->u.c; break; + case kUShortDtId: *vp = (float)p->u.us; break; + case kShortDtId: *vp = (float)p->u.s; break; + case kUIntDtId: *vp = (float)p->u.ui; break; + case kIntDtId: *vp = (float)p->u.i; break; + case kULongDtId: *vp = (float)p->u.ul; break; + case kLongDtId: *vp = (float)p->u.l; break; + case kFloatDtId: *vp = p->u.f; break; + case kDoubleDtId: *vp = (float)p->u.d; break; + default: + return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'float'.",cmDataTypeToLabel(p->tid)); + + } + return kOkDtRC; +} + +cmDtRC_t cmDataGetDouble( const cmData_t* p, double* vp ) +{ + if( p->cid != kScalarDtId ) + return _cmDtErrMsg(p,kInvalidContDtRC,"Cannot convert a non-scalar value to a scalar value."); + + switch( p->tid ) + { + case kUCharDtId: *vp = (double)p->u.uc; break; + case kCharDtId: *vp = (double)p->u.c; break; + case kUShortDtId: *vp = (double)p->u.us; break; + case kShortDtId: *vp = (double)p->u.s; break; + case kUIntDtId: *vp = (double)p->u.ui; break; + case kIntDtId: *vp = (double)p->u.i; break; + case kULongDtId: *vp = (double)p->u.ul; break; + case kLongDtId: *vp = (double)p->u.l; break; + case kFloatDtId: *vp = (double)p->u.f; break; + case kDoubleDtId: *vp = p->u.d; break; + default: + return _cmDtErrMsg(p,kCvtErrDtRC,"Cannot convert '%s' to 'double'.",cmDataTypeToLabel(p->tid)); + + } + return kOkDtRC; +} + +cmDtRC_t cmDataNewArray( cmData_t* parent, cmDataTypeId_t tid, void* vp, unsigned eleCnt, unsigned flags, cmData_t** ref ) +{ + cmDtRC_t rc; + cmData_t* d = NULL; + + *ref = NULL; + + // create a new 'null' object + if((rc = _cmDataNew(parent, &d)) != kOkDtRC ) + return rc; + + // assign the value + if((rc = cmDataSetArrayValue(d,tid,vp,eleCnt,flags)) != kOkDtRC ) + return rc; + + // set the flags for the new object + d->flags = cmSetFlag(d->flags, flags & (kConstValueDtFl | kConstObjDtFl | kNoCopyDtFl)); + + *ref = d; + + return rc; + +} + +cmDtRC_t cmDataNewCharArray( cmData_t* parent, char* v, unsigned eleCnt, unsigned flags, cmData_t** ref ) +{ return cmDataNewArray(parent, kCharDtId, v, eleCnt, flags, ref ); } +cmDtRC_t cmDataNewUCharArray( cmData_t* parent, unsigned char* v, unsigned eleCnt, unsigned flags, cmData_t** ref ) +{ return cmDataNewArray(parent, kUCharDtId, v, eleCnt, flags, ref ); } +cmDtRC_t cmDataNewShortArray( cmData_t* parent, short* v, unsigned eleCnt, unsigned flags, cmData_t** ref ) +{ return cmDataNewArray(parent, kShortDtId, v, eleCnt, flags, ref ); } +cmDtRC_t cmDataNewUShortArray( cmData_t* parent, unsigned short* v, unsigned eleCnt, unsigned flags, cmData_t** ref ) +{ return cmDataNewArray(parent, kUShortDtId, v, eleCnt, flags, ref ); } +cmDtRC_t cmDataNewIntArray( cmData_t* parent, int* v, unsigned eleCnt, unsigned flags, cmData_t** ref ) +{ return cmDataNewArray(parent, kIntDtId, v, eleCnt, flags, ref ); } +cmDtRC_t cmDataNewUIntArray( cmData_t* parent, unsigned int* v, unsigned eleCnt, unsigned flags, cmData_t** ref ) +{ return cmDataNewArray(parent, kUIntDtId, v, eleCnt, flags, ref ); } +cmDtRC_t cmDataNewLongArray( cmData_t* parent, long* v, unsigned eleCnt, unsigned flags, cmData_t** ref ) +{ return cmDataNewArray(parent, kLongDtId, v, eleCnt, flags, ref ); } +cmDtRC_t cmDataNewULongArray( cmData_t* parent, unsigned long* v, unsigned eleCnt, unsigned flags, cmData_t** ref ) +{ return cmDataNewArray(parent, kULongDtId, v, eleCnt, flags, ref ); } +cmDtRC_t cmDataNewFloatArray( cmData_t* parent, float* v, unsigned eleCnt, unsigned flags, cmData_t** ref ) +{ return cmDataNewArray(parent, kFloatDtId, v, eleCnt, flags, ref ); } +cmDtRC_t cmDataNewDoubleArray( cmData_t* parent, double* v, unsigned eleCnt, unsigned flags, cmData_t** ref ) +{ return cmDataNewArray(parent, kDoubleDtId, v, eleCnt, flags, ref ); } +cmDtRC_t cmDataNewStrArray( cmData_t* parent, cmChar_t** v, unsigned eleCnt, unsigned flags, cmData_t** ref ) +{ return cmDataNewArray(parent, kStrDtId, v, eleCnt, flags, ref ); } +cmDtRC_t cmDataNewConstStrArray( cmData_t* parent, const cmChar_t** v,unsigned eleCnt, unsigned flags, cmData_t** ref ) +{ return cmDataNewArray(parent, kStrDtId, (cmChar_t**)v, eleCnt, flags, ref ); } + + +cmDtRC_t cmDataSetArrayValue( cmData_t* d, cmDataTypeId_t tid, void* vp, unsigned eleCnt, unsigned flags ) +{ + cmDtRC_t rc = kOkDtRC; + + // if the type of the object is changing + if( d->tid != tid || d->cid != kScalarDtId ) + { + // verify that it is legal to change the type of the object + if( cmIsFlag(d->flags,kConstObjDtFl) ) + return _cmDtErrMsg(d,kConstErrDtRC,"Const object violation."); + + // convert this to a scalar null object. + if((rc = _cmDataFreeData(d)) != kOkDtRC ) + return rc; + } + + // verify that it is legal to change the value of this object + if( cmIsFlag(d->flags,kConstValueDtFl) ) + return _cmDtErrMsg(d,kConstErrDtRC,"Const value violation."); + + + // if the array should be reallocated + if( cmIsNotFlag(flags,kNoCopyDtFl) ) + { + unsigned byteCnt = cmDataByteWidth(tid) * eleCnt; + + // reallocate a new string + if( d->cid == kArrayDtId && cmIsFlag(d->flags,kFreeValueDtFl) ) + d->u.vp = cmMemResize(char,d->u.z,byteCnt); + else + d->u.vp = cmMemAlloc(char,byteCnt); + + memcpy(d->u.z,vp,byteCnt); + + d->flags |= kFreeValueDtFl; + } + else + { + // free the previous value ... + if((rc = _cmDataFreeData(d)) != kOkDtRC ) + return rc; + + // and assign the new value (without reallocating the array) + d->u.vp = vp; + + d->flags = cmEnaFlag(d->flags,kFreeValueDtFl,cmIsFlag(flags,kFreeValueDtFl)); + + } + + // we can't set this above because the string type relies + // on knowing the previous type of the object + d->cid = kArrayDtId; + d->tid = tid; + d->cnt = eleCnt; + + return rc; + +} + +cmDtRC_t cmDataSetCharArray( cmData_t* d, char* v, unsigned eleCnt, unsigned flags ) +{ return cmDataSetArrayValue(d, kCharDtId, v, eleCnt, flags ); } +cmDtRC_t cmDataSetUCharArray( cmData_t* d, unsigned char* v, unsigned eleCnt, unsigned flags ) +{ return cmDataSetArrayValue(d, kUCharDtId, v, eleCnt, flags ); } +cmDtRC_t cmDataSetShortArray( cmData_t* d, short* v, unsigned eleCnt, unsigned flags ) +{ return cmDataSetArrayValue(d, kShortDtId, v, eleCnt, flags ); } +cmDtRC_t cmDataSetUShortArray( cmData_t* d, unsigned short* v, unsigned eleCnt, unsigned flags ) +{ return cmDataSetArrayValue(d, kUShortDtId, v, eleCnt, flags ); } +cmDtRC_t cmDataSetIntArray( cmData_t* d, int* v, unsigned eleCnt, unsigned flags ) +{ return cmDataSetArrayValue(d, kIntDtId, v, eleCnt, flags ); } +cmDtRC_t cmDataSetUIntArray( cmData_t* d, unsigned int* v, unsigned eleCnt, unsigned flags ) +{ return cmDataSetArrayValue(d, kUIntDtId, v, eleCnt, flags ); } +cmDtRC_t cmDataSetLongArray( cmData_t* d, long* v, unsigned eleCnt, unsigned flags ) +{ return cmDataSetArrayValue(d, kLongDtId, v, eleCnt, flags ); } +cmDtRC_t cmDataSetULongArray( cmData_t* d, unsigned long* v, unsigned eleCnt, unsigned flags ) +{ return cmDataSetArrayValue(d, kULongDtId, v, eleCnt, flags ); } +cmDtRC_t cmDataSetFloatArray( cmData_t* d, float* v, unsigned eleCnt, unsigned flags ) +{ return cmDataSetArrayValue(d, kFloatDtId, v, eleCnt, flags ); } +cmDtRC_t cmDataSetDoubleArray( cmData_t* d, double* v, unsigned eleCnt, unsigned flags ) +{ return cmDataSetArrayValue(d, kDoubleDtId, v, eleCnt, flags ); } +cmDtRC_t cmDataSetStrArray( cmData_t* d, cmChar_t** v, unsigned eleCnt, unsigned flags ) +{ return cmDataSetArrayValue(d, kStrDtId, v, eleCnt, flags ); } +cmDtRC_t cmDataSetConstStrArray(cmData_t* d,const cmChar_t** v,unsigned eleCnt, unsigned flags ) +{ return cmDataSetArrayValue(d, kStrDtId, (cmChar_t**)v, eleCnt, flags ); } + + +unsigned cmDataArrayEleCount( const cmData_t* d ) +{ return d->cid==kArrayDtId ? d->cnt : 0; } + + +cmDtRC_t cmDataCharArray( const cmData_t* d, char** v ) +{ + if( d->cid != kArrayDtId ) + return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid)); + *v = (char*)d->u.vp; + return kOkDtRC; +} + +cmDtRC_t cmDataUCharArray( const cmData_t* d, unsigned char** v ) +{ + if( d->cid != kArrayDtId ) + return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid)); + *v = (unsigned char*)d->u.vp; + return kOkDtRC; +} + +cmDtRC_t cmDataShortArray( const cmData_t* d, short** v ) +{ + if( d->cid != kArrayDtId ) + return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid)); + *v = (short*)d->u.vp; + return kOkDtRC; +} + +cmDtRC_t cmDataUShortArray( const cmData_t* d, unsigned short** v ) +{ + if( d->cid != kArrayDtId ) + return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid)); + *v = (unsigned short*)d->u.vp; + return kOkDtRC; +} + +cmDtRC_t cmDataIntArray( const cmData_t* d, int** v ) +{ + if( d->cid != kArrayDtId ) + return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid)); + *v = (int*)d->u.vp; + return kOkDtRC; +} + +cmDtRC_t cmDataUIntArray( const cmData_t* d, unsigned int** v ) +{ + if( d->cid != kArrayDtId ) + return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid)); + *v = (unsigned int*)d->u.vp; + return kOkDtRC; +} + +cmDtRC_t cmDataLongArray( const cmData_t* d, long** v ) +{ + if( d->cid != kArrayDtId ) + return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid)); + *v = (long*)d->u.vp; + return kOkDtRC; +} + +cmDtRC_t cmDataULongArray( const cmData_t* d, unsigned long** v ) +{ + if( d->cid != kArrayDtId ) + return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid)); + *v = (unsigned long*)d->u.vp; + return kOkDtRC; +} + +cmDtRC_t cmDataFloatArray( const cmData_t* d, float** v ) +{ + if( d->cid != kArrayDtId ) + return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid)); + *v = (float*)d->u.vp; + return kOkDtRC; +} + +cmDtRC_t cmDataDoubleArray( const cmData_t* d, double** v ) +{ + if( d->cid != kArrayDtId ) + return _cmDtErrMsg(d,kInvalidContDtRC,"Cannot return an array base for a %s container.",cmDataContainerIdToLabel(d->cid)); + *v = (double*)d->u.vp; + return kOkDtRC; +} + +cmDtRC_t cmDataStrArray( const cmData_t* d, cmChar_t*** v ) +{ +} + +cmDtRC_t cmDataConstStrArray( const cmData_t* d, const cmChar_t*** v ) +{ +} + + + + +//---------------------------------------------------------------------------- +// Structure related functions +// + + +void cmDataFree( cmData_t* p ) +{ + _cmDataFree(p); +} + +cmData_t* cmDataUnlink( cmData_t* p ) +{ + if( p->parent == NULL ) + return p; + + assert( cmDataIsStruct(p->parent) ); + + cmData_t* cp = p->u.child; + cmData_t* pp = NULL; + for(; cp!=NULL; cp=cp->sibling) + if( cp == p ) + { + if( pp == NULL ) + p->parent->u.child = p->sibling; + else + pp->sibling = cp->sibling; + } + return p; +} + +void cmDataUnlinkAndFree( cmData_t* p ) +{ + cmDataUnlink(p); + cmDataFree(p); +} + +cmDtRC_t _cmDataDupl( const cmData_t* d, cmData_t* parent, cmData_t** ref ) +{ + cmData_t* rp = NULL; + + *ref = NULL; + + switch( d->cid ) + { + case kScalarDtId: + if( d->tid == kBlobDtId || d->tid == kStrDtId ) + rc = cmDataNewScalar(parent, d->tid, d->flags, d->u.vp, d->cnt, &rp ); + else + rc = cmDataNewScalar(parent, d->tid, d->flags, d->u.vp, 0, &rp ); + break; + + case kArrayDtId: + rc = cmDataNewArray(parent, d->tid, d->u.vp, d->cnt, d->flags, &rp ); + break; + + case kListDtId: + case kPairDtId: + case kRecordDtId: + { + rp = _cmDataAllocNode(parent,d->tid); + cmData_t* cp = d->u.child; + for(; cp!=NULL; cp=cd->sibling) + cmDataAppendChild(rp,_cmDataDupl(cp,rp)); + } + break; + + default: + assert(0); + break; + } + + if( rp != NULL ) + *ref = rp; + + return rc; + + /* + cmData_t* rp = NULL; + + switch( p->tid ) + { + case kNullDtId: rp = cmDataAllocNull(parent); break; + case kUCharDtId: rp = cmDataAllocUChar(parent,p->u.uc); break; + case kCharDtId: rp = cmDataAllocChar(parent,p->u.c); break; + case kUShortDtId: rp = cmDataAllocShort(parent,p->u.us); break; + case kShortDtId: rp = cmDataAllocUShort(parent,p->u.s); break; + case kUIntDtId: rp = cmDataAllocUInt(parent,p->u.i); break; + case kIntDtId: rp = cmDataAllocInt(parent,p->u.ui); break; + case kULongDtId: rp = cmDataAllocULong(parent,p->u.ul); break; + case kLongDtId: rp = cmDataAllocLong(parent,p->u.l); break; + case kFloatDtId: rp = cmDataAllocFloat(parent,p->u.f); break; + case kDoubleDtId: rp = cmDataAllocDouble(parent,p->u.d); break; + + + case kStrDtId: rp = cmDataStrAlloc(parent,p->u.z); break; + case kConstStrDtId: rp = cmDataConstStrAlloc(parent,p->u.cz); break; + + case kUCharPtrDtId: rp = cmDataUCharAllocPtr(parent,p->u.ucp,p->cnt); break; + case kCharPtrDtId: rp = cmDataCharAllocPtr(parent,p->u.cp,p->cnt); break; + case kUShortPtrDtId: rp = cmDataUShortAllocPtr(parent,p->u.usp,p->cnt); break; + case kShortPtrDtId: rp = cmDataShortAllocPtr(parent,p->u.sp,p->cnt); break; + case kUIntPtrDtId: rp = cmDataUIntAllocPtr(parent,p->u.uip,p->cnt); break; + case kIntPtrDtId: rp = cmDataIntAllocPtr(parent,p->u.ip,p->cnt); break; + case kULongPtrDtId: rp = cmDataULongAllocPtr(parent,p->u.ulp,p->cnt); break; + case kLongPtrDtId: rp = cmDataLongAllocPtr(parent,p->u.lp,p->cnt); break; + case kFloatPtrDtId: rp = cmDataFloatAllocPtr(parent,p->u.fp,p->cnt); break; + case kDoublePtrDtId: rp = cmDataDoubleAllocPtr(parent,p->u.dp,p->cnt); break; + case kVoidPtrDtId: rp = cmDataVoidAllocPtr(parent,p->u.vp,p->cnt); break; + + case kListDtId: + case kPairDtId: + case kRecordDtId: + { + rp = _cmDataAllocNode(parent,p->tid); + cmData_t* cp = p->u.child; + for(; cp!=NULL; cp=cp->sibling) + cmDataAppendChild(rp,_cmDataDupl(cp,rp)); + } + break; + + default: + assert(0); + } + + return rp; + */ +} + +cmData_t* cmDataDupl( const cmData_t* p ) +{ return _cmDataDupl(p,NULL); } + +cmData_t* cmDataReplace( cmData_t* dst, cmData_t* src ) +{ + if( dst->parent == NULL ) + { + cmDataUnlinkAndFree(dst); + src->parent = NULL; + return src; + } + + cmData_t* parent = dst->parent; + cmData_t* cp = parent->u.child; + cmData_t* pp = NULL; + unsigned i = 0; + unsigned n = cmDataChildCount(parent); + + // locate dst's right sibling + for(i=0; isibling) + { + + if( cp == dst ) + { + // link in 'src' in place of 'dst' + src->sibling = dst->sibling; + + // free dst + cmDataUnlinkAndFree(dst); + + // update the sibling link to + if( pp == NULL ) + parent->u.child = src; + else + pp->sibling = src; + + src->parent = parent; + break; + } + pp = cp; + } + return src; +} + + +unsigned cmDataChildCount( const cmData_t* p ) +{ + if( !cmDataIsStruct(p) ) + return 0; + + unsigned n = 0; + const cmData_t* cp = p->u.child; + for(; cp!=NULL; cp=cp->sibling) + ++n; + + return n; +} + +cmData_t* cmDataChild( cmData_t* p, unsigned index ) +{ + if( !cmDataIsStruct(p) ) + return NULL; + + unsigned n = 0; + cmData_t* cp = p->u.child; + for(; cp!=NULL; cp=cp->sibling) + { + if( n == index ) + break; + ++n; + } + + return cp; +} + +cmData_t* cmDataPrependChild(cmData_t* parent, cmData_t* p ) +{ + assert( cmDataIsStruct(p) ); + + + cmDataUnlink(p); + + p->u.child = parent->u.child; + parent->u.child = p; + p->parent = parent; + return p; +} + +cmData_t* cmDataAppendChild( cmData_t* parent, cmData_t* p ) +{ + assert( cmDataIsStruct(parent) ); + assert( parent->cid != kRecordDtId || (parent->cid == kRecordDtId && p->cid==kPairDtId)); + + cmDataUnlink(p); + + cmData_t* cp = parent->u.child; + if( cp == NULL ) + parent->u.child = p; + else + { + for(; cp!=NULL; cp=cp->sibling) + if( cp->sibling == NULL ) + { + cp->sibling = p; + break; + } + } + + p->parent = parent; + p->sibling = NULL; + return p; +} + +cmData_t* cmDataInsertChild( cmData_t* parent, unsigned index, cmData_t* p ) +{ + if( !cmDataIsStruct(parent) ) + return NULL; + + cmDataUnlink(p); + + unsigned n = 0; + cmData_t* cp = parent->u.child; + cmData_t* pp = NULL; + for(; cp!=NULL; cp=cp->sibling) + { + if( n == index ) + { + if( pp == NULL ) + { + parent->u.child = p; + p->sibling = NULL; + } + else + { + p->sibling = pp->sibling; + pp->sibling = p; + } + break; + + } + ++n; + } + + p->parent = parent; + + return p; + +} + + +void cmDataTest( cmCtx_t* ctx ) +{ + +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////// +#ifdef NOT_DEF cmDtRC_t _cmDataErrNo = kOkDtRC; cmData_t cmDataNull = { kInvalidDtId,0,NULL,NULL,0 }; @@ -2985,4 +4297,4 @@ void cmDataTest( cmCtx_t* ctx ) cmRptPrintf(&ctx->rpt,"Done!.\n"); } - +#endif diff --git a/cmData.h b/cmData.h index 38b3e5f..86db015 100644 --- a/cmData.h +++ b/cmData.h @@ -5,30 +5,433 @@ extern "C" { #endif + /* + TODO: + 0) Figure out a error handling scheme that does not rely on + a global errno. This is not useful in multi-thread environments. + It might be ok to go with an 'all errors are fatal' model + (except in the var-args functions). + Consider the use of a context object for use with functions + that can have runtime errors or need to allocate memory. + + 1) Implement the canConvert and willTruncate functions. + + 2) Make a set of cmDataAllocXXXPtr() functions which take + a flag indicating whether or not to dynamically allocate + the array space. This will allow dynamic allocattion to + occur at runtime. Make var args functions for list and + record objects which also take this flag. + Whereever a function may be implemented using + static/dynamic allocation this flag should be present. + (e.g. string allocation for pair labels) + This choice is common enough that it may be worth + suffixing function names with a capital letter to + be clear what the functions memory policy is. + + 3) Come up with a var-args format which allows a + hierchy of records to be defined in one line. + + 4) Implement the serialization functions. + + 5) Implement an ascii string/parse format for writing/reading. + + 6) Implement fast lookup of record fields. + + 7) Allow for user defined types. For example a 'matrix' + data type. This might be as simple as adding an extra 'user_tid' + field to cmData_t. + + 8) Implement type specific cmDataGetRecordValueXXX() functions. + + 9) Implement cmDataIsEqual(), cmDataIsLtE(), ... + + */ + enum { kOkDtRC = cmOkRC, + kAssertErrDtRC, + kConstErrDtRC, kCvtErrDtRC, - kVarArgErrDtRC, - kMissingFieldDtRC, - kLexFailDtRC, - kParseStackFailDtRC, - kSyntaxErrDtRC, + kInvalidContDtRC, + kInvalidTypeDtRC, kEolDtRC }; + typedef unsigned cmDtRC_t; + + typedef enum + { + kInvalidTypeDtId,// 0 + kNullDtId, // 1 the data object exists but it has no data + kUCharDtId, // 2 + kCharDtId, // 3 + kUShortDtId, // 4 + kShortDtId, // 5 + kUIntDtId, // 6 + kIntDtId, // 7 + kULongDtId, // 8 + kLongDtId, // 9 + kFloatDtId, // 10 + kDoubleDtId, // 11 + kStrDtId, // 12 zero terminated string + kBlobDtId // 13 application defined raw memory object + } cmDataTypeId_t; + + + typedef enum + { + kInvalidCntDtId, // 0 + kScalarDtId, // 1 + kArrayDtId, // 2 + kPairDtId, // 3 + kListDtId, // 4 + kRecordDtId // 5 + } cmDataContainerId_t; + enum { - kInvalidDtChar = 0xff, - kInvalidDtUChar = 0xff, - kInvalidDtShort = 0xffff, - kInvalidDtUShort = 0xffff, - kInvalidDtInt = 0xffffffff, - kInvalidDtUInt = 0xffffffff, - kInvalidDtLong = 0xffffffff, - kInvalidDtULong = 0xffffffff, + kNoFlagsDtFl = 0x00, + + // Indicate that the memory used by the data object + // was dynamically allocated and should be released + // by cmDataFree(). + kFreeObjDtFl = 0x01, + + // Indicate that the memory used by strings, blobs + // and arrays should be freed by cmDataFree(). + kFreeValueDtFl = 0x02, + + // Indicate that the value of the object cannot be changed. + // (but the object could be reassigned as a new type). + kConstValueDtFl = 0x04, + + // Indicate that the type of the object cannot be changed. + // (but the value may be changed). + kConstObjDtFl = 0x08, + + // Indicate that the array or string should not be + // internally reallocated but rather the source pointer + // should be taken as the new value of the object. + kNoCopyDtFl = 0x10, + + }; + + typedef struct cmData_str + { + cmDataTypeId_t tid; // data format id + cmDataContainerId_t cid; // container id + unsigned flags; // + struct cmData_str* parent; // this childs parent + struct cmData_str* sibling; // this childs left sibling + unsigned cnt; // byte cnt for strings/blobs and ele count for arrays + + union + { + char c; + unsigned char uc; + short s; + unsigned short us; + int i; + unsigned int ui; + long l; + unsigned long ul; + float f; + double d; + + cmChar_t* z; + + void* vp; + + char* cp; + unsigned char* ucp; + short* sp; + unsigned short* usp; + int* ip; + unsigned int* uip; + long* lp; + unsigned long* ulp; + float* fp; + double* dp; + + + struct cmData_str* child; // first child (list,record,pair) + } u; + + } cmData_t; + + extern cmData_t cmDataNull; + + const cmChar_t* cmDataTypeToLabel( cmDataTypeId_t tid ); + cmDataTypeId_t cmDataLabelToType( const cmChar_t* typeLabelStr ); + + // Returns 1 for kStrDtId. + // Returns cmInvalidCnt if tid is not recognized. + unsigned dmDataByteWidth( cmDataTypeId_t tid ); + + const cmChar_t* cmDataContainerIdToLabel( cmDataContainerId_t tid ); + cmDataContainerId_t cmDataLabelToContainerId( const cmChar_t* contLabelStr ); + + bool cmDataIsConstObj( const cmData_t* d ); + void cmDataEnableConstObj( cmData_t* d, bool enaFl ); + + bool cmDataIsConstValue( const cmData_t* d ); + void cmDataEnableConstValue( cmData_t* d, bool enaFl ); + + bool cmDataIsFreeValue( const cmData_t* d ); + void cmDataEnableFreeValue( cmData_t* d, bool enaFl ); + + // Returns true if this is a scalar or array node. + bool cmDataIsLeaf( const cmData_t* d); + + // Return true if this is NOT a scalar or array node. + bool cmDataIsStruct( const cmData_t* d ); + + + + //---------------------------------------------------------------------------- + // Scalar related functions + // + + // Dynamically allocate a scalar object and set it's value. + // The 'flags' argument may include kConstValueDtFl and kConstObjDtFl. + // The string and blob constructors may also use the + // kNoCopyDtFl and the kFreeValueDtFl. + + // Generic: + // 'byteCnt' is ignored for all types other than strings and blobs. + cmDtRC_t cmDataNewScalar( cmData_t* parent, cmDataTypeId_t tid, unsigned flags, void* vp, unsigned byteCnt, cmData_t** ref ); + + // Type specific + cmDtRC_t cmDataNewNull( cmData_t* parent, unsigned flags, cmData_t** ref ); + cmDtRC_t cmDataNewChar( cmData_t* parent, unsigned flags, char v, cmData_t** ref ); + cmDtRC_t cmDataNewUChar( cmData_t* parent, unsigned flags, unsigned char v, cmData_t** ref ); + cmDtRC_t cmDataNewShort( cmData_t* parent, unsigned flags, short v, cmData_t** ref ); + cmDtRC_t cmDataNewUShort( cmData_t* parent, unsigned flags, unsigned short v, cmData_t** ref ); + cmDtRC_t cmDataNewInt( cmData_t* parent, unsigned flags, int v, cmData_t** ref ); + cmDtRC_t cmDataNewUInt( cmData_t* parent, unsigned flags, unsigned int v, cmData_t** ref ); + cmDtRC_t cmDataNewLong( cmData_t* parent, unsigned flags, long v, cmData_t** ref ); + cmDtRC_t cmDataNewULong( cmData_t* parent, unsigned flags, unsigned long v, cmData_t** ref ); + cmDtRC_t cmDataNewFloat( cmData_t* parent, unsigned flags, float v, cmData_t** ref ); + cmDtRC_t cmDataNewDouble( cmData_t* parent, unsigned flags, double v, cmData_t** ref ); + cmDtRC_t cmDataNewStr( cmData_t* parent, unsigned flags, cmChar_t* str, cmData_t** ref ); + cmDtRC_t cmDataNewConstStr( cmData_t* parent, unsigned flags, const cmChar_t* str, cmData_t** ref ); + cmDtRC_t cmDataNewStrN( cmData_t* parent, unsigned flags, cmChar_t* str, unsigned charCnt, cmData_t** ref ); + cmDtRC_t cmDataNewConstStrN(cmData_t* parent, unsigned flags, const cmChar_t* str, unsigned charCnt, cmData_t** ref ); + cmDtRC_t cmDataNewBlob( cmData_t* parent, unsigned flags, void* vp, unsigned byteCnt, cmData_t** ref ); + cmDtRC_t cmDataNewConstBlob(cmData_t* parent, unsigned flags, const void* vp, unsigned byteCnt, cmData_t** ref ); + + + + // Set the value and type of an existing scalar object. + // These functions begin by releasing any resources held by *p + // prior to resetting the type and value of the object. + // The 'flags' argument to cmDataSetStr() and cmDataSetConstStr() + // may use the kNoCopyDtFl and the kFreeValueDtFl + cmDtRC_t cmDataSetScalarValue( cmData_t* d, cmDataTypeId_t tid, void* vp, unsigned byteCnt, unsigned flags ); + + cmDtRC_t cmDataSetNull( cmData_t* p ); + cmDtRC_t cmDataSetChar( cmData_t* p, char v ); + cmDtRC_t cmDataSetUChar( cmData_t* p, unsigned char v ); + cmDtRC_t cmDataSetShort( cmData_t* p, short v ); + cmDtRC_t cmDataSetUShort( cmData_t* p, unsigned short v ); + cmDtRC_t cmDataSetInt( cmData_t* p, int v ); + cmDtRC_t cmDataSetUInt( cmData_t* p, unsigned int v ); + cmDtRC_t cmDataSetLong( cmData_t* p, long v ); + cmDtRC_t cmDataSetULong( cmData_t* p, unsigned long v ); + cmDtRC_t cmDataSetFloat( cmData_t* p, float v ); + cmDtRC_t cmDataSetDouble( cmData_t* p, double v ); + cmDtRC_t cmDataSetStr( cmData_t* p, unsigned flags, cmChar_t* s ); + cmDtRC_t cmDataSetConstStr( cmData_t* p, unsigned flags, const cmChar_t* s ); + cmDtRC_t cmDataSetStrN( cmData_t* p, unsigned flags, cmChar_t* s, unsigned charCnt ); + cmDtRC_t cmDataSetConstStrN( cmData_t* p, unsigned flags, const cmChar_t* s, unsigned charCnt ); + cmDtRC_t cmDataSetBlob( cmData_t* p, unsigned flags, void* v, unsigned byteCnt ); + cmDtRC_t cmDataSetConstBlob( cmData_t* p, unsigned flags, const void* v, unsigned byteCnt ); + + // Get the value of an object. No conversion is applied the + // type must match exactly or an error is generated. + cmDtRC_t cmDataChar( const cmData_t* p, char* v ); + cmDtRC_t cmDataUChar( const cmData_t* p, unsigned char* v ); + cmDtRC_t cmDataShort( const cmData_t* p, short* v ); + cmDtRC_t cmDataUShort( const cmData_t* p, unsigned short* v ); + cmDtRC_t cmDataInt( const cmData_t* p, int* v ); + cmDtRC_t cmDataUInt( const cmData_t* p, unsigned int* v ); + cmDtRC_t cmDataLong( const cmData_t* p, long* v ); + cmDtRC_t cmDataULong( const cmData_t* p, unsigned long* v ); + cmDtRC_t cmDataFloat( const cmData_t* p, float* v ); + cmDtRC_t cmDataDouble( const cmData_t* p, double* v ); + cmDtRC_t cmDataStr( const cmData_t* p, cmChar_t** v ); + cmDtRC_t cmDataConstStr( const cmData_t* p, const cmChar_t** v ); + cmDtRC_t cmDataBlob( const cmData_t* p, cmChar_t** v, unsigned* byteCntRef ); + cmDtRC_t cmDataConstBlob( const cmData_t* p, const cmChar_t** v, unsigned* byteCntRef ); + + // Get the value of an object with conversion. + cmDtRC_t cmDataGetChar( const cmData_t* p, char* v ); + cmDtRC_t cmDataGetUChar( const cmData_t* p, unsigned char* v ); + cmDtRC_t cmDataGetShort( const cmData_t* p, short* v ); + cmDtRC_t cmDataGetUShort( const cmData_t* p, unsigned short* v ); + cmDtRC_t cmDataGetInt( const cmData_t* p, int* v ); + cmDtRC_t cmDataGetUInt( const cmData_t* p, unsigned int* v ); + cmDtRC_t cmDataGetLong( const cmData_t* p, long* v ); + cmDtRC_t cmDataGetULong( const cmData_t* p, unsigned long* v ); + cmDtRC_t cmDataGetFloat( const cmData_t* p, float* v ); + cmDtRC_t cmDataGetDouble( const cmData_t* p, double* v ); + + + //---------------------------------------------------------------------------- + // Array related functions + // + + // Notes: + // 1) string arrays are arrays of string pointers. + // 2) blob arrays (array of void pointers) are not supported because + // there is no direct way to determine the length of each blob + // and therefore they cannot be internally duplicated - a special scheme + // could be devised (length goes in first 4 bytes) to make this + // work but we will defer that until the need arises. + + // + // Dynamically allocate a new array data object. + // + // eleCnt referes to the number of elements in the array pointed + // to by 'vp'. The number of bytes pointed to by 'vp' is then + // cmDataByteWidth(tid)*eleCnt. + // + // If no flags are set then the array pointed to by 'vp' is reallocated + // and kDataFreeDtFl is set. + // + // If kFreeValueDtFl is set then the object will take responsibility for + // releasing the memory pointed to by 'vp' when the object is destroyed + // or the array is reassigned. + // + // If kNoCopyDtFl is set then 'vp' becomes the internal array + // value (vp[cnt]) is NOT reallocated). In this case the client is + // responsibile for eventually releasing the associated memory - when + // the data object is no longer valid. + cmDtRC_t cmDataNewArray( cmData_t* parent, cmDataTypeId_t tid, void* vp, unsigned eleCnt, unsigned flags, cmData_t** ref ); + + cmDtRC_t cmDataNewCharArray( cmData_t* parent, char* v, unsigned eleCnt, unsigned flags, cmData_t** ref ); + cmDtRC_t cmDataNewUCharArray( cmData_t* parent, unsigned char* v, unsigned eleCnt, unsigned flags, cmData_t** ref ); + cmDtRC_t cmDataNewShortArray( cmData_t* parent, short* v, unsigned eleCnt, unsigned flags, cmData_t** ref ); + cmDtRC_t cmDataNewUShortArray( cmData_t* parent, unsigned short* v, unsigned eleCnt, unsigned flags, cmData_t** ref ); + cmDtRC_t cmDataNewIntArray( cmData_t* parent, int* v, unsigned eleCnt, unsigned flags, cmData_t** ref ); + cmDtRC_t cmDataNewUIntArray( cmData_t* parent, unsigned int* v, unsigned eleCnt, unsigned flags, cmData_t** ref ); + cmDtRC_t cmDataNewLongArray( cmData_t* parent, long* v, unsigned eleCnt, unsigned flags, cmData_t** ref ); + cmDtRC_t cmDataNewULongArray( cmData_t* parent, unsigned long* v, unsigned eleCnt, unsigned flags, cmData_t** ref ); + cmDtRC_t cmDataNewFloatArray( cmData_t* parent, float* v, unsigned eleCnt, unsigned flags, cmData_t** ref ); + cmDtRC_t cmDataNewDoubleArray( cmData_t* parent, double* v, unsigned eleCnt, unsigned flags, cmData_t** ref ); + cmDtRC_t cmDataNewStrArray( cmData_t* parent, cmChar_t** v, unsigned eleCnt, unsigned flags, cmData_t** ref ); + cmDtRC_t cmDataNewConstStrArray( cmData_t* parent, const cmChar_t** v,unsigned eleCnt, unsigned flags, cmData_t** ref ); + + // Set the value and type of an existing scalar object. + // + // These functions begin by releasing any resources held by *p + // prior to resetting the type and value of the object. + // The 'flags' argument may include kConstValueDtFl, kConstObjDtFl, + // kNoCopyDtFl and the kFreeValueDtFl. + + // Generic set array functions. 'vp' is assumed to point to an array + // of the type defined by 'tid'. + cmDtRC_t cmDataSetArrayValue( cmData_t* dt, cmDataTypeId_t tid, void* vp, unsigned eleCnt, unsigned flags ); + + // Type sepctific set array functions. + cmDtRC_t cmDataSetCharArray( cmData_t* d, char* v, unsigned eleCnt, unsigned flags ); + cmDtRC_t cmDataSetUCharArray( cmData_t* d, unsigned char* v, unsigned eleCnt, unsigned flags ); + cmDtRC_t cmDataSetShortArray( cmData_t* d, short* v, unsigned eleCnt, unsigned flags ); + cmDtRC_t cmDataSetUShortArray( cmData_t* d, unsigned short* v, unsigned eleCnt, unsigned flags ); + cmDtRC_t cmDataSetIntArray( cmData_t* d, int* v, unsigned eleCnt, unsigned flags ); + cmDtRC_t cmDataSetUIntArray( cmData_t* d, unsigned int* v, unsigned eleCnt, unsigned flags ); + cmDtRC_t cmDataSetLongArray( cmData_t* d, long* v, unsigned eleCnt, unsigned flags ); + cmDtRC_t cmDataSetULongArray( cmData_t* d, unsigned long* v, unsigned eleCnt, unsigned flags ); + cmDtRC_t cmDataSetFloatArray( cmData_t* d, float* v, unsigned eleCnt, unsigned flags ); + cmDtRC_t cmDataSetDoubleArray( cmData_t* d, double* v, unsigned eleCnt, unsigned flags ); + cmDtRC_t cmDataSetStrArray( cmData_t* d, cmChar_t** v, unsigned eleCnt, unsigned flags ); + cmDtRC_t cmDataSetConstStrArray(cmData_t* d,const cmChar_t** v,unsigned eleCnt, unsigned flags ); + + // Return the count of elements in a n array. + unsigned cmDataArrayEleCount( const cmData_t* d ); + + // Get a pointer to the base of an array. + // The type must match exactly or an error is generated. + // Use cmDataEleCount() to determine the number of elements in the array. + cmDtRC_t cmDataCharArray( const cmData_t* d, char** v ); + cmDtRC_t cmDataUCharArray( const cmData_t* d, unsigned char** v ); + cmDtRC_t cmDataShortArray( const cmData_t* d, short** v ); + cmDtRC_t cmDataUShortArray( const cmData_t* d, unsigned short** v ); + cmDtRC_t cmDataIntArray( const cmData_t* d, int** v ); + cmDtRC_t cmDataUIntArray( const cmData_t* d, unsigned int** v ); + cmDtRC_t cmDataLongArray( const cmData_t* d, long** v ); + cmDtRC_t cmDataULongArray( const cmData_t* d, unsigned long** v ); + cmDtRC_t cmDataFloatArray( const cmData_t* d, float** v ); + cmDtRC_t cmDataDoubleArray( const cmData_t* d, double** v ); + cmDtRC_t cmDataStrArray( const cmData_t* d, cmChar_t*** v ); + cmDtRC_t cmDataConstStrArray( const cmData_t* d, const cmChar_t*** v ); + + //---------------------------------------------------------------------------- + // Structure related functions + // + + // Release an object and any resources held by it. + // Note the this function does not unlink the object + // from it's parent. Use cmDataUnlinkAndFree() + // to remove a object from it's parent list prior + // to releasing it. + void cmDataFree( cmData_t* p ); + + // Unlink 'p' from its parents and siblings. + // Asserts if parent is not a structure. + // Returns 'p'. + cmData_t* cmDataUnlink( cmData_t* p ); + + // Wrapper function to cmDataUnlink() and cmDataFree(). + void cmDataUnlinkAndFree( cmData_t* p ); + + // Replace the 'dst' node with the 'src' node and + // return 'src'. This operation does not duplicate + // 'src' it simply links in 'src' at the location of + // 'dst' and then unlinks and free's 'dst'. + cmData_t* cmDataReplace( cmData_t* dst, cmData_t* src ); + + // Return the count of child nodes. + // 1. Array nodes have one child per array element. + // 2. List nodes have one child pair. + // 3. Pair nodes have two children. + // 4. Leaf nodes have 0 children. + unsigned cmDataChildCount( const cmData_t* p ); + + // Returns the ith child of 'p'. + // Returns NULL if p has no children or index is invalid. + cmData_t* cmDataChild( cmData_t* p, unsigned index ); + + // Prepend 'p' to 'parents' child list. + // The source node 'p' is not duplicated it is simply linked in. + // 'p' is automatically unlinked prior to being prepended. + // Returns 'p'. + cmData_t* cmDataPrependChild(cmData_t* parent, cmData_t* p ); + + // Append 'p' to the end of 'parent' child list. + // The source node 'p' is not duplicated it is simply linked in. + // 'p' is automatically unlinked prior to being appended. + // Returns 'p'. + cmData_t* cmDataAppendChild( cmData_t* parent, cmData_t* p ); + + // Insert 'p' at index. Index must be in the range: + // 0 to cmDataChildCount(parent). + // The source node 'p' is not duplicated it is simply linked in. + // 'p' is automatically unlinked prior to being inserted. + // Returns 'p'. + cmData_t* cmDataInsertChild( cmData_t* parent, unsigned index, cmData_t* p ); + + + +//////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////// + +#ifdef NOT_DEF typedef enum { kInvalidDtId, @@ -131,47 +534,6 @@ extern "C" { bool cmDataIsPtr( const cmData_t* p ); bool cmDataIsStruct( const cmData_t* p ); // is a pair,list or record - /* - TODO: - 0) Figure out a error handling scheme that does not rely on - a global errno. This is not useful in multi-thread environments. - It might be ok to go with an 'all errors are fatal' model - (except in the var-args functions). - Consider the use of a context object for use with functions - that can have runtime errors or need to allocate memory. - - 1) Implement the canConvert and willTruncate functions. - - 2) Make a set of cmDataAllocXXXPtr() functions which take - a flag indicating whether or not to dynamically allocate - the array space. This will allow dynamic allocattion to - occur at runtime. Make var args functions for list and - record objects which also take this flag. - Where ever a function may be implemented using - static/dynamic allocation this flag should be present. - (e.g. string allocation for pair labels) - This choice is common enough that it may be worth - suffixing function names with a capital letter to - be clear what the functions memory policy is. - - 3) Come up with a var-args format which allows a - hierchy of records to be defined in one line. - - 4) Implement the serialization functions. - - 5) Implement an ascii string/parse format for writing/reading. - - 6) Implement fast lookup of record fields. - - 7) Allow for user defined types. For example a 'matrix' - data type. This might be as simple as adding an extra 'user_tid' - field to cmData_t. - - 8) Implement type specific cmDataGetRecordValueXXX() functions. - - 9) Implement cmDataIsEqual(), cmDataIsLtE(), ... - - */ bool canConvertType( cmDataFmtId_t srcId, cmDataFmtId_t dstId ); bool willTruncate( cmDataFmtId_t srcId, cmDataFmtId_t dstId ); @@ -556,7 +918,7 @@ extern "C" { void cmDataPrint( const cmData_t* p, cmRpt_t* rpt ); void cmDataTest( cmCtx_t* ctx ); - +#endif #ifdef __cplusplus From c809469b6233c50bfce4cb9dfb1d67425b692f51 Mon Sep 17 00:00:00 2001 From: kpl Date: Tue, 19 Nov 2013 00:11:25 -0800 Subject: [PATCH 19/23] cmData.h/c : More changes - that won't fully compile. --- cmData.c | 1756 +++++------------------------------------------------- cmData.h | 354 +---------- 2 files changed, 162 insertions(+), 1948 deletions(-) diff --git a/cmData.c b/cmData.c index d965ab9..b1580f8 100644 --- a/cmData.c +++ b/cmData.c @@ -154,26 +154,13 @@ void _cmDataFree( cmData_t* p ) cmMemFree(p); } -/* -cmData_t* _cmDataAllocNode( cmData_t* parent, cmDataFmtId_t tid ) -{ - cmData_t* p = cmMemAllocZ(cmData_t,1); - p->tid = tid; - p->flags = kDynObjDtFl; - p->parent = parent; - if( parent != NULL ) - return cmDataAppendChild(parent,p); - return p; -} -*/ - -// Dynamically allocate a 'null' data object. -cmDtRC_t _cmDataNew(cmData_t* parent, cmData_t** ref) +// Dynamically allocate a new data object. +cmData_t* _cmDataNew(cmData_t* parent, cmDataContainerId_t cid, cmDataTypeId_t tid) { cmData_t* d = cmMemAllocZ(cmData_t,1); - d->tid = kNullDtId; // objects without data are of type 'null'. - d->cid = kScalarDtId; + d->tid = tid; // objects without data are of type 'null'. + d->cid = cid; d->flags = kFreeObjDtFl; d->parent = parent; d->cnt = 0; @@ -181,8 +168,7 @@ cmDtRC_t _cmDataNew(cmData_t* parent, cmData_t** ref) if( parent != NULL ) cmDataAppendChild(parent,d); - *ref = d; - return kOkDtRC; + return d; } @@ -213,14 +199,13 @@ bool cmDataIsStruct( const cmData_t* d ) cmDtRC_t cmDataNewScalar( cmData_t* parent, cmDataTypeId_t tid, unsigned flags, void* vp, unsigned byteCnt, cmData_t** ref ) { - cmData_t* d = NULL; cmDtRC_t rc; - *ref = NULL; + if( ref != NULL ) + *ref = NULL; // create a scalar null object - if((rc = _cmDataNew(parent,&d)) != kOkDtRC ) - return rc; + cmData_t* d = _cmDataNew(parent,kScalarDtId,kNullDtId); if( tid!=kStrDtId && tid!=kBlobDtId ) { @@ -241,13 +226,14 @@ cmDtRC_t cmDataNewScalar( cmData_t* parent, cmDataTypeId_t tid, unsigned flags, // set the const flags for the new object d->flags = cmSetFlag(d->flags, flags & (kConstValueDtFl | kConstObjDtFl)); - *ref = d; + if( ref != NULL ) + *ref = d; return rc; } cmDtRC_t cmDataNewNull( cmData_t* parent, unsigned flags, cmData_t** ref ) -{ return _cmDataNew(parent, ref); } +{ *ref = _cmDataNew(parent, kScalarDtId, kNullDtId); return kOkDtRC; } cmDtRC_t cmDataNewChar( cmData_t* parent, unsigned flags, char v, cmData_t** ref ) { return cmDataNewScalar(parent,kCharDtId,flags,&v,0,ref); } cmDtRC_t cmDataNewUChar( cmData_t* parent, unsigned flags, unsigned char v, cmData_t** ref ) @@ -807,13 +793,12 @@ cmDtRC_t cmDataGetDouble( const cmData_t* p, double* vp ) cmDtRC_t cmDataNewArray( cmData_t* parent, cmDataTypeId_t tid, void* vp, unsigned eleCnt, unsigned flags, cmData_t** ref ) { cmDtRC_t rc; - cmData_t* d = NULL; - *ref = NULL; + if( ref != NULL ) + *ref = NULL; // create a new 'null' object - if((rc = _cmDataNew(parent, &d)) != kOkDtRC ) - return rc; + cmData_t* d = _cmDataNew(parent, kScalarDtId, kNullDtId ); // assign the value if((rc = cmDataSetArrayValue(d,tid,vp,eleCnt,flags)) != kOkDtRC ) @@ -822,7 +807,8 @@ cmDtRC_t cmDataNewArray( cmData_t* parent, cmDataTypeId_t tid, void* vp, unsigne // set the flags for the new object d->flags = cmSetFlag(d->flags, flags & (kConstValueDtFl | kConstObjDtFl | kNoCopyDtFl)); - *ref = d; + if( ref != NULL ) + *ref = d; return rc; @@ -1072,6 +1058,7 @@ void cmDataUnlinkAndFree( cmData_t* p ) cmDtRC_t _cmDataDupl( const cmData_t* d, cmData_t* parent, cmData_t** ref ) { + cmDtRC_t rc = kOkDtRC; cmData_t* rp = NULL; *ref = NULL; @@ -1093,11 +1080,17 @@ cmDtRC_t _cmDataDupl( const cmData_t* d, cmData_t* parent, cmData_t** ref ) case kPairDtId: case kRecordDtId: { - rp = _cmDataAllocNode(parent,d->tid); - cmData_t* cp = d->u.child; - for(; cp!=NULL; cp=cd->sibling) - cmDataAppendChild(rp,_cmDataDupl(cp,rp)); + rp = _cmDataNew(parent,d->cid,d->tid); + const cmData_t* cp = d->u.child; + for(; cp!=NULL; cp=cp->sibling) + { + cmData_t* ncp = NULL; + // duplicate the child (ncp) and append it to the parent (rp) + if((rc = _cmDataDupl(cp,rp,&ncp)) == kOkDtRC ) + cmDataAppendChild(rp,ncp); + } } + break; default: @@ -1109,61 +1102,10 @@ cmDtRC_t _cmDataDupl( const cmData_t* d, cmData_t* parent, cmData_t** ref ) *ref = rp; return rc; - - /* - cmData_t* rp = NULL; - - switch( p->tid ) - { - case kNullDtId: rp = cmDataAllocNull(parent); break; - case kUCharDtId: rp = cmDataAllocUChar(parent,p->u.uc); break; - case kCharDtId: rp = cmDataAllocChar(parent,p->u.c); break; - case kUShortDtId: rp = cmDataAllocShort(parent,p->u.us); break; - case kShortDtId: rp = cmDataAllocUShort(parent,p->u.s); break; - case kUIntDtId: rp = cmDataAllocUInt(parent,p->u.i); break; - case kIntDtId: rp = cmDataAllocInt(parent,p->u.ui); break; - case kULongDtId: rp = cmDataAllocULong(parent,p->u.ul); break; - case kLongDtId: rp = cmDataAllocLong(parent,p->u.l); break; - case kFloatDtId: rp = cmDataAllocFloat(parent,p->u.f); break; - case kDoubleDtId: rp = cmDataAllocDouble(parent,p->u.d); break; - - - case kStrDtId: rp = cmDataStrAlloc(parent,p->u.z); break; - case kConstStrDtId: rp = cmDataConstStrAlloc(parent,p->u.cz); break; - - case kUCharPtrDtId: rp = cmDataUCharAllocPtr(parent,p->u.ucp,p->cnt); break; - case kCharPtrDtId: rp = cmDataCharAllocPtr(parent,p->u.cp,p->cnt); break; - case kUShortPtrDtId: rp = cmDataUShortAllocPtr(parent,p->u.usp,p->cnt); break; - case kShortPtrDtId: rp = cmDataShortAllocPtr(parent,p->u.sp,p->cnt); break; - case kUIntPtrDtId: rp = cmDataUIntAllocPtr(parent,p->u.uip,p->cnt); break; - case kIntPtrDtId: rp = cmDataIntAllocPtr(parent,p->u.ip,p->cnt); break; - case kULongPtrDtId: rp = cmDataULongAllocPtr(parent,p->u.ulp,p->cnt); break; - case kLongPtrDtId: rp = cmDataLongAllocPtr(parent,p->u.lp,p->cnt); break; - case kFloatPtrDtId: rp = cmDataFloatAllocPtr(parent,p->u.fp,p->cnt); break; - case kDoublePtrDtId: rp = cmDataDoubleAllocPtr(parent,p->u.dp,p->cnt); break; - case kVoidPtrDtId: rp = cmDataVoidAllocPtr(parent,p->u.vp,p->cnt); break; - - case kListDtId: - case kPairDtId: - case kRecordDtId: - { - rp = _cmDataAllocNode(parent,p->tid); - cmData_t* cp = p->u.child; - for(; cp!=NULL; cp=cp->sibling) - cmDataAppendChild(rp,_cmDataDupl(cp,rp)); - } - break; - - default: - assert(0); - } - - return rp; - */ } -cmData_t* cmDataDupl( const cmData_t* p ) -{ return _cmDataDupl(p,NULL); } +cmRC_t cmDataDupl( const cmData_t* p, cmData_t** ref ) +{ return _cmDataDupl(p,NULL,ref); } cmData_t* cmDataReplace( cmData_t* dst, cmData_t* src ) { @@ -1203,6 +1145,7 @@ cmData_t* cmDataReplace( cmData_t* dst, cmData_t* src ) } pp = cp; } + return src; } @@ -1312,1381 +1255,11 @@ cmData_t* cmDataInsertChild( cmData_t* parent, unsigned index, cmData_t* p ) } -void cmDataTest( cmCtx_t* ctx ) -{ - -} - -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -#ifdef NOT_DEF -cmDtRC_t _cmDataErrNo = kOkDtRC; - -cmData_t cmDataNull = { kInvalidDtId,0,NULL,NULL,0 }; - -cmDtRC_t _cmDataSetError( unsigned err ) -{ - _cmDataErrNo = err; - return err; -} - -void _cmDataFreeArray( cmData_t* p ) -{ - if(cmIsFlag(p->flags,kDynPtrDtFl)) - { - cmMemFree(p->u.vp); - p->u.vp = NULL; - p->flags = cmClrFlag(p->flags,kDynPtrDtFl); - } - p->tid = kInvalidDtId; - p->cnt = 0; -} - -void _cmDataFree( cmData_t* p ) -{ - if( p == NULL ) - return; - - if( cmDataIsStruct(p) ) - { - cmData_t* cp = p->u.child; - for(; cp!=NULL; cp=cp->sibling) - _cmDataFree(cp); - } - - _cmDataFreeArray(p); - if( cmIsFlag(p->flags,kDynObjDtFl) ) - cmMemFree(p); -} - -cmData_t* _cmDataAllocNode( cmData_t* parent, cmDataFmtId_t tid ) -{ - cmData_t* p = cmMemAllocZ(cmData_t,1); - p->tid = tid; - p->flags = kDynObjDtFl; - p->parent = parent; - if( parent != NULL ) - return cmDataAppendChild(parent,p); - return p; -} - - -unsigned _cmDataByteCount( const cmData_t* p ) -{ - unsigned n = 0; - - switch( p->tid ) - { - case kInvalidDtId: return 0; - case kNullDtId: return n; - case kUCharDtId: return n + sizeof(unsigned char); - case kCharDtId: return n + sizeof(char); - case kUShortDtId: return n + sizeof(unsigned short); - case kShortDtId: return n + sizeof(short); - case kUIntDtId: return n + sizeof(unsigned int); - case kIntDtId: return n + sizeof(int); - case kULongDtId: return n + sizeof(unsigned long); - case kLongDtId: return n + sizeof(long); - case kFloatDtId: return n + sizeof(float); - case kDoubleDtId: return n + sizeof(double); - - case kStrDtId: return n + (p->u.z ==NULL ? 0 : strlen(p->u.z) + 1); - case kConstStrDtId: return n + (p->u.cz==NULL ? 0 : strlen(p->u.cz) + 1); - - case kUCharPtrDtId: return n + p->cnt * sizeof(unsigned char); - case kCharPtrDtId: return n + p->cnt * sizeof(char); - case kUShortPtrDtId: return n + p->cnt * sizeof(unsigned short); - case kShortPtrDtId: return n + p->cnt * sizeof(short); - case kUIntPtrDtId: return n + p->cnt * sizeof(unsigned int); - case kIntPtrDtId: return n + p->cnt * sizeof(int); - case kULongPtrDtId: return n + p->cnt * sizeof(unsigned long); - case kLongPtrDtId: return n + p->cnt * sizeof(long); - case kFloatPtrDtId: return n + p->cnt * sizeof(float); - case kDoublePtrDtId: return n + p->cnt * sizeof(double); - case kVoidPtrDtId: return n + p->cnt * sizeof(char); - - default: - return n; - } - assert(0); - return 0; -} - -bool cmDataIsValue( const cmData_t* p ) -{ return kMinValDtId <= p->tid && p->tid <= kMaxValDtId; } - -bool cmDataIsPtr( const cmData_t* p ) -{ return kMinPtrDtId <= p->tid && p->tid <= kMaxPtrDtId; } - -bool cmDataIsStruct( const cmData_t* p ) -{ return kMinStructDtId <= p->tid && p->tid <= kMaxStructDtId; } - -char cmDataChar( const cmData_t* p ) { assert(p->tid==kCharDtId); return p->u.c; } -unsigned char cmDataUChar( const cmData_t* p ) { assert(p->tid==kUCharDtId); return p->u.uc; } -short cmDataShort( const cmData_t* p ) { assert(p->tid==kShortDtId); return p->u.s; } -unsigned short cmDataUShort( const cmData_t* p ) { assert(p->tid==kUShortDtId); return p->u.us; } -int cmDataInt( const cmData_t* p ) { assert(p->tid==kIntDtId); return p->u.i; } -unsigned int cmDataUInt( const cmData_t* p ) { assert(p->tid==kUIntDtId); return p->u.ui; } -long cmDataLong( const cmData_t* p ) { assert(p->tid==kLongDtId); return p->u.l; } -unsigned long cmDataULong( const cmData_t* p ) { assert(p->tid==kULongDtId); return p->u.ul; } -float cmDataFloat( const cmData_t* p ) { assert(p->tid==kFloatDtId); return p->u.f; } -double cmDataDouble( const cmData_t* p ) { assert(p->tid==kDoubleDtId); return p->u.d; } -cmChar_t* cmDataStr( const cmData_t* p ) { assert(p->tid==kStrDtId); return p->u.z; } -const cmChar_t* cmDataConstStr( const cmData_t* p ) { assert(p->tid==kConstStrDtId); return p->u.cz; } -void* cmDataVoidPtr( const cmData_t* p ) { assert(p->tid==kVoidPtrDtId); return p->u.vp; } -char* cmDataCharPtr( const cmData_t* p ) { assert(p->tid==kCharPtrDtId); return p->u.cp; } -unsigned char* cmDataUCharPtr( const cmData_t* p ) { assert(p->tid==kUCharPtrDtId); return p->u.ucp; } -short* cmDataShortPtr( const cmData_t* p ) { assert(p->tid==kShortPtrDtId); return p->u.sp; } -unsigned short* cmDataUShortPtr( const cmData_t* p ) { assert(p->tid==kUShortPtrDtId); return p->u.usp; } -int* cmDataIntPtr( const cmData_t* p ) { assert(p->tid==kIntPtrDtId); return p->u.ip; } -unsigned int* cmDataUIntPtr( const cmData_t* p ) { assert(p->tid==kUIntPtrDtId); return p->u.uip; } -long* cmDataLongPtr( const cmData_t* p ) { assert(p->tid==kLongPtrDtId); return p->u.lp; } -unsigned long* cmDataULongPtr( const cmData_t* p ) { assert(p->tid==kULongPtrDtId); return p->u.ulp; } -float* cmDataFloatPtr( const cmData_t* p ) { assert(p->tid==kFloatPtrDtId); return p->u.fp; } -double* cmDataDoublePtr( const cmData_t* p ) { assert(p->tid==kDoublePtrDtId); return p->u.dp; } - -cmDtRC_t cmDataGetUChar( const cmData_t* p, unsigned char* vp ) -{ - switch( p->tid ) - { - case kUCharDtId: *vp = p->u.uc; break; - case kCharDtId: *vp = (unsigned char)p->u.c; break; - case kUShortDtId: *vp = (unsigned char)p->u.us; break; - case kShortDtId: *vp = (unsigned char)p->u.s; break; - case kUIntDtId: *vp = (unsigned char)p->u.ui; break; - case kIntDtId: *vp = (unsigned char)p->u.i; break; - case kULongDtId: *vp = (unsigned char)p->u.ul; break; - case kLongDtId: *vp = (unsigned char)p->u.l; break; - case kFloatDtId: *vp = (unsigned char)p->u.f; break; - case kDoubleDtId: *vp = (unsigned char)p->u.d; break; - default: - return _cmDataSetError(kCvtErrDtRC); - } - return kOkDtRC; -} - -cmDtRC_t cmDataGetChar( const cmData_t* p, char* vp ) -{ - switch( p->tid ) - { - case kUCharDtId: *vp = (char)p->u.uc; break; - case kCharDtId: *vp = p->u.c; break; - case kUShortDtId: *vp = (char)p->u.us; break; - case kShortDtId: *vp = (char)p->u.s; break; - case kUIntDtId: *vp = (char)p->u.ui; break; - case kIntDtId: *vp = (char)p->u.i; break; - case kULongDtId: *vp = (char)p->u.ul; break; - case kLongDtId: *vp = (char)p->u.l; break; - case kFloatDtId: *vp = (char)p->u.f; break; - case kDoubleDtId: *vp = (char)p->u.d; break; - default: - return _cmDataSetError(kCvtErrDtRC); - } - return kOkDtRC; -} - -cmDtRC_t cmDataGetShort( const cmData_t* p, short* vp ) -{ - switch( p->tid ) - { - case kUCharDtId: *vp = (short)p->u.uc; break; - case kCharDtId: *vp = (short)p->u.c; break; - case kUShortDtId: *vp = (short)p->u.us; break; - case kShortDtId: *vp = p->u.s; break; - case kUIntDtId: *vp = (short)p->u.ui; break; - case kIntDtId: *vp = (short)p->u.i; break; - case kULongDtId: *vp = (short)p->u.ul; break; - case kLongDtId: *vp = (short)p->u.l; break; - case kFloatDtId: *vp = (short)p->u.f; break; - case kDoubleDtId: *vp = (short)p->u.d; break; - default: - return _cmDataSetError(kCvtErrDtRC); - } - return kOkDtRC; -} - - -cmDtRC_t cmDataGetUShort( const cmData_t* p, unsigned short* vp ) -{ - switch( p->tid ) - { - case kUCharDtId: *vp = (unsigned short)p->u.uc; break; - case kCharDtId: *vp = (unsigned short)p->u.c; break; - case kUShortDtId: *vp = p->u.us; break; - case kShortDtId: *vp = (unsigned short)p->u.s; break; - case kUIntDtId: *vp = (unsigned short)p->u.ui; break; - case kIntDtId: *vp = (unsigned short)p->u.i; break; - case kULongDtId: *vp = (unsigned short)p->u.ul; break; - case kLongDtId: *vp = (unsigned short)p->u.l; break; - case kFloatDtId: *vp = (unsigned short)p->u.f; break; - case kDoubleDtId: *vp = (unsigned short)p->u.d; break; - default: - return _cmDataSetError(kCvtErrDtRC); - } - return kOkDtRC; -} - -cmDtRC_t cmDataGetInt( const cmData_t* p, int* vp ) -{ - - switch( p->tid ) - { - case kUCharDtId: *vp = (int)p->u.uc; break; - case kCharDtId: *vp = (int)p->u.c; break; - case kUShortDtId: *vp = (int)p->u.us; break; - case kShortDtId: *vp = (int)p->u.s; break; - case kUIntDtId: *vp = (int)p->u.ui; break; - case kIntDtId: *vp = p->u.i; break; - case kULongDtId: *vp = (int)p->u.ul; break; - case kLongDtId: *vp = (int)p->u.l; break; - case kFloatDtId: *vp = (int)p->u.f; break; - case kDoubleDtId: *vp = (int)p->u.d; break; - default: - return _cmDataSetError(kCvtErrDtRC); - } - return kOkDtRC; -} - -cmDtRC_t cmDataGetUInt( const cmData_t* p, unsigned int* vp ) -{ - switch( p->tid ) - { - case kUCharDtId: *vp = (unsigned int)p->u.uc; break; - case kCharDtId: *vp = (unsigned int)p->u.c; break; - case kUShortDtId: *vp = (unsigned int)p->u.us; break; - case kShortDtId: *vp = (unsigned int)p->u.s; break; - case kUIntDtId: *vp = p->u.ui; break; - case kIntDtId: *vp = (unsigned int)p->u.i; break; - case kULongDtId: *vp = (unsigned int)p->u.ul; break; - case kLongDtId: *vp = (unsigned int)p->u.l; break; - case kFloatDtId: *vp = (unsigned int)p->u.f; break; - case kDoubleDtId: *vp = (unsigned int)p->u.d; break; - default: - return _cmDataSetError(kCvtErrDtRC); - } - return kOkDtRC; -} - -cmDtRC_t cmDataGetLong( const cmData_t* p, long* vp ) -{ - switch( p->tid ) - { - case kUCharDtId: *vp = (long)p->u.uc; break; - case kCharDtId: *vp = (long)p->u.c; break; - case kUShortDtId: *vp = (long)p->u.us; break; - case kShortDtId: *vp = (long)p->u.s; break; - case kUIntDtId: *vp = (long)p->u.ui; break; - case kIntDtId: *vp = (long)p->u.i; break; - case kULongDtId: *vp = (long)p->u.ul; break; - case kLongDtId: *vp = p->u.l; break; - case kFloatDtId: *vp = (long)p->u.f; break; - case kDoubleDtId: *vp = (long)p->u.d; break; - default: - return _cmDataSetError(kCvtErrDtRC); - } - return kOkDtRC; -} - -cmDtRC_t cmDataGetULong( const cmData_t* p, unsigned long* vp ) -{ - switch( p->tid ) - { - case kUCharDtId: *vp = (unsigned long)p->u.uc; break; - case kCharDtId: *vp = (unsigned long)p->u.c; break; - case kUShortDtId: *vp = (unsigned long)p->u.us; break; - case kShortDtId: *vp = (unsigned long)p->u.s; break; - case kUIntDtId: *vp = (unsigned long)p->u.ui; break; - case kIntDtId: *vp = (unsigned long)p->u.i; break; - case kULongDtId: *vp = p->u.ul; break; - case kLongDtId: *vp = (unsigned long)p->u.l; break; - case kFloatDtId: *vp = (unsigned long)p->u.f; break; - case kDoubleDtId: *vp = (unsigned long)p->u.d; break; - default: - return _cmDataSetError(kCvtErrDtRC); - } - return kOkDtRC; -} - -cmDtRC_t cmDataGetFloat( const cmData_t* p, float* vp ) -{ - - switch( p->tid ) - { - case kUCharDtId: *vp = (float)p->u.uc; break; - case kCharDtId: *vp = (float)p->u.c; break; - case kUShortDtId: *vp = (float)p->u.us; break; - case kShortDtId: *vp = (float)p->u.s; break; - case kUIntDtId: *vp = (float)p->u.ui; break; - case kIntDtId: *vp = (float)p->u.i; break; - case kULongDtId: *vp = (float)p->u.ul; break; - case kLongDtId: *vp = (float)p->u.l; break; - case kFloatDtId: *vp = p->u.f; break; - case kDoubleDtId: *vp = (float)p->u.d; break; - default: - return _cmDataSetError(kCvtErrDtRC); - } - return kOkDtRC; -} - -cmDtRC_t cmDataGetDouble( const cmData_t* p, double* vp ) -{ - switch( p->tid ) - { - case kUCharDtId: *vp = (double)p->u.uc; break; - case kCharDtId: *vp = (double)p->u.c; break; - case kUShortDtId: *vp = (double)p->u.us; break; - case kShortDtId: *vp = (double)p->u.s; break; - case kUIntDtId: *vp = (double)p->u.ui; break; - case kIntDtId: *vp = (double)p->u.i; break; - case kULongDtId: *vp = (double)p->u.ul; break; - case kLongDtId: *vp = (double)p->u.l; break; - case kFloatDtId: *vp = (double)p->u.f; break; - case kDoubleDtId: *vp = p->u.d; break; - default: - return _cmDataSetError(kCvtErrDtRC); - } - return kOkDtRC; -} - -cmDtRC_t cmDataGetStr( const cmData_t* p, cmChar_t** vp ) -{ - if( p->tid == kStrDtId || p->tid == kConstStrDtId) - { - *vp = (p->tid == kStrDtId || p->tid == kConstStrDtId) ? p->u.z : NULL; - return kOkDtRC; - } - return _cmDataSetError(kCvtErrDtRC); -} - -cmDtRC_t cmDataGetConstStr( const cmData_t* p, const cmChar_t** vp ) -{ - if( p->tid == kStrDtId || p->tid == kConstStrDtId) - { - *vp = (p->tid == kStrDtId || p->tid == kConstStrDtId) ? p->u.cz : NULL; - return kOkDtRC; - } - return _cmDataSetError(kCvtErrDtRC); -} - -cmDtRC_t cmDataGetVoidPtr( const cmData_t* p, void** vp ) -{ - if( kMinPtrDtId <= p->tid && p->tid <= kMaxPtrDtId ) - { - *vp = ( kMinPtrDtId <= p->tid && p->tid <= kMaxPtrDtId ) ? p->u.vp : NULL; - return kOkDtRC; - } - return _cmDataSetError(kCvtErrDtRC); -} - -cmDtRC_t cmDataGetCharPtr( const cmData_t* p, char** vp ) -{ - if( p->tid == kCharPtrDtId || p->tid == kUCharPtrDtId ) - { - *vp = (p->tid == kCharPtrDtId || p->tid == kUCharPtrDtId) ? p->u.cp : NULL; - return kOkDtRC; - } - return _cmDataSetError(kCvtErrDtRC); -} - -cmDtRC_t cmDataGetUCharPtr( const cmData_t* p, unsigned char** vp ) -{ - if( p->tid == kCharPtrDtId || p->tid == kUCharPtrDtId ) - { - *vp = (p->tid == kCharPtrDtId || p->tid == kUCharPtrDtId) ? p->u.ucp : NULL; - return kOkDtRC; - } - return _cmDataSetError(kCvtErrDtRC); -} - -cmDtRC_t cmDataGetShortPtr( const cmData_t* p, short** vp ) -{ - if( p->tid == kShortPtrDtId || p->tid == kUShortPtrDtId ) - { - *vp = (p->tid == kShortPtrDtId || p->tid == kUShortPtrDtId ) ? p->u.sp : NULL; - return kOkDtRC; - } - return _cmDataSetError(kCvtErrDtRC); -} - -cmDtRC_t cmDataGetUShortPtr( const cmData_t* p, unsigned short** vp ) -{ - if( p->tid == kShortPtrDtId || p->tid == kUShortPtrDtId ) - { - *vp = (p->tid == kShortPtrDtId || p->tid == kUShortPtrDtId ) ? p->u.usp : NULL; - return kOkDtRC; - } - return _cmDataSetError(kCvtErrDtRC); -} - -cmDtRC_t cmDataGetIntPtr( const cmData_t* p, int** vp ) -{ - if( p->tid == kIntPtrDtId || p->tid == kUIntPtrDtId ) - { - *vp = (p->tid == kIntPtrDtId || p->tid == kUIntPtrDtId ) ? p->u.ip : NULL; - return kOkDtRC; - } - return _cmDataSetError(kCvtErrDtRC); -} - -cmDtRC_t cmDataGetUIntPtr( const cmData_t* p, unsigned int** vp ) -{ - if( p->tid == kIntPtrDtId || p->tid == kUIntPtrDtId ) - { - *vp = (p->tid == kIntPtrDtId || p->tid == kUIntPtrDtId ) ? p->u.uip : NULL; - return kOkDtRC; - } - return _cmDataSetError(kCvtErrDtRC); -} - -cmDtRC_t cmDataGetLongPtr( const cmData_t* p, long** vp ) -{ - if( p->tid == kLongPtrDtId || p->tid == kULongPtrDtId ) - { - *vp = (p->tid == kLongPtrDtId || p->tid == kULongPtrDtId ) ? p->u.lp : NULL; - return kOkDtRC; - } - return _cmDataSetError(kCvtErrDtRC); -} - -cmDtRC_t cmDataGetULongPtr( const cmData_t* p, unsigned long** vp ) -{ - if( p->tid == kLongPtrDtId || p->tid == kULongPtrDtId ) - { - *vp = (p->tid == kLongPtrDtId || p->tid == kULongPtrDtId ) ? p->u.ulp : NULL; - return kOkDtRC; - } - return _cmDataSetError(kCvtErrDtRC); -} - -cmDtRC_t cmDataGetFloatPtr( const cmData_t* p, float** vp ) -{ - if( p->tid == kFloatPtrDtId ) - { - *vp = p->u.fp; - return kOkDtRC; - } - return _cmDataSetError(kCvtErrDtRC); -} - -cmDtRC_t cmDataGetDoublePtr( const cmData_t* p, double** vp ) -{ - if( p->tid == kDoublePtrDtId ) - { - *vp = p->u.dp; - return kOkDtRC; - } - return _cmDataSetError(kCvtErrDtRC); -} - -// Set the value of an existing data object. -cmData_t* cmDataSetNull( cmData_t* p ) -{ - _cmDataFreeArray(p); - p->tid = kNullDtId; - return p; -} - -cmData_t* cmDataSetChar( cmData_t* p, char v ) -{ - _cmDataFreeArray(p); - p->tid = kCharDtId; - p->u.c = v; - return p; -} - -cmData_t* cmDataSetUChar( cmData_t* p, unsigned char v ) -{ - _cmDataFreeArray(p); - p->tid = kUCharDtId; - p->u.uc = v; - return p; -} - -cmData_t* cmDataSetShort( cmData_t* p, short v ) -{ - _cmDataFreeArray(p); - p->tid = kShortDtId; - p->u.s = v; - return p; -} - -cmData_t* cmDataSetUShort( cmData_t* p, unsigned short v ) -{ - _cmDataFreeArray(p); - p->tid = kUShortDtId; - p->u.us = v; - return p; -} - -cmData_t* cmDataSetInt( cmData_t* p, int v ) -{ - _cmDataFreeArray(p); - p->tid = kCharDtId; - p->u.c = v; - return p; -} - -cmData_t* cmDataSetUInt( cmData_t* p, unsigned int v ) -{ - _cmDataFreeArray(p); - p->tid = kUIntDtId; - p->u.ui = v; - return p; -} - -cmData_t* cmDataSetLong( cmData_t* p, long v ) -{ - _cmDataFreeArray(p); - p->tid = kLongDtId; - p->u.l = v; - return p; -} - -cmData_t* cmDataSetULong( cmData_t* p, unsigned long v ) -{ - _cmDataFreeArray(p); - p->tid = kULongDtId; - p->u.ul = v; - return p; -} - -cmData_t* cmDataSetFloat( cmData_t* p, float v ) -{ - _cmDataFreeArray(p); - p->tid = kFloatDtId; - p->u.f = v; - return p; -} - -cmData_t* cmDataSetDouble( cmData_t* p, double v ) -{ - _cmDataFreeArray(p); - p->tid = kDoubleDtId; - p->u.d = v; - return p; -} - -cmData_t* cmDataSetStr( cmData_t* p, cmChar_t* s ) -{ - _cmDataFreeArray(p); - p->tid = kStrDtId; - p->u.z = s; - return p; -} - -cmData_t* cmDataSetConstStr( cmData_t* p, const cmChar_t* s ) -{ - _cmDataFreeArray(p); - p->tid = kConstStrDtId; - p->u.cz = s; - return p; -} - -// Set the value of an existing data object to an external array. -// The array is not copied. -cmData_t* cmDataSetVoidPtr( cmData_t* p, void* vp, unsigned cnt ) -{ - cmDataSetCharPtr(p,(char*)vp,cnt); - p->tid = kVoidPtrDtId; - return p; -} - -cmData_t* cmDataSetCharPtr( cmData_t* p, char* vp, unsigned cnt ) -{ - _cmDataFreeArray(p); - p->tid = kCharPtrDtId; - p->u.cp = vp; - p->cnt = cnt; - return p; -} - -cmData_t* cmDataSetUCharPtr( cmData_t* p, unsigned char* vp, unsigned cnt ) -{ - _cmDataFreeArray(p); - p->tid = kUCharPtrDtId; - p->u.ucp = vp; - p->cnt = cnt; - return p; -} - -cmData_t* cmDataSetShortPtr( cmData_t* p, short* vp, unsigned cnt ) -{ - _cmDataFreeArray(p); - p->tid = kShortPtrDtId; - p->u.sp = vp; - p->cnt = cnt; - return p; -} - -cmData_t* cmDataSetUShortPtr( cmData_t* p, unsigned short* vp, unsigned cnt ) -{ - _cmDataFreeArray(p); - p->tid = kUShortPtrDtId; - p->u.usp = vp; - p->cnt = cnt; - return p; -} - -cmData_t* cmDataSetIntPtr( cmData_t* p, int* vp, unsigned cnt ) -{ - _cmDataFreeArray(p); - p->tid = kCharPtrDtId; - p->u.ip = vp; - p->cnt = cnt; - return p; -} - -cmData_t* cmDataSetUIntPtr( cmData_t* p, unsigned int* vp, unsigned cnt ) -{ - _cmDataFreeArray(p); - p->tid = kUIntPtrDtId; - p->u.uip = vp; - p->cnt = cnt; - return p; -} - -cmData_t* cmDataSetLongPtr( cmData_t* p, long* vp, unsigned cnt ) -{ - _cmDataFreeArray(p); - p->tid = kLongPtrDtId; - p->u.lp = vp; - p->cnt = cnt; - return p; -} - -cmData_t* cmDataSetULongPtr( cmData_t* p, unsigned long* vp, unsigned cnt ) -{ - _cmDataFreeArray(p); - p->tid = kULongPtrDtId; - p->u.ulp = vp; - p->cnt = cnt; - return p; -} - -cmData_t* cmDataSetFloatPtr( cmData_t* p, float* vp, unsigned cnt ) -{ - _cmDataFreeArray(p); - p->tid = kFloatPtrDtId; - p->u.fp = vp; - p->cnt = cnt; - return p; -} - -cmData_t* cmDataSetDoublePtr( cmData_t* p, double* vp, unsigned cnt ) -{ - _cmDataFreeArray(p); - p->tid = kDoublePtrDtId; - p->u.dp = vp; - p->cnt = cnt; - return p; -} - -// Set the value of an existing array based data object. -// Allocate the internal array and copy the array into it. -cmData_t* cmDataSetStrAllocN( cmData_t* p, const cmChar_t* s, unsigned charCnt ) -{ - if( cmIsFlag(p->flags,kDynPtrDtFl) ) - cmMemResizeStrN(p->u.z,s,charCnt); - else - { - _cmDataFreeArray(p); - p->u.z = cmMemAllocStrN(s,charCnt); - } - p->tid = kStrDtId; - p->flags = cmSetFlag(p->flags,kDynPtrDtFl); - return p; -} - -cmData_t* cmDataSetStrAlloc( cmData_t* p, const cmChar_t* s ) -{ return cmDataSetStrAllocN(p,s,strlen(s)); } - -cmData_t* cmDataSetConstStrAllocN( cmData_t* p, const cmChar_t* s, unsigned charCnt ) -{ return cmDataSetStrAllocN(p,s,charCnt); } - -cmData_t* cmDataSetConstStrAlloc( cmData_t* p, const cmChar_t* s ) -{ return cmDataSetStrAlloc(p,s); } - -cmData_t* cmDataSetVoidAllocPtr( cmData_t* p, const void* vp, unsigned cnt ) -{ return cmDataSetCharAllocPtr(p,(char*)vp,cnt); } - -cmData_t* cmDataSetCharAllocPtr( cmData_t* p, const char* vp, unsigned cnt ) -{ - if( cmIsFlag(p->flags,kDynPtrDtFl) ) - p->u.cp = cmMemResize(char, p->u.cp, cnt ); - else - { - _cmDataFreeArray(p); - p->u.cp = cmMemAlloc(char, cnt ); - } - - memcpy(p->u.cp,vp,sizeof(char)*cnt); - p->tid = kCharPtrDtId; - p->flags = cmSetFlag(p->flags,kDynPtrDtFl); - p->cnt = cnt; - return p; -} - -cmData_t* cmDataSetUCharAllocPtr( cmData_t* p, const unsigned char* vp, unsigned cnt ) -{ - if( cmIsFlag(p->flags,kDynPtrDtFl) ) - p->u.ucp = cmMemResize(unsigned char, p->u.ucp, cnt ); - else - { - _cmDataFreeArray(p); - p->u.ucp = cmMemAlloc(unsigned char, cnt ); - } - memcpy(p->u.ucp,vp,sizeof(unsigned char)*cnt); - p->tid = kUCharPtrDtId; - p->flags = cmSetFlag(p->flags,kDynPtrDtFl); - p->cnt = cnt; - return p; -} - -cmData_t* cmDataSetShortAllocPtr( cmData_t* p, const short* vp, unsigned cnt ) -{ - if( cmIsFlag(p->flags,kDynPtrDtFl) ) - p->u.sp = cmMemResize(short, p->u.sp, cnt ); - else - { - _cmDataFreeArray(p); - p->u.sp = cmMemAlloc(short, cnt ); - } - memcpy(p->u.sp,vp,sizeof(short)*cnt); - p->tid = kShortPtrDtId; - p->flags = cmSetFlag(p->flags,kDynPtrDtFl); - p->cnt = cnt; - return p; -} - -cmData_t* cmDataSetUShortAllocPtr( cmData_t* p, const unsigned short* vp, unsigned cnt ) -{ - if( cmIsFlag(p->flags,kDynPtrDtFl) ) - p->u.usp = cmMemResize(unsigned short, p->u.usp, cnt ); - else - { - _cmDataFreeArray(p); - p->u.usp = cmMemAlloc(unsigned short, cnt ); - } - memcpy(p->u.usp,vp,sizeof(unsigned short)*cnt); - p->tid = kUShortPtrDtId; - p->flags = cmSetFlag(p->flags,kDynPtrDtFl); - p->cnt = cnt; - return p; -} - -cmData_t* cmDataSetIntAllocPtr( cmData_t* p, const int* vp, unsigned cnt ) -{ - if( cmIsFlag(p->flags,kDynPtrDtFl) ) - p->u.ip = cmMemResize(int, p->u.ip, cnt ); - else - { - _cmDataFreeArray(p); - p->u.ip = cmMemAlloc(int, cnt ); - } - memcpy(p->u.ip,vp,sizeof(int)*cnt); - p->tid = kIntPtrDtId; - p->flags = cmSetFlag(p->flags,kDynPtrDtFl); - p->cnt = cnt; - return p; -} - -cmData_t* cmDataSetUIntAllocPtr( cmData_t* p, const unsigned int* vp, unsigned cnt ) -{ - if( cmIsFlag(p->flags,kDynPtrDtFl) ) - p->u.uip = cmMemResize(unsigned int, p->u.uip, cnt ); - else - { - _cmDataFreeArray(p); - p->u.uip = cmMemAlloc(unsigned int, cnt ); - } - memcpy(p->u.uip,vp,sizeof(unsigned int)*cnt); - p->tid = kUIntPtrDtId; - p->flags = cmSetFlag(p->flags,kDynPtrDtFl); - p->cnt = cnt; - return p; -} - - -cmData_t* cmDataSetLongAllocPtr( cmData_t* p, const long* vp, unsigned cnt ) -{ - if( cmIsFlag(p->flags,kDynPtrDtFl) ) - p->u.lp = cmMemResize(long, p->u.lp, cnt ); - else - { - _cmDataFreeArray(p); - p->u.lp = cmMemAlloc(long, cnt ); - } - memcpy(p->u.lp,vp,sizeof(long)*cnt); - p->tid = kLongPtrDtId; - p->flags = cmSetFlag(p->flags,kDynPtrDtFl); - p->cnt = cnt; - return p; -} - - -cmData_t* cmDataSetULongAllocPtr( cmData_t* p, const unsigned long* vp, unsigned cnt ) -{ - if( cmIsFlag(p->flags,kDynPtrDtFl) ) - p->u.ulp = cmMemResize(unsigned long, p->u.ulp, cnt ); - else - { - _cmDataFreeArray(p); - p->u.ulp = cmMemAlloc(unsigned long, cnt ); - } - memcpy(p->u.ulp,vp,sizeof(unsigned long)*cnt); - p->tid = kULongPtrDtId; - p->flags = cmSetFlag(p->flags,kDynPtrDtFl); - p->cnt = cnt; - return p; -} - - -cmData_t* cmDataSetFloatAllocPtr( cmData_t* p, const float* vp, unsigned cnt ) -{ - if( cmIsFlag(p->flags,kDynPtrDtFl) ) - p->u.fp = cmMemResize(float, p->u.fp, cnt ); - else - { - _cmDataFreeArray(p); - p->u.fp = cmMemAlloc(float, cnt ); - } - memcpy(p->u.fp,vp,sizeof(float)*cnt); - p->tid = kFloatPtrDtId; - p->flags = cmSetFlag(p->flags,kDynPtrDtFl); - p->cnt = cnt; - return p; -} - - -cmData_t* cmDataSetDoubleAllocPtr( cmData_t* p, const double* vp, unsigned cnt ) -{ - if( cmIsFlag(p->flags,kDynPtrDtFl) ) - p->u.dp = cmMemResize(double, p->u.dp, cnt ); - else - { - _cmDataFreeArray(p); - p->u.dp = cmMemAlloc(double, cnt ); - } - memcpy(p->u.dp,vp,sizeof(double)*cnt); - p->tid = kDoublePtrDtId; - p->flags = cmSetFlag(p->flags,kDynPtrDtFl); - p->cnt = cnt; - return p; -} - - - -// Dynamically allocate a data object and set it's value. -cmData_t* cmDataAllocNull( cmData_t* parent ) -{ return _cmDataAllocNode(parent,kNullDtId); } - -cmData_t* cmDataAllocChar( cmData_t* parent, char v ) -{ - cmData_t* p = _cmDataAllocNode(parent,kCharDtId); - cmDataSetChar(p,v); - return p; -} - -cmData_t* cmDataAllocUChar( cmData_t* parent, unsigned char v ) -{ - cmData_t* p = _cmDataAllocNode(parent,kUCharDtId); - cmDataSetUChar(p,v); - return p; -} - -cmData_t* cmDataAllocShort( cmData_t* parent, short v ) -{ - cmData_t* p = _cmDataAllocNode(parent,kShortDtId); - cmDataSetShort(p,v); - return p; -} - -cmData_t* cmDataAllocUShort( cmData_t* parent, unsigned short v ) -{ - cmData_t* p = _cmDataAllocNode(parent,kUShortDtId); - cmDataSetUShort(p,v); - return p; -} - -cmData_t* cmDataAllocInt( cmData_t* parent, int v ) -{ - cmData_t* p = _cmDataAllocNode(parent,kIntDtId); - cmDataSetInt(p,v); - return p; -} - -cmData_t* cmDataAllocUInt( cmData_t* parent, unsigned int v ) -{ - cmData_t* p = _cmDataAllocNode(parent,kUIntDtId); - cmDataSetUInt(p,v); - return p; -} - -cmData_t* cmDataAllocLong( cmData_t* parent, long v ) -{ - cmData_t* p = _cmDataAllocNode(parent,kLongDtId); - cmDataSetLong(p,v); - return p; -} - -cmData_t* cmDataAllocULong( cmData_t* parent, unsigned long v ) -{ - cmData_t* p = _cmDataAllocNode(parent,kULongDtId); - cmDataSetULong(p,v); - return p; -} - -cmData_t* cmDataAllocFloat( cmData_t* parent, float v ) -{ - cmData_t* p = _cmDataAllocNode(parent,kFloatDtId); - cmDataSetFloat(p,v); - return p; -} - -cmData_t* cmDataAllocDouble( cmData_t* parent, double v ) -{ - cmData_t* p = _cmDataAllocNode(parent,kDoubleDtId); - cmDataSetDouble(p,v); - return p; -} - - -// Dynamically allocate a data object and set its array value to an external -// array. The data is not copied. -cmData_t* cmDataAllocStr( cmData_t* parent, cmChar_t* str ) -{ - cmData_t* p = _cmDataAllocNode(parent,kStrDtId); - cmDataSetStr(p,str); - return p; -} - -cmData_t* cmDataAllocConstStr( cmData_t* parent, const cmChar_t* str ) -{ - cmData_t* p = _cmDataAllocNode(parent,kConstStrDtId); - cmDataSetConstStr(p,str); - return p; -} - -cmData_t* cmDataAllocCharPtr( cmData_t* parent, char* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kCharPtrDtId); - cmDataSetCharPtr(p,(char*)v,cnt); - return p; -} - -cmData_t* cmDataAllocUCharPtr( cmData_t* parent, unsigned char* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kUCharPtrDtId); - cmDataSetUCharPtr(p,(unsigned char*)v,cnt); - return p; -} - -cmData_t* cmDataAllocShortPtr( cmData_t* parent, short* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kShortPtrDtId); - cmDataSetShortPtr(p,(short*)v,cnt); - return p; -} - -cmData_t* cmDataAllocUShortPtr( cmData_t* parent, unsigned short* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kUShortPtrDtId); - cmDataSetUShortPtr(p,(unsigned short*)v,cnt); - return p; -} - -cmData_t* cmDataAllocIntPtr( cmData_t* parent, int* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kIntPtrDtId); - cmDataSetIntPtr(p,(int*)v,cnt); - return p; -} - -cmData_t* cmDataAllocUIntPtr( cmData_t* parent, unsigned int* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kUIntPtrDtId); - cmDataSetUIntPtr(p,(unsigned int*)v,cnt); - return p; -} - -cmData_t* cmDataAllocLongPtr( cmData_t* parent, long* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kLongPtrDtId); - cmDataSetLongPtr(p,(long*)v,cnt); - return p; -} - -cmData_t* cmDataAllocULongPtr( cmData_t* parent, unsigned long* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kULongPtrDtId); - cmDataSetULongPtr(p,(unsigned long*)v,cnt); - return p; -} - -cmData_t* cmDataAllocFloatPtr( cmData_t* parent, float* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kFloatPtrDtId); - cmDataSetFloatPtr(p,(float*)v,cnt); - return p; -} - -cmData_t* cmDataAllocDoublePtr( cmData_t* parent, double* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kDoublePtrDtId); - cmDataSetDoublePtr(p,(double*)v,cnt); - return p; -} - -cmData_t* cmDataAllocVoidPtr( cmData_t* parent, void* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kVoidPtrDtId); - cmDataSetCharPtr(p,(char*)v,cnt); - p->tid = kVoidPtrDtId; - return p; -} - - - -// Dynamically allocate a data object and its array value. -// v[cnt] is copied into the allocated array. -cmData_t* cmDataStrAlloc( cmData_t* parent, cmChar_t* str ) -{ - cmData_t* p = _cmDataAllocNode(parent,kStrDtId); - cmDataSetStrAlloc(p,str); - return p; -} - -cmData_t* cmDataConstStrAllocN( cmData_t* parent, const cmChar_t* str, unsigned charCnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kConstStrDtId); - cmDataSetConstStrAllocN(p,str,charCnt); - return p; -} - - -cmData_t* cmDataConstStrAlloc( cmData_t* parent, const cmChar_t* str ) -{ - cmData_t* p = _cmDataAllocNode(parent,kConstStrDtId); - cmDataSetConstStrAlloc(p,str); - return p; -} - -cmData_t* cmDataCharAllocPtr( cmData_t* parent, const char* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kCharPtrDtId); - cmDataSetCharAllocPtr(p, v, cnt ); - return p; -} - -cmData_t* cmDataUCharAllocPtr( cmData_t* parent, const unsigned char* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kUCharPtrDtId); - cmDataSetUCharAllocPtr(p, v, cnt ); - return p; -} - -cmData_t* cmDataShortAllocPtr( cmData_t* parent, const short* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kShortPtrDtId); - cmDataSetShortAllocPtr(p, v, cnt ); - return p; -} - -cmData_t* cmDataUShortAllocPtr( cmData_t* parent, const unsigned short* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kUShortPtrDtId); - cmDataSetUShortAllocPtr(p, v, cnt ); - return p; -} - -cmData_t* cmDataIntAllocPtr( cmData_t* parent, const int* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kIntPtrDtId); - cmDataSetIntAllocPtr(p, v, cnt ); - return p; -} - -cmData_t* cmDataUIntAllocPtr( cmData_t* parent, const unsigned int* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kUIntPtrDtId); - cmDataSetUIntAllocPtr(p, v, cnt ); - return p; -} - -cmData_t* cmDataLongAllocPtr( cmData_t* parent, const long* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kLongPtrDtId); - cmDataSetLongAllocPtr(p, v, cnt ); - return p; -} - -cmData_t* cmDataULongAllocPtr( cmData_t* parent, const unsigned long* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kULongPtrDtId); - cmDataSetULongAllocPtr(p, v, cnt ); - return p; -} - -cmData_t* cmDataFloatAllocPtr( cmData_t* parent, const float* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kFloatPtrDtId); - cmDataSetFloatAllocPtr(p, v, cnt ); - return p; -} - -cmData_t* cmDataDoubleAllocPtr( cmData_t* parent, const double* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kDoublePtrDtId); - cmDataSetDoubleAllocPtr(p, v, cnt ); - return p; -} - - -cmData_t* cmDataVoidAllocPtr( cmData_t* parent, const void* v, unsigned cnt ) -{ - cmData_t* p = _cmDataAllocNode(parent,kVoidPtrDtId); - cmDataSetCharAllocPtr(p, (const char*)v, cnt ); - p->tid = kVoidPtrDtId; - return p; -} - -void cmDataFree( cmData_t* p ) -{ - _cmDataFree(p); -} - -cmData_t* cmDataUnlink( cmData_t* p ) -{ - if( p->parent == NULL ) - return p; - - assert( cmDataIsStruct(p->parent) ); - - cmData_t* cp = p->u.child; - cmData_t* pp = NULL; - for(; cp!=NULL; cp=cp->sibling) - if( cp == p ) - { - if( pp == NULL ) - p->parent->u.child = p->sibling; - else - pp->sibling = cp->sibling; - } - return p; -} - -void cmDataUnlinkAndFree( cmData_t* p ) -{ - cmDataUnlink(p); - cmDataFree(p); -} - -cmData_t* _cmDataDupl( const cmData_t* p, cmData_t* parent ) -{ - cmData_t* rp = NULL; - - switch( p->tid ) - { - case kNullDtId: rp = cmDataAllocNull(parent); break; - case kUCharDtId: rp = cmDataAllocUChar(parent,p->u.uc); break; - case kCharDtId: rp = cmDataAllocChar(parent,p->u.c); break; - case kUShortDtId: rp = cmDataAllocShort(parent,p->u.us); break; - case kShortDtId: rp = cmDataAllocUShort(parent,p->u.s); break; - case kUIntDtId: rp = cmDataAllocUInt(parent,p->u.i); break; - case kIntDtId: rp = cmDataAllocInt(parent,p->u.ui); break; - case kULongDtId: rp = cmDataAllocULong(parent,p->u.ul); break; - case kLongDtId: rp = cmDataAllocLong(parent,p->u.l); break; - case kFloatDtId: rp = cmDataAllocFloat(parent,p->u.f); break; - case kDoubleDtId: rp = cmDataAllocDouble(parent,p->u.d); break; - - case kStrDtId: rp = cmDataStrAlloc(parent,p->u.z); break; - case kConstStrDtId: rp = cmDataConstStrAlloc(parent,p->u.cz); break; - case kUCharPtrDtId: rp = cmDataUCharAllocPtr(parent,p->u.ucp,p->cnt); break; - case kCharPtrDtId: rp = cmDataCharAllocPtr(parent,p->u.cp,p->cnt); break; - case kUShortPtrDtId: rp = cmDataUShortAllocPtr(parent,p->u.usp,p->cnt); break; - case kShortPtrDtId: rp = cmDataShortAllocPtr(parent,p->u.sp,p->cnt); break; - case kUIntPtrDtId: rp = cmDataUIntAllocPtr(parent,p->u.uip,p->cnt); break; - case kIntPtrDtId: rp = cmDataIntAllocPtr(parent,p->u.ip,p->cnt); break; - case kULongPtrDtId: rp = cmDataULongAllocPtr(parent,p->u.ulp,p->cnt); break; - case kLongPtrDtId: rp = cmDataLongAllocPtr(parent,p->u.lp,p->cnt); break; - case kFloatPtrDtId: rp = cmDataFloatAllocPtr(parent,p->u.fp,p->cnt); break; - case kDoublePtrDtId: rp = cmDataDoubleAllocPtr(parent,p->u.dp,p->cnt); break; - case kVoidPtrDtId: rp = cmDataVoidAllocPtr(parent,p->u.vp,p->cnt); break; - - case kListDtId: - case kPairDtId: - case kRecordDtId: - { - rp = _cmDataAllocNode(parent,p->tid); - cmData_t* cp = p->u.child; - for(; cp!=NULL; cp=cp->sibling) - cmDataAppendChild(rp,_cmDataDupl(cp,rp)); - } - break; - - default: - assert(0); - } - - return rp; -} - -cmData_t* cmDataDupl( const cmData_t* p ) -{ return _cmDataDupl(p,NULL); } - -cmData_t* cmDataReplace( cmData_t* dst, cmData_t* src ) -{ - if( dst->parent == NULL ) - { - cmDataUnlinkAndFree(dst); - src->parent = NULL; - return src; - } - - cmData_t* parent = dst->parent; - cmData_t* cp = parent->u.child; - cmData_t* pp = NULL; - unsigned i = 0; - unsigned n = cmDataChildCount(parent); - - // locate dst's right sibling - for(i=0; isibling) - { - - if( cp == dst ) - { - // link in 'src' in place of 'dst' - src->sibling = dst->sibling; - - // free dst - cmDataUnlinkAndFree(dst); - - // update the sibling link to - if( pp == NULL ) - parent->u.child = src; - else - pp->sibling = src; - - src->parent = parent; - break; - } - pp = cp; - } - return src; -} - - -unsigned cmDataChildCount( const cmData_t* p ) -{ - if( !cmDataIsStruct(p) ) - return 0; - - unsigned n = 0; - const cmData_t* cp = p->u.child; - for(; cp!=NULL; cp=cp->sibling) - ++n; - - return n; -} - -cmData_t* cmDataChild( cmData_t* p, unsigned index ) -{ - if( !cmDataIsStruct(p) ) - return NULL; - - unsigned n = 0; - cmData_t* cp = p->u.child; - for(; cp!=NULL; cp=cp->sibling) - { - if( n == index ) - break; - ++n; - } - - return cp; -} - -cmData_t* cmDataPrependChild(cmData_t* parent, cmData_t* p ) -{ - assert( cmDataIsStruct(p) ); - - - cmDataUnlink(p); - - p->u.child = parent->u.child; - parent->u.child = p; - p->parent = parent; - return p; -} - -cmData_t* cmDataAppendChild( cmData_t* parent, cmData_t* p ) -{ - assert( cmDataIsStruct(parent) ); - assert( parent->tid != kRecordDtId || (parent->tid == kRecordDtId && p->tid==kPairDtId)); - - cmDataUnlink(p); - - cmData_t* cp = parent->u.child; - if( cp == NULL ) - parent->u.child = p; - else - { - for(; cp!=NULL; cp=cp->sibling) - if( cp->sibling == NULL ) - { - cp->sibling = p; - break; - } - } - - p->parent = parent; - p->sibling = NULL; - return p; -} - -cmData_t* cmDataInsertChild( cmData_t* parent, unsigned index, cmData_t* p ) -{ - if( !cmDataIsStruct(parent) ) - return NULL; - - cmDataUnlink(p); - - unsigned n = 0; - cmData_t* cp = parent->u.child; - cmData_t* pp = NULL; - for(; cp!=NULL; cp=cp->sibling) - { - if( n == index ) - { - if( pp == NULL ) - { - parent->u.child = p; - p->sibling = NULL; - } - else - { - p->sibling = pp->sibling; - pp->sibling = p; - } - break; - - } - ++n; - } - - p->parent = parent; - - return p; - -} - //---------------------------------------------------------------------------- bool _cmDataPairIsValid( const cmData_t* p ) { - assert( p->tid == kPairDtId ); + assert( p->cid == kPairDtId && p->tid==kStructDtId ); bool fl = p->u.child == NULL || p->u.child->sibling == NULL || p->u.child->sibling->sibling!=NULL; return !fl; @@ -2711,7 +1284,7 @@ const cmChar_t* cmDataPairKeyLabel( cmData_t* p ) { assert( _cmDataPairIsValid(p) ); const cmChar_t* label = NULL; - cmDataGetConstStr(p->u.child,&label); + cmDataConstStr(p->u.child,&label); return label; } @@ -2748,7 +1321,7 @@ cmData_t* cmDataPairSetKeyId( cmData_t* p, unsigned id ) cmData_t* cmDataPairSetKeyLabel( cmData_t* p, const cmChar_t* label ) { assert( _cmDataPairIsValid(p) ); - cmDataSetConstStrAlloc(p->u.child,label); + cmDataSetConstStr(p->u.child,kNoFlagsDtFl,label); return p; } @@ -2756,7 +1329,8 @@ cmData_t* cmDataPairSetKeyLabel( cmData_t* p, const cmChar_t* label ) cmData_t* cmDataMakePair( cmData_t* parent, cmData_t* p, cmData_t* key, cmData_t* value ) { _cmDataFree(p); - p->tid = kPairDtId; + p->tid = kStructDtId; + p->cid = kPairDtId; p->parent = parent; p->flags = 0; p->u.child = NULL; @@ -2768,9 +1342,14 @@ cmData_t* cmDataMakePair( cmData_t* parent, cmData_t* p, cmData_t* key, cmData_t // Dynamically allocate a pair node cmData_t* cmDataAllocPair( cmData_t* parent, const cmData_t* key, const cmData_t* value ) { - cmData_t* p = _cmDataAllocNode(parent,kPairDtId); - cmData_t* kp = cmDataDupl(key); - cmData_t* vp = cmDataDupl(value); + cmData_t* p = _cmDataNew(parent,kPairDtId,kStructDtId); + cmData_t* kp = NULL; + cmData_t* vp = NULL; + + // BUG BUG BUG - must check return value of cmDataDupl() + cmDataDupl(key,&kp); + cmDataDupl(value,&vp); + cmDataPrependChild(p,vp); cmDataPrependChild(p,kp); return p; @@ -2778,24 +1357,27 @@ cmData_t* cmDataAllocPair( cmData_t* parent, const cmData_t* key, const cmData_ cmData_t* cmDataAllocPairId(cmData_t* parent, unsigned keyId, cmData_t* value ) { - cmData_t* p = _cmDataAllocNode(parent,kPairDtId); - cmDataAllocUInt(p,keyId); + cmData_t* p = _cmDataNew(parent,kPairDtId,kStructDtId); + cmDataNewUInt(p,kNoFlagsDtFl,keyId,NULL); cmDataAppendChild(p,value); return p; } cmData_t* cmDataAllocPairLabel( cmData_t* parent, const cmChar_t *label, cmData_t* value ) { - cmData_t* p = _cmDataAllocNode(parent,kPairDtId); - cmDataConstStrAlloc(p,label); + cmData_t* p = _cmDataNew(parent,kPairDtId,kStructDtId); + + // BUG BUG BUG - should check return value + cmDataNewConstStr(p,kNoFlagsDtFl,label,NULL); cmDataAppendChild(p,value); return p; } cmData_t* cmDataAllocPairLabelN(cmData_t* parent, const cmChar_t* label, unsigned charCnt, cmData_t* value) { - cmData_t* p = _cmDataAllocNode(parent,kPairDtId); - cmDataConstStrAllocN(p,label,charCnt); + cmData_t* p = _cmDataNew(parent,kPairDtId,kStructDtId); + // BUG BUG BUG - should check return value + cmDataNewConstStrN(p,kNoFlagsDtFl,label,charCnt,NULL); cmDataAppendChild(p,value); return p; } @@ -2820,117 +1402,72 @@ cmData_t* cmDataListMake( cmData_t* parent, cmData_t* p ) } cmData_t* cmDataListAlloc( cmData_t* parent) -{ return _cmDataAllocNode(parent,kListDtId); } +{ return _cmDataNew(parent,kListDtId,kStructDtId); } cmDtRC_t _cmDataParseArgV( cmData_t* parent, va_list vl, cmData_t** vpp ) { - cmDtRC_t rc = kOkDtRC; - cmData_t* vp = NULL; - unsigned tid = va_arg(vl,unsigned); + cmDtRC_t rc = kOkDtRC; + cmData_t* vp = NULL; + cmDataContainerId_t cid = va_arg(vl,unsigned); + cmDataTypeId_t tid = va_arg(vl,unsigned); - switch(tid) + switch(cid) { - case kInvalidDtId: rc = kEolDtRC; break; - case kNullDtId: vp = cmDataAllocNull(parent); break; - case kUCharDtId: vp = cmDataAllocUChar( parent,va_arg(vl,int)); break; - case kCharDtId: vp = cmDataAllocChar( parent,va_arg(vl,int)); break; - case kUShortDtId: vp = cmDataAllocUShort( parent,va_arg(vl,int)); break; - case kShortDtId: vp = cmDataAllocShort( parent,va_arg(vl,int)); break; - case kUIntDtId: vp = cmDataAllocUInt( parent,va_arg(vl,unsigned int)); break; - case kIntDtId: vp = cmDataAllocInt( parent,va_arg(vl,int)); break; - case kULongDtId: vp = cmDataAllocULong( parent,va_arg(vl,unsigned long)); break; - case kLongDtId: vp = cmDataAllocLong( parent,va_arg(vl,long)); break; - case kFloatDtId: vp = cmDataAllocFloat( parent,va_arg(vl,double)); break; - case kDoubleDtId: vp = cmDataAllocDouble( parent,va_arg(vl,double)); break; - - case kStrDtId: vp = cmDataStrAlloc( parent,va_arg(vl,cmChar_t*)); break; - case kConstStrDtId: vp = cmDataConstStrAlloc( parent,va_arg(vl,const cmChar_t*)); break; - - case kUCharPtrDtId: + case kInvalidCntDtId: rc = kEolDtRC; break; + + case kScalarDtId: + switch(tid) { - unsigned char* p = va_arg(vl,unsigned char*); - vp = cmDataUCharAllocPtr(parent, p, va_arg(vl,unsigned)); + case kNullDtId: rc = cmDataNewNull( parent,kNoFlagsDtFl,&vp); break; + case kUCharDtId: rc = cmDataNewUChar( parent,kNoFlagsDtFl,va_arg(vl,int),&vp); break; + case kCharDtId: rc = cmDataNewChar( parent,kNoFlagsDtFl,va_arg(vl,int),&vp); break; + case kUShortDtId: rc = cmDataNewUShort( parent,kNoFlagsDtFl,va_arg(vl,int),&vp); break; + case kShortDtId: rc = cmDataNewShort( parent,kNoFlagsDtFl,va_arg(vl,int),&vp); break; + case kUIntDtId: rc = cmDataNewUInt( parent,kNoFlagsDtFl,va_arg(vl,unsigned int),&vp); break; + case kIntDtId: rc = cmDataNewInt( parent,kNoFlagsDtFl,va_arg(vl,int),&vp); break; + case kULongDtId: rc = cmDataNewULong( parent,kNoFlagsDtFl,va_arg(vl,unsigned long),&vp); break; + case kLongDtId: rc = cmDataNewLong( parent,kNoFlagsDtFl,va_arg(vl,long),&vp); break; + case kFloatDtId: rc = cmDataNewFloat( parent,kNoFlagsDtFl,va_arg(vl,double),&vp); break; + case kDoubleDtId: rc = cmDataNewDouble( parent,kNoFlagsDtFl,va_arg(vl,double),&vp); break; + case kStrDtId: rc = cmDataNewStr( parent,kNoFlagsDtFl,va_arg(vl,cmChar_t*),&vp); break; + default: + // BUG BUG BUG - signal an error here + assert(0); + break; } break; - case kCharPtrDtId: + case kArrayDtId: + switch(tid) { - char* p = va_arg(vl,char*); - vp = cmDataCharAllocPtr(parent, p, va_arg(vl,unsigned)); - } - break; - - case kUShortPtrDtId: - { - unsigned short* p = va_arg(vl,unsigned short*); - vp = cmDataUShortAllocPtr(parent, p, va_arg(vl,unsigned)); - } - break; - - case kShortPtrDtId: - { - short* p = va_arg(vl,short*); - vp = cmDataShortAllocPtr(parent, p, va_arg(vl,unsigned)); - } - break; - - case kUIntPtrDtId: - { - unsigned int* p = va_arg(vl,unsigned int*); - vp = cmDataUIntAllocPtr(parent, p, va_arg(vl,unsigned)); - } - break; - - case kIntPtrDtId: - { - int * p = va_arg(vl,int*); - vp = cmDataIntAllocPtr(parent, p, va_arg(vl,unsigned)); - } - break; - - case kULongPtrDtId: - { - unsigned long* p = va_arg(vl,unsigned long*); - vp = cmDataULongAllocPtr(parent, p, va_arg(vl,unsigned)); - } - break; - - case kLongPtrDtId: - { - long* p = va_arg(vl,long*); - vp = cmDataLongAllocPtr(parent, p, va_arg(vl,unsigned)); - } - break; - - case kFloatPtrDtId: - { - float* p = va_arg(vl,float*); - vp = cmDataFloatAllocPtr(parent, p, va_arg(vl,unsigned)); - } - break; - - case kDoublePtrDtId: - { - double* p = va_arg(vl,double*); - vp = cmDataDoubleAllocPtr(parent,p, va_arg(vl,unsigned)); - } - break; - - case kVoidPtrDtId: - { - void* p = va_arg(vl,void*); - vp = cmDataVoidAllocPtr(parent, p, va_arg(vl,unsigned)); + case kUCharDtId: rc = cmDataNewUCharArray( parent,va_arg(vl,unsigned char*), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break; + case kCharDtId: rc = cmDataNewCharArray( parent,va_arg(vl,char*), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break; + case kUShortDtId: rc = cmDataNewUShortArray( parent,va_arg(vl,unsigned short*),va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break; + case kShortDtId: rc = cmDataNewShortArray( parent,va_arg(vl,short*), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break; + case kUIntDtId: rc = cmDataNewUIntArray( parent,va_arg(vl,unsigned int*), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break; + case kIntDtId: rc = cmDataNewIntArray( parent,va_arg(vl,int*), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break; + case kULongDtId: rc = cmDataNewULongArray( parent,va_arg(vl,unsigned long*), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break; + case kLongDtId: rc = cmDataNewLongArray( parent,va_arg(vl,long*), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break; + case kFloatDtId: rc = cmDataNewFloatArray( parent,va_arg(vl,float*), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break; + case kDoubleDtId: rc = cmDataNewDoubleArray( parent,va_arg(vl,double*), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break; + case kStrDtId: rc = cmDataNewStrArray( parent,va_arg(vl,cmChar_t**), va_arg(vl,unsigned),kNoFlagsDtFl,&vp); break; + default: + // BUG BUG BUG - signal an error here + + assert(0); + break; } break; case kListDtId: case kPairDtId: case kRecordDtId: - vp = _cmDataAllocNode(parent,tid); + vp = _cmDataNew(parent,cid,kStructDtId); break; default: - _cmDataSetError(kVarArgErrDtRC); + // BUG BUG BUG - signal an error here + assert(0); break; } @@ -2939,49 +1476,62 @@ cmDtRC_t _cmDataParseArgV( cmData_t* parent, va_list vl, cmData_t** vpp ) return rc; } -cmData_t* _cmDataListParseV(cmData_t* parent, va_list vl ) +cmDtRC_t _cmDataListParseV(cmData_t* parent, va_list vl ) { - cmData_t* p = NULL; + cmDtRC_t rc = kOkDtRC; bool contFl = true; while( contFl ) { cmData_t* vp; - cmDtRC_t rc = _cmDataParseArgV(parent, vl, &vp); + + rc = _cmDataParseArgV(parent, vl, &vp); if(rc != kOkDtRC || cmDataAppendChild(parent,vp)==NULL ) contFl = false; } - return p; + + return rc; } -cmData_t* cmDataListAllocV(cmData_t* parent, va_list vl ) +cmRC_t cmDataListAllocV(cmData_t* parent, cmData_t** ref, va_list vl ) { cmData_t* p = cmDataListAlloc(parent); - _cmDataListParseV(p, vl ); - return p; + + cmRC_t rc; + + if((rc = _cmDataListParseV(p, vl )) != kOkDtRC ) + { + cmDataUnlinkAndFree(p); + return rc; + } + + if( ref != NULL ) + *ref = p; + + return rc; } -cmData_t* cmDataListAllocA(cmData_t* parent, ... ) +cmRC_t cmDataListAllocA(cmData_t* parent, cmData_t** ref, ... ) { va_list vl; - va_start(vl,parent); - cmData_t* p = cmDataListAllocV(parent,vl); + va_start(vl,ref); + cmRC_t rc = cmDataListAllocV(parent,ref,vl); va_end(vl); - return p; + return rc; } cmData_t* cmDataListAppendEle( cmData_t* p, cmData_t* ele ) { - assert(p->tid == kListDtId); + assert(p->cid == kListDtId && p->tid==kStructDtId); return cmDataAppendChild(p,ele); } cmData_t* cmDataListAppendEleN(cmData_t* p, cmData_t* ele[], unsigned n ) { - assert(p->tid == kListDtId); + assert(p->cid == kListDtId && p->tid==kStructDtId); cmData_t* rp = NULL; unsigned i; @@ -2996,8 +1546,9 @@ cmData_t* cmDataListAppendEleN(cmData_t* p, cmData_t* ele[], unsigned n ) cmDtRC_t cmDataListAppendV( cmData_t* p, va_list vl ) { - if( _cmDataListParseV(p, vl ) == NULL ) - return _cmDataErrNo; + cmDtRC_t rc; + if((rc = _cmDataListParseV(p, vl )) != kOkDtRC ) + return rc; return kOkDtRC; } @@ -3026,42 +1577,42 @@ cmData_t* cmDataListInsertEleN(cmData_t* p, unsigned index, cmData_t* ele[], uns //---------------------------------------------------------------------------- unsigned cmDataRecdCount( const cmData_t* p ) { - assert( p->tid == kRecordDtId ); + assert( p->cid == kRecordDtId && p->tid==kStructDtId ); return cmDataChildCount(p); } cmData_t* cmDataRecdEle( cmData_t* p, unsigned index ) { - assert( p->tid == kRecordDtId ); + assert( p->cid == kRecordDtId && p->tid==kStructDtId ); cmData_t* cp = cmDataChild(p,index); - assert( p->tid == kPairDtId ); + assert( p->cid == kPairDtId ); return cp; } cmData_t* cmDataRecdValueFromIndex( cmData_t* p, unsigned index ) { - assert( p->tid == kRecordDtId ); + assert( p->cid == kRecordDtId && p->tid==kStructDtId ); cmData_t* cp = cmDataChild(p,index); - assert( p->tid == kPairDtId ); + assert( p->cid == kPairDtId && p->tid==kStructDtId ); return cmDataPairValue(cp); } cmData_t* cmDataRecdValueFromId( cmData_t* p, unsigned id ) { - assert( p->tid == kRecordDtId ); + assert( p->cid == kRecordDtId || p->tid==kStructDtId ); cmData_t* cp = p->u.child; for(; cp!=NULL; cp=cp->sibling) if( cmDataPairKeyId(cp) == id ) break; - assert( cp!=NULL && cp->tid==kPairDtId ); + assert( cp!=NULL && cp->cid==kPairDtId && cp->tid==kStructDtId); return cmDataPairValue(cp); } cmData_t* cmDataRecdValueFromLabel( cmData_t* p, const cmChar_t* label ) { - assert( p->tid == kRecordDtId ); + assert( p->cid == kRecordDtId && p->tid==kStructDtId); cmData_t* cp = p->u.child; for(; cp!=NULL; cp=cp->sibling) { @@ -3070,16 +1621,16 @@ cmData_t* cmDataRecdValueFromLabel( cmData_t* p, const cmChar_t* label if( lp!=NULL && strcmp(lp,label)==0 ) break; } - assert( cp!=NULL && cp->tid==kPairDtId ); + assert( cp!=NULL && cp->cid==kPairDtId && cp->tid==kStructDtId); return cmDataPairValue(cp); } cmData_t* cmDataRecdKey( cmData_t* p, unsigned index ) { - assert( p->tid == kRecordDtId ); + assert( p->cid == kRecordDtId && p->tid==kStructDtId ); cmData_t* cp = cmDataChild(p,index); - assert( p->tid == kPairDtId ); + assert( cp->cid == kPairDtId && cp->tid==kStructDtId); return cmDataPairKey(cp); } @@ -3095,7 +1646,8 @@ const cmChar_t* cmDataRecdKeyLabel( cmData_t* p, unsigned index ) { cmData_t* kp = cmDataRecdKey(p,index); const cmChar_t* label = NULL; - cmDataGetConstStr(kp,&label); + // BUG BUG BUG - test return value + cmDataConstStr(kp,&label); return label; } @@ -3110,11 +1662,11 @@ cmData_t* cmDataRecdMake( cmData_t* parent, cmData_t* p ) } cmData_t* cmDataRecdAlloc(cmData_t* parent) -{ return _cmDataAllocNode(parent,kRecordDtId); } +{ return _cmDataNew(parent,kRecordDtId,kStructDtId); } cmData_t* cmDataRecdAppendPair( cmData_t* p, cmData_t* pair ) { - assert( p!=NULL && p->tid==kRecordDtId); + assert( p!=NULL && p->cid==kRecordDtId && p->tid==kStructDtId); cmDataAppendChild(p,pair); return p; } @@ -3122,7 +1674,7 @@ cmData_t* cmDataRecdAppendPair( cmData_t* p, cmData_t* pair ) cmDtRC_t _cmDataRecdParseInputV(cmData_t* parent, unsigned idFl, va_list vl ) { - assert( parent != NULL && parent->tid == kRecordDtId ); + assert( parent != NULL && parent->cid == kRecordDtId && parent->tid == kStructDtId ); bool contFl = true; cmDtRC_t rc = kOkDtRC; @@ -3140,7 +1692,7 @@ cmDtRC_t _cmDataRecdParseInputV(cmData_t* parent, unsigned idFl, va_list vl ) label = va_arg(vl,const char*); // text field label identifier // validate the field identifier - if( (idFl && id==kInvalidDtId) || (!idFl && label==NULL) ) + if( (idFl && id==cmInvalidId) || (!idFl && label==NULL) ) break; // parse the field data @@ -3209,8 +1761,8 @@ cmDtRC_t _cmDataRecdParseV(cmData_t* p, bool idFl, cmErr_t* err, unsigned errRC, while( contFl ) { - unsigned id; - const char* label; + unsigned id = cmInvalidId; + const char* label = NULL; // parse the field idenfier if( idFl ) @@ -3219,14 +1771,15 @@ cmDtRC_t _cmDataRecdParseV(cmData_t* p, bool idFl, cmErr_t* err, unsigned errRC, label = va_arg(vl,const char*); // text field label identifier // validate the field identifier - if( (idFl && id==kInvalidDtId) || (!idFl && label==NULL) ) + if( (idFl && id==cmInvalidId) || (!idFl && label==NULL) ) break; - cmDataFmtId_t typeId = va_arg(vl,unsigned); - void* v = va_arg(vl,void*); - cmData_t* np = NULL; - bool optFl = cmIsFlag(typeId,kOptArgDtFl); - cmDtRC_t rc0 = kOkDtRC; + cmDataContainerId_t cid = va_arg(vl,unsigned); + cmDataTypeId_t typeId = va_arg(vl,unsigned); + void* v = va_arg(vl,void*); + cmData_t* np = NULL; + bool optFl = cmIsFlag(typeId,kOptArgDtFl); + cmDtRC_t rc0 = kOkDtRC; typeId = cmClrFlag(typeId,kOptArgDtFl); @@ -4297,4 +2850,3 @@ void cmDataTest( cmCtx_t* ctx ) cmRptPrintf(&ctx->rpt,"Done!.\n"); } -#endif diff --git a/cmData.h b/cmData.h index 86db015..e246944 100644 --- a/cmData.h +++ b/cmData.h @@ -75,7 +75,8 @@ extern "C" { kFloatDtId, // 10 kDoubleDtId, // 11 kStrDtId, // 12 zero terminated string - kBlobDtId // 13 application defined raw memory object + kBlobDtId, // 13 application defined raw memory object + kStructDtId // 14 node is a pair,list, or recd } cmDataTypeId_t; @@ -425,341 +426,6 @@ extern "C" { cmData_t* cmDataInsertChild( cmData_t* parent, unsigned index, cmData_t* p ); - -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// - -#ifdef NOT_DEF - typedef enum - { - kInvalidDtId, - - kMinValDtId, - - kNullDtId = kMinValDtId, - kUCharDtId, - kCharDtId, - kUShortDtId, - kShortDtId, - kUIntDtId, - kIntDtId, - kULongDtId, - kLongDtId, - kFloatDtId, - kDoubleDtId, - - kStrDtId, - kConstStrDtId, - kMaxValDtId = kConstStrDtId, - - kMinPtrDtId, - kUCharPtrDtId = kMinPtrDtId, // cnt=array element count - kCharPtrDtId, - kUShortPtrDtId, - kShortPtrDtId, - kUIntPtrDtId, - kIntPtrDtId, - kULongPtrDtId, - kLongPtrDtId, - kFloatPtrDtId, - kDoublePtrDtId, - kVoidPtrDtId, - kMaxPtrDtId = kVoidPtrDtId, - - kMinStructDtId, - kListDtId = kMinStructDtId, // children nodes are array elements, cnt=child count - kPairDtId, // key/value pairs, cnt=2, first child is key, second is value - kRecordDtId, // children nodes are pairs, cnt=pair count - kMaxStructDtId, - - kOptArgDtFl = 0x80000000 - } cmDataFmtId_t; - - enum - { - kDynObjDtFl = 0x01, // object was dynamically allocated - kDynPtrDtFl = 0x02 // ptr array was dynamically allocated - }; - - typedef struct cmData_str - { - cmDataFmtId_t tid; // data format id - unsigned flags; // - struct cmData_str* parent; // this childs parent - struct cmData_str* sibling; // this childs left sibling - unsigned cnt; // array ele count - - union - { - char c; - unsigned char uc; - short s; - unsigned short us; - int i; - unsigned int ui; - long l; - unsigned long ul; - float f; - double d; - - cmChar_t* z; - const cmChar_t* cz; - - void* vp; - - char* cp; - unsigned char* ucp; - short* sp; - unsigned short* usp; - int* ip; - unsigned int* uip; - long* lp; - unsigned long* ulp; - float* fp; - double* dp; - - - struct cmData_str* child; // first child (array,record,pair) - } u; - - } cmData_t; - - typedef unsigned cmDtRC_t; - - extern cmData_t cmDataNull; - - bool cmDataIsValue( const cmData_t* p ); - bool cmDataIsPtr( const cmData_t* p ); - bool cmDataIsStruct( const cmData_t* p ); // is a pair,list or record - - - bool canConvertType( cmDataFmtId_t srcId, cmDataFmtId_t dstId ); - bool willTruncate( cmDataFmtId_t srcId, cmDataFmtId_t dstId ); - bool canConvertObj( const cmData_t* srcObj, cmData_t* dstObj ); - bool willTruncateObj(const cmData_t* srcObj, cmData_t* dstObj ); - - - - // Get the value of an object without conversion. - // The data type id must match the return type or the - // conversion must be an automatic C conversion. - char cmDataChar( const cmData_t* p ); - unsigned char cmDataUChar( const cmData_t* p ); - short cmDataShort( const cmData_t* p ); - unsigned short cmDataUShort( const cmData_t* p ); - int cmDataInt( const cmData_t* p ); - unsigned int cmDataUInt( const cmData_t* p ); - long cmDataLong( const cmData_t* p ); - unsigned long cmDataULong( const cmData_t* p ); - float cmDataFloat( const cmData_t* p ); - double cmDataDouble( const cmData_t* p ); - cmChar_t* cmDataStr( const cmData_t* p ); - const cmChar_t* cmDataConstStr( const cmData_t* p ); - void* cmDataVoidPtr( const cmData_t* p ); - char* cmDataCharPtr( const cmData_t* p ); - unsigned char* cmDataUCharPtr( const cmData_t* p ); - short* cmDataShortPtr( const cmData_t* p ); - unsigned short* cmDataUShortPtr( const cmData_t* p ); - int* cmDataIntPtr( const cmData_t* p ); - unsigned int* cmDataUIntPtr( const cmData_t* p ); - long* cmDataLongPtr( const cmData_t* p ); - unsigned long* cmDataULongPtr( const cmData_t* p ); - float* cmDataFloatPtr( const cmData_t* p ); - double* cmDataDoublePtr( const cmData_t* p ); - - - // Get the value of an object with conversion. - cmDtRC_t cmDataGetChar( const cmData_t* p, char* v ); - cmDtRC_t cmDataGetUChar( const cmData_t* p, unsigned char* v ); - cmDtRC_t cmDataGetShort( const cmData_t* p, short* v ); - cmDtRC_t cmDataGetUShort( const cmData_t* p, unsigned short* v ); - cmDtRC_t cmDataGetInt( const cmData_t* p, int* v ); - cmDtRC_t cmDataGetUInt( const cmData_t* p, unsigned int* v ); - cmDtRC_t cmDataGetLong( const cmData_t* p, long* v ); - cmDtRC_t cmDataGetULong( const cmData_t* p, unsigned long* v ); - cmDtRC_t cmDataGetFloat( const cmData_t* p, float* v ); - cmDtRC_t cmDataGetDouble( const cmData_t* p, double* v ); - - // Returns the pointer - does not copy the data. - cmDtRC_t cmDataGetStr( const cmData_t* p, char** v ); - cmDtRC_t cmDataGetConstStr( const cmData_t* p, const char** v ); - cmDtRC_t cmDataGetVoidPtr( const cmData_t* p, void** v ); - cmDtRC_t cmDataGetCharPtr( const cmData_t* p, char** v ); - cmDtRC_t cmDataGetUCharPtr( const cmData_t* p, unsigned char** v ); - cmDtRC_t cmDataGetShortPtr( const cmData_t* p, short** v ); - cmDtRC_t cmDataGetUShortPtr( const cmData_t* p, unsigned short** v ); - cmDtRC_t cmDataGetIntPtr( const cmData_t* p, int** v ); - cmDtRC_t cmDataGetUIntPtr( const cmData_t* p, unsigned int** v ); - cmDtRC_t cmDataGetLongPtr( const cmData_t* p, long** v ); - cmDtRC_t cmDataGetULongPtr( const cmData_t* p, unsigned long** v ); - cmDtRC_t cmDataGetFloatPtr( const cmData_t* p, float** v ); - cmDtRC_t cmDataGetDoublePtr( const cmData_t* p, double** v ); - - - // Set the value and type of an existing scalar object. - // These functions begin by releasing any resources held by *p - // prior to resetting the type and value of the object. - cmData_t* cmDataSetNull( cmData_t* p ); - cmData_t* cmDataSetChar( cmData_t* p, char v ); - cmData_t* cmDataSetUChar( cmData_t* p, unsigned char v ); - cmData_t* cmDataSetShort( cmData_t* p, short v ); - cmData_t* cmDataSetUShort( cmData_t* p, unsigned short v ); - cmData_t* cmDataSetInt( cmData_t* p, int v ); - cmData_t* cmDataSetUInt( cmData_t* p, unsigned int v ); - cmData_t* cmDataSetLong( cmData_t* p, long v ); - cmData_t* cmDataSetULong( cmData_t* p, unsigned long v ); - cmData_t* cmDataSetFloat( cmData_t* p, float v ); - cmData_t* cmDataSetDouble( cmData_t* p, double v ); - cmData_t* cmDataSetStr( cmData_t* p, cmChar_t* s ); - cmData_t* cmDataSetConstStr( cmData_t* p, const cmChar_t* s ); - - // Set the type and value of an existing data object to an external array. - // These functions begin by releasing any resources help by *p. - // The array pointed to by 'vp' is not copied or duplicated. - // 'vp' is simply assigned as the data space for the object and therefore must remain - // valid for the life of the object. - cmData_t* cmDataSetVoidPtr( cmData_t* p, void* vp, unsigned cnt ); - cmData_t* cmDataSetCharPtr( cmData_t* p, char* vp, unsigned cnt ); - cmData_t* cmDataSetUCharPtr( cmData_t* p, unsigned char* vp, unsigned cnt ); - cmData_t* cmDataSetShortPtr( cmData_t* p, short* vp, unsigned cnt ); - cmData_t* cmDataSetUShortPtr( cmData_t* p, unsigned short* vp, unsigned cnt ); - cmData_t* cmDataSetIntPtr( cmData_t* p, int* vp, unsigned cnt ); - cmData_t* cmDataSetUIntPtr( cmData_t* p, unsigned int* vp, unsigned cnt ); - cmData_t* cmDataSetLongPtr( cmData_t* p, long* vp, unsigned cnt ); - cmData_t* cmDataSetULongPtr( cmData_t* p, unsigned long* vp, unsigned cnt ); - cmData_t* cmDataSetFloatPtr( cmData_t* p, float* vp, unsigned cnt ); - cmData_t* cmDataSetDoublePtr( cmData_t* p, double* vp, unsigned cnt ); - - // Set the value of an existing array based data object. - // These functions begin by releasing any resources help by *p - // and then dynamically allocate the internal array and copy - // the array data into it. - cmData_t* cmDataSetStrAllocN( cmData_t* p, const cmChar_t* s, unsigned charCnt ); - cmData_t* cmDataSetStrAlloc( cmData_t* p, const cmChar_t* s ); - cmData_t* cmDataSetConstStrAllocN( cmData_t* p, const cmChar_t* s, unsigned charCnt ); - cmData_t* cmDataSetConstStrAlloc( cmData_t* p, const cmChar_t* s ); - cmData_t* cmDataSetVoidAllocPtr( cmData_t* p, const void* vp, unsigned cnt ); - cmData_t* cmDataSetCharAllocPtr( cmData_t* p, const char* vp, unsigned cnt ); - cmData_t* cmDataSetUCharAllocPtr( cmData_t* p, const unsigned char* vp, unsigned cnt ); - cmData_t* cmDataSetShortAllocPtr( cmData_t* p, const short* vp, unsigned cnt ); - cmData_t* cmDataSetUShortAllocPtr( cmData_t* p, const unsigned short* vp, unsigned cnt ); - cmData_t* cmDataSetIntAllocPtr( cmData_t* p, const int* vp, unsigned cnt ); - cmData_t* cmDataSetUIntAllocPtr( cmData_t* p, const unsigned int* vp, unsigned cnt ); - cmData_t* cmDataSetLongAllocPtr( cmData_t* p, const long* vp, unsigned cnt ); - cmData_t* cmDataSetULongAllocPtr( cmData_t* p, const unsigned long* vp, unsigned cnt ); - cmData_t* cmDataSetFloatAllocPtr( cmData_t* p, const float* vp, unsigned cnt ); - cmData_t* cmDataSetDoubleAllocPtr( cmData_t* p, const double* vp, unsigned cnt ); - - - // Dynamically allocate a data object and set it's value. - cmData_t* cmDataAllocNull( cmData_t* parent ); - cmData_t* cmDataAllocChar( cmData_t* parent, char v ); - cmData_t* cmDataAllocUChar( cmData_t* parent, unsigned char v ); - cmData_t* cmDataAllocShort( cmData_t* parent, short v ); - cmData_t* cmDataAllocUShort( cmData_t* parent, unsigned short v ); - cmData_t* cmDataAllocInt( cmData_t* parent, int v ); - cmData_t* cmDataAllocUInt( cmData_t* parent, unsigned int v ); - cmData_t* cmDataAllocLong( cmData_t* parent, long v ); - cmData_t* cmDataAllocULong( cmData_t* parent, unsigned long v ); - cmData_t* cmDataAllocFloat( cmData_t* parent, float v ); - cmData_t* cmDataAllocDouble( cmData_t* parent, double v ); - - // Dynamically allocate a data object and set its array value to an external - // array. v[cnt] is assigned as the internal data space for the object and - // therefore must remain valid for the life of the object. - // See the cmDataXXXAlocPtr() for equivalent functions which dynamically - // allocate the intenal data space. - cmData_t* cmDataAllocStr( cmData_t* parent, cmChar_t* str ); - cmData_t* cmDataAllocConstStr( cmData_t* parent, const cmChar_t* str ); - cmData_t* cmDataAllocCharPtr( cmData_t* parent, char* v, unsigned cnt ); - cmData_t* cmDataAllocUCharPtr( cmData_t* parent, unsigned char* v, unsigned cnt ); - cmData_t* cmDataAllocShortPtr( cmData_t* parent, short* v, unsigned cnt ); - cmData_t* cmDataAllocUShortPtr( cmData_t* parent, unsigned short* v, unsigned cnt ); - cmData_t* cmDataAllocIntPtr( cmData_t* parent, int* v, unsigned cnt ); - cmData_t* cmDataAllocUIntPtr( cmData_t* parent, unsigned int* v, unsigned cnt ); - cmData_t* cmDataAllocLongPtr( cmData_t* parent, long* v, unsigned cnt ); - cmData_t* cmDataAllocULongPtr( cmData_t* parent, unsigned long* v, unsigned cnt ); - cmData_t* cmDataAllocFloatPtr( cmData_t* parent, float* v, unsigned cnt ); - cmData_t* cmDataAllocDoublePtr( cmData_t* parent, double* v, unsigned cnt ); - cmData_t* cmDataAllocVoidPtr( cmData_t* parent, void* v, unsigned cnt ); - - - // Dynamically allocate a data object and its array value. - // These functions dynamically allocate the internal array data space - // and copy v[cnt] into it. - cmData_t* cmDataStrAlloc( cmData_t* parent, cmChar_t* str ); - cmData_t* cmDataConstStrAlloc( cmData_t* parent, const cmChar_t* str ); - cmData_t* cmDataConstStrAllocN( cmData_t* parent, const cmChar_t* str, unsigned charCnt ); - cmData_t* cmDataCharAllocPtr( cmData_t* parent, const char* v, unsigned cnt ); - cmData_t* cmDataUCharAllocPtr( cmData_t* parent, const unsigned char* v, unsigned cnt ); - cmData_t* cmDataShortAllocPtr( cmData_t* parent, const short* v, unsigned cnt ); - cmData_t* cmDataUShortAllocPtr( cmData_t* parent, const unsigned short* v, unsigned cnt ); - cmData_t* cmDataIntAllocPtr( cmData_t* parent, const int* v, unsigned cnt ); - cmData_t* cmDataUIntAllocPtr( cmData_t* parent, const unsigned int* v, unsigned cnt ); - cmData_t* cmDataLongAllocPtr( cmData_t* parent, const long* v, unsigned cnt ); - cmData_t* cmDataULongAllocPtr( cmData_t* parent, const unsigned long* v, unsigned cnt ); - cmData_t* cmDataFloatAllocPtr( cmData_t* parent, const float* v, unsigned cnt ); - cmData_t* cmDataDoubleAllocPtr( cmData_t* parent, const double* v, unsigned cnt ); - cmData_t* cmDataVoidAllocPtr( cmData_t* parent, const void* v, unsigned cnt ); - - //---------------------------------------------------------------------------- - // Structure related functions - // - - // Release an object and any resources held by it. - // Note the this function does not unlink the object - // from it's parent. Use cmDataUnlinkAndFree() - // to remove a object from it's parent list prior - // to releasing it. - void cmDataFree( cmData_t* p ); - - // Unlink 'p' from its parents and siblings. - // Asserts if parent is not a structure. - // Returns 'p'. - cmData_t* cmDataUnlink( cmData_t* p ); - - // Wrapper function to cmDataUnlink() and cmDataFree(). - void cmDataUnlinkAndFree( cmData_t* p ); - - // Replace the 'dst' node with the 'src' node and - // return 'src'. This operation does not duplicate - // 'src' it simply links in 'src' at the location of - // 'dst' and then unlinks and free's 'dst'. - cmData_t* cmDataReplace( cmData_t* dst, cmData_t* src ); - - // Return the count of child nodes. - // 1. Array nodes have one child per array element. - // 2. List nodes have one child pair. - // 3. Pair nodes have two children. - // 4. Leaf nodes have 0 children. - unsigned cmDataChildCount( const cmData_t* p ); - - // Returns the ith child of 'p'. - // Returns NULL if p has no children or index is invalid. - cmData_t* cmDataChild( cmData_t* p, unsigned index ); - - // Prepend 'p' to 'parents' child list. - // The source node 'p' is not duplicated it is simply linked in. - // 'p' is automatically unlinked prior to being prepended. - // Returns 'p'. - cmData_t* cmDataPrependChild(cmData_t* parent, cmData_t* p ); - - // Append 'p' to the end of 'parent' child list. - // The source node 'p' is not duplicated it is simply linked in. - // 'p' is automatically unlinked prior to being appended. - // Returns 'p'. - cmData_t* cmDataAppendChild( cmData_t* parent, cmData_t* p ); - - // Insert 'p' at index. Index must be in the range: - // 0 to cmDataChildCount(parent). - // The source node 'p' is not duplicated it is simply linked in. - // 'p' is automatically unlinked prior to being inserted. - // Returns 'p'. - cmData_t* cmDataInsertChild( cmData_t* parent, unsigned index, cmData_t* p ); - - //---------------------------------------------------------------------------- // Pair related functions // @@ -814,15 +480,15 @@ extern "C" { // Var-args fmt: - // {} + // {} {} // scalar types: is literal, is not included // null has no or - // ptr types: is pointer, is element count - // struct types: is cmData_t, is not included + // array types: is pointer, is element count + // struct types: is cmData_t, and is not included // Indicate the end of argument list by setting to kInvalidDtId. // The memory for array based data types is dynamically allocated. - cmData_t* cmDataListAllocV(cmData_t* parent, va_list vl ); - cmData_t* cmDataListAllocA(cmData_t* parent, ... ); + cmRC_t cmDataListAllocV(cmData_t* parent, cmData_t** ref, va_list vl ); + cmRC_t cmDataListAllocA(cmData_t* parent, cmData_t** ref, ... ); // Returns a ptr to 'ele'. cmData_t* cmDataListAppendEle( cmData_t* p, cmData_t* ele ); @@ -833,9 +499,6 @@ extern "C" { cmData_t* cmDataListInsertEle( cmData_t* p, unsigned index, cmData_t* ele ); cmData_t* cmDataListInsertEleN(cmData_t* p, unsigned index, cmData_t* ele[], unsigned n ); - cmData_t* cmDataListUnlink( cmData_t* p, unsigned index ); - cmData_t* cmDataListFree( cmData_t* p, unsigned index ); - //---------------------------------------------------------------------------- // Record related functions // @@ -866,7 +529,7 @@ extern "C" { // Var-args format: - // {} + // {} {} // scalar types: is literal, is not included // null type: has no or // ptr types: is pointer, is element count @@ -918,7 +581,6 @@ extern "C" { void cmDataPrint( const cmData_t* p, cmRpt_t* rpt ); void cmDataTest( cmCtx_t* ctx ); -#endif #ifdef __cplusplus From e6933b61d2fe971d4e753b2939c664578ff456da Mon Sep 17 00:00:00 2001 From: kevin Date: Tue, 19 Nov 2013 11:06:56 -0500 Subject: [PATCH 20/23] cmScore.c : Fixed bug in _cmScParseFile() where _cmScParseSectionColumn() overwrote 'rc' and thereby prevented the functio from returning the correct result code on fail. --- app/cmScore.c | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/app/cmScore.c b/app/cmScore.c index 355fa41..8637a24 100644 --- a/app/cmScore.c +++ b/app/cmScore.c @@ -1306,27 +1306,30 @@ cmScRC_t _cmScParseFile( cmSc_t* p, cmCtx_t* ctx, const cmChar_t* fn ) break; } - if( secs != DBL_MAX ) - cur_secs = secs; - - // form the section list - if( j > 0 ) - if((rc = _cmScParseSectionColumn(p,i,j-1,p->sectList)) != kOkScRC ) - break; - - // the bar lines don't have times so set the time of the bar line to the - // time of the first event in the bar. - if( barEvtIdx != cmInvalidIdx && secs != DBL_MAX ) + if( rc == kOkScRC ) { - assert( p->array[ barEvtIdx ].type == kBarEvtScId ); - p->array[ barEvtIdx ].secs = secs; + if( secs != DBL_MAX ) + cur_secs = secs; - // handle the case where the previous bar had no events - // BUG BUG BUG this is a hack which will fail if the first bar does not have events. - if( barEvtIdx>=1 && p->array[ barEvtIdx-1].type == kBarEvtScId ) - p->array[ barEvtIdx-1].secs = secs; + // form the section list + if( j > 0 ) + if((rc = _cmScParseSectionColumn(p,i,j-1,p->sectList)) != kOkScRC ) + break; - barEvtIdx = cmInvalidIdx; + // the bar lines don't have times so set the time of the bar line to the + // time of the first event in the bar. + if( barEvtIdx != cmInvalidIdx && secs != DBL_MAX ) + { + assert( p->array[ barEvtIdx ].type == kBarEvtScId ); + p->array[ barEvtIdx ].secs = secs; + + // handle the case where the previous bar had no events + // BUG BUG BUG this is a hack which will fail if the first bar does not have events. + if( barEvtIdx>=1 && p->array[ barEvtIdx-1].type == kBarEvtScId ) + p->array[ barEvtIdx-1].secs = secs; + + barEvtIdx = cmInvalidIdx; + } } } From ebef000a277a3638ac38386732d000da408b95ce Mon Sep 17 00:00:00 2001 From: kevin Date: Tue, 19 Nov 2013 11:07:22 -0500 Subject: [PATCH 21/23] cmData.h/c: Commented out uncompilable bits. --- cmData.c | 6 +++++- cmData.h | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/cmData.c b/cmData.c index b1580f8..db0cdae 100644 --- a/cmData.c +++ b/cmData.c @@ -1009,6 +1009,7 @@ cmDtRC_t cmDataDoubleArray( const cmData_t* d, double** v ) return kOkDtRC; } +#ifdef NOT_DEF cmDtRC_t cmDataStrArray( const cmData_t* d, cmChar_t*** v ) { } @@ -1016,7 +1017,7 @@ cmDtRC_t cmDataStrArray( const cmData_t* d, cmChar_t*** v ) cmDtRC_t cmDataConstStrArray( const cmData_t* d, const cmChar_t*** v ) { } - +#endif @@ -1754,6 +1755,8 @@ cmData_t* cmDataRecdAllocIdA( cmData_t* parent, ... ) return p; } +#ifdef NOT_DEF + cmDtRC_t _cmDataRecdParseV(cmData_t* p, bool idFl, cmErr_t* err, unsigned errRC, va_list vl ) { bool contFl = true; @@ -2850,3 +2853,4 @@ void cmDataTest( cmCtx_t* ctx ) cmRptPrintf(&ctx->rpt,"Done!.\n"); } +#endif diff --git a/cmData.h b/cmData.h index e246944..0116183 100644 --- a/cmData.h +++ b/cmData.h @@ -127,7 +127,7 @@ extern "C" { unsigned flags; // struct cmData_str* parent; // this childs parent struct cmData_str* sibling; // this childs left sibling - unsigned cnt; // byte cnt for strings/blobs and ele count for arrays + unsigned cnt; // byte cnt for strings/blobs and ele count for arrays union { @@ -146,6 +146,7 @@ extern "C" { void* vp; + /* char* cp; unsigned char* ucp; short* sp; @@ -156,7 +157,7 @@ extern "C" { unsigned long* ulp; float* fp; double* dp; - + */ struct cmData_str* child; // first child (list,record,pair) } u; From 57d2a86a42a4f745cbb070eab3bb99156f4b775f Mon Sep 17 00:00:00 2001 From: kevin Date: Tue, 19 Nov 2013 11:08:08 -0500 Subject: [PATCH 22/23] cmProc4.h/c, cmDspKr.c : Added look-ahead buffer to cmRecdPlay object. --- cmProc4.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++--- cmProc4.h | 8 +++- dsp/cmDspKr.c | 16 ++++++- 3 files changed, 133 insertions(+), 11 deletions(-) diff --git a/cmProc4.c b/cmProc4.c index b312df6..f6a18a6 100644 --- a/cmProc4.c +++ b/cmProc4.c @@ -4134,11 +4134,11 @@ cmRC_t cmScModulatorDump( cmScModulator* p ) } //======================================================================================================================= -cmRecdPlay* cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs ) +cmRecdPlay* cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs ) { cmRecdPlay* op = cmObjAlloc(cmRecdPlay,c,p); - if( cmRecdPlayInit(op,srate,fragCnt,chCnt,initFragSecs) != cmOkRC ) + if( cmRecdPlayInit(op,srate,fragCnt,chCnt,initFragSecs,maxLaSecs,curLaSecs) != cmOkRC ) cmRecdPlayFree(&op); return op; @@ -4159,26 +4159,40 @@ cmRC_t cmRecdPlayFree( cmRecdPlay** pp ) } -cmRC_t cmRecdPlayInit( cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs ) +cmRC_t cmRecdPlayInit( cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs ) { - cmRC_t rc; + unsigned i; + + if( curLaSecs > maxLaSecs ) + return cmCtxRtCondition( &p->obj, cmInvalidArgRC, "The initial look-ahead time %f is greater than the maximum look-ahead time %f.",curLaSecs,maxLaSecs); if((rc = cmRecdPlayFinal(p)) != cmOkRC ) return rc; + if( chCnt == 0 ) + return cmOkRC; + p->frags = cmMemAllocZ(cmRecdPlayFrag,fragCnt); p->fragCnt = fragCnt; p->srate = srate; p->chCnt = chCnt; p->initFragSecs = initFragSecs; + p->maxLaSmpCnt = floor(maxLaSecs*srate); + p->curLaSmpCnt = floor(curLaSecs*srate); + p->laChs = cmMemAllocZ(cmSample_t*,chCnt); + p->laSmpIdx = 0; + for(i=0; ilaChs[i] = cmMemAllocZ(cmSample_t,p->maxLaSmpCnt); + return rc; } cmRC_t cmRecdPlayFinal( cmRecdPlay* p ) { unsigned i,j; + // free the fragments for(i=0; ifragCnt; ++i) { for(j=0; jchCnt; ++j) @@ -4186,9 +4200,17 @@ cmRC_t cmRecdPlayFinal( cmRecdPlay* p ) cmMemFree(p->frags[i].chArray); } - cmMemFree(p->frags); - p->fragCnt=0; - p->chCnt=0; + + // free the look-ahead buffers + for(i=0; ichCnt; ++i) + cmMemFree(p->laChs[i]); + + cmMemPtrFree(&p->laChs); + cmMemPtrFree(&p->frags); + p->fragCnt = 0; + p->chCnt = 0; + p->rlist = NULL; + p->plist = NULL; return cmOkRC; } @@ -4216,6 +4238,8 @@ cmRC_t cmRecdPlayRewind( cmRecdPlay* p ) { unsigned i; + p->laSmpIdx = 0; + while( p->plist != NULL ) cmRecdPlayEndPlay(p,p->plist->labelSymId); @@ -4228,6 +4252,7 @@ cmRC_t cmRecdPlayRewind( cmRecdPlay* p ) return cmOkRC; } + cmRC_t cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId ) { unsigned i; @@ -4242,6 +4267,39 @@ cmRC_t cmRecdPlayBeginRecord( cmRecdPlay* p, unsigned labelSymId ) p->frags[i].playIdx = 0; p->frags[i].rlink = p->rlist; p->rlist = p->frags + i; + + // handle LA buf longer than frag buf. + int cpyCnt = cmMin(p->curLaSmpCnt,p->frags[i].allocCnt); + + // go backwards in LA buf from newest sample to find init src offset + int srcOffs = p->laSmpIdx - cpyCnt; + + // if the src is before the first sample in the LA buf then wrap to end of buf + if( srcOffs < 0 ) + srcOffs += p->maxLaSmpCnt; + + assert( 0 <= srcOffs && srcOffs < p->maxLaSmpCnt ); + + // cnt of samples to copy from LA buf (limited by end of LA buf) + int n0 = cmMin(cpyCnt,p->maxLaSmpCnt - srcOffs); + + // if necessary wrap to begin of LA buf for remaining samples + int n1 = cpyCnt>n0 ? n1 = cpyCnt-n0 : 0; + int j; + + assert(n0+n1 == cpyCnt ); + + for(j=0; jchCnt; ++j) + cmVOS_Copy(p->frags[i].chArray[j],n0,p->laChs[j]+srcOffs); + + if( n1 > 0 ) + { + for(j=0; jchCnt; ++j) + cmVOS_Copy(p->frags[i].chArray[j]+n0,n1,p->laChs[j]); + } + + p->frags[i].recdIdx = cpyCnt; + } return cmOkRC; @@ -4341,8 +4399,53 @@ cmRC_t cmRecdPlayBeginFade( cmRecdPlay* p, unsigned labelSymId, double fadeDbP cmRC_t cmRecdPlayExec( cmRecdPlay* p, const cmSample_t** iChs, cmSample_t** oChs, unsigned chCnt, unsigned smpCnt ) { + unsigned i; + chCnt = cmMin(chCnt, p->chCnt); + //------------------------------------------------------------------- + // copy incoming audio into the look-head buffers + // + + // if the number of incoming samples is longer than the look-head buffer + // then copy exactly maxLaSmpCnt samples from the end of the incoming sample + // buffer to the look-ahead buffer. + unsigned srcOffs = 0; + unsigned srcSmpCnt = smpCnt; + if( srcSmpCnt > p->maxLaSmpCnt ) + { + // advance incoming sample buffer so that there are maxLaSmpCnt samples remaining + srcOffs = smpCnt-p->maxLaSmpCnt; + srcSmpCnt = p->maxLaSmpCnt; // decrease the total samples to copy + } + + // count of samples from cur posn to end of the LA buffer. + unsigned n0 = cmMin(srcSmpCnt, p->maxLaSmpCnt - p->laSmpIdx ); + + // count of samples past the end of the LA buffer to be wrapped into begin of buffer + unsigned n1 = srcSmpCnt>n0 ? srcSmpCnt-n0 : 0; + + assert(n0+n1 == srcSmpCnt); + + // copy first block to end of LA buffer + for(i=0; ilaChs[i]+p->laSmpIdx,n0,iChs[i] + srcOffs); + + p->laSmpIdx += n0; + + if( n1!=0) + { + // copy second block to begin of LA buffer + for(i=0; ilaChs[i],n1,iChs[i] + srcOffs + n0); + + p->laSmpIdx = n1; + + } + + //------------------------------------------------------------------- + // copy incoming audio into the active record buffers + // cmRecdPlayFrag* fp = p->rlist; for(; fp!=NULL; fp=fp->rlink) @@ -4357,6 +4460,9 @@ cmRC_t cmRecdPlayExec( cmRecdPlay* p, const cmSample_t** iChs, cmSample_ } } + //------------------------------------------------------------------- + // copy outgoing audio out of the active play buffers + // fp = p->plist; for(; fp!=NULL; fp=fp->rlink) { diff --git a/cmProc4.h b/cmProc4.h index 36b88d2..8ad104e 100644 --- a/cmProc4.h +++ b/cmProc4.h @@ -649,14 +649,18 @@ extern "C" { double srate; // system sample rate unsigned chCnt; // count of input and output audio channels double initFragSecs; // size initial memory allocated to each frag in seconds + unsigned maxLaSmpCnt; // samples allocated to each channel of the look-ahead buffers. + unsigned curLaSmpCnt; // current look-ahead time in samples (curLaSmpCnt<=maxLaSmpCnt) + cmSample_t** laChs; // laChs[chCnt][maxLaSmpCnt] - look-ahead buffers + int laSmpIdx; // next look-ahead buffer index to receive a sample cmRecdPlayFrag* plist; // currently playing frags cmRecdPlayFrag* rlist; // currently recording frags } cmRecdPlay; - cmRecdPlay* cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs ); + cmRecdPlay* cmRecdPlayAlloc( cmCtx* c, cmRecdPlay* p, double srate, unsigned fragCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs ); cmRC_t cmRecdPlayFree( cmRecdPlay** pp ); - cmRC_t cmRecdPlayInit( cmRecdPlay* p, double srate, unsigned flagCnt, unsigned chCnt, double initFragSecs ); + cmRC_t cmRecdPlayInit( cmRecdPlay* p, double srate, unsigned flagCnt, unsigned chCnt, double initFragSecs, double maxLaSecs, double curLaSecs ); cmRC_t cmRecdPlayFinal( cmRecdPlay* p ); cmRC_t cmRecdPlayRegisterFrag( cmRecdPlay* p, unsigned fragIdx, unsigned labelSymId ); diff --git a/dsp/cmDspKr.c b/dsp/cmDspKr.c index 178016b..a19bb2f 100644 --- a/dsp/cmDspKr.c +++ b/dsp/cmDspKr.c @@ -2271,6 +2271,8 @@ enum kChCntPrId, kFnPrId, kSecsPrId, + kMaxLaSecsPrId, + kCurLaSecsPrId, kFadeRatePrId, kScLocIdxPrId, kCmdPrId, @@ -2311,8 +2313,11 @@ cmDspRC_t _cmDspRecdPlayOpenScore( cmDspCtx_t* ctx, cmDspInst_t* inst ) { unsigned i; unsigned markerCnt = cmScoreMarkerLabelCount(p->scH); + double initFragSecs = cmDspDouble(inst,kSecsPrId); + double maxLaSecs = cmDspDouble(inst,kMaxLaSecsPrId); + double curLaSecs = cmDspDouble(inst,kCurLaSecsPrId); - if((p->rcdply = cmRecdPlayAlloc(ctx->cmProcCtx, NULL, cmDspSampleRate(ctx), markerCnt, p->chCnt, cmDspDouble(inst,kSecsPrId))) == NULL) + if((p->rcdply = cmRecdPlayAlloc(ctx->cmProcCtx, NULL, cmDspSampleRate(ctx), markerCnt, p->chCnt, initFragSecs, maxLaSecs, curLaSecs)) == NULL) return cmErrMsg(&inst->classPtr->err,kSubSysFailDspRC,"Unable to create the internal recorder-player object."); for(i=0; iscLocIdx = 0; cmDspSetDefaultDouble(ctx,&p->inst, kSecsPrId, 0, 10.0 ); + cmDspSetDefaultDouble(ctx,&p->inst, kMaxLaSecsPrId,0, 2.0); + cmDspSetDefaultDouble(ctx,&p->inst, kCurLaSecsPrId,0, 0.5); cmDspSetDefaultDouble(ctx,&p->inst, kFadeRatePrId, 0, 1.0); return &p->inst; @@ -2446,6 +2455,9 @@ cmDspRC_t _cmDspRecdPlayRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ break; + case kCurLaSecsPrId: + break; + case kScLocIdxPrId: { unsigned endScLocIdx = cmDspUInt(inst,kScLocIdxPrId) ; @@ -2474,7 +2486,7 @@ cmDspRC_t _cmDspRecdPlayRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_ break; case kPlayEndScMId: - printf("recd-end\n"); + printf("play-end\n"); cmRecdPlayEndPlay(p->rcdply, mp->labelSymId ); break; From 031210c7e911baf2c970a73cda99828669914bc4 Mon Sep 17 00:00:00 2001 From: kevin Date: Tue, 19 Nov 2013 11:08:56 -0500 Subject: [PATCH 23/23] cmDspPgmKr.c : Added look-head parameters for cmDspRecdPlay object. --- dsp/cmDspPgmKr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dsp/cmDspPgmKr.c b/dsp/cmDspPgmKr.c index ccbacd3..6ee2b81 100644 --- a/dsp/cmDspPgmKr.c +++ b/dsp/cmDspPgmKr.c @@ -98,6 +98,8 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) double cmpWndMs = 200.0; double recdPlayInitAllocSecs = 10.0; + double recdPlayMaxLaSecs = 2.0; + double recdPlayCurLaSecs = 0.1; double recdPlayFadeRateDbPerSec = 4.0; memset(&r,0,sizeof(r)); @@ -123,7 +125,7 @@ cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr ) cmDspInst_t* mop = cmDspSysAllocInst(h,"MidiOut", NULL, 2, r.midiDevice,r.midiOutPort); cmDspInst_t* sfp = cmDspSysAllocInst(h,"ScFol", NULL, 1, r.scFn ); cmDspInst_t* amp = cmDspSysAllocInst(h,"ActiveMeas", NULL, 1, 100 ); - cmDspInst_t* rpp = cmDspSysAllocInst(h,"RecdPlay", NULL, 4, 2, r.scFn, recdPlayInitAllocSecs, recdPlayFadeRateDbPerSec ); + cmDspInst_t* rpp = cmDspSysAllocInst(h,"RecdPlay", NULL, 4, 2, r.scFn, recdPlayInitAllocSecs, recdPlayMaxLaSecs, recdPlayCurLaSecs, recdPlayFadeRateDbPerSec ); cmDspInst_t* modp = cmDspSysAllocInst(h,"ScMod", NULL, 2, r.modFn, "m1" ); cmDspInst_t* asp = cmDspSysAllocInst(h,"AmSync", NULL, 0 );