1
0
forked from 0ad/0ad

current version of archive interface (for review purposes)

This was SVN commit r5451.
This commit is contained in:
janwas 2007-11-10 19:39:26 +00:00
parent 0636b65228
commit e3d8592fa2

View File

@ -0,0 +1,101 @@
/**
* =========================================================================
* File : archive.h
* Project : 0 A.D.
* Description : interface for reading from and creating archives.
* =========================================================================
*/
// license: GPL; see lib/license.txt
#ifndef INCLUDED_ARCHIVE
#define INCLUDED_ARCHIVE
struct ICodec;
namespace ERR
{
const LibError UNKNOWN_FORMAT = -110400;
const LibError IS_COMPRESSED = -110401;
}
enum ArchiveEntryFlags
{
// (this avoids having to interpret each archive's method values)
AEF_COMPRESSED = 1,
// indicates ArchiveEntry.ofs points to a "local file header" instead of
// the file data. a fixup routine is called upon file open; it skips
// past LFH and clears this flag.
// this is somewhat of a hack, but vital to archive open performance.
// without it, we'd have to scan through the entire archive file,
// which can take *seconds*.
// (we cannot use the information in CDFH, because its 'extra' field
// has been observed to differ from that of the LFH)
// by reading LFH when a file in archive is opened, the block cache
// absorbs the IO cost because the file will likely be read anyway.
AEF_NEEDS_FIXUP = 2
};
// holds all per-file information extracted from the header.
// this is intended to work for all archive types.
struct ArchiveEntry
{
off_t ofs;
size_t usize;
size_t csize;
time_t mtime;
u32 checksum;
uint method;
uint flags; // ArchiveEntryFlags
// note that size == usize isn't foolproof, and adding a flag to
// ofs or size is ugly and error-prone.
bool IsCompressed() const
{
return (flags & AEF_COMPRESSED) != 0;
}
};
// successively called for each archive entry.
typedef LibError (*ArchiveCB)(const char* pathname, const ArchiveEntry& ae, uintptr_t cbData);
struct IArchive
{
IArchive(const char* pathname);
virtual ~IArchive();
virtual boost::shared_ptr<ICodec> CreateDecompressor() const = 0;
/**
* call back for each file entry in the archive.
**/
virtual LibError ForEachEntry(ArchiveCB cb, uintptr_t cbData) const = 0;
virtual LibError LoadFile(ArchiveEntry& archiveEntry) const = 0;
};
// note: when creating an archive, any existing file with the given pathname
// will be overwritten.
struct IArchiveBuilder
{
/**
* write out the archive to disk; only hereafter is it valid.
**/
virtual ~IArchiveBuilder();
virtual boost::shared_ptr<ICodec> CreateCompressor() const = 0;
/**
* add a file to the archive.
*
* @param fileContents the file data; its compression method is defined by
* ae.method and can be CM_NONE.
**/
virtual LibError AddFile(const ArchiveEntry& ae, const u8* fileContents) = 0;
};
#endif // #ifndef INCLUDED_ARCHIVE