mirror of https://github.com/icsharpcode/ILSpy.git
				
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							382 lines
						
					
					
						
							9.7 KiB
						
					
					
				
			
		
		
	
	
							382 lines
						
					
					
						
							9.7 KiB
						
					
					
				#nullable enable | 
						|
// | 
						|
// UnicodeNewline.cs | 
						|
// | 
						|
// Author: | 
						|
//       Mike Krüger <mkrueger@xamarin.com> | 
						|
// | 
						|
// Copyright (c) 2013 Xamarin Inc. (http://xamarin.com) | 
						|
// | 
						|
// Permission is hereby granted, free of charge, to any person obtaining a copy | 
						|
// of this software and associated documentation files (the "Software"), to deal | 
						|
// in the Software without restriction, including without limitation the rights | 
						|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | 
						|
// copies of the Software, and to permit persons to whom the Software is | 
						|
// furnished to do so, subject to the following conditions: | 
						|
// | 
						|
// The above copyright notice and this permission notice shall be included in | 
						|
// all copies or substantial portions of the Software. | 
						|
// | 
						|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
						|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
						|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | 
						|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 
						|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 
						|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | 
						|
// THE SOFTWARE. | 
						|
using System; | 
						|
 | 
						|
namespace ICSharpCode.Decompiler.Util | 
						|
{ | 
						|
	public enum UnicodeNewline | 
						|
	{ | 
						|
		Unknown, | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Line Feed, U+000A | 
						|
		/// </summary> | 
						|
		LF = 0x0A, | 
						|
 | 
						|
 | 
						|
		CRLF = 0x0D0A, | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Carriage Return, U+000D | 
						|
		/// </summary> | 
						|
		CR = 0x0D, | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Next Line, U+0085 | 
						|
		/// </summary> | 
						|
		NEL = 0x85, | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Vertical Tab, U+000B | 
						|
		/// </summary> | 
						|
		VT = 0x0B, | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Form Feed, U+000C | 
						|
		/// </summary> | 
						|
		FF = 0x0C, | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Line Separator, U+2028 | 
						|
		/// </summary> | 
						|
		LS = 0x2028, | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Paragraph Separator, U+2029 | 
						|
		/// </summary> | 
						|
		PS = 0x2029 | 
						|
	} | 
						|
 | 
						|
 | 
						|
	/// <summary> | 
						|
	/// Defines unicode new lines according to  Unicode Technical Report #13 | 
						|
	/// http://www.unicode.org/standard/reports/tr13/tr13-5.html | 
						|
	/// </summary> | 
						|
	public static class NewLine | 
						|
	{ | 
						|
		/// <summary> | 
						|
		/// Carriage Return, U+000D | 
						|
		/// </summary> | 
						|
		public const char CR = (char)0x0D; | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Line Feed, U+000A | 
						|
		/// </summary> | 
						|
		public const char LF = (char)0x0A; | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Next Line, U+0085 | 
						|
		/// </summary> | 
						|
		public const char NEL = (char)0x85; | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Vertical Tab, U+000B | 
						|
		/// </summary> | 
						|
		public const char VT = (char)0x0B; | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Form Feed, U+000C | 
						|
		/// </summary> | 
						|
		public const char FF = (char)0x0C; | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Line Separator, U+2028 | 
						|
		/// </summary> | 
						|
		public const char LS = (char)0x2028; | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Paragraph Separator, U+2029 | 
						|
		/// </summary> | 
						|
		public const char PS = (char)0x2029; | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Determines if a char is a new line delimiter. | 
						|
		/// </summary> | 
						|
		/// <returns>0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter.</returns> | 
						|
		/// <param name="curChar">The current character.</param> | 
						|
		/// <param name="nextChar">A callback getting the next character (may be null).</param> | 
						|
		public static int GetDelimiterLength(char curChar, Func<char>? nextChar = null) | 
						|
		{ | 
						|
			if (curChar == CR) | 
						|
			{ | 
						|
				if (nextChar != null && nextChar() == LF) | 
						|
					return 2; | 
						|
				return 1; | 
						|
			} | 
						|
 | 
						|
			if (curChar == LF || curChar == NEL || curChar == VT || curChar == FF || curChar == LS || curChar == PS) | 
						|
				return 1; | 
						|
			return 0; | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Determines if a char is a new line delimiter. | 
						|
		/// </summary> | 
						|
		/// <returns>0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter.</returns> | 
						|
		/// <param name="curChar">The current character.</param> | 
						|
		/// <param name="nextChar">The next character (if != LF then length will always be 0 or 1).</param> | 
						|
		public static int GetDelimiterLength(char curChar, char nextChar) | 
						|
		{ | 
						|
			if (curChar == CR) | 
						|
			{ | 
						|
				if (nextChar == LF) | 
						|
					return 2; | 
						|
				return 1; | 
						|
			} | 
						|
 | 
						|
			if (curChar == LF || curChar == NEL || curChar == VT || curChar == FF || curChar == LS || curChar == PS) | 
						|
				return 1; | 
						|
			return 0; | 
						|
		} | 
						|
 | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Determines if a char is a new line delimiter. | 
						|
		/// </summary> | 
						|
		/// <returns>0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter.</returns> | 
						|
		/// <param name="curChar">The current character.</param> | 
						|
		/// <param name = "length">The length of the delimiter</param> | 
						|
		/// <param name = "type">The type of the delimiter</param> | 
						|
		/// <param name="nextChar">A callback getting the next character (may be null).</param> | 
						|
		public static bool TryGetDelimiterLengthAndType(char curChar, out int length, out UnicodeNewline type, Func<char>? nextChar = null) | 
						|
		{ | 
						|
			if (curChar == CR) | 
						|
			{ | 
						|
				if (nextChar != null && nextChar() == LF) | 
						|
				{ | 
						|
					length = 2; | 
						|
					type = UnicodeNewline.CRLF; | 
						|
				} | 
						|
				else | 
						|
				{ | 
						|
					length = 1; | 
						|
					type = UnicodeNewline.CR; | 
						|
 | 
						|
				} | 
						|
				return true; | 
						|
			} | 
						|
 | 
						|
			switch (curChar) | 
						|
			{ | 
						|
				case LF: | 
						|
					type = UnicodeNewline.LF; | 
						|
					length = 1; | 
						|
					return true; | 
						|
				case NEL: | 
						|
					type = UnicodeNewline.NEL; | 
						|
					length = 1; | 
						|
					return true; | 
						|
				case VT: | 
						|
					type = UnicodeNewline.VT; | 
						|
					length = 1; | 
						|
					return true; | 
						|
				case FF: | 
						|
					type = UnicodeNewline.FF; | 
						|
					length = 1; | 
						|
					return true; | 
						|
				case LS: | 
						|
					type = UnicodeNewline.LS; | 
						|
					length = 1; | 
						|
					return true; | 
						|
				case PS: | 
						|
					type = UnicodeNewline.PS; | 
						|
					length = 1; | 
						|
					return true; | 
						|
			} | 
						|
			length = -1; | 
						|
			type = UnicodeNewline.Unknown; | 
						|
			return false; | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Determines if a char is a new line delimiter. | 
						|
		/// </summary> | 
						|
		/// <returns>0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter.</returns> | 
						|
		/// <param name="curChar">The current character.</param> | 
						|
		/// <param name = "length">The length of the delimiter</param> | 
						|
		/// <param name = "type">The type of the delimiter</param> | 
						|
		/// <param name="nextChar">The next character (if != LF then length will always be 0 or 1).</param> | 
						|
		public static bool TryGetDelimiterLengthAndType(char curChar, out int length, out UnicodeNewline type, char nextChar) | 
						|
		{ | 
						|
			if (curChar == CR) | 
						|
			{ | 
						|
				if (nextChar == LF) | 
						|
				{ | 
						|
					length = 2; | 
						|
					type = UnicodeNewline.CRLF; | 
						|
				} | 
						|
				else | 
						|
				{ | 
						|
					length = 1; | 
						|
					type = UnicodeNewline.CR; | 
						|
 | 
						|
				} | 
						|
				return true; | 
						|
			} | 
						|
 | 
						|
			switch (curChar) | 
						|
			{ | 
						|
				case LF: | 
						|
					type = UnicodeNewline.LF; | 
						|
					length = 1; | 
						|
					return true; | 
						|
				case NEL: | 
						|
					type = UnicodeNewline.NEL; | 
						|
					length = 1; | 
						|
					return true; | 
						|
				case VT: | 
						|
					type = UnicodeNewline.VT; | 
						|
					length = 1; | 
						|
					return true; | 
						|
				case FF: | 
						|
					type = UnicodeNewline.FF; | 
						|
					length = 1; | 
						|
					return true; | 
						|
				case LS: | 
						|
					type = UnicodeNewline.LS; | 
						|
					length = 1; | 
						|
					return true; | 
						|
				case PS: | 
						|
					type = UnicodeNewline.PS; | 
						|
					length = 1; | 
						|
					return true; | 
						|
			} | 
						|
			length = -1; | 
						|
			type = UnicodeNewline.Unknown; | 
						|
			return false; | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets the new line type of a given char/next char. | 
						|
		/// </summary> | 
						|
		/// <returns>0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter.</returns> | 
						|
		/// <param name="curChar">The current character.</param> | 
						|
		/// <param name="nextChar">A callback getting the next character (may be null).</param> | 
						|
		public static UnicodeNewline GetDelimiterType(char curChar, Func<char>? nextChar = null) | 
						|
		{ | 
						|
			switch (curChar) | 
						|
			{ | 
						|
				case CR: | 
						|
					if (nextChar != null && nextChar() == LF) | 
						|
						return UnicodeNewline.CRLF; | 
						|
					return UnicodeNewline.CR; | 
						|
				case LF: | 
						|
					return UnicodeNewline.LF; | 
						|
				case NEL: | 
						|
					return UnicodeNewline.NEL; | 
						|
				case VT: | 
						|
					return UnicodeNewline.VT; | 
						|
				case FF: | 
						|
					return UnicodeNewline.FF; | 
						|
				case LS: | 
						|
					return UnicodeNewline.LS; | 
						|
				case PS: | 
						|
					return UnicodeNewline.PS; | 
						|
			} | 
						|
			return UnicodeNewline.Unknown; | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets the new line type of a given char/next char. | 
						|
		/// </summary> | 
						|
		/// <returns>0 == no new line, otherwise it returns either 1 or 2 depending of the length of the delimiter.</returns> | 
						|
		/// <param name="curChar">The current character.</param> | 
						|
		/// <param name="nextChar">The next character (if != LF then length will always be 0 or 1).</param> | 
						|
		public static UnicodeNewline GetDelimiterType(char curChar, char nextChar) | 
						|
		{ | 
						|
			switch (curChar) | 
						|
			{ | 
						|
				case CR: | 
						|
					if (nextChar == LF) | 
						|
						return UnicodeNewline.CRLF; | 
						|
					return UnicodeNewline.CR; | 
						|
				case LF: | 
						|
					return UnicodeNewline.LF; | 
						|
				case NEL: | 
						|
					return UnicodeNewline.NEL; | 
						|
				case VT: | 
						|
					return UnicodeNewline.VT; | 
						|
				case FF: | 
						|
					return UnicodeNewline.FF; | 
						|
				case LS: | 
						|
					return UnicodeNewline.LS; | 
						|
				case PS: | 
						|
					return UnicodeNewline.PS; | 
						|
			} | 
						|
			return UnicodeNewline.Unknown; | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Determines if a char is a new line delimiter.  | 
						|
		///  | 
						|
		/// Note that the only 2 char wide new line is CR LF and both chars are new line | 
						|
		/// chars on their own. For most cases GetDelimiterLength is the better choice. | 
						|
		/// </summary> | 
						|
		public static bool IsNewLine(char ch) | 
						|
		{ | 
						|
			return | 
						|
				ch == NewLine.CR || | 
						|
				ch == NewLine.LF || | 
						|
				ch == NewLine.NEL || | 
						|
				ch == NewLine.VT || | 
						|
				ch == NewLine.FF || | 
						|
				ch == NewLine.LS || | 
						|
				ch == NewLine.PS; | 
						|
		} | 
						|
 | 
						|
		/// <summary> | 
						|
		/// Gets the new line as a string. | 
						|
		/// </summary> | 
						|
		public static string GetString(UnicodeNewline newLine) | 
						|
		{ | 
						|
			switch (newLine) | 
						|
			{ | 
						|
				case UnicodeNewline.Unknown: | 
						|
					return ""; | 
						|
				case UnicodeNewline.LF: | 
						|
					return "\n"; | 
						|
				case UnicodeNewline.CRLF: | 
						|
					return "\r\n"; | 
						|
				case UnicodeNewline.CR: | 
						|
					return "\r"; | 
						|
				case UnicodeNewline.NEL: | 
						|
					return "\u0085"; | 
						|
				case UnicodeNewline.VT: | 
						|
					return "\u000B"; | 
						|
				case UnicodeNewline.FF: | 
						|
					return "\u000C"; | 
						|
				case UnicodeNewline.LS: | 
						|
					return "\u2028"; | 
						|
				case UnicodeNewline.PS: | 
						|
					return "\u2029"; | 
						|
				default: | 
						|
					throw new ArgumentOutOfRangeException(); | 
						|
			} | 
						|
		} | 
						|
	} | 
						|
} | 
						|
 | 
						|
 |