Simplify Serialise for FileIndex

This commit is contained in:
duncanspumpkin 2020-12-06 18:13:03 +00:00
parent ee9ede6c33
commit 60729113d9
6 changed files with 69 additions and 118 deletions

View File

@ -110,6 +110,10 @@ template<> struct DataSerializerTraits_t<int8_t> : public DataSerializerTraitsIn
{
};
template<> struct DataSerializerTraits_t<utf8> : public DataSerializerTraitsIntegral<utf8>
{
};
template<> struct DataSerializerTraits_t<uint16_t> : public DataSerializerTraitsIntegral<uint16_t>
{
};
@ -141,6 +145,10 @@ template<> struct DataSerializerTraits_t<std::string>
uint16_t len = static_cast<uint16_t>(str.size());
uint16_t swapped = ByteSwapBE(len);
stream->Write(&swapped);
if (len == 0)
{
return;
}
stream->WriteArray(str.c_str(), len);
}
static void decode(OpenRCT2::IStream* stream, std::string& res)
@ -148,7 +156,11 @@ template<> struct DataSerializerTraits_t<std::string>
uint16_t len;
stream->Read(&len);
len = ByteSwapBE(len);
if (len == 0)
{
res = "";
return;
}
const char* str = stream->ReadArray<char>(len);
res.assign(str, len);
@ -157,7 +169,10 @@ template<> struct DataSerializerTraits_t<std::string>
static void log(OpenRCT2::IStream* stream, const std::string& str)
{
stream->Write("\"", 1);
stream->Write(str.data(), str.size());
if (str.size() != 0)
{
stream->Write(str.data(), str.size());
}
stream->Write("\"", 1);
}
};
@ -327,6 +342,10 @@ template<size_t _Size> struct DataSerializerTraits_t<uint8_t[_Size]> : public Da
{
};
template<size_t _Size> struct DataSerializerTraits_t<utf8[_Size]> : public DataSerializerTraitsPODArray<utf8, _Size>
{
};
template<size_t _Size> struct DataSerializerTraits_t<uint16_t[_Size]> : public DataSerializerTraitsPODArray<uint16_t, _Size>
{
};

View File

