Added hammock project to debug streaming issues
[pithos-ms-client] / trunk / hammock / src / net35 / ICSharpCode.SharpZipLib.Silverlight / Zip / ZipEntryFactory.cs
1 // ZipEntryFactory.cs
2 //
3 // Copyright 2006 John Reilly
4 //
5 // Copyright (C) 2001 Free Software Foundation, Inc.
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 //
21 // Linking this library statically or dynamically with other modules is
22 // making a combined work based on this library.  Thus, the terms and
23 // conditions of the GNU General Public License cover the whole
24 // combination.
25 // 
26 // As a special exception, the copyright holders of this library give you
27 // permission to link this library with independent modules to produce an
28 // executable, regardless of the license terms of these independent
29 // modules, and to copy and distribute the resulting executable under
30 // terms of your choice, provided that you also meet, for each linked
31 // independent module, the terms and conditions of the license of that
32 // module.  An independent module is a module which is not derived from
33 // or based on this library.  If you modify this library, you may extend
34 // this exception to your version of the library, but you are not
35 // obligated to do so.  If you do not wish to do so, delete this
36 // exception statement from your version.
37
38 using System;
39 using System.IO;
40 using ICSharpCode.SharpZipLib.Silverlight.Core;
41 using IEntryFactory=ICSharpCode.SharpZipLib.Silverlight.Zip.IEntryFactory;
42 using ZipEntry=ICSharpCode.SharpZipLib.Silverlight.Zip.ZipEntry;
43 using ZipException=ICSharpCode.SharpZipLib.Silverlight.Zip.ZipException;
44 using ZipNameTransform=ICSharpCode.SharpZipLib.Zip.ZipNameTransform;
45
46 namespace ICSharpCode.SharpZipLib.Silverlight.Zip
47 {
48     /// <summary>
49     /// Basic implementation of <see cref="IEntryFactory"></see>
50     /// </summary>
51     public class ZipEntryFactory : IEntryFactory
52     {
53         #region Enumerations
54         /// <summary>
55         /// Defines the possible values to be used for the <see cref="ZipEntry.DateTime"/>.
56         /// </summary>
57         public enum TimeSetting
58         {
59             /// <summary>
60             /// Use the recorded LastWriteTime value for the file.
61             /// </summary>
62             LastWriteTime,
63             /// <summary>
64             /// Use the recorded LastWriteTimeUtc value for the file
65             /// </summary>
66             LastWriteTimeUtc,
67             /// <summary>
68             /// Use the recorded CreateTime value for the file.
69             /// </summary>
70             CreateTime,
71             /// <summary>
72             /// Use the recorded CreateTimeUtc value for the file.
73             /// </summary>
74             CreateTimeUtc,
75             /// <summary>
76             /// Use the recorded LastAccessTime value for the file.
77             /// </summary>
78             LastAccessTime,
79             /// <summary>
80             /// Use the recorded LastAccessTimeUtc value for the file.
81             /// </summary>
82             LastAccessTimeUtc,
83             /// <summary>
84             /// Use a fixed value.
85             /// </summary>
86             /// <remarks>The actual <see cref="DateTime"/> value used can be
87             /// specified via the <see cref="ZipEntryFactory(DateTime)"/> constructor or 
88             /// using the <see cref="ZipEntryFactory(TimeSetting)"/> with the setting set
89             /// to <see cref="TimeSetting.Fixed"/> which will use the <see cref="DateTime"/> when this class was constructed.
90             /// The <see cref="FixedDateTime"/> property can also be used to set this value.</remarks>
91             Fixed,
92         }
93         #endregion
94
95         #region Constructors
96         /// <summary>
97         /// Initialise a new instance of the <see cref="ZipEntryFactory"/> class.
98         /// </summary>
99         /// <remarks>A default <see cref="INameTransform"/>, and the LastWriteTime for files is used.</remarks>
100         public ZipEntryFactory()
101         {
102             nameTransform_ = new ZipNameTransform();
103         }
104
105         /// <summary>
106         /// Initialise a new instance of <see cref="ZipEntryFactory"/> using the specified <see cref="TimeSetting"/>
107         /// </summary>
108         /// <param name="timeSetting">The <see cref="TimeSetting">time setting</see> to use when creating <see cref="ZipEntry">Zip entries</see>.</param>
109         public ZipEntryFactory(TimeSetting timeSetting)
110         {
111             timeSetting_ = timeSetting;
112             nameTransform_ = new ZipNameTransform();
113         }
114
115         /// <summary>
116         /// Initialise a new instance of <see cref="ZipEntryFactory"/> using the specified <see cref="DateTime"/>
117         /// </summary>
118         /// <param name="time">The time to set all <see cref="ZipEntry.DateTime"/> values to.</param>
119         public ZipEntryFactory(DateTime time)
120         {
121             timeSetting_ = TimeSetting.Fixed;
122             FixedDateTime = time;
123             nameTransform_ = new ZipNameTransform();
124         }
125
126         #endregion
127
128         #region Properties
129         /// <summary>
130         /// Get / set the <see cref="INameTransform"/> to be used when creating new <see cref="ZipEntry"/> values.
131         /// </summary>
132         /// <remarks>
133         /// Setting this property to null will cause a default <see cref="ZipNameTransform">name transform</see> to be used.
134         /// </remarks>
135         public INameTransform NameTransform
136         {
137             get { return nameTransform_; }
138             set 
139             {
140                 nameTransform_ = value ?? new ZipNameTransform();
141             }
142         }
143
144         /// <summary>
145         /// Get / set the <see cref="TimeSetting"/> in use.
146         /// </summary>
147         public TimeSetting Setting
148         {
149             get { return timeSetting_; }
150             set { timeSetting_ = value; }
151         }
152
153         /// <summary>
154         /// Get / set the <see cref="DateTime"/> value to use when <see cref="Setting"/> is set to <see cref="TimeSetting.Fixed"/>
155         /// </summary>
156         public DateTime FixedDateTime
157         {
158             get { return fixedDateTime_; }
159             set
160             {
161                 if (value.Year < 1970) {
162                     throw new ArgumentException("Value is too old to be valid", "value");
163                 }
164                 fixedDateTime_ = value;
165             }
166         }
167
168         /// <summary>
169         /// A bitmask defining the attributes to be retrieved from the actual file.
170         /// </summary>
171         /// <remarks>The default is to get all possible attributes from the actual file.</remarks>
172         public int GetAttributes
173         {
174             get { return getAttributes_; }
175             set { getAttributes_ = value; }
176         }
177
178         /// <summary>
179         /// A bitmask defining which attributes are to be set on.
180         /// </summary>
181         /// <remarks>By default no attributes are set on.</remarks>
182         public int SetAttributes
183         {
184             get { return setAttributes_; }
185             set { setAttributes_ = value; }
186         }
187
188         /// <summary>
189         /// Get set a value indicating wether unidoce text should be set on.
190         /// </summary>
191         public bool IsUnicodeText
192         {
193             get { return isUnicodeText_; }
194             set { isUnicodeText_ = value; }
195         }
196
197         #endregion
198
199         #region IEntryFactory Members
200
201         /// <summary>
202         /// Make a new <see cref="ZipEntry"/> for a file.
203         /// </summary>
204         /// <param name="fileName">The name of the file to create a new entry for.</param>
205         /// <returns>Returns a new <see cref="ZipEntry"/> based on the <paramref name="fileName"/>.</returns>
206         public ZipEntry MakeFileEntry(string fileName)
207         {
208             return MakeFileEntry(fileName, true);
209         }
210
211         /// <summary>
212         /// Make a new <see cref="ZipEntry"/> from a name.
213         /// </summary>
214         /// <param name="fileName">The name of the file to create a new entry for.</param>
215         /// <param name="useFileSystem">If true entry detail is retrieved from the file system if the file exists.</param>
216         /// <returns>Returns a new <see cref="ZipEntry"/> based on the <paramref name="fileName"/>.</returns>
217         public ZipEntry MakeFileEntry(string fileName, bool useFileSystem)
218         {
219             var result = new ZipEntry(nameTransform_.TransformFile(fileName)){IsUnicodeText = isUnicodeText_};
220
221             var externalAttributes = 0;
222             var useAttributes = (setAttributes_ != 0);
223
224             FileInfo fi = null;
225             if (useFileSystem)
226             {
227                 fi = new FileInfo(fileName);
228             }
229
230             if ((fi != null) && fi.Exists)
231             {
232                 switch (timeSetting_)
233                 {
234                     case TimeSetting.CreateTime:
235                         result.DateTime = fi.CreationTime;
236                         break;
237
238                         //case TimeSetting.CreateTimeUtc:
239                         //result.DateTime = fi.CreationTimeUtc;
240                         //break;
241
242                     case TimeSetting.LastAccessTime:
243                         result.DateTime = fi.LastAccessTime;
244                         break;
245
246                         //case TimeSetting.LastAccessTimeUtc:
247                         //result.DateTime = fi.LastAccessTimeUtc;
248                         //break;
249
250                     case TimeSetting.LastWriteTime:
251                         result.DateTime = fi.LastWriteTime;
252                         break;
253
254                         //case TimeSetting.LastWriteTimeUtc:
255                         //result.DateTime = fi.LastWriteTimeUtc;
256                         //break;
257
258                     case TimeSetting.Fixed:
259                         result.DateTime = fixedDateTime_;
260                         break;
261
262                     default:
263                         throw new ZipException("Unhandled time setting in MakeFileEntry");
264                 }
265
266                 result.Size = fi.Length;
267
268                 useAttributes = true;
269                 externalAttributes = ((int)fi.Attributes & getAttributes_);
270             }
271             else
272             {
273                 if (timeSetting_ == TimeSetting.Fixed)
274                 {
275                     result.DateTime = fixedDateTime_;
276                 }
277             }
278
279             if (useAttributes)
280             {
281                 externalAttributes |= setAttributes_;
282                 result.ExternalFileAttributes = externalAttributes;
283             }
284                         
285             return result;
286         }
287
288         /// <summary>
289         /// Make a new <see cref="ZipEntry"></see> for a directory.
290         /// </summary>
291         /// <param name="directoryName">The raw untransformed name for the new directory</param>
292         /// <returns>Returns a new <see cref="ZipEntry"></see> representing a directory.</returns>
293         public ZipEntry MakeDirectoryEntry(string directoryName)
294         {
295             return MakeDirectoryEntry(directoryName, true);
296         }
297
298         /// <summary>
299         /// Make a new <see cref="ZipEntry"></see> for a directory.
300         /// </summary>
301         /// <param name="directoryName">The raw untransformed name for the new directory</param>
302         /// <param name="useFileSystem">If true entry detail is retrieved from the file system if the file exists.</param>
303         /// <returns>Returns a new <see cref="ZipEntry"></see> representing a directory.</returns>
304         public ZipEntry MakeDirectoryEntry(string directoryName, bool useFileSystem)
305         {
306                         
307             var result = new ZipEntry(nameTransform_.TransformDirectory(directoryName)){Size = 0};
308
309             var externalAttributes = 0;
310
311             DirectoryInfo di = null;
312
313             if (useFileSystem)
314             {
315                 di = new DirectoryInfo(directoryName);
316             }
317
318
319             if ((di != null) && di.Exists)
320             {
321                 switch (timeSetting_)
322                 {
323                     case TimeSetting.CreateTime:
324                         result.DateTime = di.CreationTime;
325                         break;
326
327                         //case TimeSetting.CreateTimeUtc:
328                         //result.DateTime = di.CreationTimeUtc;
329                         //break;
330
331                     case TimeSetting.LastAccessTime:
332                         result.DateTime = di.LastAccessTime;
333                         break;
334
335                         //case TimeSetting.LastAccessTimeUtc:
336                         //result.DateTime = di.LastAccessTimeUtc;
337                         //break;
338
339                     case TimeSetting.LastWriteTime:
340                         result.DateTime = di.LastWriteTime;
341                         break;
342
343                         //case TimeSetting.LastWriteTimeUtc:
344                         //result.DateTime = di.LastWriteTimeUtc;
345                         //break;
346
347                     case TimeSetting.Fixed:
348                         result.DateTime = fixedDateTime_;
349                         break;
350
351                     default:
352                         throw new ZipException("Unhandled time setting in MakeDirectoryEntry");
353                 }
354
355                 externalAttributes = ((int)di.Attributes & getAttributes_);
356             }
357             else
358             {
359                 if (timeSetting_ == TimeSetting.Fixed)
360                 {
361                     result.DateTime = fixedDateTime_;
362                 }
363             }
364
365             // Always set directory attribute on.
366             externalAttributes |= (setAttributes_ | 16);
367             result.ExternalFileAttributes = externalAttributes;
368
369             return result;
370         }
371                 
372         #endregion
373
374         #region Instance Fields
375         INameTransform nameTransform_;
376         DateTime fixedDateTime_ = DateTime.Now;
377         TimeSetting timeSetting_;
378         bool isUnicodeText_;
379
380         int getAttributes_ = -1;
381         int setAttributes_;
382         #endregion
383     }
384 }