[llvm-commits] [parallel] CVS: llvm/runtime/zlib/contrib/iostream3/README TODO test.cc zfstream.cc zfstream.h

Misha Brukman brukman at cs.uiuc.edu
Mon Mar 1 18:14:03 PST 2004


Changes in directory llvm/runtime/zlib/contrib/iostream3:

README added (r1.1.2.1)
TODO added (r1.1.2.1)
test.cc added (r1.1.2.1)
zfstream.cc added (r1.1.2.1)
zfstream.h added (r1.1.2.1)

---
Log message:

Merge from trunk

---
Diffs of the changes:  (+1047 -0)

Index: llvm/runtime/zlib/contrib/iostream3/README
diff -c /dev/null llvm/runtime/zlib/contrib/iostream3/README:1.1.2.1
*** /dev/null	Mon Mar  1 17:58:58 2004
--- llvm/runtime/zlib/contrib/iostream3/README	Mon Mar  1 17:58:48 2004
***************
*** 0 ****
--- 1,35 ----
+ These classes provide a C++ stream interface to the zlib library. It allows you
+ to do things like:
+ 
+   gzofstream outf("blah.gz");
+   outf << "These go into the gzip file " << 123 << endl;
+ 
+ It does this by deriving a specialized stream buffer for gzipped files, which is
+ the way Stroustrup would have done it. :->
+ 
+ The gzifstream and gzofstream classes were originally written by Kevin Ruland
+ and made available in the zlib contrib/iostream directory. The older version still
+ compiles under gcc 2.xx, but not under gcc 3.xx, which sparked the development of
+ this version.
+ 
+ The new classes are as standard-compliant as possible, closely following the
+ approach of the standard library's fstream classes. It compiles under gcc versions
+ 3.2 and 3.3, but not under gcc 2.xx. This is mainly due to changes in the standard
+ library naming scheme. The new version of gzifstream/gzofstream/gzfilebuf differs
+ from the previous one in the following respects:
+ - added showmanyc
+ - added setbuf, with support for unbuffered output via setbuf(0,0)
+ - a few bug fixes of stream behavior
+ - gzipped output file opened with default compression level instead of maximum level
+ - setcompressionlevel()/strategy() members replaced by single setcompression()
+ 
+ The code is provided "as is", with the permission to use, copy, modify, distribute
+ and sell it for any purpose without fee.
+ 
+ Ludwig Schwardt
+ <schwardt at sun.ac.za>
+ 
+ DSP Lab
+ Electrical & Electronic Engineering Department
+ University of Stellenbosch
+ South Africa


Index: llvm/runtime/zlib/contrib/iostream3/TODO
diff -c /dev/null llvm/runtime/zlib/contrib/iostream3/TODO:1.1.2.1
*** /dev/null	Mon Mar  1 17:58:58 2004
--- llvm/runtime/zlib/contrib/iostream3/TODO	Mon Mar  1 17:58:48 2004
***************
*** 0 ****
--- 1,17 ----
+ Possible upgrades to gzfilebuf:
+ 
+ - The ability to do putback (e.g. putbackfail)
+ 
+ - The ability to seek (zlib supports this, but could be slow/tricky)
+ 
+ - Simultaneous read/write access (does it make sense?)
+ 
+ - Support for ios_base::ate open mode
+ 
+ - Locale support?
+ 
+ - Check public interface to see which calls give problems
+   (due to dependence on library internals)
+ 
+ - Override operator<<(ostream&, gzfilebuf*) to allow direct copying
+   of stream buffer to stream ( i.e. os << is.rdbuf(); )


