1cdf0e10cSrcweir /************************************************************************* 2cdf0e10cSrcweir * 3cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4cdf0e10cSrcweir * 5cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6cdf0e10cSrcweir * 7cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8cdf0e10cSrcweir * 9cdf0e10cSrcweir * This file is part of OpenOffice.org. 10cdf0e10cSrcweir * 11cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14cdf0e10cSrcweir * 15cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20cdf0e10cSrcweir * 21cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25cdf0e10cSrcweir * 26cdf0e10cSrcweir ************************************************************************/ 27cdf0e10cSrcweir 28cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29cdf0e10cSrcweir #include "precompiled_shell.hxx" 30cdf0e10cSrcweir #include "zipexcptn.hxx" 31cdf0e10cSrcweir #include "internal/zipfile.hxx" 32cdf0e10cSrcweir #include "internal/global.hxx" 33cdf0e10cSrcweir 34cdf0e10cSrcweir #include <malloc.h> 35cdf0e10cSrcweir #include <algorithm> 36cdf0e10cSrcweir #include <functional> 37cdf0e10cSrcweir 38cdf0e10cSrcweir #include <string.h> 39cdf0e10cSrcweir 40cdf0e10cSrcweir #ifdef OS2 41cdf0e10cSrcweir #include <alloca.h> 42cdf0e10cSrcweir #define _alloca alloca 43cdf0e10cSrcweir #define ERROR_NOT_ENOUGH_MEMORY 8 44cdf0e10cSrcweir #endif 45cdf0e10cSrcweir 46cdf0e10cSrcweir namespace internal 47cdf0e10cSrcweir { 48cdf0e10cSrcweir /* for case in-sensitive string comparison */ 49cdf0e10cSrcweir struct stricmp : public std::unary_function<std::string, bool> 50cdf0e10cSrcweir { 51cdf0e10cSrcweir stricmp(const std::string& str) : str_(str) 52cdf0e10cSrcweir {} 53cdf0e10cSrcweir 54cdf0e10cSrcweir bool operator() (const std::string& other) 55cdf0e10cSrcweir { return (0 == _stricmp(str_.c_str(), other.c_str())); } 56cdf0e10cSrcweir 57cdf0e10cSrcweir std::string str_; 58cdf0e10cSrcweir }; 59cdf0e10cSrcweir } // namespace internal 60cdf0e10cSrcweir 61cdf0e10cSrcweir /** Checks whether a file is a zip file or not 62cdf0e10cSrcweir 63cdf0e10cSrcweir @precond The given parameter must be a string with length > 0 64cdf0e10cSrcweir The file must exist 65cdf0e10cSrcweir The file must be readable for the current user 66cdf0e10cSrcweir 67cdf0e10cSrcweir @returns true if the file is a zip file 68cdf0e10cSrcweir false if the file is not a zip file 69cdf0e10cSrcweir 70cdf0e10cSrcweir @throws ParameterException if the given file name is empty 71cdf0e10cSrcweir IOException if the specified file doesn't exist 72cdf0e10cSrcweir AccessViolationException if read access to the file is denied 73cdf0e10cSrcweir */ 74cdf0e10cSrcweir bool ZipFile::IsZipFile(const std::string& /*FileName*/) 75cdf0e10cSrcweir { 76cdf0e10cSrcweir return true; 77cdf0e10cSrcweir } 78cdf0e10cSrcweir 79cdf0e10cSrcweir bool ZipFile::IsZipFile(void* /*stream*/) 80cdf0e10cSrcweir { 81cdf0e10cSrcweir return true; 82cdf0e10cSrcweir } 83cdf0e10cSrcweir 84cdf0e10cSrcweir 85cdf0e10cSrcweir /** Returns wheter the version of the specified zip file may be uncompressed with the 86cdf0e10cSrcweir currently used zlib version or not 87cdf0e10cSrcweir 88cdf0e10cSrcweir @precond The given parameter must be a string with length > 0 89cdf0e10cSrcweir The file must exist 90cdf0e10cSrcweir The file must be readable for the current user 91cdf0e10cSrcweir The file must be a valid zip file 92cdf0e10cSrcweir 93cdf0e10cSrcweir @returns true if the file may be uncompressed with the currently used zlib 94cdf0e10cSrcweir false if the file may not be uncompressed with the currently used zlib 95cdf0e10cSrcweir 96cdf0e10cSrcweir @throws ParameterException if the given file name is empty 97cdf0e10cSrcweir IOException if the specified file doesn't exist or is no zip file 98cdf0e10cSrcweir AccessViolationException if read access to the file is denied 99cdf0e10cSrcweir */ 100cdf0e10cSrcweir bool ZipFile::IsValidZipFileVersionNumber(const std::string& /*FileName*/) 101cdf0e10cSrcweir { 102cdf0e10cSrcweir return true; 103cdf0e10cSrcweir } 104cdf0e10cSrcweir 105cdf0e10cSrcweir bool ZipFile::IsValidZipFileVersionNumber(void* /* stream*/) 106cdf0e10cSrcweir { 107cdf0e10cSrcweir return true; 108cdf0e10cSrcweir } 109cdf0e10cSrcweir 110cdf0e10cSrcweir 111cdf0e10cSrcweir /** Constructs a zip file from a zip file 112cdf0e10cSrcweir 113cdf0e10cSrcweir @precond The given parameter must be a string with length > 0 114cdf0e10cSrcweir The file must exist 115cdf0e10cSrcweir The file must be readable for the current user 116cdf0e10cSrcweir 117cdf0e10cSrcweir @throws ParameterException if the given file name is empty 118cdf0e10cSrcweir IOException if the specified file doesn't exist or is no valid zip file 119cdf0e10cSrcweir AccessViolationException if read access to the file is denied 120cdf0e10cSrcweir WrongZipVersionException if the zip file cannot be uncompressed 121cdf0e10cSrcweir with the used zlib version 122cdf0e10cSrcweir */ 123cdf0e10cSrcweir ZipFile::ZipFile(const std::string& FileName) 124cdf0e10cSrcweir { 125cdf0e10cSrcweir m_uzFile = unzOpen(FileName.c_str()); 126cdf0e10cSrcweir 127cdf0e10cSrcweir if (0 == m_uzFile) 128cdf0e10cSrcweir throw IOException(-1); 129cdf0e10cSrcweir } 130cdf0e10cSrcweir 131cdf0e10cSrcweir ZipFile::ZipFile(void* stream, zlib_filefunc_def* fa) 132cdf0e10cSrcweir { 133cdf0e10cSrcweir fa->opaque = stream; 134cdf0e10cSrcweir m_uzFile = unzOpen2((const char *)NULL, fa); 135cdf0e10cSrcweir 136cdf0e10cSrcweir if (0 == m_uzFile) 137cdf0e10cSrcweir throw IOException(-1); 138cdf0e10cSrcweir } 139cdf0e10cSrcweir 140cdf0e10cSrcweir 141cdf0e10cSrcweir /** Destroys a zip file 142cdf0e10cSrcweir */ 143cdf0e10cSrcweir ZipFile::~ZipFile() 144cdf0e10cSrcweir { 145cdf0e10cSrcweir unzClose(m_uzFile); 146cdf0e10cSrcweir } 147cdf0e10cSrcweir 148cdf0e10cSrcweir /** Provides an interface to read the uncompressed data of a content of the zip file 149cdf0e10cSrcweir 150cdf0e10cSrcweir @precond The specified content must exist in this file 151cdf0e10cSrcweir ppstm must not be NULL 152cdf0e10cSrcweir */ 153cdf0e10cSrcweir void ZipFile::GetUncompressedContent( 154cdf0e10cSrcweir const std::string& ContentName, /*inout*/ ZipContentBuffer_t& ContentBuffer) 155cdf0e10cSrcweir { 156cdf0e10cSrcweir int rc = unzLocateFile(m_uzFile, ContentName.c_str(), 0); 157cdf0e10cSrcweir 158cdf0e10cSrcweir if (UNZ_END_OF_LIST_OF_FILE == rc) 159cdf0e10cSrcweir throw ZipContentMissException(rc); 160cdf0e10cSrcweir 161cdf0e10cSrcweir unz_file_info finfo; 162cdf0e10cSrcweir unzGetCurrentFileInfo(m_uzFile, &finfo, 0, 0, 0, 0, 0, 0); 163cdf0e10cSrcweir 164cdf0e10cSrcweir ContentBuffer.resize(finfo.uncompressed_size); 165cdf0e10cSrcweir 166cdf0e10cSrcweir rc = unzOpenCurrentFile(m_uzFile); 167cdf0e10cSrcweir 168cdf0e10cSrcweir if (UNZ_OK != rc) 169cdf0e10cSrcweir throw ZipException(rc); 170cdf0e10cSrcweir 171cdf0e10cSrcweir rc = unzReadCurrentFile(m_uzFile, &ContentBuffer[0], finfo.uncompressed_size); 172cdf0e10cSrcweir 173cdf0e10cSrcweir if (rc < 0) 174cdf0e10cSrcweir throw ZipException(rc); 175cdf0e10cSrcweir 176cdf0e10cSrcweir rc = unzCloseCurrentFile(m_uzFile); 177cdf0e10cSrcweir 178cdf0e10cSrcweir if (rc < 0) 179cdf0e10cSrcweir throw ZipException(rc); 180cdf0e10cSrcweir } 181cdf0e10cSrcweir 182cdf0e10cSrcweir /** Returns a list with the content names contained within this file 183cdf0e10cSrcweir 184cdf0e10cSrcweir */ 185cdf0e10cSrcweir ZipFile::DirectoryPtr_t ZipFile::GetDirectory() const 186cdf0e10cSrcweir { 187cdf0e10cSrcweir DirectoryPtr_t dir(new Directory_t()); 188cdf0e10cSrcweir 189cdf0e10cSrcweir long lmax = GetFileLongestFileNameLength() + 1; 190cdf0e10cSrcweir char* szFileName = reinterpret_cast<char*>(_alloca(lmax)); 191cdf0e10cSrcweir 192cdf0e10cSrcweir if (!szFileName) 193cdf0e10cSrcweir throw ZipException(ERROR_NOT_ENOUGH_MEMORY); 194cdf0e10cSrcweir 195cdf0e10cSrcweir int rc = unzGoToFirstFile(m_uzFile); 196cdf0e10cSrcweir 197cdf0e10cSrcweir while (UNZ_OK == rc && UNZ_END_OF_LIST_OF_FILE != rc) 198cdf0e10cSrcweir { 199*5448f169SMichael Stahl unz_file_info finfo; 200cdf0e10cSrcweir unzGetCurrentFileInfo( 201*5448f169SMichael Stahl m_uzFile, &finfo, szFileName, lmax, 0, 0, 0, 0); 202cdf0e10cSrcweir 203cdf0e10cSrcweir dir->push_back(szFileName); 204cdf0e10cSrcweir 205cdf0e10cSrcweir rc = unzGoToNextFile(m_uzFile); 206cdf0e10cSrcweir } 207cdf0e10cSrcweir 208cdf0e10cSrcweir if (UNZ_OK != rc && UNZ_END_OF_LIST_OF_FILE != rc) 209cdf0e10cSrcweir throw ZipException(rc); 210cdf0e10cSrcweir 211cdf0e10cSrcweir return dir; 212cdf0e10cSrcweir } 213cdf0e10cSrcweir 214cdf0e10cSrcweir /** Convinience query function may even realized with 215cdf0e10cSrcweir iterating over a ZipFileDirectory returned by 216cdf0e10cSrcweir GetDirectory */ 217cdf0e10cSrcweir bool ZipFile::HasContent(const std::string& ContentName) const 218cdf0e10cSrcweir { 219cdf0e10cSrcweir //#i34314# we need to compare package content names 220cdf0e10cSrcweir //case in-sensitive as it is not defined that such 221cdf0e10cSrcweir //names must be handled case sensitive 222cdf0e10cSrcweir DirectoryPtr_t dir = GetDirectory(); 223cdf0e10cSrcweir Directory_t::iterator iter = 224cdf0e10cSrcweir std::find_if(dir->begin(), dir->end(), internal::stricmp(ContentName)); 225cdf0e10cSrcweir 226cdf0e10cSrcweir return (iter != dir->end()); 227cdf0e10cSrcweir } 228cdf0e10cSrcweir 229cdf0e10cSrcweir 230cdf0e10cSrcweir /** Returns the length of the longest file name 231cdf0e10cSrcweir in the current zip file 232cdf0e10cSrcweir */ 233cdf0e10cSrcweir long ZipFile::GetFileLongestFileNameLength() const 234cdf0e10cSrcweir { 235cdf0e10cSrcweir long lmax = 0; 236cdf0e10cSrcweir unz_file_info finfo; 237cdf0e10cSrcweir 238cdf0e10cSrcweir int rc = unzGoToFirstFile(m_uzFile); 239cdf0e10cSrcweir 240cdf0e10cSrcweir while (UNZ_OK == rc && UNZ_END_OF_LIST_OF_FILE != rc) 241cdf0e10cSrcweir { 242cdf0e10cSrcweir unzGetCurrentFileInfo(m_uzFile, &finfo, 0, 0, 0, 0, 0, 0); 243cdf0e10cSrcweir lmax = std::max<long>(lmax, finfo.size_filename); 244cdf0e10cSrcweir rc = unzGoToNextFile(m_uzFile); 245cdf0e10cSrcweir } 246cdf0e10cSrcweir 247cdf0e10cSrcweir if (UNZ_OK != rc && UNZ_END_OF_LIST_OF_FILE != rc) 248cdf0e10cSrcweir throw ZipException(rc); 249cdf0e10cSrcweir 250cdf0e10cSrcweir return lmax; 251cdf0e10cSrcweir } 252cdf0e10cSrcweir 253