openmohaa/code/fgame/archive.h

348 lines
8.3 KiB
C
Raw Normal View History

2016-03-27 11:49:47 +02:00
/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// archive.h: OpenMoHAA Archiver
#ifndef __ARCHIVE_H__
#define __ARCHIVE_H__
2023-04-29 21:56:38 +02:00
#include "g_local.h"
2016-03-27 11:49:47 +02:00
#include "class.h"
#include "str.h"
2023-04-29 21:56:38 +02:00
#include "vector.h"
2016-03-27 11:49:47 +02:00
2023-09-13 19:46:39 +02:00
#define ARCHIVE_NULL_POINTER (-654321)
#define ARCHIVE_POINTER_VALID (0)
#define ARCHIVE_POINTER_NULL (ARCHIVE_NULL_POINTER)
#define ARCHIVE_POINTER_SELF_REFERENTIAL (-123456)
2016-03-27 11:49:47 +02:00
#define ARCHIVE_USE_TYPES
typedef enum {
ARCHIVE_NONE,
ARCHIVE_WRITE,
ARCHIVE_READ
} archivemode_e;
2016-03-27 11:49:47 +02:00
2023-09-13 19:46:39 +02:00
enum {
pointer_fixup_ptr,
2023-09-13 19:46:39 +02:00
pointer_fixup_normal,
pointer_fixup_safe
2016-03-27 11:49:47 +02:00
};
2023-09-13 19:46:39 +02:00
typedef struct {
void **ptr;
int index;
int type;
2016-03-27 11:49:47 +02:00
} pointer_fixup_t;
2023-01-30 16:26:38 +01:00
using fileSize_t = uint32_t;
class ArchiveFile
2016-03-27 11:49:47 +02:00
{
protected:
2023-09-13 19:46:39 +02:00
str filename;
size_t length;
byte *buffer;
byte *pos;
size_t bufferlength;
bool writing;
bool opened;
2016-03-27 11:49:47 +02:00
public:
ArchiveFile();
~ArchiveFile();
void Close();
2023-09-13 19:46:39 +02:00
const char *Filename(void);
qboolean Compress();
2023-09-13 19:46:39 +02:00
size_t Length(void);
size_t Pos(void);
size_t Tell(void);
2023-09-13 19:46:39 +02:00
qboolean Seek(size_t newpos);
qboolean OpenRead(const char *name);
qboolean OpenWrite(const char *name);
2023-09-13 19:46:39 +02:00
qboolean Read(void *dest, size_t size);
qboolean Write(const void *source, size_t size);
2016-03-27 11:49:47 +02:00
};
class Archiver
2016-03-27 11:49:47 +02:00
{
private:
Container<LightClass *> classpointerList;
2023-09-13 19:46:39 +02:00
Container<pointer_fixup_t *> fixupList;
2016-03-27 11:49:47 +02:00
protected:
str filename;
qboolean fileerror;
ArchiveFile archivefile;
int archivemode;
int numclassespos;
qboolean harderror;
size_t m_iNumBytesIO;
qboolean silent;
2023-09-13 19:46:39 +02:00
void CheckRead(void);
void CheckType(int type);
int ReadType(void);
fileSize_t ReadSize(void);
void CheckSize(int type, fileSize_t size);
void ArchiveData(int type, void *data, size_t size);
void CheckWrite(void);
void WriteType(int type);
void WriteSize(fileSize_t size);
2016-03-27 11:49:47 +02:00
public:
2023-09-13 19:46:39 +02:00
Archiver();
~Archiver();
void FileError(const char *fmt, ...);
void Close(void);
qboolean Read(str& name, qboolean harderror = qtrue);
qboolean Read(const char *name, qboolean harderror = qtrue);
Class *ReadObject(void);
qboolean Create(str& name, qboolean harderror = qtrue);
qboolean Create(const char *name, qboolean harderror = qtrue);
qboolean Loading(void);
qboolean Saving(void);
qboolean NoErrors(void);
void ArchiveVector(Vector *vec);
void ArchiveQuat(Quat *quat);
void ArchiveInteger(int *num);
void ArchiveUnsigned(unsigned *unum);
void ArchiveSize(long *unum);
void ArchiveByte(byte *num);
void ArchiveChar(char *ch);
void ArchiveShort(short *num);
void ArchiveUnsignedShort(unsigned short *num);
void ArchiveFloat(float *num);
void ArchiveDouble(double *num);
void ArchiveBoolean(qboolean *boolean);
void ArchiveString(str *string);
void ArchiveObjectPointer(LightClass **ptr);
2023-09-13 19:46:39 +02:00
void ArchiveObjectPointer(Class **ptr);
void ArchiveObjectPosition(LightClass *obj);
2023-09-13 19:46:39 +02:00
void ArchiveSafePointer(SafePtrBase *ptr);
void ArchiveEventPointer(Event **ev);
void ArchiveBool(bool *boolean);
void ArchivePosition(int *pos);
void ArchiveSvsTime(int *time);
void ArchiveVec2(vec2_t vec);
void ArchiveVec3(vec3_t vec);
void ArchiveVec4(vec4_t vec);
void ArchiveRaw(void *data, size_t size);
void ArchiveObject(Class *obj);
void ArchiveObject(SafePtrBase* obj); // Added in OPM
2023-09-13 19:46:39 +02:00
qboolean ObjectPositionExists(void *obj);
void Reset();
size_t Counter() const;
void ArchiveConfigString(int cs);
2023-09-13 19:46:39 +02:00
void SetSilent(bool bSilent);
2016-03-27 11:49:47 +02:00
};
2023-09-13 19:46:39 +02:00
template<class Type>
inline void Container<Type>::Archive(Archiver& arc, void (*ArchiveFunc)(Archiver& arc, Type *obj))
2016-03-27 11:49:47 +02:00
{
2023-09-13 19:46:39 +02:00
int num;
int i;
if (arc.Loading()) {
arc.ArchiveInteger(&num);
Resize(num);
} else {
num = numobjects;
arc.ArchiveInteger(&num);
}
for (i = 1; i <= num; i++) {
if (num > numobjects) {
numobjects = num;
}
ArchiveFunc(arc, &objlist[i - 1]);
}
2016-03-27 11:49:47 +02:00
}
template<>
2023-09-13 19:46:39 +02:00
inline void Container<str>::Archive(Archiver& arc)
2016-03-27 11:49:47 +02:00
{
2023-09-13 19:46:39 +02:00
int i, num;
if (arc.Loading()) {
ClearObjectList();
arc.ArchiveInteger(&num);
Resize(num);
} else {
num = numobjects;
arc.ArchiveInteger(&num);
}
for (i = 1; i <= num; i++) {
arc.ArchiveString(AddressOfObjectAt(i));
}
2016-03-27 11:49:47 +02:00
}
template<>
2023-09-13 19:46:39 +02:00
inline void Container<Vector>::Archive(Archiver& arc)
2016-03-27 11:49:47 +02:00
{
2023-09-13 19:46:39 +02:00
int i, num;
if (arc.Loading()) {
ClearObjectList();
arc.ArchiveInteger(&num);
Resize(num);
} else {
num = numobjects;
arc.ArchiveInteger(&num);
}
for (i = 1; i <= num; i++) {
arc.ArchiveVector(AddressOfObjectAt(i));
}
2016-03-27 11:49:47 +02:00
}
template<>
2023-09-13 19:46:39 +02:00
inline void Container<int>::Archive(Archiver& arc)
2016-03-27 11:49:47 +02:00
{
2023-09-13 19:46:39 +02:00
int i, num;
if (arc.Loading()) {
ClearObjectList();
arc.ArchiveInteger(&num);
Resize(num);
} else {
num = numobjects;
arc.ArchiveInteger(&num);
}
for (i = 1; i <= num; i++) {
arc.ArchiveInteger(AddressOfObjectAt(i));
}
2016-03-27 11:49:47 +02:00
}
template<>
2023-09-13 19:46:39 +02:00
inline void Container<float>::Archive(Archiver& arc)
2016-03-27 11:49:47 +02:00
{
2023-09-13 19:46:39 +02:00
int i, num;
if (arc.Loading()) {
ClearObjectList();
arc.ArchiveInteger(&num);
Resize(num);
} else {
num = numobjects;
arc.ArchiveInteger(&num);
}
for (i = 1; i <= num; i++) {
arc.ArchiveFloat(AddressOfObjectAt(i));
}
2016-03-27 11:49:47 +02:00
}
2023-09-13 19:46:39 +02:00
template<typename c>
inline void ArchiveClass(Archiver& arc, c *obj)
2016-03-27 11:49:47 +02:00
{
2023-09-13 19:46:39 +02:00
arc.ArchiveObject(obj);
2016-03-27 11:49:47 +02:00
}
template<typename Type>
void Container<Type>::Archive(Archiver& arc)
{
Archive(arc, ArchiveClass<Type>);
}
2016-03-27 11:49:47 +02:00
#ifndef NO_ARCHIVE
2023-09-13 19:46:39 +02:00
template<typename key, typename value>
void con_set<key, value>::Archive(Archiver& arc)
2016-03-27 11:49:47 +02:00
{
Entry *e = NULL;
2023-09-13 19:46:39 +02:00
int hash;
int i;
arc.ArchiveUnsigned(&tableLength);
arc.ArchiveUnsigned(&threshold);
arc.ArchiveUnsigned(&count);
arc.ArchiveUnsignedShort(&tableLengthIndex);
if (arc.Loading()) {
if (tableLength != 1) {
table = new Entry *[tableLength]();
memset(table, 0, tableLength * sizeof(Entry *));
}
for (i = 0; i < count; i++) {
e = new Entry;
e->Archive(arc);
hash = HashCode<key>(e->GetKey()) % tableLength;
2023-09-13 19:46:39 +02:00
e->next = table[hash];
table[hash] = e;
}
defaultEntry = e;
2023-09-13 19:46:39 +02:00
} else {
#ifndef NDEBUG
int total;
total = 0;
for (i = 0; i < tableLength; i++) {
2023-09-13 19:46:39 +02:00
for (e = table[i]; e != NULL; e = e->next) {
e->Archive(arc);
total++;
2023-09-13 19:46:39 +02:00
}
}
// it must match the number of elements
assert(total == count);
#else
for (i = 0; i < tableLength; i++) {
for (e = table[i]; e != NULL; e = e->next) {
e->Archive(arc);
}
}
#endif
2023-09-13 19:46:39 +02:00
}
2016-03-27 11:49:47 +02:00
}
2023-09-13 19:46:39 +02:00
template<typename key, typename value>
void con_map<key, value>::Archive(Archiver& arc)
2016-03-27 11:49:47 +02:00
{
2023-09-13 19:46:39 +02:00
m_con_set.Archive(arc);
2016-03-27 11:49:47 +02:00
}
#endif
2023-09-13 19:46:39 +02:00
#define ArchiveEnum(thing, type) \
{ \
int tempInt; \
\
tempInt = (int)(thing); \
arc.ArchiveInteger(&tempInt); \
(thing) = (type)tempInt; \
}
2016-03-27 11:49:47 +02:00
#endif // __ARCHIVE_H__