1using System;
2using System.Collections;
3using java.util;
4using java.util.zip;
5
6namespace DotNetZip
7{
8	public delegate Enumeration EnumerationMethod();
9
10	/// <summary>
11	/// Wraps java enumerators 
12	/// </summary>
13	public class EnumerationAdapter : IEnumerable
14	{
15		private class EnumerationWrapper : IEnumerator
16		{
17			private EnumerationMethod m_Method;
18			private Enumeration m_Wrapped;
19			private object m_Current;
20
21			public EnumerationWrapper(EnumerationMethod method)
22			{
23				m_Method = method;
24			}
25
26			// IEnumerator
27			public object Current
28			{
29				get { return m_Current; }
30			}
31
32			public void Reset()
33			{
34				m_Wrapped = m_Method();
35				if (m_Wrapped == null)
36					throw new InvalidOperationException();
37			}
38
39			public bool MoveNext()
40			{
41				if (m_Wrapped == null)
42					Reset();
43				bool Result = m_Wrapped.hasMoreElements();
44				if (Result)
45					m_Current = m_Wrapped.nextElement();
46				return Result;
47			}
48		}
49
50		private EnumerationMethod m_Method;
51
52		public EnumerationAdapter(EnumerationMethod method)
53		{
54			if (method == null)
55				throw new ArgumentException();
56			m_Method = method;
57		}
58
59		// IEnumerable
60		public IEnumerator GetEnumerator()
61		{
62			return new EnumerationWrapper(m_Method);
63		}
64	}
65
66	public delegate bool FilterEntryMethod(ZipEntry e);
67
68	/// <summary>
69	/// Zip stream utils
70	/// </summary>
71	public class ZipUtils
72	{
73		public static void CopyStream(java.io.InputStream from, java.io.OutputStream to)
74		{
75			sbyte[] buffer = new sbyte[8192];
76			int got; 
77			while ((got = from.read(buffer, 0, buffer.Length)) > 0)
78				to.write(buffer, 0, got);
79		}
80
81		public static void ExtractZipFile(ZipFile file, string path, 
82			FilterEntryMethod filter, bool moveAllFilesToRootLevel)
83		{
84			foreach(ZipEntry entry in new EnumerationAdapter(new EnumerationMethod(file.entries)))
85			{
86				if (!entry.isDirectory())
87				{
88					if ((filter == null || filter(entry)))
89					{
90						java.io.InputStream s = file.getInputStream(entry);
91						try
92						{
93							string fname = System.IO.Path.GetFileName(entry.getName());
94							string newpath = path;
95							if (!moveAllFilesToRootLevel)
96								newpath = System.IO.Path.Combine(path, System.IO.Path.GetDirectoryName(entry.getName()));
97
98							System.IO.Directory.CreateDirectory(newpath);
99
100							java.io.FileOutputStream dest = new java.io.FileOutputStream(System.IO.Path.Combine(newpath, fname));
101							try
102							{
103								CopyStream(s, dest);
104							}
105							finally
106							{
107								dest.close();
108							}
109						}
110						finally
111						{
112							s.close();
113						}
114					}
115				}
116			}
117		}
118
119		public static ZipFile CreateEmptyZipFile(string fileName)
120		{
121			new ZipOutputStream(new java.io.FileOutputStream(fileName)).close();
122			return new ZipFile(fileName);
123		}
124
125		public static ZipFile UpdateZipFile(ZipFile file, FilterEntryMethod filter, string[] newFiles)
126		{
127			string prev = file.getName();
128			string tmp = System.IO.Path.GetTempFileName();
129			ZipOutputStream to = new ZipOutputStream(new java.io.FileOutputStream(tmp));
130			try
131			{
132				CopyEntries(file, to, filter);
133				// add entries here
134				if (newFiles != null)
135				{
136					foreach(string f in newFiles)
137					{
138						ZipEntry z = new ZipEntry(f.Remove(0, System.IO.Path.GetPathRoot(f).Length));
139						z.setMethod(ZipEntry.DEFLATED);
140						to.putNextEntry(z);
141						try
142						{
143							java.io.FileInputStream s = new java.io.FileInputStream(f);
144							try
145							{
146								CopyStream(s, to);
147							}
148							finally
149							{
150								s.close();
151							}
152						}
153						finally
154						{
155							to.closeEntry();
156						}
157					}
158				}
159			}
160			finally
161			{
162				to.close();
163			}
164			file.close();
165
166			// now replace the old file with the new one
167			System.IO.File.Copy(tmp, prev, true);
168			System.IO.File.Delete(tmp);
169
170			return new ZipFile(prev);
171		}
172
173		public static void CopyEntries(ZipFile from, ZipOutputStream to)
174		{
175			CopyEntries(from, to, null);
176		}
177
178		public static void CopyEntries(ZipFile from, ZipOutputStream to, FilterEntryMethod filter)
179		{
180			foreach(ZipEntry entry in new EnumerationAdapter(new EnumerationMethod(from.entries)))
181			{
182				if (filter == null || filter(entry))
183				{
184					java.io.InputStream s = from.getInputStream(entry);
185					try
186					{
187						to.putNextEntry(entry);
188						try
189						{
190							CopyStream(s, to);
191						}
192						finally
193						{
194							to.closeEntry();
195						}
196					}
197					finally
198					{
199						s.close();
200					}
201				}
202			}
203		}
204	}
205}