Update ooo320-m1
[ooovba.git] / shell / source / all / zipfile / zipfile.cxx
blobd5b6ef6e06b346ac8668491a7c8e787bd8b13f00
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: zipfile.cxx,v $
10 * $Revision: 1.8 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_shell.hxx"
33 #include "zipexcptn.hxx"
34 #include "internal/zipfile.hxx"
35 #include "internal/global.hxx"
37 #include <malloc.h>
38 #include <algorithm>
39 #include <functional>
41 #include <string.h>
43 #ifdef OS2
44 #include <alloca.h>
45 #define _alloca alloca
46 #define ERROR_NOT_ENOUGH_MEMORY 8
47 #endif
49 namespace internal
51 /* for case in-sensitive string comparison */
52 struct stricmp : public std::unary_function<std::string, bool>
54 stricmp(const std::string& str) : str_(str)
57 bool operator() (const std::string& other)
58 { return (0 == _stricmp(str_.c_str(), other.c_str())); }
60 std::string str_;
62 } // namespace internal
64 /** Checks whether a file is a zip file or not
66 @precond The given parameter must be a string with length > 0
67 The file must exist
68 The file must be readable for the current user
70 @returns true if the file is a zip file
71 false if the file is not a zip file
73 @throws ParameterException if the given file name is empty
74 IOException if the specified file doesn't exist
75 AccessViolationException if read access to the file is denied
77 bool ZipFile::IsZipFile(const std::string& /*FileName*/)
79 return true;
82 bool ZipFile::IsZipFile(void* /*stream*/)
84 return true;
88 /** Returns wheter the version of the specified zip file may be uncompressed with the
89 currently used zlib version or not
91 @precond The given parameter must be a string with length > 0
92 The file must exist
93 The file must be readable for the current user
94 The file must be a valid zip file
96 @returns true if the file may be uncompressed with the currently used zlib
97 false if the file may not be uncompressed with the currently used zlib
99 @throws ParameterException if the given file name is empty
100 IOException if the specified file doesn't exist or is no zip file
101 AccessViolationException if read access to the file is denied
103 bool ZipFile::IsValidZipFileVersionNumber(const std::string& /*FileName*/)
105 return true;
108 bool ZipFile::IsValidZipFileVersionNumber(void* /* stream*/)
110 return true;
114 /** Constructs a zip file from a zip file
116 @precond The given parameter must be a string with length > 0
117 The file must exist
118 The file must be readable for the current user
120 @throws ParameterException if the given file name is empty
121 IOException if the specified file doesn't exist or is no valid zip file
122 AccessViolationException if read access to the file is denied
123 WrongZipVersionException if the zip file cannot be uncompressed
124 with the used zlib version
126 ZipFile::ZipFile(const std::string& FileName)
128 m_uzFile = unzOpen(FileName.c_str());
130 if (0 == m_uzFile)
131 throw IOException(-1);
134 ZipFile::ZipFile(void* stream, zlib_filefunc_def* fa)
136 fa->opaque = stream;
137 m_uzFile = unzOpen2((const char *)NULL, fa);
139 if (0 == m_uzFile)
140 throw IOException(-1);
144 /** Destroys a zip file
146 ZipFile::~ZipFile()
148 unzClose(m_uzFile);
151 /** Provides an interface to read the uncompressed data of a content of the zip file
153 @precond The specified content must exist in this file
154 ppstm must not be NULL
156 void ZipFile::GetUncompressedContent(
157 const std::string& ContentName, /*inout*/ ZipContentBuffer_t& ContentBuffer)
159 int rc = unzLocateFile(m_uzFile, ContentName.c_str(), 0);
161 if (UNZ_END_OF_LIST_OF_FILE == rc)
162 throw ZipContentMissException(rc);
164 unz_file_info finfo;
165 unzGetCurrentFileInfo(m_uzFile, &finfo, 0, 0, 0, 0, 0, 0);
167 ContentBuffer.resize(finfo.uncompressed_size);
169 rc = unzOpenCurrentFile(m_uzFile);
171 if (UNZ_OK != rc)
172 throw ZipException(rc);
174 rc = unzReadCurrentFile(m_uzFile, &ContentBuffer[0], finfo.uncompressed_size);
176 if (rc < 0)
177 throw ZipException(rc);
179 rc = unzCloseCurrentFile(m_uzFile);
181 if (rc < 0)
182 throw ZipException(rc);
185 /** Returns a list with the content names contained within this file
188 ZipFile::DirectoryPtr_t ZipFile::GetDirectory() const
190 DirectoryPtr_t dir(new Directory_t());
192 long lmax = GetFileLongestFileNameLength() + 1;
193 char* szFileName = reinterpret_cast<char*>(_alloca(lmax));
195 if (!szFileName)
196 throw ZipException(ERROR_NOT_ENOUGH_MEMORY);
198 int rc = unzGoToFirstFile(m_uzFile);
200 while (UNZ_OK == rc && UNZ_END_OF_LIST_OF_FILE != rc)
202 unzGetCurrentFileInfo(
203 m_uzFile, 0, szFileName, lmax, 0, 0, 0, 0);
205 dir->push_back(szFileName);
207 rc = unzGoToNextFile(m_uzFile);
210 if (UNZ_OK != rc && UNZ_END_OF_LIST_OF_FILE != rc)
211 throw ZipException(rc);
213 return dir;
216 /** Convinience query function may even realized with
217 iterating over a ZipFileDirectory returned by
218 GetDirectory */
219 bool ZipFile::HasContent(const std::string& ContentName) const
221 //#i34314# we need to compare package content names
222 //case in-sensitive as it is not defined that such
223 //names must be handled case sensitive
224 DirectoryPtr_t dir = GetDirectory();
225 Directory_t::iterator iter =
226 std::find_if(dir->begin(), dir->end(), internal::stricmp(ContentName));
228 return (iter != dir->end());
232 /** Returns the length of the longest file name
233 in the current zip file
235 long ZipFile::GetFileLongestFileNameLength() const
237 long lmax = 0;
238 unz_file_info finfo;
240 int rc = unzGoToFirstFile(m_uzFile);
242 while (UNZ_OK == rc && UNZ_END_OF_LIST_OF_FILE != rc)
244 unzGetCurrentFileInfo(m_uzFile, &finfo, 0, 0, 0, 0, 0, 0);
245 lmax = std::max<long>(lmax, finfo.size_filename);
246 rc = unzGoToNextFile(m_uzFile);
249 if (UNZ_OK != rc && UNZ_END_OF_LIST_OF_FILE != rc)
250 throw ZipException(rc);
252 return lmax;