mirror of
https://github.com/neocturne/MinedMap.git
synced 2025-03-05 17:44:52 +01:00
Parse chunk data on demand
This commit is contained in:
parent
fc1fc8fbbc
commit
8a8a41a800
14 changed files with 74 additions and 98 deletions
|
@ -40,34 +40,47 @@ private:
|
|||
size_t len;
|
||||
|
||||
public:
|
||||
static uint16_t parse16(const uint8_t *buf) {
|
||||
return (buf[0] << 8) | buf[1];
|
||||
}
|
||||
|
||||
static uint32_t parse32(const uint8_t *buf) {
|
||||
return (uint32_t(buf[0]) << 24) | (uint32_t(buf[1]) << 16) | (uint32_t(buf[2]) << 8) | uint32_t(buf[3]);
|
||||
}
|
||||
|
||||
static uint64_t parse64(const uint8_t *buf) {
|
||||
return (uint64_t(buf[0]) << 56) | (uint64_t(buf[1]) << 48) | (uint64_t(buf[2]) << 40) | (uint64_t(buf[3]) << 32)
|
||||
| (uint64_t(buf[4]) << 24) | (uint64_t(buf[5]) << 16) | (uint64_t(buf[6]) << 8) | uint64_t(buf[7]);
|
||||
}
|
||||
|
||||
|
||||
Buffer(const uint8_t *data0, size_t len0) : data(data0), len(len0) {}
|
||||
|
||||
uint8_t get() {
|
||||
if (!len)
|
||||
throw std::runtime_error("Buffer::get(): buffer underrun");
|
||||
|
||||
data++;
|
||||
len--;
|
||||
return data[-1];
|
||||
}
|
||||
|
||||
std::string getString(size_t n) {
|
||||
const uint8_t * get(size_t n) {
|
||||
if (n > len)
|
||||
throw std::runtime_error("Buffer::get(): buffer underrun");
|
||||
|
||||
data += n;
|
||||
len -= n;
|
||||
return std::string(reinterpret_cast<const char *>(data - n), n);
|
||||
return (data - n);
|
||||
}
|
||||
|
||||
void getData(void *buf, size_t n) {
|
||||
if (n > len)
|
||||
throw std::runtime_error("Buffer::get(): buffer underrun");
|
||||
|
||||
data += n;
|
||||
len -= n;
|
||||
std::memcpy(buf, data - n, n);
|
||||
uint8_t get8() {
|
||||
return *get(1);
|
||||
}
|
||||
|
||||
uint16_t get16() {
|
||||
return parse16(get(2));
|
||||
}
|
||||
|
||||
uint32_t get32() {
|
||||
return parse32(get(4));
|
||||
}
|
||||
|
||||
uint64_t get64() {
|
||||
return parse64(get(8));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -38,22 +38,26 @@ class ByteArrayTag : public Tag {
|
|||
private:
|
||||
friend class Tag;
|
||||
|
||||
std::vector<uint8_t> value;
|
||||
uint32_t len;
|
||||
const uint8_t *value;
|
||||
|
||||
ByteArrayTag(Buffer *buffer) {
|
||||
uint32_t len = uint32_t(buffer->get()) << 24;
|
||||
len |= uint32_t(buffer->get()) << 16;
|
||||
len |= uint32_t(buffer->get()) << 8;
|
||||
len |= uint32_t(buffer->get());
|
||||
|
||||
value.resize(len);
|
||||
buffer->getData(value.data(), len);
|
||||
len = buffer->get32();
|
||||
value = buffer->get(len);
|
||||
}
|
||||
|
||||
public:
|
||||
virtual Type getType() const {
|
||||
return Type::ByteArray;
|
||||
}
|
||||
|
||||
uint32_t getLength() const {
|
||||
return len;
|
||||
}
|
||||
|
||||
const uint8_t & operator[](size_t i) const {
|
||||
return value[i];
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ private:
|
|||
uint8_t value;
|
||||
|
||||
ByteTag(Buffer *buffer) {
|
||||
value = buffer->get();
|
||||
value = buffer->get8();
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
@ -36,17 +36,10 @@ class DoubleTag : public Tag {
|
|||
private:
|
||||
friend class Tag;
|
||||
|
||||
DoubleTag(Buffer *buffer) {
|
||||
uint64_t value;
|
||||
const uint8_t *ptr;
|
||||
|
||||
value = uint64_t(buffer->get()) << 56;
|
||||
value |= uint64_t(buffer->get()) << 48;
|
||||
value |= uint64_t(buffer->get()) << 40;
|
||||
value |= uint64_t(buffer->get()) << 32;
|
||||
value |= uint64_t(buffer->get()) << 24;
|
||||
value |= uint64_t(buffer->get()) << 16;
|
||||
value |= uint64_t(buffer->get()) << 8;
|
||||
value |= uint64_t(buffer->get());
|
||||
DoubleTag(Buffer *buffer) {
|
||||
ptr = buffer->get(8);
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
@ -36,13 +36,10 @@ class FloatTag : public Tag {
|
|||
private:
|
||||
friend class Tag;
|
||||
|
||||
FloatTag(Buffer *buffer) {
|
||||
uint32_t value;
|
||||
const uint8_t *ptr;
|
||||
|
||||
value = uint32_t(buffer->get()) << 24;
|
||||
value |= uint32_t(buffer->get()) << 16;
|
||||
value |= uint32_t(buffer->get()) << 8;
|
||||
value |= uint32_t(buffer->get());
|
||||
FloatTag(Buffer *buffer) {
|
||||
ptr = buffer->get(4);
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
@ -38,24 +38,12 @@ class IntArrayTag : public Tag {
|
|||
private:
|
||||
friend class Tag;
|
||||
|
||||
std::vector<uint32_t> value;
|
||||
uint32_t len;
|
||||
const uint8_t *ptr;
|
||||
|
||||
IntArrayTag(Buffer *buffer) {
|
||||
uint32_t len = uint32_t(buffer->get()) << 24;
|
||||
len |= uint32_t(buffer->get()) << 16;
|
||||
len |= uint32_t(buffer->get()) << 8;
|
||||
len |= uint32_t(buffer->get());
|
||||
|
||||
value.resize(len);
|
||||
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
uint32_t v = uint32_t(buffer->get()) << 24;
|
||||
v |= uint32_t(buffer->get()) << 16;
|
||||
v |= uint32_t(buffer->get()) << 8;
|
||||
v |= uint32_t(buffer->get());
|
||||
|
||||
value[i] = v;
|
||||
}
|
||||
len = buffer->get32();
|
||||
ptr = buffer->get(4*len);
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
@ -36,13 +36,10 @@ class IntTag : public Tag {
|
|||
private:
|
||||
friend class Tag;
|
||||
|
||||
uint32_t value;
|
||||
const uint8_t *ptr;
|
||||
|
||||
IntTag(Buffer *buffer) {
|
||||
value = uint32_t(buffer->get()) << 24;
|
||||
value |= uint32_t(buffer->get()) << 16;
|
||||
value |= uint32_t(buffer->get()) << 8;
|
||||
value |= uint32_t(buffer->get());
|
||||
ptr = buffer->get(4);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -51,7 +48,7 @@ public:
|
|||
}
|
||||
|
||||
uint32_t getValue() const {
|
||||
return value;
|
||||
return Buffer::parse32(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -53,10 +53,7 @@ private:
|
|||
Type type;
|
||||
|
||||
ListTag(Type type0, Buffer *buffer) : type(type0) {
|
||||
uint32_t len = uint32_t(buffer->get()) << 24;
|
||||
len |= uint32_t(buffer->get()) << 16;
|
||||
len |= uint32_t(buffer->get()) << 8;
|
||||
len |= uint32_t(buffer->get());
|
||||
uint32_t len = buffer->get32();
|
||||
|
||||
this->resize(len);
|
||||
|
||||
|
|
|
@ -36,17 +36,10 @@ class LongTag : public Tag {
|
|||
private:
|
||||
friend class Tag;
|
||||
|
||||
uint64_t value;
|
||||
const uint8_t *ptr;
|
||||
|
||||
LongTag(Buffer *buffer) {
|
||||
value = uint64_t(buffer->get()) << 56;
|
||||
value |= uint64_t(buffer->get()) << 48;
|
||||
value |= uint64_t(buffer->get()) << 40;
|
||||
value |= uint64_t(buffer->get()) << 32;
|
||||
value |= uint64_t(buffer->get()) << 24;
|
||||
value |= uint64_t(buffer->get()) << 16;
|
||||
value |= uint64_t(buffer->get()) << 8;
|
||||
value |= uint64_t(buffer->get());
|
||||
ptr = buffer->get(8);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -55,7 +48,7 @@ public:
|
|||
}
|
||||
|
||||
uint64_t getValue() const {
|
||||
return value;
|
||||
return Buffer::parse64(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -36,11 +36,10 @@ class ShortTag : public Tag {
|
|||
private:
|
||||
friend class Tag;
|
||||
|
||||
uint16_t value;
|
||||
const uint8_t *ptr;
|
||||
|
||||
ShortTag(Buffer *buffer) {
|
||||
value = buffer->get() << 8;
|
||||
value |= buffer->get();
|
||||
ptr = buffer->get(2);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -49,7 +48,7 @@ public:
|
|||
}
|
||||
|
||||
uint16_t getValue() const {
|
||||
return value;
|
||||
return Buffer::parse16(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -36,23 +36,18 @@ class StringTag : public Tag {
|
|||
private:
|
||||
friend class Tag;
|
||||
|
||||
std::string value;
|
||||
uint16_t len;
|
||||
const uint8_t *ptr;
|
||||
|
||||
StringTag(Buffer *buffer) {
|
||||
uint16_t len = buffer->get() << 8;
|
||||
len |= buffer->get();
|
||||
|
||||
value = buffer->getString(len);
|
||||
len = buffer->get16();
|
||||
ptr = buffer->get(len);
|
||||
}
|
||||
|
||||
public:
|
||||
virtual Type getType() const {
|
||||
return Type::String;
|
||||
}
|
||||
|
||||
const std::string & getValue() const {
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ std::shared_ptr<const Tag> Tag::readTag(Type type, Buffer *buffer) {
|
|||
}
|
||||
|
||||
std::shared_ptr<const Tag> Tag::readList(Buffer *buffer) {
|
||||
Type type = static_cast<Type>(buffer->get());
|
||||
Type type = static_cast<Type>(buffer->get8());
|
||||
|
||||
switch (type) {
|
||||
case Type::End:
|
||||
|
@ -135,13 +135,12 @@ std::shared_ptr<const Tag> Tag::readList(Buffer *buffer) {
|
|||
}
|
||||
|
||||
std::pair<std::string, std::shared_ptr<const Tag>> Tag::readNamedTag(Buffer *buffer) {
|
||||
Type type = static_cast<Type>(buffer->get());
|
||||
Type type = static_cast<Type>(buffer->get8());
|
||||
if (type == Type::End)
|
||||
return std::make_pair("", std::shared_ptr<EndTag>(new EndTag()));
|
||||
|
||||
uint16_t len = buffer->get() << 8;
|
||||
len |= buffer->get();
|
||||
std::string name = buffer->getString(len);
|
||||
uint16_t len = buffer->get16();
|
||||
std::string name(reinterpret_cast<const char*>(buffer->get(len)), len);
|
||||
|
||||
return std::make_pair(name, readTag(type, buffer));
|
||||
}
|
||||
|
|
|
@ -82,7 +82,6 @@ Chunk::Chunk(uint8_t *buffer, size_t buflen) {
|
|||
if (format != 2)
|
||||
throw std::invalid_argument("unknown chunk format");
|
||||
|
||||
UniqueCPtr<uint8_t[]> data;
|
||||
size_t len;
|
||||
std::tie(data, len) = inflateChunk(buffer+5, size-1);
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ public:
|
|||
static const size_t SIZE = 16;
|
||||
|
||||
private:
|
||||
UniqueCPtr<uint8_t[]> data;
|
||||
|
||||
static std::pair<UniqueCPtr<uint8_t[]>, size_t> inflateChunk(uint8_t *data, size_t len);
|
||||
|
||||
std::shared_ptr<const NBT::ListTag<NBT::CompoundTag>> sections;
|
||||
|
|
Loading…
Add table
Reference in a new issue