forked from PowerShell/PowerShell
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEncodingUtils.cs
More file actions
159 lines (142 loc) · 6.25 KB
/
EncodingUtils.cs
File metadata and controls
159 lines (142 loc) · 6.25 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
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Management.Automation.Internal;
namespace System.Management.Automation
{
internal static class EncodingConversion
{
internal const string ANSI = "ansi";
internal const string Ascii = "ascii";
internal const string BigEndianUnicode = "bigendianunicode";
internal const string BigEndianUtf32 = "bigendianutf32";
internal const string Default = "default";
internal const string OEM = "oem";
internal const string String = "string";
internal const string Unicode = "unicode";
internal const string Unknown = "unknown";
internal const string Utf7 = "utf7";
internal const string Utf8 = "utf8";
internal const string Utf8Bom = "utf8BOM";
internal const string Utf8NoBom = "utf8NoBOM";
internal const string Utf32 = "utf32";
internal static readonly string[] TabCompletionResults = {
ANSI, Ascii, BigEndianUnicode, BigEndianUtf32, OEM, Unicode, Utf7, Utf8, Utf8Bom, Utf8NoBom, Utf32
};
internal static readonly Dictionary<string, Encoding> encodingMap = new(StringComparer.OrdinalIgnoreCase)
{
{ ANSI, Encoding.GetEncoding(CultureInfo.CurrentCulture.TextInfo.ANSICodePage) },
{ Ascii, Encoding.ASCII },
{ BigEndianUnicode, Encoding.BigEndianUnicode },
{ BigEndianUtf32, new UTF32Encoding(bigEndian: true, byteOrderMark: true) },
{ Default, Encoding.Default },
{ OEM, ClrFacade.GetOEMEncoding() },
{ String, Encoding.Unicode },
{ Unicode, Encoding.Unicode },
{ Unknown, Encoding.Unicode },
#pragma warning disable SYSLIB0001
{ Utf7, Encoding.UTF7 },
#pragma warning restore SYSLIB0001
{ Utf8, Encoding.Default },
{ Utf8Bom, Encoding.UTF8 },
{ Utf8NoBom, Encoding.Default },
{ Utf32, Encoding.UTF32 },
};
/// <summary>
/// Retrieve the encoding parameter from the command line
/// it throws if the encoding does not match the known ones.
/// </summary>
/// <returns>A System.Text.Encoding object (null if no encoding specified).</returns>
internal static Encoding Convert(Cmdlet cmdlet, string encoding)
{
if (string.IsNullOrEmpty(encoding))
{
// no parameter passed, default to UTF8
return Encoding.Default;
}
if (encodingMap.TryGetValue(encoding, out Encoding foundEncoding))
{
// Write a warning if using utf7 as it is obsolete in .NET5
if (string.Equals(encoding, Utf7, StringComparison.OrdinalIgnoreCase))
{
cmdlet.WriteWarning(PathUtilsStrings.Utf7EncodingObsolete);
}
return foundEncoding;
}
// error condition: unknown encoding value
string validEncodingValues = string.Join(", ", TabCompletionResults);
string msg = StringUtil.Format(PathUtilsStrings.OutFile_WriteToFileEncodingUnknown, encoding, validEncodingValues);
ErrorRecord errorRecord = new ErrorRecord(
PSTraceSource.NewArgumentException("Encoding"),
"WriteToFileEncodingUnknown",
ErrorCategory.InvalidArgument,
null);
errorRecord.ErrorDetails = new ErrorDetails(msg);
cmdlet.ThrowTerminatingError(errorRecord);
return null;
}
/// <summary>
/// Warn if the encoding has been designated as obsolete.
/// </summary>
/// <param name="cmdlet">A cmdlet instance which is used to emit the warning.</param>
/// <param name="encoding">The encoding to check for obsolescence.</param>
internal static void WarnIfObsolete(Cmdlet cmdlet, Encoding encoding)
{
// Check for UTF-7 by checking for code page 65000
// See: https://learn.microsoft.com/dotnet/core/compatibility/corefx#utf-7-code-paths-are-obsolete
if (encoding != null && encoding.CodePage == 65000)
{
cmdlet.WriteWarning(PathUtilsStrings.Utf7EncodingObsolete);
}
}
}
/// <summary>
/// To make it easier to specify -Encoding parameter, we add an ArgumentTransformationAttribute here.
/// When the input data is of type string and is valid to be converted to System.Text.Encoding, we do
/// the conversion and return the converted value. Otherwise, we just return the input data.
/// </summary>
internal sealed class ArgumentToEncodingTransformationAttribute : ArgumentTransformationAttribute
{
public override object Transform(EngineIntrinsics engineIntrinsics, object inputData)
{
inputData = PSObject.Base(inputData);
switch (inputData)
{
case string stringName:
if (EncodingConversion.encodingMap.TryGetValue(stringName, out Encoding foundEncoding))
{
return foundEncoding;
}
else
{
return Encoding.GetEncoding(stringName);
}
case int intName:
return Encoding.GetEncoding(intName);
}
return inputData;
}
}
/// <summary>
/// Provides the set of Encoding values for tab completion of an Encoding parameter.
/// </summary>
internal sealed class ArgumentEncodingCompletionsAttribute : ArgumentCompletionsAttribute
{
public ArgumentEncodingCompletionsAttribute() : base(
EncodingConversion.ANSI,
EncodingConversion.Ascii,
EncodingConversion.BigEndianUnicode,
EncodingConversion.BigEndianUtf32,
EncodingConversion.OEM,
EncodingConversion.Unicode,
EncodingConversion.Utf7,
EncodingConversion.Utf8,
EncodingConversion.Utf8Bom,
EncodingConversion.Utf8NoBom,
EncodingConversion.Utf32
)
{ }
}
}