Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

CPipeInflate.cpp

Go to the documentation of this file.
00001 
00032 #include "stdafx.h"
00033 #include "CPipeInflate.h"
00034 
00035 // Can't use this for convenient notation below:
00036 // using AxPipe::Stock::CPipeInflate;
00037 // because the Doxygen get's confused.
00038 
00039 namespace AxPipe {
00040     namespace Stock {
00042         CPipeInflate::CPipeInflate() {
00043             m_pOutSeg = NULL;
00044             m_cb = 0;
00045             ZeroMemory(&m_Zstream, sizeof m_Zstream);
00046         }
00047 
00050         CPipeInflate::~CPipeInflate() {
00051             if (m_pOutSeg) {
00052                 m_pOutSeg->Release();
00053             }
00054         }
00055 
00058         bool
00059         CPipeInflate::OutOpen() {
00060             bool fReturn = CPipe::OutOpen();        // Open base first, like constructor
00061             m_cb = 0;                               // Total output bytes counter
00062             ZeroMemory(&m_Zstream, sizeof m_Zstream);
00063             m_Zstream.next_in = Z_NULL;             // Defer check to first call to inflate
00064             m_Zstream.zalloc = Z_NULL;              // Use default alloc()
00065             m_Zstream.zfree = Z_NULL;               // Use default free()
00066 
00067             if (inflateInit(&m_Zstream) != Z_OK) {
00068                 SetError(ERROR_CODE_STOCK, _T("ZLIB initialization error"));
00069             }
00070             ASSCHK(m_pOutSeg == NULL, _T("CPipeInflate::OutOpen() [m_pOutSeg non-NULL]"));
00071 
00072             return fReturn;                         // Return the saved return code.
00073         }
00074 
00077         bool
00078         CPipeInflate::OutClose() {
00079             // This is a safety first measure, should not really be needed.
00080             if (m_pOutSeg) {
00081                 m_pOutSeg->Release();
00082                 m_pOutSeg = NULL;
00083             }
00084             return CPipe::OutClose();               // End by closing base, like destructor
00085         }
00086 
00093         void
00094         CPipeInflate::Out(AxPipe::CSeg *pSeg) {
00095             m_Zstream.next_in = (unsigned char *)pSeg->PtrRd();
00096             m_Zstream.avail_in = (UINT)pSeg->Len();
00097             while (true) {
00098                 if (!m_pOutSeg) {
00099                     // Allocate the output segment, and point the Zstream structure to it
00100                     m_pOutSeg = GetSeg(m_Zstream.avail_in + m_Zstream.avail_in);
00101                     ASSPTR(m_pOutSeg);
00102                     m_Zstream.avail_out = (UINT)m_pOutSeg->Size();
00103                     m_Zstream.next_out = m_pOutSeg->PtrWr();
00104                 }
00105                 int iZerror = inflate(&m_Zstream, 0);
00106                 m_cb += m_Zstream.total_out;        // Update total output bytes ctr
00107                 m_Zstream.total_out = 0;            // can't use total_out since it's 32-bit
00108                 switch (iZerror) {
00109                 case Z_OK:
00110                     // ZLib guarantees to either use all input or all output buffer.
00111                     if (m_Zstream.avail_in && m_Zstream.avail_out) {
00112                         SetError(ERROR_CODE_DERIVED, _T("ZLIB sequence error"));
00113                     }
00114                     if (!m_Zstream.avail_out) {
00115                         Pump(m_pOutSeg);
00116                         m_pOutSeg = NULL;
00117                     }
00118                     if (m_Zstream.avail_in) {
00119                         continue;                   // More data to inflate!
00120                     }
00121                     // If we have no more input, we need to return and wait for more
00122                     break;
00123                 case Z_STREAM_END:
00124                     m_pOutSeg->Len(m_pOutSeg->Size() - m_Zstream.avail_out);
00125                     Pump(m_pOutSeg);
00126                     m_pOutSeg = NULL;
00127                     if (m_Zstream.avail_in) {
00128                         SetError(ERROR_CODE_STOCK, _T("Trailing data"));
00129                     }
00130                     break;
00131                 default:
00132                     SetError(ERROR_CODE_STOCK, _T("ZLIB inflate error"));
00133                     break;
00134                 }
00135                 break;
00136             }
00137             pSeg->Release();
00138         }
00139     }
00140 }

Generated on Mon Feb 2 13:19:18 2004 for AxPipe by doxygen 1.3.5