Commit 7926ed06 authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

patch 0001-added-tile-support-to-the-iterator-interface

parent b054fa1c
...@@ -411,6 +411,8 @@ char *cdiIterator_inqVTime(CdiIterator *me); //Returns the validity date as ...@@ -411,6 +411,8 @@ char *cdiIterator_inqVTime(CdiIterator *me); //Returns the validity date as
int cdiIterator_inqLevelType(CdiIterator *me, int levelSelector, char **outName_optional, char **outLongName_optional, char **outStdName_optional, char **outUnit_optional); //callers are responsible to Free() strings that they request int cdiIterator_inqLevelType(CdiIterator *me, int levelSelector, char **outName_optional, char **outLongName_optional, char **outStdName_optional, char **outUnit_optional); //callers are responsible to Free() strings that they request
int cdiIterator_inqLevel(CdiIterator *me, int levelSelector, double *outValue1_optional, double *outValue2_optional); //outValue2 is only written to if the level is a hybrid level int cdiIterator_inqLevel(CdiIterator *me, int levelSelector, double *outValue1_optional, double *outValue2_optional); //outValue2 is only written to if the level is a hybrid level
int cdiIterator_inqLevelUuid(CdiIterator *me, int *outVgridNumber_optional, int *outLevelCount_optional, unsigned char outUuid_optional[CDI_UUID_SIZE]); //outUuid must point to a buffer of 16 bytes, returns an error code if no generalized zaxis is used. int cdiIterator_inqLevelUuid(CdiIterator *me, int *outVgridNumber_optional, int *outLevelCount_optional, unsigned char outUuid_optional[CDI_UUID_SIZE]); //outUuid must point to a buffer of 16 bytes, returns an error code if no generalized zaxis is used.
int cdiIterator_inqTile(CdiIterator *me, int *outTileIndex, int *outTileAttribute); //Returns CDI_EINVAL if there is no tile information connected to the current field, *outTileIndex and *outTileAttribute will be set to -1 in this case.
int cdiIterator_inqTileCount(CdiIterator *me, int *outTileCount, int *outTileAttributeCount); //outTileAttributeCount is the count for the tile associated with the current field, a total attribute count cannot be inquired. Returns CDI_EINVAL if there is no tile information connected to the current field, *outTileCount and *outTileAttributeCount will be set to 0 in this case.
CdiParam cdiIterator_inqParam(CdiIterator *me); CdiParam cdiIterator_inqParam(CdiIterator *me);
int cdiIterator_inqDatatype(CdiIterator *me); int cdiIterator_inqDatatype(CdiIterator *me);
int cdiIterator_inqTsteptype(CdiIterator *me); int cdiIterator_inqTsteptype(CdiIterator *me);
...@@ -1180,6 +1182,9 @@ int subtypeInqSubEntry(int subtypeID, subtype_query_t criterion); ...@@ -1180,6 +1182,9 @@ int subtypeInqSubEntry(int subtypeID, subtype_query_t criterion);
/* subtypeInqTile: Specialized version of subtypeInqSubEntry looking for tile/attribute pair. */ /* subtypeInqTile: Specialized version of subtypeInqSubEntry looking for tile/attribute pair. */
int subtypeInqTile(int subtypeID, int tileindex, int attribute); int subtypeInqTile(int subtypeID, int tileindex, int attribute);
/* subtypeInqAttribute: Inquire the value of a subtype attribute. Returns CDI_EINVAL if the attribute does not exist.*/
int subtypeInqAttribute(int subtypeID, int index, const char *key, int *outValue);
/* vlistInqVarSubtype: Return subtype ID for a given variable. */ /* vlistInqVarSubtype: Return subtype ID for a given variable. */
int vlistInqVarSubtype(int vlistID, int varID); int vlistInqVarSubtype(int vlistID, int varID);
......
...@@ -274,7 +274,8 @@ static int getAvailabilityOfRelativeTimes(grib_handle* gh, bool* outHaveForecast ...@@ -274,7 +274,8 @@ static int getAvailabilityOfRelativeTimes(grib_handle* gh, bool* outHaveForecast
*outHaveForecastTime = false, *outHaveTimeRange = false; *outHaveForecastTime = false, *outHaveTimeRange = false;
return 0; return 0;
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 15: case 32: case 33: case 40: case 41: case 44: case 45: case 48: case 51: case 53: case 54: case 60: case 1000: case 1002: case 1100: case 40033: //case 55 and case 40455 are the same: 55 is the proposed standard value, 40455 is the value in the local use range that is used by the dwd until the standard is updated.
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 15: case 32: case 33: case 40: case 41: case 44: case 45: case 48: case 51: case 53: case 54: case 55: case 60: case 1000: case 1002: case 1100: case 40033: case 40055:
*outHaveForecastTime = true, *outHaveTimeRange = false; *outHaveForecastTime = true, *outHaveTimeRange = false;
return 0; return 0;
......
...@@ -700,6 +700,105 @@ int cdiIterator_inqLevelUuid(CdiIterator* me, int* outVgridNumber, int* outLevel ...@@ -700,6 +700,105 @@ int cdiIterator_inqLevelUuid(CdiIterator* me, int* outVgridNumber, int* outLevel
} }
} }
/*
@Function cdiIterator_inqTile
@Title Inquire the tile information for the current field
@Prototype int cdiIterator_inqTile(CdiIterator* me, int* outTileIndex, int* outTileAttribute)
@Parameter
@item iterator The iterator to operate on.
@item outTileIndex The index of the current tile, -1 if no tile information is available.
@item outTileAttribute The attribute of the current tile, -1 if no tile information is available.
@Result An error code. CDI_EINVAL if there is no tile information associated with the current field.
@Description
Inquire the tile index and attribute for the current field.
*/
int cdiIterator_inqTile(CdiIterator* me, int* outTileIndex, int* outTileAttribute)
{
sanityCheck(me);
switch(me->filetype)
{
#ifdef HAVE_LIBGRIB_API
case FILETYPE_GRB:
case FILETYPE_GRB2:
return cdiGribIterator_inqTile(me, outTileIndex, outTileAttribute);
#endif
#ifdef HAVE_LIBNETCDF
case FILETYPE_NC:
case FILETYPE_NC2:
case FILETYPE_NC4:
case FILETYPE_NC4C:
#endif
#ifdef HAVE_LIBSERVICE
case FILETYPE_SRV:
#endif
#ifdef HAVE_LIBEXTRA
case FILETYPE_EXT:
#endif
#ifdef HAVE_LIBIEG
case FILETYPE_IEG:
#endif
return cdiFallbackIterator_inqTile(me, outTileIndex, outTileAttribute);
default:
Error(kUnexpectedFileTypeMessage);
return CDI_ELIBNAVAIL;
}
}
/**
@Function cdiIterator_inqTileCount
@Title Inquire the tile count and tile attribute counts for the current field
@Prototype int cdiIterator_inqTileCount(CdiIterator* me, int* outTileCount, int* outTileAttributeCount)
@Parameter
@item iterator The iterator to operate on.
@item outTileCount The number of tiles used for this variable, zero if no tile information is available.
@item outTileAttributeCount The number of attributes available for the tile of this field, zero if no tile information is available.
Note: This is not the global attribute count, which would be impossible to infer without reading the entire file if it's a GRIB file.
@Result An error code. CDI_EINVAL if there is no tile information associated with the current field.
@Description
Inquire the tile count and tile attribute counts for the current field.
*/
int cdiIterator_inqTileCount(CdiIterator* me, int* outTileCount, int* outTileAttributeCount)
{
sanityCheck(me);
switch(me->filetype)
{
#ifdef HAVE_LIBGRIB_API
case FILETYPE_GRB:
case FILETYPE_GRB2:
return cdiGribIterator_inqTileCount(me, outTileCount, outTileAttributeCount);
#endif
#ifdef HAVE_LIBNETCDF
case FILETYPE_NC:
case FILETYPE_NC2:
case FILETYPE_NC4:
case FILETYPE_NC4C:
#endif
#ifdef HAVE_LIBSERVICE
case FILETYPE_SRV:
#endif
#ifdef HAVE_LIBEXTRA
case FILETYPE_EXT:
#endif
#ifdef HAVE_LIBIEG
case FILETYPE_IEG:
#endif
return cdiFallbackIterator_inqTileCount(me, outTileCount, outTileAttributeCount);
default:
Error(kUnexpectedFileTypeMessage);
return CDI_ELIBNAVAIL;
}
}
/* /*
@Function cdiIterator_inqParam @Function cdiIterator_inqParam
@Title Get discipline, category, and number @Title Get discipline, category, and number
......
...@@ -11,11 +11,12 @@ ...@@ -11,11 +11,12 @@
struct CdiFallbackIterator { struct CdiFallbackIterator {
CdiIterator super; CdiIterator super;
int streamId, vlistId; int streamId, vlistId, subtypeId;
char *path; //needed for clone() & serialize() char *path; //needed for clone() & serialize()
int variableCount, curVariable; int variableCount, curVariable;
int curLevelCount, curLevel; int curLevelCount, curLevel;
int curSubtypeCount, curSubtype;
int curTimestep; int curTimestep;
}; };
...@@ -39,12 +40,15 @@ static CdiFallbackIterator *cdiFallbackIterator_condestruct(CdiFallbackIterator ...@@ -39,12 +40,15 @@ static CdiFallbackIterator *cdiFallbackIterator_condestruct(CdiFallbackIterator
if(me->vlistId == CDI_UNDEFID) goto closeStream; if(me->vlistId == CDI_UNDEFID) goto closeStream;
me->variableCount = vlistNvars(me->vlistId); me->variableCount = vlistNvars(me->vlistId);
if(me->variableCount <= 0) goto closeStream; if(me->variableCount <= 0) goto closeStream;
me->subtypeId = CDI_UNDEFID; //Will be set in cdiFallbackIterator_nextField()
me->curSubtypeCount = -1; //Will be set in cdiFallbackIterator_nextField()
me->curLevelCount = -1; //Will be set in cdiFallbackIterator_nextField() me->curLevelCount = -1; //Will be set in cdiFallbackIterator_nextField()
//These values are chosen so that the natural increment at the start of cdiFallbackIterator_nextField() will correctly position us at the first slice. //These values are chosen so that the natural increment at the start of cdiFallbackIterator_nextField() will correctly position us at the first slice.
me->curTimestep = 0; me->curTimestep = 0;
if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) goto closeStream; if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) goto closeStream;
me->curVariable = 0; me->curVariable = 0;
me->curSubtype = 0;
me->curLevel = -1; me->curLevel = -1;
me->path = strdup(path); me->path = strdup(path);
if(!me->path) goto closeStream; if(!me->path) goto closeStream;
...@@ -70,14 +74,20 @@ CdiIterator *cdiFallbackIterator_new(const char *path, int filetype) ...@@ -70,14 +74,20 @@ CdiIterator *cdiFallbackIterator_new(const char *path, int filetype)
return &cdiFallbackIterator_condestruct(NULL, path, filetype)->super; return &cdiFallbackIterator_condestruct(NULL, path, filetype)->super;
} }
//Fetches the info that is published by the variables in the base class from the current field. //Fetches the info that is derived from the current variable. Most of this is published by the data members in the base class.
static void fetchSuperInfo(CdiFallbackIterator *me) static void fetchVariableInfo(CdiFallbackIterator *me)
{ {
//Fetch data that's published via base class data members.
me->super.datatype = vlistInqVarDatatype(me->vlistId, me->curVariable); me->super.datatype = vlistInqVarDatatype(me->vlistId, me->curVariable);
me->super.timesteptype = vlistInqVarTsteptype(me->vlistId, me->curVariable); me->super.timesteptype = vlistInqVarTsteptype(me->vlistId, me->curVariable);
me->super.gridId = vlistInqVarGrid(me->vlistId, me->curVariable); me->super.gridId = vlistInqVarGrid(me->vlistId, me->curVariable);
int param = vlistInqVarParam(me->vlistId, me->curVariable); int param = vlistInqVarParam(me->vlistId, me->curVariable);
cdiDecodeParam(param, &me->super.param.number, &me->super.param.category, &me->super.param.discipline); cdiDecodeParam(param, &me->super.param.number, &me->super.param.category, &me->super.param.discipline);
//Fetch the current level and subtype counts.
me->curLevelCount = zaxisInqSize(vlistInqVarZaxis(me->vlistId, me->curVariable));
me->subtypeId = vlistInqVarSubtype(me->vlistId, me->curVariable);
me->curSubtypeCount = (me->subtypeId == CDI_UNDEFID) ? 1 : subtypeInqSize(me->subtypeId);
} }
CdiFallbackIterator *cdiFallbackIterator_clone(CdiIterator *super) CdiFallbackIterator *cdiFallbackIterator_clone(CdiIterator *super)
...@@ -93,10 +103,12 @@ CdiFallbackIterator *cdiFallbackIterator_clone(CdiIterator *super) ...@@ -93,10 +103,12 @@ CdiFallbackIterator *cdiFallbackIterator_clone(CdiIterator *super)
clone->curVariable = me->curVariable; clone->curVariable = me->curVariable;
clone->curLevelCount = me->curLevelCount; clone->curLevelCount = me->curLevelCount;
clone->curLevel = me->curLevel; clone->curLevel = me->curLevel;
clone->curSubtypeCount = me->curSubtypeCount;
clone->curSubtype = me->curSubtype;
clone->curTimestep = me->curTimestep; clone->curTimestep = me->curTimestep;
clone->super.isAdvanced = super->isAdvanced; clone->super.isAdvanced = super->isAdvanced;
if(super->isAdvanced) fetchSuperInfo(clone); if(super->isAdvanced) fetchVariableInfo(clone);
return clone; return clone;
} }
...@@ -107,8 +119,8 @@ char *cdiFallbackIterator_serialize(CdiIterator *super) ...@@ -107,8 +119,8 @@ char *cdiFallbackIterator_serialize(CdiIterator *super)
char *escapedPath = cdiEscapeSpaces(me->path); char *escapedPath = cdiEscapeSpaces(me->path);
char *result = (char *) Malloc(strlen(escapedPath) char *result = (char *) Malloc(strlen(escapedPath)
+ 5 * (3 * sizeof (int) * CHAR_BIT / 8 + 1) + 1); + 7 * (3 * sizeof (int) * CHAR_BIT / 8 + 1) + 1);
sprintf(result, "%s %d %d %d %d %d", escapedPath, me->variableCount, me->curVariable, me->curLevelCount, me->curLevel, me->curTimestep); sprintf(result, "%s %d %d %d %d %d %d %d", escapedPath, me->variableCount, me->curVariable, me->curLevelCount, me->curLevel, me->curSubtypeCount, me->curSubtype, me->curTimestep);
Free(escapedPath); Free(escapedPath);
return result; return result;
} }
...@@ -142,11 +154,13 @@ CdiFallbackIterator *cdiFallbackIterator_deserialize(const char *description) ...@@ -142,11 +154,13 @@ CdiFallbackIterator *cdiFallbackIterator_deserialize(const char *description)
decodeValue(me->curVariable, description); decodeValue(me->curVariable, description);
decodeValue(me->curLevelCount, description); decodeValue(me->curLevelCount, description);
decodeValue(me->curLevel, description); decodeValue(me->curLevel, description);
decodeValue(me->curSubtypeCount, description);
decodeValue(me->curSubtype, description);
decodeValue(me->curTimestep, description); decodeValue(me->curTimestep, description);
#undef decodeValue #undef decodeValue
if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) goto closeStream; if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) goto closeStream;
if(me->super.isAdvanced) fetchSuperInfo(me); if(me->super.isAdvanced) fetchVariableInfo(me);
return me; return me;
...@@ -164,17 +178,22 @@ fail: ...@@ -164,17 +178,22 @@ fail:
static int advance(CdiFallbackIterator *me) static int advance(CdiFallbackIterator *me)
{ {
me->curLevel++; me->curLevel++;
if(me->curLevel == me->curLevelCount) if(me->curLevel >= me->curLevelCount)
{ {
me->curLevel = 0; me->curLevel = 0;
me->curSubtype++;
if(me->curSubtype >= me->curSubtypeCount)
{
me->curSubtype = 0;
me->curVariable++; me->curVariable++;
if(me->curVariable == me->variableCount) if(me->curVariable >= me->variableCount)
{ {
me->curVariable = 0; me->curVariable = 0;
me->curTimestep++; me->curTimestep++;
if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) return CDI_EEOF; if(streamInqTimestep(me->streamId, me->curTimestep) <= 0) return CDI_EEOF;
} }
} }
}
return CDI_NOERR; return CDI_NOERR;
} }
...@@ -184,11 +203,7 @@ int cdiFallbackIterator_nextField(CdiIterator *super) ...@@ -184,11 +203,7 @@ int cdiFallbackIterator_nextField(CdiIterator *super)
int result = advance(me); int result = advance(me);
if(result) return result; if(result) return result;
if(!me->curLevel) if(!me->curLevel && !me->curSubtype) fetchVariableInfo(me); //Check whether we are processing a new variable/timestep and fetch the information that may have changed in this case.
{ //Fetch the information that may have changed (we are processing a new variable/timestep if this point is reached).
fetchSuperInfo(me);
me->curLevelCount = zaxisInqSize(vlistInqVarZaxis(me->vlistId, me->curVariable));
}
return CDI_NOERR; return CDI_NOERR;
} }
...@@ -278,6 +293,32 @@ int cdiFallbackIterator_zaxisUuid(CdiIterator *super, int *outVgridNumber, int * ...@@ -278,6 +293,32 @@ int cdiFallbackIterator_zaxisUuid(CdiIterator *super, int *outVgridNumber, int *
return CDI_NOERR; return CDI_NOERR;
} }
int cdiFallbackIterator_inqTile(CdiIterator *super, int *outTileIndex, int *outTileAttribute)
{
CdiFallbackIterator *me = (CdiFallbackIterator*)super;
if(!outTileIndex) outTileIndex = &(int){0};
if(!outTileAttribute) outTileAttribute = &(int){0};
int error = CDI_NOERR;
if(subtypeInqAttribute(me->subtypeId, me->curSubtype, "tileIndex", outTileIndex)) error = CDI_EINVAL;
if(subtypeInqAttribute(me->subtypeId, me->curSubtype, "tileAttribute", outTileAttribute)) error = CDI_EINVAL;
if(error) *outTileIndex = *outTileAttribute = -1; //Guarantee defined values in case of an error.
return error;
}
int cdiFallbackIterator_inqTileCount(CdiIterator *super, int *outTileCount, int *outTileAttributeCount)
{
CdiFallbackIterator *me = (CdiFallbackIterator*)super;
if(!outTileCount) outTileCount = &(int){0};
if(!outTileAttributeCount) outTileAttributeCount = &(int){0};
int error = CDI_NOERR;
if(subtypeInqAttribute(me->subtypeId, me->curSubtype, "numberOfTiles", outTileCount)) error = CDI_EINVAL;
if(subtypeInqAttribute(me->subtypeId, me->curSubtype, "numberOfTileAttributes", outTileAttributeCount)) error = CDI_EINVAL;
if(error) *outTileCount = *outTileAttributeCount = -1; //Guarantee defined values in case of an error.
return CDI_NOERR;
}
char *cdiFallbackIterator_copyVariableName(CdiIterator *super) char *cdiFallbackIterator_copyVariableName(CdiIterator *super)
{ {
CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super; CdiFallbackIterator *me = (CdiFallbackIterator*)(void *)super;
......
...@@ -26,6 +26,8 @@ int cdiFallbackIterator_levelType(CdiIterator *me, int levelSelector, char **out ...@@ -26,6 +26,8 @@ int cdiFallbackIterator_levelType(CdiIterator *me, int levelSelector, char **out
int cdiFallbackIterator_level(CdiIterator *me, int levelSelector, double *outValue1, double *outValue2); int cdiFallbackIterator_level(CdiIterator *me, int levelSelector, double *outValue1, double *outValue2);
int cdiFallbackIterator_zaxisUuid(CdiIterator *me, int *outVgridNumber, int *outLevelCount, unsigned char outUuid[CDI_UUID_SIZE]); int cdiFallbackIterator_zaxisUuid(CdiIterator *me, int *outVgridNumber, int *outLevelCount, unsigned char outUuid[CDI_UUID_SIZE]);
char *cdiFallbackIterator_copyVariableName(CdiIterator *me); char *cdiFallbackIterator_copyVariableName(CdiIterator *me);
int cdiFallbackIterator_inqTile(CdiIterator* me, int* outTileIndex, int* outTileAttribute);
int cdiFallbackIterator_inqTileCount(CdiIterator* me, int* outTileCount, int* outTileAttributeCount);
void cdiFallbackIterator_readField(CdiIterator *me, double *buffer, size_t *nmiss); void cdiFallbackIterator_readField(CdiIterator *me, double *buffer, size_t *nmiss);
void cdiFallbackIterator_readFieldF(CdiIterator *me, float *buffer, size_t *nmiss); void cdiFallbackIterator_readFieldF(CdiIterator *me, float *buffer, size_t *nmiss);
......
...@@ -21,14 +21,14 @@ ...@@ -21,14 +21,14 @@
struct CdiGribIterator { struct CdiGribIterator {
CdiIterator super; CdiIterator super;
CdiInputFile* file; CdiInputFile *file;
off_t fileOffset; off_t fileOffset;
unsigned char* gribBuffer; unsigned char *gribBuffer;
size_t bufferSize, curRecordSize; size_t bufferSize, curRecordSize;
#ifdef HAVE_LIBGRIB_API #ifdef HAVE_LIBGRIB_API
grib_handle* gribHandle; grib_handle *gribHandle;
#else #else
void* gribHandle; void *gribHandle;
#endif #endif
}; };
...@@ -88,7 +88,7 @@ CdiGribIterator *cdiGribIterator_makeClone(CdiIterator *super) ...@@ -88,7 +88,7 @@ CdiGribIterator *cdiGribIterator_makeClone(CdiIterator *super)
CdiGribIterator *me = (CdiGribIterator*)super; CdiGribIterator *me = (CdiGribIterator*)super;
//Allocate memory and copy data. (operations that may fail) //Allocate memory and copy data. (operations that may fail)
CdiGribIterator* result = (struct CdiGribIterator *) Malloc(sizeof(*result)); CdiGribIterator *result = (struct CdiGribIterator *) Malloc(sizeof(*result));
if(!result) goto fail; if(!result) goto fail;
result->file = me->file; result->file = me->file;
...@@ -139,9 +139,9 @@ char *cdiGribIterator_serialize(CdiIterator *super) ...@@ -139,9 +139,9 @@ char *cdiGribIterator_serialize(CdiIterator *super)
{ {
CdiGribIterator *me = (CdiGribIterator*)super; CdiGribIterator *me = (CdiGribIterator*)super;
const char* path = cdiInputFile_getPath(me->file); const char *path = cdiInputFile_getPath(me->file);
char* escapedPath = cdiEscapeSpaces(path); char *escapedPath = cdiEscapeSpaces(path);
char* result = (char *) Malloc(strlen(escapedPath) + 3 * sizeof(int) * CHAR_BIT/8); char *result = (char *) Malloc(strlen(escapedPath) + 3 * sizeof(int) * CHAR_BIT/8);
sprintf(result, "%s %zu", escapedPath, me->fileOffset); sprintf(result, "%s %zu", escapedPath, me->fileOffset);
Free(escapedPath); Free(escapedPath);
return result; return result;
...@@ -150,8 +150,8 @@ char *cdiGribIterator_serialize(CdiIterator *super) ...@@ -150,8 +150,8 @@ char *cdiGribIterator_serialize(CdiIterator *super)
CdiGribIterator *cdiGribIterator_deserialize(const char *description) CdiGribIterator *cdiGribIterator_deserialize(const char *description)
{ {
char* path; char *path;
CdiGribIterator* me = (CdiGribIterator *) Malloc(sizeof(*me)); CdiGribIterator *me = (CdiGribIterator *) Malloc(sizeof(*me));
if(!me) goto fail; if(!me) goto fail;
description = baseIter_constructFromString(&me->super, description); description = baseIter_constructFromString(&me->super, description);
...@@ -254,13 +254,13 @@ static ssize_t scanToGribMarker(CdiGribIterator *me) ...@@ -254,13 +254,13 @@ static ssize_t scanToGribMarker(CdiGribIterator *me)
static unsigned decode24(void *beData) static unsigned decode24(void *beData)
{ {
unsigned char* bytes = (unsigned char *)beData; unsigned char *bytes = (unsigned char *)beData;
return ((unsigned)bytes[0] << 16) + ((unsigned)bytes[1] << 8) + (unsigned)bytes[2]; return ((unsigned)bytes[0] << 16) + ((unsigned)bytes[1] << 8) + (unsigned)bytes[2];
} }
static uint64_t decode64(void *beData) static uint64_t decode64(void *beData)
{ {
unsigned char* bytes = (unsigned char *)beData; unsigned char *bytes = (unsigned char *)beData;
uint64_t result = 0; uint64_t result = 0;
for(size_t i = 0; i < 8; i++) result = (result << 8) + bytes[i]; for(size_t i = 0; i < 8; i++) result = (result << 8) + bytes[i];
return result; return result;
...@@ -525,6 +525,46 @@ int cdiGribIterator_zaxisUuid(CdiIterator *super, int *outVgridNumber, int *outL ...@@ -525,6 +525,46 @@ int cdiGribIterator_zaxisUuid(CdiIterator *super, int *outVgridNumber, int *outL
return CDI_NOERR; return CDI_NOERR;
} }
int cdiGribIterator_inqTile(CdiIterator *super, int *outTileIndex, int *outTileAttribute)
{
CdiGribIterator *me = (CdiGribIterator*)super;
int trash;
if(!outTileIndex) outTileIndex = &trash;
if(!outTileAttribute) outTileAttribute = &trash;
//Get the values if possible.
int error = CDI_NOERR;
long value;
if(grib_get_long(me->gribHandle, "tileIndex", &value)) error = CDI_EINVAL;
*outTileIndex = (int)value;
if(grib_get_long(me->gribHandle, "tileAttribute", &value)) error = CDI_EINVAL;
*outTileAttribute = (int)value;
//Ensure defined return values in case of failure.
if(error) *outTileIndex = *outTileAttribute = -1;
return error;
}
int cdiGribIterator_inqTileCount(CdiIterator *super, int *outTileCount, int *outTileAttributeCount)
{
CdiGribIterator *me = (CdiGribIterator*)super;
int trash;
if(!outTileCount) outTileCount = &trash;
if(!outTileAttributeCount) outTileAttributeCount = &trash;
//Get the values if possible.
int error = CDI_NOERR;
long value;
if(grib_get_long(me->gribHandle, "numberOfTiles", &value)) error = CDI_EINVAL;
*outTileCount = (int)value;
if(grib_get_long(me->gribHandle, "numberOfTileAttributes", &value)) error = CDI_EINVAL;
*outTileAttributeCount = (int)value;
//Ensure defined return values in case of failure.
if(error) *outTileCount = *outTileAttributeCount = 0;
return error;
}
char *cdiGribIterator_copyVariableName(CdiIterator *super) char *cdiGribIterator_copyVariableName(CdiIterator *super)
{ {
CdiGribIterator *me = (CdiGribIterator*)super; CdiGribIterator *me = (CdiGribIterator*)super;
...@@ -549,7 +589,7 @@ void cdiGribIterator_readFieldF(CdiIterator *super, float *buffer, size_t *nmiss ...@@ -549,7 +589,7 @@ void cdiGribIterator_readFieldF(CdiIterator *super, float *buffer, size_t *nmiss
CdiGribIterator *me = (CdiGribIterator*)super; CdiGribIterator *me = (CdiGribIterator*)super;
size_t valueCount = gribGetArraySize(me->gribHandle, "values"); size_t valueCount = gribGetArraySize(me->gribHandle, "values");
double* temp = (double *) Malloc(valueCount*sizeof(*temp)); double *temp = (double *) Malloc(valueCount*sizeof(*temp));
cdiGribIterator_readField(super, temp, nmiss); cdiGribIterator_readField(super, temp, nmiss);
for(size_t i = valueCount; i--; ) buffer[i] = (float)temp[i]; for(size_t i = valueCount; i--; ) buffer[i] = (float)temp[i];
Free(temp); Free(temp);
......
...@@ -29,6 +29,8 @@ char *cdiGribIterator_inqTime(CdiIterator *me, bool getEndTime); ...@@ -29,6 +29,8 @@ char *cdiGribIterator_inqTime(CdiIterator *me, bool getEndTime);
int cdiGribIterator_levelType(CdiIterator *me, int levelSelector, char **outName, char **outLongName, char **outStdName, char **outUnit); int cdiGribIterator_levelType(CdiIterator *me, int levelSelector, char **outName, char **outLongName, char **outStdName, char **outUnit);
int cdiGribIterator_level(CdiIterator *me, int levelSelector, double *outValue1, double *outValue2); int cdiGribIterator_level(CdiIterator *me, int levelSelector, double *outValue1, double *outValue2);
int cdiGribIterator_zaxisUuid(CdiIterator *me, int *outVgridNumber, int *outLevelCount, unsigned char outUuid[CDI_UUID_SIZE]); int cdiGribIterator_zaxisUuid(CdiIterator *me, int *outVgridNumber, int *outLevelCount, unsigned char outUuid[CDI_UUID_SIZE]);
int cdiGribIterator_inqTile(CdiIterator *me, int *outTileIndex, int *outTileAttribute);
int cdiGribIterator_inqTileCount(CdiIterator *me, int *outTileCount, int *outTileAttributeCount);
char *cdiGribIterator_copyVariableName(CdiIterator *me); char *cdiGribIterator_copyVariableName(CdiIterator *me);
void cdiGribIterator_readField(CdiIterator *me, double *buffer, size_t *nmiss); void cdiGribIterator_readField(CdiIterator *me, double *buffer, size_t *nmiss);
......
...@@ -273,6 +273,8 @@ module mo_cdi ...@@ -273,6 +273,8 @@ module mo_cdi
public :: cdiIterator_inqLevelType public :: cdiIterator_inqLevelType
public :: cdiIterator_inqLevel public :: cdiIterator_inqLevel
public :: cdiIterator_inqLevelUuid public :: cdiIterator_inqLevelUuid
public :: cdiIterator_inqTile
public :: cdiIterator_inqTileCount
public :: cdiIterator_inqParam public :: cdiIterator_inqParam
public :: cdiIterator_inqDatatype public :: cdiIterator_inqDatatype
public :: cdiIterator_inqTsteptype public :: cdiIterator_inqTsteptype
...@@ -627,6 +629,7 @@ module mo_cdi ...@@ -627,6 +629,7 @@ module mo_cdi
public :: subtypeInqActiveIndex public :: subtypeInqActiveIndex
public :: subtypeDefActiveIndex public :: subtypeDefActiveIndex
public :: subtypeInqTile public :: subtypeInqTile
public :: subtypeInqAttribute
public :: vlistInqVarSubtype public :: vlistInqVarSubtype
public :: gribapiLibraryVersion public :: gribapiLibraryVersion