@ -11,6 +11,7 @@
#include "../common.h"
#include "Console.hpp"
#include "DataSerialiser.h"
#include "File.h"
#include "FileScanner.h"
#include "FileStream.h"
@ -130,14 +131,9 @@ protected:
virtual std::tuple<bool, TItem> Create(int32_t language, const std::string& path) const abstract;
/**
* Serialises an index item to the given stream.
* Serialises/DeSerialises an index item to/from the given stream.
*/
virtual void Serialise(OpenRCT2::IStream* stream, const TItem& item) const abstract;
/**
* Deserialises an index item from the given stream.
*/
virtual TItem Deserialise(OpenRCT2::IStream* stream) const abstract;
virtual void Serialise(DataSerialiser& ds, TItem& item) const abstract;
private:
ScanResult Scan() const
@ -272,10 +268,12 @@ private:
&& header.Stats.PathChecksum == stats.PathChecksum)
{
items.reserve(header.NumItems);
DataSerialiser ds(false, fs);
// Directory is the same, just read the saved items
for (uint32_t i = 0; i < header.NumItems; i++)
{
auto item = Deserialise(&fs);
TItem item;
Serialise(ds, item);
items.emplace_back(std::move(item));
}
loadedItems = true;
@ -294,7 +292,7 @@ private:
return std::make_tuple(loadedItems, std::move(items));
}
void WriteIndexFile(int32_t language, const DirectoryStats& stats, const std::vector<TItem>& items) const
void WriteIndexFile(int32_t language, const DirectoryStats& stats, std::vector<TItem>& items) const
{
try
{
@ -312,10 +310,11 @@ private:
header.NumItems = static_cast<uint32_t>(items.size());
fs.WriteValue(header);
DataSerialiser ds(true, fs);
// Write items
for (const auto& item : items)
for (auto& item : items)
{
Serialise(&fs, item);
Serialise(ds, item);
}
}
catch (const std::exception& e)

View File

@ -168,6 +168,10 @@ namespace OpenRCT2
void FileStream::Write(const void* buffer, uint64_t length)
{
if (length == 0)
{
return;
}
if (fwrite(buffer, static_cast<size_t>(length), 1, _file) != 1)
{
throw IOException("Unable to write to file.");

View File

@ -76,7 +76,7 @@ class ObjectFileIndex final : public FileIndex<ObjectRepositoryItem>
{
private:
static constexpr uint32_t MAGIC_NUMBER = 0x5844494F; // OIDX
static constexpr uint16_t VERSION = 25;
static constexpr uint16_t VERSION = 26;
static constexpr auto PATTERN = "*.dat;*.pob;*.json;*.parkobj";
IObjectRepository& _objectRepository;
@ -126,27 +126,26 @@ public:
}
protected:
void Serialise(IStream* stream, const ObjectRepositoryItem& item) const override
void Serialise(DataSerialiser& ds, ObjectRepositoryItem& item) const override
{
DataSerialiser serialiser(true, *stream);
serialiser << item.Identifier;
serialiser << item.ObjectEntry;
serialiser << item.Path;
serialiser << item.Name;
ds << item.Identifier;
ds << item.ObjectEntry;
ds << item.Path;
ds << item.Name;
serialiser << item.Sources;
serialiser << item.Authors;
ds << item.Sources;
ds << item.Authors;
switch (item.ObjectEntry.GetType())
{
case ObjectType::Ride:
serialiser << item.RideInfo.RideFlags;
serialiser << item.RideInfo.RideCategory;
serialiser << item.RideInfo.RideType;
ds << item.RideInfo.RideFlags;
ds << item.RideInfo.RideCategory;
ds << item.RideInfo.RideType;
break;
case ObjectType::SceneryGroup:
{
serialiser << item.SceneryGroupInfo.Entries;
ds << item.SceneryGroupInfo.Entries;
break;
}
default:
@ -155,38 +154,6 @@ protected:
}
}
ObjectRepositoryItem Deserialise(IStream* stream) const override
{
ObjectRepositoryItem item;
DataSerialiser serialiser(false, *stream);
serialiser << item.Identifier;
serialiser << item.ObjectEntry;
serialiser << item.Path;
serialiser << item.Name;
serialiser << item.Sources;
serialiser << item.Authors;
switch (item.ObjectEntry.GetType())
{
case ObjectType::Ride:
serialiser << item.RideInfo.RideFlags;
serialiser << item.RideInfo.RideCategory;
serialiser << item.RideInfo.RideType;
break;
case ObjectType::SceneryGroup:
{
serialiser << item.SceneryGroupInfo.Entries;
break;
}
default:
// Switch processes only ObjectType::Ride and ObjectType::SceneryGroup
break;
}
return item;
}
private:
bool IsTrackReadOnly(const std::string& path) const
{

View File

@ -57,7 +57,7 @@ class TrackDesignFileIndex final : public FileIndex<TrackRepositoryItem>
{
private:
static constexpr uint32_t MAGIC_NUMBER = 0x58444954; // TIDX
static constexpr uint16_t VERSION = 3;
static constexpr uint16_t VERSION = 4;
static constexpr auto PATTERN = "*.td4;*.td6";
public:
@ -97,24 +97,13 @@ public:
}
protected:
void Serialise(IStream* stream, const TrackRepositoryItem& item) const override
void Serialise(DataSerialiser& ds, TrackRepositoryItem& item) const override
{
stream->WriteString(item.Name);
stream->WriteString(item.Path);
stream->WriteValue(item.RideType);
stream->WriteString(item.ObjectEntry);
stream->WriteValue(item.Flags);
}
TrackRepositoryItem Deserialise(IStream* stream) const override
{
TrackRepositoryItem item;
item.Name = stream->ReadStdString();
item.Path = stream->ReadStdString();
item.RideType = stream->ReadValue<uint8_t>();
item.ObjectEntry = stream->ReadStdString();
item.Flags = stream->ReadValue<uint32_t>();
return item;
ds << item.Name;
ds << item.Path;
ds << item.RideType;
ds << item.ObjectEntry;
ds << item.Flags;
}
private:

View File

@ -129,7 +129,7 @@ class ScenarioFileIndex final : public FileIndex<scenario_index_entry>
{
private:
static constexpr uint32_t MAGIC_NUMBER = 0x58444953; // SIDX
static constexpr uint16_t VERSION = 3;
static constexpr uint16_t VERSION = 4;
static constexpr auto PATTERN = "*.sc4;*.sc6;*.sea";
public:
@ -159,49 +159,22 @@ protected:
}
}
void Serialise(IStream* stream, const scenario_index_entry& item) const override
void Serialise(DataSerialiser& ds, scenario_index_entry& item) const override
{
stream->Write(item.path, sizeof(item.path));
stream->WriteValue(item.timestamp);
ds << item.path;
ds << item.timestamp;
ds << item.category;
ds << item.source_game;
ds << item.source_index;
ds << item.sc_id;
ds << item.objective_type;
ds << item.objective_arg_1;
ds << item.objective_arg_2;
ds << item.objective_arg_3;
stream->WriteValue(item.category);
stream->WriteValue(item.source_game);
stream->WriteValue(item.source_index);
stream->WriteValue(item.sc_id);
stream->WriteValue(item.objective_type);
stream->WriteValue(item.objective_arg_1);
stream->WriteValue(item.objective_arg_2);
stream->WriteValue(item.objective_arg_3);
stream->Write(item.internal_name, sizeof(item.internal_name));
stream->Write(item.name, sizeof(item.name));
stream->Write(item.details, sizeof(item.details));
}
scenario_index_entry Deserialise(IStream* stream) const override
{
scenario_index_entry item;
stream->Read(item.path, sizeof(item.path));
item.timestamp = stream->ReadValue<uint64_t>();
item.category = stream->ReadValue<uint8_t>();
item.source_game = ScenarioSource{ stream->ReadValue<uint8_t>() };
item.source_index = stream->ReadValue<int16_t>();
item.sc_id = stream->ReadValue<uint16_t>();
item.objective_type = stream->ReadValue<uint8_t>();
item.objective_arg_1 = stream->ReadValue<uint8_t>();
item.objective_arg_2 = stream->ReadValue<int32_t>();
item.objective_arg_3 = stream->ReadValue<int16_t>();
item.highscore = nullptr;
stream->Read(item.internal_name, sizeof(item.internal_name));
stream->Read(item.name, sizeof(item.name));
stream->Read(item.details, sizeof(item.details));
return item;
ds << item.internal_name;
ds << item.name;
ds << item.details;
}
private: