summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2015-02-01 04:14:42 +0100
committerMatthias Schiffer <mschiffer@universe-factory.net>2015-02-01 04:14:42 +0100
commit8a8a41a800dfe9bdcab934d6b53d9c6defd4a457 (patch)
treef9d40b96ee3413cbe7a402a4b4abad607b2a1c7c
parentfc1fc8fbbc9dd9534f40de348210ea66b6defe42 (diff)
downloadMinedMap-8a8a41a800dfe9bdcab934d6b53d9c6defd4a457.tar
MinedMap-8a8a41a800dfe9bdcab934d6b53d9c6defd4a457.zip
Parse chunk data on demand
-rw-r--r--src/Buffer.hpp43
-rw-r--r--src/NBT/ByteArrayTag.hpp20
-rw-r--r--src/NBT/ByteTag.hpp2
-rw-r--r--src/NBT/DoubleTag.hpp13
-rw-r--r--src/NBT/FloatTag.hpp9
-rw-r--r--src/NBT/IntArrayTag.hpp20
-rw-r--r--src/NBT/IntTag.hpp9
-rw-r--r--src/NBT/ListTag.hpp5
-rw-r--r--src/NBT/LongTag.hpp13
-rw-r--r--src/NBT/ShortTag.hpp7
-rw-r--r--src/NBT/StringTag.hpp13
-rw-r--r--src/NBT/Tag.cpp9
-rw-r--r--src/World/Chunk.cpp1
-rw-r--r--src/World/Chunk.hpp2
14 files changed, 71 insertions, 95 deletions
diff --git a/src/Buffer.hpp b/src/Buffer.hpp
index c7fa9c7..3bf1ef0 100644
--- a/src/Buffer.hpp
+++ b/src/Buffer.hpp
@@ -40,34 +40,47 @@ private:
size_t len;
public:
- Buffer(const uint8_t *data0, size_t len0) : data(data0), len(len0) {}
+ static uint16_t parse16(const uint8_t *buf) {
+ return (buf[0] << 8) | buf[1];
+ }
- uint8_t get() {
- if (!len)
- throw std::runtime_error("Buffer::get(): buffer underrun");
+ 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]);
+ }
- data++;
- len--;
- return data[-1];
+ 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]);
}
- std::string getString(size_t n) {
+
+ Buffer(const uint8_t *data0, size_t len0) : data(data0), len(len0) {}
+
+ 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");
+ uint8_t get8() {
+ return *get(1);
+ }
- data += n;
- len -= n;
- std::memcpy(buf, data - n, n);
+ uint16_t get16() {
+ return parse16(get(2));
+ }
+
+ uint32_t get32() {
+ return parse32(get(4));
+ }
+
+ uint64_t get64() {
+ return parse64(get(8));
}
+
};
}
diff --git a/src/NBT/ByteArrayTag.hpp b/src/NBT/ByteArrayTag.hpp
index ee0d7d1..2081759 100644
--- a/src/NBT/ByteArrayTag.hpp
+++ b/src/NBT/ByteArrayTag.hpp
@@ -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];
+ }
};
}
diff --git a/src/NBT/ByteTag.hpp b/src/NBT/ByteTag.hpp
index cc4aba9..64bdaa1 100644
--- a/src/NBT/ByteTag.hpp
+++ b/src/NBT/ByteTag.hpp
@@ -39,7 +39,7 @@ private:
uint8_t value;
ByteTag(Buffer *buffer) {
- value = buffer->get();
+ value = buffer->get8();
}
public:
diff --git a/src/NBT/DoubleTag.hpp b/src/NBT/DoubleTag.hpp
index 327dcf5..dace193 100644
--- a/src/NBT/DoubleTag.hpp
+++ b/src/NBT/DoubleTag.hpp
@@ -36,17 +36,10 @@ class DoubleTag : public Tag {
private:
friend class Tag;
+ const uint8_t *ptr;
+
DoubleTag(Buffer *buffer) {
- uint64_t value;
-
- 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:
diff --git a/src/NBT/FloatTag.hpp b/src/NBT/FloatTag.hpp
index 8859f94..ad9cc64 100644
--- a/src/NBT/FloatTag.hpp
+++ b/src/NBT/FloatTag.hpp
@@ -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:
diff --git a/src/NBT/IntArrayTag.hpp b/src/NBT/IntArrayTag.hpp
index e9b0d3d..22f84b2 100644
--- a/src/NBT/IntArrayTag.hpp
+++ b/src/NBT/IntArrayTag.hpp
@@ -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:
diff --git a/src/NBT/IntTag.hpp b/src/NBT/IntTag.hpp
index 9e7b3db..b0337c7 100644
--- a/src/NBT/IntTag.hpp
+++ b/src/NBT/IntTag.hpp
@@ -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);
}
};
diff --git a/src/NBT/ListTag.hpp b/src/NBT/ListTag.hpp
index 1a48062..757a0aa 100644
--- a/src/NBT/ListTag.hpp
+++ b/src/NBT/ListTag.hpp
@@ -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);
diff --git a/src/NBT/LongTag.hpp b/src/NBT/LongTag.hpp
index 6cd5f8f..b07bc1a 100644
--- a/src/NBT/LongTag.hpp
+++ b/src/NBT/LongTag.hpp
@@ -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);
}
};
diff --git a/src/NBT/ShortTag.hpp b/src/NBT/ShortTag.hpp
index a44ca9b..7415317 100644
--- a/src/NBT/ShortTag.hpp
+++ b/src/NBT/ShortTag.hpp
@@ -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);
}
};
diff --git a/src/NBT/StringTag.hpp b/src/NBT/StringTag.hpp
index 0144081..42432f2 100644
--- a/src/NBT/StringTag.hpp
+++ b/src/NBT/StringTag.hpp
@@ -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;
- }
};
}
diff --git a/src/NBT/Tag.cpp b/src/NBT/Tag.cpp
index 1829dc5..c75cb9f 100644
--- a/src/NBT/Tag.cpp
+++ b/src/NBT/Tag.cpp
@@ -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));
}
diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp
index fb46466..db286ee 100644
--- a/src/World/Chunk.cpp
+++ b/src/World/Chunk.cpp
@@ -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);
diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp
index 3ed6cf4..5b0ecdb 100644
--- a/src/World/Chunk.hpp
+++ b/src/World/Chunk.hpp
@@ -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;