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 int result = unzGetCurrentFileInfo (handle, out info, null, IntPtr.Zero, IntPtr.Zero, new IntPtr (0), null, IntPtr.Zero);
88 StringBuilder sbName = new StringBuilder ((int)info.SizeFilename+1); // +1 to account for extra \0 at the end
89 result = unzGetCurrentFileInfo (handle, out info, sbName, new IntPtr (sbName.Capacity), IntPtr.Zero, new IntPtr (0), null, IntPtr.Zero);
94 return sbName.ToString ();
97 public static string[] GetFiles (UnzipHandle handle)
99 List<string> files = new List<string> ();
101 GoToFirstFile (handle);
104 while ((name = GetCurrentFileName(handle)) != null)
107 if (!NativeUnzip.GoToNextFile (handle))
111 return files.ToArray ();
114 static void GoToFirstFile (UnzipHandle handle)
116 if (NativeUnzip.unzGoToFirstFile (handle) != 0)
117 throw new Exception ("Zip file is invalid");
120 static bool GoToNextFile (UnzipHandle handle)
122 return unzGoToNextFile(handle) == 0;
125 public static UnzipHandle OpenArchive (ZlibFileFuncDef fileFuncs)
127 UnzipHandle handle = unzOpen2 ("", ref fileFuncs);
128 if (handle.IsInvalid)
129 throw new Exception ("Could not open unzip archive");
133 public static void OpenFile (UnzipHandle handle, string name, out CompressionOption level)
135 if (unzLocateFile (handle, name, (int) ZipStringComparison.CaseInsensitive) != 0)
136 throw new Exception ("The file doesn't exist");
138 int method, compression;
139 // '0' means do not open in raw mode (raw == do not decompress)
140 if (unzOpenCurrentFile2 (handle, out method, out compression, 0) != 0)
141 throw new Exception ("The file could not be opened");
143 level = ConvertCompression (method == 0 ? 0 : compression);
146 public static unsafe int Read (UnzipHandle handle, byte[] buffer, int offset, int count)
148 if ((buffer.Length - offset) > count)
149 throw new ArgumentOutOfRangeException ("count", "Buffer is too small to read that amount of data");
151 fixed (byte * b = &buffer[offset])
152 return unzReadCurrentFile (handle, b, (uint)count);
155 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
156 static extern int unzCloseCurrentFile (UnzipHandle handle);
158 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
159 static extern IntPtr unztell (UnzipHandle handle);
161 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
162 static extern int unzGoToFirstFile (UnzipHandle handle);
164 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
165 static extern UnzipHandle unzOpen2 (string path,
166 ref ZlibFileFuncDef pzlib_filefunc_def);
168 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
169 static extern int unzGoToNextFile (UnzipHandle handle);
171 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
172 static extern int unzLocateFile (UnzipHandle handle,
174 int iCaseSensitivity);
176 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
177 static extern int unzOpenCurrentFile2 (UnzipHandle handle,
182 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
183 static extern int unzGetCurrentFileInfo (UnzipHandle handle,
184 out UnzipFileInfo pfile_info,
185 StringBuilder szFileName,
186 IntPtr fileNameBufferSize, // uLong
187 IntPtr extraField, // void *
188 IntPtr extraFieldBufferSize, // uLong
189 StringBuilder szComment,
190 IntPtr commentBufferSize); // uLong
192 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
193 static unsafe extern int unzReadCurrentFile (UnzipHandle handle,
197 //[DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
198 //static extern int unzSetOffset (UnzipHandle handle, IntPtr pos); // uLong
200 [DllImport ("MonoPosixHelper", CallingConvention=CallingConvention.Cdecl)]
201 static extern int unzClose (UnzipHandle handle);