📄 zippie.cpp
字号:
// if (szDir.IsEmpty())
// if (!ZipPlatform::GetCurrentDirectory(szDir))
// return;
struct AddDirectoryInfo adi(l);
adi.m_bAddEmpty = bAddEmpty;
adi.m_bRecursive = bRecursive;
adi.m_lpszFile = zpc.GetFileName();
AddDirectory(szDir, adi, !bFullPath); // when not full path is specified for a single file with a path, do not add a directory then
}
void FindInZip(CZipArchive& zip, FILELIST& l, CZipWordArray& n)
{
for (FILELISTIT it = l.begin(); it != l.end(); ++it)
zip.FindMatches(*it, n);
}
void ProcessData(CZipArchive& zip, CCmdLine& cmd, CZipWordArray& vRevised, bool bExtract)
{
if (cmd.HasSwitch(bExtract ? "-xa" : "-da"))
{
int iMax = zip.GetCount();
for (int i = 0; i < iMax; i++)
vRevised.Add(i);
}
else
{
CZipWordArray numbers;
CZipString temp = bExtract ? "-x" : "-d";
int iCount = cmd.GetArgumentCount(temp);
if (iCount > 0)
{
FILELIST lFiles;
for (int i = 0; i < iCount; i++)
lFiles.push_back(cmd.GetArgument(temp, i));
FindInZip(zip, lFiles, numbers);
}
temp = bExtract ? "-xf" : "-df";
if (cmd.GetArgumentCount(temp) > 0)
{
FILELIST lFiles;
FillFromFile(lFiles, cmd.GetArgument(temp, 0), false);
FindInZip(zip, lFiles, numbers);
}
temp = bExtract ? "-xr" : "-dr";
iCount = cmd.GetArgumentCount(temp);
CZipWordArray notNumbers;
if (iCount > 0)
{
for (int i = 0; i < iCount; i++)
{
CZipString sz = cmd.GetArgument(temp, i);
bool bNot = !sz.IsEmpty() && sz[0] == '!';
CZipWordArray& vN = bNot ? notNumbers : numbers;
if (bNot)
sz.TrimLeft('!');
size_t pos = strcspn(sz, "-");
if (pos == sz.GetLength() )
vN.Add(atoi(sz) - 1);
else
{
int b = atoi (sz.Left(pos));
int e = atoi (sz.Mid(pos + 1));
for (int i = b; i <= e ; i++)
vN.Add(i - 1);
}
}
}
int iSize = notNumbers.GetSize();
if (iSize)
{
for (int j = 0; j < iSize; ++j)
for (int i = numbers.GetSize() ; i >= 0 ;i--)
if (numbers[i] == notNumbers[j])
numbers.RemoveAt(i);
}
int iMax = zip.GetCount() - 1;
for (int i = 0; i < numbers.GetSize(); ++i)
{
int x = numbers[i];
if (x < 0 || x > iMax)
continue;
bool bNew = true;
for (int j = 0; j < vRevised.GetSize(); ++j)
if (vRevised[j] == numbers[i])
{
bNew = false;
break;
}
if (bNew)
vRevised.Add(x);
}
}
}
int main(int argc, char* argv[])
{
#ifndef __GNUC__
// set the locale the same as the system locale
// to handle local characters (non-English) properly by CZipString
std::locale::global(std::locale(""));
#endif
int iRet = 0;
CCmdLine cmd;
CZipArchive zip;
CZipString szArchive;
try
{
if (cmd.SplitLine(argc, argv) < 1)
throw 0;
if (cmd.GetArgumentCount("-f") <= 0)
throw 0;
int iVolumeSize = 0;
int iMode = CZipArchive::zipOpen;
bool bIsAdding = cmd.GetArgumentCount("-a") > 0 || cmd.GetArgumentCount("-af") > 0;
bool bIsExtracting = cmd.GetArgumentCount("-x") > 0 || cmd.GetArgumentCount("-xr") > 0
|| cmd.GetArgumentCount("-xf") > 0 || cmd.HasSwitch("-xa");
bool bIsDeleting = cmd.GetArgumentCount("-d") > 0 || cmd.GetArgumentCount("-dr") > 0
|| cmd.GetArgumentCount("-df") > 0 || cmd.HasSwitch("-da");
szArchive = cmd.GetArgument("-f", 0);
CZipPathComponent zpc(szArchive);
if (zpc.GetFileExt().IsEmpty())
szArchive += ".zip";
bool bUpdateMode = cmd.HasSwitch("-u");
bool bSetComment = cmd.GetArgumentCount("-g") > 0;
bool bIsListing = cmd.HasSwitch("-l") || cmd.HasSwitch("-ll") ||
cmd.HasSwitch("-lr");
bool bOnlyErrors = cmd.HasSwitch("-dse");
if (bIsAdding)
{
if (cmd.GetArgumentCount("-v") > 0)
{
iMode = CZipArchive::zipCreateSpan;
iVolumeSize = atoi(cmd.GetArgument("-v", 0));
}
else
{
if (!bUpdateMode || !ZipPlatform::FileExists(szArchive))
iMode = CZipArchive::zipCreate;
}
}
else if (bIsExtracting || cmd.HasSwitch("-t") || bIsListing)
{
if (cmd.HasSwitch("-st"))
iVolumeSize = 1;
}
else if (!bSetComment && !bIsDeleting)
throw 0;
SpanCallback span;
zip.SetSpanCallback(&span);
bool bAddEmpty = cmd.HasSwitch("-re");
bool bRecursive = cmd.HasSwitch("-r") || bAddEmpty;
bool bCaseSensitiveInZip = cmd.HasSwitch("-cs");
pZipComp = GetCZipStrCompFunc(bCaseSensitiveInZip);
zip.SetCaseSensitivity(bCaseSensitiveInZip);
try
{
zip.Open(szArchive, iMode, iVolumeSize);
if (cmd.GetArgumentCount("-p") > 0)
zip.SetPassword(cmd.GetArgument("-p", 0));
}
catch(...)
{
bool bContinue = false;
if (iMode == CZipArchive::zipOpen && !bIsDeleting && !bSetComment)
{
try
{
// try to open in read only mode (required if there is no write access to the storage)
zip.Open(szArchive, CZipArchive::zipOpenReadOnly, iVolumeSize);
bContinue = true;
}
catch(...)
{
throw;
}
}
if (!bContinue)
throw;
}
if (cmd.GetArgumentCount("-rp") > 0)
zip.SetRootPath(cmd.GetArgument("-rp", 0));
bool bFullPath = !cmd.HasSwitch("-nfp") && zip.GetRootPath().IsEmpty();
bool bIsSpan = zip.GetSpanMode() != 0;
if (bSetComment && !bIsSpan)
{
CZipString sz = cmd.GetArgument("-g", 0);
sz.TrimLeft("\"");
sz.TrimRight("\"");
zip.SetGlobalComment(sz);
}
if (bIsAdding)
{
if (bUpdateMode && bIsSpan)
{
printf ("Cannot update an existing disk spanning archive\n");
zip.Close();
return 1;
}
int iLevel = atoi(cmd.GetSafeArgument("-c", 0, "5"));
int iSmartLevel;
if (cmd.HasSwitch("-as"))
{
iSmartLevel = CZipArchive::zipsmSmartest;
zip.SetTempPath(cmd.GetSafeArgument("-as", 0, ""));
}
else
iSmartLevel = CZipArchive::zipsmSafeSmart;
FILELIST lFiles;
int iCount = cmd.GetArgumentCount("-a");
if (iCount > 0)
{
for (int i = 0; i < iCount; i++)
ExpandFile(lFiles, cmd.GetArgument("-a", i), bRecursive,
bAddEmpty, bFullPath);
}
iCount = cmd.GetArgumentCount("-af");
if (iCount > 0)
FillFromFile(lFiles, cmd.GetArgument("-af", 0), true);
FILELIST excl;
iCount = cmd.GetArgumentCount("-ax");
if (iCount > 0)
{
for (int i = 0; i < iCount; i++)
ExpandFile(excl, cmd.GetArgument("-ax", i), bRecursive,
bAddEmpty, bFullPath);
}
iCount = cmd.GetArgumentCount("-afx");
if (iCount > 0)
FillFromFile(excl, cmd.GetArgument("-afx", 0), true);
FILELISTADD rev;
for (FILELISTIT it = lFiles.begin(); it != lFiles.end(); ++it)
{
// that is how the filename will look in the archive
CZipString sz = zip.PredictFileNameInZip(*it, bFullPath);
if (!sz.IsEmpty())
{
bool bAdd = true;
for (FILELISTIT itt = excl.begin(); itt != excl.end(); ++itt)
{
if (!((*itt).*pZipComp)(*it))
{
bAdd = false;
break;
}
}
if (bAdd)
rev.push_back(CZipAddFileInfo(*it, sz));
}
}
lFiles.clear();
excl.clear();
// remove duplicates
FILELISTADDIT it1;
for (it1 = rev.begin(); it1 != rev.end();)
{
bool bErase = false;
FILELISTADDIT it2 = it1;
for (++it2; it2 != rev.end(); ++it2)
{
int x = ((*it1).m_szFileNameInZip.*pZipComp)((*it2).m_szFileNameInZip);
if (x == 0)
{
bErase = true;
break;
}
}
if (bErase)
rev.erase(it1++);
else
++it1;
}
// sort
rev.sort(std::greater<CZipAddFileInfo>());
printf ("\n");
for (it1 = rev.begin(); it1 != rev.end(); ++it1)
{
if (zip.AddNewFile((*it1).m_szFilePath, iLevel, bFullPath, iSmartLevel))
{
if (!bOnlyErrors)
printf ("%s added\n", (LPCTSTR)(*it1).m_szFileNameInZip);
}
else
printf ("%s not added\n", (LPCTSTR)(*it1).m_szFilePath);
}
}
else if (bIsExtracting)
{
CZipString szPath = cmd.GetSafeArgument("-xp", 0, ".");
CZipWordArray vRevised;
ProcessData(zip, cmd, vRevised, true);
printf ("\n");
for (int k = 0; k < vRevised.GetSize(); ++k)
{
int iFile = vRevised[k];
try
{
zip.ExtractFile(iFile, szPath, bFullPath);
CZipFileHeader fh;
if (zip.GetFileInfo(fh, iFile))
{
if (!bOnlyErrors )
printf ("%s extracted\n", (LPCTSTR)fh.GetFileName());
}
}
catch (...)
{
CZipFileHeader fh;
if (zip.GetFileInfo(fh, iFile))
printf("Error extracting file %s\n", (LPCTSTR)fh.GetFileName());
else
printf("There are troubles with getting info from file number %d\n", iFile);
}
}
printf("\n");
}
else if (bIsDeleting)
{
if (bIsSpan)
{
printf ("Cannot delete from an existing disk spanning archive\n");
zip.Close();
return 1;
}
CZipWordArray vRevised;
ProcessData(zip, cmd, vRevised, false);
try
{
zip.DeleteFiles(vRevised);
}
catch (...)
{
printf("Error occured while deleting files\n");
}
}
else if (cmd.HasSwitch("-t"))
{
FILELIST lFiles;
int iCount = zip.GetCount();
for (int i = 0; i < iCount; i++)
{
bool bOK = false;
try
{
bOK = zip.TestFile(i);
printf("Tested: %d of %d \r", i, iCount);
}
catch (...)
{
}
if (!bOK)
{
CZipFileHeader fh;
if (zip.GetFileInfo(fh, i))
lFiles.push_back(fh.GetFileName());
else
{
char buf[50];
sprintf(buf, "There are troubles with getting info from file number %d", i);
lFiles.push_back(buf);
}
}
}
printf("\n");
if (lFiles.size())
{
printf ("There were errors found in the following files:\n");
for (FILELISTIT it = lFiles.begin(); it != lFiles.end(); ++it)
printf("%s\n", (LPCTSTR)(*it));
}
else
printf ("There were no errors found in the archive\n");
}
else if (bIsListing)
{
bool bNumbers = cmd.HasSwitch("-lr");
bool bDescription = !cmd.HasSwitch("-ll");
int iCount = zip.GetCount();
if (bDescription)
printf("\n File name\tSize\t\tRatio\tTime Stamp\n\n");
for (int i = 0; i < iCount; i++)
{
CZipFileHeader fh;
if (zip.GetFileInfo(fh, i))
{
if (bNumbers)
printf("%d. " ,i + 1);
printf("%s\n", (LPCTSTR)fh.GetFileName());
if (bDescription)
{
printf("\t\t");
if (fh.IsDirectory())
printf("<DIR>\t\t");
else
{
printf("%u Bytes\t", fh.m_uUncomprSize);
printf("%.2f%%", fh.GetCompressionRatio());
}
time_t t = fh.GetTime();
printf ("\t%s", ctime(&t));
}
}
else
printf("There are troubles with getting info from file number %d\n", i);
}
printf("\n");
CZipString sz = zip.GetGlobalComment();
if (!sz.IsEmpty())
printf("Global archive comment:\n%s\n", (LPCTSTR)sz);
}
zip.Close();
}
catch (int)
{
DisplayUsage();
iRet = 1;
}
catch (CZipException e)
{
printf ("Error while processing archive %s\n%s\n", (LPCTSTR) szArchive, (LPCTSTR)e.GetErrorDescription());
if (e.m_szFileName.IsEmpty())
printf("\n");
else
printf("Filename in error object: %s\n\n", (LPCTSTR)e.m_szFileName);
zip.Close(true);
iRet = 1;
}
catch (...)
{
printf ("Unknown error while processing archive %s\n\n", (LPCTSTR) szArchive);
zip.Close(true);
iRet = 1;
}
if (cmd.HasSwitch("-w"))
{
printf("\nPress <ENTER> to exit.\n");
ReadKey();
printf ("\n");
}
return iRet;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -