1 #include "soplex/spxdefines.h" 2 #ifdef SOPLEX_WITH_ZLIB 3 4 // ============================================================================ 5 // gzstream, C++ iostream classes wrapping the zlib compression library. 6 // Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner 7 // 8 // This library is free software; you can redistribute it and/or 9 // modify it under the terms of the GNU Lesser General Public 10 // License as published by the Free Software Foundation; either 11 // version 2.1 of the License, or (at your option) any later version. 12 // 13 // This library is distributed in the hope that it will be useful, 14 // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 // Lesser General Public License for more details. 17 // 18 // You should have received a copy of the GNU Lesser General Public 19 // License along with this library; if not, write to the Free Software 20 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 // ============================================================================ 22 // 23 // File : gzstream.C 24 // Revision : $Revision: 1.8 $ 25 // Revision_date : $Date: 2005/12/07 18:03:25 $ 26 // Author(s) : Deepak Bandyopadhyay, Lutz Kettner 27 // 28 // Standard streambuf implementation following Nicolai Josuttis, "The 29 // Standard C++ Library". 30 // ============================================================================ 31 32 #include "soplex/gzstream.h" 33 #include <iostream> 34 #include <string.h> // for memcpy 35 36 #ifdef SOPLEX_GZSTREAM_NAMESPACE 37 namespace SOPLEX_GZSTREAM_NAMESPACE 38 { 39 #endif 40 41 // ---------------------------------------------------------------------------- 42 // Internal classes to implement gzstream. See header file for user classes. 43 // ---------------------------------------------------------------------------- 44 45 // -------------------------------------- 46 // class gzstreambuf: 47 // -------------------------------------- 48 49 gzstreambuf* gzstreambuf::open(const char* _name, int _open_mode) 50 { 51 if(is_open()) 52 return 0; 53 54 mode = static_cast<unsigned int>(_open_mode); 55 56 // no append nor read/write mode 57 if((mode & std::ios::ate) || (mode & std::ios::app) 58 || ((mode & std::ios::in) && (mode & std::ios::out))) 59 return 0; 60 61 char fmode[10]; 62 char* fmodeptr = fmode; 63 64 if(mode & std::ios::in) 65 *fmodeptr++ = 'r'; 66 else if(mode & std::ios::out) 67 *fmodeptr++ = 'w'; 68 69 *fmodeptr++ = 'b'; 70 *fmodeptr = '\0'; 71 file = gzopen(_name, fmode); 72 73 if(file == 0) 74 return 0; 75 76 opened = 1; 77 return this; 78 } 79 80 gzstreambuf* gzstreambuf::close() 81 { 82 if(is_open()) 83 { 84 sync(); 85 opened = 0; 86 87 if(gzclose(file) == Z_OK) 88 return this; 89 } 90 91 return 0; 92 } 93 94 int gzstreambuf::underflow() // used for input buffer only 95 { 96 if(gptr() && (gptr() < egptr())) 97 return * reinterpret_cast<unsigned char*>(gptr()); 98 99 if(!(mode & std::ios::in) || ! opened) 100 return EOF; 101 102 // Josuttis' implementation of inbuf 103 size_t n_putback = (size_t)(gptr() - eback()); 104 105 if(n_putback > 4) 106 n_putback = 4; 107 108 memcpy(buffer + (4 - n_putback), gptr() - n_putback, n_putback); 109 110 int num = gzread(file, buffer + 4, bufferSize - 4); 111 112 if(num <= 0) // ERROR or EOF 113 return EOF; 114 115 // reset buffer pointers 116 setg(buffer + (4 - n_putback), // beginning of putback area 117 buffer + 4, // read position 118 buffer + 4 + num); // end of buffer 119 120 // return next character 121 return * reinterpret_cast<unsigned char*>(gptr()); 122 } 123 124 int gzstreambuf::flush_buffer() 125 { 126 // Separate the writing of the buffer from overflow() and 127 // sync() operation. 128 int w = static_cast<int>(pptr() - pbase()); 129 130 if(gzwrite(file, pbase(), (unsigned int) w) != w) 131 return EOF; 132 133 pbump(-w); 134 return w; 135 } 136 137 int gzstreambuf::overflow(int c) // used for output buffer only 138 { 139 if(!(mode & std::ios::out) || ! opened) 140 return EOF; 141 142 if(c != EOF) 143 { 144 *pptr() = static_cast<char>(c); 145 pbump(1); 146 } 147 148 if(flush_buffer() == EOF) 149 return EOF; 150 151 return c; 152 } 153 154 int gzstreambuf::sync() 155 { 156 // Changed to use flush_buffer() instead of overflow( EOF) 157 // which caused improper behavior with std::endl and flush(), 158 // bug reported by Vincent Ricard. 159 if(pptr() && pptr() > pbase()) 160 { 161 if(flush_buffer() == EOF) 162 return -1; 163 } 164 165 return 0; 166 } 167 168 // -------------------------------------- 169 // class gzstreambase: 170 // -------------------------------------- 171 172 gzstreambase::gzstreambase(const char* name, int mode) 173 { 174 init(&buf); 175 open(name, mode); 176 } 177 178 gzstreambase::~gzstreambase() 179 { 180 buf.close(); 181 } 182 183 void gzstreambase::open(const char* _name, int _open_mode) 184 { 185 if(! buf.open(_name, _open_mode)) 186 setstate(std::ios::badbit); 187 188 // clear( rdstate() | std::ios::badbit); 189 } 190 191 void gzstreambase::close() 192 { 193 if(buf.is_open()) 194 if(! buf.close()) 195 setstate(std::ios::badbit); 196 197 // clear( rdstate() | std::ios::badbit); 198 } 199 200 #ifdef SOPLEX_GZSTREAM_NAMESPACE 201 } // namespace SOPLEX_GZSTREAM_NAMESPACE 202 #endif 203 204 // ============================================================================ 205 // EOF // 206 207 #endif 208