AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
DBCFileLoader Class Reference

#include "DBCFileLoader.h"

Classes

class  Record
 

Public Member Functions

 DBCFileLoader ()
 
 ~DBCFileLoader ()
 
bool Load (const char *filename, const char *fmt)
 
Record getRecord (std::size_t id)
 
uint32 GetNumRows () const
 
uint32 GetRowSize () const
 
uint32 GetCols () const
 
uint32 GetOffset (std::size_t id) const
 
bool IsLoaded () const
 
char * AutoProduceData (char const *fmt, uint32 &count, char **&indexTable)
 
char * AutoProduceStrings (char const *fmt, char *dataTable)
 

Static Public Member Functions

static uint32 GetFormatRecordSize (const char *format, int32 *index_pos=nullptr)
 

Private Member Functions

 DBCFileLoader (DBCFileLoader const &right)=delete
 
DBCFileLoaderoperator= (DBCFileLoader const &right)=delete
 

Private Attributes

uint32 recordSize
 
uint32 recordCount
 
uint32 fieldCount
 
uint32 stringSize
 
uint32fieldsOffset
 
unsigned char * data
 
unsigned char * stringTable
 

Detailed Description

Constructor & Destructor Documentation

◆ DBCFileLoader() [1/2]

DBCFileLoader::DBCFileLoader ( )
23: recordSize(0), recordCount(0), fieldCount(0), stringSize(0), fieldsOffset(nullptr), data(nullptr), stringTable(nullptr) { }
uint32 stringSize
Definition: DBCFileLoader.h:103
unsigned char * data
Definition: DBCFileLoader.h:105
uint32 recordCount
Definition: DBCFileLoader.h:101
unsigned char * stringTable
Definition: DBCFileLoader.h:106
uint32 * fieldsOffset
Definition: DBCFileLoader.h:104
uint32 fieldCount
Definition: DBCFileLoader.h:102
uint32 recordSize
Definition: DBCFileLoader.h:100

◆ ~DBCFileLoader()

DBCFileLoader::~DBCFileLoader ( )
117{
118 delete[] data;
119
120 delete[] fieldsOffset;
121}

References data, and fieldsOffset.

◆ DBCFileLoader() [2/2]

DBCFileLoader::DBCFileLoader ( DBCFileLoader const &  right)
privatedelete

Member Function Documentation

◆ AutoProduceData()

char * DBCFileLoader::AutoProduceData ( char const *  fmt,
uint32 count,
char **&  indexTable 
)
178{
179 /*
180 format STRING, NA, FLOAT, NA, INT <=>
181 struct{
182 char* field0,
183 float field1,
184 int field2
185 }entry;
186
187 this func will generate entry[rows] data;
188 */
189
190 typedef char* ptr;
191 if (strlen(format) != fieldCount)
192 {
193 return nullptr;
194 }
195
196 //get struct size and index pos
197 int32 i;
198 uint32 recordsize = GetFormatRecordSize(format, &i);
199
200 if (i >= 0)
201 {
202 uint32 maxi = 0;
203 //find max index
204 for (uint32 y = 0; y < recordCount; ++y)
205 {
206 uint32 ind = getRecord(y).getUInt(i);
207 if (ind > maxi)
208 {
209 maxi = ind;
210 }
211 }
212
213 ++maxi;
214 records = maxi;
215 indexTable = new ptr[maxi];
216 memset(indexTable, 0, maxi * sizeof(ptr));
217 }
218 else
219 {
220 records = recordCount;
221 indexTable = new ptr[recordCount];
222 }
223
224 char* dataTable = new char[recordCount * recordsize];
225
226 uint32 offset = 0;
227
228 for (uint32 y = 0; y < recordCount; ++y)
229 {
230 if (i >= 0)
231 {
232 indexTable[getRecord(y).getUInt(i)] = &dataTable[offset];
233 }
234 else
235 {
236 indexTable[y] = &dataTable[offset];
237 }
238
239 for (uint32 x = 0; x < fieldCount; ++x)
240 {
241 switch (format[x])
242 {
243 case FT_FLOAT:
244 *((float*)(&dataTable[offset])) = getRecord(y).getFloat(x);
245 offset += sizeof(float);
246 break;
247 case FT_IND:
248 case FT_INT:
249 *((uint32*)(&dataTable[offset])) = getRecord(y).getUInt(x);
250 offset += sizeof(uint32);
251 break;
252 case FT_BYTE:
253 *((uint8*)(&dataTable[offset])) = getRecord(y).getUInt8(x);
254 offset += sizeof(uint8);
255 break;
256 case FT_STRING:
257 *((char**)(&dataTable[offset])) = nullptr; // will replace non-empty or "" strings in AutoProduceStrings
258 offset += sizeof(char*);
259 break;
260 case FT_LOGIC:
261 ASSERT(false && "Attempted to load DBC files that do not have field types that match what is in the core. Check DBCfmt.h or your DBC files.");
262 break;
263 case FT_NA:
264 case FT_NA_BYTE:
265 case FT_SORT:
266 break;
267 default:
268 ASSERT(false && "Unknown field format character in DBCfmt.h");
269 break;
270 }
271 }
272 }
273
274 return dataTable;
275}
@ FT_IND
Definition: DBCFileLoader.h:34
@ FT_NA
Definition: DBCFileLoader.h:27
@ FT_FLOAT
Definition: DBCFileLoader.h:30
@ FT_STRING
Definition: DBCFileLoader.h:29
@ FT_SORT
Definition: DBCFileLoader.h:33
@ FT_NA_BYTE
Definition: DBCFileLoader.h:28
@ FT_INT
Definition: DBCFileLoader.h:31
@ FT_LOGIC
Definition: DBCFileLoader.h:35
@ FT_BYTE
Definition: DBCFileLoader.h:32
std::int32_t int32
Definition: Define.h:103
std::uint8_t uint8
Definition: Define.h:109
std::uint32_t uint32
Definition: Define.h:107
#define ASSERT
Definition: Errors.h:68
static uint32 GetFormatRecordSize(const char *format, int32 *index_pos=nullptr)
Definition: DBCFileLoader.cpp:129
Record getRecord(std::size_t id)
Definition: DBCFileLoader.cpp:123
float getFloat(std::size_t field) const
Definition: DBCFileLoader.h:49
uint32 getUInt(std::size_t field) const
Definition: DBCFileLoader.h:57
uint8 getUInt8(std::size_t field) const
Definition: DBCFileLoader.h:65

