diff --git a/TestLineEndingConversion/IntegrationTesting.cs b/TestLineEndingConversion/IntegrationTesting.cs new file mode 100644 index 0000000..e1bd4a1 --- /dev/null +++ b/TestLineEndingConversion/IntegrationTesting.cs @@ -0,0 +1,71 @@ +using System.Diagnostics; +using System.IO; +using System.Threading.Tasks; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using TextFileConvert; + + + +namespace TestLineEndingConversion; + +[TestClass] +public class IntegrationTesting +{ + private const string TestUnixTxt = "testunix.txt"; + private const string TestDosTxt = "testdos.txt"; + + [TestMethod] + public async Task TestDos2Ux() + { + // Where am I? + Debug.WriteLine(Directory.GetCurrentDirectory()); + if(File.Exists(TestUnixTxt)) + File.Delete(TestUnixTxt); + + // ensure we start well + var precondition = await File.ReadAllTextAsync("dos.txt"); + Assert.IsTrue(precondition.Contains("\r\n")); + + // Do Conversion + var exitCode = await ConvertLineEndings.Dos2Ux("dos.txt", TestUnixTxt); + + // Zero is success + Assert.AreEqual(exitCode, 0); + + // Compare the test file to the artifact file + var result = await File.ReadAllTextAsync(TestUnixTxt); + Assert.IsFalse(result.Contains("\r\n")); + Assert.AreEqual(await File.ReadAllTextAsync("unix.txt"), result); + + // Clean up + File.Delete(TestUnixTxt); + } + + [TestMethod] + public async Task TestUx2Dos() + { + // Where am I? + Debug.WriteLine(Directory.GetCurrentDirectory()); + + if(File.Exists(TestDosTxt)) + File.Delete(TestDosTxt); + + // ensure we start well + var precondition = await File.ReadAllTextAsync("unix.txt"); + Assert.IsFalse(precondition.Contains("\r\n")); + + // Do Conversion + int exitCode = await ConvertLineEndings.Ux2Dos("unix.txt", TestDosTxt); + + // Zero is success + Assert.AreEqual(exitCode, 0); + + // Compare the test file to the artifact file + var result = await File.ReadAllTextAsync(TestDosTxt); + Assert.IsTrue(result.Contains("\r\n")); + Assert.AreEqual(await File.ReadAllTextAsync("dos.txt"), result); + + // Clean up + File.Delete(TestDosTxt); + } +} \ No newline at end of file diff --git a/TestLineEndingConversion/IntegrationTesting.vb b/TestLineEndingConversion/IntegrationTesting.vb deleted file mode 100644 index 44e30d8..0000000 --- a/TestLineEndingConversion/IntegrationTesting.vb +++ /dev/null @@ -1,47 +0,0 @@ -Imports System.IO -Imports Microsoft.VisualStudio.TestTools.UnitTesting -Imports TextFileConvert - - - -Namespace TestLineEndingConversion - - Public Class IntegrationTesting - - Sub TestDos2Ux() - ' Where am I? - Debug.WriteLine(Directory.GetCurrentDirectory()) - - ' Do Conversion - Dim exitCode As Integer = ConvertLineEndings.Dos2Ux("dos.txt", "testunix.txt").GetAwaiter().GetResult() - - ' Zero is success - Assert.AreEqual(exitCode, 0) - - ' Compare the test file to the artifact file - Assert.IsTrue(File.ReadAllBytes("unix.txt").SequenceEqual(File.ReadAllBytes("testunix.txt"))) - - ' Clean up - File.Delete("testunix.txt") - End Sub - - - Sub TestUx2Dos() - ' Where am I? - Debug.WriteLine(Directory.GetCurrentDirectory()) - - ' Do Conversion - Dim exitCode As Integer = ConvertLineEndings.Ux2Dos("unix.txt", "testdos.txt").GetAwaiter().GetResult() - - ' Zero is success - Assert.AreEqual(exitCode, 0) - - ' Compare the test file to the artifact file - Assert.IsTrue(File.ReadAllBytes("dos.txt").SequenceEqual(File.ReadAllBytes("testdos.txt"))) - - ' Clean up - File.Delete("testdos.txt") - End Sub - End Class -End Namespace - diff --git a/TestLineEndingConversion/TestLineEndingConversion.vbproj b/TestLineEndingConversion/TestLineEndingConversion.csproj similarity index 50% rename from TestLineEndingConversion/TestLineEndingConversion.vbproj rename to TestLineEndingConversion/TestLineEndingConversion.csproj index 0b3a741..c3849f2 100644 --- a/TestLineEndingConversion/TestLineEndingConversion.vbproj +++ b/TestLineEndingConversion/TestLineEndingConversion.csproj @@ -1,23 +1,23 @@ - - + TestLineEndingConversion - net5.0 - + net8.0 false + $(DefaultItemExcludes);$(ProjectDir)**\*.vb + latest - - - - - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + - - + - Always @@ -29,5 +29,4 @@ Always - - + \ No newline at end of file diff --git a/TextFileConvert.sln b/TextFileConvert.sln index d687d8c..2268662 100644 --- a/TextFileConvert.sln +++ b/TextFileConvert.sln @@ -3,13 +3,13 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31613.86 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "TextFileConvert", "TextFileConvert\TextFileConvert.vbproj", "{C6D516A4-A83D-405A-8F46-DF37C9C25D4B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TextFileConvert", "TextFileConvert\TextFileConvert.csproj", "{74F197CF-6465-0FAB-0D1E-1549AB5569EB}" EndProject -Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "dos2ux", "dos2ux\dos2ux.vbproj", "{AA1FC840-1A4A-4F07-BAFC-8B281CEE6F10}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dos2ux", "dos2ux\dos2ux.csproj", "{183B492B-D612-00F6-38A4-41567E795BB0}" EndProject -Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "ux2dos", "ux2dos\ux2dos.vbproj", "{C596EC73-1634-429E-A20C-CD73DB6D416C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ux2dos", "ux2dos\ux2dos.csproj", "{77B26D18-DA6C-0D6F-2054-070DB9FA75CC}" EndProject -Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "TestLineEndingConversion", "TestLineEndingConversion\TestLineEndingConversion.vbproj", "{FC6A6D47-7C99-41D6-BD55-C6394BF804C4}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestLineEndingConversion", "TestLineEndingConversion\TestLineEndingConversion.csproj", "{4E4EEC2C-B0C1-0E27-3F0D-0C47296F3064}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -17,22 +17,22 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C6D516A4-A83D-405A-8F46-DF37C9C25D4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C6D516A4-A83D-405A-8F46-DF37C9C25D4B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C6D516A4-A83D-405A-8F46-DF37C9C25D4B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C6D516A4-A83D-405A-8F46-DF37C9C25D4B}.Release|Any CPU.Build.0 = Release|Any CPU - {AA1FC840-1A4A-4F07-BAFC-8B281CEE6F10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AA1FC840-1A4A-4F07-BAFC-8B281CEE6F10}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AA1FC840-1A4A-4F07-BAFC-8B281CEE6F10}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AA1FC840-1A4A-4F07-BAFC-8B281CEE6F10}.Release|Any CPU.Build.0 = Release|Any CPU - {C596EC73-1634-429E-A20C-CD73DB6D416C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C596EC73-1634-429E-A20C-CD73DB6D416C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C596EC73-1634-429E-A20C-CD73DB6D416C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C596EC73-1634-429E-A20C-CD73DB6D416C}.Release|Any CPU.Build.0 = Release|Any CPU - {FC6A6D47-7C99-41D6-BD55-C6394BF804C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FC6A6D47-7C99-41D6-BD55-C6394BF804C4}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FC6A6D47-7C99-41D6-BD55-C6394BF804C4}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FC6A6D47-7C99-41D6-BD55-C6394BF804C4}.Release|Any CPU.Build.0 = Release|Any CPU + {74F197CF-6465-0FAB-0D1E-1549AB5569EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {74F197CF-6465-0FAB-0D1E-1549AB5569EB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {74F197CF-6465-0FAB-0D1E-1549AB5569EB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {74F197CF-6465-0FAB-0D1E-1549AB5569EB}.Release|Any CPU.Build.0 = Release|Any CPU + {183B492B-D612-00F6-38A4-41567E795BB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {183B492B-D612-00F6-38A4-41567E795BB0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {183B492B-D612-00F6-38A4-41567E795BB0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {183B492B-D612-00F6-38A4-41567E795BB0}.Release|Any CPU.Build.0 = Release|Any CPU + {77B26D18-DA6C-0D6F-2054-070DB9FA75CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {77B26D18-DA6C-0D6F-2054-070DB9FA75CC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {77B26D18-DA6C-0D6F-2054-070DB9FA75CC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {77B26D18-DA6C-0D6F-2054-070DB9FA75CC}.Release|Any CPU.Build.0 = Release|Any CPU + {4E4EEC2C-B0C1-0E27-3F0D-0C47296F3064}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4E4EEC2C-B0C1-0E27-3F0D-0C47296F3064}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4E4EEC2C-B0C1-0E27-3F0D-0C47296F3064}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4E4EEC2C-B0C1-0E27-3F0D-0C47296F3064}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/TextFileConvert/Common.cs b/TextFileConvert/Common.cs new file mode 100644 index 0000000..ec2b2d1 --- /dev/null +++ b/TextFileConvert/Common.cs @@ -0,0 +1,80 @@ +using System; +using System.IO; +using System.Text; + +namespace TextFileConvert; + +public static class Common +{ + public const byte Cr = 13; //'\r'; // Carriage Return + public const byte Lf = 10; //'\n'; // Line Feed + + /// + /// This is the command line help that is displayed when invalid parameters are given. + /// + /// + public static void PrintUsage(string programName) + { + Console.WriteLine(""" + + NAME + {0} - Text file format converter + + SYNOPSIS + {0} old-filename new-filename + + DESCRIPTION + {0} reads old-filename and writes out new-filename, converting line endings. + + """, programName); + } + + /// + /// Attempt to detect the encoding of a file. + /// + /// The file to get the encoding pattern from. + /// Encoding type, defaults to ASCII. + [Obsolete("No longer used internally. Prefer native methods.")] + public static Encoding GetEncoding(FileStream theFile) + { + var bom = new byte[4]; + var count = theFile.Read(bom, 0, 4); + + // Detect BOM type + if (count > 2 && bom[0] == 0x2B && bom[1] == 0x2F && bom[2] == 0x76) + { + return Encoding.UTF7; + } + if (count > 2 && bom[0] == 0xEF && bom[1] == 0xBB && bom[2] == 0xBF) + { + return Encoding.UTF8; + } + if (count > 1 && bom[0] == 0xFF && bom[1] == 0xFE) + { + return Encoding.Unicode; + } + if (count > 1 && bom[0] == 0xFE && bom[1] == 0xFF) + { + return Encoding.BigEndianUnicode; + } + if (count > 3 && bom[0] == 0 && bom[1] == 0 && bom[2] == 0xFE && bom[3] == 0xFF) + { + return Encoding.UTF32; + } + + // Default to + return Encoding.ASCII; + } + + /// + /// Detect when the file in the given path is a symbolic link. + /// WARNING: Could have false positive for any file with a reparse point that is not a symbolic link. + /// + /// Full path to file to test. + /// True if Reparse Point is found. + public static bool IsSymbolic(string path) + { + var pathInfo = new FileInfo(path); + return pathInfo.Attributes.HasFlag(FileAttributes.ReparsePoint); + } +} \ No newline at end of file diff --git a/TextFileConvert/ConvertLineEndings.cs b/TextFileConvert/ConvertLineEndings.cs new file mode 100644 index 0000000..7a2f2f1 --- /dev/null +++ b/TextFileConvert/ConvertLineEndings.cs @@ -0,0 +1,64 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using TextFileConvert.Converters; + +namespace TextFileConvert; + +public class ConvertLineEndings +{ + /// + /// Converts a DOS text file to have Unix line endings. + /// + /// The file to convert. + /// The name of a new file to create. + /// Exit code. + public static async Task Dos2Ux(string originalFile, string newFile) + { + return await ReplaceLineEndings(originalFile, newFile, new ConvertDos2Ux()); + } + + /// + /// Converts a DOS text file to have Unix line endings. + /// + /// The file to convert. + /// The name of a new file to create. + /// Exit code. + public static async Task Ux2Dos(string originalFile, string newFile) + { + return await ReplaceLineEndings(originalFile, newFile, new ConvertUx2Dos()); + } + + /// + /// Loads a whole text file in to memory, Performs a find\replace, and writes a new file. + /// + /// The file path to convert. + /// The name of a new file to create. + /// This is the type of conversion we are going to perform. + /// Exit code. 0 is success. -1 is a symbolic link. + private static async Task ReplaceLineEndings(string originalFile, string newFile, ITextConverter convertMode) + { + try + { + // Do not attempt to work on symbolic links + if (Common.IsSymbolic(originalFile)) + return -1; + + using var oldFileStream = new FileStream(originalFile, FileMode.Open, FileAccess.Read, FileShare.Read, 65536, FileOptions.Asynchronous); + using var newFileStream = new FileStream(newFile, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 65536, FileOptions.Asynchronous); + + // Reading and writing is done in this one line + convertMode.WriteConvertedText(oldFileStream, newFileStream); + await oldFileStream.FlushAsync(); + await newFileStream.FlushAsync(); + } + catch (Exception ex) + { + Console.WriteLine($"Error: {ex.Message}"); + Console.WriteLine($"Number: {ex.HResult}"); + return ex.HResult; + } + + return 0; + } +} \ No newline at end of file diff --git a/TextFileConvert/ConvertLineEndings.vb b/TextFileConvert/ConvertLineEndings.vb deleted file mode 100644 index b74b740..0000000 --- a/TextFileConvert/ConvertLineEndings.vb +++ /dev/null @@ -1,130 +0,0 @@ -Imports System.IO -Imports System.Text - - - -Public Class ConvertLineEndings - ''' - ''' These are the different conversions that this library can perform. - ''' - Private Enum TextConvertMode - Dos2Ux - Ux2Dos - 'Dos2Mac - 'Mac2Dos - 'Mac2Ux - 'Ux2Mac - End Enum - - ''' - ''' Converts a DOS text file to have Unix line endings. - ''' - ''' The file to convert. - ''' The name of a new file to create. - ''' Exit code. - Public Shared Async Function Dos2Ux(originalFile As String, newFile As String) As Task(Of Integer) - Return Await ReplaceLineEndings(originalFile, newFile, TextConvertMode.Dos2Ux) - End Function - - ''' - ''' Converts a DOS text file to have Unix line endings. - ''' - ''' The file to convert. - ''' The name of a new file to create. - ''' Exit code. - Public Shared Async Function Ux2Dos(originalFile As String, newFile As String) As Task(Of Integer) - Return Await ReplaceLineEndings(originalFile, newFile, TextConvertMode.Ux2Dos) - End Function - - ''' - ''' Loads a whole text file in to memory, Performs a find\replace, and writes a new file. - ''' - ''' The file path to convert. - ''' The name of a new file to create. - ''' This is the type of conversion we are going to perform. - ''' Exit code. 0 is success. -1 is a symbolic link. - Private Shared Async Function ReplaceLineEndings(originalFile As String, newFile As String, - convertMode As TextConvertMode) As Task(Of Integer) - - Try - ' Do not attempt to work on symbolic links - If IsSymbolic(originalFile) Then Return -1 - - Using oldFileStream As New FileStream(originalFile, FileMode.Open, FileAccess.Read) - ' Attempt to detect encoding we will use for reading and writing - Dim fileEncoding As Encoding = Await GetEncoding(oldFileStream) - Debug.Print(fileEncoding.ToString()) - - ' Rewind stream - oldFileStream.Position = 0 - Await oldFileStream.FlushAsync - - ' Reading and writing is done in this one line - File.WriteAllText(newFile, Await GetConvertedText(oldFileStream, fileEncoding, convertMode), fileEncoding) - End Using - Catch ex As Exception - Debug.Print("Error: " & ex.Message & Environment.NewLine & "Number: " & ex.HResult.ToString) - Return ex.HResult - End Try - - Return 0 - End Function - - ''' - ''' This is where the actual conversion logic lives. - ''' - ''' The file you want to convert. - ''' The encoding you want to read that file as. - ''' The type of conversion you want to perform. - ''' The full text of the file with new line endings. - Private Shared Async Function GetConvertedText(originalFile As FileStream, fileEncoding As Encoding, convertMode As TextConvertMode) As Task(Of String) - Const CR As Char = ChrW(13) ' Carriage Return - Const LF As Char = ChrW(10) ' Line Feed - - Dim convertedLines As New StringBuilder - Using oldFile As New StreamReader(originalFile, fileEncoding, True) - Select Case convertMode - Case TextConvertMode.Dos2Ux - Do Until oldFile.EndOfStream - Dim readBuffer(0) As Char - Dim readChars As Integer = Await oldFile.ReadAsync(readBuffer, 0, 1) - If readChars >= 1 Then - ' Look for Dos line endings - If readBuffer(0) = CR AndAlso oldFile.Peek() = 10 Then - ' Strip out CR chars if followed by LF - Await oldFile.ReadAsync(readBuffer, 0, 1) - End If - - 'Yield readBuffer - convertedLines.Append(readBuffer) - End If - Loop - Case TextConvertMode.Ux2Dos - Do Until oldFile.EndOfStream - Dim readBuffer(0) As Char - Dim readChars As Integer = Await oldFile.ReadAsync(readBuffer, 0, 1) - If readChars >= 1 Then - ' Check for CR first to avoid doubling the CR character when LF is found - If readBuffer(0) = CR AndAlso oldFile.Peek() = 10 Then - ' This is a DOS line ending, keep it. - ReDim Preserve readBuffer(1) - Dim tempBuffer(1) As Char - Await oldFile.ReadAsync(tempBuffer, 0, 1) - readBuffer(1) = tempBuffer(0) - ElseIf readBuffer(0) = LF Then - ' This is a Unix line ending. Add preceeding CR. - ReDim readBuffer(1) - readBuffer(0) = CR - readBuffer(1) = LF - End If - - 'Yield readBuffer - convertedLines.Append(readBuffer) - End If - Loop - End Select - End Using - - Return convertedLines.ToString - End Function -End Class diff --git a/TextFileConvert/Converters/ConvertDos2Ux.cs b/TextFileConvert/Converters/ConvertDos2Ux.cs new file mode 100644 index 0000000..bd63d72 --- /dev/null +++ b/TextFileConvert/Converters/ConvertDos2Ux.cs @@ -0,0 +1,36 @@ +using System.IO; + +namespace TextFileConvert.Converters; + +public class ConvertDos2Ux : ITextConverter +{ + public void WriteConvertedText(FileStream originalFile, FileStream newFile) + { + var readBuffer = new byte[1]; + while (originalFile.CanRead) + { + int readChars = originalFile.Read(readBuffer, 0, 1); + if (readChars == 0) break; + + // Look for Dos line endings + if (readBuffer[0] == Common.Cr) + { + // Strip out CR chars if followed by LF + var peekBuffer = new byte[1]; + readChars = originalFile.Read(peekBuffer, 0, 1); + if (readChars == 0) break; + + if (peekBuffer[0] != Common.Lf) + { + originalFile.Position -= 1; + } + else + { + readBuffer = peekBuffer; + } + } + + newFile.Write(readBuffer, 0, 1); + } + } +} \ No newline at end of file diff --git a/TextFileConvert/Converters/ConvertUx2Dos.cs b/TextFileConvert/Converters/ConvertUx2Dos.cs new file mode 100644 index 0000000..8a1fcc4 --- /dev/null +++ b/TextFileConvert/Converters/ConvertUx2Dos.cs @@ -0,0 +1,46 @@ +using System; +using System.IO; + +namespace TextFileConvert.Converters; + +public class ConvertUx2Dos : ITextConverter +{ + public void WriteConvertedText(FileStream originalFile, FileStream newFile) + { + while (originalFile.CanRead) + { + var readBuffer = new byte[1]; + int readChars = originalFile.Read(readBuffer, 0, 1); + if (readChars == 0) break; + + // Check for CR first to avoid doubling the CR character when LF is found + if (readBuffer[0] == Common.Cr) + { + var peekBuffer = new byte[1]; + readChars = originalFile.Read(peekBuffer, 0, 1); + if (readChars == 0) break; + + if (peekBuffer[0] == Common.Lf) + { + // This is a DOS line ending, keep it. + Array.Resize(ref readBuffer, 2); + readBuffer[1] = peekBuffer[0]; + } + else + { + // Rewind + originalFile.Position -= 1; + } + } + else if (readBuffer[0] == Common.Lf) + { + // This is a Unix line ending. Add preceding CR. + readBuffer = new byte[2]; + readBuffer[0] = Common.Cr; + readBuffer[1] = Common.Lf; + } + + newFile.Write(readBuffer, 0, readBuffer.Length); + } + } +} \ No newline at end of file diff --git a/TextFileConvert/Converters/ITextConverter.cs b/TextFileConvert/Converters/ITextConverter.cs new file mode 100644 index 0000000..b9b1e29 --- /dev/null +++ b/TextFileConvert/Converters/ITextConverter.cs @@ -0,0 +1,13 @@ +using System.IO; + +namespace TextFileConvert.Converters; + +public interface ITextConverter +{ + /// + /// This is where the conversion logic lives. + /// + /// The file to convert. + /// The file to write with new line endings + public void WriteConvertedText(FileStream originalFile, FileStream newFile); +} \ No newline at end of file diff --git a/TextFileConvert/TextFileConvert.csproj b/TextFileConvert/TextFileConvert.csproj new file mode 100644 index 0000000..514383e --- /dev/null +++ b/TextFileConvert/TextFileConvert.csproj @@ -0,0 +1,55 @@ + + + TextFileConvert + netstandard2.0 + Adam Kauffman + en + true + This provides text file conversion capabilities like the common Unix utilities "ux2dos" and "dos2ux". + Copyright 2018 Adam Kauffman + false + 2.0.0 + The first release verified with integration tests. + ux2dos, dos2ux + https://github.com/A9G-Data-Droid/TextFileConvert + ux2dos.png + https://github.com/A9G-Data-Droid/TextFileConvert + + BSD-2-Clause + + $(DefaultItemExcludes);$(ProjectDir)**\*.vb + latest + ux2dos.ico + enable + Text File Convert Line Endings + $(AssemblyVersion) + True + True + latest-recommended + $(AssemblyVersion) + README.md + + + 7 + True + + + 7 + True + + + + + + + True + \ + + + Always + + + + + + \ No newline at end of file diff --git a/TextFileConvert/TextFileConvert.vbproj b/TextFileConvert/TextFileConvert.vbproj deleted file mode 100644 index 34a3563..0000000 --- a/TextFileConvert/TextFileConvert.vbproj +++ /dev/null @@ -1,29 +0,0 @@ - - - TextFileConvert - netstandard2.0 - Adam Kauffman - en - true - This provides text file conversion capabilities like the common Unix utilities "ux2dos" and "dos2ux". - Copyright 2018 Adam Kauffman - false - 1.0.0.0 - The first release verified with integration tests. - ux2dos, dos2ux - https://github.com/A9G-Data-Droid/TextFileConvert - ux2dos.png - https://github.com/A9G-Data-Droid/TextFileConvert - GitHub - true - On - Off - BSD-2-Clause - - - - - Always - - - diff --git a/TextFileConvert/common.vb b/TextFileConvert/common.vb deleted file mode 100644 index 0aef110..0000000 --- a/TextFileConvert/common.vb +++ /dev/null @@ -1,61 +0,0 @@ -Imports System.IO -Imports System.Text - - - -Public Module common - ''' - ''' This is the command line help that is displayed when invalid parameters are given. - ''' - ''' - Public Sub PrintUsage(programName As String) - Console.WriteLine( -" -NAME - {0} - Text file format converter - -SYNOPSIS - {0} oldfilename newfilename - -DESCRIPTION - {0} reads oldfilename and writes out newfilename, converting line endings. -", programName) - End Sub - - ''' - ''' Attempt to detect the encoding of a file. - ''' - ''' The file to get the encoding pattern from. - ''' Encoding type, defaults to ASCII. - Public Async Function GetEncoding(theFile As FileStream) As Task(Of Encoding) - Dim bom As Byte() = New Byte(3) {} - Await theFile.ReadAsync(bom, 0, 4) - - ' Detect BOM type - If bom(0) = &H2B AndAlso bom(1) = &H2F AndAlso bom(2) = &H76 Then - Return Encoding.UTF7 - ElseIf bom(0) = &HEF AndAlso bom(1) = &HBB AndAlso bom(2) = &HBF Then - Return Encoding.UTF8 - ElseIf bom(0) = &HFF AndAlso bom(1) = &HFE Then - Return Encoding.Unicode - ElseIf bom(0) = &HFE AndAlso bom(1) = &HFF Then - Return Encoding.BigEndianUnicode - ElseIf bom(0) = 0 AndAlso bom(1) = 0 AndAlso bom(2) = &HFE AndAlso bom(3) = &HFF Then - Return Encoding.UTF32 - Else - ' Default to - Return Encoding.ASCII - End If - End Function - - ''' - ''' Detect when the file in the given path is a symbolic link. - ''' WARNING: Could have false positive for any file with a reparse point that is not a symbolic link. - ''' - ''' Full path to file to test. - ''' True if Reparse Point is found. - Public Function IsSymbolic(path As String) As Boolean - Dim pathInfo As New FileInfo(path) - Return pathInfo.Attributes.HasFlag(FileAttributes.ReparsePoint) - End Function -End Module diff --git a/dos2ux/dos2ux.cs b/dos2ux/dos2ux.cs new file mode 100644 index 0000000..07bfbb2 --- /dev/null +++ b/dos2ux/dos2ux.cs @@ -0,0 +1,37 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using TextFileConvert; + +namespace dos2ux; + +public static class Dos2Ux +{ + // Public Async Function Main(args As String()) As Task(Of Integer) + public static async Task Main(string[] args) + { + int exitCode; + if (args.Length != 2 || string.IsNullOrEmpty(args[0]) || string.IsNullOrEmpty(args[1])) + { + Common.PrintUsage(Path.GetFileName(Environment.GetCommandLineArgs()[0])); + exitCode = -1; + } + else + { + Console.WriteLine("Perform DOS to UNIX conversion"); + try + { + // exitCode = Await ConvertLineEndings.Dos2Ux(args(0), args(1)) + exitCode = await ConvertLineEndings.Dos2Ux(args[0], args[1]); + Console.WriteLine("Conversion complete: " + args[1]); + } + catch (Exception ex) + { + Console.WriteLine("Conversion failed."); + exitCode = ex.HResult; + } + } + + return exitCode; + } +} \ No newline at end of file diff --git a/dos2ux/dos2ux.vbproj b/dos2ux/dos2ux.csproj similarity index 65% rename from dos2ux/dos2ux.vbproj rename to dos2ux/dos2ux.csproj index 77e0c84..3711dd5 100644 --- a/dos2ux/dos2ux.vbproj +++ b/dos2ux/dos2ux.csproj @@ -1,19 +1,10 @@ - + - net5.0 + net4.8 Exe - true - true - win-x64 - true - true - Sub Main - Empty - On - Off This provides text file conversion capabilities like the common Unix utility "dos2ux". Copyright 2018 Adam Kauffman - 1.0.0.0 + 1.0.0 The first release verified with integration tests. ux2dos.ico My Project\app.manifest @@ -21,20 +12,31 @@ true false true + $(DefaultItemExcludes);$(ProjectDir)**\*.vb + latest + enable + True + True + latest-recommended + $(AssemblyVersion) + $(AssemblyVersion) embedded 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + 7 + True - false 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + 7 + True - + - + diff --git a/dos2ux/dos2ux.vb b/dos2ux/dos2ux.vb deleted file mode 100644 index 3ade82d..0000000 --- a/dos2ux/dos2ux.vb +++ /dev/null @@ -1,28 +0,0 @@ -Imports System.IO -Imports TextFileConvert - - - -Module Dos2Ux - - 'Public Async Function Main(args As String()) As Task(Of Integer) - Public Function Main(args As String()) As Integer - Dim exitCode As Integer - If args.Length <> 2 OrElse String.IsNullOrEmpty(args(0)) OrElse String.IsNullOrEmpty(args(1)) Then - PrintUsage(Path.GetFileName(Environment.GetCommandLineArgs()(0))) - exitCode = -1 - Else - Console.WriteLine("Perform DOS to UNIX conversion") - Try - 'exitCode = Await ConvertLineEndings.Dos2Ux(args(0), args(1)) - exitCode = ConvertLineEndings.Dos2Ux(args(0), args(1)).GetAwaiter().GetResult() - Console.WriteLine("Conversion complete: " & args(1)) - Catch ex As Exception - Console.WriteLine("Conversion failed.") - exitCode = ex.HResult - End Try - End If - - Return exitCode - End Function -End Module diff --git a/ux2dos/ux2dos.cs b/ux2dos/ux2dos.cs new file mode 100644 index 0000000..68ff83a --- /dev/null +++ b/ux2dos/ux2dos.cs @@ -0,0 +1,41 @@ +using System; +using System.IO; +using TextFileConvert; + +namespace ux2dos +{ + + + + static class Ux2Dos + { + + // Public Async Function Main(args As String()) As Task(Of Integer) + public static int Main(string[] args) + { + int exitCode; + if (args.Length != 2 || string.IsNullOrEmpty(args[0]) || string.IsNullOrEmpty(args[1])) + { + Common.PrintUsage(Path.GetFileName(Environment.GetCommandLineArgs()[0])); + exitCode = -1; + } + else + { + Console.WriteLine("Perform UNIX to DOS conversion"); + try + { + // exitCode = Await ConvertLineEndings.Ux2Dos(args(0), args(1)) + exitCode = ConvertLineEndings.Ux2Dos(args[0], args[1]).GetAwaiter().GetResult(); + Console.WriteLine("Conversion complete: " + args[1]); + } + catch (Exception ex) + { + Console.WriteLine("Conversion failed."); + exitCode = ex.HResult; + } + } + + return exitCode; + } + } +} \ No newline at end of file diff --git a/ux2dos/ux2dos.vbproj b/ux2dos/ux2dos.csproj similarity index 64% rename from ux2dos/ux2dos.vbproj rename to ux2dos/ux2dos.csproj index 3888d3f..fb636c2 100644 --- a/ux2dos/ux2dos.vbproj +++ b/ux2dos/ux2dos.csproj @@ -1,19 +1,11 @@  - net5.0 + net4.8 Exe - true - true - win-x64 - true - true - Sub Main - Empty - On - Off + ux2dos.Ux2Dos This provides text file conversion capabilities like the common Unix utility "ux2dos". Copyright 2018 Adam Kauffman - 1.0.0.0 + 1.1.0 The first release verified with integration tests. ux2dos.ico My Project\app.manifest @@ -21,20 +13,32 @@ true false true + $(DefaultItemExcludes);$(ProjectDir)**\*.vb + latest + enable + True + True + latest-recommended + $(AssemblyVersion) + $(AssemblyVersion) embedded 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + 7 + True - false 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 + 7 + True - + + - + diff --git a/ux2dos/ux2dos.vb b/ux2dos/ux2dos.vb deleted file mode 100644 index d20f9b6..0000000 --- a/ux2dos/ux2dos.vb +++ /dev/null @@ -1,28 +0,0 @@ -Imports System.IO -Imports TextFileConvert - - - -Module Ux2Dos - - 'Public Async Function Main(args As String()) As Task(Of Integer) - Public Function Main(args As String()) As Integer - Dim exitCode As Integer - If args.Length <> 2 OrElse String.IsNullOrEmpty(args(0)) OrElse String.IsNullOrEmpty(args(1)) Then - PrintUsage(Path.GetFileName(Environment.GetCommandLineArgs()(0))) - exitCode = -1 - Else - Console.WriteLine("Perform UNIX to DOS conversion") - Try - 'exitCode = Await ConvertLineEndings.Ux2Dos(args(0), args(1)) - exitCode = ConvertLineEndings.Ux2Dos(args(0), args(1)).GetAwaiter().GetResult() - Console.WriteLine("Conversion complete: " & args(1)) - Catch ex As Exception - Console.WriteLine("Conversion failed.") - exitCode = ex.HResult - End Try - End If - - Return exitCode - End Function -End Module