Browse Source

feat: convert between RawCode and CommonCode

master
Dnomd343 2 years ago
parent
commit
fbbdbd9139
  1. 28
      src/main.cc
  2. 18
      src/raw_code/convert.cc
  3. 78
      src/raw_code/raw_code.cc
  4. 16
      src/raw_code/raw_code.h

28
src/main.cc

@ -362,22 +362,24 @@ int main() {
// printf("%09lX\n", CommonCode::from_string("1a9bf0c").unwrap());
// std::cout << CommonCode("4feA134") << std::endl;
std::vector<uint64_t> 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::vector<uint64_t> 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::cout << CommonCode(0x4FEA13400).to_raw_code().to_common_code() << 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;
// std::cout << "complete benchmark" << std::endl;

18
src/raw_code/convert.cc

@ -1,7 +1,21 @@
#include "raw_code.h"
#include <stdexcept>
#include "common.h"
#include "raw_code.h"
RawCode::RawCode(const CommonCode &common_code) {
code = RawCode::extract(common_code.unwrap()); // load from common code
}
// TODO: for check function -> one 2x2 / >=2 space
CommonCode RawCode::to_common_code() const {
// TODO: check before release common code
// TODO: raw code pass RawCode::check -> using CommonCode::unsafe_create directly
if (!RawCode::check(code)) {
throw std::runtime_error("invalid raw code");
}
return CommonCode::unsafe_create(RawCode::compact(code)); // release common code
}
/// NOTE: ensure that input raw code is valid !!!
uint64_t RawCode::compact(uint64_t raw_code) { // raw code --> common code

78
src/raw_code/raw_code.cc

@ -6,71 +6,6 @@ uint64_t RawCode::unwrap() const { // get raw uint64_t code
return code;
}
CommonCode RawCode::to_common_code() const {
uint32_t range = 0;
uint64_t raw_code = code;
uint32_t unfilled_num = 16;
uint64_t head = ((uint64_t)16 << 32); // using invalid address
for (int addr = 0; raw_code; ++addr, raw_code >>= 3) {
switch (raw_code & 0b111) { // get low 3-bits
case B_space:
range <<= 2; // add space block
break;
case B_1x2:
(range <<= 2) |= 0b01; // add 1x2 block
break;
case B_2x1:
(range <<= 2) |= 0b10; // add 2x1 block
break;
case B_1x1:
(range <<= 2) |= 0b11; // add 1x1 block
break;
case B_2x2:
head = (uint64_t)addr << 32; // 2x2 block address
default:
// TODO: should we throw an error?
continue; // unknown block type
}
--unfilled_num; // less unfilled block
}
// TODO: should we check the high 4-bits equal to zero?
// printf("head -> %09lX\n", head);
// printf("range -> %08X\n", range << 10);
// printf("unfilled -> %d\n", unfilled_num);
unfilled_num <<= 1; // aka unfilled_num *= 2
return CommonCode(head | (range << unfilled_num));
}
// TODO: check function for RawCode
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 {
std::string result;
result.reserve(40); // 5 lines * ("x x x x\n")
@ -91,6 +26,19 @@ std::string RawCode::dump_case() const {
return result;
}
bool RawCode::check(uint64_t raw_code) {
// TODO: check function for RawCode
/// we can check any raw_code in this function
// TODO: for check function -> one 2x2 / >=2 space
// TODO: check the high 4-bits equal to zero
return true;
}

16
src/raw_code/raw_code.h

@ -12,22 +12,26 @@ public:
uint64_t unwrap() const;
std::string dump_case() const;
CommonCode to_common_code() const;
static bool check(uint64_t raw_code);
// friend std::ostream& operator<<(std::ostream &out, const RawCode &self);
explicit RawCode(const CommonCode &common_code);
// TODO: check raw_code before object create
explicit RawCode(uint64_t raw_code) : code(raw_code) {}
// TODO: mirror functions
// static RawCode create(uint64_t raw_code);
// static RawCode from_common_code(const CommonCode &common_code);
// TODO: mirror functions
static uint64_t compact(uint64_t raw_code);
static uint64_t extract(uint64_t common_code);
// TODO: unsafe_create static function
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);
};

Loading…
Cancel
Save