11
11
namespace l ::serialization {
12
12
const int32_t kHeaderIdentifier = 0x00defa00 ; // storage base file identifier
13
13
14
+ const int32_t kTinyHeaderIdentifier = 0xdf000000 ; // tiny identifier
15
+ const int32_t kTinyHeaderVersionMask = 0x00fff000 ;
16
+
14
17
bool HeaderValidity::Peek (std::vector<unsigned char >& data) {
15
18
if (data.size () < 4 * 2 ) { // identifier + version = 8 bytes
16
19
return false ;
@@ -30,6 +33,22 @@ namespace l::serialization {
30
33
return mVersion >= 0 && mVersion <= latestVersion;
31
34
}
32
35
36
+ bool TinyHeaderValidity::Peek (std::vector<unsigned char >& data) {
37
+ if (data.size () < 4 ) { // identifier + version = 8 bytes
38
+ return false ;
39
+ }
40
+ zpp::serializer::memory_input_archive_peek inPeek (data);
41
+ inPeek (*this );
42
+ return true ;
43
+ }
44
+
45
+ bool TinyHeaderValidity::IsIdentifierValid () {
46
+ return (mHeader & kTinyHeaderIdentifier ) == kTinyHeaderIdentifier ;
47
+ }
48
+ bool TinyHeaderValidity::IsVersionValid (int32_t minVersion, int32_t latestVersion) {
49
+ auto version = (mHeader & kTinyHeaderVersionMask ) >> 3 ;
50
+ return version >= minVersion && version <= latestVersion;
51
+ }
33
52
/* *****************************************************************************/
34
53
35
54
SerializationBase& SerializationBase::operator =(SerializationBase&& other) noexcept {
@@ -40,6 +59,9 @@ namespace l::serialization {
40
59
mUseIdentifier = other.mUseIdentifier ;
41
60
mUseVersion = other.mUseVersion ;
42
61
mUseFiletype = other.mUseFiletype ;
62
+ mUseTinyHeader = other.mUseTinyHeader ;
63
+ mExpectIdentifier = other.mExpectIdentifier ;
64
+ mExpectVersion = other.mExpectVersion ;
43
65
return *this ;
44
66
}
45
67
SerializationBase& SerializationBase::operator =(const SerializationBase& other) noexcept {
@@ -50,6 +72,9 @@ namespace l::serialization {
50
72
mUseIdentifier = other.mUseIdentifier ;
51
73
mUseVersion = other.mUseVersion ;
52
74
mUseFiletype = other.mUseFiletype ;
75
+ mUseTinyHeader = other.mUseTinyHeader ;
76
+ mExpectIdentifier = other.mExpectIdentifier ;
77
+ mExpectVersion = other.mExpectVersion ;
53
78
return *this ;
54
79
}
55
80
SerializationBase::SerializationBase (SerializationBase&& other) noexcept {
@@ -60,24 +85,57 @@ namespace l::serialization {
60
85
}
61
86
62
87
void SerializationBase::LoadArchiveData (std::vector<unsigned char >& data) {
63
- HeaderValidity headerValidity;
64
- bool peekSuccessful = headerValidity.Peek (data);
65
- if (peekSuccessful && headerValidity.IsIdentifierValid ()) {
66
- mUseIdentifier = true ;
67
- mUseVersion = true ;
88
+ // data should have identifier, but doesn't, or should not have identifier - don't load identifier (this is fine since we can determine if identifier is present or not)
89
+ // data should not have version - fine
90
+ // data should have version but doesn't - error (we can't know this)
91
+ // data should have version and seems to have version - load version (it is possible for false positives when checking for version in data so must be sure data contain version in this case)
92
+
93
+ // data should have identifier, and does - load identifier
94
+ // no - (data should not have version - fine)
95
+ // no - (data should have version but doesn't - error (we can't know this)) - it must be there
96
+ // data should have version and does - load version
97
+
98
+ if (mUseTinyHeader ) {
99
+
68
100
}
69
101
else {
70
- mUseIdentifier = false ;
71
- if (mUseVersion ) {
72
- ASSERT (peekSuccessful && headerValidity.IsVersionValid (mLatestVersion ));
102
+ HeaderValidity headerValidity;
103
+ bool peekSuccessful = headerValidity.Peek (data);
104
+ if (mExpectIdentifier ) {
105
+ if (!peekSuccessful || !headerValidity.IsIdentifierValid ()) {
106
+ LOG (LogError) << " Expected serialization identifier: " << headerValidity.mIdentifier << " (version: " << headerValidity.mVersion << " )" ;
107
+ return ;
108
+ }
109
+ if (!peekSuccessful || !headerValidity.IsVersionValid (mLatestVersion )) {
110
+ LOG (LogError) << " Expected serialization version: " << headerValidity.mVersion << " (identifier: " << headerValidity.mIdentifier << " )" ;
111
+ return ;
112
+ }
113
+ mUseIdentifier = true ; // if identifier is expected, we should continue using it even if user didn't not set it
114
+ mExpectIdentifier = true ;
115
+ mExpectVersion = true ;
116
+ mUseVersion = true ;
73
117
}
74
- }
118
+ else if (peekSuccessful && headerValidity.IsIdentifierValid ()) {
119
+ mUseIdentifier = true ;
120
+ mExpectIdentifier = true ;
121
+
122
+ if (!headerValidity.IsVersionValid (mLatestVersion )) {
123
+ LOG (LogError) << " Expected serialization version: " << headerValidity.mVersion ;
124
+ return ;
125
+ }
75
126
76
- zpp::serializer::memory_input_archive in (data);
77
- in (*this );
78
-
79
- mUseIdentifier = true ;
80
- mUseVersion = true ;
127
+ mExpectVersion = true ;
128
+ mUseVersion = true ;
129
+ }
130
+ else if (mExpectVersion ) {
131
+ if (!peekSuccessful || !headerValidity.IsVersionValid (mLatestVersion )) {
132
+ return ;
133
+ }
134
+ mUseVersion = true ; // if version is expected, we should continue using it even if user didn't not set it
135
+ }
136
+ zpp::serializer::memory_input_archive in (data);
137
+ in (*this );
138
+ }
81
139
}
82
140
83
141
void SerializationBase::GetArchiveData (std::vector<unsigned char >& data) {
@@ -89,6 +147,49 @@ namespace l::serialization {
89
147
return mVersion ;
90
148
}
91
149
150
+ void SerializationBase::SaveHandler (SaveArchive& saveArchive) const {
151
+ if (mUseTinyHeader ) {
152
+
153
+ }
154
+ else {
155
+ if (mUseIdentifier ) {
156
+ saveArchive (kHeaderIdentifier );
157
+ }
158
+ if (mUseVersion ) {
159
+ if (mVersion != mLatestVersion ) { // make sure version is latest version
160
+ int32_t * p = const_cast <int32_t *>(&mVersion );
161
+ *p = mLatestVersion ;
162
+ }
163
+ saveArchive (mVersion );
164
+ }
165
+ if (mUseFiletype ) {
166
+ saveArchive (mFiletype );
167
+ }
168
+ }
169
+ Save (saveArchive);
170
+ }
171
+
172
+ void SerializationBase::LoadHandler (LoadArchive& loadArchive) {
173
+ if (mUseTinyHeader ) {
174
+
175
+ }
176
+ else {
177
+ if (mExpectIdentifier ) {
178
+ int32_t fileIdentifier;
179
+ loadArchive (fileIdentifier);
180
+ ASSERT (fileIdentifier == kHeaderIdentifier );
181
+ }
182
+ if (mExpectVersion ) {
183
+ loadArchive (mVersion );
184
+ }
185
+ if (mUseFiletype ) {
186
+ loadArchive (mFiletype );
187
+ }
188
+ }
189
+ Load (loadArchive);
190
+ UpgradeToLatest ();
191
+ }
192
+
92
193
void SerializationBase::UpgradeToLatest () {
93
194
mLatestVersion = mVersion > mLatestVersion ? mVersion : mLatestVersion ;
94
195
if (mUseVersion ) {
@@ -99,5 +200,4 @@ namespace l::serialization {
99
200
mVersion = mVersion < mLatestVersion ? mLatestVersion : mVersion ;
100
201
}
101
202
102
-
103
203
}
0 commit comments