| | 1 | | using System; |
| | 2 | | using System.IO; |
| | 3 | | using ICSharpCode.SharpZipLib.Core; |
| | 4 | |
|
| | 5 | | namespace ICSharpCode.SharpZipLib.Zip |
| | 6 | | { |
| | 7 | | /// <summary> |
| | 8 | | /// Basic implementation of <see cref="IEntryFactory"></see> |
| | 9 | | /// </summary> |
| | 10 | | public class ZipEntryFactory : IEntryFactory |
| | 11 | | { |
| | 12 | | #region Enumerations |
| | 13 | | /// <summary> |
| | 14 | | /// Defines the possible values to be used for the <see cref="ZipEntry.DateTime"/>. |
| | 15 | | /// </summary> |
| | 16 | | public enum TimeSetting |
| | 17 | | { |
| | 18 | | /// <summary> |
| | 19 | | /// Use the recorded LastWriteTime value for the file. |
| | 20 | | /// </summary> |
| | 21 | | LastWriteTime, |
| | 22 | | /// <summary> |
| | 23 | | /// Use the recorded LastWriteTimeUtc value for the file |
| | 24 | | /// </summary> |
| | 25 | | LastWriteTimeUtc, |
| | 26 | | /// <summary> |
| | 27 | | /// Use the recorded CreateTime value for the file. |
| | 28 | | /// </summary> |
| | 29 | | CreateTime, |
| | 30 | | /// <summary> |
| | 31 | | /// Use the recorded CreateTimeUtc value for the file. |
| | 32 | | /// </summary> |
| | 33 | | CreateTimeUtc, |
| | 34 | | /// <summary> |
| | 35 | | /// Use the recorded LastAccessTime value for the file. |
| | 36 | | /// </summary> |
| | 37 | | LastAccessTime, |
| | 38 | | /// <summary> |
| | 39 | | /// Use the recorded LastAccessTimeUtc value for the file. |
| | 40 | | /// </summary> |
| | 41 | | LastAccessTimeUtc, |
| | 42 | | /// <summary> |
| | 43 | | /// Use a fixed value. |
| | 44 | | /// </summary> |
| | 45 | | /// <remarks>The actual <see cref="DateTime"/> value used can be |
| | 46 | | /// specified via the <see cref="ZipEntryFactory(DateTime)"/> constructor or |
| | 47 | | /// using the <see cref="ZipEntryFactory(TimeSetting)"/> with the setting set |
| | 48 | | /// to <see cref="TimeSetting.Fixed"/> which will use the <see cref="DateTime"/> when this class was constructed. |
| | 49 | | /// The <see cref="FixedDateTime"/> property can also be used to set this value.</remarks> |
| | 50 | | Fixed, |
| | 51 | | } |
| | 52 | | #endregion |
| | 53 | |
|
| | 54 | | #region Constructors |
| | 55 | | /// <summary> |
| | 56 | | /// Initialise a new instance of the <see cref="ZipEntryFactory"/> class. |
| | 57 | | /// </summary> |
| | 58 | | /// <remarks>A default <see cref="INameTransform"/>, and the LastWriteTime for files is used.</remarks> |
| 95 | 59 | | public ZipEntryFactory() |
| | 60 | | { |
| 95 | 61 | | nameTransform_ = new ZipNameTransform(); |
| 95 | 62 | | } |
| | 63 | |
|
| | 64 | | /// <summary> |
| | 65 | | /// Initialise a new instance of <see cref="ZipEntryFactory"/> using the specified <see cref="TimeSetting"/> |
| | 66 | | /// </summary> |
| | 67 | | /// <param name="timeSetting">The <see cref="TimeSetting">time setting</see> to use when creating <see cref="ZipEntr |
| 1 | 68 | | public ZipEntryFactory(TimeSetting timeSetting) |
| | 69 | | { |
| 1 | 70 | | timeSetting_ = timeSetting; |
| 1 | 71 | | nameTransform_ = new ZipNameTransform(); |
| 1 | 72 | | } |
| | 73 | |
|
| | 74 | | /// <summary> |
| | 75 | | /// Initialise a new instance of <see cref="ZipEntryFactory"/> using the specified <see cref="DateTime"/> |
| | 76 | | /// </summary> |
| | 77 | | /// <param name="time">The time to set all <see cref="ZipEntry.DateTime"/> values to.</param> |
| 1 | 78 | | public ZipEntryFactory(DateTime time) |
| | 79 | | { |
| 1 | 80 | | timeSetting_ = TimeSetting.Fixed; |
| 1 | 81 | | FixedDateTime = time; |
| 1 | 82 | | nameTransform_ = new ZipNameTransform(); |
| 1 | 83 | | } |
| | 84 | |
|
| | 85 | | #endregion |
| | 86 | |
|
| | 87 | | #region Properties |
| | 88 | | /// <summary> |
| | 89 | | /// Get / set the <see cref="INameTransform"/> to be used when creating new <see cref="ZipEntry"/> values. |
| | 90 | | /// </summary> |
| | 91 | | /// <remarks> |
| | 92 | | /// Setting this property to null will cause a default <see cref="ZipNameTransform">name transform</see> to be used. |
| | 93 | | /// </remarks> |
| | 94 | | public INameTransform NameTransform { |
| 65743 | 95 | | get { return nameTransform_; } |
| | 96 | | set { |
| 4 | 97 | | if (value == null) { |
| 0 | 98 | | nameTransform_ = new ZipNameTransform(); |
| 0 | 99 | | } else { |
| 4 | 100 | | nameTransform_ = value; |
| | 101 | | } |
| 4 | 102 | | } |
| | 103 | | } |
| | 104 | |
|
| | 105 | | /// <summary> |
| | 106 | | /// Get / set the <see cref="TimeSetting"/> in use. |
| | 107 | | /// </summary> |
| | 108 | | public TimeSetting Setting { |
| 3 | 109 | | get { return timeSetting_; } |
| 2 | 110 | | set { timeSetting_ = value; } |
| | 111 | | } |
| | 112 | |
|
| | 113 | | /// <summary> |
| | 114 | | /// Get / set the <see cref="DateTime"/> value to use when <see cref="Setting"/> is set to <see cref="TimeSetting.Fi |
| | 115 | | /// </summary> |
| | 116 | | public DateTime FixedDateTime { |
| 5 | 117 | | get { return fixedDateTime_; } |
| | 118 | | set { |
| 2 | 119 | | if (value.Year < 1970) { |
| 0 | 120 | | throw new ArgumentException("Value is too old to be valid", nameof(value)); |
| | 121 | | } |
| 2 | 122 | | fixedDateTime_ = value; |
| 2 | 123 | | } |
| | 124 | | } |
| | 125 | |
|
| | 126 | | /// <summary> |
| | 127 | | /// A bitmask defining the attributes to be retrieved from the actual file. |
| | 128 | | /// </summary> |
| | 129 | | /// <remarks>The default is to get all possible attributes from the actual file.</remarks> |
| | 130 | | public int GetAttributes { |
| 3 | 131 | | get { return getAttributes_; } |
| 0 | 132 | | set { getAttributes_ = value; } |
| | 133 | | } |
| | 134 | |
|
| | 135 | | /// <summary> |
| | 136 | | /// A bitmask defining which attributes are to be set on. |
| | 137 | | /// </summary> |
| | 138 | | /// <remarks>By default no attributes are set on.</remarks> |
| | 139 | | public int SetAttributes { |
| 3 | 140 | | get { return setAttributes_; } |
| 2 | 141 | | set { setAttributes_ = value; } |
| | 142 | | } |
| | 143 | |
|
| | 144 | | /// <summary> |
| | 145 | | /// Get set a value indicating wether unidoce text should be set on. |
| | 146 | | /// </summary> |
| | 147 | | public bool IsUnicodeText { |
| 0 | 148 | | get { return isUnicodeText_; } |
| 4 | 149 | | set { isUnicodeText_ = value; } |
| | 150 | | } |
| | 151 | |
|
| | 152 | | #endregion |
| | 153 | |
|
| | 154 | | #region IEntryFactory Members |
| | 155 | |
|
| | 156 | | /// <summary> |
| | 157 | | /// Make a new <see cref="ZipEntry"/> for a file. |
| | 158 | | /// </summary> |
| | 159 | | /// <param name="fileName">The name of the file to create a new entry for.</param> |
| | 160 | | /// <returns>Returns a new <see cref="ZipEntry"/> based on the <paramref name="fileName"/>.</returns> |
| | 161 | | public ZipEntry MakeFileEntry(string fileName) |
| | 162 | | { |
| 7 | 163 | | return MakeFileEntry(fileName, null, true); |
| | 164 | | } |
| | 165 | |
|
| | 166 | | /// <summary> |
| | 167 | | /// Make a new <see cref="ZipEntry"/> for a file. |
| | 168 | | /// </summary> |
| | 169 | | /// <param name="fileName">The name of the file to create a new entry for.</param> |
| | 170 | | /// <param name="useFileSystem">If true entry detail is retrieved from the file system if the file exists.</param> |
| | 171 | | /// <returns>Returns a new <see cref="ZipEntry"/> based on the <paramref name="fileName"/>.</returns> |
| | 172 | | public ZipEntry MakeFileEntry(string fileName, bool useFileSystem) |
| | 173 | | { |
| 165 | 174 | | return MakeFileEntry(fileName, null, useFileSystem); |
| | 175 | | } |
| | 176 | |
|
| | 177 | | /// <summary> |
| | 178 | | /// Make a new <see cref="ZipEntry"/> from a name. |
| | 179 | | /// </summary> |
| | 180 | | /// <param name="fileName">The name of the file to create a new entry for.</param> |
| | 181 | | /// <param name="entryName">An alternative name to be used for the new entry. Null if not applicable.</param> |
| | 182 | | /// <param name="useFileSystem">If true entry detail is retrieved from the file system if the file exists.</param> |
| | 183 | | /// <returns>Returns a new <see cref="ZipEntry"/> based on the <paramref name="fileName"/>.</returns> |
| | 184 | | public ZipEntry MakeFileEntry(string fileName, string entryName, bool useFileSystem) |
| | 185 | | { |
| 172 | 186 | | var result = new ZipEntry(nameTransform_.TransformFile(!string.IsNullOrEmpty(entryName) ? entryName : fileName)); |
| 172 | 187 | | result.IsUnicodeText = isUnicodeText_; |
| | 188 | |
|
| 172 | 189 | | int externalAttributes = 0; |
| 172 | 190 | | bool useAttributes = (setAttributes_ != 0); |
| | 191 | |
|
| 172 | 192 | | FileInfo fi = null; |
| 172 | 193 | | if (useFileSystem) { |
| 7 | 194 | | fi = new FileInfo(fileName); |
| | 195 | | } |
| | 196 | |
|
| 172 | 197 | | if ((fi != null) && fi.Exists) { |
| 7 | 198 | | switch (timeSetting_) { |
| | 199 | | case TimeSetting.CreateTime: |
| 0 | 200 | | result.DateTime = fi.CreationTime; |
| 0 | 201 | | break; |
| | 202 | |
|
| | 203 | | case TimeSetting.CreateTimeUtc: |
| 0 | 204 | | result.DateTime = fi.CreationTimeUtc; |
| 0 | 205 | | break; |
| | 206 | |
|
| | 207 | | case TimeSetting.LastAccessTime: |
| 0 | 208 | | result.DateTime = fi.LastAccessTime; |
| 0 | 209 | | break; |
| | 210 | |
|
| | 211 | | case TimeSetting.LastAccessTimeUtc: |
| 0 | 212 | | result.DateTime = fi.LastAccessTimeUtc; |
| 0 | 213 | | break; |
| | 214 | |
|
| | 215 | | case TimeSetting.LastWriteTime: |
| 7 | 216 | | result.DateTime = fi.LastWriteTime; |
| 7 | 217 | | break; |
| | 218 | |
|
| | 219 | | case TimeSetting.LastWriteTimeUtc: |
| 0 | 220 | | result.DateTime = fi.LastWriteTimeUtc; |
| 0 | 221 | | break; |
| | 222 | |
|
| | 223 | | case TimeSetting.Fixed: |
| 0 | 224 | | result.DateTime = fixedDateTime_; |
| 0 | 225 | | break; |
| | 226 | |
|
| | 227 | | default: |
| 0 | 228 | | throw new ZipException("Unhandled time setting in MakeFileEntry"); |
| | 229 | | } |
| | 230 | |
|
| 7 | 231 | | result.Size = fi.Length; |
| | 232 | |
|
| 7 | 233 | | useAttributes = true; |
| 7 | 234 | | externalAttributes = ((int)fi.Attributes & getAttributes_); |
| 7 | 235 | | } else { |
| 165 | 236 | | if (timeSetting_ == TimeSetting.Fixed) { |
| 2 | 237 | | result.DateTime = fixedDateTime_; |
| | 238 | | } |
| | 239 | | } |
| | 240 | |
|
| 172 | 241 | | if (useAttributes) { |
| 9 | 242 | | externalAttributes |= setAttributes_; |
| 9 | 243 | | result.ExternalFileAttributes = externalAttributes; |
| | 244 | | } |
| | 245 | |
|
| 172 | 246 | | return result; |
| | 247 | | } |
| | 248 | |
|
| | 249 | | /// <summary> |
| | 250 | | /// Make a new <see cref="ZipEntry"></see> for a directory. |
| | 251 | | /// </summary> |
| | 252 | | /// <param name="directoryName">The raw untransformed name for the new directory</param> |
| | 253 | | /// <returns>Returns a new <see cref="ZipEntry"></see> representing a directory.</returns> |
| | 254 | | public ZipEntry MakeDirectoryEntry(string directoryName) |
| | 255 | | { |
| 0 | 256 | | return MakeDirectoryEntry(directoryName, true); |
| | 257 | | } |
| | 258 | |
|
| | 259 | | /// <summary> |
| | 260 | | /// Make a new <see cref="ZipEntry"></see> for a directory. |
| | 261 | | /// </summary> |
| | 262 | | /// <param name="directoryName">The raw untransformed name for the new directory</param> |
| | 263 | | /// <param name="useFileSystem">If true entry detail is retrieved from the file system if the file exists.</param> |
| | 264 | | /// <returns>Returns a new <see cref="ZipEntry"></see> representing a directory.</returns> |
| | 265 | | public ZipEntry MakeDirectoryEntry(string directoryName, bool useFileSystem) |
| | 266 | | { |
| | 267 | |
|
| 0 | 268 | | var result = new ZipEntry(nameTransform_.TransformDirectory(directoryName)); |
| 0 | 269 | | result.IsUnicodeText = isUnicodeText_; |
| 0 | 270 | | result.Size = 0; |
| | 271 | |
|
| 0 | 272 | | int externalAttributes = 0; |
| | 273 | |
|
| 0 | 274 | | DirectoryInfo di = null; |
| | 275 | |
|
| 0 | 276 | | if (useFileSystem) { |
| 0 | 277 | | di = new DirectoryInfo(directoryName); |
| | 278 | | } |
| | 279 | |
|
| | 280 | |
|
| 0 | 281 | | if ((di != null) && di.Exists) { |
| 0 | 282 | | switch (timeSetting_) { |
| | 283 | | case TimeSetting.CreateTime: |
| 0 | 284 | | result.DateTime = di.CreationTime; |
| 0 | 285 | | break; |
| | 286 | |
|
| | 287 | | case TimeSetting.CreateTimeUtc: |
| 0 | 288 | | result.DateTime = di.CreationTimeUtc; |
| 0 | 289 | | break; |
| | 290 | |
|
| | 291 | | case TimeSetting.LastAccessTime: |
| 0 | 292 | | result.DateTime = di.LastAccessTime; |
| 0 | 293 | | break; |
| | 294 | |
|
| | 295 | | case TimeSetting.LastAccessTimeUtc: |
| 0 | 296 | | result.DateTime = di.LastAccessTimeUtc; |
| 0 | 297 | | break; |
| | 298 | |
|
| | 299 | | case TimeSetting.LastWriteTime: |
| 0 | 300 | | result.DateTime = di.LastWriteTime; |
| 0 | 301 | | break; |
| | 302 | |
|
| | 303 | | case TimeSetting.LastWriteTimeUtc: |
| 0 | 304 | | result.DateTime = di.LastWriteTimeUtc; |
| 0 | 305 | | break; |
| | 306 | |
|
| | 307 | | case TimeSetting.Fixed: |
| 0 | 308 | | result.DateTime = fixedDateTime_; |
| 0 | 309 | | break; |
| | 310 | |
|
| | 311 | | default: |
| 0 | 312 | | throw new ZipException("Unhandled time setting in MakeDirectoryEntry"); |
| | 313 | | } |
| | 314 | |
|
| 0 | 315 | | externalAttributes = ((int)di.Attributes & getAttributes_); |
| 0 | 316 | | } else { |
| 0 | 317 | | if (timeSetting_ == TimeSetting.Fixed) { |
| 0 | 318 | | result.DateTime = fixedDateTime_; |
| | 319 | | } |
| | 320 | | } |
| | 321 | |
|
| | 322 | | // Always set directory attribute on. |
| 0 | 323 | | externalAttributes |= (setAttributes_ | 16); |
| 0 | 324 | | result.ExternalFileAttributes = externalAttributes; |
| | 325 | |
|
| 0 | 326 | | return result; |
| | 327 | | } |
| | 328 | |
|
| | 329 | | #endregion |
| | 330 | |
|
| | 331 | | #region Instance Fields |
| | 332 | | INameTransform nameTransform_; |
| 97 | 333 | | DateTime fixedDateTime_ = DateTime.Now; |
| | 334 | | TimeSetting timeSetting_; |
| | 335 | | bool isUnicodeText_; |
| | 336 | |
|
| 97 | 337 | | int getAttributes_ = -1; |
| | 338 | | int setAttributes_; |
| | 339 | | #endregion |
| | 340 | | } |
| | 341 | | } |