1
0
mirror of https://github.com/chylex/Query.git synced 2025-05-02 20:34:09 +02:00
Query/AppConv/Units/Radix.cs

125 lines
4.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using AppConv.General;
using AppConv.Utils;
using Base;
namespace AppConv.Units{
internal class Radix : IUnitType{
private static readonly Dictionary<string, int> RadixDescriptions = new Dictionary<string, int>{
{ "UNARY", 1 },
{ "BINARY", 2 },
{ "BIN", 2 },
{ "TERNARY", 3 },
{ "QUATERNARY", 4 },
{ "QUINARY", 5 },
{ "SENARY", 6 },
{ "OCTAL", 8 },
{ "OCT", 8 },
{ "DECIMAL", 10 },
{ "DEC", 10 },
{ "UNDECIMAL", 11 },
{ "DUODECIMAL", 12 },
{ "DOZENAL", 12 },
{ "TRIDECIMAL", 13 },
{ "TETRADECIMAL", 14 },
{ "PENTADECIMAL", 15 },
{ "HEXADECIMAL", 16 },
{ "HEX", 16 }
};
static Radix(){
for(int baseNumber = 1; baseNumber <= 16; baseNumber++){
RadixDescriptions.Add("RADIX "+baseNumber, baseNumber);
RadixDescriptions.Add("BASE "+baseNumber, baseNumber);
}
}
public bool TryProcess(string src, string dst, out string result){
int targetBase;
if (!RadixDescriptions.TryGetValue(dst.ToUpperInvariant(), out targetBase)){
result = string.Empty;
return false;
}
string contents;
int sourceBase;
if (!ParseSrc(src, out contents, out sourceBase)){
result = string.Empty;
return false;
}
if (contents[0] == '-'){
throw new CommandException("Negative numbers are not supported.");
}
else if (!RadixConversion.IsBaseValid(sourceBase) || !RadixConversion.IsBaseValid(targetBase)){
throw new CommandException("Only bases between 1 and 16 allowed.");
}
else if (!RadixConversion.IsNumberValid(contents, sourceBase)){
throw new CommandException("The input is not a valid base "+sourceBase+" number: "+contents);
}
if (sourceBase == targetBase){
result = src;
return true;
}
try{
result = RadixConversion.Do(contents, sourceBase, targetBase);
}catch(OverflowException){
throw new CommandException("The number has overflown.");
}
return true;
}
private static bool ParseSrc(string src, out string sourceContent, out int sourceBase){
if (src.All(chr => chr >= '0' && chr <= '9')){
sourceContent = src;
sourceBase = 10;
return true;
}
string upper = src.ToUpperInvariant();
if (upper.StartsWith("0X")){
sourceContent = upper.Substring(2);
sourceBase = 16;
return true;
}
if (upper.StartsWith("0B")){
sourceContent = upper.Substring(2);
sourceBase = 2;
return true;
}
int fromIndex = src.IndexOf("FROM", StringComparison.InvariantCultureIgnoreCase);
if (fromIndex != -1){
src = src.Remove(fromIndex, 4);
}
foreach(KeyValuePair<string, int> kvp in RadixDescriptions){
if (src.StartsWith(kvp.Key, StringComparison.InvariantCultureIgnoreCase)){
sourceContent = src.Substring(kvp.Key.Length).Trim();
sourceBase = kvp.Value;
return true;
}
else if (src.EndsWith(kvp.Key, StringComparison.InvariantCultureIgnoreCase)){
sourceContent = src.Substring(0, src.Length-kvp.Key.Length).Trim();
sourceBase = kvp.Value;
return true;
}
}
sourceContent = string.Empty;
sourceBase = 0;
return false;
}
}
}