Improvement to mapblock deserialisation

master
Unknown 2018-04-24 05:28:03 +02:00
parent 059675666f
commit 4f12a2b983
3 changed files with 27 additions and 23 deletions

View File

@ -89,9 +89,10 @@ inline void MapBlock::deserialize(const unsigned char *data, size_t length)
checkDataLimit("zlib", dataOffset, 3, length); checkDataLimit("zlib", dataOffset, 3, length);
ZlibDecompressor decompressor(data, length); ZlibDecompressor decompressor(data, length);
decompressor.setSeekPos(dataOffset); decompressor.setSeekPos(dataOffset);
mapData = decompressor.decompress(); mapData = decompressor.decompressNodes();
checkBlockNodeDataLimit(); checkBlockNodeDataLimit();
auto mapMetadata = decompressor.decompress(); decompressor.decompressVoid();
//auto mapMetadata = decompressor.decompress();
dataOffset = decompressor.seekPos(); dataOffset = decompressor.seekPos();
// Skip unused data // Skip unused data

View File

@ -28,13 +28,13 @@ public:
void reset() { void reset() {
nodeId2NodeName.clear(); nodeId2NodeName.clear();
mapData.clear(); //mapData.clear();
empty = true; empty = true;
version = 0; version = 0;
} }
const std::unordered_map<int, std::string> &getMappings() const { return nodeId2NodeName; } const std::unordered_map<int, std::string> &getMappings() const { return nodeId2NodeName; }
const BlockPos &getPos() const { return pos; } const BlockPos &getPos() const { return pos; }
const std::vector<unsigned char> &getMapData() const { return mapData; } //const std::vector<unsigned char> &getMapData() const { return mapData; }
int getVersion() const { return version; } int getVersion() const { return version; }
bool isEmpty() const { return empty; } bool isEmpty() const { return empty; }
@ -55,7 +55,8 @@ public:
private: private:
std::unordered_map<int, std::string> nodeId2NodeName; std::unordered_map<int, std::string> nodeId2NodeName;
std::vector<unsigned char> mapData; //std::vector<unsigned char> mapData;
std::array<unsigned char, ZlibDecompressor::nodesBlockSize> mapData;
BlockPos pos; BlockPos pos;
int version = 0; int version = 0;
bool empty = true; bool empty = true;

View File

@ -109,29 +109,31 @@ void ZlibDecompressor::decompressVoid()
std::array<unsigned char, ZlibDecompressor::nodesBlockSize> ZlibDecompressor::decompressNodes() std::array<unsigned char, ZlibDecompressor::nodesBlockSize> ZlibDecompressor::decompressNodes()
{ {
const unsigned char *data = m_data + m_seekPos; const unsigned char *data = m_data + m_seekPos;
const uLong size = static_cast<uLong>(m_size - m_seekPos); const std::size_t size = m_size - m_seekPos;
std::array<unsigned char, nodesBlockSize> nodes; std::array<unsigned char, ZlibDecompressor::nodesBlockSize> nodes;
uLong nodeSize = static_cast<uLong>(nodes.size());
int status = uncompress(nodes.data(), &nodeSize, data, size); z_stream strm;
switch (status) strm.zalloc = Z_NULL;
{ strm.zfree = Z_NULL;
case Z_MEM_ERROR: strm.opaque = Z_NULL;
throw DecompressError("not enough Memory"); strm.next_in = Z_NULL;
break; strm.avail_in = static_cast<uInt>(size);
case Z_BUF_ERROR:
throw DecompressError("Mapblock too big, buffer too small"); if (inflateInit(&strm) != Z_OK) {
break; throw DecompressError(strm.msg);
case Z_DATA_ERROR:
throw DecompressError("Data Error: Mapblock corrupted");
break;
case Z_OK:
default:
break;
} }
strm.next_in = const_cast<unsigned char *>(data);
strm.avail_out = static_cast<uInt>(nodes.size());
strm.next_out = nodes.data();
//inflate(&strm, Z_NO_FLUSH); // TODO: Test use of Z_FINISH
if (inflate(&strm, Z_FINISH) != Z_STREAM_END) {
throw DecompressError(strm.msg);
}
m_seekPos += strm.next_in - data;
(void)inflateEnd(&strm);
return nodes; return nodes;
} }