References ASSERT, fieldCount, FT_BYTE, FT_FLOAT, FT_IND, FT_INT, FT_LOGIC, FT_NA, FT_NA_BYTE, FT_SORT, FT_STRING, DBCFileLoader::Record::getFloat(), GetFormatRecordSize(), getRecord(), DBCFileLoader::Record::getUInt(), DBCFileLoader::Record::getUInt8(), and recordCount.

Referenced by DBCStorageBase::Load().

◆ AutoProduceStrings()

char * DBCFileLoader::AutoProduceStrings ( char const *  fmt,
char *  dataTable 
)
278{
279 if (strlen(format) != fieldCount)
280 {
281 return nullptr;
282 }
283
284 char* stringPool = new char[stringSize];
285 memcpy(stringPool, stringTable, stringSize);
286
287 uint32 offset = 0;
288
289 for (uint32 y = 0; y < recordCount; ++y)
290 {
291 for (uint32 x = 0; x < fieldCount; ++x)
292 {
293 switch (format[x])
294 {
295 case FT_FLOAT:
296 offset += sizeof(float);
297 break;
298 case FT_IND:
299 case FT_INT:
300 offset += sizeof(uint32);
301 break;
302 case FT_BYTE:
303 offset += sizeof(uint8);
304 break;
305 case FT_STRING:
306 {
307 // fill only not filled entries
308 char** slot = (char**)(&dataTable[offset]);
309 if (!*slot || !** slot)
310 {
311 const char* st = getRecord(y).getString(x);
312 *slot = stringPool + (st - (char const*)stringTable);
313 }
314 offset += sizeof(char*);
315 break;
316 }
317 case FT_LOGIC:
318 ASSERT(false && "Attempted to load DBC files that does not have field types that match what is in the core. Check DBCfmt.h or your DBC files.");
319 break;
320 case FT_NA:
321 case FT_NA_BYTE:
322 case FT_SORT:
323 break;
324 default:
325 ASSERT(false && "Unknown field format character in DBCfmt.h");
326 break;
327 }
328 }
329 }
330
331 return stringPool;
332}
const char * getString(std::size_t field) const
Definition: DBCFileLoader.h:71

References ASSERT, fieldCount, FT_BYTE, FT_FLOAT, FT_IND, FT_INT, FT_LOGIC, FT_NA, FT_NA_BYTE, FT_SORT, FT_STRING, getRecord(), DBCFileLoader::Record::getString(), recordCount, stringSize, and stringTable.

Referenced by DBCStorageBase::Load(), and DBCStorageBase::LoadStringsFrom().

◆ GetCols()

uint32 DBCFileLoader::GetCols ( ) const
inline
92{ return fieldCount; }

References fieldCount.

Referenced by DBCStorageBase::Load().

◆ GetFormatRecordSize()

