campo-sirio/xvaga/agasys.cpp
luca 14bf3ae259 Patch level :2.1 112
Files correlati     :xvagadll.dll
Ricompilazione Demo : [ ]
Commento            :
AO21036
Non si riesce a fare il backup in quanto viene sempre restituito il messaggio: "Si ? verificato un errore di accesso al disco: verificare lo spazio disponibile"; premesso che sul disco c'? pi? di 1Gb di spazio libero. Il ripristino invece funziona correttamente.


git-svn-id: svn://10.65.10.50/trunk@12309 c028cbd2-c16b-5b4b-a496-9718f37d4682
2004-09-13 13:49:57 +00:00

324 lines
8.5 KiB
C++
Executable File

#include "wxinc.h"
#ifdef LINUX
#include "xvt_type.h"
#include "incstr.h"
#else
#include <fstream.h>
#endif
#include "agasys.h"
///////////////////////////////////////////////////////////
// Unzip support
///////////////////////////////////////////////////////////
#include <wx/dir.h>
#include <wx/wfstream.h>
#include <wx/zipstrm.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)
{
const unsigned long dwDirectorySignature = 0x02014B50;
const unsigned long dwEndDirectorySignature = 0x06054B50;
wxFileInputStream fin(zipfile);
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();
}
int aga_find_slash(const wxString& path, int from)
{
for (int i = from; path[i]; i++)
if (wxIsPathSeparator(path[i]))
return i;
return -1;
}
void aga_create_dir(wxString strPath)
{
if (!wxEndsWithPathSeparator(strPath))
strPath += wxFILE_SEP_PATH;
for (int i = aga_find_slash(strPath, 0); i > 0; i = aga_find_slash(strPath, i+1))
{
const wxString strDir = strPath.Mid(0,i);
if (!::wxDirExists(strDir))
::wxMkdir(strDir);
}
}
bool aga_unzip(const char* zipfile, const char* destdir)
{
wxArrayString aFiles;
const unsigned int files = aga_ziplist(zipfile, aFiles);
for (unsigned int f = 0; f < files; f++)
{
const wxString& strFileName = aFiles[f];
if (wxEndsWithPathSeparator(strFileName)) // Is dir name
{
wxString strOutDir = destdir;
if (!wxEndsWithPathSeparator(strOutDir))
strOutDir += wxFILE_SEP_PATH;
strOutDir += strFileName;
if (!::wxDirExists(strOutDir))
::wxMkdir(strOutDir);
}
else
{
wxZipInputStream fin(zipfile, strFileName);
wxString strOutFile = destdir;
if (!wxEndsWithPathSeparator(strOutFile) && !wxIsPathSeparator(strFileName[0]))
strOutFile += wxFILE_SEP_PATH;
strOutFile += strFileName;
wxString strPath;
::wxSplitPath(strOutFile, &strPath, NULL, NULL);
aga_create_dir(strPath);
wxFileOutputStream fout(strOutFile);
fout.Write(fin);
}
}
return files > 0;
}
///////////////////////////////////////////////////////////
// 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)
{
const size_t n = wxDir::GetAllFiles(strBase, &aFiles, strMask);
return n;
}
static void AddFileToZip(const wxString& strPrefix, const wxString& strFile,
wxFileOutputStream& fout, wxFileOutputStream& fdir)
{
if (!wxFileExists(strFile))
return;
wxString strPath, strName, strExt;
wxSplitPath(strFile, &strPath, &strName, &strExt);
wxString strRelName;
strRelName = strPath.Mid(strPrefix.Length());
if (!strRelName.IsEmpty())
strRelName += '/';
strRelName += strName;
strRelName += '.';
strRelName += strExt;
const off_t nStartPos = fout.TellO(); // Memorizzo posizione
const unsigned long dwLocalSignature = 0x04034B50;
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)
{
const char* zipdir = "zipdir.tmp";
wxFileOutputStream fout(zipfile);
off_t nDirSize = 0, nDirStart = 0;
if (aFiles.GetCount() > 0) // Dummy test
{
wxFileOutputStream fdir(zipdir);
for (size_t i = 0; i < aFiles.GetCount(); i++)
AddFileToZip(strBase, aFiles[i], fout, fdir);
nDirSize = fdir.TellO();
nDirStart = fout.TellO();
}
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)
{
wxString strBase, strMask, strExt;
wxSplitPath(srcfiles, &strBase, &strMask, &strExt);
strMask += '.';
strMask += strExt;
wxArrayString aFiles;
AddFilesToList(strBase, strMask, aFiles);
return AddFilesToZip(strBase, aFiles, zipfile);
}
bool aga_zip_filelist(const char* filelist, const char* zipfile)
{
wxArrayString aFiles;
ifstream fin(filelist);
while (!fin.eof())
{
char name[_MAX_PATH];
fin.getline(name, sizeof(name));
if (*name)
aFiles.Add(name);
else
break;
}
return AddFilesToZip("", aFiles, zipfile);
}