Clean up reading of values of various types
This commit is contained in:
parent
c3701056c6
commit
ef3509cbcf
5 changed files with 77 additions and 93 deletions
|
@ -58,4 +58,35 @@ T1 _read_common(const unsigned char* source)
|
||||||
#define read64ube(t) _read_common<uint64_t, uint64_t, 8, true>(reinterpret_cast<const unsigned char*>(t))
|
#define read64ube(t) _read_common<uint64_t, uint64_t, 8, true>(reinterpret_cast<const unsigned char*>(t))
|
||||||
#define read64ule(t) _read_common<uint64_t, uint64_t, 8, false>(reinterpret_cast<const unsigned char*>(t))
|
#define read64ule(t) _read_common<uint64_t, uint64_t, 8, false>(reinterpret_cast<const unsigned char*>(t))
|
||||||
|
|
||||||
|
template<typename T> void swap_endian(T& value)
|
||||||
|
{
|
||||||
|
char* _value = reinterpret_cast<char*>(&value);
|
||||||
|
for(size_t i = 0; i < sizeof(T)/2; i++)
|
||||||
|
std::swap(_value[i], _value[sizeof(T)-i-1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> void swap_endian(T& value, int endian)
|
||||||
|
{
|
||||||
|
short _magic = 258;
|
||||||
|
char magic = *reinterpret_cast<char*>(&_magic);
|
||||||
|
bool do_swap = (endian == -1 && magic == 1) || (endian == 1 && magic == 2);
|
||||||
|
if(do_swap)
|
||||||
|
swap_endian(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> T read_of_endian(const void* value, int endian)
|
||||||
|
{
|
||||||
|
T val;
|
||||||
|
memcpy(&val, value, sizeof(T));
|
||||||
|
swap_endian(val, endian);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> void write_of_endian(void* value, const T& val, int endian)
|
||||||
|
{
|
||||||
|
T val2;
|
||||||
|
memcpy(value, &val, sizeof(T));
|
||||||
|
swap_endian(*reinterpret_cast<T*>(value), endian);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "memorysearch.hpp"
|
#include "memorysearch.hpp"
|
||||||
#include "minmax.hpp"
|
#include "minmax.hpp"
|
||||||
|
#include "serialization.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
memory_search::memory_search(memory_space& space) throw(std::bad_alloc)
|
memory_search::memory_search(memory_space& space) throw(std::bad_alloc)
|
||||||
|
@ -136,21 +137,8 @@ struct search_value_helper
|
||||||
{
|
{
|
||||||
if(left < sizeof(value_type))
|
if(left < sizeof(value_type))
|
||||||
return false;
|
return false;
|
||||||
value_type v1 = 0;
|
value_type v1 = read_of_endian<value_type>(oldv, endian);
|
||||||
value_type v2 = 0;
|
value_type v2 = read_of_endian<value_type>(newv, endian);
|
||||||
if(!endian || (endian == memory_space::get_system_endian() && memory_space::can_read_unaligned())) {
|
|
||||||
v1 = *reinterpret_cast<const value_type*>(oldv);
|
|
||||||
v2 = *reinterpret_cast<const value_type*>(newv);
|
|
||||||
} else if(endian < 0)
|
|
||||||
for(size_t i = 0; i < sizeof(value_type); i++) {
|
|
||||||
v1 |= static_cast<value_type>(oldv[i]) << (8 * i);
|
|
||||||
v2 |= static_cast<value_type>(newv[i]) << (8 * i);
|
|
||||||
}
|
|
||||||
else if(endian > 0)
|
|
||||||
for(size_t i = 0; i < sizeof(value_type); i++) {
|
|
||||||
v1 |= static_cast<value_type>(oldv[i]) << (8 * (sizeof(T) - i - 1));
|
|
||||||
v2 |= static_cast<value_type>(newv[i]) << (8 * (sizeof(T) - i - 1));
|
|
||||||
}
|
|
||||||
return val(v1, v2);
|
return val(v1, v2);
|
||||||
}
|
}
|
||||||
const T& val;
|
const T& val;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "memoryspace.hpp"
|
#include "memoryspace.hpp"
|
||||||
#include "minmax.hpp"
|
#include "minmax.hpp"
|
||||||
|
#include "serialization.hpp"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
@ -14,27 +15,12 @@ namespace
|
||||||
g = m.lookup(addr);
|
g = m.lookup(addr);
|
||||||
if(!g.first || g.second + sizeof(T) > g.first->size)
|
if(!g.first || g.second + sizeof(T) > g.first->size)
|
||||||
return 0;
|
return 0;
|
||||||
if((!g.first->endian || g.first->endian == system_endian) && memory_space::can_read_unaligned()) {
|
if(g.first->direct_map)
|
||||||
//Native endian.
|
return read_of_endian<T>(g.first->direct_map + g.second, g.first->endian);
|
||||||
|
else {
|
||||||
T buf;
|
T buf;
|
||||||
if(g.first->direct_map)
|
g.first->read(g.second, &buf, sizeof(T));
|
||||||
return *reinterpret_cast<T*>(g.first->direct_map + g.second);
|
return read_of_endian<T>(&buf, g.first->endian);
|
||||||
else
|
|
||||||
g.first->read(g.second, &buf, sizeof(T));
|
|
||||||
return buf;
|
|
||||||
} else {
|
|
||||||
//Can't read directly.
|
|
||||||
unsigned char buf[sizeof(T)];
|
|
||||||
if(g.first->direct_map)
|
|
||||||
memcpy(buf, g.first->direct_map + g.second, sizeof(T));
|
|
||||||
else
|
|
||||||
g.first->read(g.second, buf, sizeof(T));
|
|
||||||
if(g.first->endian && g.first->endian != system_endian) {
|
|
||||||
//Needs byteswap.
|
|
||||||
for(size_t i = 0; i < sizeof(T) / 2; i++)
|
|
||||||
std::swap(buf[i], buf[sizeof(T) - i - 1]);
|
|
||||||
}
|
|
||||||
return *reinterpret_cast<T*>(buf);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,26 +34,12 @@ namespace
|
||||||
g = m.lookup(addr);
|
g = m.lookup(addr);
|
||||||
if(!g.first || g.first->readonly || g.second + sizeof(T) > g.first->size)
|
if(!g.first || g.first->readonly || g.second + sizeof(T) > g.first->size)
|
||||||
return false;
|
return false;
|
||||||
if((!g.first->endian || g.first->endian == system_endian) && memory_space::can_read_unaligned()) {
|
if(g.first->direct_map)
|
||||||
//Native endian.
|
write_of_endian(g.first->direct_map + g.second, value, g.first->endian);
|
||||||
if(g.first->direct_map) {
|
else {
|
||||||
*reinterpret_cast<T*>(g.first->direct_map + g.second) = value;
|
T buf;
|
||||||
return true;
|
write_of_endian(&buf, value, g.first->endian);
|
||||||
} else
|
g.first->write(g.second, &buf, sizeof(T));
|
||||||
g.first->write(g.second, &value, sizeof(T));
|
|
||||||
} else {
|
|
||||||
//The opposite endian (little).
|
|
||||||
unsigned char buf[sizeof(T)];
|
|
||||||
*reinterpret_cast<T*>(buf) = value;
|
|
||||||
if(g.first->endian && g.first->endian != system_endian) {
|
|
||||||
//Needs byteswap.
|
|
||||||
for(size_t i = 0; i < sizeof(T) / 2; i++)
|
|
||||||
std::swap(buf[i], buf[sizeof(T) - i - 1]);
|
|
||||||
}
|
|
||||||
if(g.first->direct_map)
|
|
||||||
memcpy(g.first->direct_map + g.second, buf, sizeof(T));
|
|
||||||
else
|
|
||||||
return g.first->write(g.second, buf, sizeof(T));
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,126 +1,121 @@
|
||||||
#include "lua/internal.hpp"
|
#include "lua/internal.hpp"
|
||||||
#include "core/moviedata.hpp"
|
#include "core/moviedata.hpp"
|
||||||
|
#include "library/serialization.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
template<typename U, typename S>
|
template<typename S>
|
||||||
int do_read(lua_state& L, const std::string& fname)
|
int do_read(lua_state& L, const std::string& fname)
|
||||||
{
|
{
|
||||||
size_t address = L.get_numeric_argument<size_t>(1, fname.c_str());
|
size_t address = L.get_numeric_argument<size_t>(1, fname.c_str());
|
||||||
auto& h = get_host_memory();
|
auto& h = get_host_memory();
|
||||||
if(address + sizeof(U) > h.size()) {
|
if(address + sizeof(S) > h.size()) {
|
||||||
L.pushboolean(0);
|
L.pushboolean(0);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
U ret = 0;
|
L.pushnumber(read_of_endian<S>(&h[address], 1));
|
||||||
for(size_t i = 0; i < sizeof(U); i++)
|
|
||||||
ret = 256 * ret + static_cast<uint8_t>(h[address + i]);
|
|
||||||
L.pushnumber(static_cast<S>(ret));
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U, typename S>
|
template<typename S>
|
||||||
int do_write(lua_state& L, const std::string& fname)
|
int do_write(lua_state& L, const std::string& fname)
|
||||||
{
|
{
|
||||||
size_t address = L.get_numeric_argument<size_t>(1, fname.c_str());
|
size_t address = L.get_numeric_argument<size_t>(1, fname.c_str());
|
||||||
U value = static_cast<U>(L.get_numeric_argument<S>(2, fname.c_str()));
|
S value = static_cast<S>(L.get_numeric_argument<S>(2, fname.c_str()));
|
||||||
auto& h = get_host_memory();
|
auto& h = get_host_memory();
|
||||||
if(address + sizeof(U) > h.size())
|
if(address + sizeof(S) > h.size())
|
||||||
h.resize(address + sizeof(U));
|
h.resize(address + sizeof(S));
|
||||||
for(size_t i = sizeof(U) - 1; i < sizeof(U); i--) {
|
write_of_endian<S>(&h[address], value, 1);
|
||||||
h[address + i] = value;
|
|
||||||
value >>= 8;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function_ptr_luafun hm_read(lua_func_misc, "hostmemory.read", [](lua_state& L,
|
function_ptr_luafun hm_read(lua_func_misc, "hostmemory.read", [](lua_state& L,
|
||||||
const std::string& fname) -> int {
|
const std::string& fname) -> int {
|
||||||
return do_read<uint8_t, uint8_t>(L, fname);
|
return do_read<uint8_t>(L, fname);
|
||||||
});
|
});
|
||||||
|
|
||||||
function_ptr_luafun hm_write(lua_func_misc, "hostmemory.write", [](lua_state& L,
|
function_ptr_luafun hm_write(lua_func_misc, "hostmemory.write", [](lua_state& L,
|
||||||
const std::string& fname) -> int {
|
const std::string& fname) -> int {
|
||||||
return do_write<uint8_t, uint8_t>(L, fname);
|
return do_write<uint8_t>(L, fname);
|
||||||
});
|
});
|
||||||
|
|
||||||
function_ptr_luafun hm_readb(lua_func_misc, "hostmemory.readbyte", [](lua_state& L,
|
function_ptr_luafun hm_readb(lua_func_misc, "hostmemory.readbyte", [](lua_state& L,
|
||||||
const std::string& fname) -> int {
|
const std::string& fname) -> int {
|
||||||
return do_read<uint8_t, uint8_t>(L, fname);
|
return do_read<uint8_t>(L, fname);
|
||||||
});
|
});
|
||||||
|
|
||||||
function_ptr_luafun hm_writeb(lua_func_misc, "hostmemory.writebyte", [](lua_state& L,
|
function_ptr_luafun hm_writeb(lua_func_misc, "hostmemory.writebyte", [](lua_state& L,
|
||||||
const std::string& fname) -> int {
|
const std::string& fname) -> int {
|
||||||
return do_write<uint8_t, uint8_t>(L, fname);
|
return do_write<uint8_t>(L, fname);
|
||||||
});
|
});
|
||||||
|
|
||||||
function_ptr_luafun hm_readsb(lua_func_misc, "hostmemory.readsbyte", [](lua_state& L,
|
function_ptr_luafun hm_readsb(lua_func_misc, "hostmemory.readsbyte", [](lua_state& L,
|
||||||
const std::string& fname) -> int {
|
const std::string& fname) -> int {
|
||||||
return do_read<uint8_t, int8_t>(L, fname);
|
return do_read<int8_t>(L, fname);
|
||||||
});
|
});
|
||||||
|
|
||||||
function_ptr_luafun hm_writesb(lua_func_misc, "hostmemory.writesbyte", [](lua_state& L,
|
function_ptr_luafun hm_writesb(lua_func_misc, "hostmemory.writesbyte", [](lua_state& L,
|
||||||
const std::string& fname) -> int {
|
const std::string& fname) -> int {
|
||||||
return do_write<uint8_t, int8_t>(L, fname);
|
return do_write<int8_t>(L, fname);
|
||||||
});
|
});
|
||||||
|
|
||||||
function_ptr_luafun hm_readw(lua_func_misc, "hostmemory.readword", [](lua_state& L,
|
function_ptr_luafun hm_readw(lua_func_misc, "hostmemory.readword", [](lua_state& L,
|
||||||
const std::string& fname) -> int {
|
const std::string& fname) -> int {
|
||||||
return do_read<uint16_t, uint16_t>(L, fname);
|
return do_read<uint16_t>(L, fname);
|
||||||
});
|
});
|
||||||
|
|
||||||
function_ptr_luafun hm_writew(lua_func_misc, "hostmemory.writeword", [](lua_state& L,
|
function_ptr_luafun hm_writew(lua_func_misc, "hostmemory.writeword", [](lua_state& L,
|
||||||
const std::string& fname) -> int {
|
const std::string& fname) -> int {
|
||||||
return do_write<uint16_t, uint16_t>(L, fname);
|
return do_write<uint16_t>(L, fname);
|
||||||
});
|
});
|
||||||
|
|
||||||
function_ptr_luafun hm_readsw(lua_func_misc, "hostmemory.readsword", [](lua_state& L,
|
function_ptr_luafun hm_readsw(lua_func_misc, "hostmemory.readsword", [](lua_state& L,
|
||||||
const std::string& fname) -> int {
|
const std::string& fname) -> int {
|
||||||
return do_read<uint16_t, int16_t>(L, fname);
|
return do_read<int16_t>(L, fname);
|
||||||
});
|
});
|
||||||
|
|
||||||
function_ptr_luafun hm_writesw(lua_func_misc, "hostmemory.writesword", [](lua_state& L,
|
function_ptr_luafun hm_writesw(lua_func_misc, "hostmemory.writesword", [](lua_state& L,
|
||||||
const std::string& fname) -> int {
|
const std::string& fname) -> int {
|
||||||
return do_write<uint16_t, int16_t>(L, fname);
|
return do_write<int16_t>(L, fname);
|
||||||
});
|
});
|
||||||
|
|
||||||
function_ptr_luafun hm_readd(lua_func_misc, "hostmemory.readdword", [](lua_state& L,
|
function_ptr_luafun hm_readd(lua_func_misc, "hostmemory.readdword", [](lua_state& L,
|
||||||
const std::string& fname) -> int {
|
const std::string& fname) -> int {
|
||||||
return do_read<uint32_t, uint32_t>(L, fname);
|
return do_read<uint32_t>(L, fname);
|
||||||
});
|
});
|
||||||
|
|
||||||
function_ptr_luafun hm_writed(lua_func_misc, "hostmemory.writedword", [](lua_state& L,
|
function_ptr_luafun hm_writed(lua_func_misc, "hostmemory.writedword", [](lua_state& L,
|
||||||
const std::string& fname) -> int {
|
const std::string& fname) -> int {
|
||||||
return do_write<uint32_t, uint32_t>(L, fname);
|
return do_write<uint32_t>(L, fname);
|
||||||
});
|
});
|
||||||
|
|
||||||
function_ptr_luafun hm_readsd(lua_func_misc, "hostmemory.readsdword", [](lua_state& L,
|
function_ptr_luafun hm_readsd(lua_func_misc, "hostmemory.readsdword", [](lua_state& L,
|
||||||
const std::string& fname) -> int {
|
const std::string& fname) -> int {
|
||||||
return do_read<uint32_t, int32_t>(L, fname);
|
return do_read<int32_t>(L, fname);
|
||||||
});
|
});
|
||||||
|
|
||||||
function_ptr_luafun hm_writesd(lua_func_misc, "hostmemory.writesdword", [](lua_state& L,
|
function_ptr_luafun hm_writesd(lua_func_misc, "hostmemory.writesdword", [](lua_state& L,
|
||||||
const std::string& fname) -> int {
|
const std::string& fname) -> int {
|
||||||
return do_write<uint32_t, int32_t>(L, fname);
|
return do_write<int32_t>(L, fname);
|
||||||
});
|
});
|
||||||
|
|
||||||
function_ptr_luafun hm_readq(lua_func_misc, "hostmemory.readqword", [](lua_state& L,
|
function_ptr_luafun hm_readq(lua_func_misc, "hostmemory.readqword", [](lua_state& L,
|
||||||
const std::string& fname) -> int {
|
const std::string& fname) -> int {
|
||||||
return do_read<uint64_t, uint64_t>(L, fname);
|
return do_read<uint64_t>(L, fname);
|
||||||
});
|
});
|
||||||
|
|
||||||
function_ptr_luafun hm_writeq(lua_func_misc, "hostmemory.writeqword", [](lua_state& L,
|
function_ptr_luafun hm_writeq(lua_func_misc, "hostmemory.writeqword", [](lua_state& L,
|
||||||
const std::string& fname) -> int {
|
const std::string& fname) -> int {
|
||||||
return do_write<uint64_t, uint64_t>(L, fname);
|
return do_write<uint64_t>(L, fname);
|
||||||
});
|
});
|
||||||
|
|
||||||
function_ptr_luafun hm_readsq(lua_func_misc, "hostmemory.readsqword", [](lua_state& L,
|
function_ptr_luafun hm_readsq(lua_func_misc, "hostmemory.readsqword", [](lua_state& L,
|
||||||
const std::string& fname) -> int {
|
const std::string& fname) -> int {
|
||||||
return do_read<uint64_t, int64_t>(L, fname);
|
return do_read<int64_t>(L, fname);
|
||||||
});
|
});
|
||||||
|
|
||||||
function_ptr_luafun hm_writesq(lua_func_misc, "hostmemory.writesqword", [](lua_state& L,
|
function_ptr_luafun hm_writesq(lua_func_misc, "hostmemory.writesqword", [](lua_state& L,
|
||||||
const std::string& fname) -> int {
|
const std::string& fname) -> int {
|
||||||
return do_write<uint64_t, int64_t>(L, fname);
|
return do_write<int64_t>(L, fname);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "core/rom.hpp"
|
#include "core/rom.hpp"
|
||||||
#include "library/sha256.hpp"
|
#include "library/sha256.hpp"
|
||||||
#include "library/string.hpp"
|
#include "library/string.hpp"
|
||||||
|
#include "library/serialization.hpp"
|
||||||
#include "library/minmax.hpp"
|
#include "library/minmax.hpp"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
|
@ -39,12 +40,9 @@ namespace
|
||||||
|
|
||||||
template<typename T> T bswap(T val)
|
template<typename T> T bswap(T val)
|
||||||
{
|
{
|
||||||
char buf[sizeof(T)];
|
T val2 = val;
|
||||||
memcpy(buf, &val, sizeof(T));
|
swap_endian(val2);
|
||||||
for(size_t i = 0; i < sizeof(T) / 2; i++)
|
return val2;
|
||||||
std::swap(buf[i], buf[sizeof(T) - i - 1]);
|
|
||||||
memcpy(&val, buf, sizeof(T));
|
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class lua_vma
|
class lua_vma
|
||||||
|
|
Loading…
Add table
Reference in a new issue