#include "Serializer.h" // read return template T MemStreamReader::read() { if (!reserveReadLength(sizeof(T))) return 0; const uint8* p = m_data + m_cursorPos; T v; std::memcpy(&v, p, sizeof(v)); m_cursorPos += sizeof(T); return v; } template uint8 MemStreamReader::read(); template uint16 MemStreamReader::read(); template uint32 MemStreamReader::read(); template uint32be MemStreamReader::read(); template uint64 MemStreamReader::read(); template int MemStreamReader::read(); template<> std::string MemStreamReader::read() { std::string s; uint32 stringSize = read(); if (hasError()) return s; if (stringSize >= (32 * 1024 * 1024)) { // out of bounds read or suspiciously large string m_hasError = true; return std::string(); } s.resize(stringSize); readData(s.data(), stringSize); return s; } // read void template void MemStreamReader::read(T& v) { if (reserveReadLength(sizeof(T))) { const uint8* p = m_data + m_cursorPos; std::memcpy(&v, p, sizeof(v)); m_cursorPos += sizeof(T); } } template void MemStreamReader::read(uint8& v); template void MemStreamReader::read(uint16& v); template void MemStreamReader::read(uint32& v); template void MemStreamReader::read(uint32be& v); template void MemStreamReader::read(uint64& v); template void MemStreamReader::read(int& v); template<> void MemStreamReader::read(std::string& v) { uint32 stringSize = read(); if (!hasError()) { if (stringSize >= (32 * 1024 * 1024)) { // out of bounds read or suspiciously large string m_hasError = true; } else { v.resize(stringSize); readData(v.data(), stringSize); } } } // readSection void MemStreamReader::readSection(const char* sec) { std::string sec_str = std::string(sec); cemu_assert_debug(read() == sec_str); } // readBE return template T MemStreamReader::readBE() { if (!reserveReadLength(sizeof(T))) return 0; const uint8* p = m_data + m_cursorPos; T v; std::memcpy(&v, p, sizeof(v)); v = _BE(v); m_cursorPos += sizeof(T); return v; } template uint8 MemStreamReader::readBE(); template uint16 MemStreamReader::readBE(); template uint32 MemStreamReader::readBE(); template uint64 MemStreamReader::readBE(); template<> std::string MemStreamReader::readBE() { std::string s; uint32 stringSize = readBE(); if (hasError()) return s; if (stringSize >= (32 * 1024 * 1024)) { // out of bounds read or suspiciously large string m_hasError = true; return std::string(); } s.resize(stringSize); readData(s.data(), stringSize); return s; } // readLE return template T MemStreamReader::readLE() { if (!reserveReadLength(sizeof(T))) return 0; const uint8* p = m_data + m_cursorPos; T v; std::memcpy(&v, p, sizeof(v)); v = _LE(v); m_cursorPos += sizeof(T); return v; } template uint8 MemStreamReader::readLE(); template uint32 MemStreamReader::readLE(); template uint64 MemStreamReader::readLE(); // write void template void MemStreamWriter::write(const T& v) { m_buffer.resize(m_buffer.size() + sizeof(T)); uint8* p = m_buffer.data() + m_buffer.size() - sizeof(T); std::memcpy(p, &v, sizeof(v)); } template void MemStreamWriter::write(const int& v); template void MemStreamWriter::write(const uint64& v); template void MemStreamWriter::write(const uint32be& v); template void MemStreamWriter::write(const uint32& v); template void MemStreamWriter::write(const uint16& v); template void MemStreamWriter::write(const uint8& v); template<> void MemStreamWriter::write(const std::string& v) { write((uint32)v.size()); writeData(v.data(), v.size()); } // writeSection void MemStreamWriter::writeSection(const char* sec) { std::string sec_str = std::string(sec); write(sec_str); } // writeBE void template void MemStreamWriter::writeBE(const T& v) { m_buffer.resize(m_buffer.size() + sizeof(T)); uint8* p = m_buffer.data() + m_buffer.size() - sizeof(T); T tmp = _BE(v); std::memcpy(p, &tmp, sizeof(tmp)); } template void MemStreamWriter::writeBE(const uint64& v); template void MemStreamWriter::writeBE(const uint32& v); template void MemStreamWriter::writeBE(const uint16& v); template void MemStreamWriter::writeBE(const uint8& v); template<> void MemStreamWriter::writeBE(const std::string& v) { writeBE((uint32)v.size()); writeData(v.data(), v.size()); } // writeLE void template void MemStreamWriter::writeLE(const T& v) { m_buffer.resize(m_buffer.size() + sizeof(T)); uint8* p = m_buffer.data() + m_buffer.size() - sizeof(T); T tmp = _LE(v); std::memcpy(p, &tmp, sizeof(tmp)); } template void MemStreamWriter::writeLE(const uint64& v); template void MemStreamWriter::writeLE(const uint32& v);