Skip to content

Commit

Permalink
Merge pull request #4 from A9G-Data-Droid/csharp
Browse files Browse the repository at this point in the history
Convert to Csharp
  • Loading branch information
A9G-Data-Droid authored Sep 24, 2024
2 parents d466f46 + 6388a3c commit 3f459c8
Show file tree
Hide file tree
Showing 19 changed files with 511 additions and 386 deletions.
71 changes: 71 additions & 0 deletions TestLineEndingConversion/IntegrationTesting.cs
Original file line number Diff line number Diff line change
@@ -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);
}
}
47 changes: 0 additions & 47 deletions TestLineEndingConversion/IntegrationTesting.vb

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>TestLineEndingConversion</RootNamespace>
<TargetFramework>net5.0</TargetFramework>

<TargetFramework>net8.0</TargetFramework>
<IsPackable>false</IsPackable>
<DefaultItemExcludes>$(DefaultItemExcludes);$(ProjectDir)**\*.vb</DefaultItemExcludes>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.3" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.3" />
<PackageReference Include="coverlet.collector" Version="3.0.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="MSTest.TestAdapter" Version="3.6.0" />
<PackageReference Include="MSTest.TestFramework" Version="3.6.0" />
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\TextFileConvert\TextFileConvert.vbproj" />
<ProjectReference Include="..\TextFileConvert\TextFileConvert.csproj" />
</ItemGroup>

<ItemGroup>
<None Update="dos.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
Expand All @@ -29,5 +29,4 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>

</Project>
</Project>
40 changes: 20 additions & 20 deletions TextFileConvert.sln
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,36 @@ 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
Debug|Any CPU = Debug|Any CPU
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
Expand Down
80 changes: 80 additions & 0 deletions TextFileConvert/Common.cs
Original file line number Diff line number Diff line change
@@ -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

/// <summary>
/// This is the command line help that is displayed when invalid parameters are given.
/// </summary>
/// <param name="programName"></param>
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);
}

/// <summary>
/// Attempt to detect the encoding of a file.
/// </summary>
/// <param name="theFile">The file to get the encoding pattern from.</param>
/// <returns>Encoding type, defaults to ASCII.</returns>
[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;
}

/// <summary>
/// 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.
/// </summary>
/// <param name="path">Full path to file to test.</param>
/// <returns>True if Reparse Point is found.</returns>
public static bool IsSymbolic(string path)
{
var pathInfo = new FileInfo(path);
return pathInfo.Attributes.HasFlag(FileAttributes.ReparsePoint);
}
}
64 changes: 64 additions & 0 deletions TextFileConvert/ConvertLineEndings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;
using System.IO;
using System.Threading.Tasks;
using TextFileConvert.Converters;

namespace TextFileConvert;

public class ConvertLineEndings
{
/// <summary>
/// Converts a DOS text file to have Unix line endings.
/// </summary>
/// <param name="originalFile">The file to convert.</param>
/// <param name="newFile">The name of a new file to create.</param>
/// <returns>Exit code.</returns>
public static async Task<int> Dos2Ux(string originalFile, string newFile)
{
return await ReplaceLineEndings(originalFile, newFile, new ConvertDos2Ux());
}

/// <summary>
/// Converts a DOS text file to have Unix line endings.
/// </summary>
/// <param name="originalFile">The file to convert.</param>
/// <param name="newFile">The name of a new file to create.</param>
/// <returns>Exit code.</returns>
public static async Task<int> Ux2Dos(string originalFile, string newFile)
{
return await ReplaceLineEndings(originalFile, newFile, new ConvertUx2Dos());
}

/// <summary>
/// Loads a whole text file in to memory, Performs a find\replace, and writes a new file.
/// </summary>
/// <param name="originalFile">The file path to convert.</param>
/// <param name="newFile">The name of a new file to create.</param>
/// <param name="convertMode">This is the type of conversion we are going to perform.</param>
/// <returns>Exit code. 0 is success. -1 is a symbolic link.</returns>
private static async Task<int> 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;
}
}
Loading

0 comments on commit 3f459c8

Please sign in to comment.