mirror of
https://github.com/chylex/Query.git
synced 2025-05-02 20:34:09 +02:00
125 lines
4.0 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|