[segyio] 103/376: Put FILE* inside segy_file opaque struct

Jørgen Kvalsvik jokva-guest at moszumanska.debian.org
Wed Sep 20 08:04:15 UTC 2017


This is an automated email from the git hooks/post-receive script.

jokva-guest pushed a commit to branch debian
in repository segyio.

commit bc957a04b67582c76e44434700d794e484bc8d39
Author: Jørgen Kvalsvik <jokva at statoil.com>
Date:   Wed Nov 2 15:39:56 2016 +0100

    Put FILE* inside segy_file opaque struct
    
    Puts file information inside an opaque handle so we can more easily
    runtime enable file handling enhancement features such as mmap without
    breaking clients.
---
 applications/segyinfo.c    |   4 +-
 applications/segyinspect.c |   4 +-
 python/segyio/_segyio.c    |  44 +++++++++---------
 src/segyio/segy.c          | 111 ++++++++++++++++++++++++++++++---------------
 src/segyio/segy.h          |  41 ++++++++++-------
 src/segyio/util.h          |   5 +-
 src/spec/segyspec.c        |   6 +--
 tests/test_segy.c          |  36 +++++++--------
 8 files changed, 150 insertions(+), 101 deletions(-)

diff --git a/applications/segyinfo.c b/applications/segyinfo.c
index c6bd858..5e59cd6 100644
--- a/applications/segyinfo.c
+++ b/applications/segyinfo.c
@@ -33,7 +33,7 @@ int main(int argc, char* argv[]) {
         exit(1);
     }
 
