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 ( )
22: 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 ( )
116{
117 delete[] data;
118
119 delete[] fieldsOffset;
120}

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 
)
177{
178 /*
179 format STRING, NA, FLOAT, NA, INT <=>
180 struct{
181 char* field0,
182 float field1,
183 int field2
184 }entry;
185
186 this func will generate entry[rows] data;
187 */
188
189 typedef char* ptr;
190 if (strlen(format) != fieldCount)
191 {
192 return nullptr;
193 }
194
195 //get struct size and index pos
196 int32 i;
197 uint32 recordsize = GetFormatRecordSize(format, &i);
198
199 if (i >= 0)
200 {
201 uint32 maxi = 0;
202 //find max index
203 for (uint32 y = 0; y < recordCount; ++y)
204 {
205 uint32 ind = getRecord(y).getUInt(i);
206 if (ind > maxi)
207 {
208 maxi = ind;
209 }
210 }
211
212 ++maxi;
213 records = maxi;
214 indexTable = new ptr[maxi];
215 memset(indexTable, 0, maxi * sizeof(ptr));
216 }
217 else
218 {
219 records = recordCount;
220 indexTable = new ptr[recordCount];
221 }
222
223 char* dataTable = new char[recordCount * recordsize];
224
225 uint32 offset = 0;
226
227 for (uint32 y = 0; y < recordCount; ++y)
228 {
229 if (i >= 0)
230 {
231 indexTable[getRecord(y).getUInt(i)] = &dataTable[offset];
232 }
233 else
234 {
235 indexTable[y] = &dataTable[offset];
236 }
237
238 for (uint32 x = 0; x < fieldCount; ++x)
239 {
240 switch (format[x])
241 {
242 case FT_FLOAT:
243 *((float*)(&dataTable[offset])) = getRecord(y).getFloat(x);
244 offset += sizeof(float);
245 break;
246 case FT_IND:
247 case FT_INT:
248 *((uint32*)(&dataTable[offset])) = getRecord(y).getUInt(x);
249 offset += sizeof(uint32);
250 break;
251 case FT_BYTE:
252 *((uint8*)(&dataTable[offset])) = getRecord(y).getUInt8(x);
253 offset += sizeof(uint8);
254 break;
255 case FT_STRING:
256 *((char**)(&dataTable[offset])) = nullptr; // will replace non-empty or "" strings in AutoProduceStrings
257 offset += sizeof(char*);
258 break;
259 case FT_LOGIC:
260 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.");
261 break;
262 case FT_NA:
263 case FT_NA_BYTE:
264 case FT_SORT:
265 break;
266 default:
267 ASSERT(false && "Unknown field format character in DBCfmt.h");
268 break;
269 }
270 }
271 }
272
273 return dataTable;
274}
#define ASSERT
Definition: Errors.h:68
@ 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
static uint32 GetFormatRecordSize(const char *format, int32 *index_pos=nullptr)
Definition: DBCFileLoader.cpp:128
Record getRecord(std::size_t id)
Definition: DBCFileLoader.cpp:122
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 
)
277{
278 if (strlen(format) != fieldCount)
279 {
280 return nullptr;
281 }
282
283 char* stringPool = new char[stringSize];
284 memcpy(stringPool, stringTable, stringSize);
285
286 uint32 offset = 0;
287
288 for (uint32 y = 0; y < recordCount; ++y)
289 {
290 for (uint32 x = 0; x < fieldCount; ++x)
291 {
292 switch (format[x])
293 {
294 case FT_FLOAT:
295 offset += sizeof(float);
296 break;
297 case FT_IND:
298 case FT_INT:
299 offset += sizeof(uint32);
300 break;
301 case FT_BYTE:
302 offset += sizeof(uint8);
303 break;
304 case FT_STRING:
305 {
306 // fill only not filled entries
307 char** slot = (char**)(&dataTable[offset]);
308 if (!*slot || !** slot)
309 {
310 const char* st = getRecord(y).getString(x);
311 *slot = stringPool + (st - (char const*)stringTable);
312 }
313 offset += sizeof(char*);
314 break;
315 }
316 case FT_LOGIC:
317 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.");
318 break;
319 case FT_NA:
320 case FT_NA_BYTE:
321 case FT_SORT:
322 break;
323 default:
324 ASSERT(false && "Unknown field format character in DBCfmt.h");
325 break;
326 }
327 }
328 }
329
330 return stringPool;
331}
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
129{
130 uint32 recordsize = 0;
131 int32 i = -1;
132
133 for (uint32 x = 0; format[x]; ++x)
134 {
135 switch (format[x])
136 {
137 case FT_FLOAT:
138 recordsize += sizeof(float);
139 break;
140 case FT_INT:
141 recordsize += sizeof(uint32);
142 break;
143 case FT_STRING:
144 recordsize += sizeof(char*);
145 break;
146 case FT_SORT:
147 i = x;
148 break;
149 case FT_IND:
150 i = x;
151 recordsize += sizeof(uint32);
152 break;
153 case FT_BYTE:
154 recordsize += sizeof(uint8);
155 break;
156 case FT_NA:
157 case FT_NA_BYTE:
158 break;
159 case FT_LOGIC:
160 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.");
161 break;
162 default:
163 ASSERT(false && "Unknown field format character in DBCfmt.h");
164 break;
165 }
166 }
167
168 if (index_pos)
169 {
170 *index_pos = i;
171 }
172
173 return recordsize;
174}

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)
123{
124 ASSERT(data);
125 return Record(*this, data + id * recordSize);
126}

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