From 37ba442bc1c310615f25ba90ba11b424423a7928 Mon Sep 17 00:00:00 2001 From: Shahram Najm Date: Wed, 21 Nov 2018 15:14:45 +0000 Subject: [PATCH] Python3: Fix for writing GRIB data --- python/grib_interface.c | 16 +++++++++++----- python/gribapi/gribapi.py | 2 ++ python/gribapi_swig.i | 17 ++++++++++++++--- python/swig_wrap_numpy.c | 6 ++---- 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/python/grib_interface.c b/python/grib_interface.c index a12941060..e8b47ad8a 100644 --- a/python/grib_interface.c +++ b/python/grib_interface.c @@ -1371,8 +1371,8 @@ int grib_c_new_from_file(FILE* f, int fd, char* fname, int* gid, int headers_onl if (p) { h=grib_new_from_file(0,p,headers_only,&err);//use cached value } else { - h=grib_new_from_file(0,f,headers_only,&err);//get new FILE* - store_file_info(fd, f); + h=grib_new_from_file(0,f,headers_only,&err);//use FILE pointer passed in + store_file_info(fd, f); //store it for next time } if(h){ @@ -1382,7 +1382,7 @@ int grib_c_new_from_file(FILE* f, int fd, char* fname, int* gid, int headers_onl *gid=-1; if (err == GRIB_SUCCESS) { /*printf("C grib_c_new_from_file: GRIB_END_OF_FILE\n");*/ - return GRIB_END_OF_FILE; + return GRIB_END_OF_FILE; //TODO: remove element from cache } else { /* A real error occurred */ return err; @@ -2250,6 +2250,7 @@ void grib_c_check(int* err,char* call,char* str) int grib_c_write(int* gid, FILE* f) { + int err = 0; grib_handle *h = get_handle(*gid); const void* mess = NULL; size_t mess_len = 0; @@ -2257,12 +2258,17 @@ int grib_c_write(int* gid, FILE* f) if(!f) return GRIB_INVALID_FILE; if (!h) return GRIB_INVALID_GRIB; - grib_get_message(h,&mess,&mess_len); + err = grib_get_message(h,&mess,&mess_len); + if (err) return err; if(fwrite(mess,1, mess_len,f) != mess_len) { perror("grib_write"); return GRIB_IO_PROBLEM; } - + err = fflush(f); + if(err) { + perror("write flush"); + return GRIB_IO_PROBLEM; + } return GRIB_SUCCESS; } diff --git a/python/gribapi/gribapi.py b/python/gribapi/gribapi.py index 08f216b9e..46323b071 100644 --- a/python/gribapi/gribapi.py +++ b/python/gribapi/gribapi.py @@ -259,6 +259,8 @@ def bufr_new_from_file(fileobj, headers_only=False): @return id of the BUFR loaded in memory @exception GribInternalError """ + fd = fileobj.fileno() + fn = fileobj.name err, bufrid = _internal.grib_c_new_bufr_from_file(fileobj, headers_only, 0) if err: if err == _internal.GRIB_END_OF_FILE: diff --git a/python/gribapi_swig.i b/python/gribapi_swig.i index ef5d26811..da49ef14f 100644 --- a/python/gribapi_swig.i +++ b/python/gribapi_swig.i @@ -17,9 +17,7 @@ import_array(); %} -/* OLD: Converts a PyFile instance to a stdio FILE* */ - -/* OLD: FIXME: Can we make this ro/rw ? */ +/* Converts a PyFile instance to a stdio FILE* for reading binary files */ %typemap(in) FILE* { int fileDescriptor = PyObject_AsFileDescriptor($input); /*printf("swig.i fileDescriptor=%d\n", fileDescriptor);*/ @@ -70,6 +68,19 @@ int grib_c_new_from_message(int *INOUT, char *binmsg, size_t *INPUT); int grib_c_count_in_file(FILE* f,int* OUTPUT); // --- +/* Converts a PyFile instance to a stdio FILE* for writing binary files */ +%typemap(in) FILE* { + int fileDescriptor = PyObject_AsFileDescriptor($input); + if(fileDescriptor >= 0) { + /* Convert file descriptor to a FILE pointer */ + $1 = fdopen(fileDescriptor,"wb"); + } + else { + PyErr_SetString(PyExc_TypeError, "$1_name must be a file type."); + return NULL; + } +} + // grib handle operations int grib_c_release(int* gid); int grib_c_write(int* gid, FILE* f); diff --git a/python/swig_wrap_numpy.c b/python/swig_wrap_numpy.c index b06bc37d2..0c98094fe 100644 --- a/python/swig_wrap_numpy.c +++ b/python/swig_wrap_numpy.c @@ -6156,10 +6156,9 @@ SWIGINTERN PyObject *_wrap_grib_c_write(PyObject *SWIGUNUSEDPARM(self), PyObject } { int fileDescriptor = PyObject_AsFileDescriptor(obj1); - /*printf("swig.i fileDescriptor=%d\n", fileDescriptor);*/ if(fileDescriptor >= 0) { /* Convert file descriptor to a FILE pointer */ - arg2 = fdopen(fileDescriptor,"rb"); // needs to be rb+ (or wb) for write + arg2 = fdopen(fileDescriptor,"wb"); } else { PyErr_SetString(PyExc_TypeError, "f must be a file type."); @@ -6572,10 +6571,9 @@ SWIGINTERN PyObject *_wrap_grib_c_multi_write(PyObject *SWIGUNUSEDPARM(self), Py } { int fileDescriptor = PyObject_AsFileDescriptor(obj1); - /*printf("swig.i fileDescriptor=%d\n", fileDescriptor);*/ if(fileDescriptor >= 0) { /* Convert file descriptor to a FILE pointer */ - arg2 = fdopen(fileDescriptor,"rb"); // needs to be rb+ (or wb) for write + arg2 = fdopen(fileDescriptor,"wb"); } else { PyErr_SetString(PyExc_TypeError, "f must be a file type.");