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);
ZlibDecompressor decompressor(data, length);
decompressor.setSeekPos(dataOffset);
mapData = decompressor.decompress();
mapData = decompressor.decompressNodes();
checkBlockNodeDataLimit();
auto mapMetadata = decompressor.decompress();
decompressor.decompressVoid();
//auto mapMetadata = decompressor.decompress();
dataOffset = decompressor.seekPos();
// Skip unused data

View File

@ -28,13 +28,13 @@ public:
void reset() {
nodeId2NodeName.clear();
mapData.clear();
//mapData.clear();
empty = true;
version = 0;
}
const std::unordered_map<int, std::string> &getMappings() const { return nodeId2NodeName; }
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; }
bool isEmpty() const { return empty; }
@ -55,7 +55,8 @@ public:
private:
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;
int version = 0;
bool empty = true;

View File

@ -109,29 +109,31 @@ void ZlibDecompressor::decompressVoid()
std::array<unsigned char, ZlibDecompressor::nodesBlockSize> ZlibDecompressor::decompressNodes()
{
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;
uLong nodeSize = static_cast<uLong>(nodes.size());
std::array<unsigned char, ZlibDecompressor::nodesBlockSize> nodes;
int status = uncompress(nodes.data(), &nodeSize, data, size);
switch (status)
{
case Z_MEM_ERROR:
throw DecompressError("not enough Memory");
break;
case Z_BUF_ERROR:
throw DecompressError("Mapblock too big, buffer too small");
break;
case Z_DATA_ERROR:
throw DecompressError("Data Error: Mapblock corrupted");
break;
case Z_OK:
default:
break;
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.next_in = Z_NULL;
strm.avail_in = static_cast<uInt>(size);
if (inflateInit(&strm) != Z_OK) {
throw DecompressError(strm.msg);
}
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;
}