22 using std::string_view;
26 template<
typename Derived>
29 string valueStr(value);
30 self().attribute(name, valueStr);
37 unsigned OutputArchiveBase2::generateID1(
const void* p)
40 assert(
"Can't serialize ID of object located on the stack" &&
48 unsigned OutputArchiveBase2::generateID2(
49 const void* p,
const std::type_info& typeInfo)
52 assert(
"Can't serialize ID of object located on the stack" &&
56 auto key = std::pair(p, std::type_index(typeInfo));
57 assert(!idMap.contains(key));
58 idMap.emplace_noDuplicateCheck(key, lastId);
62 unsigned OutputArchiveBase2::getID1(
const void* p)
64 auto* v =
lookup(polyIdMap, p);
67 unsigned OutputArchiveBase2::getID2(
68 const void* p,
const std::type_info& typeInfo)
70 auto* v =
lookup(idMap, std::pair(p, std::type_index(typeInfo)));
75 template<
typename Derived>
77 const char* tag,
const void* data_,
size_t len,
bool )
79 const auto* data =
static_cast<const uint8_t*
>(data_);
86 tmp = HexDump::encode(data, len);
89 tmp = Base64::encode(data, len);
91 encoding =
"gz-base64";
93 auto dstLen = uLongf(len + len / 1000 + 12 + 1);
95 if (compress2(buf.
data(), &dstLen,
96 reinterpret_cast<const Bytef*
>(data),
101 tmp = Base64::encode(buf.
data(), dstLen);
103 this->
self().beginTag(tag);
104 this->
self().attribute(
"encoding", encoding);
106 saver(this->
self(), tmp,
false);
107 this->
self().endTag(tag);
117 auto* v =
lookup(idMap,
id);
118 return v ? *v :
nullptr;
129 for (
const auto& [
id, pt] : idMap) {
130 if (pt == ptr)
return id;
135 template<
typename Derived>
137 const char* tag,
void* data,
size_t len,
bool )
139 this->
self().beginTag(tag);
141 this->
self().attribute(
"encoding", encoding);
143 string_view tmp = this->
self().loadStr();
144 this->
self().endTag(tag);
146 if (encoding ==
"gz-base64") {
147 auto [buf, bufSize] = Base64::decode(tmp);
148 auto dstLen = uLongf(len);
149 if ((uncompress(
reinterpret_cast<Bytef*
>(data), &dstLen,
150 reinterpret_cast<const Bytef*
>(buf.data()), uLong(bufSize))
155 }
else if (encoding ==
one_of(
"hex",
"base64")) {
156 bool ok = (encoding ==
"hex")
161 "Length of decoded blob different from "
162 "expected value (", len,
')');
165 throw XMLException(
"Unsupported encoding \"", encoding,
"\" for blob");
176 auto size = s.size();
180 memcpy(buf +
sizeof(
size), s.data(),
size);
207 return {
reinterpret_cast<const char*
>(p),
length};
219 size_t len,
bool diff)
223 auto deltaBlockIdx = unsigned(deltaBlocks.size());
225 deltaBlocks.push_back(diff
227 data,
static_cast<const uint8_t*
>(data), len)
229 data,
static_cast<const uint8_t*
>(data), len));
231 uint8_t* buf = buffer.
allocate(len);
232 memcpy(buf, data, len);
249 unsigned deltaBlockIdx;
load(deltaBlockIdx);
250 deltaBlocks[deltaBlockIdx]->apply(
static_cast<uint8_t*
>(data), len);
266 int duped_fd = dup(fileno(f.get()));
267 if (duped_fd == -1)
error();
268 file = gzdopen(duped_fd,
"wb9");
277 static constexpr std::string_view header =
278 "<?xml version=\"1.0\" ?>\n"
279 "<!DOCTYPE openmsx-serialize SYSTEM 'openmsx-serialize.dtd'>\n";
280 write(header.data(), header.size());
282 writer.begin(
"serial");
285 writer.attribute(
"platform", TARGET_PLATFORM);
292 writer.end(
"serial");
294 if (gzclose(file) != Z_OK) {
311 if ((gzwrite(file, buf,
unsigned(len)) == 0) && (len != 0)) {
318 if (gzputc(file, c) == -1) {
325 assert(condition); (void)condition;
334 throw XMLException(
"could not write \"", filename,
'"');
339 writer.data(std::string_view(&c, 1));
347 writer.data(b ?
"true" :
"false");
376 writer.attribute(name, str);
401 const auto* root = xmlDoc.
getRoot();
402 elems.emplace_back(root, root->getFirstChild());
408 throw XMLException(
"No child tags expected for primitive type");
420 std::istringstream is(str);
426 if (s ==
one_of(
"true",
"1")) {
428 }
else if (s ==
one_of(
"false",
"0")) {
448 template<std::
integral T>
static inline void fastAtoi(string_view str, T&
t)
453 size_t l = str.
size();
455 if constexpr (std::numeric_limits<T>::is_signed) {
463 unsigned d = str[i] -
'0';
464 if (d > 9) [[unlikely]] {
465 throw XMLException(
"Invalid integer: ", str);
469 if constexpr (std::numeric_limits<T>::is_signed) {
472 assert(!neg); (void)neg;
514 for (
auto&
e : elems) {
518 "\" found at location \"", path,
'\"');
520 elems.emplace_back(child, child->getFirstChild());
525 if (elem.getName() != tag) {
527 "\" not equal to begin tag \"", tag,
"\"");
538 throw XMLException(
"Missing attribute \"", name,
"\".");
540 t = attr->getValue();
bool contains(const K &k) const
iterator emplace_noDuplicateCheck(Args &&... args)
void attribute(const char *name, T &t)
Load/store an attribute from/in the archive.
std::shared_ptr< DeltaBlock > createNullDiff(const void *id, const uint8_t *data, size_t size)
std::shared_ptr< DeltaBlock > createNew(const void *id, const uint8_t *data, size_t size)
const T * data() const
Returns pointer to the start of the memory buffer.
MemBuffer< uint8_t > releaseBuffer(size_t &size)
void serialize_blob(const char *tag, const void *data, size_t len, bool diff=true)
void serialize_blob(const char *tag, const void *data, size_t len, bool diff=true)
uint8_t * allocate(size_t len)
Reserve space to insert the given number of bytes.
MemBuffer< uint8_t > release(size_t &size)
Release ownership of the buffer.
static std::string full()
const XMLElement * getRoot() const
void load(const std::string &filename, std::string_view systemID)
const XMLAttribute * findAttribute(std::string_view attrName) const
const XMLElement * findChild(std::string_view childName) const
std::string_view getData() const
void saveImpl(const T &t)
void check(bool condition) const
XmlOutputArchive(zstring_view filename)
void attributeImpl(const char *name, const T &t)
void endTag(const char *tag)
void beginTag(const char *tag)
void attribute(const char *name, const T &t)
void write(const char *buf, size_t len)
Like std::string_view, but with the extra guarantee that it refers to a zero-terminated string.
const Value * lookup(const hash_map< Key, Value, Hasher, Equal > &map, const Key2 &key)
bool decode_inplace(std::string_view input, uint8_t *output, size_t outSize)
bool decode_inplace(std::string_view input, uint8_t *output, size_t outSize)
T length(const vecN< N, T > &x)
std::string toString(time_t time)
FILE_t openFile(zstring_view filename, zstring_view mode)
Call fopen() in a platform-independent manner.
This file implemented 3 utility functions:
constexpr size_t SMALL_SIZE
constexpr const char *const filename
size_t size(std::string_view utf8)
void strAppend(std::string &result, Ts &&...ts)