aboutsummaryrefslogtreecommitdiff
path: root/src/common/DataStores/DB2FileLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/DataStores/DB2FileLoader.cpp')
-rw-r--r--src/common/DataStores/DB2FileLoader.cpp166
1 files changed, 159 insertions, 7 deletions
diff --git a/src/common/DataStores/DB2FileLoader.cpp b/src/common/DataStores/DB2FileLoader.cpp
index 6ec065aef27..7578eace9b6 100644
--- a/src/common/DataStores/DB2FileLoader.cpp
+++ b/src/common/DataStores/DB2FileLoader.cpp
@@ -37,8 +37,8 @@ DB2FileLoadInfo::DB2FileLoadInfo(DB2FieldMeta const* fields, std::size_t fieldCo
uint32 DB2FileLoadInfo::GetStringFieldCount(bool localizedOnly) const
{
uint32 stringFields = 0;
- for (std::size_t i = 0; i < TypesString.length(); ++i)
- if (TypesString[i] == FT_STRING || (TypesString[i] == FT_STRING_NOT_LOCALIZED && !localizedOnly))
+ for (char fieldType : TypesString)
+ if (fieldType == FT_STRING || (fieldType == FT_STRING_NOT_LOCALIZED && !localizedOnly))
++stringFields;
return stringFields;
@@ -93,6 +93,7 @@ public:
uint32 GetMaxId() const override;
private:
+ void FillCommonValues(char** indexTable);
unsigned char const* GetRawRecordData(uint32 recordNumber) const override;
uint32 RecordGetId(unsigned char const* record, uint32 recordIndex) const override;
uint8 RecordGetUInt8(unsigned char const* record, uint32 field, uint32 arrayIndex) const override;
@@ -126,6 +127,7 @@ private:
uint32 idTableSize;
DB2RecordCopy* copyTable;
FieldEntry* fields;
+ unsigned char* commonData;
};
class DB2FileLoaderSparseImpl final : public DB2FileLoaderImpl
@@ -196,6 +198,7 @@ DB2FileLoaderRegularImpl::DB2FileLoaderRegularImpl()
idTableSize = 0;
copyTable = nullptr;
fields = nullptr;
+ commonData = nullptr;
}
bool DB2FileLoaderRegularImpl::Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo, DB2Header const* header)
@@ -232,6 +235,20 @@ bool DB2FileLoaderRegularImpl::Load(DB2FileSource* source, DB2FileLoadInfo const
return false;
}
+ if (header->CommonDataSize)
+ {
+ uint32 commonFieldCount;
+ if (!source->Read(&commonFieldCount, sizeof(uint32)))
+ return false;
+
+ if (commonFieldCount != header->TotalFieldCount)
+ return false;
+
+ commonData = new unsigned char[header->CommonDataSize - sizeof(uint32)];
+ if (!source->Read(commonData, header->CommonDataSize - sizeof(uint32)))
+ return false;
+ }
+
return true;
}
@@ -241,13 +258,14 @@ DB2FileLoaderRegularImpl::~DB2FileLoaderRegularImpl()
delete[] idTable;
delete[] copyTable;
delete[] fields;
+ delete[] commonData;
}
static char const* const nullStr = "";
char* DB2FileLoaderRegularImpl::AutoProduceData(uint32& records, char**& indexTable, std::vector<char*>& stringPool)
{
- if (_loadInfo->Meta->FieldCount != _header->FieldCount)
+ if (_loadInfo->Meta->FieldCount != _header->TotalFieldCount)
return nullptr;
//get struct size and index pos
@@ -347,14 +365,61 @@ char* DB2FileLoaderRegularImpl::AutoProduceData(uint32& records, char**& indexTa
++fieldIndex;
}
}
+
+ for (uint32 x = _header->FieldCount; x < _header->TotalFieldCount; ++x)
+ {
+ for (uint32 z = 0; z < _loadInfo->Meta->ArraySizes[x]; ++z)
+ {
+ switch (_loadInfo->TypesString[fieldIndex])
+ {
+ case FT_FLOAT:
+ *((float*)(&dataTable[offset])) = _loadInfo->Meta->FieldDefaults[x].AsFloat;
+ offset += 4;
+ break;
+ case FT_INT:
+ *((uint32*)(&dataTable[offset])) = _loadInfo->Meta->FieldDefaults[x].AsUInt32;
+ offset += 4;
+ break;
+ case FT_BYTE:
+ *((uint8*)(&dataTable[offset])) = _loadInfo->Meta->FieldDefaults[x].AsUInt8;
+ offset += 1;
+ break;
+ case FT_SHORT:
+ *((uint16*)(&dataTable[offset])) = _loadInfo->Meta->FieldDefaults[x].AsUInt16;
+ offset += 2;
+ break;
+ case FT_STRING:
+ case FT_STRING_NOT_LOCALIZED:
+ {
+ // 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 (_loadInfo->TypesString[fieldIndex] == FT_STRING)
+ stringFieldOffset += sizeof(LocalizedString);
+ else
+ stringFieldOffset += sizeof(char*);
+
+ offset += sizeof(char*);
+ break;
+ }
+ default:
+ ASSERT(false, "Unknown format character '%c' found in %s meta", _loadInfo->TypesString[x], fileName);
+ break;
+ }
+ ++fieldIndex;
+ }
+ }
}
+ if (commonData)
+ FillCommonValues(indexTable);
+
return dataTable;
}
char* DB2FileLoaderRegularImpl::AutoProduceStrings(char* dataTable, uint32 locale)
{
- if (_loadInfo->Meta->FieldCount != _header->FieldCount)
+ if (_loadInfo->Meta->FieldCount != _header->TotalFieldCount)
return nullptr;
if (!(_header->Locale & (1 << locale)))
@@ -389,7 +454,7 @@ char* DB2FileLoaderRegularImpl::AutoProduceStrings(char* dataTable, uint32 local
++fieldIndex;
}
- for (uint32 x = 0; x < _header->FieldCount; ++x)
+ for (uint32 x = 0; x < _header->TotalFieldCount; ++x)
{
for (uint32 z = 0; z < _loadInfo->Meta->ArraySizes[x]; ++z)
{
@@ -460,6 +525,91 @@ void DB2FileLoaderRegularImpl::AutoProduceRecordCopies(uint32 records, char** in
}
}
+void DB2FileLoaderRegularImpl::FillCommonValues(char** indexTable)
+{
+ uint32 fieldOffset = 0;
+ if (!_loadInfo->Meta->HasIndexFieldInData())
+ fieldOffset += 4;
+
+ unsigned char* commonDataItr = commonData;
+ for (uint32 field = 0; field < _header->TotalFieldCount; ++field)
+ {
+ uint32 numExtraValuesForField = *reinterpret_cast<uint32*>(commonDataItr);
+ commonDataItr += sizeof(uint32);
+ uint8 dataType = *reinterpret_cast<uint8*>(commonDataItr);
+ commonDataItr += sizeof(uint8);
+ for (uint32 record = 0; record < numExtraValuesForField; ++record)
+ {
+ uint32 recordId = *reinterpret_cast<uint32*>(commonDataItr);
+ commonDataItr += sizeof(uint32);
+
+ char* recordData = indexTable[recordId];
+
+ switch (dataType)
+ {
+ case 1:
+ {
+ ASSERT(_loadInfo->Meta->Types[field] == FT_SHORT);
+ uint16 value = *reinterpret_cast<uint16*>(commonDataItr);
+ EndianConvert(value);
+ commonDataItr += sizeof(uint16);
+ for (uint32 arrayIndex = 0; arrayIndex < _loadInfo->Meta->ArraySizes[field]; ++arrayIndex)
+ *reinterpret_cast<uint16*>(&recordData[fieldOffset + sizeof(uint16) * arrayIndex]) = value;
+ break;
+ }
+ case 2:
+ {
+ ASSERT(_loadInfo->Meta->Types[field] == FT_BYTE);
+ uint8 value = *reinterpret_cast<uint8*>(commonDataItr);
+ commonDataItr += sizeof(uint8);
+ for (uint32 arrayIndex = 0; arrayIndex < _loadInfo->Meta->ArraySizes[field]; ++arrayIndex)
+ *reinterpret_cast<uint8*>(&recordData[fieldOffset + sizeof(uint8) * arrayIndex]) = value;
+ break;
+ }
+ case 3:
+ {
+ ASSERT(_loadInfo->Meta->Types[field] == FT_FLOAT);
+ float value = *reinterpret_cast<float*>(commonDataItr);
+ EndianConvert(value);
+ commonDataItr += sizeof(float);
+ for (uint32 arrayIndex = 0; arrayIndex < _loadInfo->Meta->ArraySizes[field]; ++arrayIndex)
+ *reinterpret_cast<float*>(&recordData[fieldOffset + sizeof(float) * arrayIndex]) = value;
+ break;
+ }
+ case 4:
+ {
+ ASSERT(_loadInfo->Meta->Types[field] == FT_INT);
+ uint32 value = *reinterpret_cast<uint32*>(commonDataItr);
+ EndianConvert(value);
+ commonDataItr += sizeof(uint32);
+ for (uint32 arrayIndex = 0; arrayIndex < _loadInfo->Meta->ArraySizes[field]; ++arrayIndex)
+ *reinterpret_cast<uint32*>(&recordData[fieldOffset + sizeof(uint32) * arrayIndex]) = value;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ switch (_loadInfo->Meta->Types[field])
+ {
+ case FT_FLOAT:
+ case FT_INT:
+ fieldOffset += 4 * _loadInfo->Meta->ArraySizes[field];
+ break;
+ case FT_BYTE:
+ fieldOffset += 1 * _loadInfo->Meta->ArraySizes[field];
+ break;
+ case FT_SHORT:
+ fieldOffset += 2 * _loadInfo->Meta->ArraySizes[field];
+ break;
+ case FT_STRING:
+ fieldOffset += sizeof(char*) * _loadInfo->Meta->ArraySizes[field];
+ break;
+ }
+ }
+}
+
DB2Record DB2FileLoaderRegularImpl::GetRecord(uint32 recordNumber) const
{
return DB2Record(*this, recordNumber, nullptr);
@@ -642,7 +792,7 @@ bool DB2FileLoaderSparseImpl::Load(DB2FileSource* source, DB2FileLoadInfo const*
char* DB2FileLoaderSparseImpl::AutoProduceData(uint32& maxId, char**& indexTable, std::vector<char*>& stringPool)
{
if (_loadInfo->Meta->FieldCount != _header->FieldCount)
- return NULL;
+ return nullptr;
//get struct size and index pos
uint32 recordsize = _loadInfo->Meta->GetRecordSize();
@@ -1100,8 +1250,10 @@ bool DB2FileLoader::Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo)
EndianConvert(_header.CopyTableSize);
EndianConvert(_header.Flags);
EndianConvert(_header.IndexField);
+ EndianConvert(_header.TotalFieldCount);
+ EndianConvert(_header.CommonDataSize);
- if (_header.Signature != 0x35424457) //'WDB5'
+ if (_header.Signature != 0x36424457) //'WDB6'
return false;
if (_header.LayoutHash != loadInfo->Meta->LayoutHash)