1
0
mirror of https://github.com/chylex/Query.git synced 2025-06-05 09:34:03 +02:00

Reformat code

This commit is contained in:
chylex 2024-07-29 17:02:09 +02:00
parent 9a386d25f4
commit a283fe7c9e
Signed by: chylex
GPG Key ID: 4DE42C8F19A80548
35 changed files with 1529 additions and 1542 deletions

View File

@ -6,182 +6,188 @@ using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Base; using Base;
namespace AppCalc{ namespace AppCalc {
public sealed class App : IApp{ public sealed class App : IApp {
private static readonly Regex RegexValidCharacters = new Regex(@"^[\s\d\.\-+*/%^]+$", RegexOptions.Compiled); private static readonly Regex RegexValidCharacters = new Regex(@"^[\s\d\.\-+*/%^]+$", RegexOptions.Compiled);
private static readonly Regex RegexTokenSeparator = new Regex(@"((?<!\d)-?(((\d+)?\.\d+(\.\.\.)?)|\d+))|[^\d\s]", RegexOptions.ExplicitCapture | RegexOptions.Compiled); private static readonly Regex RegexTokenSeparator = new Regex(@"((?<!\d)-?(((\d+)?\.\d+(\.\.\.)?)|\d+))|[^\d\s]", RegexOptions.ExplicitCapture | RegexOptions.Compiled);
private static readonly Regex RegexRecurringDecimal = new Regex(@"\b(?:(\d+?\.\d{0,}?)(\d+?)\2+|([\d+?\.]*))\b", RegexOptions.Compiled); private static readonly Regex RegexRecurringDecimal = new Regex(@"\b(?:(\d+?\.\d{0,}?)(\d+?)\2+|([\d+?\.]*))\b", RegexOptions.Compiled);
private static readonly char[] SplitSpace = { ' ' }; private static readonly char[] SplitSpace = { ' ' };
public string[] RecognizedNames => new string[]{ public string[] RecognizedNames => new string[] {
"calc", "calc",
"calculate", "calculate",
"calculator" "calculator"
}; };
public MatchConfidence GetConfidence(Command cmd){ public MatchConfidence GetConfidence(Command cmd) {
return RegexValidCharacters.IsMatch(cmd.Text) ? MatchConfidence.Possible : MatchConfidence.None; return RegexValidCharacters.IsMatch(cmd.Text) ? MatchConfidence.Possible : MatchConfidence.None;
} }
string IApp.ProcessCommand(Command cmd){ string IApp.ProcessCommand(Command cmd) {
return ParseAndProcessExpression(cmd.Text); return ParseAndProcessExpression(cmd.Text);
} }
private static string ParseAndProcessExpression(string text){ private static string ParseAndProcessExpression(string text) {
// text = RegexBalancedParentheses.Replace(text, match => " "+ParseAndProcessExpression(match.Groups[1].Value)+" "); // parens are handled as apps // text = RegexBalancedParentheses.Replace(text, match => " "+ParseAndProcessExpression(match.Groups[1].Value)+" "); // parens are handled as apps
string expression = RegexTokenSeparator.Replace(text, match => " "+match.Value+" "); string expression = RegexTokenSeparator.Replace(text, match => " " + match.Value + " ");
string[] tokens = expression.Split(SplitSpace, StringSplitOptions.RemoveEmptyEntries); string[] tokens = expression.Split(SplitSpace, StringSplitOptions.RemoveEmptyEntries);
decimal result = ProcessExpression(tokens); decimal result = ProcessExpression(tokens);
if (Math.Abs(result-decimal.Round(result)) < 0.0000000000000000000000000010M){ if (Math.Abs(result - decimal.Round(result)) < 0.0000000000000000000000000010M) {
return decimal.Round(result).ToString(CultureInfo.InvariantCulture); return decimal.Round(result).ToString(CultureInfo.InvariantCulture);
} }
string res = result.ToString(CultureInfo.InvariantCulture); string res = result.ToString(CultureInfo.InvariantCulture);
bool hasDecimalPoint = decimal.Round(result) != result; bool hasDecimalPoint = decimal.Round(result) != result;
if (res.Length == 30 && hasDecimalPoint && res.IndexOf('.') < 15){ // Length 30 uses all available bytes if (res.Length == 30 && hasDecimalPoint && res.IndexOf('.') < 15) { // Length 30 uses all available bytes
res = res.Substring(0, res.Length-1); res = res.Substring(0, res.Length - 1);
Match match = RegexRecurringDecimal.Match(res); Match match = RegexRecurringDecimal.Match(res);
if (match.Groups[2].Success){ if (match.Groups[2].Success) {
string repeating = match.Groups[2].Value; string repeating = match.Groups[2].Value;
StringBuilder build = new StringBuilder(34); StringBuilder build = new StringBuilder(34);
build.Append(match.Groups[1].Value); build.Append(match.Groups[1].Value);
do{ do {
build.Append(repeating); build.Append(repeating);
}while(build.Length+repeating.Length <= res.Length); } while (build.Length + repeating.Length <= res.Length);
return build.Append(repeating.Substring(0, 1+build.Length-res.Length)).Append("...").ToString(); return build.Append(repeating.Substring(0, 1 + build.Length - res.Length)).Append("...").ToString();
} }
} }
else if (hasDecimalPoint){ else if (hasDecimalPoint) {
res = res.TrimEnd('0'); res = res.TrimEnd('0');
} }
return res; return res;
} }
private static decimal ProcessExpression(string[] tokens){ private static decimal ProcessExpression(string[] tokens) {
bool isPostfix; bool isPostfix;
if (tokens.Length < 3){ if (tokens.Length < 3) {
isPostfix = false; isPostfix = false;
} }
else{ else {
try{ try {
ParseNumberToken(tokens[0]); ParseNumberToken(tokens[0]);
}catch(CommandException){ } catch (CommandException) {
throw new CommandException("Prefix notation is not supported."); throw new CommandException("Prefix notation is not supported.");
} }
try{ try {
ParseNumberToken(tokens[1]); ParseNumberToken(tokens[1]);
isPostfix = true; isPostfix = true;
}catch(CommandException){ } catch (CommandException) {
isPostfix = false; isPostfix = false;
} }
} }
if (isPostfix){ if (isPostfix) {
return ProcessPostfixExpression(tokens); return ProcessPostfixExpression(tokens);
} }
else{ else {
return ProcessPostfixExpression(ConvertInfixToPostfix(tokens)); return ProcessPostfixExpression(ConvertInfixToPostfix(tokens));
} }
} }
private static IEnumerable<string> ConvertInfixToPostfix(IEnumerable<string> tokens){ private static IEnumerable<string> ConvertInfixToPostfix(IEnumerable<string> tokens) {
Stack<string> operators = new Stack<string>(); Stack<string> operators = new Stack<string>();
foreach(string token in tokens){ foreach (string token in tokens) {
if (Operators.With2Operands.Contains(token)){ if (Operators.With2Operands.Contains(token)) {
int currentPrecedence = Operators.GetPrecedence(token); int currentPrecedence = Operators.GetPrecedence(token);
bool currentRightAssociative = Operators.IsRightAssociative(token); bool currentRightAssociative = Operators.IsRightAssociative(token);
while(operators.Count > 0){ while (operators.Count > 0) {
int topPrecedence = Operators.GetPrecedence(operators.Peek()); int topPrecedence = Operators.GetPrecedence(operators.Peek());
if ((currentRightAssociative && currentPrecedence < topPrecedence) || (!currentRightAssociative && currentPrecedence <= topPrecedence)){ if ((currentRightAssociative && currentPrecedence < topPrecedence) || (!currentRightAssociative && currentPrecedence <= topPrecedence)) {
yield return operators.Pop(); yield return operators.Pop();
} }
else{ else {
break; break;
} }
} }
operators.Push(token); operators.Push(token);
} }
else{ else {
yield return ParseNumberToken(token).ToString(CultureInfo.InvariantCulture); yield return ParseNumberToken(token).ToString(CultureInfo.InvariantCulture);
} }
} }
while(operators.Count > 0){ while (operators.Count > 0) {
yield return operators.Pop(); yield return operators.Pop();
} }
} }
private static decimal ProcessPostfixExpression(IEnumerable<string> tokens){ private static decimal ProcessPostfixExpression(IEnumerable<string> tokens) {
Stack<decimal> stack = new Stack<decimal>(); Stack<decimal> stack = new Stack<decimal>();
foreach(string token in tokens){ foreach (string token in tokens) {
decimal operand1, operand2; decimal operand1, operand2;
if (token == "-" && stack.Count == 1){ if (token == "-" && stack.Count == 1) {
operand2 = stack.Pop(); operand2 = stack.Pop();
operand1 = 0M; operand1 = 0M;
} }
else if (Operators.With2Operands.Contains(token)){ else if (Operators.With2Operands.Contains(token)) {
if (stack.Count < 2){ if (stack.Count < 2) {
throw new CommandException("Incorrect syntax, not enough numbers in stack."); throw new CommandException("Incorrect syntax, not enough numbers in stack.");
} }
operand2 = stack.Pop(); operand2 = stack.Pop();
operand1 = stack.Pop(); operand1 = stack.Pop();
} }
else{ else {
operand1 = operand2 = 0M; operand1 = operand2 = 0M;
} }
switch(token){ switch (token) {
case "+": stack.Push(operand1+operand2); break; case "+":
case "-": stack.Push(operand1-operand2); break; stack.Push(operand1 + operand2);
case "*": stack.Push(operand1*operand2); break; break;
case "-":
stack.Push(operand1 - operand2);
break;
case "*":
stack.Push(operand1 * operand2);
break;
case "/": case "/":
if (operand2 == 0M){ if (operand2 == 0M) {
throw new CommandException("Cannot divide by zero."); throw new CommandException("Cannot divide by zero.");
} }
stack.Push(operand1/operand2); stack.Push(operand1 / operand2);
break; break;
case "%": case "%":
if (operand2 == 0M){ if (operand2 == 0M) {
throw new CommandException("Cannot divide by zero."); throw new CommandException("Cannot divide by zero.");
} }
stack.Push(operand1%operand2); stack.Push(operand1 % operand2);
break; break;
case "^": case "^":
if (operand1 == 0M && operand2 == 0M){ if (operand1 == 0M && operand2 == 0M) {
throw new CommandException("Cannot evaluate 0 to the power of 0."); throw new CommandException("Cannot evaluate 0 to the power of 0.");
} }
else if (operand1 < 0M && Math.Abs(operand2) < 1M){ else if (operand1 < 0M && Math.Abs(operand2) < 1M) {
throw new CommandException("Cannot evaluate a root of a negative number."); throw new CommandException("Cannot evaluate a root of a negative number.");
} }
try{ try {
stack.Push((decimal)Math.Pow((double)operand1, (double)operand2)); stack.Push((decimal) Math.Pow((double) operand1, (double) operand2));
}catch(OverflowException ex){ } catch (OverflowException ex) {
throw new CommandException("Number overflow.", ex); throw new CommandException("Number overflow.", ex);
} }
@ -193,42 +199,42 @@ namespace AppCalc{
} }
} }
if (stack.Count != 1){ if (stack.Count != 1) {
throw new CommandException("Incorrect syntax, too many numbers in stack."); throw new CommandException("Incorrect syntax, too many numbers in stack.");
} }
return stack.Pop(); return stack.Pop();
} }
private static decimal ParseNumberToken(string token){ private static decimal ParseNumberToken(string token) {
string str = token; string str = token;
if (str.StartsWith("-.")){ if (str.StartsWith("-.")) {
str = "-0"+str.Substring(1); str = "-0" + str.Substring(1);
} }
else if (str[0] == '.'){ else if (str[0] == '.') {
str = "0"+str; str = "0" + str;
} }
if (str.EndsWith("...")){ if (str.EndsWith("...")) {
string truncated = str.Substring(0, str.Length-3); string truncated = str.Substring(0, str.Length - 3);
if (truncated.IndexOf('.') != -1){ if (truncated.IndexOf('.') != -1) {
str = truncated; str = truncated;
} }
} }
decimal value; decimal value;
if (decimal.TryParse(str, NumberStyles.Float, CultureInfo.InvariantCulture, out value)){ if (decimal.TryParse(str, NumberStyles.Float, CultureInfo.InvariantCulture, out value)) {
if (value.ToString(CultureInfo.InvariantCulture) != str){ if (value.ToString(CultureInfo.InvariantCulture) != str) {
throw new CommandException("Provided number is outside of decimal range: "+token); throw new CommandException("Provided number is outside of decimal range: " + token);
} }
return value; return value;
} }
else{ else {
throw new CommandException("Invalid token, expected a number: "+token); throw new CommandException("Invalid token, expected a number: " + token);
} }
} }
} }

View File

@ -1,9 +1,9 @@
namespace AppCalc{ namespace AppCalc {
internal static class Operators{ static class Operators {
internal static readonly string[] With2Operands = { "+", "-", "*", "/", "%", "^" }; internal static readonly string[] With2Operands = { "+", "-", "*", "/", "%", "^" };
internal static int GetPrecedence(string token){ internal static int GetPrecedence(string token) {
switch(token){ switch (token) {
case "^": case "^":
return 4; return 4;
@ -21,7 +21,7 @@
} }
} }
internal static bool IsRightAssociative(string token){ internal static bool IsRightAssociative(string token) {
return token == "^"; return token == "^";
} }
} }

View File

@ -4,8 +4,8 @@ using AppConv.General;
using AppConv.Units; using AppConv.Units;
using Base; using Base;
namespace AppConv{ namespace AppConv {
public sealed class App : IApp{ public sealed class App : IApp {
private static readonly IUnitType[] Processors = { private static readonly IUnitType[] Processors = {
new Temperature(), new Temperature(),
new Weight(), new Weight(),
@ -17,29 +17,29 @@ namespace AppConv{
new Radix() new Radix()
}; };
public string[] RecognizedNames => new string[]{ public string[] RecognizedNames => new string[] {
"conv", "conv",
"convert" "convert"
}; };
public MatchConfidence GetConfidence(Command cmd){ public MatchConfidence GetConfidence(Command cmd) {
return cmd.Text.IndexOf(" to ", StringComparison.InvariantCultureIgnoreCase) != -1 ? MatchConfidence.Possible : MatchConfidence.None; return cmd.Text.IndexOf(" to ", StringComparison.InvariantCultureIgnoreCase) != -1 ? MatchConfidence.Possible : MatchConfidence.None;
} }
public string ProcessCommand(Command cmd){ public string ProcessCommand(Command cmd) {
string[] data = cmd.Text.Split(new string[]{ " to " }, 2, StringSplitOptions.None); string[] data = cmd.Text.Split(new string[] { " to " }, 2, StringSplitOptions.None);
string src = data[0].Trim(); string src = data[0].Trim();
string dst = data[1].Trim(); string dst = data[1].Trim();
if (src.Length == 0 || dst.Length == 0){ if (src.Length == 0 || dst.Length == 0) {
throw new CommandException("Unrecognized conversion app syntax."); throw new CommandException("Unrecognized conversion app syntax.");
} }
string result = string.Empty; string result = string.Empty;
IUnitType used = Processors.FirstOrDefault(processor => processor.TryProcess(src, dst, out result)); IUnitType used = Processors.FirstOrDefault(processor => processor.TryProcess(src, dst, out result));
if (used == null){ if (used == null) {
throw new CommandException("Could not recognize conversion units."); throw new CommandException("Could not recognize conversion units.");
} }

View File

@ -3,121 +3,109 @@ using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
namespace AppConv.General{ namespace AppConv.General {
internal abstract class DecimalUnitConverterBase<T> : IUnitType where T : struct{ abstract class DecimalUnitConverterBase<T> : IUnitType where T : struct {
internal sealed class DecimalFuncMap : Dictionary<T, Func<decimal, decimal>>{ internal sealed class DecimalFuncMap : Dictionary<T, Func<decimal, decimal>> {
public DecimalFuncMap(){} public DecimalFuncMap() {}
public DecimalFuncMap(int capacity) : base(capacity){} public DecimalFuncMap(int capacity) : base(capacity) {}
} }
internal sealed class NameMap : Dictionary<string, T>{ internal sealed class NameMap : Dictionary<string, T> {
public NameMap(){} public NameMap() {}
public NameMap(int capacity) : base(capacity){} public NameMap(int capacity) : base(capacity) {}
} }
protected abstract NameMap Names { get; } protected abstract NameMap Names { get; }
protected abstract DecimalFuncMap ConvertTo { get; } protected abstract DecimalFuncMap ConvertTo { get; }
protected abstract DecimalFuncMap ConvertFrom { get; } protected abstract DecimalFuncMap ConvertFrom { get; }
protected virtual int Precision{ protected virtual int Precision => 0;
get{
return 0;
}
}
protected virtual bool CaseCheck{ protected virtual bool CaseCheck => false;
get{
return false;
}
}
protected virtual NumberStyles NumberStyle{ protected virtual NumberStyles NumberStyle => NumberStyles.Float & ~NumberStyles.AllowLeadingSign;
get{
return NumberStyles.Float & ~NumberStyles.AllowLeadingSign;
}
}
protected virtual string ProcessSrc(string src){ protected virtual string ProcessSrc(string src) {
return src; return src;
} }
protected virtual string ProcessDst(string dst){ protected virtual string ProcessDst(string dst) {
return dst; return dst;
} }
protected abstract bool IsValueInvalid(T value); protected abstract bool IsValueInvalid(T value);
protected virtual decimal Convert(decimal value, T from, T to){ protected virtual decimal Convert(decimal value, T from, T to) {
return ConvertFrom[to](ConvertTo[from](value)); return ConvertFrom[to](ConvertTo[from](value));
} }
protected virtual string Format(decimal value){ protected virtual string Format(decimal value) {
if (Precision > 0){ if (Precision > 0) {
decimal truncated = decimal.Truncate(value); decimal truncated = decimal.Truncate(value);
if (value == truncated){ if (value == truncated) {
return truncated.ToString(CultureInfo.InvariantCulture); return truncated.ToString(CultureInfo.InvariantCulture);
} }
} }
int decimalPlaces = Precision; int decimalPlaces = Precision;
if (Math.Abs(value) < 1M){ if (Math.Abs(value) < 1M) {
double fractionalPart = (double)Math.Abs(value%1M); double fractionalPart = (double) Math.Abs(value % 1M);
int fractionalZeroCount = -(int)Math.Ceiling(Math.Log(fractionalPart, 10D)); int fractionalZeroCount = -(int) Math.Ceiling(Math.Log(fractionalPart, 10D));
decimalPlaces = Math.Min(28, fractionalZeroCount+Precision); decimalPlaces = Math.Min(28, fractionalZeroCount + Precision);
} }
string result = decimal.Round(value, decimalPlaces, MidpointRounding.ToEven).ToString(CultureInfo.InvariantCulture); string result = decimal.Round(value, decimalPlaces, MidpointRounding.ToEven).ToString(CultureInfo.InvariantCulture);
if (decimalPlaces > 0){ if (decimalPlaces > 0) {
result = result.TrimEnd('0').TrimEnd('.'); result = result.TrimEnd('0').TrimEnd('.');
} }
return result; return result;
} }
public bool TryProcess(string src, string dst, out string result){ public bool TryProcess(string src, string dst, out string result) {
src = ProcessSrc(src); src = ProcessSrc(src);
dst = ProcessDst(dst); dst = ProcessDst(dst);
KeyValuePair<string, T>[] pairs = new KeyValuePair<string, T>[2]; var pairs = new KeyValuePair<string, T>[2];
for(int index = 0; index < 2; index++){ for (int index = 0; index < 2; index++) {
string str = index == 0 ? src : dst; string str = index == 0 ? src : dst;
if (CaseCheck){ if (CaseCheck) {
List<KeyValuePair<string, T>> list = Names.Where(kvp => str.EndsWith(kvp.Key, StringComparison.InvariantCultureIgnoreCase) && (str.Length == kvp.Key.Length || !char.IsLetter(str[str.Length-kvp.Key.Length-1]))).ToList(); List<KeyValuePair<string, T>> list = Names.Where(kvp => str.EndsWith(kvp.Key, StringComparison.InvariantCultureIgnoreCase) && (str.Length == kvp.Key.Length || !char.IsLetter(str[str.Length - kvp.Key.Length - 1]))).ToList();
if (list.Count == 1){ if (list.Count == 1) {
pairs[index] = list[0]; pairs[index] = list[0];
} }
else{ else {
pairs[index] = list.FirstOrDefault(kvp => str.EndsWith(kvp.Key, StringComparison.InvariantCulture)); pairs[index] = list.FirstOrDefault(kvp => str.EndsWith(kvp.Key, StringComparison.InvariantCulture));
} }
} }
else{ else {
pairs[index] = Names.FirstOrDefault(kvp => str.EndsWith(kvp.Key, StringComparison.InvariantCultureIgnoreCase) && (str.Length == kvp.Key.Length || !char.IsLetter(str[str.Length-kvp.Key.Length-1]))); pairs[index] = Names.FirstOrDefault(kvp => str.EndsWith(kvp.Key, StringComparison.InvariantCultureIgnoreCase) && (str.Length == kvp.Key.Length || !char.IsLetter(str[str.Length - kvp.Key.Length - 1])));
} }
if (IsValueInvalid(pairs[index].Value)){ if (IsValueInvalid(pairs[index].Value)) {
result = string.Empty; result = string.Empty;
return false; return false;
} }
if (index == 0){ if (index == 0) {
src = src.Substring(0, src.Length-pairs[index].Key.Length).TrimEnd(); src = src.Substring(0, src.Length - pairs[index].Key.Length).TrimEnd();
} }
} }
decimal value; decimal value;
if (decimal.TryParse(src, NumberStyle, CultureInfo.InvariantCulture, out value)){ if (decimal.TryParse(src, NumberStyle, CultureInfo.InvariantCulture, out value)) {
result = Format(Convert(value, pairs[0].Value, pairs[1].Value)); result = Format(Convert(value, pairs[0].Value, pairs[1].Value));
return true; return true;
} }
else{ else {
result = string.Empty; result = string.Empty;
return false; return false;
} }

View File

@ -1,7 +1,7 @@
using System; using System;
namespace AppConv.General{ namespace AppConv.General {
internal abstract class DecimalUnitConverterSimple<T> : DecimalUnitConverterBase<T> where T : struct{ abstract class DecimalUnitConverterSimple<T> : DecimalUnitConverterBase<T> where T : struct {
// ReSharper disable once StaticMemberInGenericType // ReSharper disable once StaticMemberInGenericType
private static readonly Func<decimal, decimal> FuncNoChange = val => val; private static readonly Func<decimal, decimal> FuncNoChange = val => val;
@ -11,38 +11,18 @@ namespace AppConv.General{
private int invalidUnitObject = -1; private int invalidUnitObject = -1;
protected sealed override NameMap Names{ protected sealed override NameMap Names => UnitNames;
get{
return UnitNames;
}
}
protected sealed override DecimalFuncMap ConvertFrom{ protected sealed override DecimalFuncMap ConvertFrom => MapFrom;
get{
return MapFrom;
}
}
protected sealed override DecimalFuncMap ConvertTo{ protected sealed override DecimalFuncMap ConvertTo => MapTo;
get{
return MapTo;
}
}
protected override int Precision{ protected override int Precision => 3;
get{
return 3;
}
}
protected override bool CaseCheck{ protected override bool CaseCheck => true;
get{
return true;
}
}
protected void AddUnit(T unitObject, params string[] names){ protected void AddUnit(T unitObject, params string[] names) {
foreach(string name in names){ foreach (string name in names) {
UnitNames.Add(name, unitObject); UnitNames.Add(name, unitObject);
} }
@ -50,17 +30,17 @@ namespace AppConv.General{
ConvertTo.Add(unitObject, FuncNoChange); ConvertTo.Add(unitObject, FuncNoChange);
} }
protected void SetUnitFactor(T unitObject, decimal factor){ protected void SetUnitFactor(T unitObject, decimal factor) {
ConvertFrom[unitObject] = val => val*factor; ConvertFrom[unitObject] = val => val * factor;
ConvertTo[unitObject] = val => val/factor; ConvertTo[unitObject] = val => val / factor;
} }
protected void SetInvalidUnitObject(T unitObject){ protected void SetInvalidUnitObject(T unitObject) {
this.invalidUnitObject = (int)(object)unitObject; invalidUnitObject = (int) (object) unitObject;
} }
protected sealed override bool IsValueInvalid(T value){ protected sealed override bool IsValueInvalid(T value) {
return (int)(object)value == invalidUnitObject; return (int) (object) value == invalidUnitObject;
} }
} }
} }

View File

@ -1,5 +1,5 @@
namespace AppConv.General{ namespace AppConv.General {
internal interface IUnitType{ interface IUnitType {
bool TryProcess(string src, string dst, out string result); bool TryProcess(string src, string dst, out string result);
} }
} }

View File

@ -2,24 +2,23 @@
using AppConv.General; using AppConv.General;
namespace AppConv.Units { namespace AppConv.Units {
internal class Angle : DecimalUnitConverterSimple<Angle.Units>{ class Angle : DecimalUnitConverterSimple<Angle.Units> {
internal enum Units{ internal enum Units {
Invalid = 0, Degree, Radian, Gradian Invalid = 0,
Degree,
Radian,
Gradian
} }
protected override int Precision{ protected override int Precision => 4;
get{
return 4;
}
}
public Angle(){ public Angle() {
AddUnit(Units.Degree, "deg", "degree", "degrees", "arc degree", "arc degrees", "arcdegree", "arcdegrees", "°"); AddUnit(Units.Degree, "deg", "degree", "degrees", "arc degree", "arc degrees", "arcdegree", "arcdegrees", "°");
AddUnit(Units.Radian, "rad", "radian", "radians"); AddUnit(Units.Radian, "rad", "radian", "radians");
AddUnit(Units.Gradian, "grad", "grade", "gon", "gradian", "gradians"); AddUnit(Units.Gradian, "grad", "grade", "gon", "gradian", "gradians");
SetUnitFactor(Units.Radian, (decimal)Math.PI/180M); SetUnitFactor(Units.Radian, (decimal) Math.PI / 180M);
SetUnitFactor(Units.Gradian, 10M/9M); SetUnitFactor(Units.Gradian, 10M / 9M);
SetInvalidUnitObject(Units.Invalid); SetInvalidUnitObject(Units.Invalid);
} }

View File

@ -1,12 +1,27 @@
using AppConv.General; using AppConv.General;
namespace AppConv.Units{ namespace AppConv.Units {
internal class Area : DecimalUnitConverterSimple<Area.Units>{ class Area : DecimalUnitConverterSimple<Area.Units> {
internal enum Units{ internal enum Units {
Invalid = 0, SquareMM, SquareCM, SquareDM, SquareM, SquareKM, SquareMile, SquareYard, SquareFoot, SquareInch, Acre, Centiare, Deciare, Are, Decare, Hectare Invalid = 0,
SquareMM,
SquareCM,
SquareDM,
SquareM,
SquareKM,
SquareMile,
SquareYard,
SquareFoot,
SquareInch,
Acre,
Centiare,
Deciare,
Are,
Decare,
Hectare
} }
public Area(){ public Area() {
AddUnit(Units.SquareMM, "mm2", "square mm", "square millimeter", "square millimeters", "square millimetre", "square millimetres"); AddUnit(Units.SquareMM, "mm2", "square mm", "square millimeter", "square millimeters", "square millimetre", "square millimetres");
AddUnit(Units.SquareCM, "cm2", "square cm", "square centimeter", "square centimeters", "square centimetre", "square centimetres"); AddUnit(Units.SquareCM, "cm2", "square cm", "square centimeter", "square centimeters", "square centimetre", "square centimetres");
AddUnit(Units.SquareDM, "dm2", "square dm", "square decimeter", "square decimeters", "square decimetre", "square decimetres"); AddUnit(Units.SquareDM, "dm2", "square dm", "square decimeter", "square decimeters", "square decimetre", "square decimetres");

View File

@ -4,16 +4,21 @@ using System.Linq;
using AppConv.General; using AppConv.General;
using AppConv.Utils; using AppConv.Utils;
namespace AppConv.Units{ namespace AppConv.Units {
internal class Length : DecimalUnitConverterSimple<Length.Units>{ class Length : DecimalUnitConverterSimple<Length.Units> {
internal enum Units{ internal enum Units {
Invalid = 0, Meter, Inch, Foot, Yard, Mile Invalid = 0,
Meter,
Inch,
Foot,
Yard,
Mile
} }
private static readonly string[] NamesInch = { "in", "inch", "inches", "\"", "''" }; private static readonly string[] NamesInch = { "in", "inch", "inches", "\"", "''" };
private static readonly string[] NamesFoot = { "ft", "foot", "feet", "'" }; private static readonly string[] NamesFoot = { "ft", "foot", "feet", "'" };
public Length(){ public Length() {
AddUnit(Units.Meter, "m", "meter", "metre", "meters", "metres"); AddUnit(Units.Meter, "m", "meter", "metre", "meters", "metres");
AddUnit(Units.Inch, NamesInch); AddUnit(Units.Inch, NamesInch);
AddUnit(Units.Foot, NamesFoot); AddUnit(Units.Foot, NamesFoot);
@ -27,10 +32,10 @@ namespace AppConv.Units{
SetInvalidUnitObject(Units.Invalid); SetInvalidUnitObject(Units.Invalid);
SI.AddSupport(typeof(Units), Units.Meter, new []{ "m" }, new []{ "meter", "metre", "meters", "metres" }, ConvertFrom, ConvertTo, Names); SI.AddSupport(typeof(Units), Units.Meter, new [] { "m" }, new [] { "meter", "metre", "meters", "metres" }, ConvertFrom, ConvertTo, Names);
} }
protected override string ProcessSrc(string src){ protected override string ProcessSrc(string src) {
string updatedStr = src; string updatedStr = src;
updatedStr = updatedStr.Replace("&", " "); updatedStr = updatedStr.Replace("&", " ");
@ -38,7 +43,7 @@ namespace AppConv.Units{
string inchName = NamesInch.FirstOrDefault(name => src.IndexOf(name, StringComparison.OrdinalIgnoreCase) != -1); string inchName = NamesInch.FirstOrDefault(name => src.IndexOf(name, StringComparison.OrdinalIgnoreCase) != -1);
if (inchName == null){ if (inchName == null) {
return src; return src;
} }
@ -47,38 +52,38 @@ namespace AppConv.Units{
string footName = NamesFoot.FirstOrDefault(name => updatedStr.IndexOf(name, StringComparison.OrdinalIgnoreCase) != -1); string footName = NamesFoot.FirstOrDefault(name => updatedStr.IndexOf(name, StringComparison.OrdinalIgnoreCase) != -1);
if (footName == null){ if (footName == null) {
return src; return src;
} }
int footIndex = updatedStr.IndexOf(footName, StringComparison.OrdinalIgnoreCase); int footIndex = updatedStr.IndexOf(footName, StringComparison.OrdinalIgnoreCase);
updatedStr = updatedStr.Remove(footIndex, footName.Length).Insert(footIndex, new string(' ', footName.Length)); updatedStr = updatedStr.Remove(footIndex, footName.Length).Insert(footIndex, new string(' ', footName.Length));
string[] tokens = updatedStr.Split(new char[]{ ' ' }, StringSplitOptions.RemoveEmptyEntries); string[] tokens = updatedStr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
decimal[] numbers = new decimal[2]; decimal[] numbers = new decimal[2];
int numberIndex = 0; int numberIndex = 0;
foreach(string token in tokens){ foreach (string token in tokens) {
decimal number; decimal number;
if (decimal.TryParse(token.Trim(), NumberStyle, CultureInfo.InvariantCulture, out number)){ if (decimal.TryParse(token.Trim(), NumberStyle, CultureInfo.InvariantCulture, out number)) {
if (numberIndex < numbers.Length){ if (numberIndex < numbers.Length) {
numbers[numberIndex++] = number; numbers[numberIndex++] = number;
} }
else{ else {
return src; return src;
} }
} }
} }
if (numberIndex != numbers.Length){ if (numberIndex != numbers.Length) {
return src; return src;
} }
decimal srcFeet = numbers[footIndex < inchIndex ? 0 : 1]; decimal srcFeet = numbers[footIndex < inchIndex ? 0 : 1];
decimal srcInches = numbers[inchIndex < footIndex ? 0 : 1]; decimal srcInches = numbers[inchIndex < footIndex ? 0 : 1];
return srcInches+srcFeet*12M+" in"; return srcInches + srcFeet * 12M + " in";
} }
} }
} }

View File

@ -5,9 +5,9 @@ using AppConv.General;
using AppConv.Utils; using AppConv.Utils;
using Base; using Base;
namespace AppConv.Units{ namespace AppConv.Units {
internal class Radix : IUnitType{ class Radix : IUnitType {
private static readonly Dictionary<string, int> RadixDescriptions = new Dictionary<string, int>{ private static readonly Dictionary<string, int> RadixDescriptions = new Dictionary<string, int> {
{ "UNARY", 1 }, { "UNARY", 1 },
{ "BINARY", 2 }, { "BINARY", 2 },
{ "BIN", 2 }, { "BIN", 2 },
@ -29,17 +29,17 @@ namespace AppConv.Units{
{ "HEX", 16 } { "HEX", 16 }
}; };
static Radix(){ static Radix() {
for(int baseNumber = 1; baseNumber <= 16; baseNumber++){ for (int baseNumber = 1; baseNumber <= 16; baseNumber++) {
RadixDescriptions.Add("RADIX "+baseNumber, baseNumber); RadixDescriptions.Add("RADIX " + baseNumber, baseNumber);
RadixDescriptions.Add("BASE "+baseNumber, baseNumber); RadixDescriptions.Add("BASE " + baseNumber, baseNumber);
} }
} }
public bool TryProcess(string src, string dst, out string result){ public bool TryProcess(string src, string dst, out string result) {
int targetBase; int targetBase;
if (!RadixDescriptions.TryGetValue(dst.ToUpperInvariant(), out targetBase)){ if (!RadixDescriptions.TryGetValue(dst.ToUpperInvariant(), out targetBase)) {
result = string.Empty; result = string.Empty;
return false; return false;
} }
@ -47,37 +47,37 @@ namespace AppConv.Units{
string contents; string contents;
int sourceBase; int sourceBase;
if (!ParseSrc(src, out contents, out sourceBase)){ if (!ParseSrc(src, out contents, out sourceBase)) {
result = string.Empty; result = string.Empty;
return false; return false;
} }
if (contents[0] == '-'){ if (contents[0] == '-') {
throw new CommandException("Negative numbers are not supported."); throw new CommandException("Negative numbers are not supported.");
} }
else if (!RadixConversion.IsBaseValid(sourceBase) || !RadixConversion.IsBaseValid(targetBase)){ else if (!RadixConversion.IsBaseValid(sourceBase) || !RadixConversion.IsBaseValid(targetBase)) {
throw new CommandException("Only bases between 1 and 16 allowed."); throw new CommandException("Only bases between 1 and 16 allowed.");
} }
else if (!RadixConversion.IsNumberValid(contents, sourceBase)){ else if (!RadixConversion.IsNumberValid(contents, sourceBase)) {
throw new CommandException("The input is not a valid base "+sourceBase+" number: "+contents); throw new CommandException("The input is not a valid base " + sourceBase + " number: " + contents);
} }
if (sourceBase == targetBase){ if (sourceBase == targetBase) {
result = src; result = src;
return true; return true;
} }
try{ try {
result = RadixConversion.Do(contents, sourceBase, targetBase); result = RadixConversion.Do(contents, sourceBase, targetBase);
}catch(OverflowException){ } catch (OverflowException) {
throw new CommandException("The number has overflown."); throw new CommandException("The number has overflown.");
} }
return true; return true;
} }
private static bool ParseSrc(string src, out string sourceContent, out int sourceBase){ private static bool ParseSrc(string src, out string sourceContent, out int sourceBase) {
if (src.All(chr => chr >= '0' && chr <= '9')){ if (src.All(chr => chr >= '0' && chr <= '9')) {
sourceContent = src; sourceContent = src;
sourceBase = 10; sourceBase = 10;
return true; return true;
@ -85,13 +85,13 @@ namespace AppConv.Units{
string upper = src.ToUpperInvariant(); string upper = src.ToUpperInvariant();
if (upper.StartsWith("0X")){ if (upper.StartsWith("0X")) {
sourceContent = upper.Substring(2); sourceContent = upper.Substring(2);
sourceBase = 16; sourceBase = 16;
return true; return true;
} }
if (upper.StartsWith("0B")){ if (upper.StartsWith("0B")) {
sourceContent = upper.Substring(2); sourceContent = upper.Substring(2);
sourceBase = 2; sourceBase = 2;
return true; return true;
@ -99,18 +99,18 @@ namespace AppConv.Units{
int fromIndex = src.IndexOf("FROM", StringComparison.InvariantCultureIgnoreCase); int fromIndex = src.IndexOf("FROM", StringComparison.InvariantCultureIgnoreCase);
if (fromIndex != -1){ if (fromIndex != -1) {
src = src.Remove(fromIndex, 4); src = src.Remove(fromIndex, 4);
} }
foreach(KeyValuePair<string, int> kvp in RadixDescriptions){ foreach (KeyValuePair<string, int> kvp in RadixDescriptions) {
if (src.StartsWith(kvp.Key, StringComparison.InvariantCultureIgnoreCase)){ if (src.StartsWith(kvp.Key, StringComparison.InvariantCultureIgnoreCase)) {
sourceContent = src.Substring(kvp.Key.Length).Trim(); sourceContent = src.Substring(kvp.Key.Length).Trim();
sourceBase = kvp.Value; sourceBase = kvp.Value;
return true; return true;
} }
else if (src.EndsWith(kvp.Key, StringComparison.InvariantCultureIgnoreCase)){ else if (src.EndsWith(kvp.Key, StringComparison.InvariantCultureIgnoreCase)) {
sourceContent = src.Substring(0, src.Length-kvp.Key.Length).Trim(); sourceContent = src.Substring(0, src.Length - kvp.Key.Length).Trim();
sourceBase = kvp.Value; sourceBase = kvp.Value;
return true; return true;
} }

View File

@ -3,12 +3,14 @@ using AppConv.General;
using AppConv.Utils; using AppConv.Utils;
namespace AppConv.Units { namespace AppConv.Units {
internal class Storage : DecimalUnitConverterSimple<Storage.Units>{ class Storage : DecimalUnitConverterSimple<Storage.Units> {
internal enum Units{ internal enum Units {
Invalid = 0, Byte, Bit Invalid = 0,
Byte,
Bit
} }
public Storage(){ public Storage() {
AddUnit(Units.Byte, "B", "byte", "bytes"); AddUnit(Units.Byte, "B", "byte", "bytes");
AddUnit(Units.Bit, "b", "bit", "bits"); AddUnit(Units.Bit, "b", "bit", "bits");
@ -16,14 +18,14 @@ namespace AppConv.Units {
SetInvalidUnitObject(Units.Invalid); SetInvalidUnitObject(Units.Invalid);
SI.ExtededProperties bitConversionProperties = new SI.ExtededProperties{ var bitConversionProperties = new SI.ExtededProperties {
FactorPredicate = factor => factor > 0 && factor%3 == 0, FactorPredicate = factor => factor > 0 && factor % 3 == 0,
FromFunctionGenerator = exponent => () => (decimal)Math.Pow(1024, -(int)(exponent/3)), FromFunctionGenerator = exponent => () => (decimal) Math.Pow(1024, -(int) (exponent / 3)),
ToFunctionGenerator = exponent => () => (decimal)Math.Pow(1024, (int)(exponent/3)) ToFunctionGenerator = exponent => () => (decimal) Math.Pow(1024, (int) (exponent / 3))
}; };
SI.AddSupportCustom(typeof(Units), Units.Byte, new []{ "B" }, new []{ "byte", "bytes" }, ConvertFrom, ConvertTo, Names, bitConversionProperties); SI.AddSupportCustom(typeof(Units), Units.Byte, new [] { "B" }, new [] { "byte", "bytes" }, ConvertFrom, ConvertTo, Names, bitConversionProperties);
SI.AddSupportCustom(typeof(Units), Units.Bit, new []{ "b" }, new []{ "bit", "bits" }, ConvertFrom, ConvertTo, Names, bitConversionProperties); SI.AddSupportCustom(typeof(Units), Units.Bit, new [] { "b" }, new [] { "bit", "bits" }, ConvertFrom, ConvertTo, Names, bitConversionProperties);
} }
} }
} }

View File

@ -3,13 +3,21 @@ using System.Text.RegularExpressions;
using AppConv.General; using AppConv.General;
using Base.Utils; using Base.Utils;
namespace AppConv.Units{ namespace AppConv.Units {
internal class Temperature : DecimalUnitConverterBase<Temperature.Units>{ class Temperature : DecimalUnitConverterBase<Temperature.Units> {
internal enum Units{ internal enum Units {
Invalid = 0, Celsius, Kelvin, Fahrenheit, Rankine, Delisle, Newton, Reaumur, Romer Invalid = 0,
Celsius,
Kelvin,
Fahrenheit,
Rankine,
Delisle,
Newton,
Reaumur,
Romer
} }
private static readonly NameMap UnitNames = new NameMap(21){ private static readonly NameMap UnitNames = new NameMap(21) {
{ "C", Units.Celsius }, { "C", Units.Celsius },
{ "Celsius", Units.Celsius }, { "Celsius", Units.Celsius },
{ "K", Units.Kelvin }, { "K", Units.Kelvin },
@ -33,69 +41,49 @@ namespace AppConv.Units{
{ "Rømer", Units.Romer } { "Rømer", Units.Romer }
}; };
private static readonly DecimalFuncMap FromCelsius = new DecimalFuncMap(8){ private static readonly DecimalFuncMap FromCelsius = new DecimalFuncMap(8) {
{ Units.Celsius, val => val }, { Units.Celsius, val => val },
{ Units.Kelvin, val => val+273.15M }, { Units.Kelvin, val => val + 273.15M },
{ Units.Fahrenheit, val => val*1.8M+32M }, { Units.Fahrenheit, val => val * 1.8M + 32M },
{ Units.Rankine, val => (val+273.15M)*1.8M }, { Units.Rankine, val => (val + 273.15M) * 1.8M },
{ Units.Delisle, val => (100M-val)*1.5M }, { Units.Delisle, val => (100M - val) * 1.5M },
{ Units.Newton, val => val*0.33M }, { Units.Newton, val => val * 0.33M },
{ Units.Reaumur, val => val*0.8M }, { Units.Reaumur, val => val * 0.8M },
{ Units.Romer, val => val*0.525M+7.5M } { Units.Romer, val => val * 0.525M + 7.5M }
}; };
private static readonly DecimalFuncMap ToCelsius = new DecimalFuncMap(8){ private static readonly DecimalFuncMap ToCelsius = new DecimalFuncMap(8) {
{ Units.Celsius, val => val }, { Units.Celsius, val => val },
{ Units.Kelvin, val => val-273.15M }, { Units.Kelvin, val => val - 273.15M },
{ Units.Fahrenheit, val => (val-32M)*5M/9M }, { Units.Fahrenheit, val => (val - 32M) * 5M / 9M },
{ Units.Rankine, val => (val-491.67M)*5M/9M }, { Units.Rankine, val => (val - 491.67M) * 5M / 9M },
{ Units.Delisle, val => 100M-val*2M/3M }, { Units.Delisle, val => 100M - val * 2M / 3M },
{ Units.Newton, val => val*100M/33M }, { Units.Newton, val => val * 100M / 33M },
{ Units.Reaumur, val => val*1.25M }, { Units.Reaumur, val => val * 1.25M },
{ Units.Romer, val => (val-7.5M)*40M/21M } { Units.Romer, val => (val - 7.5M) * 40M / 21M }
}; };
private static readonly Regex RegexCleanup = new Regex("deg(?:rees?)?|°", RegexUtils.Text); private static readonly Regex RegexCleanup = new Regex("deg(?:rees?)?|°", RegexUtils.Text);
protected override NameMap Names{ protected override NameMap Names => UnitNames;
get{
return UnitNames;
}
}
protected override DecimalFuncMap ConvertFrom{ protected override DecimalFuncMap ConvertFrom => FromCelsius;
get{
return FromCelsius;
}
}
protected override DecimalFuncMap ConvertTo{ protected override DecimalFuncMap ConvertTo => ToCelsius;
get{
return ToCelsius;
}
}
protected override int Precision{ protected override int Precision => 2;
get{
return 2;
}
}
protected override NumberStyles NumberStyle{ protected override NumberStyles NumberStyle => NumberStyles.Float;
get{
return NumberStyles.Float;
}
}
protected override string ProcessSrc(string src){ protected override string ProcessSrc(string src) {
return RegexCleanup.Replace(src, ""); return RegexCleanup.Replace(src, "");
} }
protected override string ProcessDst(string dst){ protected override string ProcessDst(string dst) {
return RegexCleanup.Replace(dst, ""); return RegexCleanup.Replace(dst, "");
} }
protected override bool IsValueInvalid(Units value){ protected override bool IsValueInvalid(Units value) {
return value == Units.Invalid; return value == Units.Invalid;
} }
} }

View File

@ -1,13 +1,19 @@
using AppConv.General; using AppConv.General;
using AppConv.Utils; using AppConv.Utils;
namespace AppConv.Units{ namespace AppConv.Units {
internal class Volume : DecimalUnitConverterSimple<Volume.Units>{ class Volume : DecimalUnitConverterSimple<Volume.Units> {
internal enum Units{ internal enum Units {
Invalid = 0, Liter, CubicMM, CubicCM, CubicDM, CubicM, CubicKM Invalid = 0,
Liter,
CubicMM,
CubicCM,
CubicDM,
CubicM,
CubicKM
} }
public Volume(){ public Volume() {
AddUnit(Units.Liter, "l", "liter", "liters", "litre", "litres"); AddUnit(Units.Liter, "l", "liter", "liters", "litre", "litres");
AddUnit(Units.CubicMM, "mm3", "cubic mm", "cubic millimeter", "cubic millimeters", "cubic millimetre", "cubic millimetres"); AddUnit(Units.CubicMM, "mm3", "cubic mm", "cubic millimeter", "cubic millimeters", "cubic millimetre", "cubic millimetres");
AddUnit(Units.CubicCM, "cm3", "cubic cm", "cubic centimeter", "cubic centimeters", "cubic centimetre", "cubic centimetres"); AddUnit(Units.CubicCM, "cm3", "cubic cm", "cubic centimeter", "cubic centimeters", "cubic centimetre", "cubic centimetres");
@ -22,7 +28,7 @@ namespace AppConv.Units{
SetInvalidUnitObject(Units.Invalid); SetInvalidUnitObject(Units.Invalid);
SI.AddSupport(typeof(Units), Units.Liter, new []{ "l" }, new []{ "liter", "litre", "liters", "litres" }, ConvertFrom, ConvertTo, Names); SI.AddSupport(typeof(Units), Units.Liter, new [] { "l" }, new [] { "liter", "litre", "liters", "litres" }, ConvertFrom, ConvertTo, Names);
} }
} }
} }

View File

@ -2,12 +2,16 @@
using AppConv.Utils; using AppConv.Utils;
namespace AppConv.Units { namespace AppConv.Units {
internal class Weight : DecimalUnitConverterSimple<Weight.Units>{ class Weight : DecimalUnitConverterSimple<Weight.Units> {
internal enum Units{ internal enum Units {
Invalid = 0, Gram, Pound, Ounce, Stone Invalid = 0,
Gram,
Pound,
Ounce,
Stone
} }
public Weight(){ public Weight() {
AddUnit(Units.Gram, "g", "gram", "grams"); AddUnit(Units.Gram, "g", "gram", "grams");
AddUnit(Units.Pound, "lb", "lbs", "pound", "pounds"); AddUnit(Units.Pound, "lb", "lbs", "pound", "pounds");
AddUnit(Units.Ounce, "oz", "ounce", "ounces"); AddUnit(Units.Ounce, "oz", "ounce", "ounces");
@ -19,7 +23,7 @@ namespace AppConv.Units {
SetInvalidUnitObject(Units.Invalid); SetInvalidUnitObject(Units.Invalid);
SI.AddSupport(typeof(Units), Units.Gram, new []{ "g" }, new []{ "gram", "grams" }, ConvertFrom, ConvertTo, Names); SI.AddSupport(typeof(Units), Units.Gram, new [] { "g" }, new [] { "gram", "grams" }, ConvertFrom, ConvertTo, Names);
} }
} }
} }

View File

@ -3,75 +3,75 @@ using System.Globalization;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
namespace AppConv.Utils{ namespace AppConv.Utils {
internal static class RadixConversion{ static class RadixConversion {
private const string Characters = "0123456789ABCDEF"; private const string Characters = "0123456789ABCDEF";
public static bool IsBaseValid(int checkedBase){ public static bool IsBaseValid(int checkedBase) {
return checkedBase >= 1 && checkedBase <= 16; return checkedBase >= 1 && checkedBase <= 16;
} }
public static bool IsNumberValid(string contents, int checkedBase){ public static bool IsNumberValid(string contents, int checkedBase) {
if (checkedBase == 1){ if (checkedBase == 1) {
return contents.All(chr => chr == '1'); return contents.All(chr => chr == '1');
} }
if (IsBaseValid(checkedBase)){ if (IsBaseValid(checkedBase)) {
return contents.Select(chr => Characters.IndexOf(char.ToUpper(chr))).All(index => index != -1 && index < checkedBase); return contents.Select(chr => Characters.IndexOf(char.ToUpper(chr))).All(index => index != -1 && index < checkedBase);
} }
return false; return false;
} }
public static string Do(string contents, int fromBase, int toBase){ // TODO biginteger public static string Do(string contents, int fromBase, int toBase) { // TODO biginteger
if (fromBase == 1){ if (fromBase == 1) {
contents = contents.Length.ToString(CultureInfo.InvariantCulture); contents = contents.Length.ToString(CultureInfo.InvariantCulture);
fromBase = 10; fromBase = 10;
} }
long wip; long wip;
if (fromBase == 10){ if (fromBase == 10) {
wip = long.Parse(contents, NumberStyles.None, CultureInfo.InvariantCulture); wip = long.Parse(contents, NumberStyles.None, CultureInfo.InvariantCulture);
} }
else{ else {
wip = 0; wip = 0;
for(int chr = 0; chr < contents.Length; chr++){ for (int chr = 0; chr < contents.Length; chr++) {
int index = Characters.IndexOf(char.ToUpperInvariant(contents[chr])); int index = Characters.IndexOf(char.ToUpperInvariant(contents[chr]));
if (index > 0){ if (index > 0) {
wip += index*(long)Math.Pow(fromBase, contents.Length-chr-1); wip += index * (long) Math.Pow(fromBase, contents.Length - chr - 1);
if (wip < 0){ if (wip < 0) {
throw new OverflowException(); throw new OverflowException();
} }
} }
} }
} }
if (toBase == 1){ if (toBase == 1) {
if (wip <= int.MaxValue){ if (wip <= int.MaxValue) {
return new string('1', (int)wip); return new string('1', (int) wip);
} }
else{ else {
throw new OverflowException(); throw new OverflowException();
} }
} }
else if (wip < toBase){ else if (wip < toBase) {
return Characters[(int)wip].ToString(); return Characters[(int) wip].ToString();
} }
else{ else {
StringBuilder converted = new StringBuilder(); var converted = new StringBuilder();
while(wip >= toBase){ while (wip >= toBase) {
int index = (int)(wip%toBase); int index = (int) (wip % toBase);
converted.Insert(0, Characters[index]); converted.Insert(0, Characters[index]);
wip = wip/toBase; wip = wip / toBase;
} }
return converted.Insert(0, Characters[(int)wip]).ToString(); return converted.Insert(0, Characters[(int) wip]).ToString();
} }
} }
} }

View File

@ -2,9 +2,9 @@
using System.Collections.Generic; using System.Collections.Generic;
using AppConv.General; using AppConv.General;
namespace AppConv.Utils{ namespace AppConv.Utils {
internal static class SI{ static class SI {
private static readonly List<Tuple<string, string, int>> Factors = new List<Tuple<string, string, int>>{ private static readonly List<Tuple<string, string, int>> Factors = new List<Tuple<string, string, int>> {
new Tuple<string, string, int>("yotta", "Y", 24), new Tuple<string, string, int>("yotta", "Y", 24),
new Tuple<string, string, int>("zetta", "Z", 21), new Tuple<string, string, int>("zetta", "Z", 21),
new Tuple<string, string, int>("exa", "E", 18), new Tuple<string, string, int>("exa", "E", 18),
@ -27,60 +27,60 @@ namespace AppConv.Utils{
new Tuple<string, string, int>("yocto", "y", -24) new Tuple<string, string, int>("yocto", "y", -24)
}; };
public static void AddSupport<T>(Type enumType, T unitObject, string[] unitShortNames, string[] unitLongNames, DecimalUnitConverterBase<T>.DecimalFuncMap funcFrom, DecimalUnitConverterBase<T>.DecimalFuncMap funcTo, DecimalUnitConverterBase<T>.NameMap nameMap) where T : struct{ public static void AddSupport<T>(Type enumType, T unitObject, string[] unitShortNames, string[] unitLongNames, DecimalUnitConverterBase<T>.DecimalFuncMap funcFrom, DecimalUnitConverterBase<T>.DecimalFuncMap funcTo, DecimalUnitConverterBase<T>.NameMap nameMap) where T : struct {
int enumCounter = 1000+Factors.Count*(int)(object)unitObject; int enumCounter = 1000 + Factors.Count * (int) (object) unitObject;
Func<decimal, decimal> convertFrom = funcFrom[unitObject]; Func<decimal, decimal> convertFrom = funcFrom[unitObject];
Func<decimal, decimal> convertTo = funcTo[unitObject]; Func<decimal, decimal> convertTo = funcTo[unitObject];
foreach(Tuple<string, string, int> factor in Factors){ foreach (Tuple<string, string, int> factor in Factors) {
T enumObject = (T)(object)enumCounter++; T enumObject = (T) (object) enumCounter++;
int exponent = factor.Item3; int exponent = factor.Item3;
foreach(string unitShortName in unitShortNames){ foreach (string unitShortName in unitShortNames) {
nameMap.Add(factor.Item2+unitShortName, enumObject); nameMap.Add(factor.Item2 + unitShortName, enumObject);
} }
foreach(string unitLongName in unitLongNames){ foreach (string unitLongName in unitLongNames) {
nameMap.Add(factor.Item1+unitLongName, enumObject); nameMap.Add(factor.Item1 + unitLongName, enumObject);
} }
funcFrom.Add(enumObject, val => convertFrom(val)*(decimal)Math.Pow(10, -exponent)); funcFrom.Add(enumObject, val => convertFrom(val) * (decimal) Math.Pow(10, -exponent));
funcTo.Add(enumObject, val => convertTo(val)*(decimal)Math.Pow(10, exponent)); funcTo.Add(enumObject, val => convertTo(val) * (decimal) Math.Pow(10, exponent));
} }
} }
public static void AddSupportCustom<T>(Type enumType, T unitObject, string[] unitShortNames, string[] unitLongNames, DecimalUnitConverterBase<T>.DecimalFuncMap funcFrom, DecimalUnitConverterBase<T>.DecimalFuncMap funcTo, DecimalUnitConverterBase<T>.NameMap nameMap, ExtededProperties extendedProps) where T : struct{ public static void AddSupportCustom<T>(Type enumType, T unitObject, string[] unitShortNames, string[] unitLongNames, DecimalUnitConverterBase<T>.DecimalFuncMap funcFrom, DecimalUnitConverterBase<T>.DecimalFuncMap funcTo, DecimalUnitConverterBase<T>.NameMap nameMap, ExtededProperties extendedProps) where T : struct {
int enumCounter = 1000+Factors.Count*(int)(object)unitObject; int enumCounter = 1000 + Factors.Count * (int) (object) unitObject;
Func<decimal, decimal> convertFrom = funcFrom[unitObject]; Func<decimal, decimal> convertFrom = funcFrom[unitObject];
Func<decimal, decimal> convertTo = funcTo[unitObject]; Func<decimal, decimal> convertTo = funcTo[unitObject];
foreach(Tuple<string, string, int> factor in Factors){ foreach (Tuple<string, string, int> factor in Factors) {
if (extendedProps.FactorPredicate != null && !extendedProps.FactorPredicate(factor.Item3)){ if (extendedProps.FactorPredicate != null && !extendedProps.FactorPredicate(factor.Item3)) {
continue; continue;
} }
T enumObject = (T)(object)enumCounter++; T enumObject = (T) (object) enumCounter++;
int exponent = factor.Item3; int exponent = factor.Item3;
foreach(string unitShortName in unitShortNames){ foreach (string unitShortName in unitShortNames) {
nameMap.Add(factor.Item2+unitShortName, enumObject); nameMap.Add(factor.Item2 + unitShortName, enumObject);
} }
foreach(string unitLongName in unitLongNames){ foreach (string unitLongName in unitLongNames) {
nameMap.Add(factor.Item1+unitLongName, enumObject); nameMap.Add(factor.Item1 + unitLongName, enumObject);
} }
Func<decimal> genFrom = extendedProps.FromFunctionGenerator(exponent); Func<decimal> genFrom = extendedProps.FromFunctionGenerator(exponent);
Func<decimal> genTo = extendedProps.ToFunctionGenerator(exponent); Func<decimal> genTo = extendedProps.ToFunctionGenerator(exponent);
funcFrom.Add(enumObject, val => convertFrom(val)*genFrom()); funcFrom.Add(enumObject, val => convertFrom(val) * genFrom());
funcTo.Add(enumObject, val => convertTo(val)*genTo()); funcTo.Add(enumObject, val => convertTo(val) * genTo());
} }
} }
internal class ExtededProperties{ internal class ExtededProperties {
public Predicate<int> FactorPredicate { get; set; } public Predicate<int> FactorPredicate { get; set; }
public Func<int, Func<decimal>> FromFunctionGenerator { get; set; } public Func<int, Func<decimal>> FromFunctionGenerator { get; set; }
public Func<int, Func<decimal>> ToFunctionGenerator { get; set; } public Func<int, Func<decimal>> ToFunctionGenerator { get; set; }

View File

@ -1,24 +1,24 @@
using System.Collections.Generic; using System.Collections.Generic;
using Base; using Base;
namespace AppMeme{ namespace AppMeme {
public sealed class App : IApp{ public sealed class App : IApp {
private static readonly Dictionary<string, string> Map = new Dictionary<string, string>{ private static readonly Dictionary<string, string> Map = new Dictionary<string, string> {
{ "shrug", @"¯\_(ツ)_/¯" }, { "shrug", @"¯\_(ツ)_/¯" },
{ "lenny", @"( ͡° ͜ʖ ͡°)" }, { "lenny", @"( ͡° ͜ʖ ͡°)" },
{ "flip", @"(╯°□°)╯︵ ┻━┻" }, { "flip", @"(╯°□°)╯︵ ┻━┻" },
{ "tableflip", @"(╯°□°)╯︵ ┻━┻" } { "tableflip", @"(╯°□°)╯︵ ┻━┻" }
}; };
public string[] RecognizedNames => new string[]{ public string[] RecognizedNames => new string[] {
"meme" "meme"
}; };
public MatchConfidence GetConfidence(Command cmd){ public MatchConfidence GetConfidence(Command cmd) {
return Map.ContainsKey(cmd.Text) ? MatchConfidence.Full : MatchConfidence.None; return Map.ContainsKey(cmd.Text) ? MatchConfidence.Full : MatchConfidence.None;
} }
public string ProcessCommand(Command cmd){ public string ProcessCommand(Command cmd) {
return Map[cmd.Text]; return Map[cmd.Text];
} }
} }

View File

@ -2,24 +2,24 @@
using AppSys.Handlers; using AppSys.Handlers;
using Base; using Base;
namespace AppSys{ namespace AppSys {
public sealed class App : IApp{ public sealed class App : IApp {
private static readonly IHandler[] Handlers = { private static readonly IHandler[] Handlers = {
new HandlerProcesses(), new HandlerProcesses(),
new HandlerApps() new HandlerApps()
}; };
public string[] RecognizedNames => new string[]{ public string[] RecognizedNames => new string[] {
"sys", "sys",
"os", "os",
"win" "win"
}; };
public MatchConfidence GetConfidence(Command cmd){ public MatchConfidence GetConfidence(Command cmd) {
return Handlers.Any(handler => handler.Matches(cmd)) ? MatchConfidence.Full : MatchConfidence.None; return Handlers.Any(handler => handler.Matches(cmd)) ? MatchConfidence.Full : MatchConfidence.None;
} }
public string ProcessCommand(Command cmd){ public string ProcessCommand(Command cmd) {
return Handlers.First(handler => handler.Matches(cmd)).Handle(cmd); return Handlers.First(handler => handler.Matches(cmd)).Handle(cmd);
} }
} }

View File

@ -5,32 +5,34 @@ using System.IO;
using Base; using Base;
namespace AppSys.Handlers { namespace AppSys.Handlers {
internal class HandlerApps : IHandler{ class HandlerApps : IHandler {
private static readonly string PathSystem = Environment.GetFolderPath(Environment.SpecialFolder.System); private static readonly string PathSystem = Environment.GetFolderPath(Environment.SpecialFolder.System);
private static readonly Dictionary<string, ProcessStartInfo> Mappings = new Dictionary<string, ProcessStartInfo>{ private static readonly Dictionary<string, ProcessStartInfo> Mappings = new Dictionary<string, ProcessStartInfo> {
{ "audio", new ProcessStartInfo{ {
"audio", new ProcessStartInfo {
FileName = Path.Combine(PathSystem, "control.exe"), FileName = Path.Combine(PathSystem, "control.exe"),
Arguments = "mmsys.cpl" Arguments = "mmsys.cpl"
} }, }
}, {
{ "programs", new ProcessStartInfo{ "programs", new ProcessStartInfo {
FileName = Path.Combine(PathSystem, "control.exe"), FileName = Path.Combine(PathSystem, "control.exe"),
Arguments = "appwiz.cpl" Arguments = "appwiz.cpl"
} }, }
}, {
{ "system", new ProcessStartInfo{ "system", new ProcessStartInfo {
FileName = Path.Combine(PathSystem, "control.exe"), FileName = Path.Combine(PathSystem, "control.exe"),
Arguments = "sysdm.cpl" Arguments = "sysdm.cpl"
} }, }
}, {
{ "environment", new ProcessStartInfo{ "environment", new ProcessStartInfo {
FileName = Path.Combine(PathSystem, "rundll32.exe"), FileName = Path.Combine(PathSystem, "rundll32.exe"),
Arguments = "sysdm.cpl,EditEnvironmentVariables" Arguments = "sysdm.cpl,EditEnvironmentVariables"
} } }
}
}; };
private static readonly Dictionary<string, string> Substitutions = new Dictionary<string, string>{ private static readonly Dictionary<string, string> Substitutions = new Dictionary<string, string> {
{ "sounds", "audio" }, { "sounds", "audio" },
{ "apps", "programs" }, { "apps", "programs" },
{ "appwiz", "programs" }, { "appwiz", "programs" },
@ -40,18 +42,19 @@ namespace AppSys.Handlers {
{ "variables", "environment" } { "variables", "environment" }
}; };
public bool Matches(Command cmd){ public bool Matches(Command cmd) {
return Mappings.ContainsKey(cmd.Text) || Substitutions.ContainsKey(cmd.Text); return Mappings.ContainsKey(cmd.Text) || Substitutions.ContainsKey(cmd.Text);
} }
public string Handle(Command cmd){ public string Handle(Command cmd) {
string key; string key;
if (!Substitutions.TryGetValue(cmd.Text, out key)){ if (!Substitutions.TryGetValue(cmd.Text, out key)) {
key = cmd.Text; key = cmd.Text;
} }
using(Process.Start(Mappings[key])){} using (Process.Start(Mappings[key])) {}
return null; return null;
} }
} }

View File

@ -3,43 +3,43 @@ using System.Diagnostics;
using System.Text; using System.Text;
using Base; using Base;
namespace AppSys.Handlers{ namespace AppSys.Handlers {
internal class HandlerProcesses : IHandler{ class HandlerProcesses : IHandler {
public bool Matches(Command cmd){ public bool Matches(Command cmd) {
return cmd.Text.StartsWith("kill ", StringComparison.InvariantCultureIgnoreCase); return cmd.Text.StartsWith("kill ", StringComparison.InvariantCultureIgnoreCase);
} }
public string Handle(Command cmd){ public string Handle(Command cmd) {
string[] processNames = cmd.Text.Substring("kill ".Length).Split(',', ';'); string[] processNames = cmd.Text.Substring("kill ".Length).Split(',', ';');
int succeeded = 0, failed = 0; int succeeded = 0, failed = 0;
foreach(string processName in processNames){ foreach (string processName in processNames) {
try{ try {
Process[] processes = Process.GetProcessesByName(processName.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase) ? processName.Substring(0, processName.Length-4) : processName); Process[] processes = Process.GetProcessesByName(processName.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase) ? processName.Substring(0, processName.Length - 4) : processName);
foreach(Process process in processes){ foreach (Process process in processes) {
try{ try {
process.Kill(); process.Kill();
++succeeded; ++succeeded;
}catch{ } catch {
++failed; ++failed;
} }
process.Close(); process.Close();
} }
}catch{ } catch {
++failed; ++failed;
} }
} }
if (succeeded == 0 && failed == 0 && (cmd.Text.Equals("kill me", StringComparison.InvariantCultureIgnoreCase) || cmd.Text.StartsWith("kill me ", StringComparison.InvariantCultureIgnoreCase) || cmd.Text.StartsWith("kill me,", StringComparison.InvariantCultureIgnoreCase))){ if (succeeded == 0 && failed == 0 && (cmd.Text.Equals("kill me", StringComparison.InvariantCultureIgnoreCase) || cmd.Text.StartsWith("kill me ", StringComparison.InvariantCultureIgnoreCase) || cmd.Text.StartsWith("kill me,", StringComparison.InvariantCultureIgnoreCase))) {
return "No."; return "No.";
} }
StringBuilder build = new StringBuilder(); var build = new StringBuilder();
build.Append("Killed ").Append(succeeded).Append(" process").Append(succeeded == 1 ? "" : "es"); build.Append("Killed ").Append(succeeded).Append(" process").Append(succeeded == 1 ? "" : "es");
if (failed > 0){ if (failed > 0) {
build.Append(", failed ").Append(failed); build.Append(", failed ").Append(failed);
} }

View File

@ -1,7 +1,7 @@
using Base; using Base;
namespace AppSys{ namespace AppSys {
internal interface IHandler{ interface IHandler {
bool Matches(Command cmd); bool Matches(Command cmd);
string Handle(Command cmd); string Handle(Command cmd);
} }

View File

@ -2,24 +2,24 @@
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using Base.Utils; using Base.Utils;
namespace Base{ namespace Base {
public sealed class Command{ public sealed class Command {
private static readonly Regex RegexBalancedBrackets = new Regex(RegexUtils.Balance(@"\[", @"\]"), RegexOptions.Compiled); private static readonly Regex RegexBalancedBrackets = new Regex(RegexUtils.Balance(@"\[", @"\]"), RegexOptions.Compiled);
private static readonly Regex RegexBalancedParentheses = new Regex(RegexUtils.Balance(@"\(", @"\)"), RegexOptions.Compiled); private static readonly Regex RegexBalancedParentheses = new Regex(RegexUtils.Balance(@"\(", @"\)"), RegexOptions.Compiled);
public string Text { get; private set; } public string Text { get; private set; }
public string PotentialAppName{ public string PotentialAppName {
get{ get {
int firstSpace = Text.IndexOf(' '); int firstSpace = Text.IndexOf(' ');
if (firstSpace == -1){ if (firstSpace == -1) {
return null; return null;
} }
string firstToken = Text.Substring(0, firstSpace); string firstToken = Text.Substring(0, firstSpace);
if (!firstToken.All(char.IsLetter)){ if (!firstToken.All(char.IsLetter)) {
return null; return null;
} }
@ -27,17 +27,13 @@ namespace Base{
} }
} }
public bool IsSingleToken{ public bool IsSingleToken => Text.IndexOf(' ') == -1;
get{
return Text.IndexOf(' ') == -1; public Command(string text) {
} Text = text;
} }
public Command(string text){ public Command ReplaceBrackets(MatchEvaluator evaluator) {
this.Text = text;
}
public Command ReplaceBrackets(MatchEvaluator evaluator){
return new Command(RegexBalancedParentheses.Replace(RegexBalancedBrackets.Replace(Text, evaluator), evaluator)); return new Command(RegexBalancedParentheses.Replace(RegexBalancedBrackets.Replace(Text, evaluator), evaluator));
} }
} }

View File

@ -1,11 +1,11 @@
using System; using System;
namespace Base{ namespace Base {
public class CommandEventArgs : EventArgs{ public class CommandEventArgs : EventArgs {
public Command Command { get; private set; } public Command Command { get; private set; }
public CommandEventArgs(string text){ public CommandEventArgs(string text) {
this.Command = new Command(text); Command = new Command(text);
} }
} }
} }

View File

@ -1,8 +1,8 @@
using System; using System;
namespace Base{ namespace Base {
public class CommandException : Exception{ public class CommandException : Exception {
public CommandException(string message) : base(message){} public CommandException(string message) : base(message) {}
public CommandException(string message, Exception innerException) : base(message,innerException){} public CommandException(string message, Exception innerException) : base(message, innerException) {}
} }
} }

View File

@ -1,5 +1,5 @@
namespace Base{ namespace Base {
public interface IApp{ public interface IApp {
string[] RecognizedNames { get; } string[] RecognizedNames { get; }
MatchConfidence GetConfidence(Command cmd); MatchConfidence GetConfidence(Command cmd);

View File

@ -1,5 +1,5 @@
namespace Base{ namespace Base {
public enum MatchConfidence{ public enum MatchConfidence {
None = 0, None = 0,
Low = 1, Low = 1,
Possible = 2, Possible = 2,

View File

@ -1,11 +1,11 @@
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace Base.Utils{ namespace Base.Utils {
public static class RegexUtils{ public static class RegexUtils {
public static readonly RegexOptions Text = RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled; public static readonly RegexOptions Text = RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture | RegexOptions.Compiled;
public static string Balance(string escapedStart, string escapedEnd){ // \(((?>[^()]+|\((?<n>)|\)(?<-n>))+(?(n)(?!)))\) public static string Balance(string escapedStart, string escapedEnd) { // \(((?>[^()]+|\((?<n>)|\)(?<-n>))+(?(n)(?!)))\)
return new StringBuilder() return new StringBuilder()
.Append(escapedStart) .Append(escapedStart)
.Append(@"((?>[^") .Append(@"((?>[^")

View File

@ -2,32 +2,35 @@
using System.Drawing; using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
namespace Query.Controls{ namespace Query.Controls {
sealed partial class QueryHistoryLog : UserControl{ sealed partial class QueryHistoryLog : UserControl {
public enum EntryType{ public enum EntryType {
UserInput, CommandResult, Information, Error UserInput,
CommandResult,
Information,
Error
} }
private static readonly Dictionary<EntryType, Color> EntryColorMap = new Dictionary<EntryType, Color>{ private static readonly Dictionary<EntryType, Color> EntryColorMap = new Dictionary<EntryType, Color> {
{ EntryType.UserInput, Color.FromArgb(160, 160, 160) }, { EntryType.UserInput, Color.FromArgb(160, 160, 160) },
{ EntryType.CommandResult, Color.FromArgb(240, 240, 240) }, { EntryType.CommandResult, Color.FromArgb(240, 240, 240) },
{ EntryType.Information, Color.FromArgb(160, 255, 140) }, { EntryType.Information, Color.FromArgb(160, 255, 140) },
{ EntryType.Error, Color.FromArgb(255, 40, 40) } { EntryType.Error, Color.FromArgb(255, 40, 40) }
}; };
public QueryHistoryLog(){ public QueryHistoryLog() {
InitializeComponent(); InitializeComponent();
} }
public void AddEntry(string text, EntryType type){ public void AddEntry(string text, EntryType type) {
int width = container.Width-SystemInformation.VerticalScrollBarWidth; int width = container.Width - SystemInformation.VerticalScrollBarWidth;
Label label = new Label{ Label label = new Label {
AutoSize = true, AutoSize = true,
Font = container.Font, Font = container.Font,
ForeColor = EntryColorMap[type], ForeColor = EntryColorMap[type],
Text = text, Text = text,
Margin = new Padding(0,1,0,1), Margin = new Padding(0, 1, 0, 1),
MaximumSize = new Size(width, 0), MaximumSize = new Size(width, 0),
Width = width Width = width
}; };
@ -36,7 +39,7 @@ namespace Query.Controls{
container.AutoScrollPosition = new Point(0, container.VerticalScroll.Maximum); container.AutoScrollPosition = new Point(0, container.VerticalScroll.Maximum);
} }
public void ClearEntries(){ public void ClearEntries() {
container.Controls.Clear(); container.Controls.Clear();
} }
} }

View File

@ -5,27 +5,27 @@ using System.Windows.Forms;
using Base; using Base;
using Query.Core; using Query.Core;
namespace Query.Controls{ namespace Query.Controls {
sealed partial class QueryTextBox : UserControl{ sealed partial class QueryTextBox : UserControl {
public event EventHandler<CommandEventArgs> CommandRan; public event EventHandler<CommandEventArgs> CommandRan;
private CommandHistory history; private CommandHistory history;
private Action<string> log; private Action<string> log;
public QueryTextBox(){ public QueryTextBox() {
InitializeComponent(); InitializeComponent();
} }
public void Setup(CommandHistory historyObj, Action<string> logFunc){ public void Setup(CommandHistory historyObj, Action<string> logFunc) {
this.history = historyObj; history = historyObj;
this.log = logFunc; log = logFunc;
} }
private void OnCommandRan(){ private void OnCommandRan() {
CommandRan?.Invoke(this, new CommandEventArgs(tb.Text)); CommandRan?.Invoke(this, new CommandEventArgs(tb.Text));
} }
private sealed class CustomTextBox : TextBox{ private sealed class CustomTextBox : TextBox {
private string lastInputStr = string.Empty; private string lastInputStr = string.Empty;
private int lastInputPos = 0; private int lastInputPos = 0;
@ -33,20 +33,20 @@ namespace Query.Controls{
private bool lastArrowShift; private bool lastArrowShift;
private int historyOffset; private int historyOffset;
public CustomTextBox(){ public CustomTextBox() {
TextChanged += CustomTextBox_TextChanged; TextChanged += CustomTextBox_TextChanged;
} }
protected override void OnKeyDown(KeyEventArgs e){ protected override void OnKeyDown(KeyEventArgs e) {
QueryTextBox input = (QueryTextBox)Parent; QueryTextBox input = (QueryTextBox) Parent;
CommandHistory history = input.history; CommandHistory history = input.history;
Keys key = e.KeyCode; Keys key = e.KeyCode;
bool handled = false; bool handled = false;
switch(key){ switch (key) {
case Keys.Enter: case Keys.Enter:
if (Text != string.Empty){ if (Text != string.Empty) {
input.OnCommandRan(); input.OnCommandRan();
Text = string.Empty; Text = string.Empty;
@ -57,14 +57,14 @@ namespace Query.Controls{
break; break;
case Keys.Up: case Keys.Up:
if (lastArrowShift != e.Shift){ if (lastArrowShift != e.Shift) {
lastArrowShift = e.Shift; lastArrowShift = e.Shift;
historyOffset = 0; historyOffset = 0;
} }
--historyOffset; --historyOffset;
if (InsertFromHistory(e.Shift ? history.Results : history.Queries)){ if (InsertFromHistory(e.Shift ? history.Results : history.Queries)) {
++historyOffset; ++historyOffset;
} }
@ -72,14 +72,14 @@ namespace Query.Controls{
break; break;
case Keys.Down: case Keys.Down:
if (lastArrowShift != e.Shift){ if (lastArrowShift != e.Shift) {
lastArrowShift = e.Shift; lastArrowShift = e.Shift;
historyOffset = 0; historyOffset = 0;
} }
++historyOffset; ++historyOffset;
if (InsertFromHistory(e.Shift ? history.Results : history.Queries)){ if (InsertFromHistory(e.Shift ? history.Results : history.Queries)) {
--historyOffset; --historyOffset;
} }
@ -87,8 +87,8 @@ namespace Query.Controls{
break; break;
case Keys.C: case Keys.C:
if (e.Modifiers == Keys.Control){ if (e.Modifiers == Keys.Control) {
if (SelectionLength == 0 && history.Results.Count > 0){ if (SelectionLength == 0 && history.Results.Count > 0) {
Clipboard.SetText(history.Results.Last(), TextDataFormat.UnicodeText); Clipboard.SetText(history.Results.Last(), TextDataFormat.UnicodeText);
input.log("Copied to clipboard."); input.log("Copied to clipboard.");
handled = true; handled = true;
@ -98,7 +98,7 @@ namespace Query.Controls{
break; break;
} }
if (!handled && key != Keys.ControlKey && key != Keys.ShiftKey && key != Keys.Menu){ if (!handled && key != Keys.ControlKey && key != Keys.ShiftKey && key != Keys.Menu) {
doResetHistoryMemory = true; doResetHistoryMemory = true;
} }
@ -106,40 +106,40 @@ namespace Query.Controls{
base.OnKeyDown(e); base.OnKeyDown(e);
} }
protected override void OnKeyUp(KeyEventArgs e){ protected override void OnKeyUp(KeyEventArgs e) {
base.OnKeyUp(e); base.OnKeyUp(e);
if (doResetHistoryMemory){ if (doResetHistoryMemory) {
doResetHistoryMemory = false; doResetHistoryMemory = false;
ResetHistoryMemory(); ResetHistoryMemory();
} }
} }
private void CustomTextBox_TextChanged(object sender, EventArgs e){ private void CustomTextBox_TextChanged(object sender, EventArgs e) {
ResetHistoryMemory(); ResetHistoryMemory();
} }
// Management // Management
private void ResetHistoryMemory(){ private void ResetHistoryMemory() {
lastInputStr = Text; lastInputStr = Text;
lastInputPos = SelectionStart; lastInputPos = SelectionStart;
historyOffset = 0; historyOffset = 0;
} }
private bool InsertFromHistory(IList<string> collection){ private bool InsertFromHistory(IList<string> collection) {
if (collection.Count == 0){ if (collection.Count == 0) {
return true; return true;
} }
int index = collection.Count + historyOffset; int index = collection.Count + historyOffset;
bool wasClamped = false; bool wasClamped = false;
if (index < 0){ if (index < 0) {
index = 0; index = 0;
wasClamped = true; wasClamped = true;
} }
else if (index >= collection.Count){ else if (index >= collection.Count) {
index = collection.Count - 1; index = collection.Count - 1;
wasClamped = true; wasClamped = true;
} }

View File

@ -1,31 +1,23 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Query.Core{ namespace Query.Core {
sealed class CommandHistory{ sealed class CommandHistory {
private readonly List<string> queries = new List<string>(); private readonly List<string> queries = new List<string>();
private readonly List<string> results = new List<string>(); private readonly List<string> results = new List<string>();
public IList<string> Queries{ public IList<string> Queries => queries;
get{
return queries;
}
}
public IList<string> Results{ public IList<string> Results => results;
get{
return results;
}
}
public void AddQuery(string text){ public void AddQuery(string text) {
queries.Add(text); queries.Add(text);
} }
public void AddResult(string text){ public void AddResult(string text) {
results.Add(text); results.Add(text);
} }
public void Clear(){ public void Clear() {
queries.Clear(); queries.Clear();
results.Clear(); results.Clear();
} }

View File

@ -3,59 +3,59 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Base; using Base;
namespace Query.Core{ namespace Query.Core {
sealed class CommandProcessor{ sealed class CommandProcessor {
private readonly Dictionary<string, IApp> appNames = new Dictionary<string, IApp>(8); private readonly Dictionary<string, IApp> appNames = new Dictionary<string, IApp>(8);
private readonly HashSet<IApp> appSet = new HashSet<IApp>(); private readonly HashSet<IApp> appSet = new HashSet<IApp>();
public Func<string, bool> SingleTokenProcessor { get; set; } public Func<string, bool> SingleTokenProcessor { get; set; }
public void AddApp<T>() where T : IApp, new(){ public void AddApp<T>() where T : IApp, new() {
IApp app = new T(); IApp app = new T();
foreach(string name in app.RecognizedNames){ foreach (string name in app.RecognizedNames) {
appNames.Add(name, app); appNames.Add(name, app);
appSet.Add(app); appSet.Add(app);
} }
} }
public string Run(Command cmd){ public string Run(Command cmd) {
cmd = cmd.ReplaceBrackets(match => Run(new Command(match.Groups[1].Value))); cmd = cmd.ReplaceBrackets(match => Run(new Command(match.Groups[1].Value)));
string appName = cmd.PotentialAppName; string appName = cmd.PotentialAppName;
IApp app; IApp app;
if (appName != null && appNames.TryGetValue(appName.ToLowerInvariant(), out app)){ if (appName != null && appNames.TryGetValue(appName.ToLowerInvariant(), out app)) {
return app.ProcessCommand(new Command(cmd.Text.Substring(appName.Length+1))); return app.ProcessCommand(new Command(cmd.Text.Substring(appName.Length + 1)));
} }
if (cmd.IsSingleToken && SingleTokenProcessor != null && SingleTokenProcessor(cmd.Text)){ if (cmd.IsSingleToken && SingleTokenProcessor != null && SingleTokenProcessor(cmd.Text)) {
return null; return null;
} }
var list = appSet.Select(iapp => new { App = iapp, Confidence = iapp.GetConfidence(cmd) }).OrderByDescending(obj => obj.Confidence).Where(obj => obj.Confidence != MatchConfidence.None).ToList(); var list = appSet.Select(iapp => new { App = iapp, Confidence = iapp.GetConfidence(cmd) }).OrderByDescending(obj => obj.Confidence).Where(obj => obj.Confidence != MatchConfidence.None).ToList();
if (list.Count == 0){ if (list.Count == 0) {
throw new CommandException("Could not find any suitable app, please write the app name and press Up Arrow."); throw new CommandException("Could not find any suitable app, please write the app name and press Up Arrow.");
} }
else if (list.Count == 1){ else if (list.Count == 1) {
app = list[0].App; app = list[0].App;
} }
else{ else {
List<IApp> plausible = new List<IApp>{ list[0].App }; List<IApp> plausible = new List<IApp> { list[0].App };
MatchConfidence topConfidence = list[0].Confidence; MatchConfidence topConfidence = list[0].Confidence;
for(int index = 1; index < list.Count; index++){ for (int index = 1; index < list.Count; index++) {
if (list[index].Confidence == topConfidence){ if (list[index].Confidence == topConfidence) {
plausible.Add(list[index].App); plausible.Add(list[index].App);
} }
} }
if (plausible.Count == 1){ if (plausible.Count == 1) {
app = plausible.First(); app = plausible.First();
} }
else{ else {
throw new CommandException("Command is ambiguous, please write the app name and press Up Arrow. Suggested apps: "+string.Join(", ",plausible.Select(iapp => iapp.RecognizedNames.First()))); throw new CommandException("Command is ambiguous, please write the app name and press Up Arrow. Suggested apps: " + string.Join(", ", plausible.Select(iapp => iapp.RecognizedNames.First())));
} }
} }

View File

@ -2,38 +2,38 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows.Forms; using System.Windows.Forms;
namespace Query.Core{ namespace Query.Core {
sealed class KeyboardHook{ sealed class KeyboardHook {
public event EventHandler Triggered; public event EventHandler Triggered;
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
private readonly NativeMethods.HookProc keyboardHookDelegate; private readonly NativeMethods.HookProc keyboardHookDelegate;
private IntPtr keyboardHook; private IntPtr keyboardHook;
public KeyboardHook(){ public KeyboardHook() {
keyboardHookDelegate = KeyboardHookProc; keyboardHookDelegate = KeyboardHookProc;
} }
public void StartHook(){ public void StartHook() {
if (keyboardHook != IntPtr.Zero){ if (keyboardHook != IntPtr.Zero) {
NativeMethods.UnhookWindowsHookEx(keyboardHook); NativeMethods.UnhookWindowsHookEx(keyboardHook);
} }
keyboardHook = NativeMethods.SetWindowsHookEx(NativeMethods.WH_KEYBOARD_LL, keyboardHookDelegate, IntPtr.Zero, 0); keyboardHook = NativeMethods.SetWindowsHookEx(NativeMethods.WH_KEYBOARD_LL, keyboardHookDelegate, IntPtr.Zero, 0);
} }
public void StopHook(){ public void StopHook() {
if (keyboardHook != IntPtr.Zero){ if (keyboardHook != IntPtr.Zero) {
NativeMethods.UnhookWindowsHookEx(keyboardHook); NativeMethods.UnhookWindowsHookEx(keyboardHook);
keyboardHook = IntPtr.Zero; keyboardHook = IntPtr.Zero;
} }
} }
private IntPtr KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam){ private IntPtr KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam) {
if (wParam == (IntPtr)NativeMethods.WM_KEYDOWN){ if (wParam == (IntPtr) NativeMethods.WM_KEYDOWN) {
Keys key = (Keys)Marshal.ReadInt32(lParam); Keys key = (Keys) Marshal.ReadInt32(lParam);
if ((key == Keys.LWin || key == Keys.RWin) && Control.ModifierKeys.HasFlag(Keys.Control)){ if ((key == Keys.LWin || key == Keys.RWin) && Control.ModifierKeys.HasFlag(Keys.Control)) {
Triggered?.Invoke(this, EventArgs.Empty); Triggered?.Invoke(this, EventArgs.Empty);
return NativeMethods.HookHandled; return NativeMethods.HookHandled;
} }
@ -42,7 +42,7 @@ namespace Query.Core{
return NativeMethods.CallNextHookEx(keyboardHook, nCode, wParam, lParam); return NativeMethods.CallNextHookEx(keyboardHook, nCode, wParam, lParam);
} }
private static class NativeMethods{ private static class NativeMethods {
public const int WH_KEYBOARD_LL = 13; public const int WH_KEYBOARD_LL = 13;
public const int WM_KEYDOWN = 0x0100; public const int WM_KEYDOWN = 0x0100;
public const int WM_KEYUP = 0x0101; public const int WM_KEYUP = 0x0101;

View File

@ -5,8 +5,8 @@ using Base;
using Query.Controls; using Query.Controls;
using Query.Core; using Query.Core;
namespace Query{ namespace Query {
partial class MainForm : Form{ partial class MainForm : Form {
private readonly CommandProcessor processor; private readonly CommandProcessor processor;
private readonly CommandHistory history; private readonly CommandHistory history;
@ -15,10 +15,10 @@ namespace Query{
private bool isLoaded; private bool isLoaded;
public MainForm(){ public MainForm() {
InitializeComponent(); InitializeComponent();
processor = new CommandProcessor{ processor = new CommandProcessor {
SingleTokenProcessor = ProcessSingleToken SingleTokenProcessor = ProcessSingleToken
}; };
@ -33,7 +33,7 @@ namespace Query{
keyboardHook = new KeyboardHook(); keyboardHook = new KeyboardHook();
keyboardHook.Triggered += keyboardHook_Triggered; keyboardHook.Triggered += keyboardHook_Triggered;
focusTimer = new Timer{ focusTimer = new Timer {
Interval = 1 Interval = 1
}; };
@ -43,57 +43,57 @@ namespace Query{
queryBox.CommandRan += queryBox_CommandRan; queryBox.CommandRan += queryBox_CommandRan;
} }
private void SetShown(bool show){ private void SetShown(bool show) {
if (show){ if (show) {
focusTimer.Start(); focusTimer.Start();
} }
else{ else {
Hide(); Hide();
} }
} }
private void MainForm_Shown(object sender, EventArgs e){ private void MainForm_Shown(object sender, EventArgs e) {
Rectangle screenRect = Screen.PrimaryScreen.WorkingArea; Rectangle screenRect = Screen.PrimaryScreen.WorkingArea;
Location = new Point(screenRect.X + screenRect.Width - Width, screenRect.Y + screenRect.Height - Height); Location = new Point(screenRect.X + screenRect.Width - Width, screenRect.Y + screenRect.Height - Height);
if (!isLoaded){ if (!isLoaded) {
isLoaded = true; isLoaded = true;
keyboardHook.StartHook(); keyboardHook.StartHook();
} }
} }
private void MainForm_Deactivate(object sender, EventArgs e){ private void MainForm_Deactivate(object sender, EventArgs e) {
SetShown(false); SetShown(false);
} }
private void MainForm_Disposed(object sender, EventArgs e){ private void MainForm_Disposed(object sender, EventArgs e) {
keyboardHook.StopHook(); keyboardHook.StopHook();
} }
private void trayIcon_Click(object sender, EventArgs e){ private void trayIcon_Click(object sender, EventArgs e) {
if (((MouseEventArgs)e).Button == MouseButtons.Left){ if (((MouseEventArgs) e).Button == MouseButtons.Left) {
SetShown(true); SetShown(true);
} }
} }
private void showToolStripMenuItem_Click(object sender, EventArgs e){ private void showToolStripMenuItem_Click(object sender, EventArgs e) {
SetShown(true); SetShown(true);
} }
private void hookToolStripMenuItem_Click(object sender, EventArgs e){ private void hookToolStripMenuItem_Click(object sender, EventArgs e) {
keyboardHook.StopHook(); keyboardHook.StopHook();
keyboardHook.StartHook(); keyboardHook.StartHook();
} }
private void exitToolStripMenuItem_Click(object sender, EventArgs e){ private void exitToolStripMenuItem_Click(object sender, EventArgs e) {
Application.Exit(); Application.Exit();
} }
private void keyboardHook_Triggered(object sender, EventArgs e){ private void keyboardHook_Triggered(object sender, EventArgs e) {
SetShown(!Visible); SetShown(!Visible);
} }
private void focusTimer_Tick(object sender, EventArgs e){ private void focusTimer_Tick(object sender, EventArgs e) {
WindowState = FormWindowState.Minimized; WindowState = FormWindowState.Minimized;
Show(); Show();
Activate(); Activate();
@ -103,27 +103,27 @@ namespace Query{
focusTimer.Stop(); focusTimer.Stop();
} }
private void queryBox_CommandRan(object sender, CommandEventArgs e){ private void queryBox_CommandRan(object sender, CommandEventArgs e) {
try{ try {
string result = processor.Run(e.Command); string result = processor.Run(e.Command);
if (result != null){ if (result != null) {
queryLog.AddEntry("> "+e.Command.Text, QueryHistoryLog.EntryType.UserInput); queryLog.AddEntry("> " + e.Command.Text, QueryHistoryLog.EntryType.UserInput);
history.AddQuery(e.Command.Text); history.AddQuery(e.Command.Text);
queryLog.AddEntry(result, QueryHistoryLog.EntryType.CommandResult); queryLog.AddEntry(result, QueryHistoryLog.EntryType.CommandResult);
history.AddResult(result); history.AddResult(result);
} }
}catch(CommandException ex){ } catch (CommandException ex) {
queryLog.AddEntry("> "+e.Command.Text, QueryHistoryLog.EntryType.UserInput); queryLog.AddEntry("> " + e.Command.Text, QueryHistoryLog.EntryType.UserInput);
history.AddQuery(e.Command.Text); history.AddQuery(e.Command.Text);
queryLog.AddEntry(ex.Message, QueryHistoryLog.EntryType.Error); queryLog.AddEntry(ex.Message, QueryHistoryLog.EntryType.Error);
} }
} }
private bool ProcessSingleToken(string token){ private bool ProcessSingleToken(string token) {
switch(token){ switch (token) {
case "exit": case "exit":
case "quit": case "quit":
Application.Exit(); Application.Exit();

View File

@ -168,7 +168,7 @@
JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8AAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8AAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA
AEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA AEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA
AEE= AEE=
</value> </value>
</data> </data>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value> <value>
@ -214,6 +214,6 @@
JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8AAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA JP8kJCT/JCQk/yQkJP8kJCT/JCQk/yQkJP8AAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA
AEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA AEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAAAEEAAABBAAAAQQAA
AEE= AEE=
</value> </value>
</data> </data>
</root> </root>

View File

@ -1,10 +1,10 @@
using System; using System;
using System.Windows.Forms; using System.Windows.Forms;
namespace Query{ namespace Query {
static class Program{ static class Program {
[STAThread] [STAThread]
private static void Main(){ private static void Main() {
Application.EnableVisualStyles(); Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false); Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm()); Application.Run(new MainForm());