Index: llvm/runtime/zlib/contrib/iostream3/test.cc
diff -c /dev/null llvm/runtime/zlib/contrib/iostream3/test.cc:1.1.2.1
*** /dev/null	Mon Mar  1 17:58:58 2004
--- llvm/runtime/zlib/contrib/iostream3/test.cc	Mon Mar  1 17:58:48 2004
***************
*** 0 ****
--- 1,50 ----
+ /*
+  * Test program for gzifstream and gzofstream
+  *
+  * by Ludwig Schwardt <schwardt at sun.ac.za>
+  * original version by Kevin Ruland <kevin at rodin.wustl.edu>
+  */
+ 
+ #include "zfstream.h"
+ #include <iostream>      // for cout
+ 
+ int main() {
+ 
+   gzofstream outf;
+   gzifstream inf;
+   char buf[80];
+ 
+   outf.open("test1.txt.gz");
+   outf << "The quick brown fox sidestepped the lazy canine\n"
+        << 1.3 << "\nPlan " << 9 << std::endl;
+   outf.close();
+   std::cout << "Wrote the following message to 'test1.txt.gz' (check with zcat or zless):\n"
+             << "The quick brown fox sidestepped the lazy canine\n"
+             << 1.3 << "\nPlan " << 9 << std::endl;
+ 
+   std::cout << "\nReading 'test1.txt.gz' (buffered) produces:\n";
+   inf.open("test1.txt.gz");
+   while (inf.getline(buf,80,'\n')) {
+     std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n";
+   }
+   inf.close();
+ 
+   outf.rdbuf()->pubsetbuf(0,0);
+   outf.open("test2.txt.gz");
+   outf << setcompression(Z_NO_COMPRESSION)
+        << "The quick brown fox sidestepped the lazy canine\n"
+        << 1.3 << "\nPlan " << 9 << std::endl;
+   outf.close();
+   std::cout << "\nWrote the same message to 'test2.txt.gz' in uncompressed form";
+ 
+   std::cout << "\nReading 'test2.txt.gz' (unbuffered) produces:\n";
+   inf.rdbuf()->pubsetbuf(0,0);
+   inf.open("test2.txt.gz");
+   while (inf.getline(buf,80,'\n')) {
+     std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n";
+   }
+   inf.close();
+ 
+   return 0;
+ 
+ }


