File: NativeUnzip.cs

package info (click to toggle)
mono 6.14.1%2Bds2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,282,732 kB
  • sloc: cs: 11,182,461; xml: 2,850,281; ansic: 699,123; cpp: 122,919; perl: 58,604; javascript: 30,841; asm: 21,845; makefile: 19,602; sh: 10,973; python: 4,772; pascal: 925; sql: 859; sed: 16; php: 1
file content (239 lines) | stat: -rw-r--r-- 8,569 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
// 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 ();
		}

		public static long CurrentFileLength32 (UnzipHandle handle)
		{
			UnzipFileInfo32 info;
			int result = unzGetCurrentFileInfo_32 (handle, out info, null, 0, IntPtr.Zero, 0, null,  0);
			return result != 0 ? -1 : (long) info.uncompressed_size;
		}

		public static long CurrentFileLength64 (UnzipHandle handle)
		{
			UnzipFileInfo64 info;
			int result = unzGetCurrentFileInfo_64 (handle, out info, null, 0, IntPtr.Zero, 0, null,  0);
			return result != 0 ? -1 : (long) info.uncompressed_size;
		}

		static string GetCurrentFileName32 (UnzipHandle handle)
		{
			UnzipFileInfo32 info;
			if (unzGetCurrentFileInfo_32 (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_32 (handle, out info, sbName, (uint) sbName.Capacity, IntPtr.Zero, 0, null, 0) != 0)
				return null;
			return sbName.ToString ();
		}

		static string GetCurrentFileName64 (UnzipHandle handle)
		{
			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 ();
		}

		public static string[] GetFiles32 (UnzipHandle handle)
		{
			return GetFiles (handle, GetCurrentFileName32);
		}

		public static string[] GetFiles64 (UnzipHandle handle)
		{
			return GetFiles (handle, GetCurrentFileName64);
		}

		private static string[] GetFiles (UnzipHandle handle, Func<UnzipHandle, string> getCurrentFileName)
		{
			GoToFirstFile (handle);
			var files = new List<string> ();
			string name;
			while ((name = getCurrentFileName (handle)) != null) {
				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;
		}
		
		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)
		{
			UnzipHandle handle = unzOpen2_64 ("", ref fileFuncs);
			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);

		[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);

		[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);

		[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

		[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);
	}
}