[runtime] Fix corlib out of date error with disabled COM
[mono.git] / mcs / class / System.IO.Compression / SharpCompress / Archive / ArchiveFactory.cs
1 using System;
2 using System.IO;
3 #if GZIP
4 using SharpCompress.Archive.GZip;
5 #endif
6 #if RAR
7 using SharpCompress.Archive.Rar;
8 #endif
9 #if SEVENZIP
10 using SharpCompress.Archive.SevenZip;
11 #endif
12 #if TAR
13 using SharpCompress.Archive.Tar;
14 #endif
15 using SharpCompress.Archive.Zip;
16 using SharpCompress.Common;
17
18 namespace SharpCompress.Archive
19 {
20     internal class ArchiveFactory
21     {
22         /// <summary>
23         /// Opens an Archive for random access
24         /// </summary>
25         /// <param name="stream"></param>
26         /// <param name="options"></param>
27         /// <returns></returns>
28         public static IArchive Open(Stream stream, Options options = Options.KeepStreamsOpen)
29         {
30             stream.CheckNotNull("stream");
31             if (!stream.CanRead || !stream.CanSeek)
32             {
33                 throw new ArgumentException("Stream should be readable and seekable");
34             }
35
36             if (ZipArchive.IsZipFile(stream, null))
37             {
38                 stream.Seek(0, SeekOrigin.Begin);
39                 return ZipArchive.Open(stream, options, null);
40             }
41 #if RAR
42             stream.Seek(0, SeekOrigin.Begin);
43             if (RarArchive.IsRarFile(stream, Options.LookForHeader | Options.KeepStreamsOpen))
44             {
45                 stream.Seek(0, SeekOrigin.Begin);
46                 return RarArchive.Open(stream, options);
47             }
48 #endif
49 #if TAR
50             stream.Seek(0, SeekOrigin.Begin);
51             if (TarArchive.IsTarFile(stream))
52             {
53                 stream.Seek(0, SeekOrigin.Begin);
54                 return TarArchive.Open(stream, options);
55             }
56 #endif
57 #if SEVENZIP
58             stream.Seek(0, SeekOrigin.Begin);
59             if (SevenZipArchive.IsSevenZipFile(stream))
60             {
61                 stream.Seek(0, SeekOrigin.Begin);
62                 return SevenZipArchive.Open(stream, options);
63             }
64 #endif
65 #if GZIP
66             stream.Seek(0, SeekOrigin.Begin);
67             if (GZipArchive.IsGZipFile(stream))
68             {
69                 stream.Seek(0, SeekOrigin.Begin);
70                 return GZipArchive.Open(stream, options);
71             }
72 #endif
73             throw new InvalidOperationException("Cannot determine compressed stream type.  Supported Archive Formats: Zip, GZip, Tar, Rar, 7Zip");
74         }
75
76         public static IArchive Create(ArchiveType type)
77         {
78             switch (type)
79             {
80                 case ArchiveType.Zip:
81                     {
82                         return ZipArchive.Create();
83                     }
84 #if TAR
85                 case ArchiveType.Tar:
86                     {
87                         return TarArchive.Create();
88                     }
89 #endif
90                 default:
91                     {
92                         throw new NotSupportedException("Cannot create Archives of type: " + type);
93                     }
94             }
95         }
96
97 #if !PORTABLE && !NETFX_CORE
98         /// <summary>
99         /// Constructor expects a filepath to an existing file.
100         /// </summary>
101         /// <param name="filePath"></param>
102         public static IArchive Open(string filePath)
103         {
104             return Open(filePath, Options.None);
105         }
106
107         /// <summary>
108         /// Constructor with a FileInfo object to an existing file.
109         /// </summary>
110         /// <param name="fileInfo"></param>
111         public static IArchive Open(FileInfo fileInfo)
112         {
113             return Open(fileInfo, Options.None);
114         }
115
116         /// <summary>
117         /// Constructor expects a filepath to an existing file.
118         /// </summary>
119         /// <param name="filePath"></param>
120         /// <param name="options"></param>
121         public static IArchive Open(string filePath, Options options)
122         {
123             filePath.CheckNotNullOrEmpty("filePath");
124             return Open(new FileInfo(filePath), options);
125         }
126
127         /// <summary>
128         /// Constructor with a FileInfo object to an existing file.
129         /// </summary>
130         /// <param name="fileInfo"></param>
131         /// <param name="options"></param>
132         public static IArchive Open(FileInfo fileInfo, Options options)
133         {
134             fileInfo.CheckNotNull("fileInfo");
135             using (var stream = fileInfo.OpenRead())
136             {
137                 if (ZipArchive.IsZipFile(stream, null))
138                 {
139                     stream.Dispose();
140                     return ZipArchive.Open(fileInfo, options, null);
141                 }
142 #if RAR
143                 stream.Seek(0, SeekOrigin.Begin);
144                 if (RarArchive.IsRarFile(stream, Options.LookForHeader | Options.KeepStreamsOpen))
145                 {
146                     stream.Dispose();
147                     return RarArchive.Open(fileInfo, options);
148                 }
149 #endif
150 #if TAR
151                 stream.Seek(0, SeekOrigin.Begin);
152                 if (TarArchive.IsTarFile(stream))
153                 {
154                     stream.Dispose();
155                     return TarArchive.Open(fileInfo, options);
156                 }
157 #endif
158 #if SEVENZIP
159                 stream.Seek(0, SeekOrigin.Begin);
160                 if (SevenZipArchive.IsSevenZipFile(stream))
161                 {
162                     stream.Dispose();
163                     return SevenZipArchive.Open(fileInfo, options);
164                 }
165 #endif
166 #if GZIP
167                 stream.Seek(0, SeekOrigin.Begin);
168                 if (GZipArchive.IsGZipFile(stream))
169                 {
170                     stream.Dispose();
171                     return GZipArchive.Open(fileInfo, options);
172                 }
173 #endif
174                 throw new InvalidOperationException("Cannot determine compressed stream type.");
175             }
176         }
177
178         /// <summary>
179         /// Extract to specific directory, retaining filename
180         /// </summary>
181         public static void WriteToDirectory(string sourceArchive, string destinationDirectory,
182                                             ExtractOptions options = ExtractOptions.Overwrite)
183         {
184             using (IArchive archive = Open(sourceArchive))
185             {
186                 foreach (IArchiveEntry entry in archive.Entries)
187                 {
188                     entry.WriteToDirectory(destinationDirectory, options);
189                 }
190             }
191         }
192 #endif
193     }
194 }