36#if defined (HAVE_CONFIG_H)
46#if defined (HAVE_ZLIB)
53#if defined (OCTAVE_USE_WINDOWS_API) && ! defined (OCTAVE_HAVE_WINDOWS_UTF8_LOCALE)
60#define STASHED_CHARACTERS 16
61#define BIGBUFSIZE (256 * 1024 + STASHED_CHARACTERS)
66 : m_file(nullptr), m_io_mode(std::ios_base::openmode(0)), m_own_fd(false),
67 m_buffer(nullptr), m_buffer_size(
BIGBUFSIZE), m_own_buffer(true)
70 this->disable_buffer ();
82 this->disable_buffer ();
89 return gzsetparams (m_file, comp_level, comp_strategy);
100 if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
104 char char_mode[6] =
"\0\0\0\0\0";
108#if defined (OCTAVE_USE_WINDOWS_API) && ! defined (OCTAVE_HAVE_WINDOWS_UTF8_LOCALE)
115 if (octave::string::any_non_ascii_chars (name))
116 error (
"zlib: cannot open gzip-compressed file %s with non-ASCII characters in its name",
121 if ((m_file = gzopen (name, char_mode)) ==
nullptr)
125 this->enable_buffer ();
139 if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
143 char char_mode[6] =
"\0\0\0\0\0";
148 if ((m_file = gzdopen (fd, char_mode)) ==
nullptr)
152 this->enable_buffer ();
168 if (this->
sync () == -1)
170 if (gzclose (m_file) < 0)
176 this->disable_buffer ();
188 bool testi = mode & std::ios_base::in;
189 bool testo = mode & std::ios_base::out;
190 bool testt = mode & std::ios_base::trunc;
191 bool testa = mode & std::ios_base::app;
198 if (! testi && testo && ! testt && ! testa)
199 strcpy (c_mode,
"w");
200 if (! testi && testo && ! testt && testa)
201 strcpy (c_mode,
"a");
202 if (! testi && testo && testt && ! testa)
203 strcpy (c_mode,
"w");
204 if (testi && ! testo && ! testt && ! testa)
205 strcpy (c_mode,
"r");
216 strcat (c_mode,
"b");
226 if (! this->
is_open () || ! (m_io_mode & std::ios_base::in))
229 if (this->gptr () && (this->gptr () < this->egptr ()))
230 return std::streamsize (this->egptr () - this->gptr ());
244 if (gzseek (m_file, this->gptr () - this->egptr () - 1,
SEEK_CUR) < 0)
245 return traits_type::eof ();
252 int bytes_read = gzread (m_file, m_buffer, m_buffer_size);
257 this->setg (m_buffer, m_buffer, m_buffer);
258 return traits_type::eof ();
262 this->setg (m_buffer, m_buffer, m_buffer + bytes_read);
266 gzfilebuf::int_type ret = traits_type::to_int_type (*(this->gptr ()));
268 return traits_type::eof ();
273 return traits_type::eof ();
283 if (this->gptr () && (this->gptr () < this->egptr ()))
284 return traits_type::to_int_type (*(this->gptr ()));
287 if (! this->
is_open () || ! (m_io_mode & std::ios_base::in))
288 return traits_type::eof ();
294 char_type *ptr1 = m_buffer;
296 if (ptr2 > this->eback ())
303 int bytes_read = gzread (m_file, m_buffer + stash, m_buffer_size - stash);
309 this->setg (m_buffer, m_buffer, m_buffer);
310 return traits_type::eof ();
313 this->setg (m_buffer, m_buffer + stash, m_buffer + bytes_read + stash);
316 return traits_type::to_int_type (*(this->gptr ()));
327 if (this->pptr () > this->epptr () || this->pptr () < this->pbase ())
328 return traits_type::eof ();
330 if (! traits_type::eq_int_type (c, traits_type::eof ()))
332 *(this->pptr ()) = traits_type::to_char_type (c);
336 int bytes_to_write = this->pptr () - this->pbase ();
338 if (bytes_to_write > 0)
341 if (! this->
is_open () || ! (m_io_mode & std::ios_base::out))
342 return traits_type::eof ();
344 if (gzwrite (m_file, this->pbase (), bytes_to_write)
346 return traits_type::eof ();
348 this->pbump (-bytes_to_write);
352 else if (! traits_type::eq_int_type (c, traits_type::eof ()))
355 if (! this->
is_open () || ! (m_io_mode & std::ios_base::out))
356 return traits_type::eof ();
358 char_type last_char = traits_type::to_char_type (c);
360 if (gzwrite (m_file, &last_char, 1) != 1)
361 return traits_type::eof ();
366 if (traits_type::eq_int_type (c, traits_type::eof ()))
367 return traits_type::not_eof (c);
377 if (this->
sync () == -1)
387 this->disable_buffer ();
391 this->enable_buffer ();
396 this->disable_buffer ();
399 m_own_buffer =
false;
400 this->enable_buffer ();
409 return traits_type::eq_int_type (this->
overflow (),
410 traits_type::eof ()) ? -1 : 0;
417gzfilebuf::enable_buffer ()
420 if (m_own_buffer && ! m_buffer)
423 if (m_buffer_size > 0)
426 m_buffer =
new char_type [m_buffer_size];
428 this->setg (m_buffer, m_buffer, m_buffer);
434 this->setp (m_buffer, m_buffer + m_buffer_size - 1);
440 m_buffer =
new char_type [m_buffer_size];
441 this->setg (m_buffer, m_buffer, m_buffer);
443 this->setp (
nullptr,
nullptr);
450 this->setg (m_buffer, m_buffer, m_buffer);
451 this->setp (m_buffer, m_buffer + m_buffer_size - 1);
457gzfilebuf::disable_buffer ()
460 if (m_own_buffer && m_buffer)
463 if (! this->pbase ())
467 this->setg (
nullptr,
nullptr,
nullptr);
468 this->setp (
nullptr,
nullptr);
473 this->setg (m_buffer, m_buffer, m_buffer);
475 this->setp (m_buffer, m_buffer + m_buffer_size - 1);
477 this->setp (
nullptr,
nullptr);
486 std::ios_base::openmode)
488 pos_type ret = pos_type (off_type (-1));
492 off_type computed_off = off;
494 if ((m_io_mode & std::ios_base::in) && way == std::ios_base::cur)
495 computed_off += this->gptr () - this->egptr ();
499 if (off == 0 && way == std::ios_base::cur)
500 return pos_type (gztell (m_file) + computed_off);
502 if (way == std::ios_base::beg)
503 ret = pos_type (gzseek (m_file, computed_off,
SEEK_SET));
504 else if (way == std::ios_base::cur)
505 ret = pos_type (gzseek (m_file, computed_off,
SEEK_CUR));
508 ret = pos_type (gzseek (m_file, computed_off,
SEEK_END));
510 if (m_io_mode & std::ios_base::in)
524 pos_type ret = pos_type (off_type (-1));
528 ret = pos_type (gzseek (m_file, sp,
SEEK_SET));
530 if (m_io_mode & std::ios_base::in)
543 : std::
istream (nullptr), m_sb ()
544{ this->init (&m_sb); }
548 : std::
istream (nullptr), m_sb ()
551 this->
open (name, mode);
556 : std::
istream (nullptr), m_sb ()
566 if (! m_sb.
open (name, mode | std::ios_base::in))
567 this->setstate (std::ios_base::failbit);
576 if (! m_sb.
attach (fd, mode | std::ios_base::in))
577 this->setstate (std::ios_base::failbit);
587 this->setstate (std::ios_base::failbit);
592 : std::
ostream (nullptr), m_sb ()
593{ this->init (&m_sb); }
597 : std::
ostream (nullptr), m_sb ()
600 this->
open (name, mode);
605 : std::
ostream (nullptr), m_sb ()
615 if (! m_sb.
open (name, mode | std::ios_base::out))
616 this->setstate (std::ios_base::failbit);
625 if (! m_sb.
attach (fd, mode | std::ios_base::out))
626 this->setstate (std::ios_base::failbit);
636 this->setstate (std::ios_base::failbit);
Gzipped file stream buffer class.
gzfilebuf * close()
Close gzipped file.
bool is_open() const
Check if file is open.
virtual int_type underflow()
Fill get area from gzipped file.
virtual int_type overflow(int_type c=traits_type::eof())
Write put area to gzipped file.
virtual pos_type seekoff(off_type off, std::ios_base::seekdir way, std::ios_base::openmode mode=std::ios_base::in|std::ios_base::out)
Alters the stream positions.
virtual int_type pbackfail(int_type c=traits_type::eof())
virtual std::streambuf * setbuf(char_type *p, std::streamsize n)
Installs external stream buffer.
gzfilebuf * open(const char *name, std::ios_base::openmode mode)
Open gzipped file.
virtual pos_type seekpos(pos_type sp, std::ios_base::openmode mode=std::ios_base::in|std::ios_base::out)
Alters the stream positions.
bool open_mode(std::ios_base::openmode mode, char *c_mode) const
Convert ios open mode int to mode string used by zlib.
int setcompression(int comp_level, int comp_strategy=Z_DEFAULT_STRATEGY)
Set compression level and strategy on the fly.
virtual int sync()
Flush stream buffer to file.
gzfilebuf * attach(int fd, std::ios_base::openmode mode)
Attach to already open gzipped file.
virtual std::streamsize showmanyc()
Number of characters available in stream buffer.
void close()
Close gzipped file.
void attach(int fd, std::ios_base::openmode mode=std::ios_base::in)
Attach to already open gzipped file.
void open(const char *name, std::ios_base::openmode mode=std::ios_base::in)
Open gzipped file.
void close()
Close gzipped file.
void attach(int fd, std::ios_base::openmode mode=std::ios_base::out)
Attach to already open gzipped file.
void open(const char *name, std::ios_base::openmode mode=std::ios_base::out)
Open gzipped file.
void error(const char *fmt,...)
#define STASHED_CHARACTERS
T::size_type strlen(const typename T::value_type *str)