Patch level : a2.2
Files correlati : xvaga.dll Ricompilazione Demo : [ ] Commento : Aggiornato supporto veri file .zip! git-svn-id: svn://10.65.10.50/trunk@13941 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
916fedd7d3
commit
ee4a4f4bfe
202
xvaga/agasys.cpp
202
xvaga/agasys.cpp
@ -16,81 +16,14 @@
|
|||||||
#include <wx/dir.h>
|
#include <wx/dir.h>
|
||||||
#include <wx/wfstream.h>
|
#include <wx/wfstream.h>
|
||||||
#include <wx/zipstrm.h>
|
#include <wx/zipstrm.h>
|
||||||
|
#include <wx/progdlg.h>
|
||||||
#pragma pack(2)
|
|
||||||
|
|
||||||
struct ZipLocalFileHeader
|
|
||||||
{
|
|
||||||
unsigned short nVersionNeeded;
|
|
||||||
unsigned short nFlags;
|
|
||||||
unsigned short nMethod;
|
|
||||||
unsigned short nLastModTime;
|
|
||||||
unsigned short nLastModDate;
|
|
||||||
unsigned long dwCRC;
|
|
||||||
unsigned long dwCompressedSize;
|
|
||||||
unsigned long dwUncompressedSize;
|
|
||||||
unsigned short nNameLength;
|
|
||||||
unsigned short nExtraLength;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZipDirectoryFileHeader
|
|
||||||
{
|
|
||||||
unsigned short nVersionUsed;
|
|
||||||
ZipLocalFileHeader zlfh;
|
|
||||||
unsigned short nCommentLength;
|
|
||||||
unsigned short nStartDisk;
|
|
||||||
unsigned short nInternalAttr;
|
|
||||||
unsigned long nExternalAttr;
|
|
||||||
unsigned long nLocalHeaderOffset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ZipDirectoryEnd
|
|
||||||
{
|
|
||||||
unsigned short nThisDisk;
|
|
||||||
unsigned short nStartDisk;
|
|
||||||
unsigned short nDiskEntries;
|
|
||||||
unsigned short nTotalEntries;
|
|
||||||
unsigned long nSize;
|
|
||||||
unsigned long nStartOffset;
|
|
||||||
unsigned short nCommentLength;
|
|
||||||
};
|
|
||||||
|
|
||||||
#pragma pack()
|
|
||||||
|
|
||||||
unsigned int aga_ziplist(const char* zipfile, wxArrayString& aFiles)
|
unsigned int aga_ziplist(const char* zipfile, wxArrayString& aFiles)
|
||||||
{
|
{
|
||||||
const unsigned long dwDirectorySignature = 0x02014B50;
|
wxFFileInputStream fin(zipfile);
|
||||||
const unsigned long dwEndDirectorySignature = 0x06054B50;
|
wxZipInputStream zip(fin);
|
||||||
|
for (wxZipEntry* z = zip.GetNextEntry(); z; z = zip.GetNextEntry())
|
||||||
wxFileInputStream fin(zipfile);
|
aFiles.Add(z->GetInternalName());
|
||||||
|
|
||||||
const off_t off = sizeof(ZipDirectoryEnd)+sizeof(dwEndDirectorySignature);
|
|
||||||
fin.SeekI(-off, wxFromEnd);
|
|
||||||
|
|
||||||
unsigned long dwSignature = 0;
|
|
||||||
fin.Read(&dwSignature, sizeof(dwSignature));
|
|
||||||
if (dwSignature != dwEndDirectorySignature)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ZipDirectoryEnd zde;
|
|
||||||
fin.Read(&zde, sizeof(zde));
|
|
||||||
if (zde.nThisDisk < zde.nStartDisk || zde.nDiskEntries == 0 || zde.nSize == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
fin.SeekI(zde.nStartOffset, wxFromStart);
|
|
||||||
|
|
||||||
for (unsigned int f = 0; f < zde.nDiskEntries; f++)
|
|
||||||
{
|
|
||||||
fin.Read(&dwSignature, sizeof(dwSignature));
|
|
||||||
if (dwSignature != dwDirectorySignature)
|
|
||||||
break;
|
|
||||||
|
|
||||||
ZipDirectoryFileHeader zdfh; memset(&zdfh, 0, sizeof(zdfh));
|
|
||||||
fin.Read(&zdfh, sizeof(zdfh));
|
|
||||||
char name[_MAX_PATH]; memset(name, 0, sizeof(name));
|
|
||||||
fin.Read(name, zdfh.zlfh.nNameLength);
|
|
||||||
aFiles.Add(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return aFiles.GetCount();
|
return aFiles.GetCount();
|
||||||
}
|
}
|
||||||
@ -121,9 +54,15 @@ bool aga_unzip(const char* zipfile, const char* destdir)
|
|||||||
{
|
{
|
||||||
wxArrayString aFiles;
|
wxArrayString aFiles;
|
||||||
const unsigned int files = aga_ziplist(zipfile, aFiles);
|
const unsigned int files = aga_ziplist(zipfile, aFiles);
|
||||||
|
|
||||||
|
wxProgressDialog pi("Unzip", "", files, NULL, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
|
||||||
|
|
||||||
for (unsigned int f = 0; f < files; f++)
|
for (unsigned int f = 0; f < files; f++)
|
||||||
{
|
{
|
||||||
const wxString& strFileName = aFiles[f];
|
const wxString& strFileName = aFiles[f];
|
||||||
|
if (!pi.Update(f, strFileName))
|
||||||
|
break;
|
||||||
|
|
||||||
if (wxEndsWithPathSeparator(strFileName)) // Is dir name
|
if (wxEndsWithPathSeparator(strFileName)) // Is dir name
|
||||||
{
|
{
|
||||||
wxString strOutDir = destdir;
|
wxString strOutDir = destdir;
|
||||||
@ -157,23 +96,6 @@ bool aga_unzip(const char* zipfile, const char* destdir)
|
|||||||
// Zip support
|
// Zip support
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <wx/zstream.h>
|
|
||||||
#include <../src/zlib/zlib.h>
|
|
||||||
|
|
||||||
class AgaZlibOutputStream : public wxZlibOutputStream
|
|
||||||
{
|
|
||||||
enum { AGA_COMPRESSION_LEVEL = 9 };
|
|
||||||
|
|
||||||
public:
|
|
||||||
AgaZlibOutputStream(wxOutputStream& stream);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Ricordarsi di taroccare il sorgente della deflateInit in zlib
|
|
||||||
AgaZlibOutputStream::AgaZlibOutputStream(wxOutputStream& stream)
|
|
||||||
: wxZlibOutputStream(stream, AGA_COMPRESSION_LEVEL)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
|
|
||||||
static size_t AddFilesToList(const wxString& strBase, const wxString& strMask, wxArrayString& aFiles)
|
static size_t AddFilesToList(const wxString& strBase, const wxString& strMask, wxArrayString& aFiles)
|
||||||
{
|
{
|
||||||
const size_t n = wxDir::GetAllFiles(strBase, &aFiles, strMask);
|
const size_t n = wxDir::GetAllFiles(strBase, &aFiles, strMask);
|
||||||
@ -181,7 +103,7 @@ static size_t AddFilesToList(const wxString& strBase, const wxString& strMask, w
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void AddFileToZip(const wxString& strPrefix, const wxString& strFile,
|
static void AddFileToZip(const wxString& strPrefix, const wxString& strFile,
|
||||||
wxFileOutputStream& fout, wxFileOutputStream& fdir)
|
wxZipOutputStream& zip)
|
||||||
{
|
{
|
||||||
if (!wxFileExists(strFile))
|
if (!wxFileExists(strFile))
|
||||||
return;
|
return;
|
||||||
@ -197,99 +119,27 @@ static void AddFileToZip(const wxString& strPrefix, const wxString& strFile,
|
|||||||
strRelName += '.';
|
strRelName += '.';
|
||||||
strRelName += strExt;
|
strRelName += strExt;
|
||||||
|
|
||||||
const off_t nStartPos = fout.TellO(); // Memorizzo posizione
|
zip.PutNextEntry(strRelName);
|
||||||
|
wxFileInputStream fin(strFile);
|
||||||
const unsigned long dwLocalSignature = 0x04034B50;
|
zip.Write(fin); // Scrivo file compresso
|
||||||
fout.Write(&dwLocalSignature, sizeof(dwLocalSignature)); // Scrivo PK34
|
|
||||||
ZipLocalFileHeader zlfh; memset(&zlfh, 0, sizeof(zlfh));
|
|
||||||
zlfh.nVersionNeeded = 20; // You need at least pkunzip 2.0
|
|
||||||
zlfh.nFlags = 0x0002; // Deep Hacking ???
|
|
||||||
zlfh.nMethod = 8; // Implode
|
|
||||||
zlfh.nNameLength = strRelName.Length();
|
|
||||||
fout.Write(&zlfh, sizeof(zlfh)); // Scrivo header azzerato
|
|
||||||
fout.Write((const char*)strRelName, zlfh.nNameLength); // Scrivo nome file
|
|
||||||
|
|
||||||
const off_t nDataStart = fout.TellO(); // Memorizzo posizione dati compressi
|
|
||||||
const int nMagicOffset = -4; // Deep hacking :-)
|
|
||||||
|
|
||||||
{
|
|
||||||
wxFileInputStream fin(strFile);
|
|
||||||
AgaZlibOutputStream zout(fout);
|
|
||||||
zout.Write(fin); // Scrivo file compresso
|
|
||||||
zlfh.dwUncompressedSize = fin.TellI();
|
|
||||||
}
|
|
||||||
|
|
||||||
fout.SeekO(nMagicOffset, wxFromEnd);
|
|
||||||
|
|
||||||
zlfh.dwCompressedSize = fout.TellO();
|
|
||||||
zlfh.dwCompressedSize -= nDataStart;
|
|
||||||
zlfh.dwCRC = ComputeFileCRC32(strFile);
|
|
||||||
|
|
||||||
const time_t tMod = ::wxFileModificationTime(strFile);
|
|
||||||
const struct tm* t = localtime(&tMod);
|
|
||||||
if (t != NULL)
|
|
||||||
{
|
|
||||||
zlfh.nLastModDate = t->tm_mday + ((t->tm_mon+1) << 5) + ((t->tm_year-80) << 9);
|
|
||||||
zlfh.nLastModTime = t->tm_sec/2 + (t->tm_min << 5) + (t->tm_hour << 11);
|
|
||||||
}
|
|
||||||
|
|
||||||
fout.SeekO(nStartPos+sizeof(dwLocalSignature), wxFromStart);
|
|
||||||
fout.Write(&zlfh, sizeof(zlfh));
|
|
||||||
// fout.Write((const char*)strRelName, strRelName.Length());
|
|
||||||
|
|
||||||
// Deep Hacking Here!
|
|
||||||
// const wxByte pkHeader = 0x85;
|
|
||||||
// fout.Write(&pkHeader, 1);
|
|
||||||
|
|
||||||
fout.SeekO(nMagicOffset, wxFromEnd);
|
|
||||||
|
|
||||||
ZipDirectoryFileHeader zdfh; memset(&zdfh, 0, sizeof(zdfh));
|
|
||||||
zdfh.nVersionUsed = zlfh.nVersionNeeded;
|
|
||||||
memcpy(&zdfh.zlfh, &zlfh, sizeof(zlfh));
|
|
||||||
zdfh.nLocalHeaderOffset = nStartPos;
|
|
||||||
|
|
||||||
const unsigned long dwDirectorySignature = 0x02014B50; // Scrivo PK12
|
|
||||||
fdir.Write(&dwDirectorySignature, sizeof(dwDirectorySignature));
|
|
||||||
fdir.Write(&zdfh, sizeof(zdfh)); // Scrivo entry directory
|
|
||||||
fdir.Write((const char*)strRelName, strRelName.Length());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool AddFilesToZip(const wxString& strBase, wxArrayString& aFiles, const char* zipfile)
|
static bool AddFilesToZip(const wxString& strBase, wxArrayString& aFiles, const char* zipfile)
|
||||||
{
|
{
|
||||||
const char* zipdir = "zipdir.tmp";
|
wxFFileOutputStream out(zipfile);
|
||||||
|
wxZipOutputStream zip(out);
|
||||||
|
|
||||||
wxFileOutputStream fout(zipfile);
|
const size_t nFiles = aFiles.GetCount();
|
||||||
|
wxProgressDialog pi("Zip", "", nFiles, NULL, wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
|
||||||
|
|
||||||
off_t nDirSize = 0, nDirStart = 0;
|
for (size_t i = 0; i < nFiles; i++)
|
||||||
|
{
|
||||||
if (aFiles.GetCount() > 0) // Dummy test
|
const wxString& str = aFiles[i];
|
||||||
{
|
if (!pi.Update(i, str))
|
||||||
wxFileOutputStream fdir(zipdir);
|
break;
|
||||||
for (size_t i = 0; i < aFiles.GetCount(); i++)
|
AddFileToZip(strBase, str, zip);
|
||||||
AddFileToZip(strBase, aFiles[i], fout, fdir);
|
|
||||||
nDirSize = fdir.TellO();
|
|
||||||
nDirStart = fout.TellO();
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
if (nDirSize > 0)
|
|
||||||
{
|
|
||||||
wxFileInputStream fdir(zipdir);
|
|
||||||
fout.Write(fdir); // Append central directory
|
|
||||||
|
|
||||||
ZipDirectoryEnd zde; memset(&zde, 0, sizeof(zde));
|
|
||||||
zde.nDiskEntries = zde.nTotalEntries = aFiles.GetCount();
|
|
||||||
zde.nSize = nDirSize;
|
|
||||||
zde.nStartOffset = nDirStart;
|
|
||||||
|
|
||||||
const unsigned long dwEndDirectorySignature = 0x06054B50;
|
|
||||||
fout.Write(&dwEndDirectorySignature, sizeof(dwEndDirectorySignature));
|
|
||||||
fout.Write(&zde, sizeof(zde));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nDirSize > 0)
|
|
||||||
wxRemoveFile(zipdir);
|
|
||||||
|
|
||||||
return (nDirSize > 0 || aFiles.GetCount() == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool aga_zip(const char* srcfiles, const char* zipfile)
|
bool aga_zip(const char* srcfiles, const char* zipfile)
|
||||||
|
@ -797,7 +797,7 @@ void TwxWindow::OnChar(wxKeyEvent& event)
|
|||||||
case WXK_NUMPAD9:
|
case WXK_NUMPAD9:
|
||||||
event.Skip();
|
event.Skip();
|
||||||
return;
|
return;
|
||||||
case WXK_NUMPAD_DECIMAL: // ??? Non arriva mai
|
case WXK_NUMPAD_DECIMAL: // Arriva solo dalla 3.6.3 in poi
|
||||||
case WXK_DECIMAL: // ??? Arriva sia '.' sia WXK_DECIMAL=340
|
case WXK_DECIMAL: // ??? Arriva sia '.' sia WXK_DECIMAL=340
|
||||||
if (nSkipNextDotKey == 0)
|
if (nSkipNextDotKey == 0)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user