📄 filefunctions.cpp
字号:
//// This file is part of the aMule Project.//// Copyright (c) 2003-2008 aMule Team ( admin@amule.org / http://www.amule.org )// Copyright (c) 2002 Merkur ( devs@emule-project.net / http://www.emule-project.net )//// Any parts of this program derived from the xMule, lMule or eMule project,// or contributed by third-party developers are copyrighted by their// respective authors.//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// // You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA//#include <wx/dir.h> // Needed for wxDir#include <wx/fs_zip.h> // Needed for wxZipFSHandler#include <wx/wfstream.h> // wxFileInputStream#include <wx/zipstrm.h> // Needed for wxZipInputStream#include <wx/zstream.h> // Needed for wxZlibInputStream#include <wx/log.h> // Needed for wxSysErrorMsg#ifdef __WXMAC__#include <zlib.h> // Do_not_auto_remove#endif#include <memory> // Needed for std::auto_ptr#include "FileFunctions.h"#include "StringFunctions.h"//// This class assumes that the following line has been executed://// wxConvFileName = &aMuleConvBrokenFileNames;//// This line is necessary so that wxWidgets handles unix file names correctly.//CDirIterator::CDirIterator(const CPath& dir) : wxDir(dir.GetRaw()){}CDirIterator::~CDirIterator(){ }CPath CDirIterator::GetFirstFile(FileType type, const wxString& mask){ if (!IsOpened()) { return CPath(); } wxString fileName; if (!GetFirst(&fileName, mask, type)) { return CPath(); } return CPath(fileName);}CPath CDirIterator::GetNextFile(){ wxString fileName; if (!GetNext(&fileName)) { return CPath(); } return CPath(fileName);}bool CDirIterator::HasSubDirs(const wxString& spec){ // Checking IsOpened() in case we don't have permissions to read that dir. return IsOpened() && wxDir::HasSubDirs(spec);}EFileType GuessFiletype(const wxString& file){ wxFile archive(file, wxFile::read); char head[10] = {0}; int read = archive.Read(head, std::min<off_t>(10, archive.Length())); if (read == wxInvalidOffset) { return EFT_Unknown; } else if ((head[0] == 'P') && (head[1] == 'K')) { // Zip-archives have a header of "PK". return EFT_Zip; } else if (head[0] == '\x1F' && head[1] == '\x8B') { // Gzip-archives have a header of 0x1F8B return EFT_GZip; } else if (head[0] == '\xE0' || head[0] == '\x0E') { // MET files have either of these headers return EFT_Met; } // Check at most the first ten chars, if all are printable, // then we can probably assume it is ascii text-file. for (int i = 0; i < read; ++i) { if (!isprint(head[i]) && !isspace(head[i])) { return EFT_Unknown; } } return EFT_Text;}/** * Replaces the zip-archive with "guarding.p2p" or "ipfilter.dat", * if either of those files are found in the archive. */bool UnpackZipFile(const wxString& file, const wxChar* files[]){ wxZipFSHandler archive; wxString filename = archive.FindFirst( wxT("file:") + file + wxT("#zip:/*"), wxFILE); wxTempFile target(file); while (!filename.IsEmpty() && !target.Length()) { // Extract the filename part of the URI filename = filename.AfterLast(wxT(':')).Lower(); // We only care about the files specified in the array for (size_t i = 0; files[i] && !target.Length(); ++i) { if (files[i] == filename) { std::auto_ptr<wxZipEntry> entry; wxFFileInputStream fileInputStream(file); wxZipInputStream zip(fileInputStream); while (entry.reset(zip.GetNextEntry()), entry.get() != NULL) { // access meta-data wxString name = entry->GetName(); // read 'zip' to access the entry's data if (name == filename) { char buffer[10240]; while (!zip.Eof()) { zip.Read(buffer, sizeof(buffer)); target.Write(buffer, zip.LastRead()); } break; } } } } filename = archive.FindNext(); } if (target.Length()) { target.Commit(); return true; } return false;}/** * Unpacks a GZip file and replaces the archive. */bool UnpackGZipFile(const wxString& file){ char buffer[10240]; wxTempFile target(file); bool write = false;#ifdef __WXMAC__ // AddDebugLogLineM( false, logFileIO, wxT("Reading gzip stream") ); gzFile inputFile = gzopen(filename2char(file), "rb"); if (inputFile != NULL) { write = true; while (int bytesRead = gzread(inputFile, buffer, sizeof(buffer))) { if (bytesRead > 0) { // AddDebugLogLineM( false, logFileIO, wxString::Format(wxT("Read %u bytes"), bytesRead) ); target.Write(buffer, bytesRead); } else if (bytesRead < 0) { wxString errString; int gzerrnum; const char* gzerrstr = gzerror(inputFile, &gzerrnum); if (gzerrnum == Z_ERRNO) { errString = wxSysErrorMsg(); } else { errString = wxString::FromAscii(gzerrstr); } // AddDebugLogLineM( false, logFileIO, wxT("Error reading gzip stream (") + errString + wxT(")") ); write = false; break; } } // AddDebugLogLineM( false, logFileIO, wxT("End reading gzip stream") ); gzclose(inputFile); } else { // AddDebugLogLineM( false, logFileIO, wxT("Error opening gzip file (") + wxString(wxSysErrorMsg()) + wxT(")") ); }#else { // AddDebugLogLineM( false, logFileIO, wxT("Reading gzip stream") ); wxFileInputStream source(file); wxZlibInputStream inputStream(source); while (!inputStream.Eof()) { inputStream.Read(buffer, sizeof(buffer)); // AddDebugLogLineM( false, logFileIO, wxString::Format(wxT("Read %u bytes"),inputStream.LastRead()) ); if (inputStream.LastRead()) { target.Write(buffer, inputStream.LastRead()); } else { break; } }; // AddDebugLogLineM( false, logFileIO, wxT("End reading gzip stream") ); write = inputStream.IsOk() || inputStream.Eof(); }#endif if (write) { target.Commit(); // AddDebugLogLineM( false, logFileIO, wxT("Commited gzip stream") ); } return write;}UnpackResult UnpackArchive(const CPath& path, const wxChar* files[]){ const wxString file = path.GetRaw(); // Attempt to discover the filetype and uncompress EFileType type = GuessFiletype(file); switch (type) { case EFT_Zip: if (UnpackZipFile(file, files)) { // Unpack nested archives if needed. return UnpackResult(true, UnpackArchive(path, files).second); } else { return UnpackResult(false, EFT_Zip); } case EFT_GZip: if (UnpackGZipFile(file)) { // Unpack nested archives if needed. return UnpackResult(true, UnpackArchive(path, files).second); } else { return UnpackResult(false, EFT_GZip); } default: return UnpackResult(false, type); }}// File_checked_for_headers
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -