diff --git a/src/main/AdrianKousz.Util/CmdApp.cs b/src/main/AdrianKousz.Util/CmdApp.cs index f71035d..a168a5d 100644 --- a/src/main/AdrianKousz.Util/CmdApp.cs +++ b/src/main/AdrianKousz.Util/CmdApp.cs @@ -5,162 +5,53 @@ namespace AdrianKousz.Util { public class CmdApp { - private string header; - private IDictionary cmds; - private Command noArgCommand; - private Command defaultCommand; + IApp app; + string[] args; - private CmdApp() { } - - public void Run(string[] args) + public CmdApp(IApp app, string[] args) { - Console.WriteLine(header); - Console.WriteLine(); + this.app = app; + this.args = args; + } - if (args.Length == 0) { - noArgCommand.Run(new string[0]); + 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(); return; } - var cmdname = args[0]; - var cmd = GetCommand(cmdname); - - if (cmd == null) { - defaultCommand.Run(new string[] { cmdname }); - return; - } - - var requireargcount = cmd.MinArgumentCount; + var cmd = commands[requestedcmd]; + var requireargcount = cmd.GetArgumentCount(); if (args.Length - 1 < requireargcount) { - var hint = string.Format(SR.Error_ArgCount, cmdname, requireargcount); - defaultCommand.Run(new string[] { cmdname, hint }); + 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(); return; } var cmdargs = new string[args.Length - 1]; Array.Copy(args, 1, cmdargs, 0, cmdargs.Length); - 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"; + cmd.SetArguments(cmdargs); + cmd.Run(); } } } diff --git a/src/main/AdrianKousz.Util/ExtendedBinaryReader.cs b/src/main/AdrianKousz.Util/ExtendedBinaryReader.cs index 8814f1a..c60dcfc 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 method with correct integer size"; + private const string ErrorChooseMethod = "Choose string writing method"; private const string ErrorHasNull = "String contains trailing null"; private const string ErrorHasNoNull = "String does not contain trailing null"; @@ -20,14 +20,17 @@ namespace AdrianKousz.Util Strict = strict; } - public override string ReadString() { throw new NotSupportedException(ErrorChooseMethod); } - public override bool ReadBoolean() { throw new NotSupportedException(ErrorChooseMethod); } + public override string ReadString() + { + throw new NotSupportedException(ErrorChooseMethod); + } - public bool ReadBooleanByte() { return ReadByte() != 0; } - public bool ReadBooleanInt16() { return ReadInt16() != 0; } - public bool ReadBooleanInt32() { return ReadInt32() != 0; } + public override bool ReadBoolean() + { + return ReadInt32() != 0; + } - public string ReadString(int len) { return ReadStringInternal(len, false); } + public string ReadStringInternal(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 aaf875e..049a98d 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 method with correct integer size"; + private const string ErrorChooseMethod = "Choose string writing method"; private const string ErrorStringTooLong = "String too long"; public ExtendedBinaryWriter(Stream stream, Encoding enc) @@ -17,12 +17,16 @@ namespace AdrianKousz.Util Encoding = enc; } - public override void Write(string value) { throw new NotSupportedException(ErrorChooseMethod); } - public override void Write(bool value) { throw new NotSupportedException(ErrorChooseMethod); } + public override void Write(string value) + { + throw new NotSupportedException(ErrorChooseMethod); + } - 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 override void Write(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); } @@ -36,8 +40,15 @@ 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 new file mode 100644 index 0000000..ec33de9 --- /dev/null +++ b/src/main/AdrianKousz.Util/IApp.cs @@ -0,0 +1,10 @@ +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 new file mode 100644 index 0000000..42c1697 --- /dev/null +++ b/src/main/AdrianKousz.Util/ICommand.cs @@ -0,0 +1,13 @@ +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 5f5e692..b4ff7c8 100644 --- a/src/main/AdrianKousz.Util/UnsafeBitmap.cs +++ b/src/main/AdrianKousz.Util/UnsafeBitmap.cs @@ -6,38 +6,59 @@ 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) { } + : this(bmp, false, true) { } public UnsafeBitmap(Bitmap bmp, bool write) + : this(bmp, write, true) { } + + public UnsafeBitmap(Bitmap bmp, bool write, bool locknow) { this.bmp = bmp; - var mode = write ? ImageLockMode.ReadWrite : ImageLockMode.ReadOnly; - var rect = new Rectangle(0, 0, bmp.Width, bmp.Height); - bmpdat = bmp.LockBits(rect, mode, bmp.PixelFormat); + this.bmpdat = null; + if (locknow) + Lock(write ? ImageLockMode.ReadWrite : ImageLockMode.ReadOnly); } public void Dispose() { if (bmp == null) return; - bmp.UnlockBits(bmpdat); - bmpdat = null; + Unlock(); bmp = null; } - 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 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); + } - private void EnsureValid() + 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() { if (bmpdat == null) - throw new ObjectDisposedException(null); + throw new InvalidOperationException(ErrorNotLocked); } } } diff --git a/src/main/ExUtil.csproj b/src/main/ExUtil.csproj index 041ade9..e506992 100644 --- a/src/main/ExUtil.csproj +++ b/src/main/ExUtil.csproj @@ -37,6 +37,8 @@ + +