1 /*
2  * Copyright (C) 2003-2006 Tommi Maekitalo
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * As a special exception, you may use this file as part of a free
10  * software library without restriction. Specifically, if other files
11  * instantiate templates or use macros or inline functions from this
12  * file, or you compile this file and link it with other files to
13  * produce an executable, this file does not by itself cause the
14  * resulting executable to be covered by the GNU General Public
15  * License. This exception does not however invalidate any other
16  * reasons why the executable file might be covered by the GNU Library
17  * General Public License.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
27  */
28 
29 
30 #include "tnt/unzipfile.h"
31 #include <sstream>
32 #include "unzip.h"
33 
34 namespace tnt
35 {
36   namespace
37   {
checkError(int ret,const char * function)38     int checkError(int ret, const char* function)
39     {
40       if (ret < 0)
41       {
42         switch (ret)
43         {
44           case UNZ_END_OF_LIST_OF_FILE:
45             throw unzipEndOfListOfFile(function);
46 
47           case UNZ_PARAMERROR:
48             throw unzipParamError(function);
49 
50           case UNZ_BADZIPFILE:
51             throw unzipBadZipFile(function);
52 
53           case UNZ_INTERNALERROR:
54             throw unzipInternalError(function);
55 
56           case UNZ_CRCERROR:
57             throw unzipCrcError(function);
58         }
59 
60         throw unzipError(ret, "unknown error", function);
61       }
62       return ret;
63     }
64 
65   }
66 
formatMsg(int err,const char * msg,const char * function)67   std::string unzipError::formatMsg(int err, const char* msg, const char* function)
68   {
69     std::ostringstream s;
70     s << "unzip-error " << err;
71     if (function && function[0])
72       s << " in function \"" << function << '"';
73     s << ": " << msg;
74     return s.str();
75   }
76 
unzipEndOfListOfFile(const char * function)77   unzipEndOfListOfFile::unzipEndOfListOfFile(const char* function)
78     : unzipError(UNZ_END_OF_LIST_OF_FILE, "end of list of file", function)
79     { }
80 
unzipParamError(const char * function)81   unzipParamError::unzipParamError(const char* function)
82     : unzipError(UNZ_PARAMERROR, "parameter error", function)
83     { }
84 
unzipBadZipFile(const char * function)85   unzipBadZipFile::unzipBadZipFile(const char* function)
86     : unzipError(UNZ_PARAMERROR, "bad zip file", function)
87     { }
88 
unzipInternalError(const char * function)89   unzipInternalError::unzipInternalError(const char* function)
90     : unzipError(UNZ_PARAMERROR, "internal error", function)
91     { }
92 
unzipCrcError(const char * function)93   unzipCrcError::unzipCrcError(const char* function)
94     : unzipError(UNZ_PARAMERROR, "crc error", function)
95     { }
96 
97   //////////////////////////////////////////////////////////////////////
98   // unzipFile
99   //
100 
101   struct unzipFile::unzFileStruct
102   {
103     unzFile file;
104   };
105 
open(const std::string & path)106   void unzipFile::open(const std::string& path)
107   {
108     close();
109     file = new unzFileStruct;
110     if (!(file->file = ::unzOpen(path.c_str())))
111     {
112       delete file;
113       file = 0;
114       throw unzipFileNotFound(path);
115     }
116   }
117 
close()118   void unzipFile::close()
119   {
120     if (file)
121     {
122       unzClose(file->file);
123       delete file;
124       file = 0;
125     }
126   }
127 
~unzipFile()128   unzipFile::~unzipFile()
129   {
130     if (file)
131     {
132       unzClose(file->file);
133       delete file;
134     }
135   }
136 
goToFirstFile()137   void unzipFile::goToFirstFile()
138   {
139     checkError(::unzGoToFirstFile(file->file), "unzGoToFirstFile");
140   }
141 
goToNextFile()142   void unzipFile::goToNextFile()
143   {
144     checkError(::unzGoToNextFile(file->file), "unzGoToNextFile");
145   }
146 
locateFile(const std::string & fileName,bool caseSensitivity)147   void unzipFile::locateFile(const std::string& fileName, bool caseSensitivity)
148   {
149     checkError(::unzLocateFile(file->file, fileName.c_str(), caseSensitivity ? 1 : 0), "unzLocateFile");
150   }
151 
openCurrentFile()152   void unzipFile::openCurrentFile()
153   {
154     checkError(::unzOpenCurrentFile(file->file), "unzOpenCurrentFile");
155   }
156 
openCurrentFile(const std::string & pw)157   void unzipFile::openCurrentFile(const std::string& pw)
158   {
159     checkError(::unzOpenCurrentFilePassword(file->file, pw.c_str()), "unzOpenCurrentFilePassword");
160   }
161 
closeCurrentFile()162   void unzipFile::closeCurrentFile()
163   {
164     checkError(::unzCloseCurrentFile(file->file), "unzCloseCurrentFile");
165   }
166 
readCurrentFile(void * buf,unsigned len)167   int unzipFile::readCurrentFile(void* buf, unsigned len)
168   {
169     return checkError(::unzReadCurrentFile(file->file, buf, len), "unzReadCurrentFile");
170   }
171 
172   //////////////////////////////////////////////////////////////////////
173   // unzipFileStreamBuf
174   //
175 
overflow(unzipFileStreamBuf::int_type c)176   unzipFileStreamBuf::int_type unzipFileStreamBuf::overflow(unzipFileStreamBuf::int_type c)
177   { return traits_type::eof(); }
178 
underflow()179   unzipFileStreamBuf::int_type unzipFileStreamBuf::underflow()
180   {
181     int n = file.readCurrentFile(buffer, sizeof(buffer));
182     if (n == 0)
183       return traits_type::eof();
184     setg(buffer, buffer, buffer + n);
185     return traits_type::to_int_type(buffer[0]);
186   }
187 
sync()188   int unzipFileStreamBuf::sync()
189   {
190     return 0;
191   }
192 }
193