uint32 DBCFileLoader::GetFormatRecordSize ( const char *  format,
int32 index_pos = nullptr 
)
static
130{
131 uint32 recordsize = 0;
132 int32 i = -1;
133
134 for (uint32 x = 0; format[x]; ++x)
135 {
136 switch (format[x])
137 {
138 case FT_FLOAT:
139 recordsize += sizeof(float);
140 break;
141 case FT_INT:
142 recordsize += sizeof(uint32);
143 break;
144 case FT_STRING:
145 recordsize += sizeof(char*);
146 break;
147 case FT_SORT:
148 i = x;
149 break;
150 case FT_IND:
151 i = x;
152 recordsize += sizeof(uint32);
153 break;
154 case FT_BYTE:
155 recordsize += sizeof(uint8);
156 break;
157 case FT_NA:
158 case FT_NA_BYTE:
159 break;
160 case FT_LOGIC:
161 ASSERT(false && "Attempted to load DBC files that do not have field types that match what is in the core. Check DBCfmt.h or your DBC files.");
162 break;
163 default:
164 ASSERT(false && "Unknown field format character in DBCfmt.h");
165 break;
166 }
167 }
168
169 if (index_pos)
170 {
171 *index_pos = i;
172 }
173
174 return recordsize;
175}

References ASSERT, FT_BYTE, FT_FLOAT, FT_IND, FT_INT, FT_LOGIC, FT_NA, FT_NA_BYTE, FT_SORT, and FT_STRING.

Referenced by AutoProduceData(), DBCDatabaseLoader::DBCDatabaseLoader(), and LoadDBC().

◆ GetNumRows()

uint32 DBCFileLoader::GetNumRows ( ) const
inline
90{ return recordCount; }

References recordCount.

◆ GetOffset()

uint32 DBCFileLoader::GetOffset ( std::size_t  id) const
inline

◆ getRecord()

DBCFileLoader::Record DBCFileLoader::getRecord ( std::size_t  id)
124{
125 ASSERT(data);
126 return Record(*this, data + id * recordSize);
127}

References ASSERT, data, and recordSize.

Referenced by AutoProduceData(), and AutoProduceStrings().

◆ GetRowSize()

uint32 DBCFileLoader::GetRowSize ( ) const
inline
91{ return recordSize; }

References recordSize.

◆ IsLoaded()

bool DBCFileLoader::IsLoaded ( ) const
inline
94{ return data != nullptr; }

References data.

◆ Load()

bool DBCFileLoader::Load ( const char *  filename,
const char *  fmt 
)
26{
27 uint32 header;
28 if (data)
29 {
30 delete [] data;
31 data = nullptr;
32 }
33
34 FILE* f = fopen(filename, "rb");
35 if (!f)
36 {
37 return false;
38 }
39
40 if (fread(&header, 4, 1, f) != 1) // Number of records
41 {
42 fclose(f);
43 return false;
44 }
45
46 EndianConvert(header);
47
48 if (header != 0x43424457) //'WDBC'
49 {
50 fclose(f);
51 return false;
52 }
53
54 if (fread(&recordCount, 4, 1, f) != 1) // Number of records
55 {
56 fclose(f);
57 return false;
58 }
59
61
62 if (fread(&fieldCount, 4, 1, f) != 1) // Number of fields
63 {
64 fclose(f);
65 return false;
66 }
67
69
70 if (fread(&recordSize, 4, 1, f) != 1) // Size of a record
71 {
72 fclose(f);
73 return false;
74 }
75
77
78 if (fread(&stringSize, 4, 1, f) != 1) // String size
79 {
80 fclose(f);
81 return false;
82 }
83
85
87 fieldsOffset[0] = 0;
88
89 for (uint32 i = 1; i < fieldCount; ++i)
90 {
91 fieldsOffset[i] = fieldsOffset[i - 1];
92 if (fmt[i - 1] == 'b' || fmt[i - 1] == 'X') // byte fields
93 {
94 fieldsOffset[i] += sizeof(uint8);
95 }
96 else // 4 byte fields (int32/float/strings)
97 {
98 fieldsOffset[i] += sizeof(uint32);
99 }
100 }
101
102 data = new unsigned char[recordSize * recordCount + stringSize];
104
105 if (fread(data, recordSize * recordCount + stringSize, 1, f) != 1)
106 {
107 fclose(f);
108 return false;
109 }
110
111 fclose(f);
112
113 return true;
114}
void EndianConvert(T &val)
Definition: ByteConverter.h:47

References data, EndianConvert(), fieldCount, fieldsOffset, recordCount, recordSize, stringSize, and stringTable.

Referenced by DBCStorageBase::Load(), and DBCStorageBase::LoadStringsFrom().

◆ operator=()

DBCFileLoader & DBCFileLoader::operator= ( DBCFileLoader const &  right)
privatedelete

Member Data Documentation

◆ data

unsigned char* DBCFileLoader::data
private

◆ fieldCount

◆ fieldsOffset

uint32* DBCFileLoader::fieldsOffset
private

Referenced by GetOffset(), Load(), and ~DBCFileLoader().

◆ recordCount

uint32 DBCFileLoader::recordCount
private

◆ recordSize

uint32 DBCFileLoader::recordSize
private

Referenced by getRecord(), GetRowSize(), and Load().

◆ stringSize

uint32 DBCFileLoader::stringSize
private

◆ stringTable

unsigned char* DBCFileLoader::stringTable
private