about summary refs log tree commit diff stats
path: root/update/library/trunk/xmlrpc/is_scalar.php
blob: c8f2bfcd46dc586fcfa9e1a8a674628fa92ff4f0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// Godot save decoder algorithm by Chris Souvey.

#include "godot_variant.h"

#include <algorithm>
#include <charconv>
#include <cstddef>
#include <fstream>
#include <string>
#include <tuple>
#include <variant>
#include <vector>

namespace {

uint16_t ReadUint16(std::basic_istream<char>& stream) {
  uint16_t result;
  stream
an> 2); return result; } uint32_t ReadUint32(std::basic_istream<char>& stream) { uint32_t result; stream.read(reinterpret_cast<char*>(&result), 4); return result; } GodotVariant ParseVariant(std::basic_istream<char>& stream) { uint16_t type = ReadUint16(stream); stream.ignore(2); switch (type) { case 1: { // bool bool boolval = (ReadUint32(stream) == 1); return {boolval}; } case 15: { // nodepath uint32_t name_length = ReadUint32(stream) & 0x7fffffff; uint32_t subname_length = ReadUint32(stream) & 0x7fffffff; uint32_t flags = ReadUint32(stream); std::vector<std::string> result; for (size_t i = 0; i < name_length + subname_length; i++) { uint32_t char_length = ReadUint32(stream); uint32_t padded_length = (char_length % 4 == 0) ? char_length : (char_length + 4 - (char_length % 4)); std::vector<char> next_bytes(padded_length); stream.read(next_bytes.data(), padded_length); std::string next_piece; std::copy(next_bytes.begin(), std::next(next_bytes.begin(), char_length), std::back_inserter(next_piece)); result.push_back(next_piece); } return {result}; } case 19: { // array uint32_t length = ReadUint32(stream) & 0x7fffffff; std::vector<GodotVariant> result; for (size_t i = 0; i < length; i++) { result.push_back(ParseVariant(stream)); } return {result}; } default: { // eh return {std::monostate{}}; } } } } // namespace GodotVariant ParseGodotFile(std::string filename) { std::ifstream file_stream(filename, std::ios_base::binary); file_stream.ignore(4); return ParseVariant(file_stream); }