12std::vector<IPSPatch::Chunk> IPSPatch::parseChunks()
const
14 std::vector<Chunk> result;
16 File ipsFile(filename);
18 std::array<uint8_t, 5> header;
21 throw MSXException(
"Invalid IPS file: ", filename.
getOriginal());
23 std::array<uint8_t, 3> offsetBuf;
24 ipsFile.read(offsetBuf);
26 size_t offset = 0x10000 * offsetBuf[0] + 0x100 * offsetBuf[1] + offsetBuf[2];
27 std::array<uint8_t, 2> lenBuf;
29 size_t length = 0x100 * lenBuf[0] + lenBuf[1];
30 std::vector<uint8_t> v;
33 std::array<uint8_t, 3> rleBuf;
35 length = 0x100 * rleBuf[0] + rleBuf[1];
36 v.resize(length, rleBuf[2]);
44 if (b !=
begin(result)) {
46 if (b->stopAddress() < offset) ++b;
52 auto start = std::min(b->startAddress, offset);
53 auto stop = std::max(offset + length,
e->stopAddress());
56 std::vector<uint8_t> tmp(length2);
61 *b = Chunk{start, std::move(tmp)};
62 result.erase(b + 1, e);
65 result.emplace(b, offset, std::move(v));
68 ipsFile.read(offsetBuf);
73size_t IPSPatch::calcSize()
const
77 : std::max(parent->getSize(), chunks.back().stopAddress());
81 std::unique_ptr<const PatchInterface> parent_)
82 : filename(
std::move(filename_))
83 , parent(
std::move(parent_))
84 , chunks(parseChunks())
91 parent->copyBlock(src, dst);
94 if (b !=
begin(chunks)) --b;
95 auto srcEnd = src + dst.size();
97 for (
auto it :
xrange(b, e)) {
98 auto chunkStart = it->startAddress;
99 auto chunkSize = int(it->size());
101 auto chunkOffset = int(src - chunkStart);
102 if (chunkOffset < 0) {
104 assert(-chunkOffset <
int(dst.size()));
106 }
else if (chunkOffset >= chunkSize) {
111 chunkSize -= chunkOffset;
112 chunkStart += chunkOffset;
115 assert(src <= chunkStart);
116 if (
auto overflow =
int(chunkStart - src + chunkSize - dst.size());
118 assert(chunkSize > overflow);
119 chunkSize -= overflow;
122 assert(chunkOffset <
int(it->size()));
123 assert((chunkOffset + chunkSize) <=
int(it->size()));
124 assert(src <= chunkStart);
125 assert((chunkStart + chunkSize) <= srcEnd);
127 subspan(dst, chunkStart - src));
133 auto result = parent->getFilenames();
134 result.push_back(filename);
This class represents a filename.
const std::string & getOriginal() const
void copyBlock(size_t src, std::span< uint8_t > dst) const override
IPSPatch(Filename filename, std::unique_ptr< const PatchInterface > parent)
std::vector< Filename > getFilenames() const override
T length(const vecN< N, T > &x)
constexpr T length2(const vecN< N, T > &x)
This file implemented 3 utility functions:
auto upper_bound(ForwardRange &&range, const T &value, Compare comp={}, Proj proj={})
constexpr bool equal(InputRange1 &&range1, InputRange2 &&range2, Pred pred={}, Proj1 proj1={}, Proj2 proj2={})
constexpr auto copy(InputRange &&range, OutputIter out)
auto lower_bound(ForwardRange &&range, const T &value, Compare comp={}, Proj proj={})
constexpr auto subspan(Range &&range, size_t offset, size_t count=std::dynamic_extent)
constexpr auto xrange(T e)
constexpr auto begin(const zstring_view &x)