/* * (C) Copyright 2005- ECMWF. * * This software is licensed under the terms of the Apache Licence Version 2.0 * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0. * * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. */ #include "grib_api_internal.h" #include "assert.h" #if HAVE_SYS_TYPES_H #include #endif #if HAVE_SYS_STAT_H #include #endif #ifdef HAVE_FCNTL_H #include #endif #include #include #if GRIB_PTHREADS static pthread_once_t once = PTHREAD_ONCE_INIT; static pthread_mutex_t handle_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t index_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t multi_handle_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t iterator_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t keys_iterator_mutex = PTHREAD_MUTEX_INITIALIZER; static void init() { pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&handle_mutex, &attr); pthread_mutex_init(&index_mutex, &attr); pthread_mutex_init(&multi_handle_mutex, &attr); pthread_mutex_init(&iterator_mutex, &attr); pthread_mutex_init(&keys_iterator_mutex, &attr); pthread_mutexattr_destroy(&attr); } #elif GRIB_OMP_THREADS static int once = 0; static omp_nest_lock_t handle_mutex; static omp_nest_lock_t index_mutex; static omp_nest_lock_t multi_handle_mutex; static omp_nest_lock_t iterator_mutex; static omp_nest_lock_t keys_iterator_mutex; static void init() { GRIB_OMP_CRITICAL(lock_python) { if (once == 0) { omp_init_nest_lock(&handle_mutex); omp_init_nest_lock(&index_mutex); omp_init_nest_lock(&multi_handle_mutex); omp_init_nest_lock(&iterator_mutex); omp_init_nest_lock(&keys_iterator_mutex); once = 1; } } } #endif int GRIB_NULL = -1; int GRIB_NULL_NEAREST = -1; typedef struct l_grib_file l_grib_file; struct l_grib_file { int id; FILE* f; l_grib_file* next; }; typedef struct l_grib_handle l_grib_handle; struct l_grib_handle { int id; grib_handle* h; l_grib_handle* next; }; typedef struct l_grib_index l_grib_index; struct l_grib_index { int id; grib_index* h; l_grib_index* next; }; typedef struct l_grib_multi_handle l_grib_multi_handle; struct l_grib_multi_handle { int id; grib_multi_handle* h; l_grib_multi_handle* next; }; typedef struct l_grib_iterator l_grib_iterator; struct l_grib_iterator { int id; grib_iterator* i; l_grib_iterator* next; }; typedef struct l_grib_keys_iterator l_grib_keys_iterator; struct l_grib_keys_iterator { int id; grib_keys_iterator* i; l_grib_keys_iterator* next; }; typedef struct l_bufr_keys_iterator l_bufr_keys_iterator; struct l_bufr_keys_iterator { int id; bufr_keys_iterator* i; l_bufr_keys_iterator* next; }; static l_grib_handle* handle_set = NULL; static l_grib_index* index_set = NULL; static l_grib_multi_handle* multi_handle_set = NULL; static l_grib_file* file_set = NULL; static l_grib_iterator* iterator_set = NULL; static l_grib_keys_iterator* keys_iterator_set = NULL; static l_bufr_keys_iterator* bufr_keys_iterator_set = NULL; static int push_file(FILE* f) { l_grib_file* current = file_set; l_grib_file* previous = file_set; l_grib_file* new = NULL; int myindex = 1; if (!file_set) { file_set = malloc(sizeof(l_grib_file)); file_set->id = myindex; file_set->f = f; file_set->next = NULL; return myindex; } while (current) { if (current->id < 0) { current->id = -(current->id); current->f = f; return current->id; } else { myindex++; previous = current; current = current->next; } } new = malloc(sizeof(l_grib_file)); new->id = myindex; new->f = f; new->next = current; previous->next = new; return myindex; } static void _push_handle(grib_handle* h, int* gid) { l_grib_handle* current = handle_set; l_grib_handle* previous = handle_set; l_grib_handle* new = NULL; int myindex = 1; if (*gid > 0) { while (current) { if (current->id == *gid) break; current = current->next; } if (current) { grib_handle_delete(current->h); current->h = h; return; } } current = handle_set; if (!handle_set) { handle_set = malloc(sizeof(l_grib_handle)); handle_set->id = myindex; handle_set->h = h; handle_set->next = NULL; *gid = myindex; return; } while (current) { if (current->id < 0) { current->id = -(current->id); current->h = h; *gid = current->id; return; } else { myindex++; previous = current; current = current->next; } } new = malloc(sizeof(l_grib_handle)); new->id = myindex; new->h = h; new->next = current; previous->next = new; *gid = myindex; return; } static void _push_index(grib_index* h, int* gid) { l_grib_index* current = index_set; l_grib_index* previous = index_set; l_grib_index* new = NULL; int myindex = 1; if (*gid > 0) { while (current) { if (current->id == *gid) break; current = current->next; } if (current) { grib_index_delete(current->h); current->h = h; return; } } current = index_set; if (!index_set) { index_set = malloc(sizeof(l_grib_index)); index_set->id = myindex; index_set->h = h; index_set->next = NULL; *gid = myindex; return; } while (current) { if (current->id < 0) { current->id = -(current->id); current->h = h; *gid = current->id; return; } else { myindex++; previous = current; current = current->next; } } new = malloc(sizeof(l_grib_index)); new->id = myindex; new->h = h; new->next = current; previous->next = new; *gid = myindex; return; } static void _push_multi_handle(grib_multi_handle* h, int* gid) { l_grib_multi_handle* current = multi_handle_set; l_grib_multi_handle* previous = multi_handle_set; l_grib_multi_handle* new = NULL; int myindex = 1; if (*gid > 0) { while (current) { if (current->id == *gid) break; current = current->next; } if (current) { grib_multi_handle_delete(current->h); current->h = h; return; } } current = multi_handle_set; if (!multi_handle_set) { multi_handle_set = malloc(sizeof(l_grib_multi_handle)); multi_handle_set->id = myindex; multi_handle_set->h = h; multi_handle_set->next = NULL; *gid = myindex; return; } while (current) { if (current->id < 0) { current->id = -(current->id); current->h = h; *gid = current->id; return; } else { myindex++; previous = current; current = current->next; } } new = malloc(sizeof(l_grib_multi_handle)); new->id = myindex; new->h = h; new->next = current; previous->next = new; *gid = myindex; return; } static void push_handle(grib_handle* h, int* gid) { GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&handle_mutex) _push_handle(h, gid); GRIB_MUTEX_UNLOCK(&handle_mutex) return; } static void push_index(grib_index* h, int* gid) { GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&index_mutex) _push_index(h, gid); GRIB_MUTEX_UNLOCK(&index_mutex) return; } static void push_multi_handle(grib_multi_handle* h, int* gid) { GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&multi_handle_mutex) _push_multi_handle(h, gid); GRIB_MUTEX_UNLOCK(&multi_handle_mutex) return; } static int _push_iterator(grib_iterator* i) { l_grib_iterator* current = iterator_set; l_grib_iterator* previous = iterator_set; l_grib_iterator* new = NULL; int myindex = 1; if (!iterator_set) { iterator_set = malloc(sizeof(l_grib_iterator)); iterator_set->id = myindex; iterator_set->i = i; iterator_set->next = NULL; return myindex; } while (current) { if (current->id < 0) { current->id = -(current->id); current->i = i; return current->id; } else { myindex++; previous = current; current = current->next; } } new = malloc(sizeof(l_grib_iterator)); new->id = myindex; new->i = i; new->next = current; previous->next = new; return myindex; } static int push_iterator(grib_iterator* i) { int ret = 0; GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&iterator_mutex) ret = _push_iterator(i); GRIB_MUTEX_UNLOCK(&iterator_mutex) return ret; } static int _push_keys_iterator(grib_keys_iterator* i) { l_grib_keys_iterator* current = keys_iterator_set; l_grib_keys_iterator* previous = keys_iterator_set; l_grib_keys_iterator* new = NULL; int myindex = 1; if (!keys_iterator_set) { keys_iterator_set = malloc(sizeof(l_grib_keys_iterator)); keys_iterator_set->id = myindex; keys_iterator_set->i = i; keys_iterator_set->next = NULL; return myindex; } while (current) { if (current->id < 0) { current->id = -(current->id); current->i = i; return current->id; } else { myindex++; previous = current; current = current->next; } } if (!previous) return -1; new = malloc(sizeof(l_grib_keys_iterator)); new->id = myindex; new->i = i; new->next = current; previous->next = new; return myindex; } static int push_keys_iterator(grib_keys_iterator* i) { int ret = 0; GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&keys_iterator_mutex) ret = _push_keys_iterator(i); GRIB_MUTEX_UNLOCK(&keys_iterator_mutex) return ret; } //BUFR keys iterator static int _push_bufr_keys_iterator(bufr_keys_iterator* i) { l_bufr_keys_iterator* current = bufr_keys_iterator_set; l_bufr_keys_iterator* previous = bufr_keys_iterator_set; l_bufr_keys_iterator* the_new = NULL; int myindex = 1; if (!bufr_keys_iterator_set) { bufr_keys_iterator_set = (l_bufr_keys_iterator*)malloc(sizeof(l_bufr_keys_iterator)); Assert(bufr_keys_iterator_set); bufr_keys_iterator_set->id = myindex; bufr_keys_iterator_set->i = i; bufr_keys_iterator_set->next = NULL; return myindex; } while (current) { if (current->id < 0) { current->id = -(current->id); current->i = i; return current->id; } else { myindex++; previous = current; current = current->next; } } if (!previous) return -1; the_new = (l_bufr_keys_iterator*)malloc(sizeof(l_bufr_keys_iterator)); Assert(the_new); the_new->id = myindex; the_new->i = i; the_new->next = current; previous->next = the_new; return myindex; } static int push_bufr_keys_iterator(bufr_keys_iterator* i) { int ret = 0; GRIB_MUTEX_INIT_ONCE(&once, &init); GRIB_MUTEX_LOCK(&keys_iterator_mutex); ret = _push_bufr_keys_iterator(i); GRIB_MUTEX_UNLOCK(&keys_iterator_mutex); return ret; } static grib_handle* _get_handle(int handle_id) { l_grib_handle* current = handle_set; while (current) { if (current->id == handle_id) return current->h; current = current->next; } return NULL; } static grib_index* _get_index(int index_id) { l_grib_index* current = index_set; while (current) { if (current->id == index_id) return current->h; current = current->next; } return NULL; } static grib_multi_handle* _get_multi_handle(int multi_handle_id) { l_grib_multi_handle* current = multi_handle_set; while (current) { if (current->id == multi_handle_id) return current->h; current = current->next; } return NULL; } static grib_handle* get_handle(int handle_id) { grib_handle* h = NULL; GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&handle_mutex) h = _get_handle(handle_id); GRIB_MUTEX_UNLOCK(&handle_mutex) return h; } static grib_index* get_index(int index_id) { grib_index* h = NULL; GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&index_mutex) h = _get_index(index_id); GRIB_MUTEX_UNLOCK(&index_mutex) return h; } static grib_multi_handle* get_multi_handle(int multi_handle_id) { grib_multi_handle* h = NULL; GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&multi_handle_mutex) h = _get_multi_handle(multi_handle_id); GRIB_MUTEX_UNLOCK(&multi_handle_mutex) return h; } static FILE* get_file(int file_id) { l_grib_file* current = file_set; while (current) { if (current->id == file_id) return current->f; current = current->next; } return NULL; } static grib_iterator* _get_iterator(int iterator_id) { l_grib_iterator* current = iterator_set; while (current) { if (current->id == iterator_id) return current->i; current = current->next; } return NULL; } static grib_iterator* get_iterator(int iterator_id) { grib_iterator* i = NULL; GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&iterator_mutex) i = _get_iterator(iterator_id); GRIB_MUTEX_UNLOCK(&iterator_mutex) return i; } static grib_keys_iterator* _get_keys_iterator(int keys_iterator_id) { l_grib_keys_iterator* current = keys_iterator_set; while (current) { if (current->id == keys_iterator_id) return current->i; current = current->next; } return NULL; } static grib_keys_iterator* get_keys_iterator(int keys_iterator_id) { grib_keys_iterator* i = NULL; GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&keys_iterator_mutex) i = _get_keys_iterator(keys_iterator_id); GRIB_MUTEX_UNLOCK(&keys_iterator_mutex) return i; } //BUFR keys iterator static bufr_keys_iterator* _get_bufr_keys_iterator(int keys_iterator_id) { l_bufr_keys_iterator* current = bufr_keys_iterator_set; while (current) { if (current->id == keys_iterator_id) return current->i; current = current->next; } return NULL; } static bufr_keys_iterator* get_bufr_keys_iterator(int keys_iterator_id) { bufr_keys_iterator* i = NULL; GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&keys_iterator_mutex) i = _get_bufr_keys_iterator(keys_iterator_id); GRIB_MUTEX_UNLOCK(&keys_iterator_mutex) return i; } static int clear_file(int file_id) { l_grib_file* current = file_set; int ret = 0; while (current) { if (current->id == file_id) { current->id = -(current->id); if (current->f) { ret = fclose(current->f); if (0 == ret) { return GRIB_SUCCESS; } else { return GRIB_IO_PROBLEM; } } return GRIB_SUCCESS; } current = current->next; } return GRIB_INVALID_FILE; } static int _clear_handle(int handle_id) { l_grib_handle* current = handle_set; /* look for the input grib id to release it */ while (current) { if (current->id == handle_id) { current->id = -(current->id); if (current->h) return grib_handle_delete(current->h); } current = current->next; } /* fail with invalid grib id if not found */ return GRIB_INVALID_GRIB; } static int _clear_index(int index_id) { l_grib_index* current = index_set; while (current) { if (current->id == index_id) { current->id = -(current->id); if (current->h) { grib_index_delete(current->h); return GRIB_SUCCESS; } } current = current->next; } return GRIB_SUCCESS; } static int _clear_multi_handle(int multi_handle_id) { l_grib_multi_handle* current = multi_handle_set; while (current) { if (current->id == multi_handle_id) { current->id = -(current->id); if (current->h) return grib_multi_handle_delete(current->h); } current = current->next; } return GRIB_SUCCESS; } static int clear_handle(int handle_id) { int ret = 0; GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&handle_mutex) ret = _clear_handle(handle_id); GRIB_MUTEX_UNLOCK(&handle_mutex) return ret; } static int clear_index(int index_id) { int ret = 0; GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&index_mutex) ret = _clear_index(index_id); GRIB_MUTEX_UNLOCK(&index_mutex) return ret; } static int clear_multi_handle(int multi_handle_id) { int ret = 0; GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&multi_handle_mutex) ret = _clear_multi_handle(multi_handle_id); GRIB_MUTEX_UNLOCK(&multi_handle_mutex) return ret; } static int _clear_iterator(int iterator_id) { l_grib_iterator* current = iterator_set; while (current) { if (current->id == iterator_id) { current->id = -(current->id); return grib_iterator_delete(current->i); } current = current->next; } return GRIB_INVALID_ITERATOR; } static int clear_iterator(int iterator_id) { int ret = 0; GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&iterator_mutex) ret = _clear_iterator(iterator_id); GRIB_MUTEX_UNLOCK(&iterator_mutex) return ret; } static int _clear_keys_iterator(int keys_iterator_id) { l_grib_keys_iterator* current = keys_iterator_set; while (current) { if (current->id == keys_iterator_id) { current->id = -(current->id); return grib_keys_iterator_delete(current->i); } current = current->next; } return GRIB_INVALID_KEYS_ITERATOR; } static int clear_keys_iterator(int keys_iterator_id) { int ret = 0; GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&keys_iterator_mutex) ret = _clear_keys_iterator(keys_iterator_id); GRIB_MUTEX_UNLOCK(&keys_iterator_mutex) return ret; } //BUFR keys iterator static int _clear_bufr_keys_iterator(int keys_iterator_id) { l_bufr_keys_iterator* current = bufr_keys_iterator_set; while (current) { if (current->id == keys_iterator_id) { current->id = -(current->id); return codes_bufr_keys_iterator_delete(current->i); } current = current->next; } return GRIB_INVALID_KEYS_ITERATOR; } static int clear_bufr_keys_iterator(int keys_iterator_id) { int ret = 0; GRIB_MUTEX_INIT_ONCE(&once, &init); GRIB_MUTEX_LOCK(&keys_iterator_mutex); ret = _clear_bufr_keys_iterator(keys_iterator_id); GRIB_MUTEX_UNLOCK(&keys_iterator_mutex); return ret; } int grib_c_read_any_from_file(int* fid, char* buffer, int* nbytes) { grib_context* c; int err = 0; size_t size = (size_t)nbytes; FILE* f = get_file(*fid); if (f) { c = grib_context_get_default(); err = grib_read_any_from_file(c, f, buffer, &size); *nbytes = size; return err; } else { return GRIB_INVALID_FILE; } } int grib_c_write_file(int* fid, char* buffer, int* nbytes) { grib_context* c; FILE* f = get_file(*fid); if (f) { int ioerr; c = grib_context_get_default(); if (fwrite(buffer, 1, *nbytes, f) != *nbytes) { ioerr = errno; grib_context_log(c, (GRIB_LOG_ERROR) | (GRIB_LOG_PERROR), "IO ERROR: %s", strerror(ioerr)); return GRIB_IO_PROBLEM; } return GRIB_SUCCESS; } else { return GRIB_INVALID_FILE; } } int grib_c_read_file(int* fid, char* buffer, int* nbytes) { grib_context* c; FILE* f = get_file(*fid); if (f) { int ioerr; c = grib_context_get_default(); if (fread(buffer, 1, *nbytes, f) != *nbytes) { ioerr = errno; grib_context_log(c, (GRIB_LOG_ERROR) | (GRIB_LOG_PERROR), "IO ERROR: %s", strerror(ioerr)); return GRIB_IO_PROBLEM; } return GRIB_SUCCESS; } else { return GRIB_INVALID_FILE; } } int grib_c_open_file(int* fid, char* name, char* op) { FILE* f = NULL; int ioerr = 0; int ret = GRIB_SUCCESS; /*TODO Proper context passed as external parameter */ grib_context* context = grib_context_get_default(); f = fopen(name, op); if (!f) { ioerr = errno; grib_context_log(context, (GRIB_LOG_ERROR) | (GRIB_LOG_PERROR), "IO ERROR: %s: %s", strerror(ioerr), name); *fid = -1; ret = GRIB_IO_PROBLEM; } else { *fid = push_file(f); ret = GRIB_SUCCESS; } return ret; } int grib_c_close_file(int* fid) { return clear_file(*fid); } int grib_c_multi_support_on(void) { grib_multi_support_on(0); return GRIB_SUCCESS; } int grib_c_multi_support_off(void) { grib_multi_support_off(0); return GRIB_SUCCESS; } static int _grib_c_iterator_new_(int* gid, int* iterid, int* mode) { int err = 0; grib_handle* h; grib_iterator* iter; h = get_handle(*gid); if (!h) { *iterid = -1; return GRIB_NULL_HANDLE; } iter = grib_iterator_new(h, *mode, &err); if (iter) *iterid = push_iterator(iter); else *iterid = -1; return err; } int grib_c_iterator_new(int* gid, int* iterid, int* mode) { int ret = 0; GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&iterator_mutex) ret = _grib_c_iterator_new_(gid, iterid, mode); GRIB_MUTEX_UNLOCK(&iterator_mutex) return ret; } int grib_c_iterator_next(int* iterid, double* lat, double* lon, double* value) { grib_iterator* iter = get_iterator(*iterid); if (!iter) return GRIB_INVALID_ITERATOR; return grib_iterator_next(iter, lat, lon, value); } int grib_c_iterator_delete(int* iterid) { return clear_iterator(*iterid); } static int _grib_c_keys_iterator_new_(int* gid, int* iterid, char* name_space) { int err = 0; grib_handle* h; grib_keys_iterator* iter; h = get_handle(*gid); if (!h) { *iterid = -1; return GRIB_NULL_HANDLE; } iter = grib_keys_iterator_new(h, 0, name_space); if (iter) *iterid = push_keys_iterator(iter); else *iterid = -1; return err; } int grib_c_keys_iterator_new(int* gid, int* iterid, char* name_space) { int ret = 0; GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&keys_iterator_mutex) ret = _grib_c_keys_iterator_new_(gid, iterid, name_space); GRIB_MUTEX_UNLOCK(&keys_iterator_mutex) return ret; } int grib_c_keys_iterator_next(int* iterid) { int ret = 0; grib_keys_iterator* iter = get_keys_iterator(*iterid); if (!iter) return GRIB_INVALID_KEYS_ITERATOR; ret = grib_keys_iterator_next(iter); return ret; } int grib_c_keys_iterator_delete(int* iterid) { return clear_keys_iterator(*iterid); } int grib_c_keys_iterator_get_name(int* iterid, char* name, int len) { size_t lsize = len; char buf[1024] = {0,}; grib_keys_iterator* kiter = get_keys_iterator(*iterid); if (!kiter) return GRIB_INVALID_KEYS_ITERATOR; if (grib_keys_iterator_get_accessor(kiter) == NULL) return GRIB_INVALID_KEYS_ITERATOR; sprintf(buf, "%s", grib_keys_iterator_get_name(kiter)); lsize = strlen(buf); if (len < lsize) return GRIB_ARRAY_TOO_SMALL; memcpy(name, buf, lsize); name[lsize] = '\0'; return 0; } int grib_c_keys_iterator_rewind(int* kiter) { grib_keys_iterator* i = get_keys_iterator(*kiter); if (!i) return GRIB_INVALID_KEYS_ITERATOR; return grib_keys_iterator_rewind(i); } /*BUFR keys iterator*/ static int _codes_c_bufr_keys_iterator_new_(int* gid, int* iterid) { int err = 0; grib_handle* h; bufr_keys_iterator* iter; h = get_handle(*gid); if (!h) { *iterid = -1; return GRIB_NULL_HANDLE; } iter = codes_bufr_keys_iterator_new(h, 0); if (iter) *iterid = push_bufr_keys_iterator(iter); else *iterid = -1; return err; } int codes_c_bufr_keys_iterator_new(int* gid, int* iterid) { int ret = 0; GRIB_MUTEX_INIT_ONCE(&once, &init) GRIB_MUTEX_LOCK(&keys_iterator_mutex) ret = _codes_c_bufr_keys_iterator_new_(gid, iterid); GRIB_MUTEX_UNLOCK(&keys_iterator_mutex) return ret; } int codes_c_bufr_keys_iterator_next(int* iterid) { int ret = 0; bufr_keys_iterator* iter = get_bufr_keys_iterator(*iterid); if (!iter) return GRIB_INVALID_KEYS_ITERATOR; ret = codes_bufr_keys_iterator_next(iter); return ret; } int codes_c_bufr_keys_iterator_get_name(int* iterid, char* name, int len) { size_t lsize = len; char buf[1024] = {0,}; bufr_keys_iterator* kiter = get_bufr_keys_iterator(*iterid); if (!kiter) return GRIB_INVALID_KEYS_ITERATOR; if (codes_bufr_keys_iterator_get_accessor(kiter) == NULL) return GRIB_INVALID_KEYS_ITERATOR; sprintf(buf, "%s", codes_bufr_keys_iterator_get_name(kiter)); lsize = strlen(buf); if (len < lsize) return GRIB_ARRAY_TOO_SMALL; memcpy(name, buf, lsize); name[lsize] = '\0'; return 0; } int codes_c_bufr_keys_iterator_rewind(int* kiter) { bufr_keys_iterator* i = get_bufr_keys_iterator(*kiter); if (!i) return GRIB_INVALID_KEYS_ITERATOR; return codes_bufr_keys_iterator_rewind(i); } int codes_c_bufr_keys_iterator_delete(int* iterid) { return clear_bufr_keys_iterator(*iterid); } int grib_c_gribex_mode_on(void) { grib_gribex_mode_on(0); return GRIB_SUCCESS; } int grib_c_gribex_mode_off(void) { grib_gribex_mode_off(0); return GRIB_SUCCESS; } int grib_c_skip_computed(int* iterid) { grib_keys_iterator* iter = get_keys_iterator(*iterid); if (!iter) return GRIB_INVALID_KEYS_ITERATOR; return grib_keys_iterator_set_flags(iter, GRIB_KEYS_ITERATOR_SKIP_COMPUTED); } int grib_c_skip_coded(int* iterid) { grib_keys_iterator* iter = get_keys_iterator(*iterid); if (!iter) return GRIB_INVALID_KEYS_ITERATOR; return grib_keys_iterator_set_flags(iter, GRIB_KEYS_ITERATOR_SKIP_CODED); } int grib_c_skip_edition_specific(int* iterid) { grib_keys_iterator* iter = get_keys_iterator(*iterid); if (!iter) return GRIB_INVALID_KEYS_ITERATOR; return grib_keys_iterator_set_flags(iter, GRIB_KEYS_ITERATOR_SKIP_EDITION_SPECIFIC); } int grib_c_skip_duplicates(int* iterid) { grib_keys_iterator* iter = get_keys_iterator(*iterid); if (!iter) return GRIB_INVALID_KEYS_ITERATOR; return grib_keys_iterator_set_flags(iter, GRIB_KEYS_ITERATOR_SKIP_DUPLICATES); } int grib_c_skip_read_only(int* iterid) { grib_keys_iterator* iter = get_keys_iterator(*iterid); if (!iter) return GRIB_INVALID_KEYS_ITERATOR; return grib_keys_iterator_set_flags(iter, GRIB_KEYS_ITERATOR_SKIP_READ_ONLY); } int grib_c_skip_function(int* iterid) { grib_keys_iterator* iter = get_keys_iterator(*iterid); if (!iter) return GRIB_INVALID_KEYS_ITERATOR; return grib_keys_iterator_set_flags(iter, GRIB_KEYS_ITERATOR_SKIP_FUNCTION); } int grib_c_new_from_message(int* gid, void* buffer, size_t* bufsize) { grib_handle* h = NULL; h = grib_handle_new_from_message_copy(0, buffer, *bufsize); if (h) { push_handle(h, gid); return GRIB_SUCCESS; } *gid = -1; return GRIB_INTERNAL_ERROR; } int grib_c_new_from_message_copy(int* gid, void* buffer, size_t* bufsize) { grib_handle* h = NULL; h = grib_handle_new_from_message_copy(0, buffer, *bufsize); if (h) { push_handle(h, gid); return GRIB_SUCCESS; } *gid = -1; return GRIB_INTERNAL_ERROR; } int grib_c_grib_new_from_samples(int* gid, char* name) { grib_handle* h = NULL; h = grib_handle_new_from_samples(NULL, name); /* grib_context_set_debug(h->context,1);*/ if (h) { push_handle(h, gid); return GRIB_SUCCESS; } *gid = -1; return GRIB_FILE_NOT_FOUND; } int grib_c_bufr_new_from_samples(int* gid, char* name) { grib_handle* h = NULL; h = codes_bufr_handle_new_from_samples(NULL, name); /* grib_context_set_debug(h->context,1);*/ if (h) { push_handle(h, gid); return GRIB_SUCCESS; } *gid = -1; return GRIB_FILE_NOT_FOUND; } int grib_c_clone(int* gidsrc, int* giddest) { grib_handle* src = get_handle(*gidsrc); grib_handle* dest = NULL; if (src) { dest = grib_handle_clone(src); if (dest) { push_handle(dest, giddest); return GRIB_SUCCESS; } } *giddest = -1; return GRIB_INVALID_GRIB; } int grib_c_copy_namespace(int* gidsrc, char* name, int* giddest) { grib_handle* src = get_handle(*gidsrc); grib_handle* dest = get_handle(*giddest); if (src && dest) return grib_copy_namespace(dest, name, src); return GRIB_INVALID_GRIB; } int grib_c_count_in_file(FILE* f, int* n) { int err = 0; if (f) err = grib_count_in_file(0, f, n); return err; } int grib_c_new_gts_from_file(FILE* f, int headers_only, int* gid) { grib_handle* h = NULL; int err = 0; if (f) { h = gts_new_from_file(0, f, &err); if (h) { push_handle(h, gid); return GRIB_SUCCESS; } else { *gid = -1; return GRIB_END_OF_FILE; } } *gid = -1; return GRIB_INVALID_FILE; } int grib_c_new_metar_from_file(FILE* f, int headers_only, int* gid) { grib_handle* h = NULL; int err = 0; if (f) { h = metar_new_from_file(0, f, &err); if (h) { push_handle(h, gid); return GRIB_SUCCESS; } else { *gid = -1; return GRIB_END_OF_FILE; } } *gid = -1; return GRIB_INVALID_FILE; } int grib_c_new_any_from_file(FILE* f, int headers_only, int* gid) { grib_handle* h = NULL; int err = 0; if (f) { h = codes_handle_new_from_file(0, f, PRODUCT_ANY, &err); if (h) { push_handle(h, gid); return GRIB_SUCCESS; } else { *gid = -1; return GRIB_END_OF_FILE; } } *gid = -1; return GRIB_INVALID_FILE; } int grib_c_new_bufr_from_file(FILE* f, int headers_only, int* gid) { grib_handle* h = NULL; int err = 0; if (f) { /* h = bufr_new_from_file(0,f,headers_only,&err); */ h = codes_handle_new_from_file(0, f, PRODUCT_BUFR, &err); if (h) { push_handle(h, gid); return GRIB_SUCCESS; } else { *gid = -1; return GRIB_END_OF_FILE; } } *gid = -1; return GRIB_INVALID_FILE; } int grib_c_new_from_file(FILE* f, int* gid, int headers_only) { grib_handle* h = NULL; int err = 0; if (f) { h = grib_new_from_file(0, f, headers_only, &err); if (h) { push_handle(h, gid); return GRIB_SUCCESS; } else { *gid = -1; if (err == GRIB_SUCCESS) { return GRIB_END_OF_FILE; } else { /* A real error occurred */ return err; } } } *gid = -1; return GRIB_INVALID_FILE; } int grib_c_new_from_index(int* iid, int* gid) { int err = 0; grib_index* i = get_index(*iid); grib_handle* h = NULL; if (i) { h = grib_handle_new_from_index(i, &err); if (h) { push_handle(h, gid); return GRIB_SUCCESS; } else { *gid = -1; return GRIB_END_OF_INDEX; } } *gid = -1; return GRIB_INVALID_INDEX; } int grib_c_index_new_from_file(char* file, char* keys, int* gid) { int err = 0; grib_index* i = NULL; if (*file) { i = grib_index_new_from_file(0, file, keys, &err); if (i) { push_index(i, gid); return GRIB_SUCCESS; } else { *gid = -1; return GRIB_END_OF_FILE; } } *gid = -1; return GRIB_INVALID_FILE; } int grib_c_index_add_file(int* iid, char* file) { grib_index* i = get_index(*iid); int err = GRIB_SUCCESS; if (!i) { return GRIB_INVALID_INDEX; } else { err = grib_index_add_file(i, file); return err; } } int grib_c_index_release(int* hid) { return clear_index(*hid); } int grib_c_multi_release(int* hid) { return clear_multi_handle(*hid); } int grib_c_release(int* hid) { return clear_handle(*hid); } int grib_c_dump(int* gid) { grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; else grib_dump_content(h, stdout, "wmo", 0, NULL); return GRIB_SUCCESS; } int grib_c_print(int* gid, char* key) { grib_handle* h = get_handle(*gid); int err = GRIB_SUCCESS; grib_dumper* d = NULL; if (!h) { return GRIB_INVALID_GRIB; } else { d = grib_dumper_factory("serialize", h, stdout, 0, 0); err = grib_print(h, key, d); grib_dumper_delete(d); return err; } } int grib_c_get_error_string(int* err, char* buf, int len) { const char* err_msg = grib_get_error_message(*err); size_t erlen = strlen(err_msg); if (len <= erlen) return GRIB_ARRAY_TOO_SMALL; strncpy(buf, err_msg, (size_t)erlen); buf[erlen] = '\0'; return GRIB_SUCCESS; } int grib_c_get_size_int(int* gid, char* key, int* val) { grib_handle* h = get_handle(*gid); int err = GRIB_SUCCESS; size_t tsize = 0; if (!h) { return GRIB_INVALID_GRIB; } else { err = grib_get_size(h, key, &tsize); *val = tsize; return err; } } int grib_c_get_message_offset(int* gid, size_t* offset) { int err = GRIB_SUCCESS; off_t myoffset; grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; else { err = grib_get_message_offset(h, &myoffset); *offset = myoffset; return err; } } int grib_c_get_message_size(int* gid, size_t* size) { grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; else return grib_get_message_size(h, size); } int grib_c_get_string_length(int* gid, char* key, size_t* val) { grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; else return grib_get_string_length(h, key, val); } int grib_c_get_size_long(int* gid, char* key, long* val) { grib_handle* h = get_handle(*gid); int err = GRIB_SUCCESS; size_t tsize = 0; if (!h) { return GRIB_INVALID_GRIB; } else { err = grib_get_size(h, key, &tsize); *val = tsize; return err; } } int grib_c_index_get_size_int(int* gid, char* key, int* val) { grib_index* h = get_index(*gid); int err = GRIB_SUCCESS; size_t tsize = 0; if (!h) { return GRIB_INVALID_GRIB; } else { err = grib_index_get_size(h, key, &tsize); *val = tsize; return err; } } int grib_c_index_get_size_long(int* gid, char* key, long* val) { grib_index* h = get_index(*gid); int err = GRIB_SUCCESS; size_t tsize = 0; if (!h) { return GRIB_INVALID_GRIB; } else { err = grib_index_get_size(h, key, &tsize); *val = tsize; return err; } } int grib_c_get_int(int* gid, char* key, int* val) { grib_handle* h = get_handle(*gid); long long_val; int err = GRIB_SUCCESS; if (!h) return GRIB_INVALID_GRIB; err = grib_get_long(h, key, &long_val); *val = long_val; return err; } int grib_c_get_long(int* gid, char* key, long* val) { grib_handle* h = get_handle(*gid); int err = GRIB_SUCCESS; if (!h) return GRIB_INVALID_GRIB; err = grib_get_long(h, key, val); return err; } int grib_c_get_double(int* gid, char* key, double* val) { grib_handle* h = get_handle(*gid); int err = GRIB_SUCCESS; if (!h) return GRIB_INVALID_GRIB; err = grib_get_double(h, key, val); return err; } int grib_c_get_int_array(int* gid, char* key, int* val, int* size) { grib_handle* h = get_handle(*gid); long* long_val = NULL; int err = GRIB_SUCCESS; size_t lsize = *size; if (!h) return GRIB_INVALID_GRIB; if (sizeof(long) == sizeof(int)) { long_val = (long*)val; err = grib_get_long_array(h, key, long_val, &lsize); *size = lsize; return err; } if (*size) long_val = grib_context_malloc(h->context, (*size) * (sizeof(long))); else long_val = grib_context_malloc(h->context, (sizeof(long))); if (!long_val) return GRIB_OUT_OF_MEMORY; err = grib_get_long_array(h, key, long_val, &lsize); for (*size = 0; *size < lsize; (*size)++) val[*size] = long_val[*size]; grib_context_free(h->context, long_val); return err; } int grib_c_get_long_array(int* gid, char* key, long* val, int* size) { grib_handle* h = get_handle(*gid); int err = GRIB_SUCCESS; size_t lsize = *size; if (!h) return GRIB_INVALID_GRIB; err = grib_get_long_array(h, key, val, &lsize); *size = lsize; return err; } int grib_c_index_get_string(int* gid, char* key, char* val, int* eachsize, int* size) { grib_index* h = get_index(*gid); int err = GRIB_SUCCESS; int i; size_t lsize = *size; char** bufval; char* p = val; if (!h) return GRIB_INVALID_GRIB; bufval = (char**)grib_context_malloc_clear(h->context, sizeof(char*) * *size); err = grib_index_get_string(h, key, bufval, &lsize); *size = lsize; if (err) return err; for (i = 0; i < lsize; i++) { int l = strlen(bufval[i]); int j; if (*eachsize < l) { grib_context_free(h->context, bufval); printf("eachsize=%d strlen(bufval[i])=%d\n", *eachsize, (unsigned int)strlen(bufval[i])); return GRIB_ARRAY_TOO_SMALL; } memcpy(p, bufval[i], l); p += l; for (j = 0; j < *eachsize - l; j++) *(p++) = ' '; } grib_context_free(h->context, bufval); return err; } int grib_c_index_get_long(int* gid, char* key, long* val, int* size) { grib_index* h = get_index(*gid); int err = GRIB_SUCCESS; size_t lsize = *size; if (!h) return GRIB_INVALID_GRIB; err = grib_index_get_long(h, key, val, &lsize); *size = lsize; return err; } int grib_c_index_get_int(int* gid, char* key, int* val, int* size) { grib_index* h = get_index(*gid); int err = GRIB_SUCCESS; size_t lsize = *size; long* lval = 0; int i; if (!h) return GRIB_INVALID_GRIB; lval = grib_context_malloc(h->context, sizeof(long) * *size); if (!lval) return GRIB_OUT_OF_MEMORY; err = grib_index_get_long(h, key, lval, &lsize); for (i = 0; i < lsize; i++) val[i] = lval[i]; *size = lsize; return err; } int grib_c_index_get_real8(int* gid, char* key, double* val, int* size) { grib_index* h = get_index(*gid); int err = GRIB_SUCCESS; size_t lsize = *size; if (!h) return GRIB_INVALID_GRIB; err = grib_index_get_double(h, key, val, &lsize); *size = lsize; return err; } int grib_c_set_int_array(int* gid, char* key, int* val, int* size) { grib_handle* h = get_handle(*gid); int err = GRIB_SUCCESS; long* long_val = NULL; size_t lsize = *size; if (!h) return GRIB_INVALID_GRIB; if (sizeof(long) == sizeof(int)) { long_val = (long*)val; return grib_set_long_array(h, key, long_val, lsize); } if (lsize) long_val = grib_context_malloc(h->context, (lsize) * (sizeof(long))); else long_val = grib_context_malloc(h->context, (sizeof(long))); if (!long_val) return GRIB_OUT_OF_MEMORY; for (lsize = 0; lsize < (*size); lsize++) long_val[lsize] = val[lsize]; err = grib_set_long_array(h, key, long_val, lsize); grib_context_free(h->context, long_val); return err; } int grib_c_set_long_array(int* gid, char* key, long* val, int* size) { grib_handle* h = get_handle(*gid); int err = GRIB_SUCCESS; size_t lsize = *size; if (!h) return GRIB_INVALID_GRIB; return grib_set_long_array(h, key, val, lsize); return err; } int grib_c_set_int(int* gid, char* key, int* val) { grib_handle* h = get_handle(*gid); long long_val = *val; if (!h) return GRIB_INVALID_GRIB; return grib_set_long(h, key, long_val); } int grib_c_set_long(int* gid, char* key, long* val) { grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; return grib_set_long(h, key, *val); } int grib_c_set_missing(int* gid, char* key) { grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; return grib_set_missing(h, key); } /* * Submits all keys with the given values in one go. * 'keyvals' is a string of the form: * key1=val1,key2=val2,key3=val3 */ int grib_c_set_key_vals(int* gid, char* keyvals) { grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; { int err = GRIB_SUCCESS; grib_values values[1024] = {{0,},}; int count = 1000; /* max. num key/val pairs */ if ((err = parse_keyval_string(NULL, keyvals, 1, GRIB_TYPE_UNDEFINED, values, &count)) != GRIB_SUCCESS) { return err; } if ((err = grib_set_values(h, values, count)) != GRIB_SUCCESS) { return err; } } return GRIB_SUCCESS; } int grib_c_is_missing(int* gid, char* key, int* isMissing) { int err = 0; grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; *isMissing = grib_is_missing(h, key, &err); return err; } int grib_c_is_defined(int* gid, char* key, int* isDefined) { grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; *isDefined = grib_is_defined(h, key); return GRIB_SUCCESS; } int grib_c_set_real4(int* gid, char* key, float* val) { grib_handle* h = get_handle(*gid); double val8 = *val; if (!h) return GRIB_INVALID_GRIB; return grib_set_double(h, key, val8); } int grib_c_get_real4_element(int* gid, char* key, int* index, float* val) { grib_handle* h = get_handle(*gid); int err = GRIB_SUCCESS; double val8 = 0; if (!h) return GRIB_INVALID_GRIB; err = grib_get_double_element(h, key, *index, &val8); *val = val8; return err; } int grib_c_get_real4_elements(int* gid, char* key, int* index, float* val, int* size) { grib_handle* h = get_handle(*gid); int err = GRIB_SUCCESS; size_t lsize = *size; long i = 0; double* val8 = NULL; if (!h) return GRIB_INVALID_GRIB; if (*size) val8 = grib_context_malloc(h->context, (*size) * (sizeof(double))); else val8 = grib_context_malloc(h->context, sizeof(double)); if (!val8) return GRIB_OUT_OF_MEMORY; err = grib_get_double_elements(h, key, index, (long)lsize, val8); for (i = 0; i < lsize; (i)++) val[i] = val8[i]; grib_context_free(h->context, val8); return err; } int grib_c_get_real4(int* gid, char* key, float* val) { grib_handle* h = get_handle(*gid); int err = GRIB_SUCCESS; double val8 = 0; if (!h) return GRIB_INVALID_GRIB; err = grib_get_double(h, key, &val8); *val = val8; return err; } int grib_c_get_real4_array(int* gid, char* key, float* val, int* size) { grib_handle* h = get_handle(*gid); int err = GRIB_SUCCESS; size_t lsize = *size; double* val8 = NULL; if (!h) return GRIB_INVALID_GRIB; if (*size) val8 = grib_context_malloc(h->context, (*size) * (sizeof(double))); else val8 = grib_context_malloc(h->context, sizeof(double)); if (!val8) return GRIB_OUT_OF_MEMORY; err = grib_get_double_array(h, key, val8, &lsize); for (*size = 0; *size < lsize; (*size)++) val[*size] = val8[*size]; grib_context_free(h->context, val8); return err; } int grib_c_set_real4_array(int* gid, char* key, float* val, int* size) { grib_handle* h = get_handle(*gid); int err = GRIB_SUCCESS; size_t lsize = *size; double* val8 = NULL; if (!h) return GRIB_INVALID_GRIB; if (*size) val8 = grib_context_malloc(h->context, lsize * (sizeof(double))); else val8 = grib_context_malloc(h->context, sizeof(double)); if (!val8) return GRIB_OUT_OF_MEMORY; for (lsize = 0; lsize < *size; lsize++) val8[lsize] = val[lsize]; err = grib_set_double_array(h, key, val8, lsize); grib_context_free(h->context, val8); return err; } int grib_c_index_select_real8(int* gid, char* key, double* val) { grib_index* h = get_index(*gid); if (!h) return GRIB_INVALID_GRIB; return grib_index_select_double(h, key, *val); } int grib_c_index_select_string(int* gid, char* key, char* val) { grib_index* h = get_index(*gid); if (!h) return GRIB_INVALID_GRIB; return grib_index_select_string(h, key, val); } int grib_c_index_select_int(int* gid, char* key, int* val) { grib_index* h = get_index(*gid); long lval = *val; if (!h) return GRIB_INVALID_GRIB; return grib_index_select_long(h, key, lval); } int grib_c_index_select_long(int* gid, char* key, long* val) { grib_index* h = get_index(*gid); if (!h) return GRIB_INVALID_GRIB; return grib_index_select_long(h, key, *val); } int grib_c_set_real8(int* gid, char* key, double* val) { grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; return grib_set_double(h, key, *val); } int grib_c_get_real8(int* gid, char* key, double* val) { grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; return grib_get_double(h, key, val); } int grib_c_set_double(int* gid, char* key, double* val) { grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; return grib_set_double(h, key, *val); } int grib_c_get_real8_element(int* gid, char* key, int* index, double* val) { grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; return grib_get_double_element(h, key, *index, val); } int grib_c_get_real8_elements(int* gid, char* key, int* index, double* val, int* size) { grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; return grib_get_double_elements(h, key, index, *size, val); } int grib_c_find_nearest_four_single(int* gid, int* is_lsm, double* inlat, double* inlon, double* outlats, double* outlons, double* values, double* distances, int* indexes) { grib_nearest* nearest = NULL; int err = 0, result = 0; unsigned long flags = 0; size_t len = 4; grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; nearest = grib_nearest_new(h, &err); if (err != GRIB_SUCCESS) return err; result = grib_nearest_find(nearest, h, *inlat, *inlon, flags, outlats, outlons, values, distances, indexes, &len); grib_nearest_delete(nearest); return result; } int grib_c_find_nearest_single(int* gid, int* is_lsm, double* inlats, double* inlons, double* outlats, double* outlons, double* values, double* distances, int* indexes) { grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; return grib_nearest_find_multiple(h, *is_lsm, inlats, inlons, 1, outlats, outlons, values, distances, indexes); } int grib_c_find_nearest_multiple(int* gid, int* is_lsm, double* inlats, double* inlons, double* outlats, double* outlons, double* values, double* distances, int* indexes, int* npoints) { grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; return grib_nearest_find_multiple(h, *is_lsm, inlats, inlons, *npoints, outlats, outlons, values, distances, indexes); } int grib_c_get_real8_array(int* gid, char* key, double* val, int* size) { grib_handle* h = get_handle(*gid); int err = GRIB_SUCCESS; size_t lsize = *size; if (!h) { return GRIB_INVALID_GRIB; } else { err = grib_get_double_array(h, key, val, &lsize); *size = lsize; return err; } } int grib_c_set_real8_array(int* gid, char* key, double* val, int* size) { grib_handle* h = get_handle(*gid); size_t lsize = *size; if (!h) return GRIB_INVALID_GRIB; return grib_set_double_array(h, key, val, lsize); } int grib_c_set_double_array(int* gid, char* key, double* val, int* size) { grib_handle* h = get_handle(*gid); size_t lsize = *size; if (!h) return GRIB_INVALID_GRIB; return grib_set_double_array(h, key, val, lsize); } int grib_c_get_string(int* gid, char* key, char* val, size_t* lsize) { grib_handle* h = get_handle(*gid); int err = GRIB_SUCCESS; if (!h) return GRIB_INVALID_GRIB; err = grib_get_string(h, key, val, lsize); return err; } int grib_c_get_string_array(int* gid, char* key, char** val, size_t* lsize) { grib_handle* h = get_handle(*gid); int err = GRIB_SUCCESS; if (!h) return GRIB_INVALID_GRIB; err = grib_get_string_array(h, key, val, lsize); return err; } int grib_c_set_string(int* gid, char* key, char* val, int len2) { grib_handle* h = get_handle(*gid); size_t lsize = len2; if (!h) return GRIB_INVALID_GRIB; return grib_set_string(h, key, val, &lsize); } int grib_c_set_string_array(int* gid, char* key, const char** val) { grib_handle* h = get_handle(*gid); int err = GRIB_SUCCESS; size_t lsize = 0; if (!h) return GRIB_INVALID_GRIB; /* Note: The array passed in will have its final entry as NULL */ /* so to find its size we just iterate thru it. */ /* See typemap for char** in swig interface file */ while (val[lsize]) { ++lsize; } err = grib_set_string_array(h, key, val, lsize); return err; } int grib_c_get_data_real4(int* gid, float* lats, float* lons, float* values, size_t* size) { grib_handle* h = get_handle(*gid); int err = GRIB_SUCCESS; double *lat8 = NULL, *lon8 = NULL, *val8 = NULL; size_t i = 0; if (!h) return GRIB_INVALID_GRIB; val8 = grib_context_malloc(h->context, (*size) * (sizeof(double))); if (!val8) return GRIB_OUT_OF_MEMORY; lon8 = grib_context_malloc(h->context, (*size) * (sizeof(double))); if (!lon8) return GRIB_OUT_OF_MEMORY; lat8 = grib_context_malloc(h->context, (*size) * (sizeof(double))); if (!lat8) return GRIB_OUT_OF_MEMORY; err = grib_get_data(h, lat8, lon8, val8); for (i = 0; i < *size; i++) { values[i] = val8[i]; lats[i] = lat8[i]; lons[i] = lon8[i]; } grib_context_free(h->context, val8); grib_context_free(h->context, lat8); grib_context_free(h->context, lon8); return err; } /* int grib_c_get_data_real8(int* gid,double* lats, double* lons,double* values,size_t* size) { grib_handle *h = get_handle(*gid); return grib_get_data(h,lats,lons,values); } */ int grib_c_copy_message(int* gid, void* mess, size_t* len) { grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; if (*len < h->buffer->ulength) { grib_context_log(h->context, GRIB_LOG_ERROR, "grib_copy_message: buffer=%ld message size=%ld", *len, h->buffer->ulength); return GRIB_BUFFER_TOO_SMALL; } memcpy(mess, h->buffer->data, h->buffer->ulength); *len = h->buffer->ulength; return GRIB_SUCCESS; } int grib_c_bufr_copy_data(int* msgid_src, int* msgid_dst) { int err = 0; grib_handle* src = get_handle(*msgid_src); grib_handle* dest = get_handle(*msgid_dst); if (!src || !dest) { return GRIB_INVALID_GRIB; } err = codes_bufr_copy_data(src, dest); return err; } void grib_c_check(int* err, char* call, char* str) { grib_context* c = grib_context_get_default(); if (*err == GRIB_SUCCESS || *err == GRIB_END_OF_FILE) return; grib_context_log(c, GRIB_LOG_ERROR, "%s: %s %s", call, str, grib_get_error_message(*err)); exit(*err); } int grib_c_write(int* gid, FILE* f) { grib_handle* h = get_handle(*gid); const void* mess = NULL; size_t mess_len = 0; if (!f) return GRIB_INVALID_FILE; if (!h) return GRIB_INVALID_GRIB; grib_get_message(h, &mess, &mess_len); if (fwrite(mess, 1, mess_len, f) != mess_len) { perror("grib_write"); return GRIB_IO_PROBLEM; } return GRIB_SUCCESS; } int grib_c_multi_new(int* mgid) { grib_multi_handle* mh = grib_multi_handle_new(0); if (!mh) return GRIB_INVALID_GRIB; push_multi_handle(mh, mgid); return GRIB_SUCCESS; } int grib_c_multi_write(int* gid, FILE* f) { grib_multi_handle* h = get_multi_handle(*gid); if (!f) return GRIB_INVALID_FILE; if (!h) return GRIB_INVALID_GRIB; return grib_multi_handle_write(h, f); } int grib_c_multi_append(int* ingid, int* sec, int* mgid) { grib_handle* h = get_handle(*ingid); grib_multi_handle* mh = get_multi_handle(*mgid); if (!h) return GRIB_INVALID_GRIB; if (!mh) { mh = grib_multi_handle_new(h->context); push_multi_handle(mh, mgid); } return grib_multi_handle_append(h, *sec, mh); } int grib_c_get_native_type(int* gid, char* key, int* type) { grib_handle* h = get_handle(*gid); if (!h) return GRIB_INVALID_GRIB; return grib_get_native_type(h, key, type); } int grib_c_index_write(int* gid, char* file) { grib_index* i = get_index(*gid); int err = GRIB_SUCCESS; if (!i) { return GRIB_INVALID_GRIB; } else { err = grib_index_write(i, file); return err; } } int grib_c_index_read(char* file, int* gid) { int err = 0; grib_index* i = NULL; if (*file) { i = grib_index_read(0, file, &err); if (i) { push_index(i, gid); return GRIB_SUCCESS; } else { *gid = -1; return GRIB_END_OF_FILE; } } *gid = -1; return GRIB_INVALID_FILE; } void no_fail_on_wrong_length(int flag) { grib_context* c = grib_context_get_default(); int value; assert(c != NULL); value = (flag != 0) ? 1 : 0; c->no_fail_on_wrong_length = value; } void grib_c_gts_header_on(void) { grib_context* c = grib_context_get_default(); assert(c != NULL); grib_gts_header_on(c); } void grib_c_gts_header_off(void) { grib_context* c = grib_context_get_default(); assert(c != NULL); grib_gts_header_off(c); } long grib_c_get_api_version(void) { return grib_get_api_version(); } int grib_c_get_message(int* gid, const void** msg, size_t* size) { grib_handle* h = get_handle(*gid); return grib_get_message(h, msg, size); } void grib_c_set_definitions_path(const char* path) { grib_context* c = grib_context_get_default(); grib_context_set_definitions_path(c, path); } void grib_c_set_samples_path(const char* path) { grib_context* c = grib_context_get_default(); grib_context_set_samples_path(c, path); } int codes_c_bufr_multi_element_constant_arrays_on(void) { codes_bufr_multi_element_constant_arrays_on(NULL); return GRIB_SUCCESS; } int codes_c_bufr_multi_element_constant_arrays_off(void) { codes_bufr_multi_element_constant_arrays_off(NULL); return GRIB_SUCCESS; }