Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Toggle main menu visibility
Loading...
Searching...
No Matches
DB2FileLoader.cpp
Go to the documentation of this file.
1
/*
2
* This file is part of Project SkyFire https://www.projectskyfire.org.
3
* See LICENSE.md file for Copyright information
4
*/
5
6
#include "
Common.h
"
7
8
#include "
DB2FileLoader.h
"
9
#include <stdio.h>
10
#include <stdlib.h>
11
#include <string.h>
12
13
bool
DB2FileLoader::Load
(
const
char
* filename,
const
char
* fmt)
14
{
15
if
(
data
)
16
{
17
delete
[]
data
;
18
data
= NULL;
19
}
20
21
FILE* f = fopen(filename,
"rb"
);
22
if
(!f)
23
return
false
;
24
25
uint32
header;
26
if
(fread(&header, 4, 1, f) != 1)
// Signature
27
{
28
fclose(f);
29
return
false
;
30
}
31
32
EndianConvert
(header);
33
34
if
(header != 0x32424457)
35
{
36
fclose(f);
37
return
false
;
//'WDB2'
38
}
39
40
if
(fread(&
recordCount
, 4, 1, f) != 1)
// Number of records
41
{
42
fclose(f);
43
return
false
;
44
}
45
46
EndianConvert
(
recordCount
);
47
48
if
(fread(&
fieldCount
, 4, 1, f) != 1)
// Number of fields
49
{
50
fclose(f);
51
return
false
;
52
}
53
54
EndianConvert
(
fieldCount
);
55
56
if
(fread(&
recordSize
, 4, 1, f) != 1)
// Size of a record
57
{
58
fclose(f);
59
return
false
;
60
}
61
62
EndianConvert
(
recordSize
);
63
64
if
(fread(&
stringSize
, 4, 1, f) != 1)
// String size
65
{
66
fclose(f);
67
return
false
;
68
}
69
70
EndianConvert
(
stringSize
);
71
72
/* NEW WDB2 FIELDS*/
73
if
(fread(&
tableHash
, 4, 1, f) != 1)
// Table hash
74
{
75
fclose(f);
76
return
false
;
77
}
78
79
EndianConvert
(
tableHash
);
80
81
if
(fread(&
build
, 4, 1, f) != 1)
// Build
82
{
83
fclose(f);
84
return
false
;
85
}
86
87
EndianConvert
(
build
);
88
89
if
(fread(&
unk1
, 4, 1, f) != 1)
// Unknown WDB2
90
{
91
fclose(f);
92
return
false
;
93
}
94
95
EndianConvert
(
unk1
);
96
97
if
(
build
> 12880)
98
{
99
if
(fread(&
minIndex
, 4, 1, f) != 1)
// MinIndex WDB2
100
{
101
fclose(f);
102
return
false
;
103
}
104
EndianConvert
(
minIndex
);
105
106
if
(fread(&
maxIndex
, 4, 1, f) != 1)
// MaxIndex WDB2
107
{
108
fclose(f);
109
return
false
;
110
}
111
EndianConvert
(
maxIndex
);
112
113
if
(fread(&
locale
, 4, 1, f) != 1)
// Locales
114
{
115
fclose(f);
116
return
false
;
117
}
118
EndianConvert
(
locale
);
119
120
if
(fread(&
unk5
, 4, 1, f) != 1)
// Unknown WDB2
121
{
122
fclose(f);
123
return
false
;
124
}
125
EndianConvert
(
unk5
);
126
}
127
128
if
(
maxIndex
!= 0)
129
{
130
int32
diff =
maxIndex
-
minIndex
+ 1;
131
fseek(f, diff * 4 + diff * 2, SEEK_CUR);
// diff * 4: an index for rows, diff * 2: a memory allocation bank
132
}
133
134
fieldsOffset
=
new
uint32
[
fieldCount
];
135
fieldsOffset
[0] = 0;
136
for
(
uint32
i = 1; i <
fieldCount
; i++)
137
{
138
fieldsOffset
[i] =
fieldsOffset
[i - 1];
139
if
(fmt[i - 1] ==
'b'
|| fmt[i - 1] ==
'X'
)
140
fieldsOffset
[i] += 1;
141
else
142
fieldsOffset
[i] += 4;
143
}
144
145
data
=
new
unsigned
char
[
recordSize
*
recordCount
+
stringSize
];
146
stringTable
=
data
+
recordSize
*
recordCount
;
147
148
if
(fread(
data
,
recordSize
*
recordCount
+
stringSize
, 1, f) != 1)
149
{
150
fclose(f);
151
return
false
;
152
}
153
154
fclose(f);
155
return
true
;
156
}
157
158
DB2FileLoader::~DB2FileLoader
()
159
{
160
if
(
data
)
161
delete
[]
data
;
162
if
(
fieldsOffset
)
163
delete
[]
fieldsOffset
;
164
}
165
166
DB2FileLoader::Record
DB2FileLoader::getRecord
(
size_t
id
)
167
{
168
assert(
data
);
169
return
Record
(*
this
,
data
+
id
*
recordSize
);
170
}
171
172
uint32
DB2FileLoader::GetFormatRecordSize
(std::string format,
int32
* index_pos)
173
{
174
uint32
recordsize = 0;
175
int32
i = -1;
176
for
(
uint32
x = 0; format[x]; ++x)
177
{
178
switch
(format[x])
179
{
180
case
FT_FLOAT
:
181
case
FT_INT
:
182
recordsize += 4;
183
break
;
184
case
FT_STRING
:
185
recordsize +=
sizeof
(
char
*);
186
break
;
187
case
FT_SORT
:
188
i = x;
189
break
;
190
case
FT_IND
:
191
i = x;
192
recordsize += 4;
193
break
;
194
case
FT_BYTE
:
195
recordsize += 1;
196
break
;
197
}
198
}
199
200
if
(index_pos)
201
*index_pos = i;
202
203
return
recordsize;
204
}
205
206
uint32
DB2FileLoader::GetFormatStringsFields
(std::string format)
207
{
208
uint32
stringfields = 0;
209
for
(
uint32
x = 0; format[x]; ++x)
210
if
(format[x] ==
FT_STRING
)
211
++stringfields;
212
213
return
stringfields;
214
}
215
216
char
*
DB2FileLoader::AutoProduceData
(std::string format,
uint32
& records,
char
**& indexTable)
217
{
218
typedef
char
* ptr;
219
if
(format.length() !=
fieldCount
)
220
return
NULL;
221
222
//get struct size and index pos
223
int32
i;
224
uint32
recordsize =
GetFormatRecordSize
(format, &i);
225
226
if
(i >= 0)
227
{
228
uint32
maxi = 0;
229
//find max index
230
for
(
uint32
y = 0; y <
recordCount
; y++)
231
{
232
uint32
ind =
getRecord
(y).
getUInt
(i);
233
if
(ind > maxi)
234
maxi = ind;
235
}
236
237
++maxi;
238
records = maxi;
239
indexTable =
new
ptr[maxi];
240
memset(indexTable, 0, maxi *
sizeof
(ptr));
241
}
242
else
243
{
244
records =
recordCount
;
245
indexTable =
new
ptr[
recordCount
];
246
}
247
248
char
* dataTable =
new
char
[
recordCount
* recordsize];
249
250
uint32
offset = 0;
251
252
for
(
uint32
y = 0; y <
recordCount
; y++)
253
{
254
if
(i >= 0)
255
{
256
indexTable[
getRecord
(y).
getUInt
(i)] = &dataTable[offset];
257
}
258
else
259
indexTable[y] = &dataTable[offset];
260
261
for
(
uint32
x = 0; x <
fieldCount
; x++)
262
{
263
switch
(format[x])
264
{
265
case
FT_FLOAT
:
266
*((
float
*)(&dataTable[offset])) =
getRecord
(y).
getFloat
(x);
267
offset += 4;
268
break
;
269
case
FT_IND
:
270
case
FT_INT
:
271
*((
uint32
*)(&dataTable[offset])) =
getRecord
(y).
getUInt
(x);
272
offset += 4;
273
break
;
274
case
FT_BYTE
:
275
*((
uint8
*)(&dataTable[offset])) =
getRecord
(y).
getUInt8
(x);
276
offset += 1;
277
break
;
278
case
FT_STRING
:
279
*((
char
**)(&dataTable[offset])) = NULL;
// will be replaces non-empty or "" strings in AutoProduceStrings
280
offset +=
sizeof
(
char
*);
281
break
;
282
}
283
}
284
}
285
286
return
dataTable;
287
}
288
289
static
char
const
*
const
nullStr
=
""
;
290
291
char
*
DB2FileLoader::AutoProduceStringsArrayHolders
(std::string format,
char
* dataTable)
292
{
293
if
(format.length() !=
fieldCount
)
294
return
NULL;
295
296
// we store flat holders pool as single memory block
297
size_t
stringFields =
GetFormatStringsFields
(format);
298
// each string field at load have array of string for each locale
299
size_t
stringHolderSize =
sizeof
(
char
*) *
TOTAL_LOCALES
;
300
size_t
stringHoldersRecordPoolSize = stringFields * stringHolderSize;
301
size_t
stringHoldersPoolSize = stringHoldersRecordPoolSize *
recordCount
;
302
303
char
* stringHoldersPool =
new
char
[stringHoldersPoolSize];
304
305
// DB2 strings expected to have at least empty string
306
for
(
size_t
i = 0; i < stringHoldersPoolSize /
sizeof
(
char
*); ++i)
307
((
char
const
**)stringHoldersPool)[i] =
nullStr
;
308
309
uint32
offset = 0;
310
311
// assign string holders to string field slots
312
for
(
uint32
y = 0; y <
recordCount
; y++)
313
{
314
uint32
stringFieldNum = 0;
315
316
for
(
uint32
x = 0; x <
fieldCount
; x++)
317
switch
(format[x])
318
{
319
case
FT_FLOAT
:
320
case
FT_IND
:
321
case
FT_INT
:
322
offset += 4;
323
break
;
324
case
FT_BYTE
:
325
offset += 1;
326
break
;
327
case
FT_STRING
:
328
{
329
// init db2 string field slots by pointers to string holders
330
char
const
*** slot = (
char
const
***)(&dataTable[offset]);
331
*slot = (
char
const
**)(&stringHoldersPool[stringHoldersRecordPoolSize * y + stringHolderSize * stringFieldNum]);
332
++stringFieldNum;
333
offset +=
sizeof
(
char
*);
334
break
;
335
}
336
case
FT_NA
:
337
case
FT_NA_BYTE
:
338
case
FT_SORT
:
339
break
;
340
default
:
341
assert(
false
&&
"unknown format character"
);
342
}
343
}
344
345
//send as char* for store in char* pool list for free at unload
346
return
stringHoldersPool;
347
}
348
349
char
*
DB2FileLoader::AutoProduceStrings
(std::string format,
char
* dataTable,
uint32
locale
)
350
{
351
if
(format.length() !=
fieldCount
)
352
return
NULL;
353
354
char
* stringPool =
new
char
[
stringSize
];
355
memcpy(stringPool,
stringTable
,
stringSize
);
356
357
uint32
offset = 0;
358
359
for
(
uint32
y = 0; y <
recordCount
; y++)
360
{
361
for
(
uint32
x = 0; x <
fieldCount
; x++)
362
switch
(format[x])
363
{
364
case
FT_FLOAT
:
365
case
FT_IND
:
366
case
FT_INT
:
367
offset += 4;
368
break
;
369
case
FT_BYTE
:
370
offset += 1;
371
break
;
372
case
FT_STRING
:
373
{
374
// fill only not filled entries
375
LocalizedString
* db2str = *(
LocalizedString
**)(&dataTable[offset]);
376
if
(db2str->
Str
[
locale
] ==
nullStr
)
377
{
378
const
char
* st =
getRecord
(y).
getString
(x);
379
db2str->
Str
[
locale
] = stringPool + (st - (
const
char
*)
stringTable
);
380
}
381
382
offset +=
sizeof
(
char
*);
383
break
;
384
}
385
}
386
}
387
388
return
stringPool;
389
}
EndianConvert
void EndianConvert(T &)
Definition
ByteConverter.h:40
Common.h
TOTAL_LOCALES
const uint8 TOTAL_LOCALES
Definition
Common.h:153
nullStr
static char const *const nullStr
Definition
DB2FileLoader.cpp:289
DB2FileLoader.h
int32
std::int32_t int32
Definition
Define.h:73
uint8
std::uint8_t uint8
Definition
Define.h:79
uint32
std::uint32_t uint32
Definition
Define.h:77
FT_IND
@ FT_IND
Definition
Define.h:90
FT_NA
@ FT_NA
Definition
Define.h:83
FT_FLOAT
@ FT_FLOAT
Definition
Define.h:86
FT_STRING
@ FT_STRING
Definition
Define.h:85
FT_SORT
@ FT_SORT
Definition
Define.h:89
FT_NA_BYTE
@ FT_NA_BYTE
Definition
Define.h:84
FT_INT
@ FT_INT
Definition
Define.h:87
FT_BYTE
@ FT_BYTE
Definition
Define.h:88
DB2FileLoader::Record
Definition
DB2FileLoader.h:25
DB2FileLoader::Record::getFloat
float getFloat(size_t field) const
Definition
DB2FileLoader.h:27
DB2FileLoader::Record::getUInt8
uint8 getUInt8(size_t field) const
Definition
DB2FileLoader.h:41
DB2FileLoader::Record::getUInt
uint32 getUInt(size_t field) const
Definition
DB2FileLoader.h:34
DB2FileLoader::Record::getString
const char * getString(size_t field) const
Definition
DB2FileLoader.h:47
DB2FileLoader::GetFormatStringsFields
static uint32 GetFormatStringsFields(std::string format)
Definition
DB2FileLoader.cpp:206
DB2FileLoader::data
unsigned char * data
Definition
DB2FileLoader.h:84
DB2FileLoader::~DB2FileLoader
~DB2FileLoader()
Definition
DB2FileLoader.cpp:158
DB2FileLoader::GetFormatRecordSize
static uint32 GetFormatRecordSize(std::string format, int32 *index_pos=NULL)
Definition
DB2FileLoader.cpp:172
DB2FileLoader::tableHash
uint32 tableHash
Definition
DB2FileLoader.h:88
DB2FileLoader::Load
bool Load(const char *filename, const char *fmt)
Definition
DB2FileLoader.cpp:13
DB2FileLoader::build
uint32 build
Definition
DB2FileLoader.h:89
DB2FileLoader::recordSize
uint32 recordSize
Definition
DB2FileLoader.h:79
DB2FileLoader::AutoProduceStrings
char * AutoProduceStrings(std::string fmt, char *dataTable, uint32 locale)
Definition
DB2FileLoader.cpp:349
DB2FileLoader::AutoProduceData
char * AutoProduceData(std::string fmt, uint32 &count, char **&indexTable)
Definition
DB2FileLoader.cpp:216
DB2FileLoader::locale
int locale
Definition
DB2FileLoader.h:94
DB2FileLoader::recordCount
uint32 recordCount
Definition
DB2FileLoader.h:80
DB2FileLoader::getRecord
Record getRecord(size_t id)
Definition
DB2FileLoader.cpp:166
DB2FileLoader::stringTable
unsigned char * stringTable
Definition
DB2FileLoader.h:85
DB2FileLoader::stringSize
uint32 stringSize
Definition
DB2FileLoader.h:82
DB2FileLoader::unk5
int unk5
Definition
DB2FileLoader.h:95
DB2FileLoader::fieldCount
uint32 fieldCount
Definition
DB2FileLoader.h:81
DB2FileLoader::maxIndex
int maxIndex
Definition
DB2FileLoader.h:93
DB2FileLoader::fieldsOffset
uint32 * fieldsOffset
Definition
DB2FileLoader.h:83
DB2FileLoader::minIndex
int minIndex
Definition
DB2FileLoader.h:92
DB2FileLoader::AutoProduceStringsArrayHolders
char * AutoProduceStringsArrayHolders(std::string fmt, char *dataTable)
Definition
DB2FileLoader.cpp:291
DB2FileLoader::unk1
int unk1
Definition
DB2FileLoader.h:91
LocalizedString
Definition
Common.h:172
LocalizedString::Str
char const * Str[TOTAL_LOCALES]
Definition
Common.h:173
src
server
shared
DataStores
DB2FileLoader.cpp
Generated on
for Project SkyFire Core by
1.17.0