diff --git a/src/main/AdrianKousz.Util/CmdApp.cs b/src/main/AdrianKousz.Util/CmdApp.cs index a168a5d..f71035d 100644 --- a/src/main/AdrianKousz.Util/CmdApp.cs +++ b/src/main/AdrianKousz.Util/CmdApp.cs @@ -5,53 +5,162 @@ namespace AdrianKousz.Util { public class CmdApp { - IApp app; - string[] args; + private string header; + private IDictionary cmds; + private Command noArgCommand; + private Command defaultCommand; - public CmdApp(IApp app, string[] args) + private CmdApp() { } + + public void Run(string[] args) { - this.app = app; - this.args = args; - } + Console.WriteLine(header); + Console.WriteLine(); - public void Run() - { - Console.Out.WriteLine(app.GetHeader()); - Console.Out.WriteLine(); - - var commands = app.GetCommands(); - - var showhelp = true; - var requestedcmd = ""; - if (args.Length != 0) { - requestedcmd = args[0].Trim().ToLower(); - showhelp = !commands.ContainsKey(requestedcmd); - } - - if (showhelp) { - Console.Out.WriteLine("Available commands are:"); - foreach (var icommand in commands) { - Console.Out.WriteLine(" {0,-12} {1}", icommand.Key, icommand.Value.GetDescription()); - } - Console.Out.WriteLine(); + if (args.Length == 0) { + noArgCommand.Run(new string[0]); return; } - var cmd = commands[requestedcmd]; - var requireargcount = cmd.GetArgumentCount(); + var cmdname = args[0]; + var cmd = GetCommand(cmdname); + + if (cmd == null) { + defaultCommand.Run(new string[] { cmdname }); + return; + } + + var requireargcount = cmd.MinArgumentCount; if (args.Length - 1 < requireargcount) { - Console.Out.WriteLine("Provide at least {0} arguments for \"{1}\". See help:", requireargcount, requestedcmd); - Console.Out.WriteLine(); - Console.Out.WriteLine(cmd.GetHelp()); - Console.Out.WriteLine(); + var hint = string.Format(SR.Error_ArgCount, cmdname, requireargcount); + defaultCommand.Run(new string[] { cmdname, hint }); return; } var cmdargs = new string[args.Length - 1]; Array.Copy(args, 1, cmdargs, 0, cmdargs.Length); - cmd.SetArguments(cmdargs); - cmd.Run(); + cmd.Run(cmdargs); + } + + private Command GetCommand(string k) + { + k = k.ToLower(); + if (cmds.ContainsKey(k)) return cmds[k]; + return null; + } + + public abstract class Command + { + public int MinArgumentCount { get; protected set; } + public string Description { get; protected set; } = SR.NoDesc; + public string Help { get; protected set; } = SR.NoHelp; + public abstract void Run(string[] args); + } + + public sealed class HelpCommand : Command + { + private CmdApp app; + + public HelpCommand(CmdApp app) + { + Description = SR.HelpCmdDesc; + Help = SR.HelpCmdHelp; + this.app = app; + } + + public override void Run(string[] args) + { + var sb = new System.Text.StringBuilder(); + var showlist = true; + var cmdname = args.Length > 0 ? args[0].ToLower() : ""; + + if (args.Length > 1) + Console.WriteLine(args[1]); + + if (!cmdname.Equals("")) { + var cmd = app.GetCommand(cmdname); + if (cmd == null) { + sb.AppendFormat(SR.Error_NoCmd, cmdname); + sb.AppendLine(); + } else { + sb.AppendFormat(SR.HelpFor, cmdname); + sb.AppendLine(); + sb.AppendLine(); + sb.AppendLine(cmd.Help); + showlist = false; + } + } + + if (showlist) { + sb.AppendLine(SR.AvailCmds); + foreach (var cmd in app.cmds) { + sb.AppendFormat(" {0,-12} {1}", cmd.Key, cmd.Value.Description); + sb.AppendLine(); + } + } + + Console.WriteLine(sb); + + if (args.Length == 0) { + Console.WriteLine(SR.PressEnter); + Console.ReadLine(); + } + } + } + + public sealed class Builder + { + private CmdApp result = new CmdApp(); + private Command helpCommand; + + public Builder() + { + result.cmds = new Dictionary(); + result.header = SR.DefaultAppHeader; + helpCommand = new HelpCommand(result); + result.noArgCommand = helpCommand; + result.defaultCommand = helpCommand; + } + + public Builder NoArg(Command value) { result.noArgCommand = value; return this; } + public Builder Default(Command value) { result.defaultCommand = value; return this; } + public Builder Header(string value) { result.header = value; return this; } + + public Builder Add(string name, Command command) + { + name = name.ToLower(); + if (name == null || name.Equals("") || name.Equals(SR.HelpCmdName)) + throw new ArgumentException(SR.Error_CmdNameForbidden); + result.cmds.Add(name, command); + return this; + } + + public CmdApp Build() + { + result.cmds.Add(SR.HelpCmdName, helpCommand); + var r = result; + result = null; + return r; + } + } + + private static class SR + { + public const string DefaultAppHeader = "Unnamed console application"; + public const string HelpCmdName = "help"; + public const string HelpCmdDesc = "Get help"; + public const string HelpCmdHelp = "List available commands or display help of a command\n\nParameters:\n[]"; + public const string NoDesc = "(No short description available)"; + public const string NoHelp = "(No help available)"; + + public const string PressEnter = "Press enter to continue ..."; + public const string HelpFor = "Help for {0}:"; + public const string AvailCmds = "Available commands are:"; + + public const string Error_CmdNameForbidden = "Forbidden name"; + public const string Error_NoCmd = "\x1b[31mCommand \"{0}\" does not exist!\x1b[0m"; + public const string Error_ArgCount = "\x1b[31mCommand \"{0}\" requires at least {1} arguments!\x1b[0m"; } } } diff --git a/src/main/AdrianKousz.Util/ExtendedBinaryReader.cs b/src/main/AdrianKousz.Util/ExtendedBinaryReader.cs index c60dcfc..8814f1a 100644 --- a/src/main/AdrianKousz.Util/ExtendedBinaryReader.cs +++ b/src/main/AdrianKousz.Util/ExtendedBinaryReader.cs @@ -9,7 +9,7 @@ namespace AdrianKousz.Util public bool Strict; public Encoding Encoding { get; private set; } - private const string ErrorChooseMethod = "Choose string writing method"; + private const string ErrorChooseMethod = "Choose method with correct integer size"; private const string ErrorHasNull = "String contains trailing null"; private const string ErrorHasNoNull = "String does not contain trailing null"; @@ -20,17 +20,14 @@ namespace AdrianKousz.Util Strict = strict; } - public override string ReadString() - { - throw new NotSupportedException(ErrorChooseMethod); - } + public override string ReadString() { throw new NotSupportedException(ErrorChooseMethod); } + public override bool ReadBoolean() { throw new NotSupportedException(ErrorChooseMethod); } - public override bool ReadBoolean() - { - return ReadInt32() != 0; - } + public bool ReadBooleanByte() { return ReadByte() != 0; } + public bool ReadBooleanInt16() { return ReadInt16() != 0; } + public bool ReadBooleanInt32() { return ReadInt32() != 0; } - public string ReadStringInternal(int len) { return ReadStringInternal(len, false); } + public string ReadString(int len) { return ReadStringInternal(len, false); } public string ReadStringByte() { return ReadStringInternal(ReadByte(), false); } public string ReadStringInt16() { return ReadStringInternal(ReadInt16(), false); } public string ReadStringInt32() { return ReadStringInternal(ReadInt32(), false); } diff --git a/src/main/AdrianKousz.Util/ExtendedBinaryWriter.cs b/src/main/AdrianKousz.Util/ExtendedBinaryWriter.cs index 049a98d..aaf875e 100644 --- a/src/main/AdrianKousz.Util/ExtendedBinaryWriter.cs +++ b/src/main/AdrianKousz.Util/ExtendedBinaryWriter.cs @@ -8,7 +8,7 @@ namespace AdrianKousz.Util { public Encoding Encoding { get; private set; } - private const string ErrorChooseMethod = "Choose string writing method"; + private const string ErrorChooseMethod = "Choose method with correct integer size"; private const string ErrorStringTooLong = "String too long"; public ExtendedBinaryWriter(Stream stream, Encoding enc) @@ -17,16 +17,12 @@ namespace AdrianKousz.Util Encoding = enc; } - public override void Write(string value) - { - throw new NotSupportedException(ErrorChooseMethod); - } + public override void Write(string value) { throw new NotSupportedException(ErrorChooseMethod); } + public override void Write(bool value) { throw new NotSupportedException(ErrorChooseMethod); } - public override void Write(bool value) - { - if (value) Write((Int32)1); - else Write((Int32)0); - } + public void WriteBooleanByte(bool value) { if (value) Write((Byte)1); else Write((Byte)0); } + public void WriteBooleanInt16(bool value) { if (value) Write((Int16)1); else Write((Int16)0); } + public void WriteBooleanInt32(bool value) { if (value) Write((Int32)1); else Write((Int32)0); } public void WriteString(string value, int len) { WriteStringInternal(value, len, TypeCode.Empty); } public void WriteStringByte(string value) { WriteStringInternal(value, 0, TypeCode.Byte); } @@ -40,15 +36,8 @@ namespace AdrianKousz.Util public void WriteZStringInt32(string value) { WriteStringInternal(value + "\0", 0, TypeCode.Int32); } public void WriteZStringRaw(string value) { WriteStringInternal(value + "\0", 0, TypeCode.Empty); } - public int GetByteCount(string value) - { - return Encoding.GetByteCount(value); - } - - public int GetZByteCount(string value) - { - return Encoding.GetByteCount(value + "\0"); - } + public int GetByteCount(string value) { return Encoding.GetByteCount(value); } + public int GetZByteCount(string value) { return Encoding.GetByteCount(value + "\0"); } private void WriteStringInternal(string value, int len, TypeCode typecode) { diff --git a/src/main/AdrianKousz.Util/IApp.cs b/src/main/AdrianKousz.Util/IApp.cs deleted file mode 100644 index ec33de9..0000000 --- a/src/main/AdrianKousz.Util/IApp.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Collections.Generic; - -namespace AdrianKousz.Util -{ - public interface IApp - { - string GetHeader(); - IDictionary> GetCommands(); - } -} diff --git a/src/main/AdrianKousz.Util/ICommand.cs b/src/main/AdrianKousz.Util/ICommand.cs deleted file mode 100644 index 42c1697..0000000 --- a/src/main/AdrianKousz.Util/ICommand.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Collections.Generic; - -namespace AdrianKousz.Util -{ - public interface ICommand - { - string GetDescription(); - string GetHelp(); - int GetArgumentCount(); - void SetArguments(T args); - void Run(); - } -} diff --git a/src/main/AdrianKousz.Util/UnsafeBitmap.cs b/src/main/AdrianKousz.Util/UnsafeBitmap.cs index b4ff7c8..5f5e692 100644 --- a/src/main/AdrianKousz.Util/UnsafeBitmap.cs +++ b/src/main/AdrianKousz.Util/UnsafeBitmap.cs @@ -6,59 +6,38 @@ namespace AdrianKousz.Util { public unsafe class UnsafeBitmap : IDisposable { - private const string ErrorNotLocked = "Bitmap not locked"; - private const string ErrorAlreadyLocked = "Bitmap already locked"; - private Bitmap bmp; private BitmapData bmpdat; public UnsafeBitmap(Bitmap bmp) - : this(bmp, false, true) { } + : this(bmp, false) { } public UnsafeBitmap(Bitmap bmp, bool write) - : this(bmp, write, true) { } - - public UnsafeBitmap(Bitmap bmp, bool write, bool locknow) { this.bmp = bmp; - this.bmpdat = null; - if (locknow) - Lock(write ? ImageLockMode.ReadWrite : ImageLockMode.ReadOnly); + var mode = write ? ImageLockMode.ReadWrite : ImageLockMode.ReadOnly; + var rect = new Rectangle(0, 0, bmp.Width, bmp.Height); + bmpdat = bmp.LockBits(rect, mode, bmp.PixelFormat); } public void Dispose() { if (bmp == null) return; - Unlock(); + bmp.UnlockBits(bmpdat); + bmpdat = null; bmp = null; } - public void Lock(ImageLockMode mode) - { - if (bmpdat != null) - throw new InvalidOperationException(ErrorAlreadyLocked); - if (bmp == null) - throw new ObjectDisposedException(null); - var rect = new Rectangle(0, 0, bmp.Width, bmp.Height); - bmpdat = bmp.LockBits(rect, mode, bmp.PixelFormat); - } + public int Height { get { EnsureValid(); return bmpdat.Height; } } + public PixelFormat PixelFormat { get { EnsureValid(); return bmpdat.PixelFormat; } } + public byte* Scan0 { get { EnsureValid(); return (byte*)bmpdat.Scan0.ToPointer(); } } + public int Stride { get { EnsureValid(); return bmpdat.Stride; } } + public int Width { get { EnsureValid(); return bmpdat.Width; } } - public void Unlock() - { - bmp.UnlockBits(bmpdat); - bmpdat = null; - } - - public int Height { get { CheckLocked(); return bmpdat.Height; } } - public PixelFormat PixelFormat { get { CheckLocked(); return bmpdat.PixelFormat; } } - public byte* Scan0 { get { CheckLocked(); return (byte*)bmpdat.Scan0.ToPointer(); } } - public int Stride { get { CheckLocked(); return bmpdat.Stride; } } - public int Width { get { CheckLocked(); return bmpdat.Width; } } - - private void CheckLocked() + private void EnsureValid() { if (bmpdat == null) - throw new InvalidOperationException(ErrorNotLocked); + throw new ObjectDisposedException(null); } } } diff --git a/src/main/ExUtil.csproj b/src/main/ExUtil.csproj index e506992..041ade9 100644 --- a/src/main/ExUtil.csproj +++ b/src/main/ExUtil.csproj @@ -37,8 +37,6 @@ - -