using System; using System.Collections.Generic; using System.Linq; using AppConv.General; using AppConv.Utils; using Base; namespace AppConv.Units { 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; } } }