-    FILE* fp = fopen( argv[ 1 ], "rb" );
+    segy_file* fp = segy_open( argv[ 1 ], "rb" );
     if( !fp ) {
         perror( "fopen():" );
         exit( 3 );
@@ -136,6 +136,6 @@ int main(int argc, char* argv[]) {
     clock_t diff = clock() - start;
     printf("Read all trace headers in: %.2f s\n", (double) diff / CLOCKS_PER_SEC);
 
-    fclose( fp );
+    segy_close( fp );
     return 0;
 }
diff --git a/applications/segyinspect.c b/applications/segyinspect.c
index b34ddf3..61750c4 100644
--- a/applications/segyinspect.c
+++ b/applications/segyinspect.c
@@ -54,7 +54,7 @@ int main(int argc, char* argv[]) {
 
     clock_t start = clock();
 
-    FILE* fp = fopen( argv[ 1 ], "rb" );
+    segy_file* fp = segy_open( argv[ 1 ], "rb" );
     if( !fp ) {
         perror( "fopen()" );
         exit( SEGY_FOPEN_ERROR );
@@ -161,7 +161,7 @@ int main(int argc, char* argv[]) {
 
     free( inline_indices );
     free( crossline_indices );
-    fclose( fp );
+    segy_close( fp );
 
     exit(0);
 }
diff --git a/python/segyio/_segyio.c b/python/segyio/_segyio.c
index 3d2ecc4..156f1e9 100644
--- a/python/segyio/_segyio.c
+++ b/python/segyio/_segyio.c
@@ -11,8 +11,8 @@
 #include <string.h>
 
 // ---------------  FILE Handling ------------
-static FILE *get_FILE_pointer_from_capsule(PyObject *capsule) {
-    if (!PyCapsule_IsValid(capsule, "FILE*")) {
+static segy_file *get_FILE_pointer_from_capsule(PyObject *capsule) {
+    if (!PyCapsule_IsValid(capsule, "segy_file*")) {
         PyErr_SetString(PyExc_TypeError, "The object was not of type FILE");
         return NULL;
     }
@@ -22,7 +22,7 @@ static FILE *get_FILE_pointer_from_capsule(PyObject *capsule) {
         return NULL;
     }
 
-    FILE *p_FILE = PyCapsule_GetPointer(capsule, "FILE*");
+    segy_file *p_FILE = PyCapsule_GetPointer(capsule, "segy_file*");
 
     if (!p_FILE) {
         PyErr_SetString(PyExc_ValueError, "File Handle is NULL");
@@ -33,7 +33,7 @@ static FILE *get_FILE_pointer_from_capsule(PyObject *capsule) {
 
 static void *py_FILE_destructor(PyObject *capsule) {
 #ifndef NDEBUG
-    fputs("FILE* destructed before calling close()\n", stderr);
+    fputs("segy_file* destructed before calling close()\n", stderr);
 #endif
     return NULL;
 }
@@ -64,13 +64,13 @@ static PyObject *py_FILE_open(PyObject *self, PyObject *args) {
         return NULL;
     }
 
-    FILE *p_FILE = fopen( filename, binary_mode );
+    segy_file *p_FILE = segy_open( filename, binary_mode );
     free( binary_mode );
 
     if (p_FILE == NULL) {
         return PyErr_SetFromErrnoWithFilename(PyExc_IOError, filename);
     }
-    return PyCapsule_New(p_FILE, "FILE*", (PyCapsule_Destructor) py_FILE_destructor);
+    return PyCapsule_New(p_FILE, "segy_file*", (PyCapsule_Destructor) py_FILE_destructor);
 }
 
 static PyObject *py_FILE_close(PyObject *self, PyObject *args) {
@@ -78,11 +78,11 @@ static PyObject *py_FILE_close(PyObject *self, PyObject *args) {
     PyObject *file_capsule = NULL;
     PyArg_ParseTuple(args, "O", &file_capsule);
 
-    FILE *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
+    segy_file *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
 
     if (PyErr_Occurred()) { return NULL; }
 
-    fclose(p_FILE);
+    segy_close(p_FILE);
 
     if (errno != 0) {
         return PyErr_SetFromErrno(PyExc_IOError);
@@ -98,12 +98,14 @@ static PyObject *py_FILE_flush(PyObject *self, PyObject *args) {
     PyObject *file_capsule = NULL;
     PyArg_ParseTuple(args, "O", &file_capsule);
 
-    FILE *p_FILE = NULL;
+    segy_file *p_FILE = NULL;
     if(file_capsule != Py_None) {
         p_FILE = get_FILE_pointer_from_capsule(file_capsule);
     }
 
-    fflush(p_FILE);
+    if( !p_FILE ) return Py_BuildValue("");
+
+    segy_flush(p_FILE, false );
 
     if (errno != 0) {
         return PyErr_SetFromErrno(PyExc_IOError);
@@ -202,7 +204,7 @@ static PyObject *py_read_texthdr(PyObject *self, PyObject *args) {
 
     PyArg_ParseTuple(args, "Oi", &file_capsule, &index);
 
-    FILE *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
+    segy_file *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
 
     char *buffer = malloc(sizeof(char) * (segy_textheader_size()));
 
@@ -231,7 +233,7 @@ static PyObject *py_write_texthdr(PyObject *self, PyObject *args) {
         return PyErr_Format(PyExc_ValueError, "String must have at least 3200 characters. Received count: %d", size);
     }
 
-    FILE *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
+    segy_file *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
 
     int error = segy_write_textheader(p_FILE, index, buffer);
 
@@ -338,7 +340,7 @@ static PyObject *py_read_binaryhdr(PyObject *self, PyObject *args) {
 
     PyArg_ParseTuple(args, "O", &file_capsule);
 
-    FILE *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
+    segy_file *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
 
     if (PyErr_Occurred()) { return NULL; }
 
@@ -361,7 +363,7 @@ static PyObject *py_write_binaryhdr(PyObject *self, PyObject *args) {
 
     PyArg_ParseTuple(args, "OO", &file_capsule, &binary_header_capsule);
 
-    FILE *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
+    segy_file *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
     char *binary_header = get_header_pointer_from_capsule(binary_header_capsule, NULL);
 
     if (PyErr_Occurred()) { return NULL; }
@@ -406,7 +408,7 @@ static PyObject *py_read_trace_header(PyObject *self, PyObject *args) {
 
     PyArg_ParseTuple(args, "OIOlI", &file_capsule, &traceno, &trace_header_capsule, &trace0, &trace_bsize);
 
-    FILE *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
+    segy_file *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
 
     if (PyErr_Occurred()) { return NULL; }
 
@@ -434,7 +436,7 @@ static PyObject *py_write_trace_header(PyObject *self, PyObject *args) {
 
     PyArg_ParseTuple(args, "OIOlI", &file_capsule, &traceno, &trace_header_capsule, &trace0, &trace_bsize);
 
-    FILE *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
+    segy_file *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
 
     if (PyErr_Occurred()) { return NULL; }
 
@@ -504,7 +506,7 @@ static PyObject *py_init_metrics(PyObject *self, PyObject *args) {
 
     PyArg_ParseTuple(args, "OOii", &file_capsule, &binary_header_capsule, &il_field, &xl_field);
 
-    FILE *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
+    segy_file *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
 
     if (PyErr_Occurred()) { return NULL; }
 
@@ -613,7 +615,7 @@ static PyObject *py_init_line_indices(PyObject *self, PyObject *args) {
 
     PyArg_ParseTuple(args, "OOOO", &file_capsule, &metrics, &iline_out, &xline_out);
 
-    FILE *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
+    segy_file *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
 
     if (PyErr_Occurred()) { return NULL; }
 
@@ -716,7 +718,7 @@ static PyObject *py_read_trace(PyObject *self, PyObject *args) {
 
     PyArg_ParseTuple(args, "OOiOlIiI", &file_capsule, &trace_no, &trace_count, &buffer_out, &trace0, &trace_bsize, &format, &samples);
 
-    FILE *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
+    segy_file *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
 
     if (PyErr_Occurred()) { return NULL; }
 
@@ -791,7 +793,7 @@ static PyObject *py_write_trace(PyObject *self, PyObject *args) {
 
     PyArg_ParseTuple(args, "OIOlIiI", &file_capsule, &trace_no, &buffer_in, &trace0, &trace_bsize, &format, &samples);
 
-    FILE *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
+    segy_file *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
 
     if (PyErr_Occurred()) { return NULL; }
 
@@ -840,7 +842,7 @@ static PyObject *py_read_line(PyObject *self, PyObject *args) {
     PyArg_ParseTuple(args, "OIIIOlIiI", &file_capsule, &line_trace0, &line_length, &stride, &buffer_in, &trace0,
                      &trace_bsize, &format, &samples);
 
-    FILE *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
+    segy_file *p_FILE = get_FILE_pointer_from_capsule(file_capsule);
 
     if (PyErr_Occurred()) { return NULL; }
 
diff --git a/src/segyio/segy.c b/src/segyio/segy.c
index 6814770..4b7bbb2 100644
--- a/src/segyio/segy.c
+++ b/src/segyio/segy.c
@@ -294,6 +294,40 @@ static int bfield_size[] = {
     [- HEADER_SIZE + BIN_Unassigned2]           =  0,
 };
 
+struct segy_file_handle {
+    FILE* fp;
+};
+
+segy_file* segy_open( const char* path, const char* mode ) {
+    FILE* fp = fopen( path, mode );
+
+    if( !fp ) return NULL;
+
+    segy_file* file = malloc( sizeof( segy_file ) );
+
+    if( !file ) {
+        fclose( fp );
+        return NULL;
+    }
+
+    file->fp = fp;
+    return file;
+}
+
+int segy_flush( segy_file* fp, bool async ) {
+    return fflush( fp->fp );
+}
+
+long segy_ftell( segy_file* fp ) {
+    return ftell( fp->fp );
+}
+
+int segy_close( segy_file* fp ) {
+    int err = fclose( fp->fp );
+    free( fp );
+    return err;
+}
+
 static int get_field( const char* header,
                       const int* table,
                       int field,
@@ -375,30 +409,30 @@ int segy_set_bfield( char* binheader, int field, int val ) {
     return set_field( binheader, bfield_size, field, val );
 }
 
-int segy_binheader( FILE* fp, char* buf ) {
+int segy_binheader( segy_file* fp, char* buf ) {
     if(fp == NULL) {
         return SEGY_INVALID_ARGS;
     }
 
-    const int err = fseek( fp, SEGY_TEXT_HEADER_SIZE, SEEK_SET );
+    const int err = fseek( fp->fp, SEGY_TEXT_HEADER_SIZE, SEEK_SET );
     if( err != 0 ) return SEGY_FSEEK_ERROR;
 
-    const size_t read_count = fread( buf, 1, SEGY_BINARY_HEADER_SIZE, fp);
+    const size_t read_count = fread( buf, 1, SEGY_BINARY_HEADER_SIZE, fp->fp );
     if( read_count != SEGY_BINARY_HEADER_SIZE )
         return SEGY_FREAD_ERROR;
 
     return SEGY_OK;
 }
 
-int segy_write_binheader( FILE* fp, const char* buf ) {
+int segy_write_binheader( segy_file* fp, const char* buf ) {
     if(fp == NULL) {
         return SEGY_INVALID_ARGS;
     }
 
-    const int err = fseek( fp, SEGY_TEXT_HEADER_SIZE, SEEK_SET );
+    const int err = fseek( fp->fp, SEGY_TEXT_HEADER_SIZE, SEEK_SET );
     if( err != 0 ) return SEGY_FSEEK_ERROR;
 
-    const size_t writec = fwrite( buf, 1, SEGY_BINARY_HEADER_SIZE, fp);
+    const size_t writec = fwrite( buf, 1, SEGY_BINARY_HEADER_SIZE, fp->fp );
     if( writec != SEGY_BINARY_HEADER_SIZE )
         return SEGY_FWRITE_ERROR;
 
@@ -430,19 +464,19 @@ long segy_trace0( const char* binheader ) {
            SEGY_TEXT_HEADER_SIZE * extra_headers;
 }
 
-int segy_seek( FILE* fp,
+int segy_seek( segy_file* fp,
                unsigned int trace,
                long trace0,
                unsigned int trace_bsize ) {
 
     trace_bsize += SEGY_TRACE_HEADER_SIZE;
     const long pos = trace0 + ( (long)trace * (long)trace_bsize );
-    const int err = fseek( fp, pos, SEEK_SET );
+    const int err = fseek( fp->fp, pos, SEEK_SET );
     if( err != 0 ) return SEGY_FSEEK_ERROR;
     return SEGY_OK;
 }
 
-int segy_traceheader( FILE* fp,
+int segy_traceheader( segy_file* fp,
                       unsigned int traceno,
                       char* buf,
                       long trace0,
@@ -451,7 +485,7 @@ int segy_traceheader( FILE* fp,
     const int err = segy_seek( fp, traceno, trace0, trace_bsize );
     if( err != 0 ) return err;
 
-    const size_t readc = fread( buf, 1, SEGY_TRACE_HEADER_SIZE, fp );
+    const size_t readc = fread( buf, 1, SEGY_TRACE_HEADER_SIZE, fp->fp );
 
     if( readc != SEGY_TRACE_HEADER_SIZE )
         return SEGY_FREAD_ERROR;
@@ -459,7 +493,7 @@ int segy_traceheader( FILE* fp,
     return SEGY_OK;
 }
 
-int segy_write_traceheader( FILE* fp,
+int segy_write_traceheader( segy_file* fp,
                             unsigned int traceno,
                             const char* buf,
                             long trace0,
@@ -468,7 +502,7 @@ int segy_write_traceheader( FILE* fp,
     const int err = segy_seek( fp, traceno, trace0, trace_bsize );
     if( err != 0 ) return err;
 
-    const size_t writec = fwrite( buf, 1, SEGY_TRACE_HEADER_SIZE, fp );
+    const size_t writec = fwrite( buf, 1, SEGY_TRACE_HEADER_SIZE, fp->fp );
 
     if( writec != SEGY_TRACE_HEADER_SIZE )
         return SEGY_FWRITE_ERROR;
@@ -502,10 +536,13 @@ static int file_size( FILE* fp, size_t* size ) {
  *
  * This function assumes that *all traces* are of the same size.
  */
-int segy_traces( FILE* fp, size_t* traces, long trace0, unsigned int trace_bsize ) {
+int segy_traces( segy_file* fp,
+                 size_t* traces,
+                 long trace0,
+                 unsigned int trace_bsize ) {
 
     size_t fsize;
-    int err = file_size( fp, &fsize );
+    int err = file_size( fp->fp, &fsize );
     if( err != 0 ) return err;
 
     trace_bsize += SEGY_TRACE_HEADER_SIZE;
@@ -518,7 +555,7 @@ int segy_traces( FILE* fp, size_t* traces, long trace0, unsigned int trace_bsize
     return SEGY_OK;
 }
 
-static int segy_sample_interval(FILE* fp, double* dt) {
+static int segy_sample_interval( segy_file* fp, double* dt) {
 
     char bin_header[ SEGY_BINARY_HEADER_SIZE ];
     char trace_header[SEGY_TRACE_HEADER_SIZE];
@@ -567,7 +604,7 @@ static int segy_sample_interval(FILE* fp, double* dt) {
 
 }
 
-int segy_sample_indexes(FILE* fp, double* buf, double t0, size_t count) {
+int segy_sample_indexes( segy_file* fp, double* buf, double t0, size_t count) {
 
     double dt;
     int err = segy_sample_interval(fp, &dt);
@@ -593,7 +630,7 @@ int segy_sample_indexes(FILE* fp, double* buf, double t0, size_t count) {
  * inline, header[0].ilnum should be equal to header[1].ilnum, similarly for
  * crosslines. If neither match, the sorting is considered unknown.
  */
-int segy_sorting( FILE* fp,
+int segy_sorting( segy_file* fp,
                   int il,
                   int xl,
                   int* sorting,
@@ -647,7 +684,7 @@ int segy_sorting( FILE* fp,
  * the crossline number changes (which changes first depends on sorting, but is
  * irrelevant for this function).
  */
-int segy_offsets( FILE* fp,
+int segy_offsets( segy_file* fp,
                   int il,
                   int xl,
                   unsigned int traces,
@@ -687,7 +724,7 @@ int segy_offsets( FILE* fp,
     return SEGY_OK;
 }
 
-static int segy_line_indices( FILE* fp,
+static int segy_line_indices( segy_file* fp,
                               int field,
                               unsigned int traceno,
                               unsigned int stride,
@@ -711,7 +748,7 @@ static int segy_line_indices( FILE* fp,
     return SEGY_OK;
 }
 
-static int count_lines( FILE* fp,
+static int count_lines( segy_file* fp,
                         int field,
                         unsigned int offsets,
                         unsigned int* out,
@@ -751,7 +788,7 @@ static int count_lines( FILE* fp,
     return SEGY_OK;
 }
 
-int segy_count_lines( FILE* fp,
+int segy_count_lines( segy_file* fp,
                       int field,
                       unsigned int offsets,
                       unsigned int* l1out,
@@ -785,7 +822,7 @@ unsigned int segy_crossline_length(unsigned int inline_count) {
     return inline_count;
 }
 
-int segy_inline_indices( FILE* fp,
+int segy_inline_indices( segy_file* fp,
                          int il,
                          int sorting,
                          unsigned int inline_count,
@@ -812,7 +849,7 @@ int segy_inline_indices( FILE* fp,
     return SEGY_INVALID_SORTING;
 }
 
-int segy_crossline_indices( FILE* fp,
+int segy_crossline_indices( segy_file* fp,
                             int xl,
                             int sorting,
                             unsigned int inline_count,
@@ -841,13 +878,13 @@ int segy_crossline_indices( FILE* fp,
 }
 
 
-static int skip_traceheader( FILE* fp ) {
-    const int err = fseek( fp, SEGY_TRACE_HEADER_SIZE, SEEK_CUR );
+static int skip_traceheader( segy_file* fp ) {
+    const int err = fseek( fp->fp, SEGY_TRACE_HEADER_SIZE, SEEK_CUR );
     if( err != 0 ) return SEGY_FSEEK_ERROR;
     return SEGY_OK;
 }
 
-int segy_readtrace( FILE* fp,
+int segy_readtrace( segy_file* fp,
                     unsigned int traceno,
                     float* buf,
                     long trace0,
@@ -859,14 +896,14 @@ int segy_readtrace( FILE* fp,
     err = skip_traceheader( fp );
     if( err != 0 ) return err;
 
-    const size_t readc = fread( buf, 1, trace_bsize, fp );
+    const size_t readc = fread( buf, 1, trace_bsize, fp->fp );
     if( readc != trace_bsize ) return SEGY_FREAD_ERROR;
 
     return SEGY_OK;
 
 }
 
-int segy_writetrace( FILE* fp,
+int segy_writetrace( segy_file* fp,
                      unsigned int traceno,
                      const float* buf,
                      long trace0,
@@ -879,7 +916,7 @@ int segy_writetrace( FILE* fp,
     err = skip_traceheader( fp );
     if( err != 0 ) return err;
 
-    const size_t writec = fwrite( buf, 1, trace_bsize, fp );
+    const size_t writec = fwrite( buf, 1, trace_bsize, fp->fp );
     if( writec != trace_bsize )
         return SEGY_FWRITE_ERROR;
     return SEGY_OK;
@@ -959,7 +996,7 @@ static long index_of( unsigned int x,
  * If reading a trace fails, this function will return whatever error
  * segy_readtrace returns.
  */
-int segy_read_line( FILE* fp,
+int segy_read_line( segy_file* fp,
                     unsigned int line_trace0,
                     unsigned int line_length,
                     unsigned int stride,
@@ -988,7 +1025,7 @@ int segy_read_line( FILE* fp,
  * If reading a trace fails, this function will return whatever error
  * segy_readtrace returns.
  */
-int segy_write_line( FILE* fp,
+int segy_write_line( segy_file* fp,
                      unsigned int line_trace0,
                      unsigned int line_length,
                      unsigned int stride,
@@ -1059,13 +1096,13 @@ int segy_crossline_stride( int sorting,
     }
 }
 
-int segy_read_textheader(FILE *fp, char *buf) { //todo: Missing position/index support
+int segy_read_textheader( segy_file* fp, char *buf) { //todo: Missing position/index support
     if(fp == NULL) {
         return SEGY_FSEEK_ERROR;
     }
-    rewind( fp );
+    rewind( fp->fp );
 
-    const size_t read = fread( buf, 1, SEGY_TEXT_HEADER_SIZE, fp );
+    const size_t read = fread( buf, 1, SEGY_TEXT_HEADER_SIZE, fp->fp );
     if( read != SEGY_TEXT_HEADER_SIZE ) return SEGY_FREAD_ERROR;
 
     buf[ SEGY_TEXT_HEADER_SIZE ] = '\0';
@@ -1073,7 +1110,7 @@ int segy_read_textheader(FILE *fp, char *buf) { //todo: Missing position/index s
     return SEGY_OK;
 }
 
-int segy_write_textheader( FILE* fp, unsigned int pos, const char* buf ) {
+int segy_write_textheader( segy_file* fp, unsigned int pos, const char* buf ) {
     int err;
     char mbuf[ SEGY_TEXT_HEADER_SIZE + 1 ];
 
@@ -1085,10 +1122,10 @@ int segy_write_textheader( FILE* fp, unsigned int pos, const char* buf ) {
                       : SEGY_TEXT_HEADER_SIZE + SEGY_BINARY_HEADER_SIZE +
                         ((pos-1) * SEGY_TEXT_HEADER_SIZE);
 
-    err = fseek( fp, offset, SEEK_SET );
+    err = fseek( fp->fp, offset, SEEK_SET );
     if( err != 0 ) return SEGY_FSEEK_ERROR;
 
-    size_t writec = fwrite( mbuf, 1, SEGY_TEXT_HEADER_SIZE, fp );
+    size_t writec = fwrite( mbuf, 1, SEGY_TEXT_HEADER_SIZE, fp->fp );
     if( writec != SEGY_TEXT_HEADER_SIZE )
         return SEGY_FWRITE_ERROR;
 
diff --git a/src/segyio/segy.h b/src/segyio/segy.h
index 3d9a444..9479f62 100644
--- a/src/segyio/segy.h
+++ b/src/segyio/segy.h
@@ -28,14 +28,21 @@
  * calls that use the same name for one of its parameters.
  */
 
+struct segy_file_handle;
+typedef struct segy_file_handle segy_file;
+
+segy_file* segy_open( const char* path, const char* mode );
+int segy_flush( segy_file*, bool async );
+int segy_close( segy_file* );
+
 /* binary header operations */
 /*
  * The binheader buffer passed to these functions must be of *at least*
  * `segy_binheader_size`.
  */
 unsigned int segy_binheader_size();
-int segy_binheader( FILE*, char* buf );
-int segy_write_binheader( FILE*, const char* buf );
+int segy_binheader( segy_file*, char* buf );
+int segy_write_binheader( segy_file*, const char* buf );
 unsigned int segy_samples( const char* binheader );
 /* exception: the int returned is an enum, SEGY_SORTING, not an error code */
 int segy_format( const char* binheader );
@@ -48,24 +55,24 @@ unsigned segy_trace_bsize( unsigned int samples );
 /* byte-offset of the first trace header. */
 long segy_trace0( const char* binheader );
 /* number of traces in this file */
-int segy_traces( FILE*, size_t*, long trace0, unsigned int trace_bsize );
+int segy_traces( segy_file*, size_t*, long trace0, unsigned int trace_bsize );
 
-int segy_sample_indexes(FILE* fp, double* buf, double t0, size_t count);
+int segy_sample_indexes(segy_file* fp, double* buf, double t0, size_t count);
 
 /* text header operations */
-int segy_read_textheader(FILE *, char *buf);
+int segy_read_textheader( segy_file*, char *buf);
 int segy_textheader_size();
-int segy_write_textheader( FILE*, unsigned int pos, const char* buf );
+int segy_write_textheader( segy_file*, unsigned int pos, const char* buf );
 
 /* Read the trace header at `traceno` into `buf`. */
-int segy_traceheader( FILE*,
+int segy_traceheader( segy_file*,
                       unsigned int traceno,
                       char* buf,
                       long trace0,
                       unsigned int trace_bsize );
 
 /* Read the trace header at `traceno` into `buf`. */
-int segy_write_traceheader( FILE*,
+int segy_write_traceheader( segy_file*,
                             unsigned int traceno,
                             const char* buf,
                             long trace0,
@@ -76,7 +83,7 @@ int segy_write_traceheader( FILE*,
  * if the function can figure out how the file is sorted. If not, some error
  * code will be returned and `out` will not be modified.
  */
-int segy_sorting( FILE*,
+int segy_sorting( segy_file*,
                   int il,
                   int xl,
                   int* sorting,
@@ -87,7 +94,7 @@ int segy_sorting( FILE*,
  * Number of offsets in this file, written to `offsets`. 1 if a 3D data set, >1
  * if a 4D data set.
  */
-int segy_offsets( FILE*,
+int segy_offsets( segy_file*,
                   int il,
                   int xl,
                   unsigned int traces,
@@ -100,13 +107,13 @@ int segy_offsets( FILE*,
  * make sense of the read trace it must be converted to native floats, and the
  * buffer sent to write must be converted to target float.
  */
-int segy_readtrace( FILE*,
+int segy_readtrace( segy_file*,
                     unsigned int traceno,
                     float* buf,
                     long trace0,
                     unsigned int trace_bsize );
 
-int segy_writetrace( FILE*,
+int segy_writetrace( segy_file*,
                      unsigned int traceno,
                      const float* buf,
                      long trace0,
@@ -121,7 +128,7 @@ int segy_from_native( int format,
                       int size,
                       float* buf );
 
-int segy_read_line( FILE* fp,
+int segy_read_line( segy_file* fp,
                     unsigned int line_trace0,
                     unsigned int line_length,
                     unsigned int stride,
@@ -129,7 +136,7 @@ int segy_read_line( FILE* fp,
                     long trace0,
                     unsigned int trace_bsize );
 
-int segy_write_line( FILE* fp,
+int segy_write_line( segy_file* fp,
                      unsigned int line_trace0,
                      unsigned int line_length,
                      unsigned int stride,
@@ -149,7 +156,7 @@ int segy_write_line( FILE* fp,
  * `offsets` is the number of offsets in the file and be found with
  * `segy_offsets`.
  */
-int segy_count_lines( FILE*,
+int segy_count_lines( segy_file*,
                       int field,
                       unsigned int offsets,
                       unsigned int* l1out,
@@ -171,7 +178,7 @@ unsigned int segy_crossline_length(unsigned int inline_count);
  * Find the indices of the inlines and write to `buf`. `offsets` are the number
  * of offsets for this file as returned by `segy_offsets`
  */
-int segy_inline_indices( FILE*,
+int segy_inline_indices( segy_file*,
                          int il,
                          int sorting,
                          unsigned int inline_count,
@@ -181,7 +188,7 @@ int segy_inline_indices( FILE*,
                          long trace0,
                          unsigned int trace_bsize );
 
-int segy_crossline_indices( FILE*,
+int segy_crossline_indices( segy_file*,
                             int xl,
                             int sorting,
                             unsigned int inline_count,
diff --git a/src/segyio/util.h b/src/segyio/util.h
index b39e49a..fa122ad 100644
--- a/src/segyio/util.h
+++ b/src/segyio/util.h
@@ -8,10 +8,13 @@
  * testing utilities. These functions won't show up in the installed headers.
  */
 
+struct segy_file_handle;
+
 void ebcdic2ascii( const char* ebcdic, char* ascii );
 void ascii2ebcdic( const char* ascii, char* ebcdic );
 void ibm2ieee(void* to, const void* from);
 void ieee2ibm(void* to, const void* from);
-int segy_seek( FILE*, unsigned int, long, unsigned int );
+int segy_seek( struct segy_file_handle*, unsigned int, long, unsigned int );
+long segy_ftell( struct segy_file_handle* );
 
 #endif //SEGYIO_UTILS_H
diff --git a/src/spec/segyspec.c b/src/spec/segyspec.c
index 798a7d7..25c6e43 100644
--- a/src/spec/segyspec.c
+++ b/src/spec/segyspec.c
@@ -15,7 +15,7 @@ int segyCreateSpec(SegySpec* spec, const char* file, unsigned int inline_field,
 
     int errc = 0;
 
-    FILE* fp = fopen( file, "rb" );
+    segy_file* fp = segy_open( file, "rb" );
     if (fp == NULL) {
         fprintf(stderr, "Unable to open file: '%s'\n", file);
         return -1;
@@ -110,7 +110,7 @@ int segyCreateSpec(SegySpec* spec, const char* file, unsigned int inline_field,
         goto CLEANUP;
     }
 
-    fclose(fp);
+    segy_close(fp);
 
     return 0;
 
@@ -123,7 +123,7 @@ int segyCreateSpec(SegySpec* spec, const char* file, unsigned int inline_field,
         free(spec->sample_indexes);
     free(spec->filename);
 
-    fclose(fp);
+    segy_close(fp);
 
     return errc;
 }
diff --git a/tests/test_segy.c b/tests/test_segy.c
index 0eda295..538407f 100644
--- a/tests/test_segy.c
+++ b/tests/test_segy.c
@@ -23,7 +23,7 @@ static void test_interpret_file() {
     const int il = INLINE_3D;
     const int xl = CROSSLINE_3D;
 
-    FILE* fp = fopen( file, "rb" );
+    segy_file* fp = segy_open( file, "rb" );
 
     assertTrue( fp != NULL, "Could not open file." );
     err = segy_binheader( fp, header );
@@ -99,7 +99,7 @@ static void test_interpret_file() {
     line_length = segy_crossline_length( inlines_sz );
     assertTrue( line_length == 5, "Crossline length should be 5." );
 
-    fclose( fp );
+    segy_close( fp );
 }
 
 /* Prestack test for when we have an approperiate prestack file
@@ -212,7 +212,7 @@ static void testReadInLine_4(){
 
     char header[ SEGY_BINARY_HEADER_SIZE ];
 
-    FILE* fp = fopen( file, "rb" );
+    segy_file* fp = segy_open( file, "rb" );
     assertTrue( 0 == segy_binheader( fp, header ), "Could not read header" );
     const long trace0 = segy_trace0( header );
     const unsigned int samples = segy_samples( header );
@@ -270,7 +270,7 @@ static void testReadInLine_4(){
         assertTrue( *ptr >= 4.0f && *ptr <= 5.0f, "Sample value not in range." );
 
     free(data);
-    fclose(fp);
+    segy_close(fp);
 }
 
 static void testReadCrossLine_22(){
@@ -287,7 +287,7 @@ static void testReadCrossLine_22(){
 
     char header[ SEGY_BINARY_HEADER_SIZE ];
 
-    FILE* fp = fopen( file, "rb" );
+    segy_file* fp = segy_open( file, "rb" );
     assertTrue( 0 == segy_binheader( fp, header ), "Could not read header" );
     const long trace0 = segy_trace0( header );
     const unsigned int samples = segy_samples( header );
@@ -347,7 +347,7 @@ static void testReadCrossLine_22(){
     }
 
     free(data);
-    fclose(fp);
+    segy_close(fp);
 }
 
 static void test_modify_trace_header() {
@@ -356,7 +356,7 @@ static void test_modify_trace_header() {
     int err;
     char bheader[ SEGY_BINARY_HEADER_SIZE ];
 
-    FILE* fp = fopen( file, "r+b" );
+    segy_file* fp = segy_open( file, "r+b" );
     err = segy_binheader( fp, bheader );
     assertTrue( err == 0, "Could not read header" );
     const long trace0 = segy_trace0( bheader );
@@ -380,7 +380,7 @@ static void test_modify_trace_header() {
     assertTrue( ilno == 2, "Wrong iline no." );
 
     err = segy_write_traceheader( fp, 0, traceh, trace0, trace_bsize );
-    fflush( fp );
+    segy_flush( fp, false );
 
     err = segy_traceheader( fp, 0, traceh, trace0, trace_bsize );
     assertTrue( err == 0, "Error while reading trace header." );
@@ -399,7 +399,7 @@ static void test_modify_trace_header() {
     err = segy_get_field( traceh, SourceGroupScalar, &scale );
     assertTrue( err == 0, "Error while reading SourceGroupScalar from dirty field." );
 
-    fclose( fp );
+    segy_close( fp );
 }
 
 static const char* expected_textheader =
@@ -446,19 +446,19 @@ static const char* expected_textheader =
 
 static void test_text_header() {
     const char *file = "test-data/text.sgy";
-    FILE* fp = fopen( file, "rb" );
+    segy_file* fp = segy_open( file, "rb" );
 
     char ascii[ SEGY_TEXT_HEADER_SIZE + 1 ] = { 0 };
     int err = segy_read_textheader(fp, ascii);
     assertTrue( err == 0, "Could not read text header" );
     assertTrue( strcmp(expected_textheader, ascii) == 0, "Text headers did not match" );
 
-    fclose( fp );
+    segy_close( fp );
 }
 
 static void test_trace_header_errors() {
     const char *file = "test-data/small.sgy";
-    FILE* fp = fopen( file, "rb" );
+    segy_file* fp = segy_open( file, "rb" );
     int err;
 
     char binheader[ SEGY_BINARY_HEADER_SIZE ];
@@ -488,13 +488,13 @@ static void test_trace_header_errors() {
     err = segy_get_field( header, DayOfYear, &field );
     assertTrue( err == SEGY_OK, "Reading failed at valid byte offset." );
 
-    fclose( fp );
+    segy_close( fp );
 }
 
 static void test_file_error_codes() {
     const char *file = "test-data/small.sgy";
-    FILE* fp = fopen( file, "rb" );
-    fclose( fp );
+    segy_file* fp = segy_open( file, "rb" );
+    segy_close( fp );
 
     int err;
     char binheader[ SEGY_BINARY_HEADER_SIZE ];
@@ -567,16 +567,16 @@ static void test_error_codes_sans_file() {
 }
 
 static void test_file_size_above_4GB(){
-    FILE* fp = tmpfile();
+    segy_file* fp = segy_open( tmpnam( NULL ), "w+b" );
 
     unsigned int trace = 5e6;
     unsigned int trace_bsize = 1e3;
     long trace0 = 0;
     int err = segy_seek( fp, trace, trace0, trace_bsize);
     assertTrue(err==0, "");
-    long pos = ftell(fp);
+    long pos = segy_ftell( fp );
     assertTrue(pos == (long)trace*((long)trace_bsize+SEGY_TRACE_HEADER_SIZE), "seek overflow");
-    fclose(fp);
+    segy_close(fp);
 }
 
 int main() {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/segyio.git



More information about the debian-science-commits mailing list