Browse Source

feat: Analyse support build partial

master
Dnomd343 2 years ago
parent
commit
500756124e
  1. 59
      src/analyse/analyse.cc
  2. 4
      src/analyse/analyse.h
  3. 2
      src/fast_cal/fast_cal.h
  4. 8
      src/main.cc

59
src/analyse/analyse.cc

@ -26,43 +26,84 @@ void Analyse::build(uint64_t code) {
std::queue<analyse_t*>{}.swap(cache);
cache.emplace(&cases.emplace(code, analyse_t {
.code = code,
.mask = 0,
.step = 0,
.src = std::list<analyse_t*>{},
}).first->second);
while (!cache.empty()) {
core.next_cases(cache.front()->code, cache.front()->mask);
cache.pop();
}
std::cout << "size: " << cases.size() << std::endl;
}
std::vector<uint64_t> Analyse::build_until(uint64_t code, const Analyse::match_t &match) {
auto core = init();
cases.clear();
cases.reserve(65536);
std::queue<analyse_t*>{}.swap(cache);
cache.emplace(&cases.emplace(code, analyse_t {
.code = code,
.mask = 0,
.step = 0,
.src = std::list<analyse_t*>{},
// .src = std::vector<analyse_t*>{},
// .src = std::set<analyse_t*>{},
// .src = std::unordered_set<analyse_t*>{},
.src = std::list<analyse_t*>{},
}).first->second);
auto layer_end = cache.back();
std::vector<uint64_t> matched; // matched list
while (!cache.empty()) {
if (match(cache.front()->code)) { // match target
matched.emplace_back(cache.front()->code);
}
core.next_cases(cache.front()->code, cache.front()->mask);
if (cache.front() == layer_end) { // reach layer ending
if (!matched.empty()) {
std::cout << "size: " << cases.size() << std::endl;
return matched; // stop at first matched layer
}
layer_end = cache.back(); // reset layer ending
}
cache.pop();
}
std::cout << "size: " << cases.size() << std::endl;
return std::vector<uint64_t>{}; // no target found
}
void Analyse::new_case(uint64_t code, uint64_t mask) {
auto current = cases.find(code);
if (current != cases.end()) { // new case already exist
if (current->second.step == cache.front()->step + 1) { // new case at next layer
current->second.mask |= mask; // update mask info
current->second.src.emplace_back(cache.front()); // link more parent case
// current->second.src.emplace(cache.front()); // link more parent case
}
} else { // new case not exist
cache.emplace(&cases.emplace(code, analyse_t { // record new case
.code = code,
.mask = mask,
.step = cache.front()->step + 1,
.src = std::list<analyse_t*>{cache.front()}, // link parent case
// .src = std::vector<analyse_t*>{cache.front()}, // link parent case
// .src = std::set<analyse_t*>{cache.front()}, // link parent case
// .src = std::unordered_set<analyse_t*>{cache.front()}, // link parent case
.src = std::list<analyse_t*>{cache.front()}, // link parent case
}).first->second);
}
}

4
src/analyse/analyse.h

@ -37,8 +37,12 @@ public:
// void backtrack(uint64_t code);
// void backtrack(const std::vector<uint64_t> &raw_code_list);
typedef std::function<bool(uint64_t)> match_t;
void build(uint64_t code);
std::vector<uint64_t> build_until(uint64_t code, const match_t &match);
// inline Core init(uint64_t code);
inline Core init();

2
src/fast_cal/fast_cal.h

@ -19,6 +19,8 @@ public:
int step_num(const RawCode &code);
std::vector<RawCode> backtrack(const RawCode &code);
// TODO: should we using code as class member
/// BFS search functions
void build(const RawCode &code);
RawCode solve(const RawCode &code);

8
src/main.cc

@ -59,7 +59,13 @@ int main() {
auto a = Analyse();
a.build((uint64_t)RawCode::from_common_code("1a9bf0c"));
// a.build((uint64_t)RawCode::from_common_code("1a9bf0c"));
auto ret = a.build_until((uint64_t)RawCode::from_common_code("1a9bf0c"), [](uint64_t code) {
return ((code >> (3 * 0xD)) & 0b111) == B_2x2;
});
for (const auto &r : ret) {
std::cout << RawCode(r) << std::endl;
}
// auto raw_code = CommonCode("A5D3AF0").to_raw_code().unwrap();

Loading…
Cancel
Save