From 8047bf0f838661000c470c52f1945f502f5d77a6 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Sun, 16 Dec 2018 16:24:45 +1100 Subject: [PATCH] encode/number: add number decoding for base36 --- CMakeLists.txt | 2 ++ encode/number.hpp | 34 ++++++++++++++++++++++++++++++++++ test/encode/number.cpp | 28 ++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 encode/number.hpp create mode 100644 test/encode/number.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f6b07f4..fada4b77 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -247,6 +247,7 @@ list ( cpuid_x86.hpp debug.cpp debug.hpp + encode/number.hpp encode/base.cpp encode/base.hpp endian.cpp @@ -531,6 +532,7 @@ if (TESTS) colour comparator coord + encode/number encode/base endian exe diff --git a/encode/number.hpp b/encode/number.hpp new file mode 100644 index 00000000..e99d90d6 --- /dev/null +++ b/encode/number.hpp @@ -0,0 +1,34 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 2018 Danny Robson + */ + +#pragma once + +#include "../view.hpp" + +/////////////////////////////////////////////////////////////////////////////// +namespace cruft::encode { + template + ValueT + decode36 (cruft::view &src) + { + ValueT accum = 0; + for (auto const i: src) { + accum *= 36; + + switch (i) { + case '0'...'9': accum += i - '0'; continue; + case 'a'...'z': accum += i - 'a' + 10; continue; + case 'A'...'Z': accum += i - 'A' + 10; continue; + default: + throw std::invalid_argument ("invalid character"); + } + } + + return accum; + } +} diff --git a/test/encode/number.cpp b/test/encode/number.cpp new file mode 100644 index 00000000..56c49f2d --- /dev/null +++ b/test/encode/number.cpp @@ -0,0 +1,28 @@ +#include "encode/number.hpp" +#include "tap.hpp" + + +int main () +{ + static struct { + char const *str; + unsigned value; + } const TESTS[] = { + { "0", 0 }, + { "a", 10 }, + { "A", 10 }, + { "10", 36 }, + { "11", 37 }, + { "bfi0", 533304 }, + { "15bfi0", 69397560 }, + }; + + cruft::TAP::logger tap; + + for (auto const &t: TESTS) { + cruft::view src (t.str); + tap.expect_eq (cruft::encode::decode36 (src), t.value, "base36 decode '%!'", t.str); + } + + return tap.status (); +} \ No newline at end of file