diff --git a/.gitignore b/.gitignore index 5474511..f8c1d3b 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ subprojects/zlib-* .xmake/ .DS_Store test/sizeof +temp/* diff --git a/das2/array.h b/das2/array.h index beceb12..f9e0293 100644 --- a/das2/array.h +++ b/das2/array.h @@ -49,6 +49,8 @@ extern "C" { #define DASIDX_FUNC -2 #define DASIDX_UNUSED -3 +#define ARYIDX_LAST {-1,-1,-1,-1-1,-1,-1,-1} + /* #define DASIDX_INIT_UNUSED {-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3} #define DASIDX_INIT_BEGIN { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} diff --git a/das2/processor.h b/das2/processor.h index cb5a550..71c13a8 100644 --- a/das2/processor.h +++ b/das2/processor.h @@ -34,11 +34,11 @@ extern "C" { /** Definition of the callback function invoked when a stream header is * encountered in the input. - * @param sd A pointer to the parsed StreamDesc + * @param sd A pointer to the parsed DasStream * @param pd A pointer to a user data structure, may be NULL. * @see StreamHandler */ -typedef DasErrCode (*StreamDescHandler)(StreamDesc* sd, void* ud); +typedef DasErrCode (*DasStreamHandler)(DasStream* sd, void* ud); /** Definition of the callback function invoked when a packet header is * encountered in the input. @@ -47,7 +47,7 @@ typedef DasErrCode (*StreamDescHandler)(StreamDesc* sd, void* ud); * @param ud A pointer to a user data structure, may be NULL. * @see StreamHandler */ -typedef DasErrCode (*PktDescHandler)(StreamDesc* sd, PktDesc* pd, void* ud); +typedef DasErrCode (*PktDescHandler)(DasStream* sd, PktDesc* pd, void* ud); /** Definition of the callback function invoked when a packet header is * going to be deleted. This only occurs if streams re-define packet IDs @@ -57,7 +57,7 @@ typedef DasErrCode (*PktDescHandler)(StreamDesc* sd, PktDesc* pd, void* ud); * @param ud A pointer to a user data structure, may be NULL. * @see StreamHandler */ -typedef DasErrCode (*PktRedefHandler)(StreamDesc* sd, PktDesc* pd, void* ud); +typedef DasErrCode (*PktRedefHandler)(DasStream* sd, PktDesc* pd, void* ud); /** Callback function invoked when a data packet is encountered in the input. * @param sd A pointer to the parsed Packet Descriptor @@ -77,7 +77,7 @@ typedef DasErrCode (*PktDataHandler)(PktDesc* pd, void* ud); * * @param */ -typedef DasErrCode (*DsDescHandler)(StreamDesc* sd, int pi, DasDs* dd, void* ud); +typedef DasErrCode (*DsDescHandler)(DasStream* sd, int pi, DasDs* dd, void* ud); /** Callback function invoked when a new data packets for a dataset are * encountered on the stream. @@ -89,7 +89,7 @@ typedef DasErrCode (*DsDescHandler)(StreamDesc* sd, int pi, DasDs* dd, void* ud) * new data were added * @param ud A pointer to a user data structure, may be NULL */ -typedef DasErrCode (*DsDataHandler)(StreamDesc* sd, int pi, DasDs* dd, void* ud); +typedef DasErrCode (*DsDataHandler)(DasStream* sd, int pi, DasDs* dd, void* ud); /** Callback functions that are invoked on Stream Close * callback function that is called at the end of the stream @@ -97,7 +97,7 @@ typedef DasErrCode (*DsDataHandler)(StreamDesc* sd, int pi, DasDs* dd, void* ud) * @param ud A pointer to a user data structure, may be NULL. * @see StreamHandler */ -typedef DasErrCode (*CloseHandler)(StreamDesc* sd, void* ud); +typedef DasErrCode (*CloseHandler)(DasStream* sd, void* ud); /** Callback functions that handle exceptions * @param se A pointer to the parsed Exception @@ -123,7 +123,7 @@ typedef struct _streamHandler { * This is the header with the element \\ in the input * file. */ - StreamDescHandler streamDescHandler; + DasStreamHandler streamDescHandler; /** Sets the function to be called when each \ element * is read in. diff --git a/das2/serial.c b/das2/serial.c index d95b9dc..9ea78ff 100644 --- a/das2/serial.c +++ b/das2/serial.c @@ -445,6 +445,7 @@ static void _serial_onOpenVar( strncpy(sIndex, psAttr[i+1], 31); else if(strcmp(psAttr[i], "units") == 0) pCtx->varUnits = Units_fromStr(psAttr[i+1]); + /* else if(strcmp(psAttr[i], )) */ /* Temporarily ignore values that are running around in wild */ else diff --git a/utilities/das3_cdf.c b/utilities/das3_cdf.c index 68adb86..0f0b744 100644 --- a/utilities/das3_cdf.c +++ b/utilities/das3_cdf.c @@ -44,9 +44,6 @@ #define PROG "das3_cdf" #define PERR 63 -/* Handle lack of const qualifier on CDFvarNum */ -#define CDFvarId(id, str) CDFgetVarNum((id), (char*) (str)) - #define NEW_FILE_MODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH #define DEF_AUTH_FILE ".dasauth" @@ -465,7 +462,7 @@ bool _cdfOkayish(CDFstatus iStatus){ ubyte g_propBuf[PROP_XFORM_SZ]; -const char* DasProp_cdfName(const DasProp* pProp) +const char* DasProp_cdfVarName(const DasProp* pProp) { /* Translate some of the common das property names to CDF names */ const char* sName = DasProp_name(pProp); @@ -489,6 +486,40 @@ const char* DasProp_cdfName(const DasProp* pProp) return sName; } +const char* DasProp_cdfGlobalName(const DasProp* pProp) +{ + /* Make sure some common variable property names are not used in + the global section, since CDF has only one property namespace */ + const char* sName = DasProp_name(pProp); + + /* Converts some das dataset level properties to CDF global names */ + if(strcmp(sName, "summary" ) == 0) return "TEXT"; + if(strcmp(sName, "info" ) == 0) return "TEXT"; + if(strcmp(sName, "title" ) == 0) return "TITLE"; + if(strcmp(sName, "label" ) == 0) return "TITLE"; + + /* Otherwise, just make sure we don't accidentally step on variable attributes */ + if(strcmp(sName, "CATDESC" ) == 0) return "G_CATDESC"; + if(strcmp(sName, "FILLVAL" ) == 0) return "G_FILLVAL"; + if(strcmp(sName, "FORMAT" ) == 0) return "G_FORMAT"; + if(strcmp(sName, "VAR_NOTES" ) == 0) return "G_VAR_NOTES"; + if(strcmp(sName, "LABLAXIS" ) == 0) return "G_LABLAXIS"; + if(strcmp(sName, "LIMITS_NOMINAL_MIN") == 0) return "G_LIMITS_NOMINAL_MIN"; + if(strcmp(sName, "LIMITS_NOMINAL_MAX") == 0) return "G_LIMITS_NOMINAL_MAX"; + if(strcmp(sName, "SCALEMIN" ) == 0) return "G_SCALEMIN"; + if(strcmp(sName, "SCALEMAX" ) == 0) return "G_SCALEMAX"; + if(strcmp(sName, "SCALETYP" ) == 0) return "G_SCALETYP"; + if(strcmp(sName, "VAR_NOTES" ) == 0) return "G_VAR_NOTES"; + if(strcmp(sName, "FIELDNAM" ) == 0) return "G_FIELDNAM"; + if(strcmp(sName, "VALIDMIN" ) == 0) return "G_VALIDMIN"; + if(strcmp(sName, "VALIDMAX" ) == 0) return "G_VALIDMAX"; + if(strcmp(sName, "LIMITS_WARN_MIN" ) == 0) return "G_LIMITS_WARN_MIN"; + if(strcmp(sName, "LIMITS_WARN_M" ) == 0) return "G_LIMITS_WARN_M"; + + return sName; +} + + /* Get the number of entries for a property. Only global properties are allowed to have multiple entries. Typically only string data are allowed to have entries. We'll interpret this to be 1 except for long @@ -533,6 +564,31 @@ long DasProp_cdfType(const DasProp* pProp) return 0; } +/* Make logging output more readable */ +const char* cdfTypeStr(long nCdfType){ + switch(nCdfType){ + case CDF_INT1: return "CDF_INT1"; + case CDF_INT2: return "CDF_INT2"; + case CDF_INT4: return "CDF_INT4"; + case CDF_INT8: return "CDF_INT8"; + case CDF_UINT1: return "CDF_UINT1"; + case CDF_UINT2: return "CDF_UINT2"; + case CDF_UINT4: return "CDF_UINT4"; + case CDF_REAL4: return "CDF_REAL4"; + case CDF_REAL8: return "CDF_REAL8"; + case CDF_EPOCH: return "CDF_EPOCH"; /* Standard style. */ + case CDF_EPOCH16: return "CDF_EPOCH16"; /* Extended style. */ + /* One more style with leap seconds and J2000 base time. */ + case CDF_TIME_TT2000: return "CDF_TIME_TT2000"; + case CDF_BYTE: return "CDF_BYTE"; /* same as CDF_INT1 (signed) */ + case CDF_FLOAT: return "CDF_FLOAT"; /* same as CDF_REAL4 */ + case CDF_DOUBLE: return "CDF_DOUBLE"; /* same as CDF_REAL8 */ + case CDF_CHAR: return "CDF_CHAR"; /* a "string" data type */ + case CDF_UCHAR: return "CDF_UCHAR"; /* a "string" data type */ + default: return "CDF_UNKNOWN"; + } +} + long DasProp_cdfEntLen(const DasProp* pProp, long iEntry) { /* Non-strings only have one entry */ @@ -676,7 +732,7 @@ DasErrCode writeGlobalProp(struct context* pCtx, const DasProp* pProp) long n = DasProp_cdfEntries(pProp); for(long iEntry = 0; iEntry < n; ++iEntry){ - sName = DasProp_cdfName(pProp); + sName = DasProp_cdfGlobalName(pProp); /* Prop filtering, 1. For global props that start with inst just skip past that part @@ -705,7 +761,10 @@ DasErrCode writeGlobalProp(struct context* pCtx, const DasProp* pProp) /* Get attribute number or make a new (why can't CDFlib use "const", is it really so hard? */ - if((iAttr = CDFgetAttrNum(pCtx->nCdfId, (char*)sName)) <= 0){ + if((iAttr = CDFattrId(pCtx->nCdfId, sName)) <= 0){ + daslog_info_v( + "Auto global attribute %s (%s)", sName, cdfTypeStr(DasProp_cdfType(pProp)) + ); if(CDF_MAD(CDFcreateAttr(pCtx->nCdfId, sName, GLOBAL_SCOPE, &iAttr))) return PERR; } @@ -729,12 +788,25 @@ DasErrCode writeVarProp(struct context* pCtx, long iVarNum, const DasProp* pProp { CDFstatus iStatus; /* Used by CDF_MAD macro */ - /* If the attribute doesn't exist, we'll need to create it first */ - long iAttr; - - const char* sName = DasProp_cdfName(pProp); + const char* sName = DasProp_cdfVarName(pProp); + long iAttr = CDFattrId(pCtx->nCdfId, sName); + long nScope = 0L; /* from cdf.h, this is NO_SCOPE */ + if(iAttr >= 0){ + if(CDF_MAD(CDFgetAttrScope(pCtx->nCdfId, iAttr, &nScope))) + return PERR; + if(nScope != VARIABLE_SCOPE){ + return das_error(PERR, + "CDF Limitiation: attribute name '%s' cannot be used for variables" + " because it's already a global attribute.", sName + ); + } + } - if((iAttr = CDFattrId(pCtx->nCdfId, sName)) < 0){ + /* If the attribute doesn't exist in var scope, we'll need to create it first */ + if((iAttr < 0)){ + daslog_info_v( + "Auto variable attribute %s (%s)", sName, cdfTypeStr(DasProp_cdfType(pProp)) + ); if(CDF_MAD(CDFcreateAttr(pCtx->nCdfId,sName,VARIABLE_SCOPE,&iAttr))) return PERR; } @@ -744,13 +816,21 @@ DasErrCode writeVarProp(struct context* pCtx, long iVarNum, const DasProp* pProp if(DasProp_cdfType(pProp) == CDF_UCHAR) nElements = strlen(DasProp_value(pProp)); + /* Hook in spots for debugging */ + long nType = DasProp_cdfType(pProp); + void* pVal = DasProp_cdfValues(pProp); + + daslog_debug_v("New attribute entry for varible #%ld, %s (attrid: %ld attrtype %ld)", + iVarNum, sName, iAttr, nType + ); + if(CDF_MAD(CDFputAttrzEntry( pCtx->nCdfId, iAttr, iVarNum, - DasProp_cdfType(pProp), + nType, nElements, - DasProp_cdfValues(pProp) + pVal ))) return PERR; @@ -770,15 +850,20 @@ DasErrCode writeVarStrAttr( /* If the attribute doesn't exist, we'll need to create it first */ long iAttr; if((iAttr = CDFattrId(pCtx->nCdfId, sAttrName)) < 0){ + daslog_info_v("Auto variable attribute %s (%s)", sAttrName, cdfTypeStr(CDF_UCHAR)); if(CDF_MAD(CDFcreateAttr(pCtx->nCdfId, sAttrName, VARIABLE_SCOPE, &iAttr ))) return PERR; } + daslog_debug_v("Writing attribute %s (attrid: %ld attrtype:%ld) for variable #%ld", + sAttrName, iAttr, CDF_UCHAR, iVarNum + ); + if(CDF_MAD(CDFputAttrzEntry( pCtx->nCdfId, iAttr, iVarNum, - CDF_CHAR, + CDF_UCHAR, (long) strlen(sValue), (void*)sValue ))) @@ -806,6 +891,10 @@ DasErrCode writeVarAttr( return PERR; } + daslog_debug_v("Writing attribute %s (attrid: %ld attrtype:%ld) for variable #%ld", + sAttrName, iAttr, nCdfType, iVarNum + ); + if(CDF_MAD(CDFputAttrzEntry( pCtx->nCdfId, iAttr, @@ -1341,6 +1430,11 @@ long DasVar_cdfNonRecDims( return nUsed; } +/** create a unique variable in the cdf output file + * + * @param[out] sNmaeBuf a buffer to reciver the variable name must point to at least + * DAS_MAX_ID_BUFSZ bytes of space + */ DasErrCode makeCdfVar( struct context* pCtx, DasDim* pDim, DasVar* pVar, int nDsRank, ptrdiff_t* pDsShape, char* sNameBuf @@ -1378,6 +1472,8 @@ DasErrCode makeCdfVar( nCharLen = aIntr[0]; } + daslog_info_v("Auto variable %s", sNameBuf); + CDFstatus iStatus = CDFcreatezVar( pCtx->nCdfId, /* CDF File ID */ sNameBuf, /* Varible's name */ @@ -1537,7 +1633,7 @@ DasErrCode makeCompLabels(struct context* pCtx, DasDim* pDim, DasVar* pVar) if(CDF_MAD(CDFcreatezVar( pCtx->nCdfId, /* CDF File ID */ sLblVarName, /* label varible's name */ - CDF_CHAR, /* CDF type of variable data */ + CDF_UCHAR, /* CDF type of variable data */ nMaxCompLen, /* Character length */ 1, /* We have 1 non-record dim */ &nNumComp, /* Number of components in first non-record dim */