Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Toggle main menu visibility
Loading...
Searching...
No Matches
DBCFileLoader.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 <stdio.h>
7
#include <stdlib.h>
8
#include <string.h>
9
10
#include "
DBCFileLoader.h
"
11
#include "
Errors.h
"
12
13
DBCFileLoader::DBCFileLoader
() :
recordSize
(0),
recordCount
(0),
fieldCount
(0),
stringSize
(0),
fieldsOffset
(NULL),
data
(NULL),
stringTable
(NULL) { }
14
15
bool
DBCFileLoader::Load
(
const
char
* filename,
const
char
* fmt)
16
{
17
uint32
header;
18
if
(
data
)
19
{
20
delete
[]
data
;
21
data
= NULL;
22
}
23
24
FILE* f = fopen(filename,
"rb"
);
25
if
(!f)
26
return
false
;
27
28
if
(fread(&header, 4, 1, f) != 1)
// Number of records
29
{
30
fclose(f);
31
return
false
;
32
}
33
34
35
EndianConvert
(header);
36
37
if
(header != 0x43424457)
//'WDBC'
38
{
39
fclose(f);
40
return
false
;
41
}
42
43
if
(fread(&
recordCount
, 4, 1, f) != 1)
// Number of records
44
{
45
fclose(f);
46
return
false
;
47
}
48
49
EndianConvert
(
recordCount
);
50
51
if
(fread(&
fieldCount
, 4, 1, f) != 1)
// Number of fields
52
{
53
fclose(f);
54
return
false
;
55
}
56
57
EndianConvert
(
fieldCount
);
58
59
if
(fread(&
recordSize
, 4, 1, f) != 1)
// Size of a record
60
{
61
fclose(f);
62
return
false
;
63
}
64
65
EndianConvert
(
recordSize
);
66
67
if
(fread(&
stringSize
, 4, 1, f) != 1)
// String size
68
{
69
fclose(f);
70
return
false
;
71
}
72
73
EndianConvert
(
stringSize
);
74
75
fieldsOffset
=
new
uint32
[
fieldCount
];
76
fieldsOffset
[0] = 0;
77
for
(
uint32
i = 1; i <
fieldCount
; ++i)
78
{
79
fieldsOffset
[i] =
fieldsOffset
[i - 1];
80
if
(fmt[i - 1] ==
'b'
|| fmt[i - 1] ==
'X'
)
// byte fields
81
fieldsOffset
[i] +=
sizeof
(
uint8
);
82
else
// 4 byte fields (int32/float/strings)
83
fieldsOffset
[i] +=
sizeof
(
uint32
);
84
}
85
86
data
=
new
unsigned
char
[
recordSize
*
recordCount
+
stringSize
];
87
stringTable
=
data
+
recordSize
*
recordCount
;
88
89
if
(fread(
data
,
recordSize
*
recordCount
+
stringSize
, 1, f) != 1)
90
{
91
fclose(f);
92
return
false
;
93
}
94
95
fclose(f);
96
97
return
true
;
98
}
99
100
DBCFileLoader::~DBCFileLoader
()
101
{
102
if
(
data
)
103
delete
[]
data
;
104
105
if
(
fieldsOffset
)
106
delete
[]
fieldsOffset
;
107
}
108
109
DBCFileLoader::Record
DBCFileLoader::getRecord
(
size_t
id
)
110
{
111
assert(
data
);
112
return
Record
(*
this
,
data
+
id
*
recordSize
);
113
}
114
115
uint32
DBCFileLoader::GetFormatRecordSize
(std::string format,
int32
* index_pos)
116
{
117
uint32
recordsize = 0;
118
int32
i = -1;
119
for
(
uint32
x = 0; format[x]; ++x)
120
{
121
switch
(format[x])
122
{
123
case
FT_FLOAT
:
124
recordsize +=
sizeof
(float);
125
break
;
126
case
FT_INT
:
127
recordsize +=
sizeof
(
uint32
);
128
break
;
129
case
FT_STRING
:
130
recordsize +=
sizeof
(
char
*);
131
break
;
132
case
FT_SORT
:
133
i = x;
134
break
;
135
case
FT_IND
:
136
i = x;
137
recordsize +=
sizeof
(
uint32
);
138
break
;
139
case
FT_BYTE
:
140
recordsize +=
sizeof
(
uint8
);
141
break
;
142
case
FT_NA
:
143
case
FT_NA_BYTE
:
144
break
;
145
default
:
146
ASSERT
(
false
&&
"Unknown field format character in DBCfmt.h"
);
147
break
;
148
}
149
}
150
151
if
(index_pos)
152
*index_pos = i;
153
154
return
recordsize;
155
}
156
157
char
*
DBCFileLoader::AutoProduceData
(std::string format,
uint32
& records,
char
**& indexTable,
uint32
sqlRecordCount,
uint32
sqlHighestIndex,
char
*& sqlDataTable)
158
{
159
/*
160
format STRING, NA, FLOAT, NA, INT <=>
161
struct{
162
char* field0,
163
float field1,
164
int field2
165
}entry;
166
167
this func will generate entry[rows] data;
168
*/
169
170
typedef
char
* ptr;
171
if
(format.length() !=
fieldCount
)
172
return
NULL;
173
174
//get struct size and index pos
175
int32
i;
176
uint32
recordsize =
GetFormatRecordSize
(format, &i);
177
178
if
(i >= 0)
179
{
180
uint32
maxi = 0;
181
//find max index
182
for
(
uint32
y = 0; y <
recordCount
; ++y)
183
{
184
uint32
ind =
getRecord
(y).
getUInt
(i);
185
if
(ind > maxi)
186
maxi = ind;
187
}
188
189
// If higher index avalible from sql - use it instead of dbcs
190
if
(sqlHighestIndex > maxi)
191
maxi = sqlHighestIndex;
192
193
++maxi;
194
records = maxi;
195
indexTable =
new
ptr[maxi];
196
memset(indexTable, 0, maxi *
sizeof
(ptr));
197
}
198
else
199
{
200
records =
recordCount
+ sqlRecordCount;
201
indexTable =
new
ptr[
recordCount
+ sqlRecordCount];
202
}
203
204
char
* dataTable =
new
char
[(
recordCount
+ sqlRecordCount) * recordsize];
205
206
uint32
offset = 0;
207
208
for
(
uint32
y = 0; y <
recordCount
; ++y)
209
{
210
if
(i >= 0)
211
indexTable[
getRecord
(y).
getUInt
(i)] = &dataTable[offset];
212
else
213
indexTable[y] = &dataTable[offset];
214
215
for
(
uint32
x = 0; x <
fieldCount
; ++x)
216
{
217
switch
(format[x])
218
{
219
case
FT_FLOAT
:
220
*((
float
*)(&dataTable[offset])) =
getRecord
(y).
getFloat
(x);
221
offset +=
sizeof
(float);
222
break
;
223
case
FT_IND
:
224
case
FT_INT
:
225
*((
uint32
*)(&dataTable[offset])) =
getRecord
(y).
getUInt
(x);
226
offset +=
sizeof
(
uint32
);
227
break
;
228
case
FT_BYTE
:
229
*((
uint8
*)(&dataTable[offset])) =
getRecord
(y).
getUInt8
(x);
230
offset +=
sizeof
(
uint8
);
231
break
;
232
case
FT_STRING
:
233
*((
char
**)(&dataTable[offset])) = NULL;
// will replace non-empty or "" strings in AutoProduceStrings
234
offset +=
sizeof
(
char
*);
235
break
;
236
case
FT_NA
:
237
case
FT_NA_BYTE
:
238
case
FT_SORT
:
239
break
;
240
default
:
241
ASSERT
(
false
&&
"Unknown field format character in DBCfmt.h"
);
242
break
;
243
}
244
}
245
}
246
247
sqlDataTable = dataTable + offset;
248
249
return
dataTable;
250
}
251
252
char
*
DBCFileLoader::AutoProduceStrings
(std::string format,
char
* dataTable)
253
{
254
if
(format.length() !=
fieldCount
)
255
return
NULL;
256
257
char
* stringPool =
new
char
[
stringSize
];
258
memcpy(stringPool,
stringTable
,
stringSize
);
259
260
uint32
offset = 0;
261
262
for
(
uint32
y = 0; y <
recordCount
; ++y)
263
{
264
for
(
uint32
x = 0; x <
fieldCount
; ++x)
265
{
266
switch
(format[x])
267
{
268
case
FT_FLOAT
:
269
offset +=
sizeof
(float);
270
break
;
271
case
FT_IND
:
272
case
FT_INT
:
273
offset +=
sizeof
(
uint32
);
274
break
;
275
case
FT_BYTE
:
276
offset +=
sizeof
(
uint8
);
277
break
;
278
case
FT_STRING
:
279
{
280
// fill only not filled entries
281
char
** slot = (
char
**)(&dataTable[offset]);
282
if
(!*slot || !**slot)
283
{
284
const
char
* st =
getRecord
(y).
getString
(x);
285
*slot = stringPool + (st - (
const
char
*)
stringTable
);
286
}
287
offset +=
sizeof
(
char
*);
288
break
;
289
}
290
case
FT_NA
:
291
case
FT_NA_BYTE
:
292
case
FT_SORT
:
293
break
;
294
default
:
295
ASSERT
(
false
&&
"Unknown field format character in DBCfmt.h"
);
296
break
;
297
}
298
}
299
}
300
301
return
stringPool;
302
}
EndianConvert
void EndianConvert(T &)
Definition
ByteConverter.h:40
DBCFileLoader.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
Errors.h
ASSERT
#define ASSERT
Definition
Errors.h:29
DBCFileLoader::Record
Definition
DBCFileLoader.h:22
DBCFileLoader::Record::getString
const char * getString(size_t field) const
Definition
DBCFileLoader.h:44
DBCFileLoader::Record::getUInt
uint32 getUInt(size_t field) const
Definition
DBCFileLoader.h:31
DBCFileLoader::Record::getFloat
float getFloat(size_t field) const
Definition
DBCFileLoader.h:24
DBCFileLoader::Record::getUInt8
uint8 getUInt8(size_t field) const
Definition
DBCFileLoader.h:38
DBCFileLoader::stringSize
uint32 stringSize
Definition
DBCFileLoader.h:77
DBCFileLoader::data
unsigned char * data
Definition
DBCFileLoader.h:79
DBCFileLoader::recordCount
uint32 recordCount
Definition
DBCFileLoader.h:75
DBCFileLoader::getRecord
Record getRecord(size_t id)
Definition
DBCFileLoader.cpp:109
DBCFileLoader::~DBCFileLoader
~DBCFileLoader()
Definition
DBCFileLoader.cpp:100
DBCFileLoader::Load
bool Load(const char *filename, const char *fmt)
Definition
DBCFileLoader.cpp:15
DBCFileLoader::stringTable
unsigned char * stringTable
Definition
DBCFileLoader.h:80
DBCFileLoader::fieldsOffset
uint32 * fieldsOffset
Definition
DBCFileLoader.h:78
DBCFileLoader::fieldCount
uint32 fieldCount
Definition
DBCFileLoader.h:76
DBCFileLoader::DBCFileLoader
DBCFileLoader()
Definition
DBCFileLoader.cpp:13
DBCFileLoader::recordSize
uint32 recordSize
Definition
DBCFileLoader.h:74
DBCFileLoader::AutoProduceData
char * AutoProduceData(std::string fmt, uint32 &count, char **&indexTable, uint32 sqlRecordCount, uint32 sqlHighestIndex, char *&sqlDataTable)
Definition
DBCFileLoader.cpp:157
DBCFileLoader::GetFormatRecordSize
static uint32 GetFormatRecordSize(std::string format, int32 *index_pos=NULL)
Definition
DBCFileLoader.cpp:115
DBCFileLoader::AutoProduceStrings
char * AutoProduceStrings(std::string fmt, char *dataTable)
Definition
DBCFileLoader.cpp:252
src
server
shared
DataStores
DBCFileLoader.cpp
Generated on
for Project SkyFire Core by
1.17.0