/// <summary> /// Gets the description of the FileLineTypes enumeration value using either custom description or the name of the enumeration value. /// </summary> /// <param name="fileLineTypes">A FileLineTypes enumeration value to get the description for.</param> /// <param name="useEnumName">A flag indicating if name of the enumeration value should be returned.</param> /// <returns>A description for the given <paramref name="fileLineTypes"/> enumeration value.</returns> public static string GetLineEndingDescriptionByEnumeration(FileLineTypes fileLineTypes, bool useEnumName) { // the name of the enumeration was requested.. if (useEnumName) { // ..so do return it.. return(Enum.GetName(typeof(FileLineTypes), fileLineTypes)); } // a simple switch..case structure.. switch (fileLineTypes) { case FileLineTypes.CRLF: return(CRLF_Description); case FileLineTypes.LF: return(LF_Description); case FileLineTypes.CR: return(CR_Description); case FileLineTypes.RS: return(RS_Description); case FileLineTypes.LFCR: return(LFCR_Description); case FileLineTypes.NL: return(NL_Description); case FileLineTypes.ATASCII: return(ATASCII_Description); case FileLineTypes.NEWLINE: return(NEWLINE_Description); case FileLineTypes.Unknown: return(Unknown_Description); case FileLineTypes.Mixed: return(Mixed_Description); case FileLineTypes.UCRLF: return(UCRLF_Description); case FileLineTypes.ULF: return(ULF_Description); case FileLineTypes.UCR: return(UCR_Description); case FileLineTypes.ULFCR: return(ULFCR_Description); default: return(Unknown_Description); } }
/// <summary> /// Gets the file line types of a text and a given encoding. /// </summary> /// <param name="contents">The text of which contents to check for the line endings.</param> /// <param name="encoding">The encoding of the text.</param> /// <param name="fileLineTypes">The types of line endings wanted to be included in the search.</param> /// <returns>A collection of line ending key value pairs with their enumeration values and their names.</returns> public static IEnumerable <KeyValuePair <FileLineTypes, string> > GetFileLineTypes( string contents, System.Text.Encoding encoding, FileLineTypes fileLineTypes = // the default set.. FileLineTypes.CR | FileLineTypes.CRLF | FileLineTypes.LF | FileLineTypes.LFCR | FileLineTypes.UCR | FileLineTypes.UCRLF | FileLineTypes.ULF | FileLineTypes.ULFCR) { return(GetFileLineTypes(encoding.GetBytes(contents))); }
/// <summary> /// Sets a description for a given <see cref="FileLineTypes"/> enumeration. This method is for localization purposes. /// </summary> /// <param name="fileLineTypes">A <see cref="FileLineTypes"/> value to set a description for.</param> /// <param name="description">The description to set for a <paramref name="fileLineTypes"/> value.</param> /// <returns>True if the description was successfully set; otherwise false.</returns> public static bool SetLineEndingDescriptionByEnumeration(FileLineTypes fileLineTypes, string description) { // a simple switch..case structure.. switch (fileLineTypes) { case FileLineTypes.CRLF: CRLF_Description = description; return(true); case FileLineTypes.LF: LF_Description = description; return(true); case FileLineTypes.CR: CR_Description = description; return(true); case FileLineTypes.RS: RS_Description = description; return(true); case FileLineTypes.LFCR: LFCR_Description = description; return(true); case FileLineTypes.NL: NL_Description = description; return(true); case FileLineTypes.ATASCII: ATASCII_Description = description; return(true); case FileLineTypes.NEWLINE: NEWLINE_Description = description; return(true); case FileLineTypes.Unknown: Unknown_Description = description; return(true); case FileLineTypes.Mixed: Mixed_Description = description; return(true); case FileLineTypes.UCRLF: UCRLF_Description = description; return(true); case FileLineTypes.ULF: ULF_Description = description; return(true); case FileLineTypes.UCR: UCR_Description = description; return(true); case FileLineTypes.ULFCR: ULFCR_Description = description; return(true); default: return(false); } }
/// <summary> /// Gets the file line ending as a string representation. /// </summary> /// <param name="fileLineTypes">The <see cref="FileLineTypes"/> enumeration value.</param> /// <returns>A string containing the line ending characters.</returns> public static string GetFileLineEndingString(FileLineTypes fileLineTypes) { // a simple switch..case structure.. switch (fileLineTypes) { case FileLineTypes.CRLF: return("\r\n"); case FileLineTypes.LF: return("\n"); case FileLineTypes.CR: return("\r"); case FileLineTypes.RS: return(((char)0x1E).ToString()); case FileLineTypes.LFCR: return("\n\r"); case FileLineTypes.NL: return(((char)0x15).ToString()); case FileLineTypes.ATASCII: return(((char)155).ToString()); case FileLineTypes.NEWLINE: return(((char)0x76).ToString()); case FileLineTypes.Unknown: return(Environment.NewLine); case FileLineTypes.Mixed: return(Environment.NewLine); case FileLineTypes.UCRLF: return("\r\n"); case FileLineTypes.ULF: return("\n"); case FileLineTypes.UCR: return("\r"); case FileLineTypes.ULFCR: return("\n\r"); default: return(Environment.NewLine); } }
/// <summary> /// Gets the file line types of a given memory stream. /// </summary> /// <param name="buffer">The byte array to be used to check for the line endings.</param> /// <param name="useLessCommon">An flag indicating if the less common line endings should also be checked.</param> /// <returns>A collection of line ending key value pairs with their enumeration values and their names.</returns> public static IEnumerable <KeyValuePair <FileLineTypes, string> > GetFileLineTypes(byte[] buffer, bool useLessCommon) { // construct an enumeration of the "common" line ending enumerations.. FileLineTypes fileLineTypes = // the default set.. FileLineTypes.CR | FileLineTypes.CRLF | FileLineTypes.LF | FileLineTypes.LFCR | FileLineTypes.UCR | FileLineTypes.UCRLF | FileLineTypes.ULF | FileLineTypes.ULFCR; // if the less common line endings are required.. if (useLessCommon) { // add them to the enumeration.. fileLineTypes |= FileLineTypes.NEWLINE | FileLineTypes.NL | FileLineTypes.RS | FileLineTypes.ATASCII; } // call the suitable overload.. return(GetFileLineTypes(buffer, fileLineTypes)); }
/// <summary> /// Gets the file line types of a given memory stream. /// </summary> /// <param name="stream">The memory stream to be used to check for the line endings.</param> /// <param name="fileLineTypes">The types of line endings wanted to be included in the search.</param> /// <returns>A collection of line ending key value pairs with their enumeration values and their names.</returns> public static IEnumerable <KeyValuePair <FileLineTypes, string> > GetFileLineTypes(MemoryStream stream, FileLineTypes fileLineTypes = // the default set.. FileLineTypes.CR | FileLineTypes.CRLF | FileLineTypes.LF | FileLineTypes.LFCR | FileLineTypes.UCR | FileLineTypes.UCRLF | FileLineTypes.ULF | FileLineTypes.ULFCR) { // do note that this is the "master" method of the overloads, so the logic is going to be weird.. List <KeyValuePair <FileLineTypes, string> > result = new List <KeyValuePair <FileLineTypes, string> >(); // the contents of the given memory stream is requires as a byte array.. byte[] contentsBytes = stream.ToArray(); // indicators if a negative or positive index for the byte array // search was given.. bool eof1, eof2, eof3; // initialize the loop variable.. int i = 0; // loop through the bytes in the array.. while (i < contentsBytes.Length) { // comparison of CR+LF without Unicode.. if (ContainsBytes(i, contentsBytes, new byte[] { 0x0D, 0x0A }, out eof1)) { if (eof1) // check for an overflow of the byte array.. { // the index was outside the byte array so do // increase the loop variable by one and continue.. i++; continue; } i += 2; // increase the loop variable by the amount of bytes used in the comparison.. // check that the result value doesn't already contain the given enumeration and string pair.. if (!result.Exists(f => f.Key == FileLineTypes.CRLF) && fileLineTypes.HasFlag(FileLineTypes.CRLF)) { result.Add( new KeyValuePair <FileLineTypes, string>(FileLineTypes.CRLF, GetLineEndingDescriptionByEnumeration(FileLineTypes.CRLF, UseEnumNames))); } continue; // match found so do continue the loop.. } // comparison of LF+CR without Unicode.. if (ContainsBytes(i, contentsBytes, new byte[] { 0x0A, 0x0D }, out eof1)) { if (eof1) // check for an overflow of the byte array.. { // the index was outside the byte array so do // increase the loop variable by one and continue.. i++; continue; } i += 2; // increase the loop variable by the amount of bytes used in the comparison.. // check that the result value doesn't already contain the given enumeration and string pair.. if (!result.Exists(f => f.Key == FileLineTypes.LFCR) && fileLineTypes.HasFlag(FileLineTypes.LFCR)) { result.Add( new KeyValuePair <FileLineTypes, string>(FileLineTypes.LFCR, GetLineEndingDescriptionByEnumeration(FileLineTypes.LFCR, UseEnumNames))); } continue; // match found so do continue the loop.. } // comparison of LF without Unicode.. if (ContainsBytes(i, contentsBytes, new byte[] { 0x0A }, out eof1) && !ContainsBytes(i + 1, contentsBytes, new byte[] { 0x0D }, out eof2) && !ContainsBytes(i - 1, contentsBytes, new byte[] { 0x0D }, out eof3)) { if (eof1 || eof2 || eof3) // check for an overflow of the byte array.. { // one or more of the indexes was outside the byte array so do // increase the loop variable by one and continue.. i++; continue; } i++; // increase the loop variable by the amount of bytes used in the comparison.. // check that the result value doesn't already contain the given enumeration and string pair.. if (!result.Exists(f => f.Key == FileLineTypes.LF) && fileLineTypes.HasFlag(FileLineTypes.LF)) { result.Add( new KeyValuePair <FileLineTypes, string>(FileLineTypes.LF, GetLineEndingDescriptionByEnumeration(FileLineTypes.LF, UseEnumNames))); } continue; // match found so do continue the loop.. } // comparison of CR without Unicode.. if (ContainsBytes(i, contentsBytes, new byte[] { 0x0D }, out eof1) && !ContainsBytes(i + 1, contentsBytes, new byte[] { 0x0A }, out eof2) && !ContainsBytes(i - 1, contentsBytes, new byte[] { 0x0A }, out eof3)) { if (eof1 || eof2 || eof3) // check for an overflow of the byte array.. { // one or more of the indexes was outside the byte array so do // increase the loop variable by one and continue.. i++; continue; } i++; // increase the loop variable by the amount of bytes used in the comparison.. // check that the result value doesn't already contain the given enumeration and string pair.. if (!result.Exists(f => f.Key == FileLineTypes.CR) && fileLineTypes.HasFlag(FileLineTypes.CR)) { result.Add( new KeyValuePair <FileLineTypes, string>(FileLineTypes.CR, GetLineEndingDescriptionByEnumeration(FileLineTypes.CR, UseEnumNames))); } continue; // match found so do continue the loop.. } // comparison of CR+LF with Unicode.. if (ContainsBytes(i, contentsBytes, new byte[] { 0x00, 0x0D, 0x00, 0x0A }, out eof1)) { if (eof1) // check for an overflow of the byte array.. { // the index was outside the byte array so do // increase the loop variable by one and continue.. i++; continue; } i += 4; // increase the loop variable by the amount of bytes used in the comparison.. // check that the result value doesn't already contain the given enumeration and string pair.. if (!result.Exists(f => f.Key == FileLineTypes.UCRLF) && fileLineTypes.HasFlag(FileLineTypes.UCRLF)) { result.Add( new KeyValuePair <FileLineTypes, string>(FileLineTypes.UCRLF, GetLineEndingDescriptionByEnumeration(FileLineTypes.UCRLF, UseEnumNames))); } continue; // match found so do continue the loop.. } // comparison of LF+CR with Unicode.. if (ContainsBytes(i, contentsBytes, new byte[] { 0x00, 0x0A, 0x00, 0x0D }, out eof1)) { if (eof1) // check for an overflow of the byte array.. { // the index was outside the byte array so do // increase the loop variable by one and continue.. i++; continue; } i += 4; // increase the loop variable by the amount of bytes used in the comparison.. // check that the result value doesn't already contain the given enumeration and string pair.. if (!result.Exists(f => f.Key == FileLineTypes.ULFCR) && fileLineTypes.HasFlag(FileLineTypes.ULFCR)) { result.Add( new KeyValuePair <FileLineTypes, string>(FileLineTypes.ULFCR, GetLineEndingDescriptionByEnumeration(FileLineTypes.ULFCR, UseEnumNames))); } continue; // match found so do continue the loop.. } // comparison of LF with Unicode.. if (ContainsBytes(i, contentsBytes, new byte[] { 0x00, 0x0A }, out eof1) && !ContainsBytes(i + 2, contentsBytes, new byte[] { 0x00, 0x0D }, out eof2) && !ContainsBytes(i - 2, contentsBytes, new byte[] { 0x00, 0x0D }, out eof3)) { if (eof1 || eof2 || eof3) // check for an overflow of the byte array.. { // one or more of the indexes was outside the byte array so do // increase the loop variable by one and continue.. i++; continue; } i += 2; // increase the loop variable by the amount of bytes used in the comparison.. // check that the result value doesn't already contain the given enumeration and string pair.. if (!result.Exists(f => f.Key == FileLineTypes.ULF) && fileLineTypes.HasFlag(FileLineTypes.ULF)) { result.Add( new KeyValuePair <FileLineTypes, string>(FileLineTypes.ULF, GetLineEndingDescriptionByEnumeration(FileLineTypes.ULF, UseEnumNames))); } continue; // match found so do continue the loop.. } // comparison of CR with Unicode.. if (ContainsBytes(i, contentsBytes, new byte[] { 0x00, 0x0D }, out eof1) && !ContainsBytes(i + 2, contentsBytes, new byte[] { 0x00, 0x0A }, out eof2) && !ContainsBytes(i - 2, contentsBytes, new byte[] { 0x00, 0x0A }, out eof3)) { if (eof1 || eof2 || eof3) // check for an overflow of the byte array.. { // one or more of the indexes was outside the byte array so do // increase the loop variable by one and continue.. i++; continue; } i += 2; // increase the loop variable by the amount of bytes used in the comparison.. // check that the result value doesn't already contain the given enumeration and string pair.. if (!result.Exists(f => f.Key == FileLineTypes.UCR) && fileLineTypes.HasFlag(FileLineTypes.UCR)) { result.Add( new KeyValuePair <FileLineTypes, string>(FileLineTypes.UCR, GetLineEndingDescriptionByEnumeration(FileLineTypes.UCR, UseEnumNames))); } continue; // match found so do continue the loop.. } // comparison of RS (see: FileLineTypes.RS description..).. if (ContainsBytes(i, contentsBytes, new byte[] { 0x1E }, out eof1)) { if (eof1) // check for an overflow of the byte array.. { // the index was outside the byte array so do // increase the loop variable by one and continue.. i++; continue; } i++; // increase the loop variable by the amount of bytes used in the comparison.. // check that the result value doesn't already contain the given enumeration and string pair.. if (!result.Exists(f => f.Key == FileLineTypes.RS) && fileLineTypes.HasFlag(FileLineTypes.RS)) { result.Add( new KeyValuePair <FileLineTypes, string>(FileLineTypes.RS, GetLineEndingDescriptionByEnumeration(FileLineTypes.RS, UseEnumNames))); } continue; // match found so do continue the loop.. } // comparison of NL (see: FileLineTypes.NL description..).. if (ContainsBytes(i, contentsBytes, new byte[] { 0x15 }, out eof1)) { if (eof1) // check for an overflow of the byte array.. { // the index was outside the byte array so do // increase the loop variable by one and continue.. i++; continue; } i++; // increase the loop variable by the amount of bytes used in the comparison.. // check that the result value doesn't already contain the given enumeration and string pair.. if (!result.Exists(f => f.Key == FileLineTypes.NL) && fileLineTypes.HasFlag(FileLineTypes.NL)) { result.Add( new KeyValuePair <FileLineTypes, string>(FileLineTypes.NL, GetLineEndingDescriptionByEnumeration(FileLineTypes.NL, UseEnumNames))); } continue; // match found so do continue the loop.. } // comparison of ATASCII (see: FileLineTypes.ATASCII description..).. if (ContainsBytes(i, contentsBytes, new byte[] { 0x9B }, out eof1)) { if (eof1) // check for an overflow of the byte array.. { // the index was outside the byte array so do // increase the loop variable by one and continue.. i++; continue; } i++; // increase the loop variable by the amount of bytes used in the comparison.. // check that the result value doesn't already contain the given enumeration and string pair.. if (!result.Exists(f => f.Key == FileLineTypes.ATASCII) && fileLineTypes.HasFlag(FileLineTypes.ATASCII)) { result.Add( new KeyValuePair <FileLineTypes, string>(FileLineTypes.ATASCII, GetLineEndingDescriptionByEnumeration(FileLineTypes.ATASCII, UseEnumNames))); } continue; // match found so do continue the loop.. } // comparison of NEWLINE (see: FileLineTypes.NEWLINE description..).. if (ContainsBytes(i, contentsBytes, new byte[] { 0x76 }, out eof1)) { if (eof1) // check for an overflow of the byte array.. { // the index was outside the byte array so do // increase the loop variable by one and continue.. i++; continue; } i++; // increase the loop variable by the amount of bytes used in the comparison.. // check that the result value doesn't already contain the given enumeration and string pair.. if (!result.Exists(f => f.Key == FileLineTypes.NEWLINE) && fileLineTypes.HasFlag(FileLineTypes.NEWLINE)) { result.Add( new KeyValuePair <FileLineTypes, string>(FileLineTypes.NEWLINE, GetLineEndingDescriptionByEnumeration(FileLineTypes.NEWLINE, UseEnumNames))); } continue; // match found so do continue the loop.. } i++; // the loop must not be infinite so increase the loop variable by one.. } // if nothing was found assume CR+LF.. if (result.Count == 0) { result.Add( new KeyValuePair <FileLineTypes, string>(FileLineTypes.CRLF, GetLineEndingDescriptionByEnumeration(FileLineTypes.CRLF, UseEnumNames))); } // if multiple items was found, assume mixed line endings.. if (result.Count() > 1) { result.Add( new KeyValuePair <FileLineTypes, string>(FileLineTypes.Mixed, GetLineEndingDescriptionByEnumeration(FileLineTypes.Mixed, UseEnumNames))); } // return the result.. return(result); }
/// <summary> /// Gets the file line types of a given byte array. /// </summary> /// <param name="buffer">The byte array to be used to check for the line endings.</param> /// <param name="fileLineTypes">The types of line endings wanted to be included in the search.</param> /// <returns>A collection of line ending key value pairs with their enumeration values and their names.</returns> public static IEnumerable <KeyValuePair <FileLineTypes, string> > GetFileLineTypes(byte[] buffer, FileLineTypes fileLineTypes = // the default set.. FileLineTypes.CR | FileLineTypes.CRLF | FileLineTypes.LF | FileLineTypes.LFCR | FileLineTypes.UCR | FileLineTypes.UCRLF | FileLineTypes.ULF | FileLineTypes.ULFCR) { using (MemoryStream memoryStream = buffer == null || buffer.Length == 0 ? new MemoryStream() : new MemoryStream(buffer)) { return(GetFileLineTypes(memoryStream, fileLineTypes)); } }
/// <summary> /// Manipulates the specified text value. /// </summary> /// <param name="value">The value to manipulate.</param> /// <param name="stringComparison">The type of string comparison.</param> /// <param name="fileLineTypes">The type of the line ending in the <see cref="Scintilla"/> control.</param> /// <returns>A string containing the manipulated text.</returns> public static string Manipulate(string value, StringComparison stringComparison, FileLineTypes fileLineTypes) { try { var lines = new List <string>(); using var reader = new StringReader(value); string readLine; while ((readLine = reader.ReadLine()) != null) { lines.Add(readLine); } var linesNew = new List <string>(); foreach (var line in lines) { if (!linesNew.Exists(f => f.Equals(line, stringComparison))) { linesNew.Add(line); } } string lineSeparator = Environment.NewLine; if (fileLineTypes.HasFlag(FileLineTypes.CRLF)) { lineSeparator = "\r\n"; } else if (fileLineTypes.HasFlag(FileLineTypes.LF)) { lineSeparator = "\n"; } else if (fileLineTypes.HasFlag(FileLineTypes.CR)) { lineSeparator = "\r"; } return(string.Join(lineSeparator, linesNew)); } catch (Exception ex) { ErrorHandlingBase.ExceptionLogAction?.Invoke(ex); return(value); } }
/// <summary> /// Removes the duplicate lines from a given <see cref="Scintilla"/> control. /// </summary> /// <param name="scintilla">The <see cref="Scintilla"/> control.</param> /// <param name="stringComparison">The type of string comparison.</param> /// <param name="fileLineTypes">The type of the line ending in the <see cref="Scintilla"/> control.</param> public static void RemoveDuplicateLines(Scintilla scintilla, StringComparison stringComparison, FileLineTypes fileLineTypes) { try { scintilla.Text = Manipulate(scintilla.Text, stringComparison, fileLineTypes); } catch (Exception ex) { // log the exception if the action has a value.. ErrorHandlingBase.ExceptionLogAction?.Invoke(ex); } }