1 // NativeUnzip.cs created with MonoDevelop
2 // User: alan at 13:11 20/10/2008
4 // To change standard headers go to Edit->Preferences->Coding->Standard Headers
8 using System.Collections.Generic;
10 using System.IO.Packaging;
11 using System.Runtime.InteropServices;
16 static class NativeUnzip
18 enum ZipStringComparison
25 public static void CloseArchive (UnzipHandle handle)
28 handle.SetHandleAsInvalid ();
31 public static void CloseCurrentFile (UnzipHandle handle)
33 if (unzCloseCurrentFile (handle) != 0)
34 throw new Exception ("Could not close the active file");
37 static CompressionOption ConvertCompression (int compressionLevel)
39 switch (compressionLevel)
43 return CompressionOption.SuperFast;
47 return CompressionOption.Fast;
51 return CompressionOption.Normal;
56 return CompressionOption.Maximum;
59 return CompressionOption.NotCompressed;
63 public static long CurrentFilePosition (UnzipHandle handle)
65 return unztell(handle).ToInt64 ();
68 public static long CurrentFileLength (UnzipHandle handle)
71 StringBuilder sbName = new StringBuilder (128);
72 int result = unzGetCurrentFileInfo (handle, out info, sbName, new IntPtr (sbName.Capacity), IntPtr.Zero, IntPtr.Zero, null, IntPtr.Zero);
77 return (long)info.UncompressedSize;
80 static string GetCurrentFileName (UnzipHandle handle)
83 StringBuilder sbName = new StringBuilder (128);
84 int result = unzGetCurrentFileInfo (handle, out info, sbName, new IntPtr (sbName.Capacity), IntPtr.Zero, new IntPtr (0), null, IntPtr.Zero);
89 return sbName.ToString ();
92 public static string[] GetFiles (UnzipHandle handle)
94 List<string> files = new List<string> ();
96 GoToFirstFile (handle);
99 while ((name = GetCurrentFileName(handle)) != null)
102 if (!NativeUnzip.GoToNextFile (handle))
106 return files.ToArray ();
109 static void GoToFirstFile (UnzipHandle handle)
111 if (NativeUnzip.unzGoToFirstFile (handle) != 0)
112 throw new Exception ("Zip file is invalid");
115 static bool GoToNextFile (UnzipHandle handle)
117 return unzGoToNextFile(handle) == 0;
120 public static UnzipHandle OpenArchive (ZlibFileFuncDef fileFuncs)
122 UnzipHandle handle = unzOpen2 ("", ref fileFuncs);
123 if (handle.IsInvalid)
124 throw new Exception ("Could not open unzip archive");
128 public static void OpenFile (UnzipHandle handle, string name, out CompressionOption level)
130 if (unzLocateFile (handle, name, (int) ZipStringComparison.CaseInsensitive) != 0)
131 throw new Exception ("The file doesn't exist");
133 int method, compression;
134 // '0' means do not open in raw mode (raw == do not decompress)
135 if (unzOpenCurrentFile2 (handle, out method, out compression, 0) != 0)
136 throw new Exception ("The file could not be opened");
138 level = ConvertCompression (method == 0 ? 0 : compression);
141 public static unsafe int Read (UnzipHandle handle, byte[] buffer, int offset, int count)
143 if ((buffer.Length - offset) > count)
144 throw new ArgumentOutOfRangeException ("count", "Buffer is too small to read that amount of data");
146 fixed (byte * b = &buffer[offset])
147 return unzReadCurrentFile (handle, b, (uint)count);
150 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
151 static extern int unzCloseCurrentFile (UnzipHandle handle);
153 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
154 static extern IntPtr unztell (UnzipHandle handle);
156 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
157 static extern int unzGoToFirstFile (UnzipHandle handle);
159 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
160 static extern UnzipHandle unzOpen2 (string path,
161 ref ZlibFileFuncDef pzlib_filefunc_def);
163 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
164 static extern int unzGoToNextFile (UnzipHandle handle);
166 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
167 static extern int unzLocateFile (UnzipHandle handle,
169 int iCaseSensitivity);
171 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
172 static extern int unzOpenCurrentFile2 (UnzipHandle handle,
177 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
178 static extern int unzGetCurrentFileInfo (UnzipHandle handle,
179 out UnzipFileInfo pfile_info,
180 StringBuilder szFileName,
181 IntPtr fileNameBufferSize, // uLong
182 IntPtr extraField, // void *
183 IntPtr extraFieldBufferSize, // uLong
184 StringBuilder szComment,
185 IntPtr commentBufferSize); // uLong
187 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
188 static unsafe extern int unzReadCurrentFile (UnzipHandle handle,
192 //[DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
193 //static extern int unzSetOffset (UnzipHandle handle, IntPtr pos); // uLong
195 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
196 static extern int unzClose (UnzipHandle handle);