19e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/*
29e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * A C++ I/O streams interface to the zlib gz* functions
39e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *
49e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * by Ludwig Schwardt <schwardt@sun.ac.za>
59e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * original version by Kevin Ruland <kevin@rodin.wustl.edu>
69e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project *
79e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project * This version is standard-compliant and compatible with gcc 3.x.
89e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project */
99e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include "zfstream.h"
119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <cstring>          // for strcpy, strcat, strlen (mode strings)
129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#include <cstdio>           // for BUFSIZ
139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Internal buffer sizes (default and "unbuffered" versions)
159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define BIGBUFSIZE BUFSIZ
169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project#define SMALLBUFSIZE 1
179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/*****************************************************************************/
199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Default constructor
219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf::gzfilebuf()
229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project: file(NULL), io_mode(std::ios_base::openmode(0)), own_fd(false),
239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  buffer(NULL), buffer_size(BIGBUFSIZE), own_buffer(true)
249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // No buffers to start with
269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  this->disable_buffer();
279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Destructor
309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf::~gzfilebuf()
319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Sync output buffer and close only if responsible for file
339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // (i.e. attached streams should be left open at this stage)
349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  this->sync();
359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (own_fd)
369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->close();
379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Make sure internal buffer is deallocated
389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  this->disable_buffer();
399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Set compression level and strategy
429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint
439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf::setcompression(int comp_level,
449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                          int comp_strategy)
459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  return gzsetparams(file, comp_level, comp_strategy);
479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Open gzipped file
509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf*
519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf::open(const char *name,
529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                std::ios_base::openmode mode)
539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Fail if file already open
559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (this->is_open())
569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return NULL;
579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Don't support simultaneous read/write access (yet)
589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return NULL;
609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Build mode string for gzopen and check it [27.8.1.3.2]
629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char char_mode[6] = "\0\0\0\0\0";
639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (!this->open_mode(mode, char_mode))
649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return NULL;
659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Attempt to open file
679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if ((file = gzopen(name, char_mode)) == NULL)
689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return NULL;
699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // On success, allocate internal buffer and set flags
719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  this->enable_buffer();
729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  io_mode = mode;
739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  own_fd = true;
749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  return this;
759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Attach to gzipped file
789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf*
799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf::attach(int fd,
809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  std::ios_base::openmode mode)
819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Fail if file already open
839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (this->is_open())
849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return NULL;
859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Don't support simultaneous read/write access (yet)
869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return NULL;
889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Build mode string for gzdopen and check it [27.8.1.3.2]
909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  char char_mode[6] = "\0\0\0\0\0";
919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (!this->open_mode(mode, char_mode))
929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return NULL;
939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Attempt to attach to file
959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if ((file = gzdopen(fd, char_mode)) == NULL)
969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return NULL;
979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // On success, allocate internal buffer and set flags
999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  this->enable_buffer();
1009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  io_mode = mode;
1019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  own_fd = false;
1029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  return this;
1039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
1049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Close gzipped file
1069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf*
1079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf::close()
1089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Fail immediately if no file is open
1109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (!this->is_open())
1119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return NULL;
1129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Assume success
1139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  gzfilebuf* retval = this;
1149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Attempt to sync and close gzipped file
1159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (this->sync() == -1)
1169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    retval = NULL;
1179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (gzclose(file) < 0)
1189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    retval = NULL;
1199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // File is now gone anyway (postcondition [27.8.1.3.8])
1209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  file = NULL;
1219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  own_fd = false;
1229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Destroy internal buffer if it exists
1239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  this->disable_buffer();
1249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  return retval;
1259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
1269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Convert int open mode to mode string
1309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectbool
1319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf::open_mode(std::ios_base::openmode mode,
1329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                     char* c_mode) const
1339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  bool testb = mode & std::ios_base::binary;
1359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  bool testi = mode & std::ios_base::in;
1369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  bool testo = mode & std::ios_base::out;
1379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  bool testt = mode & std::ios_base::trunc;
1389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  bool testa = mode & std::ios_base::app;
1399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Check for valid flag combinations - see [27.8.1.3.2] (Table 92)
1419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Original zfstream hardcoded the compression level to maximum here...
1429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Double the time for less than 1% size improvement seems
1439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // excessive though - keeping it at the default level
1449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // To change back, just append "9" to the next three mode strings
1459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (!testi && testo && !testt && !testa)
1469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    strcpy(c_mode, "w");
1479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (!testi && testo && !testt && testa)
1489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    strcpy(c_mode, "a");
1499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (!testi && testo && testt && !testa)
1509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    strcpy(c_mode, "w");
1519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (testi && !testo && !testt && !testa)
1529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    strcpy(c_mode, "r");
1539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // No read/write mode yet
1549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project//  if (testi && testo && !testt && !testa)
1559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project//    strcpy(c_mode, "r+");
1569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project//  if (testi && testo && testt && !testa)
1579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project//    strcpy(c_mode, "w+");
1589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Mode string should be empty for invalid combination of flags
1609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (strlen(c_mode) == 0)
1619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return false;
1629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (testb)
1639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    strcat(c_mode, "b");
1649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  return true;
1659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
1669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Determine number of characters in internal get buffer
1689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectstd::streamsize
1699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf::showmanyc()
1709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Calls to underflow will fail if file not opened for reading
1729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (!this->is_open() || !(io_mode & std::ios_base::in))
1739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return -1;
1749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Make sure get area is in use
1759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (this->gptr() && (this->gptr() < this->egptr()))
1769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return std::streamsize(this->egptr() - this->gptr());
1779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  else
1789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return 0;
1799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
1809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Fill get area from gzipped file
1829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf::int_type
1839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf::underflow()
1849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
1859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // If something is left in the get area by chance, return it
1869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // (this shouldn't normally happen, as underflow is only supposed
1879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // to be called when gptr >= egptr, but it serves as error check)
1889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (this->gptr() && (this->gptr() < this->egptr()))
1899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return traits_type::to_int_type(*(this->gptr()));
1909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // If the file hasn't been opened for reading, produce error
1929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (!this->is_open() || !(io_mode & std::ios_base::in))
1939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return traits_type::eof();
1949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Attempt to fill internal buffer from gzipped file
1969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // (buffer must be guaranteed to exist...)
1979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  int bytes_read = gzread(file, buffer, buffer_size);
1989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Indicates error or EOF
1999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (bytes_read <= 0)
2009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  {
2019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    // Reset get area
2029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->setg(buffer, buffer, buffer);
2039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return traits_type::eof();
2049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  }
2059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Make all bytes read from file available as get area
2069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  this->setg(buffer, buffer, buffer + bytes_read);
2079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Return next character in get area
2099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  return traits_type::to_int_type(*(this->gptr()));
2109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
2119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Write put area to gzipped file
2139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf::int_type
2149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf::overflow(int_type c)
2159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
2169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Determine whether put area is in use
2179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (this->pbase())
2189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  {
2199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    // Double-check pointer range
2209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (this->pptr() > this->epptr() || this->pptr() < this->pbase())
2219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      return traits_type::eof();
2229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    // Add extra character to buffer if not EOF
2239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (!traits_type::eq_int_type(c, traits_type::eof()))
2249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
2259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      *(this->pptr()) = traits_type::to_char_type(c);
2269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      this->pbump(1);
2279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
2289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    // Number of characters to write to file
2299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    int bytes_to_write = this->pptr() - this->pbase();
2309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    // Overflow doesn't fail if nothing is to be written
2319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (bytes_to_write > 0)
2329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
2339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      // If the file hasn't been opened for writing, produce error
2349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      if (!this->is_open() || !(io_mode & std::ios_base::out))
2359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return traits_type::eof();
2369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      // If gzipped file won't accept all bytes written to it, fail
2379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      if (gzwrite(file, this->pbase(), bytes_to_write) != bytes_to_write)
2389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        return traits_type::eof();
2399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      // Reset next pointer to point to pbase on success
2409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      this->pbump(-bytes_to_write);
2419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
2429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  }
2439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // Write extra character to file if not EOF
2449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  else if (!traits_type::eq_int_type(c, traits_type::eof()))
2459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  {
2469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    // If the file hasn't been opened for writing, produce error
2479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (!this->is_open() || !(io_mode & std::ios_base::out))
2489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      return traits_type::eof();
2499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    // Impromptu char buffer (allows "unbuffered" output)
2509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    char_type last_char = traits_type::to_char_type(c);
2519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    // If gzipped file won't accept this character, fail
2529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (gzwrite(file, &last_char, 1) != 1)
2539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      return traits_type::eof();
2549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  }
2559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // If you got here, you have succeeded (even if c was EOF)
2579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // The return value should therefore be non-EOF
2589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (traits_type::eq_int_type(c, traits_type::eof()))
2599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return traits_type::not_eof(c);
2609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  else
2619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return c;
2629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
2639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Assign new buffer
2659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectstd::streambuf*
2669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf::setbuf(char_type* p,
2679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                  std::streamsize n)
2689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
2699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // First make sure stuff is sync'ed, for safety
2709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (this->sync() == -1)
2719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    return NULL;
2729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // If buffering is turned off on purpose via setbuf(0,0), still allocate one...
2739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // "Unbuffered" only really refers to put [27.8.1.4.10], while get needs at
2749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // least a buffer of size 1 (very inefficient though, therefore make it bigger?)
2759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // This follows from [27.5.2.4.3]/12 (gptr needs to point at something, it seems)
2769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (!p || !n)
2779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  {
2789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    // Replace existing buffer (if any) with small internal buffer
2799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->disable_buffer();
2809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    buffer = NULL;
2819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    buffer_size = 0;
2829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    own_buffer = true;
2839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->enable_buffer();
2849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  }
2859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  else
2869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  {
2879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    // Replace existing buffer (if any) with external buffer
2889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->disable_buffer();
2899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    buffer = p;
2909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    buffer_size = n;
2919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    own_buffer = false;
2929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->enable_buffer();
2939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  }
2949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  return this;
2959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
2969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Write put area to gzipped file (i.e. ensures that put area is empty)
2989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectint
2999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf::sync()
3009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  return traits_type::eq_int_type(this->overflow(), traits_type::eof()) ? -1 : 0;
3029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
3059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Allocate internal buffer
3079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid
3089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf::enable_buffer()
3099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // If internal buffer required, allocate one
3119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (own_buffer && !buffer)
3129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  {
3139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    // Check for buffered vs. "unbuffered"
3149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (buffer_size > 0)
3159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
3169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      // Allocate internal buffer
3179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      buffer = new char_type[buffer_size];
3189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      // Get area starts empty and will be expanded by underflow as need arises
3199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      this->setg(buffer, buffer, buffer);
3209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      // Setup entire internal buffer as put area.
3219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      // The one-past-end pointer actually points to the last element of the buffer,
3229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      // so that overflow(c) can safely add the extra character c to the sequence.
3239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      // These pointers remain in place for the duration of the buffer
3249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      this->setp(buffer, buffer + buffer_size - 1);
3259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
3269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    else
3279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
3289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      // Even in "unbuffered" case, (small?) get buffer is still required
3299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      buffer_size = SMALLBUFSIZE;
3309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      buffer = new char_type[buffer_size];
3319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      this->setg(buffer, buffer, buffer);
3329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      // "Unbuffered" means no put buffer
3339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      this->setp(0, 0);
3349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
3359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  }
3369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  else
3379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  {
3389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    // If buffer already allocated, reset buffer pointers just to make sure no
3399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    // stale chars are lying around
3409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->setg(buffer, buffer, buffer);
3419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->setp(buffer, buffer + buffer_size - 1);
3429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  }
3439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Destroy internal buffer
3469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid
3479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzfilebuf::disable_buffer()
3489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  // If internal buffer exists, deallocate it
3509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (own_buffer && buffer)
3519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  {
3529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    // Preserve unbuffered status by zeroing size
3539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (!this->pbase())
3549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      buffer_size = 0;
3559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    delete[] buffer;
3569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    buffer = NULL;
3579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->setg(0, 0, 0);
3589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->setp(0, 0);
3599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  }
3609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  else
3619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  {
3629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    // Reset buffer pointers to initial state if external buffer exists
3639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->setg(buffer, buffer, buffer);
3649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    if (buffer)
3659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      this->setp(buffer, buffer + buffer_size - 1);
3669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    else
3679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project      this->setp(0, 0);
3689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  }
3699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/*****************************************************************************/
3729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Default constructor initializes stream buffer
3749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzifstream::gzifstream()
3759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project: std::istream(NULL), sb()
3769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ this->init(&sb); }
3779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Initialize stream buffer and open file
3799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzifstream::gzifstream(const char* name,
3809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                       std::ios_base::openmode mode)
3819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project: std::istream(NULL), sb()
3829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  this->init(&sb);
3849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  this->open(name, mode);
3859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Initialize stream buffer and attach to file
3889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzifstream::gzifstream(int fd,
3899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                       std::ios_base::openmode mode)
3909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project: std::istream(NULL), sb()
3919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
3929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  this->init(&sb);
3939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  this->attach(fd, mode);
3949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
3959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
3969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Open file and go into fail() state if unsuccessful
3979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid
3989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzifstream::open(const char* name,
3999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                 std::ios_base::openmode mode)
4009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
4019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (!sb.open(name, mode | std::ios_base::in))
4029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->setstate(std::ios_base::failbit);
4039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  else
4049e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->clear();
4059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
4069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Attach to file and go into fail() state if unsuccessful
4089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid
4099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzifstream::attach(int fd,
4109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                   std::ios_base::openmode mode)
4119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
4129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (!sb.attach(fd, mode | std::ios_base::in))
4139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->setstate(std::ios_base::failbit);
4149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  else
4159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->clear();
4169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
4179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Close file
4199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid
4209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzifstream::close()
4219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
4229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (!sb.close())
4239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->setstate(std::ios_base::failbit);
4249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
4259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project/*****************************************************************************/
4279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Default constructor initializes stream buffer
4299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzofstream::gzofstream()
4309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project: std::ostream(NULL), sb()
4319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{ this->init(&sb); }
4329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Initialize stream buffer and open file
4349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzofstream::gzofstream(const char* name,
4359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                       std::ios_base::openmode mode)
4369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project: std::ostream(NULL), sb()
4379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
4389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  this->init(&sb);
4399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  this->open(name, mode);
4409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
4419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Initialize stream buffer and attach to file
4439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzofstream::gzofstream(int fd,
4449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                       std::ios_base::openmode mode)
4459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project: std::ostream(NULL), sb()
4469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
4479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  this->init(&sb);
4489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  this->attach(fd, mode);
4499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
4509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Open file and go into fail() state if unsuccessful
4529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid
4539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzofstream::open(const char* name,
4549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                 std::ios_base::openmode mode)
4559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
4569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (!sb.open(name, mode | std::ios_base::out))
4579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->setstate(std::ios_base::failbit);
4589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  else
4599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->clear();
4609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
4619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Attach to file and go into fail() state if unsuccessful
4639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid
4649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzofstream::attach(int fd,
4659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                   std::ios_base::openmode mode)
4669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
4679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (!sb.attach(fd, mode | std::ios_base::out))
4689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->setstate(std::ios_base::failbit);
4699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  else
4709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->clear();
4719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
4729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
4739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// Close file
4749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectvoid
4759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectgzofstream::close()
4769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
4779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project  if (!sb.close())
4789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    this->setstate(std::ios_base::failbit);
4799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}
480