forked from ChrisRyan98008/NwCpp-May2020
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathArchive.cpp
146 lines (136 loc) · 3.12 KB
/
Archive.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include "Archive.h"
using namespace Serialize;
//Archive non-templatized implementations
void Archive::Reset()
{
_mapTypeId.clear();
_mapObjShared.clear();
_mapIdType.clear();
_mapIdObj.clear();
_mapObjId.clear();
_mapIdObj[ID_NULL] = nullptr;
_mapObjId[nullptr] = ID_NULL;
_nextObjId = ID_START;
_nextTypeId = ID_START;
_hash = BIG_PRIME;
_error = 0;
}
bool Archive::CheckPoint()
{
if(IsError()) return false;
switch(_mode)
{
case SaveArchive:
Save(_hash);
return true;
case LoadArchive:
{
uint32 hash = _hash;
uint32 fileHash = {};
Load(fileHash);
if(fileHash == hash)
return true;
}
default:
break;
}
Error();
return false;
}
void Archive::Save(std::string& str)
{
if(IsError()) return;
uint32 size = uint32(str.length());
SaveDint(size);
if(size && (save((BYTE*)str.data(), size) != int32(size)))
return Error();
}
void Archive::Load(std::string& str)
{
if(IsError()) return;
uint32 size = LoadDint();
str.clear();
if(size)
{
std::string str2(size + 1, '\0');
if(load((BYTE*)str2.data(), size) != int32(size))
return Error();
str.swap(str2);
}
}
void Archive::Save(void* pVoid, uint32 size)
{
if(IsError()) return;
SaveDint(size);
if(size && (save(pVoid, size) != int32(size)))
return Error();
}
void Archive::Load(void* pVoid, uint32 size)
{
if(IsError()) return;
uint32 arcSize = LoadDint();
if(arcSize > size)
return Error();
if(arcSize && (load(pVoid, arcSize) != int32(arcSize)))
return Error();
}
void Archive::SaveType(SerializableBase* pObj)
{
const TypeInfo* pTypeInfo = pObj->GetTypeInfo();
TypeId& typeId = _mapTypeId[pTypeInfo];
if(typeId)
SaveDint(typeId);
else
{
typeId = _nextTypeId++;
SaveDint(typeId);
HASH hash = pTypeInfo->Hash();
Save(hash);
}
}
const TypeInfo* Archive::LoadType()
{
TypeId typeId = LoadDint();
const TypeInfo*& pTypeInfo = _mapIdType[typeId];
if(!pTypeInfo)
{
HASH hash = 0;
Load(hash);
pTypeInfo = TypeInfo::Find(hash);
}
return pTypeInfo;
}
void Archive::SaveDint(uint32 dint)
{
do
{
uint8 u8 = uint8(dint & 0x7f);
dint >>= 7;
if(!dint) u8 |= 0x80;
save(&u8, sizeof(u8));
} while(dint);
}
uint32 Archive::LoadDint()
{
uint32 dint = 0;
uint32 shift = 0;
uint8 u8 = 0;
do
{
load(&u8, sizeof(u8));
dint |= (uint32(u8 & 0x7f) << shift);
shift += 7;
} while(!(u8 & 0x80));
return dint;
}
int32 Archive::save(void* pData, uint32 size)
{
Hash((BYTE*)pData, size);
return _source.save(pData, size);
}
int32 Archive::load(void* pData, uint32 size)
{
int32 ret = _source.load(pData, size);
Hash((BYTE*)pData, size);
return ret;
}