Index: llvm/runtime/zlib/contrib/iostream3/zfstream.cc
diff -c /dev/null llvm/runtime/zlib/contrib/iostream3/zfstream.cc:1.1.2.1
*** /dev/null	Mon Mar  1 17:58:58 2004
--- llvm/runtime/zlib/contrib/iostream3/zfstream.cc	Mon Mar  1 17:58:48 2004
***************
*** 0 ****
--- 1,479 ----
+ /*
+  * A C++ I/O streams interface to the zlib gz* functions
+  *
+  * by Ludwig Schwardt <schwardt at sun.ac.za>
+  * original version by Kevin Ruland <kevin at rodin.wustl.edu>
+  *
+  * This version is standard-compliant and compatible with gcc 3.x.
+  */
+ 
+ #include "zfstream.h"
+ #include <cstring>          // for strcpy, strcat, strlen (mode strings)
+ #include <cstdio>           // for BUFSIZ
+ 
+ // Internal buffer sizes (default and "unbuffered" versions)
+ #define BIGBUFSIZE BUFSIZ
+ #define SMALLBUFSIZE 1
+ 
+ /*****************************************************************************/
+ 
+ // Default constructor
+ gzfilebuf::gzfilebuf()
+ : file(NULL), io_mode(std::ios_base::openmode(0)), own_fd(false),
+   buffer(NULL), buffer_size(BIGBUFSIZE), own_buffer(true)
+ {
+   // No buffers to start with
+   this->disable_buffer();
+ }
+ 
+ // Destructor
+ gzfilebuf::~gzfilebuf()
+ {
+   // Sync output buffer and close only if responsible for file
+   // (i.e. attached streams should be left open at this stage)
+   this->sync();
+   if (own_fd)
+     this->close();
+   // Make sure internal buffer is deallocated
+   this->disable_buffer();
+ }
+ 
+ // Set compression level and strategy
+ int
+ gzfilebuf::setcompression(int comp_level,
+                           int comp_strategy)
+ {
+   return gzsetparams(file, comp_level, comp_strategy);
+ }
+ 
+ // Open gzipped file
+ gzfilebuf*
+ gzfilebuf::open(const char *name,
+                 std::ios_base::openmode mode)
+ {
+   // Fail if file already open
+   if (this->is_open())
+     return NULL;
+   // Don't support simultaneous read/write access (yet)
+   if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
+     return NULL;
+ 
+   // Build mode string for gzopen and check it [27.8.1.3.2]
+   char char_mode[6] = "\0\0\0\0\0";
+   if (!this->open_mode(mode, char_mode))
+     return NULL;
+ 
+   // Attempt to open file
+   if ((file = gzopen(name, char_mode)) == NULL)
+     return NULL;
+ 
+   // On success, allocate internal buffer and set flags
+   this->enable_buffer();
+   io_mode = mode;
+   own_fd = true;
+   return this;
+ }
+ 
+ // Attach to gzipped file
+ gzfilebuf*
+ gzfilebuf::attach(int fd,
+                   std::ios_base::openmode mode)
+ {
+   // Fail if file already open
+   if (this->is_open())
+     return NULL;
+   // Don't support simultaneous read/write access (yet)
+   if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
+     return NULL;
+ 
+   // Build mode string for gzdopen and check it [27.8.1.3.2]
+   char char_mode[6] = "\0\0\0\0\0";
+   if (!this->open_mode(mode, char_mode))
+     return NULL;
+ 
+   // Attempt to attach to file
+   if ((file = gzdopen(fd, char_mode)) == NULL)
+     return NULL;
+ 
+   // On success, allocate internal buffer and set flags
+   this->enable_buffer();
+   io_mode = mode;
+   own_fd = false;
+   return this;
+ }
+ 
+ // Close gzipped file
+ gzfilebuf*
+ gzfilebuf::close()
+ {
+   // Fail immediately if no file is open
+   if (!this->is_open())
+     return NULL;
+   // Assume success
+   gzfilebuf* retval = this;
+   // Attempt to sync and close gzipped file
+   if (this->sync() == -1)
+     retval = NULL;
+   if (gzclose(file) < 0)
+     retval = NULL;
+   // File is now gone anyway (postcondition [27.8.1.3.8])
+   file = NULL;
+   own_fd = false;
+   // Destroy internal buffer if it exists
+   this->disable_buffer();
+   return retval;
+ }
+ 
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+ 
+ // Convert int open mode to mode string
+ bool
+ gzfilebuf::open_mode(std::ios_base::openmode mode,
+                      char* c_mode) const
+ {
+   bool testb = mode & std::ios_base::binary;
+   bool testi = mode & std::ios_base::in;
+   bool testo = mode & std::ios_base::out;
+   bool testt = mode & std::ios_base::trunc;
+   bool testa = mode & std::ios_base::app;
+ 
+   // Check for valid flag combinations - see [27.8.1.3.2] (Table 92)
+   // Original zfstream hardcoded the compression level to maximum here...
+   // Double the time for less than 1% size improvement seems
+   // excessive though - keeping it at the default level
+   // To change back, just append "9" to the next three mode strings
+   if (!testi && testo && !testt && !testa)
+     strcpy(c_mode, "w");
+   if (!testi && testo && !testt && testa)
+     strcpy(c_mode, "a");
+   if (!testi && testo && testt && !testa)
+     strcpy(c_mode, "w");
+   if (testi && !testo && !testt && !testa)
+     strcpy(c_mode, "r");
+   // No read/write mode yet
+ //  if (testi && testo && !testt && !testa)
+ //    strcpy(c_mode, "r+");
+ //  if (testi && testo && testt && !testa)
+ //    strcpy(c_mode, "w+");
+ 
+   // Mode string should be empty for invalid combination of flags
+   if (strlen(c_mode) == 0)
+     return false;
+   if (testb)
+     strcat(c_mode, "b");
+   return true;
+ }
+ 
+ // Determine number of characters in internal get buffer
+ std::streamsize
+ gzfilebuf::showmanyc()
+ {
+   // Calls to underflow will fail if file not opened for reading
+   if (!this->is_open() || !(io_mode & std::ios_base::in))
+     return -1;
+   // Make sure get area is in use
+   if (this->gptr() && (this->gptr() < this->egptr()))
+     return std::streamsize(this->egptr() - this->gptr());
+   else
+     return 0;
+ }
+ 
+ // Fill get area from gzipped file
+ gzfilebuf::int_type
+ gzfilebuf::underflow()
+ {
+   // If something is left in the get area by chance, return it
+   // (this shouldn't normally happen, as underflow is only supposed
+   // to be called when gptr >= egptr, but it serves as error check)
+   if (this->gptr() && (this->gptr() < this->egptr()))
+     return traits_type::to_int_type(*(this->gptr()));
+ 
+   // If the file hasn't been opened for reading, produce error
+   if (!this->is_open() || !(io_mode & std::ios_base::in))
+     return traits_type::eof();
+ 
+   // Attempt to fill internal buffer from gzipped file
+   // (buffer must be guaranteed to exist...)
+   int bytes_read = gzread(file, buffer, buffer_size);
+   // Indicates error or EOF
+   if (bytes_read <= 0)
+   {
+     // Reset get area
+     this->setg(buffer, buffer, buffer);
+     return traits_type::eof();
+   }
+   // Make all bytes read from file available as get area
+   this->setg(buffer, buffer, buffer + bytes_read);
+ 
+   // Return next character in get area
+   return traits_type::to_int_type(*(this->gptr()));
+ }
+ 
+ // Write put area to gzipped file
+ gzfilebuf::int_type
+ gzfilebuf::overflow(int_type c)
+ {
+   // Determine whether put area is in use
+   if (this->pbase())
+   {
+     // Double-check pointer range
+     if (this->pptr() > this->epptr() || this->pptr() < this->pbase())
+       return traits_type::eof();
+     // Add extra character to buffer if not EOF
+     if (!traits_type::eq_int_type(c, traits_type::eof()))
+     {
+       *(this->pptr()) = traits_type::to_char_type(c);
+       this->pbump(1);
+     }
+     // Number of characters to write to file
+     int bytes_to_write = this->pptr() - this->pbase();
+     // Overflow doesn't fail if nothing is to be written
+     if (bytes_to_write > 0)
+     {
+       // If the file hasn't been opened for writing, produce error
+       if (!this->is_open() || !(io_mode & std::ios_base::out))
+         return traits_type::eof();
+       // If gzipped file won't accept all bytes written to it, fail
+       if (gzwrite(file, this->pbase(), bytes_to_write) != bytes_to_write)
+         return traits_type::eof();
+       // Reset next pointer to point to pbase on success
+       this->pbump(-bytes_to_write);
+     }
+   }
+   // Write extra character to file if not EOF
+   else if (!traits_type::eq_int_type(c, traits_type::eof()))
+   {
+     // If the file hasn't been opened for writing, produce error
+     if (!this->is_open() || !(io_mode & std::ios_base::out))
+       return traits_type::eof();
+     // Impromptu char buffer (allows "unbuffered" output)
+     char_type last_char = traits_type::to_char_type(c);
+     // If gzipped file won't accept this character, fail
+     if (gzwrite(file, &last_char, 1) != 1)
+       return traits_type::eof();
+   }
+ 
+   // If you got here, you have succeeded (even if c was EOF)
+   // The return value should therefore be non-EOF
+   if (traits_type::eq_int_type(c, traits_type::eof()))
+     return traits_type::not_eof(c);
+   else
+     return c;
+ }
+ 
+ // Assign new buffer
+ std::streambuf*
+ gzfilebuf::setbuf(char_type* p,
+                   std::streamsize n)
+ {
+   // First make sure stuff is sync'ed, for safety
+   if (this->sync() == -1)
+     return NULL;
+   // If buffering is turned off on purpose via setbuf(0,0), still allocate one...
+   // "Unbuffered" only really refers to put [27.8.1.4.10], while get needs at
+   // least a buffer of size 1 (very inefficient though, therefore make it bigger?)
+   // This follows from [27.5.2.4.3]/12 (gptr needs to point at something, it seems)
+   if (!p || !n)
+   {
+     // Replace existing buffer (if any) with small internal buffer
+     this->disable_buffer();
+     buffer = NULL;
+     buffer_size = 0;
+     own_buffer = true;
+     this->enable_buffer();
+   }
+   else
+   {
+     // Replace existing buffer (if any) with external buffer
+     this->disable_buffer();
+     buffer = p;
+     buffer_size = n;
+     own_buffer = false;
+     this->enable_buffer();
+   }
+   return this;
+ }
+ 
+ // Write put area to gzipped file (i.e. ensures that put area is empty)
+ int
+ gzfilebuf::sync()
+ {
+   return traits_type::eq_int_type(this->overflow(), traits_type::eof()) ? -1 : 0;
+ }
+ 
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+ 
+ // Allocate internal buffer
+ void
+ gzfilebuf::enable_buffer()
+ {
+   // If internal buffer required, allocate one
+   if (own_buffer && !buffer)
+   {
+     // Check for buffered vs. "unbuffered"
+     if (buffer_size > 0)
+     {
+       // Allocate internal buffer
+       buffer = new char_type[buffer_size];
+       // Get area starts empty and will be expanded by underflow as need arises
+       this->setg(buffer, buffer, buffer);
+       // Setup entire internal buffer as put area.
+       // The one-past-end pointer actually points to the last element of the buffer,
+       // so that overflow(c) can safely add the extra character c to the sequence.
+       // These pointers remain in place for the duration of the buffer
+       this->setp(buffer, buffer + buffer_size - 1);
+     }
+     else
+     {
+       // Even in "unbuffered" case, (small?) get buffer is still required
+       buffer_size = SMALLBUFSIZE;
+       buffer = new char_type[buffer_size];
+       this->setg(buffer, buffer, buffer);
+       // "Unbuffered" means no put buffer
+       this->setp(0, 0);
+     }
+   }
+   else
+   {
+     // If buffer already allocated, reset buffer pointers just to make sure no
+     // stale chars are lying around
+     this->setg(buffer, buffer, buffer);
+     this->setp(buffer, buffer + buffer_size - 1);
+   }
+ }
+ 
+ // Destroy internal buffer
+ void
+ gzfilebuf::disable_buffer()
+ {
+   // If internal buffer exists, deallocate it
+   if (own_buffer && buffer)
+   {
+     // Preserve unbuffered status by zeroing size
+     if (!this->pbase())
+       buffer_size = 0;
+     delete[] buffer;
+     buffer = NULL;
+     this->setg(0, 0, 0);
+     this->setp(0, 0);
+   }
+   else
+   {
+     // Reset buffer pointers to initial state if external buffer exists
+     this->setg(buffer, buffer, buffer);
+     if (buffer)
+       this->setp(buffer, buffer + buffer_size - 1);
+     else
+       this->setp(0, 0);
+   }
+ }
+ 
+ /*****************************************************************************/
+ 
+ // Default constructor initializes stream buffer
+ gzifstream::gzifstream()
+ : std::istream(NULL), sb()
+ { this->init(&sb); }
+ 
+ // Initialize stream buffer and open file
+ gzifstream::gzifstream(const char* name,
+                        std::ios_base::openmode mode)
+ : std::istream(NULL), sb()
+ {
+   this->init(&sb);
+   this->open(name, mode);
+ }
+ 
+ // Initialize stream buffer and attach to file
+ gzifstream::gzifstream(int fd,
+                        std::ios_base::openmode mode)
+ : std::istream(NULL), sb()
+ {
+   this->init(&sb);
+   this->attach(fd, mode);
+ }
+ 
+ // Open file and go into fail() state if unsuccessful
+ void
+ gzifstream::open(const char* name,
+                  std::ios_base::openmode mode)
+ {
+   if (!sb.open(name, mode | std::ios_base::in))
+     this->setstate(std::ios_base::failbit);
+   else
+     this->clear();
+ }
+ 
+ // Attach to file and go into fail() state if unsuccessful
+ void
+ gzifstream::attach(int fd,
+                    std::ios_base::openmode mode)
+ {
+   if (!sb.attach(fd, mode | std::ios_base::in))
+     this->setstate(std::ios_base::failbit);
+   else
+     this->clear();
+ }
+ 
+ // Close file
+ void
+ gzifstream::close()
+ {
+   if (!sb.close())
+     this->setstate(std::ios_base::failbit);
+ }
+ 
+ /*****************************************************************************/
+ 
+ // Default constructor initializes stream buffer
+ gzofstream::gzofstream()
+ : std::ostream(NULL), sb()
+ { this->init(&sb); }
+ 
+ // Initialize stream buffer and open file
+ gzofstream::gzofstream(const char* name,
+                        std::ios_base::openmode mode)
+ : std::ostream(NULL), sb()
+ {
+   this->init(&sb);
+   this->open(name, mode);
+ }
+ 
+ // Initialize stream buffer and attach to file
+ gzofstream::gzofstream(int fd,
+                        std::ios_base::openmode mode)
+ : std::ostream(NULL), sb()
+ {
+   this->init(&sb);
+   this->attach(fd, mode);
+ }
+ 
+ // Open file and go into fail() state if unsuccessful
+ void
+ gzofstream::open(const char* name,
+                  std::ios_base::openmode mode)
+ {
+   if (!sb.open(name, mode | std::ios_base::out))
+     this->setstate(std::ios_base::failbit);
+   else
+     this->clear();
+ }
+ 
+ // Attach to file and go into fail() state if unsuccessful
+ void
+ gzofstream::attach(int fd,
+                    std::ios_base::openmode mode)
+ {
+   if (!sb.attach(fd, mode | std::ios_base::out))
+     this->setstate(std::ios_base::failbit);
+   else
+     this->clear();
+ }
+ 
+ // Close file
+ void
+ gzofstream::close()
+ {
+   if (!sb.close())
+     this->setstate(std::ios_base::failbit);
+ }


