/*
* Created by SharpDevelop.
* User: LYCJ
* Date: 18/12/2006
* Time: 0:10
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System.IO;
using System;
using System.Collections;
using System.Diagnostics;
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;
using Cake3;
namespace Cake3.SharpZipLib
{
public class FileSource : IStaticDataSource
{
Stream fileStream;
public Stream GetSource()
{
return fileStream;
}
public FileSource(string filename)
{
StreamReader sr = new StreamReader(filename);
sr.ReadToEnd();
fileStream = sr.BaseStream;
}
}
/// <summary>
/// Description of ZipBase.
/// </summary>
public class ZipBase : ArchiverBase
{
ICSharpCode.SharpZipLib.Zip.ZipFile ZipDir;
CakArchiver arc;
FastZipEvents fze;
ExtractOptions extrOptions;
public ZipBase(CakArchiver anArc)
{
arc = anArc;
fze = new FastZipEvents();
fze.ProcessFile += new ProcessFileDelegate(FastZipProcessFile);
fze.FileFailure += new FileFailureDelegate(FastZipFileFailure);
}
public override bool Open()
{
try
{
ZipDir = new ZipFile(archiveName);
}
catch
{
return false;
}
return true;
}
public override bool Close()
{
try
{
ZipDir.Close();
ZipDir = null;
}
catch
{
return false;
}
return true;
}
public override bool List(string mask)
{
if(arc.OnItemList == null) return false;
if (ZipDir == null) return false;
try
{
foreach (ZipEntry e in ZipDir)
{
if ((!e.IsDirectory) &&(Utils.MatchMask(e.Name, mask)))
arc.OnItemList(arc, new ItemListEventArgs(arc,
new ContentType((UInt32)e.Size, (UInt32)e.CompressedSize,
e.DateTime, e.Crc, ModifySlashToCak(e.Name), e.IsCrypted)));
}
}
catch
{
return false;
}
return true;
}
public void FastZipProcessFile(object sender, ScanEventArgs e)
{
arc.DispMessage(Defines.ErrorMessage("PROCESS"), ModifySlashToCak(e.Name));
e.ContinueRunning = true;
}
public void FastZipFileFailure(object sender, ScanFailureEventArgs e)
{
arc.DispMessage(Defines.ErrorMessage("PROCESSFAIL"), ModifySlashToCak(e.Name));
e.ContinueRunning = false;
}
internal void ProcessFileDelegate(object sender, ScanEventArgs e)
{
}
internal bool FastZipConfirmOverwrite(string fileName)
{
if (extrOptions.allowOverwrite)
return true;
OverwriteEventArgs e = new OverwriteEventArgs(arc, fileName);
if (arc.OnOverwrite != null)
arc.OnOverwrite(arc, ref e);
return e.Overwrite;
}
public override bool Extract(ExtractOptions options)
{
try
{
FastZip fz = new FastZip(fze);
fz.Password = options.password;
extrOptions = options;
foreach (string item in options.extractItem)
fz.ExtractZip(archiveName, options.extractFolder, FastZip.Overwrite.Prompt , FastZipConfirmOverwrite,
ModifySlashFromCak(item), "", true);
}
catch
{
return false;
}
return true;
}
private string getRelativePath(string filePath, string basePath)
{
if (basePath == "")
return ZipEntry.CleanName(filePath);
string retVal;
basePath = Utils.RemoveSlash(basePath).ToLower();
string path = Utils.ExtractFilePath(filePath);
string name = Utils.ExtractFileName(filePath);
if (path.ToLower().IndexOf(basePath) == 0)
retVal = path.Substring(basePath.Length);
else retVal = path;
if (retVal != "")
retVal += @"\";
return ZipEntry.CleanName(retVal + name);
}
private Hashtable parseAddFile(AddOptions options)
{
//TODO: Support mask
Hashtable retVal = new Hashtable();
foreach (string item in AddOptions.ParseAddFile(options.addFile, true))
{
// Console.WriteLine(item);
switch (options.addFolder)
{
case AddOptions.folderMode.full: //06-16-07 Fixed Zip Add Error my remove front slash.
retVal.Add(item, ZipEntry.CleanName(item));
break;
case AddOptions.folderMode.relative:
retVal.Add(item, getRelativePath(item, options.baseFolder));
break;
default:
retVal.Add(item, Utils.ExtractFileName(item));
break;
}
}
return retVal;
}
public override bool Add(AddOptions options)
{
// Close();
string tempArchive = options.archiveName+".temp.add";
Utils.RemoveFile(tempArchive);
ZipOutputStream output = new ZipOutputStream(File.Create(tempArchive));
output.SetLevel(options.addCompressLevel);
try
{
Hashtable addList = parseAddFile(options);
byte[] buffer = new byte[1024*16];
//TODO: Zip Add does not work with archive created by other archiver.
#region Append existing data
if (Utils.FileExists(options.archiveName))
{
ZipInputStream input = new ZipInputStream(File.Open(options.archiveName, FileMode.Open));
ZipEntry entry = input.GetNextEntry();
while (entry != null)
{
if (!addList.ContainsValue(entry.Name))
{
// entry.Size = input.Length;
ZipEntry newEntry = new ZipEntry(entry.Name);
newEntry.Comment = entry.Comment;
newEntry.CompressionMethod = entry.CompressionMethod;
newEntry.DateTime = entry.DateTime;
newEntry.Flags = entry.Flags;
output.PutNextEntry(newEntry);
int sourceBytes;
int totalBytes = 0;
do
{
sourceBytes = input.Read(buffer, 0, buffer.Length);
output.Write(buffer, 0, sourceBytes);
totalBytes += sourceBytes;
} while (sourceBytes > 0);
}
entry = input.GetNextEntry();
}
input.Close();
}
#endregion
#region Compress new data
foreach (string item in addList.Keys)
{
// Debug.WriteLine(addList[item]);
ZipEntry entry = new ZipEntry((string)addList[item]);
entry.DateTime = DateTime.Now;
// entry.Size = Utils.GetFileInfo(item).Length;
output.PutNextEntry(entry);
FileStream fs = File.OpenRead(item);
int sourceBytes;
do
{
sourceBytes = fs.Read(buffer, 0, buffer.Length);
output.Write(buffer, 0, sourceBytes);
} while (sourceBytes > 0);
fs.Close(); //06-16-07 Fix file locked after file add.
fs.Dispose();
}
#endregion
output.Finish();
output.Close();
Utils.MoveFile(tempArchive, options.archiveName);
}
catch (Exception ex)
{
output.Close();
Open();
Debug.WriteLine(ex.Message);
arc.DispError(ex.Message, options.archiveName);
return false;
}
finally
{
// Open();
}
return true;
}
bool matchMasks(ArrayList deleteFileMasks, string fileName)
{
foreach (string mask in deleteFileMasks)
if (Utils.MatchMask(fileName, mask))
return true;
return false;
}
public override bool Delete(DeleteOptions options)
{
// Close();
try
{
string tempArchive = options.archiveName+".temp.del";
Utils.RemoveFile(tempArchive);
ZipOutputStream output = new ZipOutputStream(File.Create(tempArchive));
byte[] buffer = new byte[4096];
ArrayList fileList = new ArrayList();
foreach (string item in options.deleteFile)
fileList.Add(this.ModifySlashFromCak(item.ToLower()));
foreach (string item in fileList)
Debug.WriteLine(item);
#region Add files to temp archive.
if (Utils.FileExists(options.archiveName))
{
ZipInputStream input = new ZipInputStream(File.Open(options.archiveName, FileMode.Open));
ZipEntry entry = input.GetNextEntry();
while (entry != null)
{
ZipEntry newEntry = new ZipEntry(entry.Name);
newEntry.Comment = entry.Comment;
newEntry.CompressionMethod = entry.CompressionMethod;
newEntry.DateTime = entry.DateTime;
newEntry.Flags = entry.Flags;
string entryFile = Utils.RemoveFrontSlash(newEntry.Name.ToLower());
//if (!fileList.Contains(entryFile))
if (!matchMasks(fileList, entryFile))
{
output.PutNextEntry(newEntry);
int sourceBytes;
do
{
sourceBytes = input.Read(buffer, 0, buffer.Length);
output.Write(buffer, 0, sourceBytes);
} while (sourceBytes > 0);
}
entry = input.GetNextEntry();
}
input.Close();
}
#endregion
output.Finish();
output.Close();
Utils.MoveFile(tempArchive, options.archiveName);
}
catch
{
return false;
}
finally
{
// Open();
}
return true;
}
public override bool Test()
{
bool retVal = false;
try
{
if (Open())
{
retVal = ZipDir.TestArchive(true);
Close();
}
}
catch
{
return false;
}
return retVal;
}
}
}