CBOR hostmem WIP
This commit is contained in:
parent
c5b368ab3f
commit
b5859a109a
11 changed files with 2682 additions and 12 deletions
|
@ -11,6 +11,7 @@ enum lsnes_movie_tags
|
|||
TAG_CORE_VERSION = 0xe4344c7e,
|
||||
TAG_GAMENAME = 0xe80d6970,
|
||||
TAG_HOSTMEMORY = 0x3bf9d187,
|
||||
TAG_HOSTMEMORY_CBOR = 0xc8dab04b,
|
||||
TAG_MACRO = 0xd261338f,
|
||||
TAG_MOVIE = 0xf3dca44b,
|
||||
TAG_MOVIE_SRAM = 0xbbc824b7,
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "core/rom-small.hpp"
|
||||
#include "core/subtitles.hpp"
|
||||
#include "interface/romtype.hpp"
|
||||
#include "library/cbor.hpp"
|
||||
#include "library/rrdata.hpp"
|
||||
#include "library/zip.hpp"
|
||||
|
||||
|
@ -32,9 +33,13 @@ struct dynamic_state
|
|||
*/
|
||||
std::vector<char> savestate; //Savestate to load (if is_savestate is true).
|
||||
/**
|
||||
* Host memory (if is_savestate is true).
|
||||
* Legacy Host memory (if is_savestate is true).
|
||||
*/
|
||||
std::vector<char> host_memory;
|
||||
std::vector<char> host_memory_legacy;
|
||||
/**
|
||||
* CBOR host memory (if is_savestate is true).
|
||||
*/
|
||||
CBOR::item host_memory_cbor;
|
||||
/**
|
||||
* Screenshot (if is_savestate is true).
|
||||
*/
|
||||
|
|
601
include/library/cbor.hpp
Normal file
601
include/library/cbor.hpp
Normal file
|
@ -0,0 +1,601 @@
|
|||
#ifndef _library__cbor__hpp__included__
|
||||
#define _library__cbor__hpp__included__
|
||||
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
|
||||
namespace CBOR
|
||||
{
|
||||
enum tag_type
|
||||
{
|
||||
T_UNSIGNED,
|
||||
T_NEGATIVE,
|
||||
T_OCTETS,
|
||||
T_STRING,
|
||||
T_ARRAY,
|
||||
T_MAP,
|
||||
T_TAG,
|
||||
T_FLOAT,
|
||||
T_SIMPLE,
|
||||
T_BOOLEAN,
|
||||
T_NULL,
|
||||
T_UNDEFINED
|
||||
};
|
||||
|
||||
class item
|
||||
{
|
||||
public:
|
||||
struct _unsigned_tag
|
||||
{
|
||||
item operator()(uint64_t val) { return item(*this, val); }
|
||||
};
|
||||
struct _negative_tag
|
||||
{
|
||||
item operator()(uint64_t val) { return item(*this, val); }
|
||||
};
|
||||
struct _octets_tag
|
||||
{
|
||||
item operator()(const std::vector<uint8_t>& val) { return item(*this, val); }
|
||||
};
|
||||
struct _string_tag
|
||||
{
|
||||
item operator()(const std::string& val) { return item(*this, val); }
|
||||
};
|
||||
struct _array_tag
|
||||
{
|
||||
item operator()() { return item(*this); }
|
||||
};
|
||||
struct _map_tag
|
||||
{
|
||||
item operator()() { return item(*this); }
|
||||
};
|
||||
struct _tag_tag
|
||||
{
|
||||
item operator()(uint64_t tag, const item& inner) { return item(*this, tag, inner); }
|
||||
};
|
||||
struct _simple_tag
|
||||
{
|
||||
item operator()(uint8_t val) { return item(*this, val); }
|
||||
};
|
||||
struct _boolean_tag
|
||||
{
|
||||
item operator()(bool val) { return item(*this, val); }
|
||||
};
|
||||
struct _null_tag
|
||||
{
|
||||
item operator()() { return item(*this); }
|
||||
};
|
||||
struct _undefined_tag
|
||||
{
|
||||
item operator()() { return item(*this); }
|
||||
};
|
||||
struct _float_tag
|
||||
{
|
||||
item operator()(double val) { return item(*this, val); }
|
||||
};
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* The constructed value is default UNSINGED(0).
|
||||
*/
|
||||
item() throw();
|
||||
/**
|
||||
* Construct new UNSIGNED value.
|
||||
*
|
||||
* Parameter _tag: Dummy.
|
||||
* Parameter _value: The value.
|
||||
*/
|
||||
item(_unsigned_tag _tag, uint64_t _value) throw();
|
||||
/**
|
||||
* Construct new NEGATIVE value.
|
||||
*
|
||||
* Parameter _tag: Dummy.
|
||||
* Parameter _value: The value.
|
||||
*/
|
||||
item(_negative_tag _tag, uint64_t _value) throw();
|
||||
/**
|
||||
* Construct new OCTETS value.
|
||||
*
|
||||
* Parameter _value: The value.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
item(_octets_tag _tag, const std::vector<uint8_t>& _value) throw(std::bad_alloc);
|
||||
/**
|
||||
* Construct new STRING value.
|
||||
*
|
||||
* Parameter _value: The value.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
* Throws std::out_of_range: The value is not valid UTF-8.
|
||||
*/
|
||||
item(_string_tag _tag, const std::string& _value) throw(std::bad_alloc, std::out_of_range);
|
||||
/**
|
||||
* Construct new empty ARRAY value.
|
||||
*
|
||||
* Parameter _tag: Dummy.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
item(_array_tag _tag) throw(std::bad_alloc);
|
||||
/**
|
||||
* Construct new empty MAP value.
|
||||
*
|
||||
* Parameter _tag: Dummy.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
item(_map_tag _tag) throw(std::bad_alloc);
|
||||
/**
|
||||
* Construct new FLOAT value.
|
||||
*
|
||||
* Parameter _value: The value.
|
||||
*/
|
||||
item(_float_tag _tag, double _value) throw();
|
||||
/**
|
||||
* Construct new BOOLEAN value.
|
||||
*
|
||||
* Parameter _value: The value.
|
||||
*/
|
||||
item(_boolean_tag _tag, bool _value) throw();
|
||||
/**
|
||||
* Construct new empty SIMPLE value.
|
||||
*
|
||||
* Parameter _tag: Dummy.
|
||||
* Parameter _value: The value.
|
||||
* Throws std::out_of_range: SIMPLE values 23-31 are not allowed.
|
||||
*
|
||||
*/
|
||||
item(_simple_tag _tag, uint8_t _value) throw(std::out_of_range);
|
||||
/**
|
||||
* Construct new NULL value.
|
||||
*
|
||||
* Parameter _tag: Dummy.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
item(_null_tag _tag) throw();
|
||||
/**
|
||||
* Construct new UNDEFINED value.
|
||||
*
|
||||
* Parameter _tag: Dummy.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
item(_undefined_tag _tag) throw();
|
||||
/**
|
||||
* Construct new TAG value.
|
||||
*
|
||||
* Parameter _tag: Dummy.
|
||||
* Parameter _value: The tag value.
|
||||
* Parameter _inner: The inner value.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
item(_tag_tag _tag, uint64_t _value, const item& _inner) throw(std::bad_alloc);
|
||||
/**
|
||||
* Create item from CBOR.
|
||||
*
|
||||
* Parameter buffer: The buffer.
|
||||
* Parameter buffersize: The size of buffer in bytes.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
* Throws std::runtime_error: Bad CBOR.
|
||||
*/
|
||||
item(const char* buffer, size_t buffersize) throw(std::bad_alloc, std::runtime_error);
|
||||
/**
|
||||
* Copy constructor.
|
||||
*
|
||||
* Parameter tocopy: The element to copy.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
item(const item& tocopy) throw(std::bad_alloc);
|
||||
/**
|
||||
* Assignment operator.
|
||||
*
|
||||
* Parameter tocopy: The element to copy.
|
||||
* Returns: Reference to this.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
item& operator=(const item& tocopy) throw(std::bad_alloc);
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~item();
|
||||
/**
|
||||
* Serialize item as CBOR.
|
||||
*
|
||||
* Returns: The serialization.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
std::vector<char> serialize() const throw(std::bad_alloc);
|
||||
/**
|
||||
* Get type of item.
|
||||
*
|
||||
* Returns: The type of item.
|
||||
*/
|
||||
tag_type get_type() const throw() { return tag; }
|
||||
/**
|
||||
* Get size of CBOR serialization.
|
||||
*
|
||||
* Returns: The size in bytes.
|
||||
*/
|
||||
uint64_t get_size() const throw();
|
||||
/**
|
||||
* Get value of UNSIGNED.
|
||||
*
|
||||
* Returns: The value.
|
||||
* Throws std::domain_error: The CBOR item is not UNSIGNED.
|
||||
*/
|
||||
uint64_t get_unsigned() const throw(std::domain_error);
|
||||
/**
|
||||
* Set value as UNSIGNED.
|
||||
*
|
||||
* Parameter _value: The value.
|
||||
*/
|
||||
void set_unsigned(uint64_t _value) throw();
|
||||
/**
|
||||
* Get value of NEGATIVE.
|
||||
*
|
||||
* Returns: The value.
|
||||
* Throws std::domain_error: The CBOR item is not NEGATIVE.
|
||||
*/
|
||||
uint64_t get_negative() const throw(std::domain_error);
|
||||
/**
|
||||
* Set value as NEGATIVE.
|
||||
*
|
||||
* Parameter _value: The value.
|
||||
*/
|
||||
void set_negative(uint64_t _value) throw();
|
||||
/**
|
||||
* Get value of OCTETS.
|
||||
*
|
||||
* Returns: The value.
|
||||
* Throws std::domain_error: The CBOR item is not OCTETS.
|
||||
*/
|
||||
const std::vector<uint8_t>& get_octets() const throw(std::domain_error);
|
||||
/**
|
||||
* Set value as OCTETS.
|
||||
*
|
||||
* Parameter _value: The value.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
void set_octets(const std::vector<uint8_t>& _value) throw(std::bad_alloc);
|
||||
/**
|
||||
* Set value as OCTETS.
|
||||
*
|
||||
* Parameter _value: The value.
|
||||
* Parameter _valuelen: The length of value.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
void set_octets(const uint8_t* _value, size_t _valuelen) throw(std::bad_alloc);
|
||||
/**
|
||||
* Get value of STRING.
|
||||
*
|
||||
* Returns: The value.
|
||||
* Throws std::domain_error: The CBOR item is not STRING.
|
||||
*/
|
||||
const std::string& get_string() const throw(std::domain_error);
|
||||
/**
|
||||
* Set value as STRING.
|
||||
*
|
||||
* Parameter _value: The value.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
* Throws std::out_of_range: The value is not valid UTF-8.
|
||||
*/
|
||||
void set_string(const std::string& _value) throw(std::bad_alloc, std::out_of_range);
|
||||
/**
|
||||
* Set value to empty array.
|
||||
*
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
void set_array() throw(std::bad_alloc);
|
||||
/**
|
||||
* Get array length.
|
||||
*
|
||||
* Returns: The number of elements in array.
|
||||
* Throws std::domain_error: The CBOR item is not ARRAY.
|
||||
*/
|
||||
size_t get_array_size() const throw(std::domain_error);
|
||||
/**
|
||||
* Set array length.
|
||||
*
|
||||
* Parameter newsize: New size for array.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
* Throws std::domain_error: The CBOR item is not ARRAY.
|
||||
*/
|
||||
void set_array_size(size_t newsize) throw(std::bad_alloc, std::domain_error);
|
||||
/**
|
||||
* Read array element.
|
||||
*
|
||||
* Parameter index: The element index.
|
||||
* Returns: The array element.
|
||||
* Throws std::domain_error: The CBOR item is not ARRAY.
|
||||
* Throws std::out_of_range: Invalid array index.
|
||||
*/
|
||||
const item& operator[](size_t index) const throw(std::domain_error, std::out_of_range);
|
||||
/**
|
||||
* Read/Write array element.
|
||||
*
|
||||
* Parameter index: The element index.
|
||||
* Returns: The array element.
|
||||
* Throws std::domain_error: The CBOR item is not ARRAY.
|
||||
* Throws std::out_of_range: Invalid array index.
|
||||
*/
|
||||
item& operator[](size_t index) throw(std::domain_error, std::out_of_range);
|
||||
/**
|
||||
* Set value to empty map.
|
||||
*
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
void set_map() throw(std::bad_alloc);
|
||||
/**
|
||||
* Get map size.
|
||||
*
|
||||
* Returns: The number of elements in map.
|
||||
* Throws std::domain_error: The CBOR item is not MAP.
|
||||
*/
|
||||
size_t get_map_size() const throw(std::domain_error);
|
||||
/**
|
||||
* Read map element.
|
||||
*
|
||||
* Parameter index: The element key.
|
||||
* Returns: The map element.
|
||||
* Throws std::domain_error: The CBOR item is not MAP.
|
||||
* Throws std::out_of_range: Invalid map key.
|
||||
*/
|
||||
const item& get_map_lookup(const item& index) const throw(std::domain_error, std::out_of_range);
|
||||
/**
|
||||
* Read map element.
|
||||
*
|
||||
* Parameter index: The element key.
|
||||
* Returns: The map element.
|
||||
* Throws std::domain_error: The CBOR item is not MAP.
|
||||
* Throws std::out_of_range: Invalid map key.
|
||||
*/
|
||||
const item& operator[](const item& index) const throw(std::domain_error, std::out_of_range)
|
||||
{
|
||||
return get_map_lookup(index);
|
||||
}
|
||||
/**
|
||||
* Read/Write map element. If key does not exist, it is created.
|
||||
*
|
||||
* Parameter index: The element key.
|
||||
* Returns: The map element.
|
||||
* Throws std::domain_error: The CBOR item is not MAP.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
item& operator[](const item& index) throw(std::bad_alloc, std::domain_error);
|
||||
/**
|
||||
* Get iterator into internal map (begin).
|
||||
*
|
||||
* Returns: The iterator.
|
||||
* Throws std::domain_error: The CBOR item is not MAP.
|
||||
*/
|
||||
std::map<item, item>::iterator get_map_begin() throw(std::domain_error);
|
||||
/**
|
||||
* Get iterator into internal map (end).
|
||||
*
|
||||
* Returns: The iterator.
|
||||
* Throws std::domain_error: The CBOR item is not MAP.
|
||||
*/
|
||||
std::map<item, item>::iterator get_map_end() throw(std::domain_error);
|
||||
/**
|
||||
* Get iterator into internal map (begin).
|
||||
*
|
||||
* Returns: The iterator.
|
||||
* Throws std::domain_error: The CBOR item is not MAP.
|
||||
*/
|
||||
std::map<item, item>::const_iterator get_map_begin() const throw(std::domain_error);
|
||||
/**
|
||||
* Get iterator into internal map (end).
|
||||
*
|
||||
* Returns: The iterator.
|
||||
* Throws std::domain_error: The CBOR item is not MAP.
|
||||
*/
|
||||
std::map<item, item>::const_iterator get_map_end() const throw(std::domain_error);
|
||||
/**
|
||||
* Get tag value.
|
||||
*
|
||||
* Returns: The tag value.
|
||||
* Throws std::domain_error: The CBOR item is not TAG.
|
||||
*/
|
||||
uint64_t get_tag_number() const throw(std::domain_error);
|
||||
/**
|
||||
* Set tag value.
|
||||
*
|
||||
* Parameter _value: The new tag value.
|
||||
* Throws std::domain_error: The CBOR item is not TAG.
|
||||
*/
|
||||
void set_tag_number(uint64_t _value) throw(std::domain_error);
|
||||
/**
|
||||
* Get tag inner.
|
||||
*
|
||||
* Returns: The tag inner item.
|
||||
* Throws std::domain_error: The CBOR item is not TAG.
|
||||
*/
|
||||
const item& get_tag_inner() const throw(std::domain_error);
|
||||
/**
|
||||
* Get tag inner.
|
||||
*
|
||||
* Returns: The tag inner item.
|
||||
* Throws std::domain_error: The CBOR item is not TAG.
|
||||
*/
|
||||
item& get_tag_inner() throw(std::domain_error);
|
||||
/**
|
||||
* Tag item.
|
||||
*
|
||||
* The current item is moved to be inner item of tag.
|
||||
*
|
||||
* Parameter _value: The tag value.
|
||||
* Throws std::bad_alloc: Not enough memory.
|
||||
*/
|
||||
void tag_item(uint64_t _value) throw(std::bad_alloc);
|
||||
/**
|
||||
* Detag item.
|
||||
*
|
||||
* The inner item is moved to be this item.
|
||||
* Throws std::domain_error: The item is not TAG.
|
||||
*/
|
||||
void detag_item() throw(std::domain_error);
|
||||
/**
|
||||
* Get value of FLOAT.
|
||||
*
|
||||
* Returns: The value.
|
||||
* Throws std::domain_error: The CBOR item is not FLOAT.
|
||||
*/
|
||||
double get_float() const throw(std::domain_error);
|
||||
/**
|
||||
* Set value as FLOAT.
|
||||
*
|
||||
* Parameter _value: The value.
|
||||
*/
|
||||
void set_float(double _value) throw() { _set_float(*id(&_value)); }
|
||||
/**
|
||||
* Get value of SIMPLE.
|
||||
*
|
||||
* Types BOOLEAN, NULL and UNDEFINED convert into appropriate values (20-23).
|
||||
*
|
||||
* Returns: The value.
|
||||
* Throws std::domain_error: The CBOR item is not SIMPLE, BOOLEAN, NULL nor UNDEFINED.
|
||||
*/
|
||||
uint8_t get_simple() const throw(std::domain_error);
|
||||
/**
|
||||
* Set value as SIMPLE.
|
||||
*
|
||||
* Simple values 20-23 autoconvert to appropriate types.
|
||||
*
|
||||
* Parameter _value: The value.
|
||||
* Throws std::out_of_range: _value is 23-31 (those are not valid):
|
||||
*/
|
||||
void set_simple(uint8_t _value) throw(std::out_of_range);
|
||||
/**
|
||||
* Get value of BOOLEAN.
|
||||
*
|
||||
* Returns: The value.
|
||||
* Throws std::domain_error: The CBOR item is not BOOLEAN.
|
||||
*/
|
||||
bool get_boolean() const throw(std::domain_error);
|
||||
/**
|
||||
* Set value as BOOLEAN.
|
||||
*
|
||||
* Parameter _value: The value.
|
||||
*/
|
||||
void set_boolean(bool _value) throw();
|
||||
/**
|
||||
* Set value to NULL.
|
||||
*/
|
||||
void set_null() throw();
|
||||
/**
|
||||
* Set value to UNDEFINED.
|
||||
*/
|
||||
void set_undefined() throw();
|
||||
/**
|
||||
* Compare two items.
|
||||
*
|
||||
* Parameter a: The another item.
|
||||
* Returns: True if this is less than a, false otherwise.
|
||||
*/
|
||||
bool operator<(const item& a) const throw() { return cmp(*this, a) < 0; }
|
||||
/**
|
||||
* Compare two items.
|
||||
*
|
||||
* Parameter a: The another item.
|
||||
* Returns: True if this is less/equal to a, false otherwise.
|
||||
*/
|
||||
bool operator<=(const item& a) const throw() { return cmp(*this, a) <= 0; }
|
||||
/**
|
||||
* Compare two items.
|
||||
*
|
||||
* Parameter a: The another item.
|
||||
* Returns: True if this is equal to a, false otherwise.
|
||||
*/
|
||||
bool operator==(const item& a) const throw() { return cmp(*this, a) == 0; }
|
||||
/**
|
||||
* Compare two items.
|
||||
*
|
||||
* Parameter a: The another item.
|
||||
* Returns: True if this is not equal to a, false otherwise.
|
||||
*/
|
||||
bool operator!=(const item& a) const throw() { return cmp(*this, a) != 0; }
|
||||
/**
|
||||
* Compare two items.
|
||||
*
|
||||
* Parameter a: The another item.
|
||||
* Returns: True if this is greater/equal to a, false otherwise.
|
||||
*/
|
||||
bool operator>=(const item& a) const throw() { return cmp(*this, a) >= 0; }
|
||||
/**
|
||||
* Compare two items.
|
||||
*
|
||||
* Parameter a: The another item.
|
||||
* Returns: True if this is greater/equal to a, false otherwise.
|
||||
*/
|
||||
bool operator>(const item& a) const throw() { return cmp(*this, a) > 0; }
|
||||
/**
|
||||
* Swap two CBOR documents.
|
||||
*
|
||||
* Parameter a: The another document.
|
||||
*/
|
||||
void swap(item& a) throw();
|
||||
/**
|
||||
* Set cleanup callback.
|
||||
*
|
||||
* Pa
|
||||
*/
|
||||
private:
|
||||
typedef std::vector<uint8_t> octets_t;
|
||||
typedef std::string string_t;
|
||||
typedef std::map<size_t, item> array_t;
|
||||
typedef std::map<item, item> map_t;
|
||||
typedef std::pair<uint64_t, item> tag_t;
|
||||
|
||||
std::function<void(item*)>* cleanup_cb;
|
||||
tag_type tag;
|
||||
union {
|
||||
uint64_t integer;
|
||||
void* pointer;
|
||||
array_t* _debug_array;
|
||||
} value;
|
||||
void release_inner() throw();
|
||||
void replace_inner(tag_type _tag, uint64_t _integer) throw();
|
||||
void replace_inner(tag_type _tag, void* _pointer) throw();
|
||||
void _set_float(uint64_t _value) throw();
|
||||
void ctor(const char* b, size_t& p, size_t s);
|
||||
static int cmp(const item& a, const item& b) throw();
|
||||
static int cmp_nosize(const item& a, const item& b) throw();
|
||||
void _serialize(char*& out) const throw();
|
||||
void check_array() const throw(std::domain_error);
|
||||
void check_boolean() const throw(std::domain_error);
|
||||
void check_float() const throw(std::domain_error);
|
||||
void check_map() const throw(std::domain_error);
|
||||
void check_negative() const throw(std::domain_error);
|
||||
void check_octets() const throw(std::domain_error);
|
||||
void check_string() const throw(std::domain_error);
|
||||
void check_tag() const throw(std::domain_error);
|
||||
void check_unsigned() const throw(std::domain_error);
|
||||
uint8_t get_tagbyte() const throw();
|
||||
uint64_t get_arg() const throw();
|
||||
const uint64_t* id(const double* v) const { return reinterpret_cast<const uint64_t*>(v); }
|
||||
const double* idinv(const uint64_t* v) const { return reinterpret_cast<const double*>(v); }
|
||||
template<typename T> T& inner_as() throw() { return *reinterpret_cast<T*>(value.pointer); }
|
||||
template<typename T> const T& inner_as() const throw() { return *reinterpret_cast<const T*>(value.pointer); }
|
||||
template<typename T> void* inner_copy(const void* pointer)
|
||||
{
|
||||
return new T(*reinterpret_cast<const T*>(pointer));
|
||||
}
|
||||
};
|
||||
|
||||
extern item::_unsigned_tag integer;
|
||||
extern item::_negative_tag negative;
|
||||
extern item::_octets_tag octets;
|
||||
extern item::_string_tag string;
|
||||
extern item::_array_tag array;
|
||||
extern item::_map_tag map;
|
||||
extern item::_tag_tag tag;
|
||||
extern item::_simple_tag simple;
|
||||
extern item::_boolean_tag boolean;
|
||||
extern item::_null_tag null;
|
||||
extern item::_undefined_tag undefined;
|
||||
extern item::_float_tag floating;
|
||||
|
||||
extern thread_local std::function<void(item*)> dtor_cb;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -133,7 +133,11 @@ void moviefile::binary_io(int _stream, rrdata_set& rrd, bool as_state) throw(std
|
|||
dyn.savestate.size());
|
||||
|
||||
out.extension(TAG_HOSTMEMORY, [this](binarystream::output& s) {
|
||||
s.blob_implicit(this->dyn.host_memory);
|
||||
s.blob_implicit(this->dyn.host_memory_legacy);
|
||||
});
|
||||
out.extension(TAG_HOSTMEMORY_CBOR, [this](binarystream::output& s) {
|
||||
auto vec = this->dyn.host_memory_cbor.serialize();
|
||||
s.blob_implicit(vec);
|
||||
});
|
||||
|
||||
out.extension(TAG_SCREENSHOT, [this](binarystream::output& s) {
|
||||
|
@ -227,7 +231,15 @@ void moviefile::binary_io(int _stream, core_type& romtype) throw(std::bad_alloc,
|
|||
}},{TAG_GAMENAME, [this](binarystream::input& s) {
|
||||
this->gamename = s.string_implicit();
|
||||
}},{TAG_HOSTMEMORY, [this](binarystream::input& s) {
|
||||
s.blob_implicit(this->dyn.host_memory);
|
||||
s.blob_implicit(this->dyn.host_memory_legacy);
|
||||
}},{TAG_HOSTMEMORY_CBOR, [this](binarystream::input& s) {
|
||||
std::vector<char> raw;
|
||||
s.blob_implicit(raw);
|
||||
try {
|
||||
this->dyn.host_memory_cbor = CBOR::item(&raw[0], raw.size());
|
||||
} catch(std::exception& e) {
|
||||
(stringfmt() << "Error parsing CBOR hostdata: " << e.what()).throwex();
|
||||
}
|
||||
}},{TAG_MACRO, [this](binarystream::input& s) {
|
||||
uint64_t n = s.number();
|
||||
this->dyn.active_macros[s.string_implicit()] = n;
|
||||
|
|
|
@ -276,7 +276,16 @@ void moviefile::load(zip::reader& r, core_type& romtype) throw(std::bad_alloc, s
|
|||
r.read_numeric_file("lagcounter", dyn.lagged_frames, true);
|
||||
read_pollcounters(r, "pollcounters", dyn.pollcounters);
|
||||
if(r.has_member("hostmemory"))
|
||||
r.read_raw_file("hostmemory", dyn.host_memory);
|
||||
r.read_raw_file("hostmemory", dyn.host_memory_legacy);
|
||||
if(r.has_member("hostmemory.cbor")) {
|
||||
std::vector<char> tmp;
|
||||
r.read_raw_file("hostmemory.cbor", tmp);
|
||||
try {
|
||||
dyn.host_memory_cbor = CBOR::item((const char*)&tmp[0], tmp.size());
|
||||
} catch(std::exception& e) {
|
||||
(stringfmt() << "Error parsing CBOR hostdata: " << e.what()).throwex();
|
||||
}
|
||||
}
|
||||
r.read_raw_file("savestate", dyn.savestate);
|
||||
for(auto name : r)
|
||||
if(name.length() >= 5 && name.substr(0, 5) == "sram.")
|
||||
|
|
|
@ -178,7 +178,9 @@ void moviefile::save(zip::writer& w, rrdata_set& rrd, bool as_state) throw(std::
|
|||
w.write_numeric_file("saveframe", dyn.save_frame);
|
||||
w.write_numeric_file("lagcounter", dyn.lagged_frames);
|
||||
write_pollcounters(w, "pollcounters", dyn.pollcounters);
|
||||
w.write_raw_file("hostmemory", dyn.host_memory);
|
||||
w.write_raw_file("hostmemory", dyn.host_memory_legacy);
|
||||
auto cbor = dyn.host_memory_cbor.serialize();
|
||||
w.write_raw_file("hostmemory.cbor", cbor);
|
||||
w.write_raw_file("savestate", dyn.savestate);
|
||||
w.write_raw_file("screenshot", dyn.screenshot);
|
||||
for(auto i : dyn.sram)
|
||||
|
|
|
@ -422,7 +422,8 @@ void dynamic_state::clear(int64_t sec, int64_t ssec, const std::map<std::string,
|
|||
{
|
||||
sram = initsram;
|
||||
savestate.clear();
|
||||
host_memory.clear();
|
||||
host_memory_legacy.clear();
|
||||
host_memory_cbor.set_null();
|
||||
screenshot.clear();
|
||||
save_frame = 0;
|
||||
lagged_frames = 0;
|
||||
|
@ -438,7 +439,8 @@ void dynamic_state::swap(dynamic_state& s) throw()
|
|||
{
|
||||
std::swap(sram, s.sram);
|
||||
std::swap(savestate, s.savestate);
|
||||
std::swap(host_memory, s.host_memory);
|
||||
std::swap(host_memory_legacy, s.host_memory_legacy);
|
||||
host_memory_cbor.swap(s.host_memory_cbor);
|
||||
std::swap(screenshot, s.screenshot);
|
||||
std::swap(save_frame, s.save_frame);
|
||||
std::swap(lagged_frames, s.lagged_frames);
|
||||
|
|
2038
src/library/cbor.cpp
Normal file
2038
src/library/cbor.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -13,7 +13,7 @@ namespace
|
|||
|
||||
P(address);
|
||||
|
||||
auto& h = CORE().mlogic->get_mfile().dyn.host_memory;
|
||||
auto& h = CORE().mlogic->get_mfile().dyn.host_memory_legacy;
|
||||
if(address + sizeof(S) > h.size()) {
|
||||
L.pushboolean(0);
|
||||
return 1;
|
||||
|
@ -30,7 +30,7 @@ namespace
|
|||
|
||||
P(address, value);
|
||||
|
||||
auto& h = CORE().mlogic->get_mfile().dyn.host_memory;
|
||||
auto& h = CORE().mlogic->get_mfile().dyn.host_memory_legacy;
|
||||
if(address + sizeof(S) > h.size())
|
||||
h.resize(address + sizeof(S));
|
||||
serialization::write_endian<S>(&h[address], value, 1);
|
||||
|
|
|
@ -751,7 +751,7 @@ namespace
|
|||
if((size_t)(daddr + rows * size) < daddr)
|
||||
throw std::runtime_error("Size to copy too large");
|
||||
|
||||
auto& h = core.mlogic->get_mfile().dyn.host_memory;
|
||||
auto& h = core.mlogic->get_mfile().dyn.host_memory_legacy;
|
||||
if(daddr + rows * size > h.size()) {
|
||||
equals = false;
|
||||
h.resize(daddr + rows * size);
|
||||
|
|
|
@ -380,7 +380,7 @@ namespace
|
|||
throw std::runtime_error("Source out of range");
|
||||
|
||||
//Calculate new size of target.
|
||||
auto& h = core.mlogic->get_mfile().dyn.host_memory;
|
||||
auto& h = core.mlogic->get_mfile().dyn.host_memory_legacy;
|
||||
size_t rsize = size * rows;
|
||||
if(size && rsize / size != rows)
|
||||
throw std::runtime_error("Copy size out of range");
|
||||
|
|
Loading…
Add table
Reference in a new issue