#include <algorithm>#include <numeric> #include "muscles.h"#include "structs.h" int Source::request_span(void) { int idx = -1; for (int i = 0; i < spans.size(); i++) { if (spans[i].flags & FLAG_AVAILABLE) { spans[i] = {0}; idx = i; break; } } if (idx < 0) { idx = spans.size(); spans.push_back({0}); } return idx;} void Source::deactivate_span(int idx) { if (idx >= 0 && idx < spans.size()) { spans[idx].flags |= FLAG_AVAILABLE; spans[idx].size = 0; }} void Source::gather_data() { if (spans.size() < 1) return; std::vector<int> index(spans.size()); std::iota(index.begin(), index.end(), 0); std::sort(index.begin(), index.end(), [this](int a, int b) { return this->spans[a].address < this->spans[b].address; }); int first = -1; for (int i = 0; i < spans.size(); i++) { auto &s = spans[index[i]]; if ((s.flags & FLAG_AVAILABLE) == 0 && s.size > 0) { first = i; s.tag = 0; break; } s.tag = -1; } if (first < 0) return; std::vector<Span> io = {{0}}; io[0].address = spans[index[first]].address; io[0].size = spans[index[first]].size; io[0].tag = index[first]; spans[index[first]].offset = 0; for (int i = first+1; i < spans.size(); i++) { Span& virt = spans[index[i]]; virt.tag = -1; if ((virt.flags & FLAG_AVAILABLE) || virt.size <= 0) continue; Span& real = io.back(); if (virt.address <= real.address + (u64)real.size) { virt.offset = virt.address - real.address; int size = virt.offset + virt.size; real.size = size > real.size ? size : real.size; } else { int offset = real.offset + real.size; virt.offset = offset; io.push_back({ .data = nullptr, .address = virt.address, .size = virt.size, .retrieved = 0, .offset = virt.offset, .tag = index[i], .flags = 0 }); } virt.tag = io.size() - 1; } auto& end = io.back(); int size = end.offset + end.size; if (!size) { if (buffer) delete[] buffer; buffer = nullptr; buf_size = 0; return; } else if (size != buf_size) { if (!buffer) buffer = new u8[size]; else if (size > buf_size) { if (buffer) delete[] buffer; buffer = new u8[size]; } } buf_size = size; if (type == SourceFile) refresh_file_spans(*this, io); else if (type == SourceProcess) refresh_process_spans(*this, io); int n_spans = io.size(); for (auto& idx : index) { auto& s = spans[idx]; s.retrieved = 0; if (s.tag < 0) continue; s.data = &buffer[s.offset]; s.retrieved = io[s.tag].retrieved - s.offset; if (s.retrieved < 0) s.retrieved = 0; }}