diff options
| author | Shauren <shauren.trinity@gmail.com> | 2016-10-09 16:54:11 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2016-10-09 16:54:11 +0200 |
| commit | d34020da7f34943e9cc84482ce19f829154334bd (patch) | |
| tree | 97a0ca5879bf3cdb6c9c6dd59a5e732b8c4531bf /src/server/shared | |
| parent | 8fba569cb93e8497b639056fc07fd3f049bac959 (diff) | |
Core/DataStores: Fixed loading signed db2 fields
Diffstat (limited to 'src/server/shared')
| -rw-r--r-- | src/server/shared/DataStores/DB2StorageLoader.cpp | 298 | ||||
| -rw-r--r-- | src/server/shared/DataStores/DB2StorageLoader.h | 22 | ||||
| -rw-r--r-- | src/server/shared/DataStores/DB2Store.h | 31 |
3 files changed, 173 insertions, 178 deletions
diff --git a/src/server/shared/DataStores/DB2StorageLoader.cpp b/src/server/shared/DataStores/DB2StorageLoader.cpp index cba5e0e524e..09ad198bbb5 100644 --- a/src/server/shared/DataStores/DB2StorageLoader.cpp +++ b/src/server/shared/DataStores/DB2StorageLoader.cpp @@ -20,11 +20,20 @@ #include "DB2Meta.h" #include "Utilities/ByteConverter.h" +DB2LoadInfo::DB2LoadInfo() : Fields(nullptr), FieldCount(0), Meta(nullptr), Statement(MAX_HOTFIXDATABASE_STATEMENTS) +{ +} + +DB2LoadInfo::DB2LoadInfo(DB2FieldMeta const* fields, std::size_t fieldCount, DB2Meta const* meta, HotfixDatabaseStatements statement) + : Fields(fields), FieldCount(fieldCount), Meta(meta), Statement(statement) +{ +} + class DB2FileLoaderImpl { public: virtual ~DB2FileLoaderImpl() { } - virtual bool Load(char const* filename, FILE* file, DB2Meta const* meta, DB2Header const* header) = 0; + virtual bool Load(char const* filename, FILE* file, DB2LoadInfo const& loadInfo, DB2Header const* header) = 0; virtual char* AutoProduceData(uint32& count, char**& indexTable, std::vector<char*>& stringPool) = 0; virtual char* AutoProduceStrings(char* dataTable, uint32 locale) = 0; virtual void AutoProduceRecordCopies(uint32 records, char** indexTable, char* dataTable) = 0; @@ -36,7 +45,7 @@ public: DB2FileLoaderRegularImpl(); ~DB2FileLoaderRegularImpl(); - bool Load(char const* filename, FILE* file, DB2Meta const* meta, DB2Header const* header) override; + bool Load(char const* filename, FILE* file, DB2LoadInfo const& loadInfo, DB2Header const* header) override; char* AutoProduceData(uint32& count, char**& indexTable, std::vector<char*>& stringPool) override; char* AutoProduceStrings(char* dataTable, uint32 locale) override; void AutoProduceRecordCopies(uint32 records, char** indexTable, char* dataTable) override; @@ -46,7 +55,7 @@ private: { public: float getFloat(uint32 field, uint32 arrayIndex) const; - uint32 getUInt(uint32 field, uint32 arrayIndex) const; + uint32 getUInt(uint32 field, uint32 arrayIndex, bool isSigned) const; uint8 getUInt8(uint32 field, uint32 arrayIndex) const; uint16 getUInt16(uint32 field, uint32 arrayIndex) const; char const* getString(uint32 field, uint32 arrayIndex) const; @@ -54,7 +63,7 @@ private: private: uint16 GetOffset(uint32 field) const; uint16 GetByteSize(uint32 field) const; - uint32 GetVarInt(uint32 field, uint16 size, uint32 arrayIndex) const; + uint32 GetVarInt(uint32 field, uint32 arrayIndex, bool isSigned) const; Record(DB2FileLoaderRegularImpl &file_, unsigned char *offset_); unsigned char *offset; @@ -75,8 +84,8 @@ private: #pragma pack(pop) char const* fileName; - DB2Meta const* meta; - DB2Header const* header; + DB2LoadInfo _loadInfo; + DB2Header const* _header; unsigned char* data; unsigned char* stringTable; @@ -92,7 +101,7 @@ public: DB2FileLoaderSparseImpl(); ~DB2FileLoaderSparseImpl(); - bool Load(char const* filename, FILE* file, DB2Meta const* meta, DB2Header const* header) override; + bool Load(char const* filename, FILE* file, DB2LoadInfo const& loadInfo, DB2Header const* header) override; char* AutoProduceData(uint32& records, char**& indexTable, std::vector<char*>& stringPool) override; char* AutoProduceStrings(char* dataTable, uint32 locale) override; void AutoProduceRecordCopies(uint32 /*records*/, char** /*indexTable*/, char* /*dataTable*/) override { } @@ -112,8 +121,8 @@ private: #pragma pack(pop) char const* fileName; - DB2Meta const* meta; - DB2Header const* header; + DB2LoadInfo _loadInfo; + DB2Header const* _header; FieldEntry* fields; uint32 dataStart; @@ -123,28 +132,28 @@ private: float DB2FileLoaderRegularImpl::Record::getFloat(uint32 field, uint32 arrayIndex) const { - ASSERT(field < file.header->FieldCount); + ASSERT(field < file._header->FieldCount); float val = *reinterpret_cast<float*>(offset + GetOffset(field) + arrayIndex * sizeof(float)); EndianConvert(val); return val; } -uint32 DB2FileLoaderRegularImpl::Record::getUInt(uint32 field, uint32 arrayIndex) const +uint32 DB2FileLoaderRegularImpl::Record::getUInt(uint32 field, uint32 arrayIndex, bool isSigned) const { - ASSERT(field < file.header->FieldCount); - return GetVarInt(field, GetByteSize(field), arrayIndex); + ASSERT(field < file._header->FieldCount); + return GetVarInt(field, arrayIndex, isSigned); } uint8 DB2FileLoaderRegularImpl::Record::getUInt8(uint32 field, uint32 arrayIndex) const { - ASSERT(field < file.header->FieldCount); + ASSERT(field < file._header->FieldCount); ASSERT(GetByteSize(field) == 1); return *reinterpret_cast<uint8*>(offset + GetOffset(field) + arrayIndex * sizeof(uint8)); } uint16 DB2FileLoaderRegularImpl::Record::getUInt16(uint32 field, uint32 arrayIndex) const { - ASSERT(field < file.header->FieldCount); + ASSERT(field < file._header->FieldCount); ASSERT(GetByteSize(field) == 2); uint16 val = *reinterpret_cast<uint16*>(offset + GetOffset(field) + arrayIndex * sizeof(uint16)); EndianConvert(val); @@ -153,73 +162,45 @@ uint16 DB2FileLoaderRegularImpl::Record::getUInt16(uint32 field, uint32 arrayInd char const* DB2FileLoaderRegularImpl::Record::getString(uint32 field, uint32 arrayIndex) const { - ASSERT(field < file.header->FieldCount); + ASSERT(field < file._header->FieldCount); uint32 stringOffset = *reinterpret_cast<uint32*>(offset + GetOffset(field) + arrayIndex * sizeof(uint32)); EndianConvert(stringOffset); - ASSERT(stringOffset < file.header->StringTableSize); + ASSERT(stringOffset < file._header->StringTableSize); return reinterpret_cast<char*>(file.stringTable + stringOffset); } uint16 DB2FileLoaderRegularImpl::Record::GetOffset(uint32 field) const { - ASSERT(field < file.header->FieldCount); + ASSERT(field < file._header->FieldCount); return file.fields[field].Offset; } uint16 DB2FileLoaderRegularImpl::Record::GetByteSize(uint32 field) const { - ASSERT(field < file.header->FieldCount); + ASSERT(field < file._header->FieldCount); return 4 - file.fields[field].UnusedBits / 8; } -uint32 DB2FileLoaderRegularImpl::Record::GetVarInt(uint32 field, uint16 size, uint32 arrayIndex) const +uint32 DB2FileLoaderRegularImpl::Record::GetVarInt(uint32 field, uint32 arrayIndex, bool isSigned) const { - ASSERT(field < file.header->FieldCount); - switch (size) - { - case 1: - { - return *reinterpret_cast<uint8*>(offset + GetOffset(field) + arrayIndex * sizeof(uint8)); - } - case 2: - { - uint16 val = *reinterpret_cast<uint16*>(offset + GetOffset(field) + arrayIndex * sizeof(uint16)); - EndianConvert(val); - return val; - } - case 3: - { -#pragma pack(push, 1) - struct dbcint24 { uint8 v[3]; }; -#pragma pack(pop) - dbcint24 val = *reinterpret_cast<dbcint24*>(offset + GetOffset(field) + arrayIndex * sizeof(dbcint24)); - EndianConvert(val); - return uint32(val.v[0]) | (uint32(val.v[1]) << 8) | (uint32(val.v[2]) << 16); - } - case 4: - { - uint32 val = *reinterpret_cast<uint32*>(offset + GetOffset(field) + arrayIndex * sizeof(uint32)); - EndianConvert(val); - return val; - } - default: - break; - } + ASSERT(field < file._header->FieldCount); + uint32 val = *reinterpret_cast<uint32*>(offset + GetOffset(field) + arrayIndex * sizeof(uint32)); + EndianConvert(val); + if (isSigned) + return int32(val) << file.fields[field].UnusedBits >> file.fields[field].UnusedBits; - ASSERT(false, "GetByteSize(field) < 4"); - return 0; + return val << file.fields[field].UnusedBits >> file.fields[field].UnusedBits; } DB2FileLoaderRegularImpl::Record::Record(DB2FileLoaderRegularImpl &file_, unsigned char *offset_) : offset(offset_), file(file_) { - } DB2FileLoaderRegularImpl::DB2FileLoaderRegularImpl() { fileName = nullptr; - meta = nullptr; - header = nullptr; + memset(&_loadInfo, 0, sizeof(_loadInfo)); + _header = nullptr; data = nullptr; stringTable = nullptr; idTable = nullptr; @@ -228,18 +209,18 @@ DB2FileLoaderRegularImpl::DB2FileLoaderRegularImpl() fields = nullptr; } -bool DB2FileLoaderRegularImpl::Load(char const* filename, FILE* file, DB2Meta const* meta_, DB2Header const* header_) +bool DB2FileLoaderRegularImpl::Load(char const* filename, FILE* file, DB2LoadInfo const& loadInfo, DB2Header const* header) { - meta = meta_; - header = header_; - ASSERT(meta->IndexField == -1 || meta->IndexField == int32(header->IndexField)); + _loadInfo = loadInfo; + _header = header; + ASSERT(loadInfo.Meta->IndexField == -1 || loadInfo.Meta->IndexField == int32(header->IndexField)); fileName = filename; fields = new FieldEntry[header->FieldCount]; if (fread(fields, header->FieldCount * sizeof(FieldEntry), 1, file) != 1) return false; - if (!meta->HasIndexFieldInData()) + if (!loadInfo.Meta->HasIndexFieldInData()) idTableSize = header->RecordCount * sizeof(uint32); data = new unsigned char[header->RecordSize * header->RecordCount + header->StringTableSize]; @@ -276,34 +257,34 @@ DB2FileLoaderRegularImpl::~DB2FileLoaderRegularImpl() DB2FileLoaderRegularImpl::Record DB2FileLoaderRegularImpl::getRecord(size_t id) { assert(data); - return Record(*this, data + id * header->RecordSize); + return Record(*this, data + id * _header->RecordSize); } static char const* const nullStr = ""; char* DB2FileLoaderRegularImpl::AutoProduceData(uint32& records, char**& indexTable, std::vector<char*>& stringPool) { - if (meta->FieldCount != header->FieldCount) + if (_loadInfo.Meta->FieldCount != _header->FieldCount) return NULL; //get struct size and index pos - uint32 indexField = meta->GetIndexField(); - uint32 recordsize = meta->GetRecordSize(); + uint32 indexField = _loadInfo.Meta->GetIndexField(); + uint32 recordsize = _loadInfo.Meta->GetRecordSize(); uint32 maxi = 0; //find max index if (!idTableSize) { - for (uint32 y = 0; y < header->RecordCount; ++y) + for (uint32 y = 0; y < _header->RecordCount; ++y) { - uint32 ind = getRecord(y).getUInt(indexField, 0); + uint32 ind = getRecord(y).getUInt(indexField, 0, false); if (ind > maxi) maxi = ind; } } else { - for (uint32 y = 0; y < header->RecordCount; ++y) + for (uint32 y = 0; y < _header->RecordCount; ++y) { uint32 ind = ((uint32*)idTable)[y]; if (ind > maxi) @@ -311,7 +292,7 @@ char* DB2FileLoaderRegularImpl::AutoProduceData(uint32& records, char**& indexTa } } - for (uint32 y = 0; y < header->CopyTableSize; y += 8) + for (uint32 y = 0; y < _header->CopyTableSize; y += 8) { uint32 ind = *((uint32*)(copyTable + y)); if (ind > maxi) @@ -325,18 +306,18 @@ char* DB2FileLoaderRegularImpl::AutoProduceData(uint32& records, char**& indexTa indexTable = new index_entry_t[maxi]; memset(indexTable, 0, maxi * sizeof(index_entry_t)); - char* dataTable = new char[(header->RecordCount + (header->CopyTableSize / 8)) * recordsize]; + char* dataTable = new char[(_header->RecordCount + (_header->CopyTableSize / 8)) * recordsize]; // we store flat holders pool as single memory block - std::size_t stringFields = meta->GetStringFieldCount(false); - std::size_t localizedStringFields = meta->GetStringFieldCount(true); + std::size_t stringFields = _loadInfo.Meta->GetStringFieldCount(false); + std::size_t localizedStringFields = _loadInfo.Meta->GetStringFieldCount(true); // each string field at load have array of string for each locale std::size_t stringHoldersRecordPoolSize = localizedStringFields * sizeof(LocalizedString) + (stringFields - localizedStringFields) * sizeof(char*); char* stringHoldersPool = nullptr; if (stringFields) { - std::size_t stringHoldersPoolSize = stringHoldersRecordPoolSize * header->RecordCount; + std::size_t stringHoldersPoolSize = stringHoldersRecordPoolSize * _header->RecordCount; stringHoldersPool = new char[stringHoldersPoolSize]; stringPool.push_back(stringHoldersPool); @@ -348,33 +329,35 @@ char* DB2FileLoaderRegularImpl::AutoProduceData(uint32& records, char**& indexTa uint32 offset = 0; - for (uint32 y = 0; y < header->RecordCount; y++) + for (uint32 y = 0; y < _header->RecordCount; y++) { Record rec = getRecord(y); - uint32 indexVal = meta->HasIndexFieldInData() ? rec.getUInt(indexField, 0) : ((uint32*)idTable)[y]; + uint32 indexVal = _loadInfo.Meta->HasIndexFieldInData() ? rec.getUInt(indexField, 0, _loadInfo.Fields[0].IsSigned) : ((uint32*)idTable)[y]; indexTable[indexVal] = &dataTable[offset]; - if (!meta->HasIndexFieldInData()) + uint32 fieldIndex = 0; + if (!_loadInfo.Meta->HasIndexFieldInData()) { *((uint32*)(&dataTable[offset])) = indexVal; offset += 4; + ++fieldIndex; } uint32 stringFieldOffset = 0; - for (uint32 x = 0; x < header->FieldCount; ++x) + for (uint32 x = 0; x < _header->FieldCount; ++x) { - for (uint32 z = 0; z < meta->ArraySizes[x]; ++z) + for (uint32 z = 0; z < _loadInfo.Meta->ArraySizes[x]; ++z) { - switch (meta->Types[x]) + switch (_loadInfo.Meta->Types[x]) { case FT_FLOAT: *((float*)(&dataTable[offset])) = rec.getFloat(x, z); offset += 4; break; case FT_INT: - *((uint32*)(&dataTable[offset])) = rec.getUInt(x, z); + *((uint32*)(&dataTable[offset])) = rec.getUInt(x, z, _loadInfo.Fields[fieldIndex].IsSigned); offset += 4; break; case FT_BYTE: @@ -391,7 +374,7 @@ char* DB2FileLoaderRegularImpl::AutoProduceData(uint32& records, char**& indexTa // init db2 string field slots by pointers to string holders char const*** slot = (char const***)(&dataTable[offset]); *slot = (char const**)(&stringHoldersPool[stringHoldersRecordPoolSize * y + stringFieldOffset]); - if (meta->Types[x] == FT_STRING) + if (_loadInfo.Meta->Types[x] == FT_STRING) stringFieldOffset += sizeof(LocalizedString); else stringFieldOffset += sizeof(char*); @@ -400,9 +383,10 @@ char* DB2FileLoaderRegularImpl::AutoProduceData(uint32& records, char**& indexTa break; } default: - ASSERT(false, "Unknown format character '%c' found in %s meta", meta->Types[x], fileName); + ASSERT(false, "Unknown format character '%c' found in %s meta", _loadInfo.Meta->Types[x], fileName); break; } + ++fieldIndex; } } } @@ -412,16 +396,16 @@ char* DB2FileLoaderRegularImpl::AutoProduceData(uint32& records, char**& indexTa char* DB2FileLoaderRegularImpl::AutoProduceStrings(char* dataTable, uint32 locale) { - if (meta->FieldCount != header->FieldCount) + if (_loadInfo.Meta->FieldCount != _header->FieldCount) return nullptr; - if (!(header->Locale & (1 << locale))) + if (!(_header->Locale & (1 << locale))) { char const* sep = ""; std::ostringstream str; for (uint32 i = 0; i < TOTAL_LOCALES; ++i) { - if (header->Locale & (1 << i)) + if (_header->Locale & (1 << i)) { str << sep << localeNames[i]; sep = ", "; @@ -432,21 +416,21 @@ char* DB2FileLoaderRegularImpl::AutoProduceStrings(char* dataTable, uint32 local return nullptr; } - char* stringPool = new char[header->StringTableSize]; - memcpy(stringPool, stringTable, header->StringTableSize); + char* stringPool = new char[_header->StringTableSize]; + memcpy(stringPool, stringTable, _header->StringTableSize); uint32 offset = 0; - for (uint32 y = 0; y < header->RecordCount; y++) + for (uint32 y = 0; y < _header->RecordCount; y++) { - if (!meta->HasIndexFieldInData()) + if (!_loadInfo.Meta->HasIndexFieldInData()) offset += 4; - for (uint32 x = 0; x < header->FieldCount; ++x) + for (uint32 x = 0; x < _header->FieldCount; ++x) { - for (uint32 z = 0; z < meta->ArraySizes[x]; ++z) + for (uint32 z = 0; z < _loadInfo.Meta->ArraySizes[x]; ++z) { - switch (meta->Types[x]) + switch (_loadInfo.Meta->Types[x]) { case FT_FLOAT: case FT_INT: @@ -480,7 +464,7 @@ char* DB2FileLoaderRegularImpl::AutoProduceStrings(char* dataTable, uint32 local break; } default: - ASSERT(false, "Unknown format character '%c' found in %s meta", meta->Types[x], fileName); + ASSERT(false, "Unknown format character '%c' found in %s meta", _loadInfo.Meta->Types[x], fileName); break; } } @@ -492,10 +476,10 @@ char* DB2FileLoaderRegularImpl::AutoProduceStrings(char* dataTable, uint32 local void DB2FileLoaderRegularImpl::AutoProduceRecordCopies(uint32 records, char** indexTable, char* dataTable) { - uint32 recordsize = meta->GetRecordSize(); - uint32 offset = header->RecordCount * recordsize; + uint32 recordsize = _loadInfo.Meta->GetRecordSize(); + uint32 offset = _header->RecordCount * recordsize; uint32* copyIds = (uint32*)copyTable; - for (uint32 c = 0; c < header->CopyTableSize / 4; c += 2) + for (uint32 c = 0; c < _header->CopyTableSize / 4; c += 2) { uint32 to = copyIds[c]; uint32 from = copyIds[c + 1]; @@ -505,8 +489,8 @@ void DB2FileLoaderRegularImpl::AutoProduceRecordCopies(uint32 records, char** in indexTable[to] = &dataTable[offset]; memcpy(indexTable[to], indexTable[from], recordsize); - if (meta->HasIndexFieldInData()) - *((uint32*)(&dataTable[offset + fields[meta->GetIndexField()].Offset])) = to; + if (_loadInfo.Meta->HasIndexFieldInData()) + *((uint32*)(&dataTable[offset + fields[_loadInfo.Meta->GetIndexField()].Offset])) = to; else *((uint32*)(&dataTable[offset])) = to; @@ -518,18 +502,18 @@ void DB2FileLoaderRegularImpl::AutoProduceRecordCopies(uint32 records, char** in DB2FileLoaderSparseImpl::DB2FileLoaderSparseImpl() { fileName = nullptr; - meta = nullptr; - header = nullptr; + memset(&_loadInfo, 0, sizeof(_loadInfo)); + _header = nullptr; fields = nullptr; dataStart = 0; data = nullptr; offsets = nullptr; } -bool DB2FileLoaderSparseImpl::Load(char const* filename, FILE* file, DB2Meta const* meta_, DB2Header const* header_) +bool DB2FileLoaderSparseImpl::Load(char const* filename, FILE* file, DB2LoadInfo const& loadInfo, DB2Header const* header) { - meta = meta_; - header = header_; + _loadInfo = loadInfo; + _header = header; fileName = filename; fields = new FieldEntry[header->FieldCount]; @@ -559,13 +543,13 @@ DB2FileLoaderSparseImpl::~DB2FileLoaderSparseImpl() char* DB2FileLoaderSparseImpl::AutoProduceData(uint32& maxId, char**& indexTable, std::vector<char*>& stringPool) { - if (meta->FieldCount != header->FieldCount) + if (_loadInfo.Meta->FieldCount != _header->FieldCount) return NULL; //get struct size and index pos - uint32 recordsize = meta->GetRecordSize(); + uint32 recordsize = _loadInfo.Meta->GetRecordSize(); - uint32 offsetCount = header->MaxId - header->MinId + 1; + uint32 offsetCount = _header->MaxId - _header->MinId + 1; uint32 records = 0; uint32 expandedDataSize = 0; for (uint32 i = 0; i < offsetCount; ++i) @@ -579,15 +563,15 @@ char* DB2FileLoaderSparseImpl::AutoProduceData(uint32& maxId, char**& indexTable using index_entry_t = char*; - maxId = header->MaxId + 1; + maxId = _header->MaxId + 1; indexTable = new index_entry_t[maxId]; memset(indexTable, 0, maxId * sizeof(index_entry_t)); char* dataTable = new char[records * recordsize]; // we store flat holders pool as single memory block - std::size_t stringFields = meta->GetStringFieldCount(false); - std::size_t localizedStringFields = meta->GetStringFieldCount(true); + std::size_t stringFields = _loadInfo.Meta->GetStringFieldCount(false); + std::size_t localizedStringFields = _loadInfo.Meta->GetStringFieldCount(true); // each string field at load have array of string for each locale std::size_t stringHoldersRecordPoolSize = localizedStringFields * sizeof(LocalizedString) + (stringFields - localizedStringFields) * sizeof(char*); @@ -600,8 +584,8 @@ char* DB2FileLoaderSparseImpl::AutoProduceData(uint32& maxId, char**& indexTable for (std::size_t i = 0; i < stringHoldersPoolSize / sizeof(char*); ++i) ((char const**)stringHoldersPool)[i] = nullStr; - char* stringTable = new char[expandedDataSize - records * ((recordsize - (!meta->HasIndexFieldInData() ? 4 : 0)) - stringFields * sizeof(char*))]; - memset(stringTable, 0, expandedDataSize - records * ((recordsize - (!meta->HasIndexFieldInData() ? 4 : 0)) - stringFields * sizeof(char*))); + char* stringTable = new char[expandedDataSize - records * ((recordsize - (!_loadInfo.Meta->HasIndexFieldInData() ? 4 : 0)) - stringFields * sizeof(char*))]; + memset(stringTable, 0, expandedDataSize - records * ((recordsize - (!_loadInfo.Meta->HasIndexFieldInData() ? 4 : 0)) - stringFields * sizeof(char*))); stringPool.push_back(stringTable); char* stringPtr = stringTable; @@ -612,23 +596,23 @@ char* DB2FileLoaderSparseImpl::AutoProduceData(uint32& maxId, char**& indexTable if (!offsets[y].FileOffset || !offsets[y].RecordSize) continue; - indexTable[y + header->MinId] = &dataTable[offset]; - ASSERT(indexTable[y + header->MinId]); + indexTable[y + _header->MinId] = &dataTable[offset]; + ASSERT(indexTable[y + _header->MinId]); std::size_t fieldOffset = 0; uint32 stringFieldOffset = 0; - if (!meta->HasIndexFieldInData()) + if (!_loadInfo.Meta->HasIndexFieldInData()) { - *((uint32*)(&dataTable[offset])) = y + header->MinId; + *((uint32*)(&dataTable[offset])) = y + _header->MinId; offset += 4; } - for (uint32 x = 0; x < header->FieldCount; ++x) + for (uint32 x = 0; x < _header->FieldCount; ++x) { uint16 fieldBytes = 4 - fields[x].UnusedBits / 8; - for (uint32 z = 0; z < meta->ArraySizes[x]; ++z) + for (uint32 z = 0; z < _loadInfo.Meta->ArraySizes[x]; ++z) { - switch (meta->Types[x]) + switch (_loadInfo.Meta->Types[x]) { case FT_FLOAT: { @@ -700,7 +684,7 @@ char* DB2FileLoaderSparseImpl::AutoProduceData(uint32& maxId, char**& indexTable LocalizedString** slot = (LocalizedString**)(&dataTable[offset]); *slot = (LocalizedString*)(&stringHoldersPool[stringHoldersRecordPoolSize * recordNum + stringFieldOffset]); for (uint32 locale = 0; locale < TOTAL_LOCALES; ++locale) - if (header->Locale & (1 << locale)) + if (_header->Locale & (1 << locale)) (*slot)->Str[locale] = stringPtr; strcpy(stringPtr, (char*)&data[offsets[y].FileOffset - dataStart + fieldOffset]); fieldOffset += strlen(stringPtr) + 1; @@ -722,7 +706,7 @@ char* DB2FileLoaderSparseImpl::AutoProduceData(uint32& maxId, char**& indexTable break; } default: - ASSERT(false, "Unknown format character '%c' found in %s meta", meta->Types[x], fileName); + ASSERT(false, "Unknown format character '%c' found in %s meta", _loadInfo.Meta->Types[x], fileName); break; } } @@ -736,16 +720,16 @@ char* DB2FileLoaderSparseImpl::AutoProduceData(uint32& maxId, char**& indexTable char* DB2FileLoaderSparseImpl::AutoProduceStrings(char* dataTable, uint32 locale) { - if (meta->FieldCount != header->FieldCount) + if (_loadInfo.Meta->FieldCount != _header->FieldCount) return nullptr; - if (!(header->Locale & (1 << locale))) + if (!(_header->Locale & (1 << locale))) { char const* sep = ""; std::ostringstream str; for (uint32 i = 0; i < TOTAL_LOCALES; ++i) { - if (header->Locale & (1 << i)) + if (_header->Locale & (1 << i)) { str << sep << localeNames[i]; sep = ", "; @@ -756,16 +740,16 @@ char* DB2FileLoaderSparseImpl::AutoProduceStrings(char* dataTable, uint32 locale return nullptr; } - uint32 offsetCount = header->MaxId - header->MinId + 1; + uint32 offsetCount = _header->MaxId - _header->MinId + 1; uint32 records = 0; for (uint32 i = 0; i < offsetCount; ++i) if (offsets[i].FileOffset && offsets[i].RecordSize) ++records; - uint32 recordsize = meta->GetRecordSize(); - std::size_t stringFields = meta->GetStringFieldCount(true); - char* stringTable = new char[header->StringTableSize - dataStart - records * ((recordsize - (!meta->HasIndexFieldInData() ? 4 : 0)) - stringFields * sizeof(char*))]; - memset(stringTable, 0, header->StringTableSize - dataStart - records * ((recordsize - (!meta->HasIndexFieldInData() ? 4 : 0)) - stringFields * sizeof(char*))); + uint32 recordsize = _loadInfo.Meta->GetRecordSize(); + std::size_t stringFields = _loadInfo.Meta->GetStringFieldCount(true); + char* stringTable = new char[_header->StringTableSize - dataStart - records * ((recordsize - (!_loadInfo.Meta->HasIndexFieldInData() ? 4 : 0)) - stringFields * sizeof(char*))]; + memset(stringTable, 0, _header->StringTableSize - dataStart - records * ((recordsize - (!_loadInfo.Meta->HasIndexFieldInData() ? 4 : 0)) - stringFields * sizeof(char*))); char* stringPtr = stringTable; uint32 offset = 0; @@ -775,15 +759,15 @@ char* DB2FileLoaderSparseImpl::AutoProduceStrings(char* dataTable, uint32 locale if (!offsets[y].FileOffset || !offsets[y].RecordSize) continue; - if (!meta->HasIndexFieldInData()) + if (!_loadInfo.Meta->HasIndexFieldInData()) offset += 4; std::size_t fieldOffset = 0; - for (uint32 x = 0; x < header->FieldCount; ++x) + for (uint32 x = 0; x < _header->FieldCount; ++x) { - for (uint32 z = 0; z < meta->ArraySizes[x]; ++z) + for (uint32 z = 0; z < _loadInfo.Meta->ArraySizes[x]; ++z) { - switch (meta->Types[x]) + switch (_loadInfo.Meta->Types[x]) { case FT_FLOAT: offset += 4; @@ -818,7 +802,7 @@ char* DB2FileLoaderSparseImpl::AutoProduceStrings(char* dataTable, uint32 locale break; } default: - ASSERT(false, "Unknown format character '%c' found in %s meta", meta->Types[x], fileName); + ASSERT(false, "Unknown format character '%c' found in %s meta", _loadInfo.Meta->Types[x], fileName); break; } } @@ -828,23 +812,23 @@ char* DB2FileLoaderSparseImpl::AutoProduceStrings(char* dataTable, uint32 locale return stringTable; } -char* DB2DatabaseLoader::Load(HotfixDatabaseStatements preparedStatement, uint32& records, char**& indexTable, char*& stringHolders, std::vector<char*>& stringPool) +char* DB2DatabaseLoader::Load(uint32& records, char**& indexTable, char*& stringHolders, std::vector<char*>& stringPool) { // Even though this query is executed only once, prepared statement is used to send data from mysql server in binary format - PreparedQueryResult result = HotfixDatabase.Query(HotfixDatabase.GetPreparedStatement(preparedStatement)); + PreparedQueryResult result = HotfixDatabase.Query(HotfixDatabase.GetPreparedStatement(_loadInfo.Statement)); if (!result) return nullptr; - if (_meta->GetDbFieldCount() != result->GetFieldCount()) + if (_loadInfo.Meta->GetDbFieldCount() != result->GetFieldCount()) return nullptr; // get struct size and index pos - uint32 indexField = _meta->GetDbIndexField(); - uint32 recordSize = _meta->GetRecordSize(); + uint32 indexField = _loadInfo.Meta->GetDbIndexField(); + uint32 recordSize = _loadInfo.Meta->GetRecordSize(); // we store flat holders pool as single memory block - std::size_t stringFields = _meta->GetStringFieldCount(false); - std::size_t localizedStringFields = _meta->GetStringFieldCount(true); + std::size_t stringFields = _loadInfo.Meta->GetStringFieldCount(false); + std::size_t localizedStringFields = _loadInfo.Meta->GetStringFieldCount(true); // each string field at load have array of string for each locale std::size_t stringHoldersRecordPoolSize = localizedStringFields * sizeof(LocalizedString) + (stringFields - localizedStringFields) * sizeof(char*); @@ -898,18 +882,18 @@ char* DB2DatabaseLoader::Load(HotfixDatabaseStatements preparedStatement, uint32 } uint32 f = 0; - if (!_meta->HasIndexFieldInData()) + if (!_loadInfo.Meta->HasIndexFieldInData()) { *((uint32*)(&dataValue[offset])) = indexValue; offset += 4; ++f; } - for (uint32 x = 0; x < _meta->FieldCount; ++x) + for (uint32 x = 0; x < _loadInfo.Meta->FieldCount; ++x) { - for (uint32 z = 0; z < _meta->ArraySizes[x]; ++z) + for (uint32 z = 0; z < _loadInfo.Meta->ArraySizes[x]; ++z) { - switch (_meta->Types[x]) + switch (_loadInfo.Meta->Types[x]) { case FT_FLOAT: *((float*)(&dataValue[offset])) = fields[f].GetFloat(); @@ -956,7 +940,7 @@ char* DB2DatabaseLoader::Load(HotfixDatabaseStatements preparedStatement, uint32 break; } default: - ASSERT(false, "Unknown format character '%c' found in %s meta", _meta->Types[x], _storageName.c_str()); + ASSERT(false, "Unknown format character '%c' found in %s meta", _loadInfo.Meta->Types[x], _storageName.c_str()); break; } ++f; @@ -990,20 +974,20 @@ char* DB2DatabaseLoader::Load(HotfixDatabaseStatements preparedStatement, uint32 return dataTable; } -void DB2DatabaseLoader::LoadStrings(HotfixDatabaseStatements preparedStatement, uint32 locale, uint32 records, char** indexTable, std::vector<char*>& stringPool) +void DB2DatabaseLoader::LoadStrings(uint32 locale, uint32 records, char** indexTable, std::vector<char*>& stringPool) { - PreparedStatement* stmt = HotfixDatabase.GetPreparedStatement(preparedStatement); + PreparedStatement* stmt = HotfixDatabase.GetPreparedStatement(HotfixDatabaseStatements(_loadInfo.Statement + 1)); stmt->setString(0, localeNames[locale]); PreparedQueryResult result = HotfixDatabase.Query(stmt); if (!result) return; - std::size_t stringFields = _meta->GetStringFieldCount(true); + std::size_t stringFields = _loadInfo.Meta->GetStringFieldCount(true); if (result->GetFieldCount() != stringFields + 1 /*ID*/) return; - uint32 fieldCount = _meta->FieldCount; - uint32 recordSize = _meta->GetRecordSize(); + uint32 fieldCount = _loadInfo.Meta->FieldCount; + uint32 recordSize = _loadInfo.Meta->GetRecordSize(); do { @@ -1018,14 +1002,14 @@ void DB2DatabaseLoader::LoadStrings(HotfixDatabaseStatements preparedStatement, // Attempt to overwrite existing data if (char* dataValue = indexTable[indexValue]) { - if (!_meta->HasIndexFieldInData()) + if (!_loadInfo.Meta->HasIndexFieldInData()) offset += 4; for (uint32 x = 0; x < fieldCount; ++x) { - for (uint32 z = 0; z < _meta->ArraySizes[x]; ++z) + for (uint32 z = 0; z < _loadInfo.Meta->ArraySizes[x]; ++z) { - switch (_meta->Types[x]) + switch (_loadInfo.Meta->Types[x]) { case FT_FLOAT: case FT_INT: @@ -1053,7 +1037,7 @@ void DB2DatabaseLoader::LoadStrings(HotfixDatabaseStatements preparedStatement, offset += sizeof(char*); break; default: - ASSERT(false, "Unknown format character '%c' found in %s meta", _meta->Types[x], _storageName.c_str()); + ASSERT(false, "Unknown format character '%c' found in %s meta", _loadInfo.Meta->Types[x], _storageName.c_str()); break; } } @@ -1102,7 +1086,7 @@ DB2FileLoader::~DB2FileLoader() delete _impl; } -bool DB2FileLoader::Load(char const* filename, DB2Meta const* meta) +bool DB2FileLoader::Load(char const* filename, DB2LoadInfo const& loadInfo) { FILE* f = fopen(filename, "rb"); if (!f) @@ -1170,7 +1154,7 @@ bool DB2FileLoader::Load(char const* filename, DB2Meta const* meta) EndianConvert(_header.LayoutHash); - if (_header.LayoutHash != meta->LayoutHash) + if (_header.LayoutHash != loadInfo.Meta->LayoutHash) { fclose(f); return false; @@ -1221,7 +1205,7 @@ bool DB2FileLoader::Load(char const* filename, DB2Meta const* meta) else _impl = new DB2FileLoaderSparseImpl(); - bool result = _impl->Load(filename, f, meta, &_header); + bool result = _impl->Load(filename, f, loadInfo, &_header); fclose(f); return result; } diff --git a/src/server/shared/DataStores/DB2StorageLoader.h b/src/server/shared/DataStores/DB2StorageLoader.h index 4cf55becc8d..e8a34c7977d 100644 --- a/src/server/shared/DataStores/DB2StorageLoader.h +++ b/src/server/shared/DataStores/DB2StorageLoader.h @@ -23,6 +23,7 @@ class DB2FileLoaderImpl; struct DB2Meta; +struct DB2FieldMeta; #pragma pack(push, 1) struct DB2Header @@ -43,13 +44,24 @@ struct DB2Header }; #pragma pack(pop) +struct TC_SHARED_API DB2LoadInfo +{ + DB2LoadInfo(); + DB2LoadInfo(DB2FieldMeta const* fields, std::size_t fieldCount, DB2Meta const* meta, HotfixDatabaseStatements statement); + + DB2FieldMeta const* Fields; + std::size_t FieldCount; + DB2Meta const* Meta; + HotfixDatabaseStatements Statement; +}; + class TC_SHARED_API DB2FileLoader { public: DB2FileLoader(); ~DB2FileLoader(); - bool Load(char const* filename, DB2Meta const* meta); + bool Load(char const* filename, DB2LoadInfo const& loadInfo); char* AutoProduceData(uint32& count, char**& indexTable, std::vector<char*>& stringPool); char* AutoProduceStrings(char* dataTable, uint32 locale); void AutoProduceRecordCopies(uint32 records, char** indexTable, char* dataTable); @@ -66,15 +78,15 @@ private: class TC_SHARED_API DB2DatabaseLoader { public: - DB2DatabaseLoader(std::string const& storageName, DB2Meta const* meta) : _storageName(storageName), _meta(meta) { } + DB2DatabaseLoader(std::string const& storageName, DB2LoadInfo const& loadInfo) : _storageName(storageName), _loadInfo(loadInfo) { } - char* Load(HotfixDatabaseStatements preparedStatement, uint32& records, char**& indexTable, char*& stringHolders, std::vector<char*>& stringPool); - void LoadStrings(HotfixDatabaseStatements preparedStatement, uint32 locale, uint32 records, char** indexTable, std::vector<char*>& stringPool); + char* Load(uint32& records, char**& indexTable, char*& stringHolders, std::vector<char*>& stringPool); + void LoadStrings(uint32 locale, uint32 records, char** indexTable, std::vector<char*>& stringPool); static char* AddString(char const** holder, std::string const& value); private: std::string _storageName; - DB2Meta const* _meta; + DB2LoadInfo _loadInfo; }; #endif diff --git a/src/server/shared/DataStores/DB2Store.h b/src/server/shared/DataStores/DB2Store.h index 0c63feba93c..dde7fd1a1b4 100644 --- a/src/server/shared/DataStores/DB2Store.h +++ b/src/server/shared/DataStores/DB2Store.h @@ -28,8 +28,8 @@ class DB2StorageBase { public: - DB2StorageBase(char const* fileName, DB2Meta const* meta, HotfixDatabaseStatements preparedStmtIndex) - : _tableHash(0), _layoutHash(0), _fileName(fileName), _fieldCount(0), _meta(meta), _dataTable(nullptr), _dataTableEx(nullptr), _hotfixStatement(preparedStmtIndex) { } + DB2StorageBase(char const* fileName, DB2LoadInfo loadInfo) + : _tableHash(0), _layoutHash(0), _fileName(fileName), _fieldCount(0), _loadInfo(loadInfo), _dataTable(nullptr), _dataTableEx(nullptr) { } virtual ~DB2StorageBase() { @@ -53,7 +53,7 @@ public: uint32 GetFieldCount() const { return _fieldCount; } - DB2Meta const* GetMeta() const { return _meta; } + DB2LoadInfo const* GetLoadInfo() const { return &_loadInfo; } virtual bool Load(std::string const& path, uint32 locale) = 0; virtual bool LoadStringsFrom(std::string const& path, uint32 locale) = 0; @@ -63,14 +63,14 @@ public: protected: void WriteRecordData(char const* entry, uint32 locale, ByteBuffer& buffer) const { - if (!_meta->HasIndexFieldInData()) + if (!_loadInfo.Meta->HasIndexFieldInData()) entry += 4; - for (uint32 i = 0; i < _meta->FieldCount; ++i) + for (uint32 i = 0; i < _loadInfo.Meta->FieldCount; ++i) { - for (uint32 a = 0; a < _meta->ArraySizes[i]; ++a) + for (uint32 a = 0; a < _loadInfo.Meta->ArraySizes[i]; ++a) { - switch (_meta->Types[i]) + switch (_loadInfo.Meta->Types[i]) { case FT_INT: buffer << *(uint32*)entry; @@ -113,11 +113,10 @@ protected: uint32 _layoutHash; std::string _fileName; uint32 _fieldCount; - DB2Meta const* _meta; + DB2LoadInfo _loadInfo; char* _dataTable; char* _dataTableEx; std::vector<char*> _stringPool; - HotfixDatabaseStatements _hotfixStatement; }; template<class T> @@ -128,7 +127,7 @@ class DB2Storage : public DB2StorageBase public: typedef DBStorageIterator<T> iterator; - DB2Storage(char const* fileName, DB2Meta const* meta, HotfixDatabaseStatements preparedStmtIndex) : DB2StorageBase(fileName, meta, preparedStmtIndex), + DB2Storage(char const* fileName, DB2LoadInfo loadInfo) : DB2StorageBase(fileName, loadInfo), _indexTableSize(0) { _indexTable.AsT = NULL; @@ -155,7 +154,7 @@ public: { DB2FileLoader db2; // Check if load was successful, only then continue - if (!db2.Load((path + _fileName).c_str(), _meta)) + if (!db2.Load((path + _fileName).c_str(), _loadInfo)) return false; _fieldCount = db2.GetCols(); @@ -184,11 +183,11 @@ public: DB2FileLoader db2; // Check if load was successful, only then continue - if (!db2.Load((path + _fileName).c_str(), _meta)) + if (!db2.Load((path + _fileName).c_str(), _loadInfo)) return false; // load strings from another locale db2 data - if (_meta->GetStringFieldCount(true)) + if (_loadInfo.Meta->GetStringFieldCount(true)) if (char* stringBlock = db2.AutoProduceStrings(_dataTable, locale)) _stringPool.push_back(stringBlock); return true; @@ -197,17 +196,17 @@ public: void LoadFromDB() override { char* extraStringHolders = nullptr; - _dataTableEx = DB2DatabaseLoader(_fileName, _meta).Load(_hotfixStatement, _indexTableSize, _indexTable.AsChar, extraStringHolders, _stringPool); + _dataTableEx = DB2DatabaseLoader(_fileName, _loadInfo).Load(_indexTableSize, _indexTable.AsChar, extraStringHolders, _stringPool); if (extraStringHolders) _stringPool.push_back(extraStringHolders); } void LoadStringsFromDB(uint32 locale) override { - if (!_meta->GetStringFieldCount(true)) + if (!_loadInfo.Meta->GetStringFieldCount(true)) return; - DB2DatabaseLoader(_fileName, _meta).LoadStrings(HotfixDatabaseStatements(_hotfixStatement + 1), locale, _indexTableSize, _indexTable.AsChar, _stringPool); + DB2DatabaseLoader(_fileName, _loadInfo).LoadStrings(locale, _indexTableSize, _indexTable.AsChar, _stringPool); } iterator begin() { return iterator(_indexTable.AsT, _indexTableSize); } |
