diff --git a/src/common_code/common_code.cc b/src/common_code/common_code.cc index c3c9d81..6d4974e 100644 --- a/src/common_code/common_code.cc +++ b/src/common_code/common_code.cc @@ -8,41 +8,54 @@ inline uint8_t last_zero_num(uint32_t bin) { // get last zero number return __builtin_popcount(bin >> 1); } -//std::string CommonCode::to_string_(uint64_t common_code, bool shorten) { -// if (!CommonCode::check(common_code)) { -// throw std::invalid_argument("invalid common code"); -// } -// char result[10]; // max length 9-bits -// sprintf(result, "%09lX", common_code); -// if (shorten) { // remove `0` after common code -// if (common_code == 0x000000000) { -// return "0"; // special case -// } -// result[9 - last_zero_num(common_code) / 4] = '\0'; // truncate string -// } -// return result; -//} +uint64_t CommonCode::unwrap() const { + return code; // get raw uint64_t code +} + +CommonCode::CommonCode(uint64_t common_code) { + if (!CommonCode::check(common_code)) { // check input common code + throw std::invalid_argument("invalid common code"); + } + code = common_code; +} + +CommonCode::CommonCode(const std::string &common_code_str) { + if (common_code_str.length() > 9 || common_code_str.length() == 0) { // check string length + throw std::invalid_argument("common code format error"); + } -//uint64_t CommonCode::from_string_(const std::string &common_code) { -// if (common_code.length() > 9 || common_code.length() == 0) { -// throw std::invalid_argument("common code format error"); -// } -// uint64_t result = 0; -// for (auto const &bit : common_code) { -// result <<= 4; -// if (bit >= '0' && bit <= '9') { // 0 ~ 9 -// result |= (bit - 48); -// } else if (bit >= 'A' && bit <= 'Z') { // A ~ Z -// result |= (bit - 55); -// } else if (bit >= 'a' && bit <= 'z') { // a ~ z -// result |= (bit - 87); -// } else { -// throw std::invalid_argument("common code format error"); -// } -// } -// // TODO: should we ensure that common code is valid? -// return result << (9 - common_code.length()) * 4; // low-bits fill with zero -//} + uint64_t common_code = 0; + for (auto const &bit : common_code_str) { + common_code <<= 4; + if (bit >= '0' && bit <= '9') { // 0 ~ 9 + common_code |= (bit - 48); + } else if (bit >= 'A' && bit <= 'Z') { // A ~ Z + common_code |= (bit - 55); + } else if (bit >= 'a' && bit <= 'z') { // a ~ z + common_code |= (bit - 87); + } else { + throw std::invalid_argument("common code format error"); // unknown characters + } + } + common_code <<= (9 - common_code_str.length()) * 4; // low-bits fill with zero + + if (!CommonCode::check(common_code)) { // check converted common code + throw std::invalid_argument("invalid common code"); + } + code = common_code; +} + +std::string CommonCode::to_string(bool shorten) const { + char result[10]; // max length 9-bits + sprintf(result, "%09lX", code); + if (shorten) { // remove `0` after common code + if (code == 0x000000000) { + return "0"; // special case + } + result[9 - last_zero_num(code) / 4] = '\0'; // truncate string + } + return result; +} bool CommonCode::check(uint64_t common_code) { // check whether common code is valid uint32_t head = common_code >> 32; @@ -72,62 +85,3 @@ bool CommonCode::check(uint64_t common_code) { // check whether common code is v } return Common::check_case(head, range); // check by head and range } - -std::string CommonCode::to_string(bool shorten) const { - - char result[10]; // max length 9-bits - sprintf(result, "%09lX", code); - if (shorten) { // remove `0` after common code - if (code == 0x000000000) { - return "0"; // special case - } - result[9 - last_zero_num(code) / 4] = '\0'; // truncate string - } - return result; - -// return CommonCode::to_string_(code, shorten); - -} - -CommonCode CommonCode::from_string(const std::string &common_code) { - - if (common_code.length() > 9 || common_code.length() == 0) { - throw std::invalid_argument("common code format error"); - } - uint64_t result = 0; - for (auto const &bit : common_code) { - result <<= 4; - if (bit >= '0' && bit <= '9') { // 0 ~ 9 - result |= (bit - 48); - } else if (bit >= 'A' && bit <= 'Z') { // A ~ Z - result |= (bit - 55); - } else if (bit >= 'a' && bit <= 'z') { // a ~ z - result |= (bit - 87); - } else { - throw std::invalid_argument("common code format error"); - } - } - - return CommonCode(result << (9 - common_code.length()) * 4); // low-bits fill with zero - - // TODO: should we ensure that common code is valid? -// return result << (9 - common_code.length()) * 4; // low-bits fill with zero - - -// return CommonCode(CommonCode::from_string_(common_code)); - -} - -CommonCode::CommonCode(uint64_t common_code) { - - if (!CommonCode::check(common_code)) { - throw std::invalid_argument("invalid common code"); - } - - code = common_code; - -} - -uint64_t CommonCode::unwrap() const { - return code; -} diff --git a/src/common_code/common_code.h b/src/common_code/common_code.h index 8148c93..f6d236e 100644 --- a/src/common_code/common_code.h +++ b/src/common_code/common_code.h @@ -5,24 +5,13 @@ class CommonCode { public: - explicit CommonCode(uint64_t common_code); + explicit CommonCode(const std::string &common_code_str); uint64_t unwrap() const; - + static bool check(uint64_t common_code); std::string to_string(bool shorten = false) const; - static CommonCode from_string(const std::string &common_code); - - private: - uint64_t code; - - static bool check(uint64_t common_code); - -// static uint64_t from_string(const std::string &common_code); -// static std::string to_string(uint64_t common_code, bool shorten = false); - - }; diff --git a/src/main.cc b/src/main.cc index 98b159e..a6e3021 100644 --- a/src/main.cc +++ b/src/main.cc @@ -53,7 +53,7 @@ int main() { // std::cout << CommonCode::to_string(0x1A9BF0C00) << std::endl; // std::cout << CommonCode::to_string(0x1A9BF0C00, true) << std::endl; - auto c = CommonCode::from_string("1A9bF0c0"); + auto c = CommonCode("1A9bF0c0"); std::cout << c.to_string(true) << std::endl; std::cout << c.to_string() << std::endl; printf("%09lX\n", c.unwrap());