# HG changeset patch # User jwe # Date 1114807716 0 # Node ID ecbe4aa87e51fa822ae83d98449a6addf700fa85 # Parent d2d11284528e10debaded1f337bcf961cb84edd7 [project @ 2005-04-29 20:48:35 by jwe] diff -r d2d11284528e -r ecbe4aa87e51 src/ChangeLog --- a/src/ChangeLog Fri Apr 29 14:56:46 2005 +0000 +++ b/src/ChangeLog Fri Apr 29 20:48:36 2005 +0000 @@ -1,3 +1,21 @@ +2005-04-29 John W. Eaton + + * c-file-ptr-stream.h (c_file_ptr_stream): New template class, + converted from i_c_file_ptr_stream. + (i_c_file_ptr_stream, o_c_file_ptr_stream, io_c_file_ptr_stream): + Now typedefs. + (i_c_zfile_ptr_stream, o_c_zfile_ptr_stream, io_c_zfile_ptr_stream): + New typedefs. + * c-file-ptr-stream.h, c-file-ptr-stream.cc (c_zfile_ptr_buf): + New class. + + * oct-stdstrm.h (class octave_tstdiostream): New template class, + converted from octave_stdiostream. + (octave_stdiostream): Now a typedef. + [HAVE_ZLIB] (octave_zstdiostream): New a typedef. + * oct-stdstrm.cc: Delete. + * Makefile.in (DIST_SRC): Remove it from the list. + 2005-04-29 David Bateman * Makefile.in: Add matrix_type.cc and spkron.cc to DLD_XSRC diff -r d2d11284528e -r ecbe4aa87e51 src/Makefile.in --- a/src/Makefile.in Fri Apr 29 14:56:46 2005 +0000 +++ b/src/Makefile.in Fri Apr 29 20:48:36 2005 +0000 @@ -168,7 +168,7 @@ ls-mat-ascii.cc ls-mat4.cc ls-mat5.cc ls-oct-ascii.cc \ ls-oct-binary.cc ls-utils.cc main.c mappers.cc matherr.c \ oct-fstrm.cc oct-hist.cc oct-iostrm.cc oct-map.cc \ - oct-obj.cc oct-prcstrm.cc oct-procbuf.cc oct-stdstrm.cc \ + oct-obj.cc oct-prcstrm.cc oct-procbuf.cc \ oct-stream.cc zfstream.cc oct-strstrm.cc oct-lvalue.cc pager.cc \ parse.y pr-output.cc procstream.cc sighandlers.cc \ siglist.c sparse-xdiv.cc sparse-xpow.cc strcasecmp.c \ diff -r d2d11284528e -r ecbe4aa87e51 src/c-file-ptr-stream.cc --- a/src/c-file-ptr-stream.cc Fri Apr 29 14:56:46 2005 +0000 +++ b/src/c-file-ptr-stream.cc Fri Apr 29 20:48:36 2005 +0000 @@ -190,9 +190,158 @@ return retval; } +#ifdef HAVE_ZLIB + +c_zfile_ptr_buf::~c_zfile_ptr_buf (void) +{ + close (); +} + +// XXX FIXME XXX -- I'm sure there is room for improvement here... + +c_zfile_ptr_buf::int_type +c_zfile_ptr_buf::overflow (int_type c) +{ +#if defined (CXX_ISO_COMPLIANT_LIBRARY) + if (f) + return (c != traits_type::eof ()) ? gzputc (f, c) : flush (); + else + return traits_type::not_eof (c); +#else + if (f) + return (c != EOF) ? gzputc (f, c) : flush (); + else + return EOF; +#endif +} + +c_zfile_ptr_buf::int_type +c_zfile_ptr_buf::underflow_common (bool bump) +{ + if (f) + { + int_type c = gzgetc (f); + + if (! bump +#if defined (CXX_ISO_COMPLIANT_LIBRARY) + && c != traits_type::eof ()) +#else + && c != EOF) +#endif + gzungetc (c, f); + + return c; + } + else +#if defined (CXX_ISO_COMPLIANT_LIBRARY) + return traits_type::eof (); +#else + return EOF; +#endif +} + +c_zfile_ptr_buf::int_type +c_zfile_ptr_buf::pbackfail (int_type c) +{ +#if defined (CXX_ISO_COMPLIANT_LIBRARY) + return (c != traits_type::eof () && f) ? gzungetc (c, f) : + traits_type::not_eof (c); +#else + return (c != EOF && f) ? gzungetc (c, f) : EOF; +#endif +} + +std::streamsize +c_zfile_ptr_buf::xsputn (const char* s, std::streamsize n) +{ + if (f) + return gzwrite (f, s, n); + else + return 0; +} + +std::streamsize +c_zfile_ptr_buf::xsgetn (char *s, std::streamsize n) +{ + if (f) + return gzread (f, s, n); + else + return 0; +} + +std::streampos +c_zfile_ptr_buf::seekoff (std::streamoff offset, std::ios::seekdir dir, + std::ios::openmode) +{ + // XXX FIXME XXX +#if 0 + if (f) + { + gzseek (f, offset, seekdir_to_whence (dir)); + + return gztell (f); + } + else + return 0; +#endif + return -1; +} + +std::streampos +c_zfile_ptr_buf::seekpos (std::streampos offset, std::ios::openmode) +{ + // XXX FIXME XXX +#if 0 + if (f) + { + gzseek (f, offset, SEEK_SET); + + return gztell (f); + } + else + return 0; +#endif + return -1; +} + +int +c_zfile_ptr_buf::sync (void) +{ + flush (); + + return 0; +} + +int +c_zfile_ptr_buf::flush (void) +{ + // XXX FIXME XXX -- do we need something more complex here, passing + // something other than 0 for the second argument to gzflush and + // checking the return value, etc.? + + return f ? gzflush (f, 0) : EOF; +} + +int +c_zfile_ptr_buf::close (void) +{ + int retval = -1; + + flush (); + + if (f) + { + retval = cf (f); + f = 0; + } + + return retval; +} + +#endif + /* ;;; Local Variables: *** ;;; mode: C++ *** ;;; End: *** */ - diff -r d2d11284528e -r ecbe4aa87e51 src/c-file-ptr-stream.h --- a/src/c-file-ptr-stream.h Fri Apr 29 14:56:46 2005 +0000 +++ b/src/c-file-ptr-stream.h Fri Apr 29 20:48:36 2005 +0000 @@ -94,18 +94,21 @@ int_type underflow_common (bool); }; +// XXX FIXME XXX -- the following three classes could probably share +// some code... + +template class -i_c_file_ptr_stream : public std::istream +c_file_ptr_stream : public STREAM_T { public: - i_c_file_ptr_stream (FILE* f, - c_file_ptr_buf::close_fcn cf = c_file_ptr_buf::fclose) - : std::istream (0), buf (new c_file_ptr_buf (f, cf)) { init (buf); } + c_file_ptr_stream (FILE_T f, typename BUF_T::close_fcn cf = BUF_T::fclose) + : STREAM_T (0), buf (new BUF_T (f, cf)) { init (buf); } - ~i_c_file_ptr_stream (void) { delete buf; buf = 0; } + ~c_file_ptr_stream (void) { delete buf; buf = 0; } - c_file_ptr_buf *rdbuf (void) { return buf; } + BUF_T *rdbuf (void) { return buf; } void close (void) { if (buf) buf->close (); } @@ -114,66 +117,95 @@ long tell (void) { return buf ? buf->tell () : -1; } - void clear (void) { if (buf) buf->clear (); std::istream::clear (); } + void clear (void) { if (buf) buf->clear (); STREAM_T::clear (); } private: - c_file_ptr_buf *buf; + BUF_T *buf; }; +typedef c_file_ptr_stream i_c_file_ptr_stream; +typedef c_file_ptr_stream o_c_file_ptr_stream; +typedef c_file_ptr_stream io_c_file_ptr_stream; + +#ifdef HAVE_ZLIB + +#ifdef HAVE_ZLIB_H +#include +#endif + class -o_c_file_ptr_stream : public std::ostream +c_zfile_ptr_buf : public std::streambuf { public: - o_c_file_ptr_stream (FILE* f, - c_file_ptr_buf::close_fcn cf = c_file_ptr_buf::fclose) - : std::ostream (0), buf (new c_file_ptr_buf (f, cf)) { init (buf); } +#if !defined (CXX_ISO_COMPLIANT_LIBRARY) + typedef int int_type; +#else + typedef std::streambuf::int_type int_type; +#endif + + typedef int (*close_fcn) (gzFile); + + gzFile stdiofile (void) { return f; } + + c_zfile_ptr_buf (gzFile f_arg, close_fcn cf_arg = fclose) + : std::streambuf (), f (f_arg), cf (cf_arg) + { } + + ~c_zfile_ptr_buf (void); + + int_type overflow (int_type); + + int_type underflow (void) { return underflow_common (false); } - ~o_c_file_ptr_stream (void) { delete buf; buf = 0; } + int_type uflow (void) { return underflow_common (true); } + + int_type pbackfail (int_type); + + std::streamsize xsputn (const char*, std::streamsize); + + std::streamsize xsgetn (char *, std::streamsize); - c_file_ptr_buf *rdbuf (void) { return buf; } + std::streampos seekoff (std::streamoff, std::ios::seekdir, + std::ios::openmode = std::ios::in | std::ios::out); + + std::streampos seekpos (std::streampos, + std::ios::openmode = std::ios::in | std::ios::out); - void close (void) { if (buf) buf->close (); } + int sync (void); + + int flush (void); + + int close (void); + + int file_number () const { return -1; } int seek (long offset, int origin) - { return buf ? buf->seek (offset, origin) : -1; } + { return f ? gzseek (f, offset, origin) : -1; } + + long tell (void) { return f ? gztell (f) : -1; } + + void clear (void) { if (f) gzclearerr (f); } - long tell (void) { return buf ? buf->tell () : -1; } + static int fclose (gzFile f) { return ::gzclose (f); } + +protected: - void clear (void) { if (buf) buf->clear (); std::ostream::clear (); } + gzFile f; + + close_fcn cf; private: - c_file_ptr_buf *buf; + int_type underflow_common (bool); }; -class -io_c_file_ptr_stream : public std::iostream -{ -public: - - io_c_file_ptr_stream (FILE* f, - c_file_ptr_buf::close_fcn cf = c_file_ptr_buf::fclose) - : std::iostream (0), buf (new c_file_ptr_buf (f, cf)) { init (buf); } - - ~io_c_file_ptr_stream (void) { delete buf; buf = 0; } - - c_file_ptr_buf *rdbuf (void) { return buf; } +typedef c_file_ptr_stream i_c_zfile_ptr_stream; +typedef c_file_ptr_stream o_c_zfile_ptr_stream; +typedef c_file_ptr_stream io_c_zfile_ptr_stream; - void close (void) { if (buf) buf->close (); } - - int seek (long offset, int origin) - { return buf ? buf->seek (offset, origin) : -1; } - - long tell (void) { return buf ? buf->tell () : -1; } - - void clear (void) { if (buf) buf->clear (); std::iostream::clear (); } - -private: - - c_file_ptr_buf *buf; -}; +#endif #endif diff -r d2d11284528e -r ecbe4aa87e51 src/file-io.cc --- a/src/file-io.cc Fri Apr 29 14:56:46 2005 +0000 +++ b/src/file-io.cc Fri Apr 29 20:48:36 2005 +0000 @@ -53,6 +53,10 @@ #include #endif +#ifdef HAVE_ZLIB_H +#include +#endif + #include "error.h" #include "file-ops.h" #include "lo-ieee.h" @@ -126,42 +130,58 @@ } static std::ios::openmode -fopen_mode_to_ios_mode (const std::string& mode) +fopen_mode_to_ios_mode (const std::string& mode_arg) { std::ios::openmode retval = std::ios::in; - if (! mode.empty ()) + if (! mode_arg.empty ()) { // Could probably be faster, but does it really matter? - if (mode == "rt") - retval = std::ios::in; - else if (mode == "wt") - retval = std::ios::out | std::ios::trunc; - else if (mode == "at") - retval = std::ios::out | std::ios::app; - else if (mode == "r+t") - retval = std::ios::in | std::ios::out; - else if (mode == "w+t") - retval = std::ios::in | std::ios::out | std::ios::trunc; - else if (mode == "a+t") - retval = std::ios::in | std::ios::out | std::ios::ate; - else if (mode == "rb" || mode == "r") - retval = std::ios::in | std::ios::binary; - else if (mode == "wb" || mode == "w") - retval = std::ios::out | std::ios::trunc | std::ios::binary; - else if (mode == "ab" || mode == "a") - retval = std::ios::out | std::ios::app | std::ios::binary; - else if (mode == "r+b" || mode == "r+") - retval = std::ios::in | std::ios::out | std::ios::binary; - else if (mode == "w+b" || mode == "w+") - retval = (std::ios::in | std::ios::out | std::ios::trunc - | std::ios::binary); - else if (mode == "a+b" || mode == "a+") - retval = (std::ios::in | std::ios::out | std::ios::ate - | std::ios::binary); - else - ::error ("invalid mode specified"); + std::string mode = mode_arg; + + size_t pos = mode.find ('z'); + + if (pos != NPOS) + { +#if defined (HAVE_ZLIB) + mode.erase (pos, 1); +#else + error ("this version of Octave does not support gzipped files"); +#endif + } + + if (! error_state) + { + if (mode == "rt") + retval = std::ios::in; + else if (mode == "wt") + retval = std::ios::out | std::ios::trunc; + else if (mode == "at") + retval = std::ios::out | std::ios::app; + else if (mode == "r+t") + retval = std::ios::in | std::ios::out; + else if (mode == "w+t") + retval = std::ios::in | std::ios::out | std::ios::trunc; + else if (mode == "a+t") + retval = std::ios::in | std::ios::out | std::ios::ate; + else if (mode == "rb" || mode == "r") + retval = std::ios::in | std::ios::binary; + else if (mode == "wb" || mode == "w") + retval = std::ios::out | std::ios::trunc | std::ios::binary; + else if (mode == "ab" || mode == "a") + retval = std::ios::out | std::ios::app | std::ios::binary; + else if (mode == "r+b" || mode == "r+") + retval = std::ios::in | std::ios::out | std::ios::binary; + else if (mode == "w+b" || mode == "w+") + retval = (std::ios::in | std::ios::out | std::ios::trunc + | std::ios::binary); + else if (mode == "a+b" || mode == "a+") + retval = (std::ios::in | std::ios::out | std::ios::ate + | std::ios::binary); + else + ::error ("invalid mode specified"); + } } return retval; @@ -386,15 +406,39 @@ if (! error_state) { - FILE *fptr = ::fopen (name.c_str (), mode.c_str ()); +#if defined (HAVE_ZLIB) + std::string tmode = mode; + + size_t pos = tmode.find ('z'); - retval = octave_stdiostream::create (name, fptr, md, flt_fmt); + if (pos != NPOS) + { + tmode.erase (pos, 1); + + gzFile fptr = ::gzopen (name.c_str (), tmode.c_str ()); - if (! fptr) + if (fptr) + retval = octave_zstdiostream::create (name, fptr, md, flt_fmt); + else + { + using namespace std; + retval.error (::strerror (errno)); + } + } + else +#endif { - using namespace std; - retval.error (::strerror (errno)); + FILE *fptr = ::fopen (name.c_str (), mode.c_str ()); + + if (fptr) + retval = octave_stdiostream::create (name, fptr, md, flt_fmt); + else + { + using namespace std; + retval.error (::strerror (errno)); + } } + } } @@ -502,6 +546,10 @@ on Windows, carriage-returnn on Macintosh). The default if no mode is\n\ specified is binary mode.\n\ \n\ +Additionally, you may append a \"z\" to the mode string to open a\n\ +gzipped file for reading or writing. For this to be successful, you\n\ +must also open the file in binary mode.\n\ +\n\ The parameter @var{arch} is a string specifying the default data format\n\ for the file. Valid values for @var{arch} are:\n\ \n\ diff -r d2d11284528e -r ecbe4aa87e51 src/oct-stdstrm.cc --- a/src/oct-stdstrm.cc Fri Apr 29 14:56:46 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - -Copyright (C) 1996, 1997 John W. Eaton - -This file is part of Octave. - -Octave is free software; you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by the -Free Software Foundation; either version 2, or (at your option) any -later version. - -Octave is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Octave; see the file COPYING. If not, write to the Free -Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. - -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include "oct-stdstrm.h" - -// Position a stream at OFFSET relative to ORIGIN. - -int -octave_stdiostream::seek (long offset, int origin) -{ - int retval = -1; - - if (s) - retval = s->seek (offset, origin); - - return retval; -} - -// Return current stream position. - -long -octave_stdiostream::tell (void) -{ - long retval = -1; - - if (s) - retval = s->tell (); - - return retval; -} - -/* -;;; Local Variables: *** -;;; mode: C++ *** -;;; End: *** -*/ diff -r d2d11284528e -r ecbe4aa87e51 src/oct-stdstrm.h --- a/src/oct-stdstrm.h Fri Apr 29 14:56:46 2005 +0000 +++ b/src/oct-stdstrm.h Fri Apr 29 20:48:36 2005 +0000 @@ -27,39 +27,39 @@ #include "oct-stream.h" #include "c-file-ptr-stream.h" +template class -octave_stdiostream : public octave_base_stream +octave_tstdiostream : public octave_base_stream { public: - octave_stdiostream (const std::string& n, FILE *f = 0, - std::ios::openmode m = std::ios::in|std::ios::out, - oct_mach_info::float_format ff - = oct_mach_info::native_float_format (), - c_file_ptr_buf::close_fcn cf = c_file_ptr_buf::fclose) - : octave_base_stream (m, ff), nm (n), md (m), s(0) - { - if (f) - s = new io_c_file_ptr_stream (f, cf); - } + octave_tstdiostream (const std::string& n, FILE_T f = 0, + std::ios::openmode m = std::ios::in|std::ios::out, + oct_mach_info::float_format ff + = oct_mach_info::native_float_format (), + typename BUF_T::close_fcn cf = BUF_T::fclose) + : octave_base_stream (m, ff), nm (n), md (m), + s(f ? new STREAM_T (f, cf) : 0) + { } static octave_stream - create (const std::string& n, FILE *f = 0, + create (const std::string& n, FILE_T f = 0, std::ios::openmode m = std::ios::in|std::ios::out, oct_mach_info::float_format ff = oct_mach_info::native_float_format (), - c_file_ptr_buf::close_fcn cf = c_file_ptr_buf::fclose) + typename BUF_T::close_fcn cf = BUF_T::fclose) { - return octave_stream (new octave_stdiostream (n, f, m, ff, cf)); + return octave_stream (new octave_tstdiostream (n, f, m, ff, cf)); } // Position a stream at OFFSET relative to ORIGIN. - int seek (long offset, int origin); + int seek (long offset, int origin) + { return s ? s->seek (offset, origin) : -1; } // Return current stream position. - long tell (void); + long tell (void) { return s ? s->tell () : -1; } // Return non-zero if EOF has been reached on this stream. @@ -74,8 +74,8 @@ std::ostream *output_stream (void) { return (md & std::ios::out) ? s : 0; } // XXX FIXME XXX -- should not have to cast away const here. - c_file_ptr_buf *rdbuf (void) const - { return s ? (const_cast (s))->rdbuf () : 0; } + BUF_T *rdbuf (void) const + { return s ? (const_cast (s))->rdbuf () : 0; } bool bad (void) const { return s ? s->bad () : true; } @@ -89,18 +89,26 @@ std::ios::openmode md; - io_c_file_ptr_stream *s; + STREAM_T *s; - ~octave_stdiostream (void) { delete s; } + ~octave_tstdiostream (void) { delete s; } private: // No copying! - octave_stdiostream (const octave_stdiostream&); + octave_tstdiostream (const octave_tstdiostream&); + + octave_tstdiostream& operator = (const octave_tstdiostream&); +}; - octave_stdiostream& operator = (const octave_stdiostream&); -}; +typedef octave_tstdiostream octave_stdiostream; + +#ifdef HAVE_ZLIB + +typedef octave_tstdiostream octave_zstdiostream; + +#endif #endif