From 967627623f9831cbd7c5b297d5b93b4a918de292 Mon Sep 17 00:00:00 2001 From: Dnomd343 Date: Tue, 17 Jan 2023 14:04:28 +0800 Subject: [PATCH] feat: `compact` and `extract` interface for RawCode --- src/main.cc | 52 +++++++++++++++++++++++++-------------- src/raw_code/convert.cc | 53 +++++++++++++++++++++++++++++++++++++--- src/raw_code/raw_code.cc | 46 +++++++++++++++++----------------- src/raw_code/raw_code.h | 7 ++++-- 4 files changed, 113 insertions(+), 45 deletions(-) diff --git a/src/main.cc b/src/main.cc index 61454ec..27b29c6 100644 --- a/src/main.cc +++ b/src/main.cc @@ -52,22 +52,22 @@ // std::cout << std::endl; //} -std::vector all_cases; - -void short_code_verify(uint32_t start, uint32_t end) { - for (uint32_t short_code = start; short_code < end; ++short_code) { - auto common_code = all_cases[short_code]; // correct result - - if (ShortCode(short_code).to_common_code().unwrap() != common_code) { - std::cout << "Error decode: " << ShortCode(short_code) << std::endl; - } - - if (ShortCode(CommonCode(common_code)).unwrap() != short_code) { - std::cout << "Error encode: " << ShortCode(short_code) << std::endl; - } - } - std::cout << "[" << start << ", " << end << ")" << std::endl; -} +//std::vector all_cases; +// +//void short_code_verify(uint32_t start, uint32_t end) { +// for (uint32_t short_code = start; short_code < end; ++short_code) { +// auto common_code = all_cases[short_code]; // correct result +// +// if (ShortCode(short_code).to_common_code().unwrap() != common_code) { +// std::cout << "Error decode: " << ShortCode(short_code) << std::endl; +// } +// +// if (ShortCode(CommonCode(common_code)).unwrap() != short_code) { +// std::cout << "Error encode: " << ShortCode(short_code) << std::endl; +// } +// } +// std::cout << "[" << start << ", " << end << ")" << std::endl; +//} int main() { @@ -359,8 +359,24 @@ int main() { // std::cout << CommonCode("1a9bf0C0").to_string() << std::endl; // std::cout << CommonCode(0x4FEA13400).to_string() << std::endl; - printf("%09lX\n", CommonCode::from_string("1a9bf0c").unwrap()); - std::cout << CommonCode("4feA134") << std::endl; +// printf("%09lX\n", CommonCode::from_string("1a9bf0c").unwrap()); +// std::cout << CommonCode("4feA134") << std::endl; + + std::vector all_cases; + for (uint64_t head = 0; head < 16; ++head) { + for (const auto &range : AllCases::fetch()[head]) { + all_cases.emplace_back(head << 32 | range); + } + } + std::cout << "test size: " << all_cases.size() << std::endl; + + for (const auto &common_code : all_cases) { + if (RawCode::compact(RawCode::extract(common_code)) != common_code) { + std::cout << "Error: " << CommonCode(common_code) << std::endl; + } + } + +// std::cout << CommonCode(RawCode(RawCode::extract(0x4FEA13400))) << std::endl; // std::cerr << (clock() - start_time) * 1000 / CLOCKS_PER_SEC << "ms" << std::endl; std::cerr << (clock() - start_time) * 1000000 / CLOCKS_PER_SEC << "us" << std::endl; diff --git a/src/raw_code/convert.cc b/src/raw_code/convert.cc index 6b83c2e..102892d 100644 --- a/src/raw_code/convert.cc +++ b/src/raw_code/convert.cc @@ -1,11 +1,58 @@ #include "raw_code.h" +#include "common.h" +// TODO: for check function -> one 2x2 / >=2 space + +/// NOTE: ensure that input raw code is valid !!! uint64_t RawCode::compact(uint64_t raw_code) { // raw code --> common code - return 0; - // TODO: should we throw error here? + int unfilled = 16; + uint64_t head = 0; // 2x2 block address + uint32_t range = 0; + for (int addr = 0; raw_code; ++addr, raw_code >>= 3) { // traverse every address + switch (raw_code & 0b111) { // low 3-bits + case B_space: + range <<= 2; // space + break; + case B_1x2: + (range <<= 2) |= 0b01; // 1x2 block + break; + case B_2x1: + (range <<= 2) |= 0b10; // 2x1 block + break; + case B_1x1: + (range <<= 2) |= 0b11; // 1x1 block + break; + case B_2x2: + (head = addr) <<= 32; // 2x2 block + default: + continue; // B_fill type + } + --unfilled; // unfilled number + } + return head | (range << (unfilled << 1)); // fill low bits as zero } /// NOTE: ensure that input common code is valid !!! uint64_t RawCode::extract(uint64_t common_code) { // common code --> raw code - return 0; + auto code = C_2x2 << (common_code >> 32) * 3; // flag for 2x2 block + auto range = Common::range_reverse((uint32_t)common_code); // reversed range + for (int addr = 0; range; range >>= 2) { + while (0b111 & code >> addr) { // check low 3-bits -> next empty address + addr += 3; // found available address + } + switch (range & 0b11) { // match low 2-bits + case 0b01: // 1x2 block + code |= C_1x2 << addr; + break; + case 0b10: // 2x1 block + code |= C_2x1 << addr; + break; + case 0b11: // 1x1 block + code |= C_1x1 << addr; + break; + case 0b00: // space + addr += 3; // next address + } + } + return code; } diff --git a/src/raw_code/raw_code.cc b/src/raw_code/raw_code.cc index f2d0f7a..1f2946d 100644 --- a/src/raw_code/raw_code.cc +++ b/src/raw_code/raw_code.cc @@ -44,29 +44,31 @@ CommonCode RawCode::to_common_code() const { return CommonCode(head | (range << unfilled_num)); } -RawCode::RawCode(const CommonCode &common_code) { - auto common_code_raw = common_code.unwrap(); // common code with uint64_t format - code = C_2x2 << (common_code_raw >> 32) * 3; // flag for 2x2 block - auto range = Common::range_reverse((uint32_t)common_code_raw); // load reversed range +// TODO: check function for RawCode - for (int addr = 0; range; range >>= 2) { - while (0b111 & code >> addr) { // check low 3-bits -> until empty address - addr += 3; // found available address - } - switch (range & 0b11) { // match low 2-bits - case 0x1: - code |= C_1x2 << addr; // add 1x2 block - break; - case 0x2: - code |= C_2x1 << addr; // add 2x1 block - break; - case 0x3: - code |= C_1x1 << addr; // add 1x1 block - break; - case 0x0: - addr += 3; // next address - } - } +RawCode::RawCode(const CommonCode &common_code) { +// auto common_code_raw = common_code.unwrap(); // common code with uint64_t format +// code = C_2x2 << (common_code_raw >> 32) * 3; // flag for 2x2 block +// auto range = Common::range_reverse((uint32_t)common_code_raw); // load reversed range +// +// for (int addr = 0; range; range >>= 2) { +// while (0b111 & code >> addr) { // check low 3-bits -> until empty address +// addr += 3; // found available address +// } +// switch (range & 0b11) { // match low 2-bits +// case 0x1: +// code |= C_1x2 << addr; // add 1x2 block +// break; +// case 0x2: +// code |= C_2x1 << addr; // add 2x1 block +// break; +// case 0x3: +// code |= C_1x1 << addr; // add 1x1 block +// break; +// case 0x0: +// addr += 3; // next address +// } +// } } std::string RawCode::dump_case() const { diff --git a/src/raw_code/raw_code.h b/src/raw_code/raw_code.h index 363d478..6e6d8b5 100644 --- a/src/raw_code/raw_code.h +++ b/src/raw_code/raw_code.h @@ -22,9 +22,12 @@ public: // TODO: mirror functions + static uint64_t compact(uint64_t raw_code); + static uint64_t extract(uint64_t common_code); + private: uint64_t code; - static uint64_t compact(uint64_t raw_code); - static uint64_t extract(uint64_t common_code); +// static uint64_t compact(uint64_t raw_code); +// static uint64_t extract(uint64_t common_code); };