home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / src / common / zipstrm.cpp < prev    next >
C/C++ Source or Header  |  2002-11-04  |  4KB  |  160 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        zipstream.cpp
  3. // Purpose:     input stream for ZIP archive access
  4. // Author:      Vaclav Slavik
  5. // Copyright:   (c) 1999 Vaclav Slavik
  6. // Licence:     wxWindows Licence
  7. /////////////////////////////////////////////////////////////////////////////
  8.  
  9. #ifdef __GNUG__
  10. #pragma implementation "zipstrm.h"
  11. #endif
  12.  
  13. // For compilers that support precompilation, includes "wx.h".
  14. #include "wx/wxprec.h"
  15.  
  16. #ifdef __BORLANDC__
  17.   #pragma hdrstop
  18. #endif
  19.  
  20. #if wxUSE_STREAMS && wxUSE_ZIPSTREAM && wxUSE_ZLIB
  21.  
  22. #include "wx/log.h"
  23. #include "wx/intl.h"
  24. #include "wx/stream.h"
  25. #include "wx/wfstream.h"
  26. #include "wx/zipstrm.h"
  27. #include "wx/utils.h"
  28.  
  29. /* Not the right solution (paths in makefiles) but... */
  30. #ifdef __BORLANDC__
  31. #include "../common/unzip.h"
  32. #else
  33. #include "unzip.h"
  34. #endif
  35.  
  36.  
  37. wxZipInputStream::wxZipInputStream(const wxString& archive, const wxString& file) : wxInputStream()
  38. {
  39.     unz_file_info zinfo;
  40.  
  41.     m_Pos = 0;
  42.     m_Size = 0;
  43.     m_Archive = (void*) unzOpen(archive.mb_str());
  44.     if (m_Archive == NULL)
  45.     {
  46.         m_lasterror = wxSTREAM_READ_ERROR;
  47.         return;
  48.     }
  49.     if (unzLocateFile((unzFile)m_Archive, file.mb_str(), 0) != UNZ_OK)
  50.     {
  51.         m_lasterror = wxSTREAM_READ_ERROR;
  52.         return;
  53.     }
  54.  
  55.     unzGetCurrentFileInfo((unzFile)m_Archive, &zinfo, (char*) NULL, 0, (void*) NULL, 0, (char*) NULL, 0);
  56.  
  57.     if (unzOpenCurrentFile((unzFile)m_Archive) != UNZ_OK)
  58.     {
  59.         m_lasterror = wxSTREAM_READ_ERROR;
  60.         return;
  61.     }
  62.     m_Size = (size_t)zinfo.uncompressed_size;
  63. }
  64.  
  65.  
  66.  
  67. wxZipInputStream::~wxZipInputStream()
  68. {
  69.     if (m_Archive)
  70.     {
  71.         if (m_Size != 0)
  72.             unzCloseCurrentFile((unzFile)m_Archive);
  73.         unzClose((unzFile)m_Archive);
  74.     }
  75. }
  76.  
  77. bool wxZipInputStream::Eof() const
  78. {
  79.     wxASSERT_MSG( m_Pos <= (off_t)m_Size,
  80.                   _T("wxZipInputStream: invalid current position") );
  81.  
  82.     return m_Pos >= (off_t)m_Size;
  83. }
  84.  
  85.  
  86. size_t wxZipInputStream::OnSysRead(void *buffer, size_t bufsize)
  87. {
  88.     wxASSERT_MSG( m_Pos <= (off_t)m_Size,
  89.                   _T("wxZipInputStream: invalid current position") );
  90.  
  91.     if ( m_Pos >= (off_t)m_Size )
  92.     {
  93.         m_lasterror = wxSTREAM_EOF;
  94.         return 0;
  95.     }
  96.  
  97.     if (m_Pos + bufsize > m_Size)
  98.         bufsize = m_Size - m_Pos;
  99.  
  100.     unzReadCurrentFile((unzFile)m_Archive, buffer, bufsize);
  101.     m_Pos += bufsize;
  102.  
  103.     return bufsize;
  104. }
  105.  
  106.  
  107.  
  108. off_t wxZipInputStream::OnSysSeek(off_t seek, wxSeekMode mode)
  109. {
  110.     // NB: since ZIP files don't natively support seeking, we have to 
  111.     //     implement a brute force workaround -- reading all the data
  112.     //     between current and the new position (or between beginning of 
  113.     //     the file and new position...)
  114.  
  115.     off_t nextpos;
  116.  
  117.     switch ( mode )
  118.     {
  119.         case wxFromCurrent : nextpos = seek + m_Pos; break;
  120.         case wxFromStart : nextpos = seek; break;
  121.         case wxFromEnd : nextpos = m_Size - 1 + seek; break;
  122.         default : nextpos = m_Pos; break; /* just to fool compiler, never happens */
  123.     }
  124.  
  125.     size_t toskip = 0;
  126.     if ( nextpos > m_Pos )
  127.     {
  128.         toskip = nextpos - m_Pos;
  129.     }
  130.     else
  131.     {
  132.         unzCloseCurrentFile((unzFile)m_Archive);
  133.         if (unzOpenCurrentFile((unzFile)m_Archive) != UNZ_OK)
  134.         {
  135.             m_lasterror = wxSTREAM_READ_ERROR;
  136.             return m_Pos;
  137.         }
  138.         toskip = nextpos;
  139.     }
  140.         
  141.     if ( toskip > 0 )
  142.     {
  143.         const size_t BUFSIZE = 4096;
  144.         size_t sz;
  145.         char buffer[BUFSIZE];
  146.         while ( toskip > 0 )
  147.         {
  148.             sz = wxMin(toskip, BUFSIZE);
  149.             unzReadCurrentFile((unzFile)m_Archive, buffer, sz);
  150.             toskip -= sz;
  151.         }
  152.     }
  153.  
  154.     m_Pos = nextpos;
  155.     return m_Pos;
  156. }
  157.  
  158. #endif
  159.   // wxUSE_STREAMS && wxUSE_ZIPSTREAM && wxUSE_ZLIB
  160.