164 lines
3.7 KiB
C++
164 lines
3.7 KiB
C++
/* -----------------------------------------------------------------------------
|
|
GSFramework
|
|
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
|
----------------------------------------------------------------------------- */
|
|
|
|
|
|
#ifndef __NARCHIVE__
|
|
#define __NARCHIVE__
|
|
|
|
|
|
#include "nstring/nstring.h"
|
|
#include "container/nlist.h"
|
|
#include "memory/nauto_ptr.h"
|
|
#include "filesystem/io_handle.h"
|
|
|
|
|
|
namespace GS {
|
|
namespace Threading { class Mutex; }
|
|
|
|
/// Archive index entry.
|
|
struct ArchiveEntry
|
|
{
|
|
// Do not change this enumeration order!
|
|
enum Method
|
|
{
|
|
MethodRaw = 0,
|
|
MethodZLibCompress
|
|
};
|
|
|
|
String path; ///< Entry path.
|
|
|
|
char method; ///< Compression method.
|
|
size_t offset; ///< Data offset in archive.
|
|
size_t length; ///< Original length.
|
|
size_t compressed_length; ///< Compressed length.
|
|
};
|
|
|
|
/*!
|
|
@short Archive index.
|
|
@author Emmanuel Julien (ejulien@gsworks.fr)
|
|
*/
|
|
class ArchiveIndex
|
|
{
|
|
friend class Archive;
|
|
|
|
protected:
|
|
|
|
AutoList <ArchiveEntry *> index;
|
|
|
|
public:
|
|
/// Find an entry in the index file.
|
|
ArchiveEntry *FindEntry(const char *alias) const;
|
|
|
|
/// Load archive index.
|
|
bool Load(const char *uri);
|
|
/// Save archive index.
|
|
bool Save(const char *uri);
|
|
};
|
|
|
|
/*!
|
|
@short Archive storage.
|
|
|
|
A pretty straightforward solid archive file format.
|
|
Supports per-file compression algorithm selection.
|
|
|
|
@author Emmanuel Julien
|
|
*/
|
|
class Archive
|
|
{
|
|
public:
|
|
|
|
enum Revision
|
|
{
|
|
Legacy = 0,
|
|
EnhancedLegacy
|
|
};
|
|
|
|
protected:
|
|
|
|
AutoPtr <Threading::Mutex> access_mutex;
|
|
|
|
bool verbose;
|
|
bool append_mode; ///< Archive open in append mode.
|
|
|
|
ArchiveIndex index; ///< Archive index table.
|
|
|
|
AutoPtr <IO::Handle> handle;
|
|
|
|
Revision revision;
|
|
size_t offset_padding, ///< File offset padding.
|
|
size_padding; ///< File size padding.
|
|
|
|
public:
|
|
|
|
/*!
|
|
@short Set file offset padding.
|
|
|
|
Padding archive content is necessary on some platforms that do not
|
|
support seeking or reading an arbitrary amount of bytes inside a
|
|
file. This is often the case with the DVD unit of console systems.
|
|
*/
|
|
void SetOffsetPadding(size_t padding = 0)
|
|
{ offset_padding = padding; }
|
|
/*!
|
|
@short Set file size padding.
|
|
@see SetOffsetPadding().
|
|
*/
|
|
void SetSizePadding(size_t padding = 0)
|
|
{ size_padding = padding; }
|
|
|
|
/// Return internal index object.
|
|
const List <ArchiveEntry *> &GetIndex() const
|
|
{ return index.index; }
|
|
|
|
/// Set the verbose mode.
|
|
void SetVerbose(bool v = true)
|
|
{ verbose = v; }
|
|
|
|
/// Load current archive index file.
|
|
bool LoadIndex(const char *path);
|
|
/// Save current archive index file.
|
|
bool SaveIndex(const char *path);
|
|
|
|
/*!
|
|
@short Open archive.
|
|
|
|
@note If no index is provided one will automatically be created
|
|
upon archive opening. Although this a fast process it
|
|
requires that the archive be opened on a stream-able
|
|
file system and that the whole archive be seeked through.
|
|
*/
|
|
bool OpenRead(const char *uri, const char *index_uri = 0);
|
|
/// Create a new archive.
|
|
bool CreateNew(const char *);
|
|
/// Close archive.
|
|
void Close();
|
|
|
|
/// Check if a file exists in archive.
|
|
ArchiveEntry *Exists(const char *path) const
|
|
{ return index.FindEntry(path); }
|
|
|
|
/*!
|
|
@short Load a file from the archive.
|
|
|
|
@note The output buffer is expected to old enough room to store
|
|
the decompressed data.
|
|
@see Exists().
|
|
*/
|
|
bool FileRead(const char *, void *);
|
|
|
|
/// Write a memory block to the archive.
|
|
ArchiveEntry *MemoryBlockWrite(const char *, const void *, size_t, int compression_level = 6);
|
|
/// Write a file to the archive.
|
|
ArchiveEntry *FileWrite(const char *path, const char *alias = 0, int compression_level = 6);
|
|
|
|
Archive();
|
|
~Archive();
|
|
};
|
|
|
|
} // GS
|
|
|
|
|
|
#endif // __NARCHIVE__
|