Compare commits
4 Commits
34b3ff8722
...
2643cd3509
Author | SHA1 | Date |
---|---|---|
Adrian | 2643cd3509 | |
Adrian | c7a4eb49b5 | |
Adrian | fbeb667c4d | |
Adrian | 16b864e0de |
|
@ -5,53 +5,162 @@ namespace AdrianKousz.Util
|
|||
{
|
||||
public class CmdApp
|
||||
{
|
||||
IApp<string, string[]> app;
|
||||
string[] args;
|
||||
private string header;
|
||||
private IDictionary<string, Command> cmds;
|
||||
private Command noArgCommand;
|
||||
private Command defaultCommand;
|
||||
|
||||
public CmdApp(IApp<string, string[]> 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<string, Command>();
|
||||
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[<command>]";
|
||||
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";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace AdrianKousz.Util
|
||||
{
|
||||
public interface IApp<TName, TCmd>
|
||||
{
|
||||
string GetHeader();
|
||||
IDictionary<TName, ICommand<TCmd>> GetCommands();
|
||||
}
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace AdrianKousz.Util
|
||||
{
|
||||
public interface ICommand<T>
|
||||
{
|
||||
string GetDescription();
|
||||
string GetHelp();
|
||||
int GetArgumentCount();
|
||||
void SetArguments(T args);
|
||||
void Run();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,8 +37,6 @@
|
|||
<Compile Include="AdrianKousz.Util\ExtendedBinaryReader.cs" />
|
||||
<Compile Include="AdrianKousz.Util\ExtendedBinaryWriter.cs" />
|
||||
<Compile Include="AdrianKousz.Util\UncompressedDeflateStream.cs" />
|
||||
<Compile Include="AdrianKousz.Util\ICommand.cs" />
|
||||
<Compile Include="AdrianKousz.Util\IApp.cs" />
|
||||
<Compile Include="AdrianKousz.Util\CmdApp.cs" />
|
||||
<Compile Include="AdrianKousz.Util\NonDisposingStreamWrapper.cs" />
|
||||
<Compile Include="AdrianKousz.Util\UnsafeBitmap.cs" />
|
||||
|
|
Loading…
Reference in New Issue