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);
56 std::vector<uint8_t> tmp(
length2);
61 *b = Chunk{start, std::move(tmp)};
62 result.erase(b + 1,
e);
65 result.emplace(b, Chunk{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();
98 auto chunkStart = it->startAddress;
99 int chunkSize = int(it->size());
101 int 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 int 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)
constexpr vecN< N, T > min(const vecN< N, T > &x, const vecN< N, T > &y)
constexpr vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
This file implemented 3 utility functions:
auto copy(InputRange &&range, OutputIter out)
bool equal(InputRange1 &&range1, InputRange2 &&range2, Pred pred={}, Proj1 proj1={}, Proj2 proj2={})
auto upper_bound(ForwardRange &&range, const T &value, Compare comp={}, Proj proj={})
auto lower_bound(ForwardRange &&range, const T &value, Compare comp={}, Proj proj={})
size_t size(std::string_view utf8)
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)