forked from icsharpcode/SharpZipLib
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathZipStrings.cs
More file actions
213 lines (182 loc) · 7.66 KB
/
Copy pathZipStrings.cs
File metadata and controls
213 lines (182 loc) · 7.66 KB
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
using System;
using System.Text;
using ICSharpCode.SharpZipLib.Core;
namespace ICSharpCode.SharpZipLib.Zip
{
internal static class EncodingExtensions
{
public static bool IsZipUnicode(this Encoding e)
=> e.Equals(StringCodec.UnicodeZipEncoding);
}
/// <summary>
/// Deprecated way of setting zip encoding provided for backwards compability.
/// Use <see cref="StringCodec"/> when possible.
/// </summary>
/// <remarks>
/// If any ZipStrings properties are being modified, it will enter a backwards compatibility mode, mimicking the
/// old behaviour where a single instance was shared between all Zip* instances.
/// </remarks>
public static class ZipStrings
{
static readonly StringCodec CompatCodec = new StringCodec();
private static bool compatibilityMode;
/// <summary>
/// Returns a new <see cref="StringCodec"/> instance or the shared backwards compatible instance.
/// </summary>
/// <returns></returns>
public static StringCodec GetStringCodec()
=> compatibilityMode ? CompatCodec : new StringCodec();
/// <inheritdoc cref="ZipStrings"/>
[Obsolete("Use ZipFile/Zip*Stream StringCodec instead")]
public static int CodePage
{
get => CompatCodec.CodePage;
set
{
CompatCodec.CodePage = value;
compatibilityMode = true;
}
}
/// <inheritdoc cref="ZipStrings"/>
[Obsolete("Use ZipFile/Zip*Stream StringCodec instead")]
public static int SystemDefaultCodePage => StringCodec.SystemDefaultCodePage;
/// <inheritdoc cref="ZipStrings"/>
[Obsolete("Use ZipFile/Zip*Stream StringCodec instead")]
public static bool UseUnicode
{
get => !CompatCodec.ForceZipLegacyEncoding;
set
{
CompatCodec.ForceZipLegacyEncoding = !value;
compatibilityMode = true;
}
}
/// <inheritdoc cref="ZipStrings"/>
[Obsolete("Use ZipFile/Zip*Stream StringCodec instead")]
private static bool HasUnicodeFlag(int flags)
=> ((GeneralBitFlags)flags).HasFlag(GeneralBitFlags.UnicodeText);
/// <inheritdoc cref="ZipStrings"/>
[Obsolete("Use ZipFile/Zip*Stream StringCodec instead")]
public static string ConvertToString(byte[] data, int count)
=> CompatCodec.ZipOutputEncoding.GetString(data, 0, count);
/// <inheritdoc cref="ZipStrings"/>
[Obsolete("Use ZipFile/Zip*Stream StringCodec instead")]
public static string ConvertToString(byte[] data)
=> CompatCodec.ZipOutputEncoding.GetString(data);
/// <inheritdoc cref="ZipStrings"/>
[Obsolete("Use ZipFile/Zip*Stream StringCodec instead")]
public static string ConvertToStringExt(int flags, byte[] data, int count)
=> CompatCodec.ZipEncoding(HasUnicodeFlag(flags)).GetString(data, 0, count);
/// <inheritdoc cref="ZipStrings"/>
[Obsolete("Use ZipFile/Zip*Stream StringCodec instead")]
public static string ConvertToStringExt(int flags, byte[] data)
=> CompatCodec.ZipEncoding(HasUnicodeFlag(flags)).GetString(data);
/// <inheritdoc cref="ZipStrings"/>
[Obsolete("Use ZipFile/Zip*Stream StringCodec instead")]
public static byte[] ConvertToArray(string str)
=> ConvertToArray(0, str);
/// <inheritdoc cref="ZipStrings"/>
[Obsolete("Use ZipFile/Zip*Stream StringCodec instead")]
public static byte[] ConvertToArray(int flags, string str)
=> (string.IsNullOrEmpty(str))
? Empty.Array<byte>()
: CompatCodec.ZipEncoding(HasUnicodeFlag(flags)).GetBytes(str);
}
/// <summary>
/// Utility class for resolving the encoding used for reading and writing strings
/// </summary>
public class StringCodec
{
static StringCodec()
{
try
{
var platformCodepage = Encoding.Default.CodePage;
SystemDefaultCodePage = (platformCodepage == 1 || platformCodepage == 2 || platformCodepage == 3 || platformCodepage == 42) ? FallbackCodePage : platformCodepage;
}
catch
{
SystemDefaultCodePage = FallbackCodePage;
}
SystemDefaultEncoding = Encoding.GetEncoding(SystemDefaultCodePage);
}
/// <summary>
/// If set, use the encoding set by <see cref="CodePage"/> for zip entries instead of the defaults
/// </summary>
public bool ForceZipLegacyEncoding { get; set; }
/// <summary>
/// The default encoding used for ZipCrypto passwords in zip files, set to <see cref="SystemDefaultEncoding"/>
/// for greatest compability.
/// </summary>
public static Encoding DefaultZipCryptoEncoding => SystemDefaultEncoding;
/// <summary>
/// Returns the encoding for an output <see cref="ZipEntry"/>.
/// Unless overriden by <see cref="ForceZipLegacyEncoding"/> it returns <see cref="UnicodeZipEncoding"/>.
/// </summary>
public Encoding ZipOutputEncoding => ZipEncoding(!ForceZipLegacyEncoding);
/// <summary>
/// Returns <see cref="UnicodeZipEncoding"/> if <paramref name="unicode"/> is set, otherwise it returns the encoding indicated by <see cref="CodePage"/>
/// </summary>
public Encoding ZipEncoding(bool unicode) => unicode ? UnicodeZipEncoding : _legacyEncoding;
/// <summary>
/// Returns the appropriate encoding for an input <see cref="ZipEntry"/> according to <paramref name="flags"/>.
/// If overridden by <see cref="ForceZipLegacyEncoding"/>, it always returns the encoding indicated by <see cref="CodePage"/>.
/// </summary>
/// <param name="flags"></param>
/// <returns></returns>
public Encoding ZipInputEncoding(GeneralBitFlags flags) => ZipInputEncoding((int)flags);
/// <inheritdoc cref="ZipInputEncoding(GeneralBitFlags)"/>
public Encoding ZipInputEncoding(int flags) => ZipEncoding(!ForceZipLegacyEncoding && (flags & (int)GeneralBitFlags.UnicodeText) != 0);
/// <summary>Code page encoding, used for non-unicode strings</summary>
/// <remarks>
/// The original Zip specification (https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT) states
/// that file names should only be encoded with IBM Code Page 437 or UTF-8.
/// In practice, most zip apps use OEM or system encoding (typically cp437 on Windows).
/// Let's be good citizens and default to UTF-8 http://utf8everywhere.org/
/// </remarks>
private Encoding _legacyEncoding = SystemDefaultEncoding;
private Encoding _zipArchiveCommentEncoding;
private Encoding _zipCryptoEncoding;
/// <summary>
/// Returns the UTF-8 code page (65001) used for zip entries with unicode flag set
/// </summary>
public static readonly Encoding UnicodeZipEncoding = Encoding.UTF8;
/// <summary>
/// Code page used for non-unicode strings and legacy zip encoding (if <see cref="ForceZipLegacyEncoding"/> is set).
/// Default value is <see cref="SystemDefaultCodePage"/>
/// </summary>
public int CodePage
{
get => _legacyEncoding.CodePage;
set => _legacyEncoding = (value < 4 || value > 65535 || value == 42)
? throw new ArgumentOutOfRangeException(nameof(value))
: Encoding.GetEncoding(value);
}
private const int FallbackCodePage = 437;
/// <summary>
/// Operating system default codepage, or if it could not be retrieved, the fallback code page IBM 437.
/// </summary>
public static int SystemDefaultCodePage { get; }
/// <summary>
/// The system default encoding, based on <see cref="SystemDefaultCodePage"/>
/// </summary>
public static Encoding SystemDefaultEncoding { get; }
/// <summary>
/// The encoding used for the zip archive comment. Defaults to the encoding for <see cref="CodePage"/>, since
/// no unicode flag can be set for it in the files.
/// </summary>
public Encoding ZipArchiveCommentEncoding
{
get => _zipArchiveCommentEncoding ?? _legacyEncoding;
set => _zipArchiveCommentEncoding = value;
}
/// <summary>
/// The encoding used for the ZipCrypto passwords. Defaults to <see cref="DefaultZipCryptoEncoding"/>.
/// </summary>
public Encoding ZipCryptoEncoding
{
get => _zipCryptoEncoding ?? DefaultZipCryptoEncoding;
set => _zipCryptoEncoding = value;
}
}
}