This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#include "Compression.h"
|
||||
|
||||
#include "VarInt.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <zlib.h>
|
||||
|
||||
@@ -33,10 +35,7 @@ DataBuffer Compress(const DataBuffer& buffer) {
|
||||
|
||||
if (buffer.GetSize() < COMPRESSION_THRESHOLD) {
|
||||
// Don't compress since it's a small packet
|
||||
std::uint64_t compressedDataLength = 0;
|
||||
std::uint64_t packetLength = compressedDataLength + buffer.GetSize();
|
||||
|
||||
packet << packetLength;
|
||||
VarInt compressedDataLength = 0;
|
||||
packet << compressedDataLength;
|
||||
packet << buffer;
|
||||
return packet;
|
||||
@@ -44,22 +43,19 @@ DataBuffer Compress(const DataBuffer& buffer) {
|
||||
|
||||
DataBuffer compressedData = Deflate(buffer.data(), buffer.GetSize());
|
||||
|
||||
std::uint64_t uncompressedDataLength = buffer.GetSize();
|
||||
std::uint64_t packetLength = uncompressedDataLength + compressedData.GetSize();
|
||||
|
||||
packet << packetLength;
|
||||
VarInt uncompressedDataLength = buffer.GetSize();
|
||||
packet << uncompressedDataLength;
|
||||
packet.WriteSome(compressedData.data(), compressedData.GetSize());
|
||||
return packet;
|
||||
}
|
||||
|
||||
DataBuffer Decompress(DataBuffer& buffer, std::uint64_t packetLength) {
|
||||
std::uint64_t uncompressedLength;
|
||||
VarInt uncompressedLength;
|
||||
buffer >> uncompressedLength;
|
||||
|
||||
std::uint64_t compressedLength = packetLength - uncompressedLength;
|
||||
std::uint64_t compressedLength = packetLength - uncompressedLength.GetSerializedLength();
|
||||
|
||||
if (uncompressedLength == 0) {
|
||||
if (uncompressedLength.GetValue() == 0) {
|
||||
// Data already uncompressed. Nothing to do
|
||||
DataBuffer ret;
|
||||
buffer.ReadSome(ret, compressedLength);
|
||||
@@ -68,12 +64,5 @@ DataBuffer Decompress(DataBuffer& buffer, std::uint64_t packetLength) {
|
||||
|
||||
assert(buffer.GetReadOffset() + compressedLength <= buffer.GetSize());
|
||||
|
||||
return Inflate(buffer.data() + buffer.GetReadOffset(), compressedLength, uncompressedLength);
|
||||
}
|
||||
|
||||
DataBuffer Decompress(DataBuffer& buffer) {
|
||||
std::uint64_t packetLength;
|
||||
buffer >> packetLength;
|
||||
|
||||
return Decompress(buffer, packetLength);
|
||||
return Inflate(buffer.data() + buffer.GetReadOffset(), compressedLength, uncompressedLength.GetValue());
|
||||
}
|
||||
|
||||
@@ -14,13 +14,6 @@
|
||||
*/
|
||||
DataBuffer Compress(const DataBuffer& buffer);
|
||||
|
||||
/**
|
||||
* \brief Reads the packet lenght and uncompress it
|
||||
* \param buffer the data to uncompress
|
||||
* \return the uncompressed data
|
||||
*/
|
||||
DataBuffer Decompress(DataBuffer& buffer);
|
||||
|
||||
/**
|
||||
* \brief Uncompress some data
|
||||
* \param buffer the data to uncompress
|
||||
|
||||
48
src/Common/VarInt.cpp
Normal file
48
src/Common/VarInt.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "VarInt.h"
|
||||
|
||||
#include "DataBuffer.h"
|
||||
#include <stdexcept>
|
||||
|
||||
static constexpr int SEGMENT_BITS = 0x7F;
|
||||
static constexpr int CONTINUE_BIT = 0x80;
|
||||
|
||||
std::size_t VarInt::GetSerializedLength() const {
|
||||
DataBuffer buffer;
|
||||
buffer << *this;
|
||||
return buffer.GetSize();
|
||||
}
|
||||
|
||||
DataBuffer& operator<<(DataBuffer& out, const VarInt& var) {
|
||||
std::uint64_t value = var.m_Value;
|
||||
while (true) {
|
||||
if ((value & ~static_cast<std::uint64_t>(SEGMENT_BITS)) == 0) {
|
||||
out << static_cast<std::uint8_t>(value);
|
||||
return out;
|
||||
}
|
||||
|
||||
out << static_cast<std::uint8_t>((value & SEGMENT_BITS) | CONTINUE_BIT);
|
||||
|
||||
value >>= 7;
|
||||
}
|
||||
}
|
||||
|
||||
DataBuffer& operator>>(DataBuffer& in, VarInt& var) {
|
||||
var.m_Value = 0;
|
||||
unsigned int position = 0;
|
||||
std::uint8_t currentByte;
|
||||
|
||||
while (true) {
|
||||
in.ReadSome(¤tByte, 1);
|
||||
var.m_Value |= static_cast<std::uint64_t>(currentByte & SEGMENT_BITS) << position;
|
||||
|
||||
if ((currentByte & CONTINUE_BIT) == 0)
|
||||
break;
|
||||
|
||||
position += 7;
|
||||
|
||||
if (position >= 8 * sizeof(var.m_Value))
|
||||
throw std::runtime_error("VarInt is too big");
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
54
src/Common/VarInt.h
Normal file
54
src/Common/VarInt.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* \file VarInt.h
|
||||
* \brief File containing the blitz::VarInt class
|
||||
*/
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
class DataBuffer;
|
||||
|
||||
/**
|
||||
* \class VarInt
|
||||
* \brief Variable-length format such that smaller numbers use fewer bytes.
|
||||
*/
|
||||
class VarInt {
|
||||
private:
|
||||
std::uint64_t m_Value;
|
||||
|
||||
public:
|
||||
VarInt() : m_Value(0) {}
|
||||
/**
|
||||
* \brief Construct a variable integer from a value
|
||||
* \param value The value of the variable integer
|
||||
*/
|
||||
VarInt(std::uint64_t value) : m_Value(value) {}
|
||||
|
||||
/**
|
||||
* \brief Get the value of the variable integer
|
||||
*/
|
||||
std::uint64_t GetValue() const {
|
||||
return m_Value;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the length of the serialized variable integer
|
||||
*/
|
||||
std::size_t GetSerializedLength() const;
|
||||
|
||||
/**
|
||||
* \brief Serialize the variable integer
|
||||
* \param out The buffer to write the serialized variable integer to
|
||||
* \param var The variable integer to serialize
|
||||
*/
|
||||
friend DataBuffer& operator<<(DataBuffer& out, const VarInt& var);
|
||||
|
||||
/**
|
||||
* \brief Deserialize the variable integer
|
||||
* \param in The buffer to read the serialized variable integer from
|
||||
* \param var The variable integer to deserialize
|
||||
*/
|
||||
friend DataBuffer& operator>>(DataBuffer& in, VarInt& var);
|
||||
};
|
||||
@@ -73,7 +73,7 @@ bool PiecesFiles::loadPieces(int polyominoSize, std::vector<Piece>& pieces, std:
|
||||
if(!compressed.ReadFile(filePath))
|
||||
return false;
|
||||
|
||||
DataBuffer buffer = Decompress(compressed);
|
||||
DataBuffer buffer = Decompress(compressed, compressed.GetSize());
|
||||
|
||||
std::ifstream piecesFile(filePath, std::ios::binary);
|
||||
if (!piecesFile.good()) {
|
||||
|
||||
Reference in New Issue
Block a user