diff --git a/inst/include/XVector_interface.h b/inst/include/XVector_interface.h index 218a435..5714333 100644 --- a/inst/include/XVector_interface.h +++ b/inst/include/XVector_interface.h @@ -49,6 +49,13 @@ void filexp_putc( int c ); +size_t filexp_fwrite( + SEXP filexp, + const void *data_ptr, + size_t size, + size_t nitems +); + int delete_trailing_LF_or_CRLF( const char *buf, int buf_len diff --git a/inst/include/_XVector_stubs.c b/inst/include/_XVector_stubs.c index a3710ba..13fc491 100644 --- a/inst/include/_XVector_stubs.c +++ b/inst/include/_XVector_stubs.c @@ -66,6 +66,11 @@ DEFINE_NOVALUE_CCALLABLE_STUB(filexp_putc, ( filexp, c) ) +DEFINE_CCALLABLE_STUB(size_t, filexp_fwrite, + (SEXP filexp, const void *data_ptr, size_t size, size_t nitems), + ( filexp, data_ptr, size, nitems) +) + DEFINE_CCALLABLE_STUB(int, delete_trailing_LF_or_CRLF, (const char *buf, int buf_len), ( buf, buf_len) diff --git a/src/R_init_XVector.c b/src/R_init_XVector.c index 36240f4..083935e 100644 --- a/src/R_init_XVector.c +++ b/src/R_init_XVector.c @@ -112,6 +112,7 @@ void R_init_XVector(DllInfo *info) REGISTER_CCALLABLE(_filexp_rewind); REGISTER_CCALLABLE(_filexp_puts); REGISTER_CCALLABLE(_filexp_putc); + REGISTER_CCALLABLE(_filexp_fwrite); REGISTER_CCALLABLE(_delete_trailing_LF_or_CRLF); /* Ocopy_byteblocks.c */ diff --git a/src/XVector.h b/src/XVector.h index 8a98ea6..e1c0798 100644 --- a/src/XVector.h +++ b/src/XVector.h @@ -45,6 +45,13 @@ void _filexp_putc( int c ); +size_t _filexp_fwrite( + SEXP filexp, + const void *data_ptr, + size_t size, + size_t nitems +); + SEXP new_input_filexp(SEXP filepath); SEXP rewind_filexp(SEXP filexp); diff --git a/src/io_utils.c b/src/io_utils.c index 9799ec1..dc43198 100644 --- a/src/io_utils.c +++ b/src/io_utils.c @@ -389,6 +389,31 @@ static void oZFile_putc(const ZFile *zfile, int c) error("write error"); } +static size_t oZFile_fwrite(const ZFile *zfile, const void *data_ptr, + size_t size, size_t nitems) +{ + int ztype; + size_t n = 0; + void *file; + + ztype = zfile->ztype; + file = zfile->file; + switch (ztype) { + case UNCOMPRESSED: + n = fwrite(data_ptr, size, nitems, (FILE *) file); + break; + case GZ_TYPE: + n = gzfwrite(data_ptr, size, nitems, (gzFile) file); + break; + default: + error(INTERNAL_ERR_IN "oZFile_puts(): " + "invalid ztype value %d", ztype); + } + if(n == nitems) return nitems; + error("write error (attempted to write %zu elements, wrote %zu)", + nitems, n); +} + /**************************************************************************** * Initialization/close. */ @@ -540,6 +565,11 @@ void _filexp_putc(SEXP filexp, int c) return; } +size_t _filexp_fwrite(SEXP filexp, const void *data_ptr, size_t size, size_t nitems){ + CHECK_USER_INTERRUPT(2000); + return oZFile_fwrite(R_ExternalPtrAddr(filexp), data_ptr, size, nitems); +} + static SEXP new_filexp(SEXP filepath, const char *mode, const char *compress, int level) {