00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00036 #include "OW_config.h"
00037 #ifdef OW_HAVE_ZLIB_H
00038 #include "OW_HTTPDeflateOStream.hpp"
00039 #include "OW_HTTPException.hpp"
00040 #include "OW_String.hpp"
00041
00042 namespace OW_NAMESPACE
00043 {
00044
00045 using std::ostream;
00046 HTTPDeflateOStreamBuffer::HTTPDeflateOStreamBuffer(ostream& ostr)
00047 : BaseStreamBuffer(HTTP_BUF_SIZE, "out")
00048 , m_ostr(ostr)
00049 {
00050 m_zstr.opaque = Z_NULL;
00051 m_zstr.zfree = Z_NULL;
00052 m_zstr.zalloc = Z_NULL;
00053 m_zstr.next_out = m_outBuf;
00054 m_zstr.avail_out = m_outBufSize;
00055 int rval = deflateInit(&m_zstr, Z_DEFAULT_COMPRESSION);
00056 if (rval != Z_OK)
00057 {
00058 String msg = "Error: deflateInit returned " + String(rval);
00059 if (m_zstr.msg)
00060 {
00061 msg += String(": ") + String(m_zstr.msg);
00062 }
00063 OW_THROW(HTTPException, msg.c_str());
00064 }
00065 }
00067 HTTPDeflateOStreamBuffer::~HTTPDeflateOStreamBuffer()
00068 {
00069 try
00070 {
00071 sync();
00072 deflateEnd(&m_zstr);
00073 }
00074 catch (...)
00075 {
00076
00077 }
00078 }
00080 int
00081 HTTPDeflateOStreamBuffer::sync()
00082 {
00083 int rval = BaseStreamBuffer::sync();
00084 m_zstr.avail_in = 0;
00085 flushOutBuf(Z_SYNC_FLUSH);
00086 m_ostr.flush();
00087 return rval;
00088 }
00090 int
00091 HTTPDeflateOStreamBuffer::buffer_to_device(const char* c, int n)
00092 {
00093 m_zstr.next_in = const_cast<Bytef*>(reinterpret_cast<const Bytef*>(c));
00094 m_zstr.avail_in = n;
00095 int rval = 0;
00096 while (m_zstr.avail_in > 0)
00097 {
00098 int rv = flushOutBuf();
00099 if (rv == -1)
00100 {
00101 rval = rv;
00102 break;
00103 }
00104 else
00105 {
00106 rval += rv;
00107 }
00108 }
00109 return rval;
00110 }
00112 int
00113 HTTPDeflateOStreamBuffer::flushOutBuf(int flush)
00114 {
00115 int rval = 0;
00116 switch (flush)
00117 {
00118 case Z_SYNC_FLUSH:
00119 case Z_FINISH:
00120 int rv;
00121 do
00122 {
00123 rv = deflate(&m_zstr, flush);
00124 int bytesToWrite = writeToStream();
00125 if (bytesToWrite == -1)
00126 {
00127 return -1;
00128 }
00129 rval += bytesToWrite;
00130 } while (rv == Z_OK);
00131 break;
00132 default:
00133 if (deflate(&m_zstr, flush) != Z_OK)
00134 {
00135 rval = -1;
00136 }
00137 else if (m_zstr.avail_out < m_outBufSize)
00138 {
00139 int bytesToWrite = writeToStream();
00140 if (bytesToWrite == -1)
00141 {
00142 return -1;
00143 }
00144 if (!m_ostr)
00145 {
00146 rval = -1;
00147 }
00148 else
00149 {
00150 rval = bytesToWrite;
00151 }
00152 }
00153 break;
00154 }
00155 return rval;
00156 }
00157
00159 int
00160 HTTPDeflateOStreamBuffer::writeToStream()
00161 {
00162 int bytesToWrite = m_outBufSize - m_zstr.avail_out;
00163 if (!m_ostr.write(reinterpret_cast<char*>(m_outBuf), bytesToWrite))
00164 {
00165 return -1;
00166 }
00167 m_zstr.next_out = m_outBuf;
00168 m_zstr.avail_out = m_outBufSize;
00169 return bytesToWrite;
00170 }
00172 void
00173 HTTPDeflateOStreamBuffer::termOutput()
00174 {
00175 sync();
00176 flushOutBuf(Z_FINISH);
00177 m_ostr.flush();
00178 }
00180 HTTPDeflateOStream::HTTPDeflateOStream(ostream& ostr)
00181 : HTTPDeflateOStreamBase(ostr)
00182 , std::basic_ostream<char, std::char_traits<char> >(&m_strbuf)
00183 , m_ostr(ostr)
00184 {
00185 }
00186
00187 }
00188
00190 #endif // #ifdef OW_HAVE_ZLIB_H
00191