From 2d2671a6866864bc8fb927a63e2d6eecddff3d6a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 1 Feb 2015 06:04:56 +0100 Subject: Use buffer API for chunk decompression --- src/Buffer.hpp | 4 ++++ src/World/Chunk.cpp | 19 ++++++++----------- src/World/Chunk.hpp | 5 +++-- src/World/Region.cpp | 2 +- 4 files changed, 16 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/Buffer.hpp b/src/Buffer.hpp index 3bf1ef0..9975dcb 100644 --- a/src/Buffer.hpp +++ b/src/Buffer.hpp @@ -56,6 +56,10 @@ public: Buffer(const uint8_t *data0, size_t len0) : data(data0), len(len0) {} + size_t getRemaining() const { + return len; + } + const uint8_t * get(size_t n) { if (n > len) throw std::runtime_error("Buffer::get(): buffer underrun"); diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index c2c59e0..915e5f3 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -39,7 +39,7 @@ namespace MinedMap { namespace World { -void Chunk::inflateChunk(uint8_t *buffer, size_t buflen) { +void Chunk::inflateChunk(Buffer buffer) { size_t outlen = 0; uint8_t *output = nullptr; @@ -48,8 +48,8 @@ void Chunk::inflateChunk(uint8_t *buffer, size_t buflen) { if (ret != Z_OK) throw std::runtime_error("inflateInit() failed"); - stream.next_in = buffer; - stream.avail_in = buflen; + stream.avail_in = buffer.getRemaining(); + stream.next_in = const_cast(buffer.get(stream.avail_in)); while (stream.avail_in) { outlen += 65536; @@ -111,19 +111,16 @@ uint8_t Chunk::getDataAt(const std::shared_ptr §ion, return (v & 0xf); } -Chunk::Chunk(uint8_t *buffer, size_t buflen) { - if (buflen < 5) - throw std::invalid_argument("short chunk"); +Chunk::Chunk(Buffer buffer) { + size_t size = buffer.get32(); - size_t size = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]; - if (size < 1 || size > (buflen - 4)) - throw std::invalid_argument("invalid chunk size"); + Buffer buffer2(buffer.get(size), size); - uint8_t format = buffer[4]; + uint8_t format = buffer2.get8(); if (format != 2) throw std::invalid_argument("unknown chunk format"); - inflateChunk(buffer+5, size-1); + inflateChunk(buffer2); parseChunk(); analyzeChunk(); } diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index 36628b4..d063d48 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -27,6 +27,7 @@ #pragma once +#include "../Buffer.hpp" #include "../UniqueCPtr.hpp" #include "../NBT/CompoundTag.hpp" #include "../NBT/ListTag.hpp" @@ -51,7 +52,7 @@ private: unsigned maxY; - void inflateChunk(uint8_t *data, size_t len); + void inflateChunk(Buffer buffer); void parseChunk(); void analyzeChunk(); @@ -66,7 +67,7 @@ private: uint8_t getDataAt(const std::shared_ptr §ion, size_t x, size_t y, size_t z); public: - Chunk(uint8_t *buffer, size_t buflen); + Chunk(Buffer buffer); const NBT::ListTag & getSections() const { return *sections; diff --git a/src/World/Region.cpp b/src/World/Region.cpp index 4f69059..fec732c 100644 --- a/src/World/Region.cpp +++ b/src/World/Region.cpp @@ -86,7 +86,7 @@ Region::Region(const char *filename) { uint8_t buffer[len * 4096]; file.read((char *)buffer, len * 4096); - chunks[x][z].reset(new Chunk(buffer, len * 4096)); + chunks[x][z].reset(new Chunk(Buffer(buffer, len * 4096))); i += len; c++; -- cgit v1.2.3