OpenMoHAA ..
Loading...
Searching...
No Matches
archive.h
1/*
2===========================================================================
3Copyright (C) 2025 the OpenMoHAA team
4
5This file is part of OpenMoHAA source code.
6
7OpenMoHAA source code is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 2 of the License,
10or (at your option) any later version.
11
12OpenMoHAA source code is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with OpenMoHAA source code; if not, write to the Free Software
19Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20===========================================================================
21*/
22
23// archive.h: OpenMoHAA Archiver
24
25#pragma once
26
27#include "g_local.h"
28#include "../corepp/class.h"
29#include "../corepp/str.h"
30#include "../corepp/vector.h"
31
32#define ARCHIVE_NULL_POINTER (-654321)
33#define ARCHIVE_POINTER_VALID (0)
34#define ARCHIVE_POINTER_NULL (ARCHIVE_NULL_POINTER)
35#define ARCHIVE_POINTER_SELF_REFERENTIAL (-123456)
36#define ARCHIVE_USE_TYPES
37
38typedef enum {
39 ARCHIVE_NONE,
40 ARCHIVE_WRITE,
41 ARCHIVE_READ
42} archivemode_e;
43
44enum {
45 pointer_fixup_ptr,
46 pointer_fixup_normal,
47 pointer_fixup_safe
48};
49
50typedef struct {
51 void **ptr;
52 int index;
53 int type;
55
56using fileSize_t = uint32_t;
57
58class ArchiveFile
59{
60protected:
61 str filename;
62 size_t length;
63 byte *buffer;
64 byte *pos;
65 size_t bufferlength;
66 bool writing;
67 bool opened;
68
69public:
70 ArchiveFile();
71 ~ArchiveFile();
72 void Close();
73 const char *Filename(void);
74 qboolean Compress();
75 size_t Length(void);
76 size_t Pos(void);
77 size_t Tell(void);
78 qboolean Seek(size_t newpos);
79 qboolean OpenRead(const char *name);
80 qboolean OpenWrite(const char *name);
81 qboolean Read(void *dest, size_t size);
82 qboolean Write(const void *source, size_t size);
83 byte *DetachBuffer();
84};
85
86class Archiver
87{
88private:
89 Container<LightClass *> classpointerList;
91
92protected:
93 str filename;
94 qboolean fileerror;
95 ArchiveFile archivefile;
96 int archivemode;
97 int numclassespos;
98 qboolean harderror;
99 size_t m_iNumBytesIO;
100 qboolean silent;
101
102 void CheckRead(void);
103 void CheckType(int type);
104 int ReadType(void);
105 fileSize_t ReadSize(void);
106 void CheckSize(int type, fileSize_t size);
107 void ArchiveData(int type, void *data, size_t size);
108
109 void CheckWrite(void);
110 void WriteType(int type);
111 void WriteSize(fileSize_t size);
112
113public:
114 Archiver();
115 ~Archiver();
116 void FileError(const char *fmt, ...) Q_PRINTF_FUNC(2, 3);
117 void Close(void);
118 void CloseDeferred(void);
119
120 qboolean SeekToStart(void);
121 size_t FileLength(void);
122 byte *DetachFileBuffer(void);
123
124 qboolean Read(str& name, qboolean bHardError = qtrue);
125 qboolean Read(const char *name, qboolean bHardError = qtrue);
126 Class *ReadObject(void);
127
128 qboolean Create(str& name, qboolean bHardError = qtrue);
129 qboolean Create(const char *name, qboolean bHardError = qtrue);
130
131 qboolean Loading(void);
132 qboolean Saving(void);
133 qboolean NoErrors(void);
134
135 void ArchiveVector(Vector *vec);
136 void ArchiveQuat(Quat *quat);
137 void ArchiveInteger(int *num);
138 void ArchiveUnsigned(unsigned *unum);
139 void ArchiveSize(long *unum);
140 void ArchiveByte(byte *num);
141 void ArchiveChar(char *ch);
142 void ArchiveShort(short *num);
143 void ArchiveUnsignedShort(unsigned short *num);
144 void ArchiveFloat(float *num);
145 void ArchiveDouble(double *num);
146 void ArchiveBoolean(qboolean *boolean);
147 void ArchiveString(str *string);
148 void ArchiveObjectPointer(LightClass **ptr);
149 void ArchiveObjectPointer(Class **ptr);
150 void ArchiveObjectPosition(LightClass *obj);
151 void ArchiveSafePointer(SafePtrBase *ptr);
152 void ArchiveEventPointer(Event **ev);
153 void ArchiveBool(bool *boolean);
154 void ArchivePosition(int *pos);
155 void ArchiveSvsTime(int *time);
156 void ArchiveVec2(vec2_t vec);
157 void ArchiveVec3(vec3_t vec);
158 void ArchiveVec4(vec4_t vec);
159
160 void ArchiveRaw(void *data, size_t size);
161 void ArchiveObject(Class *obj);
162 void ArchiveObject(SafePtrBase *obj); // Added in OPM
163
164 qboolean ObjectPositionExists(void *obj);
165
166 void Reset();
167 size_t Counter() const;
168
169 void ArchiveConfigString(int cs);
170 void SetSilent(bool bSilent);
171};
172
173template<class Type>
174inline void Container<Type>::Archive(Archiver& arc, void (*ArchiveFunc)(Archiver& arc, Type *obj))
175{
176 Type *obj;
177 int num;
178 int i;
179
180 if (arc.Loading()) {
181 arc.ArchiveInteger(&num);
182 Resize(num);
183
184 if (num > numobjects) {
185 numobjects = num;
186 }
187
188 for (i = 0; i < num; i++) {
189 obj = new (objlist + i) Type();
190 ArchiveFunc(arc, obj);
191 }
192 } else {
193 num = numobjects;
194 arc.ArchiveInteger(&num);
195
196 for (i = 0; i < num; i++) {
197 ArchiveFunc(arc, &objlist[i]);
198 }
199 }
200}
201
202template<>
203inline void Container<str>::Archive(Archiver& arc)
204{
205 int i, num;
206
207 if (arc.Loading()) {
208 ClearObjectList();
209 arc.ArchiveInteger(&num);
210 Resize(num);
211 } else {
212 num = numobjects;
213 arc.ArchiveInteger(&num);
214 }
215 for (i = 1; i <= num; i++) {
216 arc.ArchiveString(AddressOfObjectAt(i));
217 }
218}
219
220template<>
221inline void Container<Vector>::Archive(Archiver& arc)
222{
223 int i, num;
224
225 if (arc.Loading()) {
226 ClearObjectList();
227 arc.ArchiveInteger(&num);
228 Resize(num);
229 } else {
230 num = numobjects;
231 arc.ArchiveInteger(&num);
232 }
233 for (i = 1; i <= num; i++) {
234 arc.ArchiveVector(AddressOfObjectAt(i));
235 }
236}
237
238template<>
239inline void Container<int>::Archive(Archiver& arc)
240{
241 int i, num;
242
243 if (arc.Loading()) {
244 ClearObjectList();
245 arc.ArchiveInteger(&num);
246 Resize(num);
247 } else {
248 num = numobjects;
249 arc.ArchiveInteger(&num);
250 }
251 for (i = 1; i <= num; i++) {
252 arc.ArchiveInteger(AddressOfObjectAt(i));
253 }
254}
255
256template<>
257inline void Container<float>::Archive(Archiver& arc)
258{
259 int i, num;
260
261 if (arc.Loading()) {
262 ClearObjectList();
263 arc.ArchiveInteger(&num);
264 Resize(num);
265 } else {
266 num = numobjects;
267 arc.ArchiveInteger(&num);
268 }
269 for (i = 1; i <= num; i++) {
270 arc.ArchiveFloat(AddressOfObjectAt(i));
271 }
272}
273
274template<typename c>
275inline void ArchiveClass(Archiver& arc, c *obj)
276{
277 arc.ArchiveObject(obj);
278}
279
280template<typename Type>
281void Container<Type>::Archive(Archiver& arc)
282{
283 Archive(arc, ArchiveClass<Type>);
284}
285
286#ifndef NO_ARCHIVE
287
288template<typename key, typename value>
289void con_set<key, value>::Archive(Archiver& arc)
290{
291 Entry *e = NULL;
292 int hash;
293 int i;
294
295 arc.ArchiveUnsigned(&tableLength);
296 arc.ArchiveUnsigned(&threshold);
297 arc.ArchiveUnsigned(&count);
298 arc.ArchiveUnsignedShort(&tableLengthIndex);
299
300 if (arc.Loading()) {
301 if (tableLength != 1) {
302 table = new (NewTable(tableLength)) Entry *[tableLength]();
303 memset(table, 0, tableLength * sizeof(Entry *));
304 }
305
306 for (i = 0; i < count; i++) {
307 e = new Entry;
308 e->Archive(arc);
309
310 hash = HashCode<key>(e->GetKey()) % tableLength;
311
312 e->next = table[hash];
313 table[hash] = e;
314 }
315
316 defaultEntry = e;
317 } else {
318# ifndef NDEBUG
319 int total;
320
321 total = 0;
322
323 for (i = 0; i < tableLength; i++) {
324 for (e = table[i]; e != NULL; e = e->next) {
325 e->Archive(arc);
326 total++;
327 }
328 }
329 // it must match the number of elements
330 assert(total == count);
331# else
332 for (i = 0; i < tableLength; i++) {
333 for (e = table[i]; e != NULL; e = e->next) {
334 e->Archive(arc);
335 }
336 }
337# endif
338 }
339}
340
341template<typename key, typename value>
342void con_map<key, value>::Archive(Archiver& arc)
343{
344 m_con_set.Archive(arc);
345}
346
347#endif
348
349#define ArchiveEnum(thing, type) \
350 { \
351 int tempInt; \
352 \
353 tempInt = (int)(thing); \
354 arc.ArchiveInteger(&tempInt); \
355 (thing) = (type)tempInt; \
356 }
357
358#define MAX_DEFERRED_SAVE_FILENAME 256
359
360extern byte *g_deferredSaveBuffer;
361extern size_t g_deferredSaveLength;
362extern char g_deferredSaveFilename[MAX_DEFERRED_SAVE_FILENAME];
363extern qboolean g_deferredSavePending;
364
365qboolean DeferredSave_Tick(int max_ms);
366void DeferredSave_Cancel(void);
367
368void Archive_StashValidatedLoad(const char *name, byte *buf, size_t len);
369void Archive_ClearPendingLoad(void);
Definition archive.h:59
Definition archive.h:87
Definition g_local.h:81
Definition archive.h:50