Index: llvm/runtime/zlib/contrib/iostream3/zfstream.h
diff -c /dev/null llvm/runtime/zlib/contrib/iostream3/zfstream.h:1.1.2.1
*** /dev/null	Mon Mar  1 17:58:58 2004
--- llvm/runtime/zlib/contrib/iostream3/zfstream.h	Mon Mar  1 17:58:48 2004
***************
*** 0 ****
--- 1,466 ----
+ /*
+  * A C++ I/O streams interface to the zlib gz* functions
+  *
+  * by Ludwig Schwardt <schwardt at sun.ac.za>
+  * original version by Kevin Ruland <kevin at rodin.wustl.edu>
+  *
+  * This version is standard-compliant and compatible with gcc 3.x.
+  */
+ 
+ #ifndef ZFSTREAM_H
+ #define ZFSTREAM_H
+ 
+ #include <istream>  // not iostream, since we don't need cin/cout
+ #include <ostream>
+ #include "zlib.h"
+ 
+ /*****************************************************************************/
+ 
+ /**
+  *  @brief  Gzipped file stream buffer class.
+  *
+  *  This class implements basic_filebuf for gzipped files. It doesn't yet support
+  *  seeking (allowed by zlib but slow/limited), putback and read/write access
+  *  (tricky). Otherwise, it attempts to be a drop-in replacement for the standard
+  *  file streambuf.
+ */
+ class gzfilebuf : public std::streambuf
+ {
+ public:
+   //  Default constructor.
+   gzfilebuf();
+ 
+   //  Destructor.
+   virtual
+   ~gzfilebuf();
+ 
+   /**
+    *  @brief  Set compression level and strategy on the fly.
+    *  @param  comp_level  Compression level (see zlib.h for allowed values)
+    *  @param  comp_strategy  Compression strategy (see zlib.h for allowed values)
+    *  @return  Z_OK on success, Z_STREAM_ERROR otherwise.
+    *
+    *  Unfortunately, these parameters cannot be modified separately, as the
+    *  previous zfstream version assumed. Since the strategy is seldom changed,
+    *  it can default and setcompression(level) then becomes like the old
+    *  setcompressionlevel(level).
+   */
+   int
+   setcompression(int comp_level,
+                  int comp_strategy = Z_DEFAULT_STRATEGY);
+ 
+   /**
+    *  @brief  Check if file is open.
+    *  @return  True if file is open.
+   */
+   bool
+   is_open() const { return (file != NULL); }
+ 
+   /**
+    *  @brief  Open gzipped file.
+    *  @param  name  File name.
+    *  @param  mode  Open mode flags.
+    *  @return  @c this on success, NULL on failure.
+   */
+   gzfilebuf*
+   open(const char* name,
+        std::ios_base::openmode mode);
+ 
+   /**
+    *  @brief  Attach to already open gzipped file.
+    *  @param  fd  File descriptor.
+    *  @param  mode  Open mode flags.
+    *  @return  @c this on success, NULL on failure.
+   */
+   gzfilebuf*
+   attach(int fd,
+          std::ios_base::openmode mode);
+ 
+   /**
+    *  @brief  Close gzipped file.
+    *  @return  @c this on success, NULL on failure.
+   */
+   gzfilebuf*
+   close();
+ 
+ protected:
+   /**
+    *  @brief  Convert ios open mode int to mode string used by zlib.
+    *  @return  True if valid mode flag combination.
+   */
+   bool
+   open_mode(std::ios_base::openmode mode,
+             char* c_mode) const;
+ 
+   /**
+    *  @brief  Number of characters available in stream buffer.
+    *  @return  Number of characters.
+    *
+    *  This indicates number of characters in get area of stream buffer.
+    *  These characters can be read without accessing the gzipped file.
+   */
+   virtual std::streamsize
+   showmanyc();
+ 
+   /**
+    *  @brief  Fill get area from gzipped file.
+    *  @return  First character in get area on success, EOF on error.
+    *
+    *  This actually reads characters from gzipped file to stream
+    *  buffer. Always buffered.
+   */
+   virtual int_type
+   underflow();
+ 
+   /**
+    *  @brief  Write put area to gzipped file.
+    *  @param  c  Extra character to add to buffer contents.
+    *  @return  Non-EOF on success, EOF on error.
+    *
+    *  This actually writes characters in stream buffer to
+    *  gzipped file. With unbuffered output this is done one
+    *  character at a time.
+   */
+   virtual int_type
+   overflow(int_type c = traits_type::eof());
+ 
+   /**
+    *  @brief  Installs external stream buffer.
+    *  @param  p  Pointer to char buffer.
+    *  @param  n  Size of external buffer.
+    *  @return  @c this on success, NULL on failure.
+    *
+    *  Call setbuf(0,0) to enable unbuffered output.
+   */
+   virtual std::streambuf*
+   setbuf(char_type* p,
+          std::streamsize n);
+ 
+   /**
+    *  @brief  Flush stream buffer to file.
+    *  @return  0 on success, -1 on error.
+    *
+    *  This calls underflow(EOF) to do the job.
+   */
+   virtual int
+   sync();
+ 
+ //
+ // Some future enhancements
+ //
+ //  virtual int_type uflow();
+ //  virtual int_type pbackfail(int_type c = traits_type::eof());
+ //  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);
+ //  virtual pos_type
+ //  seekpos(pos_type sp,
+ //          std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
+ 
+ private:
+   /**
+    *  @brief  Allocate internal buffer.
+    *
+    *  This function is safe to call multiple times. It will ensure
+    *  that a proper internal buffer exists if it is required. If the
+    *  buffer already exists or is external, the buffer pointers will be
+    *  reset to their original state.
+   */
+   void
+   enable_buffer();
+ 
+   /**
+    *  @brief  Destroy internal buffer.
+    *
+    *  This function is safe to call multiple times. It will ensure
+    *  that the internal buffer is deallocated if it exists. In any
+    *  case, it will also reset the buffer pointers.
+   */
+   void
+   disable_buffer();
+ 
+   /**
+    *  Underlying file pointer.
+   */
+   gzFile file;
+ 
+   /**
+    *  Mode in which file was opened.
+   */
+   std::ios_base::openmode io_mode;
+ 
+   /**
+    *  @brief  True if this object owns file descriptor.
+    *
+    *  This makes the class responsible for closing the file
+    *  upon destruction.
+   */
+   bool own_fd;
+ 
+   /**
+    *  @brief  Stream buffer.
+    *
+    *  For simplicity this remains allocated on the free store for the
+    *  entire life span of the gzfilebuf object, unless replaced by setbuf.
+   */
+   char_type* buffer;
+ 
+   /**
+    *  @brief  Stream buffer size.
+    *
+    *  Defaults to system default buffer size (typically 8192 bytes).
+    *  Modified by setbuf.
+   */
+   std::streamsize buffer_size;
+ 
+   /**
+    *  @brief  True if this object owns stream buffer.
+    *
+    *  This makes the class responsible for deleting the buffer
+    *  upon destruction.
+   */
+   bool own_buffer;
+ };
+ 
+ /*****************************************************************************/
+ 
+ /**
+  *  @brief  Gzipped file input stream class.
+  *
+  *  This class implements ifstream for gzipped files. Seeking and putback
+  *  is not supported yet.
+ */
+ class gzifstream : public std::istream
+ {
+ public:
+   //  Default constructor
+   gzifstream();
+ 
+   /**
+    *  @brief  Construct stream on gzipped file to be opened.
+    *  @param  name  File name.
+    *  @param  mode  Open mode flags (forced to contain ios::in).
+   */
+   explicit
+   gzifstream(const char* name,
+              std::ios_base::openmode mode = std::ios_base::in);
+ 
+   /**
+    *  @brief  Construct stream on already open gzipped file.
+    *  @param  fd    File descriptor.
+    *  @param  mode  Open mode flags (forced to contain ios::in).
+   */
+   explicit
+   gzifstream(int fd,
+              std::ios_base::openmode mode = std::ios_base::in);
+ 
+   /**
+    *  Obtain underlying stream buffer.
+   */
+   gzfilebuf*
+   rdbuf() const
+   { return const_cast<gzfilebuf*>(&sb); }
+ 
+   /**
+    *  @brief  Check if file is open.
+    *  @return  True if file is open.
+   */
+   bool
+   is_open() { return sb.is_open(); }
+ 
+   /**
+    *  @brief  Open gzipped file.
+    *  @param  name  File name.
+    *  @param  mode  Open mode flags (forced to contain ios::in).
+    *
+    *  Stream will be in state good() if file opens successfully;
+    *  otherwise in state fail(). This differs from the behavior of
+    *  ifstream, which never sets the state to good() and therefore
+    *  won't allow you to reuse the stream for a second file unless
+    *  you manually clear() the state. The choice is a matter of
+    *  convenience.
+   */
+   void
+   open(const char* name,
+        std::ios_base::openmode mode = std::ios_base::in);
+ 
+   /**
+    *  @brief  Attach to already open gzipped file.
+    *  @param  fd  File descriptor.
+    *  @param  mode  Open mode flags (forced to contain ios::in).
+    *
+    *  Stream will be in state good() if attach succeeded; otherwise
+    *  in state fail().
+   */
+   void
+   attach(int fd,
+          std::ios_base::openmode mode = std::ios_base::in);
+ 
+   /**
+    *  @brief  Close gzipped file.
+    *
+    *  Stream will be in state fail() if close failed.
+   */
+   void
+   close();
+ 
+ private:
+   /**
+    *  Underlying stream buffer.
+   */
+   gzfilebuf sb;
+ };
+ 
+ /*****************************************************************************/
+ 
+ /**
+  *  @brief  Gzipped file output stream class.
+  *
+  *  This class implements ofstream for gzipped files. Seeking and putback
+  *  is not supported yet.
+ */
+ class gzofstream : public std::ostream
+ {
+ public:
+   //  Default constructor
+   gzofstream();
+ 
+   /**
+    *  @brief  Construct stream on gzipped file to be opened.
+    *  @param  name  File name.
+    *  @param  mode  Open mode flags (forced to contain ios::out).
+   */
+   explicit
+   gzofstream(const char* name,
+              std::ios_base::openmode mode = std::ios_base::out);
+ 
+   /**
+    *  @brief  Construct stream on already open gzipped file.
+    *  @param  fd    File descriptor.
+    *  @param  mode  Open mode flags (forced to contain ios::out).
+   */
+   explicit
+   gzofstream(int fd,
+              std::ios_base::openmode mode = std::ios_base::out);
+ 
+   /**
+    *  Obtain underlying stream buffer.
+   */
+   gzfilebuf*
+   rdbuf() const
+   { return const_cast<gzfilebuf*>(&sb); }
+ 
+   /**
+    *  @brief  Check if file is open.
+    *  @return  True if file is open.
+   */
+   bool
+   is_open() { return sb.is_open(); }
+ 
+   /**
+    *  @brief  Open gzipped file.
+    *  @param  name  File name.
+    *  @param  mode  Open mode flags (forced to contain ios::out).
+    *
+    *  Stream will be in state good() if file opens successfully;
+    *  otherwise in state fail(). This differs from the behavior of
+    *  ofstream, which never sets the state to good() and therefore
+    *  won't allow you to reuse the stream for a second file unless
+    *  you manually clear() the state. The choice is a matter of
+    *  convenience.
+   */
+   void
+   open(const char* name,
+        std::ios_base::openmode mode = std::ios_base::out);
+ 
+   /**
+    *  @brief  Attach to already open gzipped file.
+    *  @param  fd  File descriptor.
+    *  @param  mode  Open mode flags (forced to contain ios::out).
+    *
+    *  Stream will be in state good() if attach succeeded; otherwise
+    *  in state fail().
+   */
+   void
+   attach(int fd,
+          std::ios_base::openmode mode = std::ios_base::out);
+ 
+   /**
+    *  @brief  Close gzipped file.
+    *
+    *  Stream will be in state fail() if close failed.
+   */
+   void
+   close();
+ 
+ private:
+   /**
+    *  Underlying stream buffer.
+   */
+   gzfilebuf sb;
+ };
+ 
+ /*****************************************************************************/
+ 
+ /**
+  *  @brief  Gzipped file output stream manipulator class.
+  *
+  *  This class defines a two-argument manipulator for gzofstream. It is used
+  *  as base for the setcompression(int,int) manipulator.
+ */
+ template<typename T1, typename T2>
+   class gzomanip2
+   {
+   public:
+     // Allows insertor to peek at internals
+     template <typename Ta, typename Tb>
+       friend gzofstream&
+       operator<<(gzofstream&,
+                  const gzomanip2<Ta,Tb>&);
+ 
+     // Constructor
+     gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2),
+               T1 v1,
+               T2 v2);
+   private:
+     // Underlying manipulator function
+     gzofstream&
+     (*func)(gzofstream&, T1, T2);
+ 
+     // Arguments for manipulator function
+     T1 val1;
+     T2 val2;
+   };
+ 
+ /*****************************************************************************/
+ 
+ // Manipulator function thunks through to stream buffer
+ inline gzofstream&
+ setcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY)
+ {
+   (gzs.rdbuf())->setcompression(l, s);
+   return gzs;
+ }
+ 
+ // Manipulator constructor stores arguments
+ template<typename T1, typename T2>
+   inline
+   gzomanip2<T1,T2>::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2),
+                               T1 v1,
+                               T2 v2)
+   : func(f), val1(v1), val2(v2)
+   { }
+ 
+ // Insertor applies underlying manipulator function to stream
+ template<typename T1, typename T2>
+   inline gzofstream&
+   operator<<(gzofstream& s, const gzomanip2<T1,T2>& m)
+   { return (*m.func)(s, m.val1, m.val2); }
+ 
+ // Insert this onto stream to simplify setting of compression level
+ inline gzomanip2<int,int>
+ setcompression(int l, int s = Z_DEFAULT_STRATEGY)
+ { return gzomanip2<int,int>(&setcompression, l, s); }
+ 
+ #endif // ZFSTREAM_H





More information about the llvm-commits mailing list