Resource files management III

Resource files management. Part I
Resource files management. Part II

In previous post I wrote about implementation of data structures of the resource file.
Today's topic will be serialization of resource files.

File types

Ok, to retrieve our resources first of all we'll need to define basic methods of reading and writing with files.
In C++ it could be done simply using file streams. Refresh your memory on std::fstream methods if necessary.
Next, the format of file must be chosen. There are two choices to go from here: text/binary format.
When using textual format the data in file is represented as human-readable text.

myresource.dat:
[LumpCount] = 3
[LumpListOffset] = 215
...

(Note: .dat filename extension is not a requirement, you can use anything you like, however you should choose unique extension that is not used by other programs)

Whereas, binary files contain non-readable characters and from human point of view its just a mess.
However, data in binary files is always packed and so it takes less storage than text files. On the other hand, binary files are platform-dependent, i.e. int variable on x64 platform will take twice more than the same int on x86 platform. Text files don't suffer from this issue - text is always the same on any other platform.
And lastly you should know that files you will store in resource file probably would be of binary format, therefore if you are up to using text files you should think about how to write binary data to text file.
That's said I'm sticking up to binary format and below are the simple writing/reading methods of data to/from binary file.

Serialization

According to wikipedia:

Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be "resurrected" later in the same or another computer environment. When the resulting series of bits is reread according to the serialization format, it can be used to create a semantically identical clone of the original object.

What it says is, serialization is a tecnhique of writing data of objects in program to another source (in our case it is a file), so that it is possible anytime to read back the data stored in file and load it into the objects.
Unfortunately, C++ do not provide native support for serialization. Therefore, we'll need to write own serialization methods to write our data to file.

I've done simple functions of writing/reading basic types and std::strings with a file, you may write additional functions that suite yourself (std::vector etc.)
Here is the source: Serialization.h
The code is pretty self-explanatory, though if you have questions, just ask. Next, I'll write about how to use this serialization stuff.

Okay, last time we discussed the data structures of resource file and I've dropped functionality of Lump and ResourceFile classes on purpose for the sake of clarity. Now, I'll define methods of Lump class (ResourceFile is left for the next post).

Lump interface is pretty simple:

class Lump
{
protected:
    LumpInfo  mLumpInfo;
    void*     mData;

public:
    Lump();
    ~Lump();

    bool LoadData (std::fstream&);        // Read data from file
    bool SaveData (std::fstream&);        // Write data to file
    void UnloadData();                    // Clear data

    void LoadInfo (std::fstream&);        // Read information from file
    void SaveInfo (std::fstream&);        // Write information to file

    // accessors and mutators
    ...
};


That's all. Lump class implements information reading and writing methods that simply call serialization write() and read() methods for each data member of mLumpInfo:
void Lump::SaveInfo (std::fstream& fs)
{
    Serialization::Binary::Write(fs, mLumpInfo.Size);
    Serialization::Binary::Write(fs, mLumpInfo.Position);
    Serialization::Binary::Write(fs, mLumpInfo.Name);
}

void Lump::LoadInfo (std::fstream& fs)
{
    Serialization::Binary::Read(fs, mLumpInfo.Size);
    Serialization::Binary::Read(fs, mLumpInfo.Position);
    Serialization::Binary::Read(fs, mLumpInfo.Name);
}


Also Lump can dynamically load and unload lump content from file to memory. Here is the full source:
Lump.h
Lump.cpp

Feel free to ask any questions you have. Next time I'll write about ResourceFile class.

Resource files management. Part IV

0 comments: (+add yours?)

Post a Comment