3 #include "serialization.hpp"
12 uint8_t readbyte(const char* buf
, uint64_t& pos
, uint64_t size
)
15 (stringfmt() << "Attempted to read byte past the end of patch (" << pos
<< " >= "
16 << size
<< ").").throwex();
17 return static_cast<uint8_t>(buf
[pos
++]);
20 struct ips_patcher
: public rom_patcher
22 ~ips_patcher() throw();
23 bool identify(const std::vector
<char>& patch
) throw();
24 void dopatch(std::vector
<char>& out
, const std::vector
<char>& original
,
25 const std::vector
<char>& patch
, int32_t offset
) throw(std::bad_alloc
, std::runtime_error
);
28 ips_patcher::~ips_patcher() throw()
32 bool ips_patcher::identify(const std::vector
<char>& patch
) throw()
34 return (patch
.size() > 5 && patch
[0] == 'P' && patch
[1] == 'A' && patch
[2] == 'T' && patch
[3] == 'C' &&
38 void ips_patcher::dopatch(std::vector
<char>& out
, const std::vector
<char>& original
,
39 const std::vector
<char>& patch
, int32_t offset
) throw(std::bad_alloc
, std::runtime_error
)
43 const char* _patch
= &patch
[0];
44 size_t psize
= patch
.size();
49 size_t left
= patch
.size() - ioffset
;
51 uint32_t off
= 0, l
= 0;
52 off
|= static_cast<uint32_t>(readbyte(_patch
, ioffset
, psize
)) << 16;
53 off
|= static_cast<uint32_t>(readbyte(_patch
, ioffset
, psize
)) << 8;
54 off
|= static_cast<uint32_t>(readbyte(_patch
, ioffset
, psize
));
57 l
|= static_cast<uint32_t>(readbyte(_patch
, ioffset
, psize
)) << 8;
58 l
|= static_cast<uint32_t>(readbyte(_patch
, ioffset
, psize
));
61 l
|= static_cast<uint32_t>(readbyte(_patch
, ioffset
, psize
)) << 8;
62 l
|= static_cast<uint32_t>(readbyte(_patch
, ioffset
, psize
));
63 b
= readbyte(_patch
, ioffset
, psize
);
70 uint32_t noffset
= static_cast<uint32_t>(-offset
);
71 uint32_t fromoff
= min(noffset
, off
);
73 extra
= min(noffset
- fromoff
, l
);
76 if(off
+ l
>= out
.size())
80 for(uint64_t i
= 0; i
< l
; i
++)
81 out
[off
+ i
] = readbyte(_patch
, ioffset
, psize
);
83 for(uint64_t i
= 0; i
< l
; i
++)