diff --git a/src/grib_io.c b/src/grib_io.c index 9b9203b6b..5c3cb56e6 100644 --- a/src/grib_io.c +++ b/src/grib_io.c @@ -1718,6 +1718,50 @@ int grib_count_in_filename(grib_context* c, const char* filename, int* n) return err; } +typedef void* (*decoder_proc)(FILE* f, int headers_only, size_t* size, off_t* offset, int* err); + +static decoder_proc get_reader_for_product(ProductKind product) +{ + decoder_proc decoder = NULL; + if (product == PRODUCT_GRIB) decoder = &wmo_read_grib_from_file_malloc; + else if (product == PRODUCT_BUFR) decoder = &wmo_read_bufr_from_file_malloc; + else if (product == PRODUCT_GTS) decoder = &wmo_read_gts_from_file_malloc; + else if (product == PRODUCT_ANY) decoder = &wmo_read_any_from_file_malloc; + return decoder; +} + +static int count_product_in_file(grib_context* c, FILE* f, ProductKind product, int* count) +{ + int err = 0; + decoder_proc decoder = NULL; + + *count = 0; + if (!c) c = grib_context_get_default(); + decoder = get_reader_for_product(product); + + if (!decoder) { + grib_context_log(c, GRIB_LOG_ERROR, "count_product_in_file: not supported for given product"); + return GRIB_INVALID_ARGUMENT; + } + + if (c->multi_support_on) { + grib_context_log(c, GRIB_LOG_ERROR, "count_product_in_file: Multi-field GRIBs not supported"); + err = GRIB_NOT_IMPLEMENTED; + } + else { + void* mesg = NULL; + size_t size = 0; + off_t offset = 0; + while ((mesg = decoder(f, 0, &size, &offset, &err)) != NULL && err == GRIB_SUCCESS) { + grib_context_free(c, mesg); + (*count)++; + } + rewind(f); + } + + return err == GRIB_END_OF_FILE ? 0 : err; +} + int codes_extract_offsets_malloc(grib_context* c, FILE* f, ProductKind product, off_t** offsets, size_t* length, int strict_mode) { int err = 0; @@ -1725,21 +1769,16 @@ int codes_extract_offsets_malloc(grib_context* c, FILE* f, ProductKind product, size_t size = 0; off_t offset = 0; int num_messages = 0, i = 0; - - typedef void* (*decoder_proc)(FILE* f, int headers_only, size_t* size, off_t* offset, int* err); decoder_proc decoder = NULL; - if (product == PRODUCT_GRIB) decoder = &wmo_read_grib_from_file_malloc; - else if (product == PRODUCT_BUFR) decoder = &wmo_read_bufr_from_file_malloc; - else if (product == PRODUCT_GTS) decoder = &wmo_read_gts_from_file_malloc; - else if (product == PRODUCT_ANY) decoder = &wmo_read_any_from_file_malloc; - else { + + decoder = get_reader_for_product(product); + if (!decoder) { grib_context_log(c, GRIB_LOG_ERROR, "codes_extract_offsets_malloc: not supported for given product"); return GRIB_INVALID_ARGUMENT; } - if (!c) c = grib_context_get_default(); - err = grib_count_in_file(c, f, &num_messages); + err = count_product_in_file(c, f, product, &num_messages); if (err) { grib_context_log(c, GRIB_LOG_ERROR, "codes_extract_offsets_malloc: Unable to count messages"); return err; @@ -1753,12 +1792,12 @@ int codes_extract_offsets_malloc(grib_context* c, FILE* f, ProductKind product, if (!*offsets) { return GRIB_OUT_OF_MEMORY; } -printf("dbg: num_messages=%d\n", num_messages); + i = 0; while (err != GRIB_END_OF_FILE) { if (i >= num_messages) break; - //printf("dbg: decoding msg %d\n", i); + mesg = decoder(f, 0, &size, &offset, &err); if (mesg != NULL && err == 0) { (*offsets)[i] = offset; diff --git a/tests/bufr_extract_headers.c b/tests/bufr_extract_headers.c index 2aafd52cd..6cfb3271f 100644 --- a/tests/bufr_extract_headers.c +++ b/tests/bufr_extract_headers.c @@ -12,7 +12,7 @@ #include #define MAX_KEYS 100 - +#if 0 int main(int argc, char* argv[]) { char *filename; @@ -38,8 +38,8 @@ int main(int argc, char* argv[]) free(offsets); return 0; } +#endif -#if 0 int main(int argc, char* argv[]) { char *filename, *keys; @@ -87,4 +87,3 @@ int main(int argc, char* argv[]) return 0; } -#endif