Skip to content

Commit

Permalink
Generalize the zzlib functions (#9083)
Browse files Browse the repository at this point in the history
  • Loading branch information
oleg-derevenetz authored Sep 7, 2024
1 parent d06c348 commit f3ef482
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 39 deletions.
3 changes: 2 additions & 1 deletion src/engine/serialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <cstring>
#include <ostream>
#include <string>
#include <string_view>

#include "endian_h2.h"
#include "logging.h"
Expand Down Expand Up @@ -230,7 +231,7 @@ OStreamBase & OStreamBase::operator<<( const uint32_t v )
return *this;
}

OStreamBase & OStreamBase::operator<<( const std::string & v )
OStreamBase & OStreamBase::operator<<( const std::string_view v )
{
put32( static_cast<uint32_t>( v.size() ) );

Expand Down
3 changes: 2 additions & 1 deletion src/engine/serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <map>
#include <memory>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
#include <vector>
Expand Down Expand Up @@ -233,7 +234,7 @@ class OStreamBase : virtual public StreamBase
OStreamBase & operator<<( const uint16_t v );
OStreamBase & operator<<( const int32_t v );
OStreamBase & operator<<( const uint32_t v );
OStreamBase & operator<<( const std::string & v );
OStreamBase & operator<<( const std::string_view v );

OStreamBase & operator<<( const fheroes2::Point & v );

Expand Down
40 changes: 20 additions & 20 deletions src/engine/zzlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace

namespace Compression
{
std::vector<uint8_t> decompressData( const uint8_t * src, const size_t srcSize, size_t realSize /* = 0 */ )
std::vector<uint8_t> unzipData( const uint8_t * src, const size_t srcSize, size_t realSize /* = 0 */ )
{
if ( src == nullptr || srcSize == 0 ) {
return {};
Expand Down Expand Up @@ -102,7 +102,7 @@ namespace Compression
return res;
}

std::vector<uint8_t> compressData( const uint8_t * src, const size_t srcSize )
std::vector<uint8_t> zipData( const uint8_t * src, const size_t srcSize )
{
if ( src == nullptr || srcSize == 0 ) {
return {};
Expand Down Expand Up @@ -134,46 +134,46 @@ namespace Compression
return res;
}

bool readFromFileStream( StreamFile & fileStream, RWStreamBuf & output )
bool unzipStream( IStreamBase & inputStream, OStreamBase & outputStream )
{
const uint32_t rawSize = fileStream.get32();
const uint32_t zipSize = fileStream.get32();
const uint32_t rawSize = inputStream.get32();
const uint32_t zipSize = inputStream.get32();
if ( zipSize == 0 ) {
return false;
}

const uint16_t version = fileStream.get16();
const uint16_t version = inputStream.get16();
if ( version != FORMAT_VERSION_0 ) {
return false;
}

fileStream.skip( 2 ); // Unused bytes
inputStream.skip( 2 ); // Unused bytes

const std::vector<uint8_t> zip = fileStream.getRaw( zipSize );
const std::vector<uint8_t> raw = decompressData( zip.data(), zip.size(), rawSize );
const std::vector<uint8_t> zip = inputStream.getRaw( zipSize );
const std::vector<uint8_t> raw = unzipData( zip.data(), zip.size(), rawSize );
if ( raw.size() != rawSize ) {
return false;
}

output.putRaw( raw.data(), raw.size() );
outputStream.putRaw( raw.data(), raw.size() );

return !output.fail();
return !outputStream.fail();
}

bool writeIntoFileStream( StreamFile & fileStream, IStreamBuf & data )
bool zipStreamBuf( IStreamBuf & inputStream, OStreamBase & outputStream )
{
const std::vector<uint8_t> zip = compressData( data.data(), data.size() );
const std::vector<uint8_t> zip = zipData( inputStream.data(), inputStream.size() );
if ( zip.empty() ) {
return false;
}

fileStream.put32( static_cast<uint32_t>( data.size() ) );
fileStream.put32( static_cast<uint32_t>( zip.size() ) );
fileStream.put16( FORMAT_VERSION_0 );
fileStream.put16( 0 ); // Unused bytes
fileStream.putRaw( zip.data(), zip.size() );
outputStream.put32( static_cast<uint32_t>( inputStream.size() ) );
outputStream.put32( static_cast<uint32_t>( zip.size() ) );
outputStream.put16( FORMAT_VERSION_0 );
outputStream.put16( 0 ); // Unused bytes
outputStream.putRaw( zip.data(), zip.size() );

return !fileStream.fail();
return !outputStream.fail();
}

fheroes2::Image CreateImageFromZlib( int32_t width, int32_t height, const uint8_t * imageData, size_t imageSize, bool doubleLayer )
Expand All @@ -182,7 +182,7 @@ namespace Compression
return {};
}

const std::vector<uint8_t> & uncompressedData = decompressData( imageData, imageSize );
const std::vector<uint8_t> & uncompressedData = unzipData( imageData, imageSize );
if ( doubleLayer && ( uncompressedData.size() & 1 ) == 1 ) {
return {};
}
Expand Down
22 changes: 11 additions & 11 deletions src/engine/zzlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,29 +30,29 @@

#include "image.h"

class IStreamBase;
class OStreamBase;
class IStreamBuf;
class RWStreamBuf;
class StreamFile;

namespace Compression
{
// Zips the input data and returns the compressed data or an empty vector in case of an error.
std::vector<uint8_t> compressData( const uint8_t * src, const size_t srcSize );

// Unzips the input data and returns the uncompressed data or an empty vector in case of an error.
// The 'realSize' parameter represents the planned size of the decompressed data and is optional
// (it is only used to speed up the decompression process). If this parameter is omitted or set to
// zero, the size of the decompressed data will be determined automatically.
std::vector<uint8_t> decompressData( const uint8_t * src, const size_t srcSize, size_t realSize = 0 );
std::vector<uint8_t> unzipData( const uint8_t * src, const size_t srcSize, size_t realSize = 0 );

// Zips the input data and returns the compressed data or an empty vector in case of an error.
std::vector<uint8_t> zipData( const uint8_t * src, const size_t srcSize );

// Reads & unzips the zipped chunk from the specified file stream and appends
// it to the end of the buffer. Returns true on success or false on error.
bool readFromFileStream( StreamFile & fileStream, RWStreamBuf & output );
// Reads & unzips the zipped chunk from the given input stream and writes it to the given output
// stream. Returns true on success or false on error.
bool unzipStream( IStreamBase & inputStream, OStreamBase & outputStream );

// Zips the contents of the buffer from the current read position to the end of the buffer and writes
// it to the specified file stream. The current read position of the buffer does not change. Returns
// it to the given output stream. The current read position of the buffer does not change. Returns
// true on success and false on error.
bool writeIntoFileStream( StreamFile & fileStream, IStreamBuf & data );
bool zipStreamBuf( IStreamBuf & inputStream, OStreamBase & outputStream );

fheroes2::Image CreateImageFromZlib( int32_t width, int32_t height, const uint8_t * imageData, size_t imageSize, bool doubleLayer );
}
Expand Down
4 changes: 2 additions & 2 deletions src/fheroes2/game/game_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ bool Game::Save( const std::string & filePath, const bool autoSave /* = false */

// End-of-data marker
dataStream << SAV2ID3;
if ( dataStream.fail() || !Compression::writeIntoFileStream( fileStream, dataStream ) ) {
if ( dataStream.fail() || !Compression::zipStreamBuf( dataStream, fileStream ) ) {
return false;
}

Expand Down Expand Up @@ -228,7 +228,7 @@ fheroes2::GameMode Game::Load( const std::string & filePath )
RWStreamBuf dataStream;
dataStream.setBigendian( true );

if ( !Compression::readFromFileStream( fileStream, dataStream ) ) {
if ( !Compression::unzipStream( fileStream, dataStream ) ) {
showGenericErrorMessage();
return fheroes2::GameMode::CANCEL;
}
Expand Down
4 changes: 2 additions & 2 deletions src/fheroes2/game/highscores.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ namespace fheroes2
RWStreamBuf hdata;
hdata.setBigendian( true );

if ( !Compression::readFromFileStream( fileStream, hdata ) ) {
if ( !Compression::unzipStream( fileStream, hdata ) ) {
return false;
}

Expand Down Expand Up @@ -211,7 +211,7 @@ namespace fheroes2
hdata.setBigendian( true );
hdata << highscoreFileMagicValueV2 << _highScoresStandard << _highScoresCampaign;

return !hdata.fail() && Compression::writeIntoFileStream( fileStream, hdata );
return !hdata.fail() && Compression::zipStreamBuf( hdata, fileStream );
}

int32_t HighScoreDataContainer::registerScoreStandard( HighscoreData && data )
Expand Down
4 changes: 2 additions & 2 deletions src/fheroes2/maps/map_format_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ namespace
compressed << map.additionalInfo << map.tiles << map.dailyEvents << map.rumors << map.standardMetadata << map.castleMetadata << map.heroMetadata
<< map.sphinxMetadata << map.signMetadata << map.adventureMapEventMetadata << map.shrineMetadata;

const std::vector<uint8_t> temp = Compression::compressData( compressed.data(), compressed.size() );
const std::vector<uint8_t> temp = Compression::zipData( compressed.data(), compressed.size() );

stream.putRaw( temp.data(), temp.size() );

Expand All @@ -241,7 +241,7 @@ namespace
return false;
}

const std::vector<uint8_t> decompressedData = Compression::decompressData( temp.data(), temp.size() );
const std::vector<uint8_t> decompressedData = Compression::unzipData( temp.data(), temp.size() );
if ( decompressedData.empty() ) {
// This is a corrupted file.
map = {};
Expand Down

0 comments on commit f3ef482

Please sign in to comment.