-
Notifications
You must be signed in to change notification settings - Fork 0
/
LineEndingMode.cs
269 lines (240 loc) · 12.3 KB
/
LineEndingMode.cs
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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
//
// Copyright (c) 2004-2019 Jaroslaw Kowalski <jaak@jkowalski.net>, Kim Christensen, Julian Verdurmen
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Jaroslaw Kowalski nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
//
using System;
using System.ComponentModel;
using System.Globalization;
using JetBrains.Annotations;
using NLog.Internal;
namespace NLog.Targets
{
/// <summary>
/// Line ending mode.
/// </summary>
#if !NETSTANDARD1_3
[TypeConverter(typeof(LineEndingModeConverter))]
#endif
public sealed class LineEndingMode : IEquatable<LineEndingMode>
{
/// <summary>
/// Insert platform-dependent end-of-line sequence after each line.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Type is immutable")]
public static readonly LineEndingMode Default = new LineEndingMode("Default", EnvironmentHelper.NewLine);
/// <summary>
/// Insert CR LF sequence (ASCII 13, ASCII 10) after each line.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Type is immutable")]
public static readonly LineEndingMode CRLF = new LineEndingMode("CRLF", "\r\n");
/// <summary>
/// Insert CR character (ASCII 13) after each line.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Type is immutable")]
public static readonly LineEndingMode CR = new LineEndingMode("CR", "\r");
/// <summary>
/// Insert LF character (ASCII 10) after each line.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Type is immutable")]
public static readonly LineEndingMode LF = new LineEndingMode("LF", "\n");
/// <summary>
/// Insert null terminator (ASCII 0) after each line.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Type is immutable")]
public static readonly LineEndingMode Null = new LineEndingMode("Null", "\0");
/// <summary>
/// Do not insert any line ending.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "Type is immutable")]
public static readonly LineEndingMode None = new LineEndingMode("None", string.Empty);
private readonly string _name;
private readonly string _newLineCharacters;
/// <summary>
/// Gets the name of the LineEndingMode instance.
/// </summary>
public string Name => _name;
/// <summary>
/// Gets the new line characters (value) of the LineEndingMode instance.
/// </summary>
public string NewLineCharacters => _newLineCharacters;
private LineEndingMode() { }
/// <summary>
/// Initializes a new instance of <see cref="LogLevel"/>.
/// </summary>
/// <param name="name">The mode name.</param>
/// <param name="newLineCharacters">The new line characters to be used.</param>
private LineEndingMode(string name, string newLineCharacters)
{
_name = name;
_newLineCharacters = newLineCharacters;
}
/// <summary>
/// Returns the <see cref="LineEndingMode"/> that corresponds to the supplied <paramref name="name"/>.
/// </summary>
/// <param name="name">
/// The textual representation of the line ending mode, such as CRLF, LF, Default etc.
/// Name is not case sensitive.
/// </param>
/// <returns>The <see cref="LineEndingMode"/> value, that corresponds to the <paramref name="name"/>.</returns>
/// <exception cref="ArgumentOutOfRangeException">There is no line ending mode with the specified name.</exception>
public static LineEndingMode FromString([NotNull] string name)
{
if (name == null) throw new ArgumentNullException(nameof(name));
if (name.Equals(CRLF.Name, StringComparison.OrdinalIgnoreCase)) return CRLF;
if (name.Equals(LF.Name, StringComparison.OrdinalIgnoreCase)) return LF;
if (name.Equals(CR.Name, StringComparison.OrdinalIgnoreCase)) return CR;
if (name.Equals(Default.Name, StringComparison.OrdinalIgnoreCase)) return Default;
if (name.Equals(Null.Name, StringComparison.OrdinalIgnoreCase)) return Null;
if (name.Equals(None.Name, StringComparison.OrdinalIgnoreCase)) return None;
#if !SILVERLIGHT
throw new ArgumentOutOfRangeException(nameof(name), name, "LineEndingMode is out of range");
#else
throw new ArgumentOutOfRangeException("name", "LineEndingMode is out of range");
#endif
}
/// <summary>
/// Compares two <see cref="LineEndingMode"/> objects and returns a
/// value indicating whether the first one is equal to the second one.
/// </summary>
/// <param name="mode1">The first level.</param>
/// <param name="mode2">The second level.</param>
/// <returns>The value of <c>mode1.NewLineCharacters == mode2.NewLineCharacters</c>.</returns>
public static bool operator ==(LineEndingMode mode1, LineEndingMode mode2)
{
if (ReferenceEquals(mode1, null))
{
return ReferenceEquals(mode2, null);
}
if (ReferenceEquals(mode2, null))
{
return false;
}
return mode1.NewLineCharacters == mode2.NewLineCharacters;
}
/// <summary>
/// Compares two <see cref="LineEndingMode"/> objects and returns a
/// value indicating whether the first one is not equal to the second one.
/// </summary>
/// <param name="mode1">The first mode</param>
/// <param name="mode2">The second mode</param>
/// <returns>The value of <c>mode1.NewLineCharacters != mode2.NewLineCharacters</c>.</returns>
public static bool operator !=(LineEndingMode mode1, LineEndingMode mode2)
{
if (ReferenceEquals(mode1, null))
{
return !ReferenceEquals(mode2, null);
}
if (ReferenceEquals(mode2, null))
{
return true;
}
return mode1.NewLineCharacters != mode2.NewLineCharacters;
}
/// <summary>
/// Returns a string representation of the log level.
/// </summary>
/// <returns>Log level name.</returns>
public override string ToString()
{
return Name;
}
/// <summary>
/// Returns a hash code for this instance.
/// </summary>
/// <returns>
/// A hash code for this instance, suitable for use in hashing algorithms
/// and data structures like a hash table.
/// </returns>
public override int GetHashCode()
{
return (_newLineCharacters != null ? _newLineCharacters.GetHashCode() : 0);
}
/// <summary>
/// Determines whether the specified <see cref="System.Object"/> is
/// equal to this instance.
/// </summary>
/// <param name="obj">The <see cref="System.Object"/> to compare with
/// this instance.</param>
/// <returns>
/// Value of <c>true</c> if the specified <see cref="System.Object"/>
/// is equal to this instance; otherwise, <c>false</c>.
/// </returns>
/// <exception cref="T:System.NullReferenceException">
/// The <paramref name="obj"/> parameter is null.
/// </exception>
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
return obj is LineEndingMode mode && Equals(mode);
}
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
/// <returns>true if the current object is equal to the <paramref name="other" /> parameter; otherwise, false.</returns>
/// <param name="other">An object to compare with this object.</param>
public bool Equals(LineEndingMode other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return string.Equals(_newLineCharacters, other._newLineCharacters);
}
#if !NETSTANDARD1_3
/// <summary>
/// Provides a type converter to convert <see cref="LineEndingMode"/> objects to and from other representations.
/// </summary>
public class LineEndingModeConverter : TypeConverter
{
/// <summary>
/// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context.
/// </summary>
/// <returns>
/// true if this converter can perform the conversion; otherwise, false.
/// </returns>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context. </param><param name="sourceType">A <see cref="T:System.Type"/> that represents the type you want to convert from. </param>
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}
/// <summary>
/// Converts the given object to the type of this converter, using the specified context and culture information.
/// </summary>
/// <returns>
/// An <see cref="T:System.Object"/> that represents the converted value.
/// </returns>
/// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"/> that provides a format context. </param><param name="culture">The <see cref="T:System.Globalization.CultureInfo"/> to use as the current culture. </param><param name="value">The <see cref="T:System.Object"/> to convert. </param><exception cref="T:System.NotSupportedException">The conversion cannot be performed. </exception>
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
var name = value as string;
return name != null ? FromString(name) : base.ConvertFrom(context, culture, value);
}
}
#endif
}
}