diff --git a/Base16384.Net.csproj b/Base16384.Net.csproj index 3f5a9cf..ecc0ec6 100644 --- a/Base16384.Net.csproj +++ b/Base16384.Net.csproj @@ -5,6 +5,7 @@ enable enable 2.0.0.0 + x64 diff --git a/Helpers.cs b/Helpers.cs index d6eab76..c41cbb3 100644 --- a/Helpers.cs +++ b/Helpers.cs @@ -1,31 +1,50 @@ -namespace ConsoleHelpers; +using System.Diagnostics.CodeAnalysis; + +namespace ConsoleHelpers; public static class Helpers { - public static int WriteToStdOut(Func func, T input, Stream? stdout = null) { - try { - stdout ??= Console.OpenStandardOutput(); - try { - func(input, stdout); - } catch { - return 4; - } finally { - stdout.Dispose(); - } - } catch { - return 3; + public static readonly string? debugEnv = Environment.GetEnvironmentVariable("Base16384_Net_Debug"); + public static readonly bool DEBUG = debugEnv is not null && debugEnv.ToLower() is not "false" and not "0"; + + + public static int PrintErrorMessage(string? message, string? debugMessage = null, int exitCode = 0) { + if (message is not null) { + Console.WriteLine(message); } - return 0; + if (DEBUG && !string.IsNullOrWhiteSpace(debugMessage)) { + Console.Error.WriteLine(debugMessage); + } + return exitCode; } - public static int WriteToFile(Func func, T input, string inputName, FileInfo output) { - Console.Write($"{inputName} -> {output.Name} ... "); + public static int PrintException(string? message, [NotNull] Exception e, int exitCode = 0) => + PrintErrorMessage(message, e.ToString(), exitCode); + + + public static int Execute(Func func, TIn input, TOut output, string? inputName, string? outputName, bool isStdOut = false) { + if (!isStdOut) { + Console.Write($"{inputName} -> {outputName} ... "); + } try { func(input, output); - } catch { - Console.WriteLine("Failed."); - return 4; + } catch (Exception e) { + return PrintException(isStdOut ? null : "Failed.", e, 4); + } + if (!isStdOut) { + Console.WriteLine("Done."); } - Console.WriteLine("Done."); return 0; } + + public static int WriteToStdOut(Func func, T input) { + try { + using var stdout = Console.OpenStandardOutput(); + return Execute(func, input, stdout, null, null, true); + } catch (Exception e) { + return PrintException(null, e, 3); + } + } + + public static int WriteToFile(Func func, T input, FileInfo output, string inputName) => + Execute(func, input, output, inputName, output.Name); } \ No newline at end of file diff --git a/Program.cs b/Program.cs index e3a8847..08677fa 100644 --- a/Program.cs +++ b/Program.cs @@ -5,165 +5,88 @@ 1. 无法解析命令行参数 2. 无法读取文件(可能是文件不存在) 3. Standard IO Stream 开启失败 4. 编解码失败 +5. 无法创建输出文件夹(可能是输出文件夹是一个已存在的文件) */ + if (args.Length is not 2 and not 3 || args is not ["e", ..] and not ["d", ..]) { Console.WriteLine("Usage: Base16384.Net.exe <\"e\" | \"d\"> [out | \"-\"]"); return 1; } -if (args[0] == "e") { - // Encode mode - if (args[1] == "-") { - // Read from stdin - try { - using var stdin = Console.OpenStandardInput(); - if (args.Length == 2 || args[2] == "-") { - // Write to stdout - return Helpers.WriteToStdOut(Base16384.EncodeToStream, stdin); - } +bool readFromStdin = args[1] == "-", + isDefaultOutput = args.Length == 2, + writeToStdout = (readFromStdin && isDefaultOutput) || (args is [string, string, "-"]), // `x -` or `x x -` + isEncodeMode = args[0] == "e"; // Encode mode or decode mode - // Write to file - FileInfo info = new(args[2]); - Console.Write($" -> {info.Name} ... "); - try { - Base16384.EncodeToNewFile(stdin, info); - } catch { - Console.WriteLine("Failed."); - return 4; - } - Console.WriteLine("Done."); - } catch { - if (args.Length != 2 && args[2] != "-") { - Console.WriteLine("Can not open stdin."); - } - return 3; - } - } else { - // Read from file - if (args is [.., "-"]) { - // Write to stdout - return File.Exists(args[1]) - ? Helpers.WriteToStdOut(Base16384.EncodeFromFileToStream, new FileInfo(args[1])) - : 2; - } else if (args.Length == 2) { - // Write to .decoded file - if (!File.Exists(args[1])) { - if (Directory.Exists(args[1])) { - // 此处应该遍历文件夹 - return 0; - } - Console.WriteLine("Source file not found."); - return 2; - } - FileInfo info = new(args[1]); - Console.Write($"{info.Name} -> {info.Name}.encoded ... "); - try { - Base16384.EncodeFromFileToNewFile(info, new($"{args[1]}.encoded")); - } catch { - Console.WriteLine("Failed."); - return 4; - } - Console.WriteLine("Done."); - } else { - // Write to file - if (!File.Exists(args[1])) { - if (Directory.Exists(args[1])) { - // 此处应该遍历文件夹 - return 0; - } - Console.WriteLine("Source file not found."); - return 2; - } - FileInfo info1 = new(args[1]), - info2 = new(args[2]); - Console.Write($"{info1.Name} -> {info2.Name} ... "); - try { - Base16384.EncodeFromFileToNewFile(info1, info2); - } catch { - Console.WriteLine("Failed."); - return 4; - } - Console.WriteLine("Done."); +if (readFromStdin) { // Read from stdin + try { + using var stdin = Console.OpenStandardInput(); + + if (writeToStdout) { // Write to stdout + return Helpers.WriteToStdOut(isEncodeMode ? Base16384.EncodeToStream : Base16384.DecodeToStream, stdin); } + + // Write to file + + return Helpers.WriteToFile(isEncodeMode ? Base16384.EncodeToNewFile : Base16384.DecodeToNewFile, + stdin, new(args[2]), ""); + + } catch (Exception e) { + + // If write to stdout, do not print message + return Helpers.PrintException(writeToStdout ? null : "Can not open stdin.", e, 3); + } -} else { - // Decode mode - if (args[1] == "-") { - // Read from stdin - try { - using var stdin = Console.OpenStandardInput(); - if (args.Length == 2 || args[2] == "-") { - // Write to stdout - return Helpers.WriteToStdOut(Base16384.DecodeToStream, stdin); - } +} - // Write to file - FileInfo info = new(args[2]); - Console.Write($" -> {info.Name} ... "); - try { - Base16384.DecodeToNewFile(stdin, info); - } catch { - Console.WriteLine("Failed."); - return 4; - } - Console.WriteLine("Done."); +// Read from file - } catch { - if (args.Length != 2 && args[2] != "-") { - Console.WriteLine("Can not open stdin."); - } - return 3; - } - } else { - // Read from file - if (args is [.., "-"]) { - // Write to stdout - return File.Exists(args[1]) - ? Helpers.WriteToStdOut(Base16384.DecodeFromFileToStream, new FileInfo(args[1])) - : 2; - } else if (args.Length == 2) { - // Write to .decoded file - if (!File.Exists(args[1])) { - if (Directory.Exists(args[1])) { - // 此处应该遍历文件夹 - return 0; - } - Console.WriteLine("Source file not found."); - return 2; - } - FileInfo info = new(args[1]); - Console.Write($"{info.Name} -> {info.Name}.decoded ... "); - try { - Base16384.DecodeFromFileToNewFile(info, new($"{args[1]}.decoded")); - } catch { - Console.WriteLine("Failed."); - return 4; - } - Console.WriteLine("Done."); - } else { - // Write to file - if (!File.Exists(args[1])) { - if (Directory.Exists(args[1])) { - // 此处应该遍历文件夹 - return 0; - } - Console.WriteLine("Source file not found."); - return 2; +if (writeToStdout) { // Write to stdout + + return File.Exists(args[1]) + ? Helpers.WriteToStdOut(isEncodeMode ? Base16384.EncodeFromFileToStream : Base16384.DecodeFromFileToStream, + new FileInfo(args[1])) + : Helpers.PrintErrorMessage(null, "Source file not found.", 2); + +} + +// Write to file + +// File not found or Directory exists +if (!File.Exists(args[1])) { + + if (Directory.Exists(args[1])) { // Encode all files in the directory + + var output = isDefaultOutput ? $"{(isEncodeMode ? "en" : "de")}coded" : args[2]; + DirectoryInfo inputDirectoryInfo = new(args[1]), + outputDirectoryInfo = new(output); + + if (!outputDirectoryInfo.Exists) { // Try to create output directory + if (File.Exists(output)) { + return Helpers.PrintErrorMessage("Output directory is an existing file.", null, 5); } - FileInfo info1 = new(args[1]), - info2 = new(args[2]); - Console.Write($"{info1.Name} -> {info2.Name} ... "); + try { - Base16384.DecodeFromFileToNewFile(info1, info2); - } catch { - Console.WriteLine("Failed."); - return 4; + outputDirectoryInfo.Create(); + } catch (Exception e) { + return Helpers.PrintException("Failed to create output directory.", e, 5); } - Console.WriteLine("Done."); } + + // 此处应该遍历文件夹 + + return 0; } + + return Helpers.PrintErrorMessage("Source file not found.", null, 2); } -return 0; \ No newline at end of file +// Encode single file + +FileInfo inputFileInfo = new(args[1]), + outputFileInfo = new(isDefaultOutput ? $"{args[1]}.{(isEncodeMode ? "en" : "de")}coded" : args[2]); + +return Helpers.Execute(isEncodeMode ? Base16384.EncodeFromFileToNewFile : Base16384.DecodeFromFileToNewFile, + inputFileInfo, outputFileInfo, inputFileInfo.Name, outputFileInfo.Name); \ No newline at end of file