2014-08-13 10:39:27 +01:00
|
|
|
|
// NativeUnzip.cs created with MonoDevelop
|
|
|
|
|
// User: alan at 13:11 20/10/2008
|
|
|
|
|
//
|
|
|
|
|
// To change standard headers go to Edit->Preferences->Coding->Standard Headers
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.IO.Packaging;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
|
|
namespace zipsharp
|
|
|
|
|
{
|
|
|
|
|
static class NativeUnzip
|
|
|
|
|
{
|
|
|
|
|
enum ZipStringComparison
|
|
|
|
|
{
|
|
|
|
|
OSDefault = 0,
|
|
|
|
|
CaseSensitive = 1,
|
|
|
|
|
CaseInsensitive = 2
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void CloseArchive (UnzipHandle handle)
|
|
|
|
|
{
|
|
|
|
|
unzClose (handle);
|
|
|
|
|
handle.SetHandleAsInvalid ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void CloseCurrentFile (UnzipHandle handle)
|
|
|
|
|
{
|
|
|
|
|
if (unzCloseCurrentFile (handle) != 0)
|
|
|
|
|
throw new Exception ("Could not close the active file");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static CompressionOption ConvertCompression (int compressionLevel)
|
|
|
|
|
{
|
|
|
|
|
switch (compressionLevel)
|
|
|
|
|
{
|
|
|
|
|
case 1:
|
|
|
|
|
case 2:
|
|
|
|
|
return CompressionOption.SuperFast;
|
|
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
|
case 4:
|
|
|
|
|
return CompressionOption.Fast;
|
|
|
|
|
|
|
|
|
|
case 5:
|
|
|
|
|
case 6:
|
|
|
|
|
return CompressionOption.Normal;
|
|
|
|
|
|
|
|
|
|
case 7:
|
|
|
|
|
case 8:
|
|
|
|
|
case 9:
|
|
|
|
|
return CompressionOption.Maximum;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return CompressionOption.NotCompressed;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static long CurrentFilePosition (UnzipHandle handle)
|
|
|
|
|
{
|
|
|
|
|
return unztell(handle).ToInt64 ();
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
|
public static long CurrentFileLength32 (UnzipHandle handle)
|
2014-08-13 10:39:27 +01:00
|
|
|
|
{
|
2017-04-10 11:41:01 +00:00
|
|
|
|
UnzipFileInfo32 info;
|
|
|
|
|
int result = unzGetCurrentFileInfo_32 (handle, out info, null, 0, IntPtr.Zero, 0, null, 0);
|
|
|
|
|
return result != 0 ? -1 : (long) info.uncompressed_size;
|
2014-08-13 10:39:27 +01:00
|
|
|
|
}
|
2017-04-10 11:41:01 +00:00
|
|
|
|
|
|
|
|
|
public static long CurrentFileLength64 (UnzipHandle handle)
|
2014-08-13 10:39:27 +01:00
|
|
|
|
{
|
2017-04-10 11:41:01 +00:00
|
|
|
|
UnzipFileInfo64 info;
|
|
|
|
|
int result = unzGetCurrentFileInfo_64 (handle, out info, null, 0, IntPtr.Zero, 0, null, 0);
|
|
|
|
|
return result != 0 ? -1 : (long) info.uncompressed_size;
|
|
|
|
|
}
|
2015-07-20 03:39:00 -04:00
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
|
static string GetCurrentFileName32 (UnzipHandle handle)
|
|
|
|
|
{
|
|
|
|
|
UnzipFileInfo32 info;
|
|
|
|
|
if (unzGetCurrentFileInfo_32 (handle, out info, null, 0, IntPtr.Zero, 0, null, 0) != 0)
|
2015-07-20 03:39:00 -04:00
|
|
|
|
return null;
|
2017-04-10 11:41:01 +00:00
|
|
|
|
var sbName = new StringBuilder ((int) info.size_filename + 1); // +1 to account for extra \0 at the end
|
|
|
|
|
if (unzGetCurrentFileInfo_32 (handle, out info, sbName, (uint) sbName.Capacity, IntPtr.Zero, 0, null, 0) != 0)
|
2014-08-13 10:39:27 +01:00
|
|
|
|
return null;
|
2017-04-10 11:41:01 +00:00
|
|
|
|
return sbName.ToString ();
|
2014-08-13 10:39:27 +01:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
|
static string GetCurrentFileName64 (UnzipHandle handle)
|
2014-08-13 10:39:27 +01:00
|
|
|
|
{
|
2017-04-10 11:41:01 +00:00
|
|
|
|
UnzipFileInfo64 info;
|
|
|
|
|
if (unzGetCurrentFileInfo_64 (handle, out info, null, 0, IntPtr.Zero, 0, null, 0) != 0)
|
|
|
|
|
return null;
|
|
|
|
|
var sbName = new StringBuilder ((int) info.size_filename + 1); // +1 to account for extra \0 at the end
|
|
|
|
|
if (unzGetCurrentFileInfo_64 (handle, out info, sbName, (uint) sbName.Capacity, IntPtr.Zero, 0, null, 0) != 0)
|
|
|
|
|
return null;
|
|
|
|
|
return sbName.ToString ();
|
|
|
|
|
}
|
2014-08-13 10:39:27 +01:00
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
|
public static string[] GetFiles32 (UnzipHandle handle)
|
|
|
|
|
{
|
|
|
|
|
return GetFiles (handle, GetCurrentFileName32);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static string[] GetFiles64 (UnzipHandle handle)
|
|
|
|
|
{
|
|
|
|
|
return GetFiles (handle, GetCurrentFileName64);
|
|
|
|
|
}
|
2014-08-13 10:39:27 +01:00
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
|
private static string[] GetFiles (UnzipHandle handle, Func<UnzipHandle, string> getCurrentFileName)
|
|
|
|
|
{
|
|
|
|
|
GoToFirstFile (handle);
|
|
|
|
|
var files = new List<string> ();
|
2014-08-13 10:39:27 +01:00
|
|
|
|
string name;
|
2017-04-10 11:41:01 +00:00
|
|
|
|
while ((name = getCurrentFileName (handle)) != null) {
|
2014-08-13 10:39:27 +01:00
|
|
|
|
files.Add (name);
|
|
|
|
|
if (!NativeUnzip.GoToNextFile (handle))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return files.ToArray ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void GoToFirstFile (UnzipHandle handle)
|
|
|
|
|
{
|
|
|
|
|
if (NativeUnzip.unzGoToFirstFile (handle) != 0)
|
|
|
|
|
throw new Exception ("Zip file is invalid");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool GoToNextFile (UnzipHandle handle)
|
|
|
|
|
{
|
|
|
|
|
return unzGoToNextFile(handle) == 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
|
public static UnzipHandle OpenArchive32 (ZlibFileFuncDef32 fileFuncs)
|
|
|
|
|
{
|
|
|
|
|
UnzipHandle handle = unzOpen2_32 ("", ref fileFuncs);
|
|
|
|
|
if (handle.IsInvalid)
|
|
|
|
|
throw new Exception ("Could not open unzip archive");
|
|
|
|
|
return handle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static UnzipHandle OpenArchive64 (ZlibFileFuncDef64 fileFuncs)
|
2014-08-13 10:39:27 +01:00
|
|
|
|
{
|
2017-04-10 11:41:01 +00:00
|
|
|
|
UnzipHandle handle = unzOpen2_64 ("", ref fileFuncs);
|
2014-08-13 10:39:27 +01:00
|
|
|
|
if (handle.IsInvalid)
|
|
|
|
|
throw new Exception ("Could not open unzip archive");
|
|
|
|
|
return handle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void OpenFile (UnzipHandle handle, string name, out CompressionOption level)
|
|
|
|
|
{
|
|
|
|
|
if (unzLocateFile (handle, name, (int) ZipStringComparison.CaseInsensitive) != 0)
|
|
|
|
|
throw new Exception ("The file doesn't exist");
|
|
|
|
|
|
|
|
|
|
int method, compression;
|
|
|
|
|
// '0' means do not open in raw mode (raw == do not decompress)
|
|
|
|
|
if (unzOpenCurrentFile2 (handle, out method, out compression, 0) != 0)
|
|
|
|
|
throw new Exception ("The file could not be opened");
|
|
|
|
|
|
|
|
|
|
level = ConvertCompression (method == 0 ? 0 : compression);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static unsafe int Read (UnzipHandle handle, byte[] buffer, int offset, int count)
|
|
|
|
|
{
|
|
|
|
|
if ((buffer.Length - offset) > count)
|
|
|
|
|
throw new ArgumentOutOfRangeException ("count", "Buffer is too small to read that amount of data");
|
|
|
|
|
|
|
|
|
|
fixed (byte * b = &buffer[offset])
|
|
|
|
|
return unzReadCurrentFile (handle, b, (uint)count);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
|
|
|
|
|
static extern int unzCloseCurrentFile (UnzipHandle handle);
|
|
|
|
|
|
|
|
|
|
[DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
|
|
|
|
|
static extern IntPtr unztell (UnzipHandle handle);
|
|
|
|
|
|
|
|
|
|
[DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
|
|
|
|
|
static extern int unzGoToFirstFile (UnzipHandle handle);
|
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
|
[DllImport ("MonoPosixHelper", EntryPoint="unzOpen2", CallingConvention=CallingConvention.Cdecl)]
|
|
|
|
|
static extern UnzipHandle unzOpen2_32 (string path,
|
|
|
|
|
ref ZlibFileFuncDef32 pzlib_filefunc_def);
|
|
|
|
|
|
|
|
|
|
[DllImport ("MonoPosixHelper", EntryPoint="unzOpen2", CallingConvention=CallingConvention.Cdecl)]
|
|
|
|
|
static extern UnzipHandle unzOpen2_64 (string path,
|
|
|
|
|
ref ZlibFileFuncDef64 pzlib_filefunc_def);
|
2014-08-13 10:39:27 +01:00
|
|
|
|
|
|
|
|
|
[DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
|
|
|
|
|
static extern int unzGoToNextFile (UnzipHandle handle);
|
|
|
|
|
|
|
|
|
|
[DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
|
|
|
|
|
static extern int unzLocateFile (UnzipHandle handle,
|
|
|
|
|
string szFileName,
|
|
|
|
|
int iCaseSensitivity);
|
|
|
|
|
|
|
|
|
|
[DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
|
|
|
|
|
static extern int unzOpenCurrentFile2 (UnzipHandle handle,
|
|
|
|
|
out int method,
|
|
|
|
|
out int level,
|
|
|
|
|
int raw);
|
|
|
|
|
|
2017-04-10 11:41:01 +00:00
|
|
|
|
[DllImport ("MonoPosixHelper", EntryPoint="unzGetCurrentFileInfo", CallingConvention=CallingConvention.Cdecl)]
|
|
|
|
|
static extern int unzGetCurrentFileInfo_32 (UnzipHandle handle,
|
|
|
|
|
out UnzipFileInfo32 pfile_info,
|
|
|
|
|
StringBuilder szFileName,
|
|
|
|
|
uint fileNameBufferSize, // uLong
|
|
|
|
|
IntPtr extraField, // void *
|
|
|
|
|
uint extraFieldBufferSize, // uLong
|
|
|
|
|
StringBuilder szComment,
|
|
|
|
|
uint commentBufferSize); // uLong
|
|
|
|
|
|
|
|
|
|
[DllImport ("MonoPosixHelper", EntryPoint="unzGetCurrentFileInfo", CallingConvention=CallingConvention.Cdecl)]
|
|
|
|
|
static extern int unzGetCurrentFileInfo_64 (UnzipHandle handle,
|
|
|
|
|
out UnzipFileInfo64 pfile_info,
|
|
|
|
|
StringBuilder szFileName,
|
|
|
|
|
ulong fileNameBufferSize, // uLong
|
|
|
|
|
IntPtr extraField, // void *
|
|
|
|
|
ulong extraFieldBufferSize, // uLong
|
|
|
|
|
StringBuilder szComment,
|
|
|
|
|
ulong commentBufferSize); // uLong
|
2014-08-13 10:39:27 +01:00
|
|
|
|
|
|
|
|
|
[DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
|
|
|
|
|
static unsafe extern int unzReadCurrentFile (UnzipHandle handle,
|
|
|
|
|
byte* buf, // voidp
|
|
|
|
|
uint len);
|
|
|
|
|
|
|
|
|
|
//[DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
|
|
|
|
|
//static extern int unzSetOffset (UnzipHandle handle, IntPtr pos); // uLong
|
|
|
|
|
|
|
|
|
|
[DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
|
|
|
|
|
static extern int unzClose (UnzipHandle handle);
|
|
|
|
|
}
|
|
|
|
|
}
|