aboutsummaryrefslogtreecommitdiff
path: root/src/common/DataStores/DB2FileLoader.cpp
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2019-06-08 13:19:48 +0200
committerShauren <shauren.trinity@gmail.com>2019-06-08 17:10:00 +0200
commitbcaaa3d6f69cd60b25a25fc69904f9a8ece24250 (patch)
tree585dac52b621b55b5f380a8cdc6725b4b2df6129 /src/common/DataStores/DB2FileLoader.cpp
parentfc330fd8ff0115804d9c4b53a1f810c00dd63de9 (diff)
Core/DataStores: Updated db2 structures to 8.1.5
Diffstat (limited to 'src/common/DataStores/DB2FileLoader.cpp')
-rw-r--r--src/common/DataStores/DB2FileLoader.cpp958
1 files changed, 593 insertions, 365 deletions
diff --git a/src/common/DataStores/DB2FileLoader.cpp b/src/common/DataStores/DB2FileLoader.cpp
index 47d5a2fc1e0..76aad009683 100644
--- a/src/common/DataStores/DB2FileLoader.cpp
+++ b/src/common/DataStores/DB2FileLoader.cpp
@@ -35,18 +35,6 @@ enum class DB2ColumnCompression : uint32
#pragma pack(push, 1)
-struct DB2SectionHeader
-{
- uint64 TactKeyId;
- uint32 FileOffset;
- uint32 RecordCount;
- uint32 StringTableSize;
- uint32 CopyTableSize;
- uint32 CatalogDataOffset;
- uint32 IdTableSize;
- uint32 ParentLookupDataSize;
-};
-
struct DB2FieldEntry
{
int16 UnusedBits;
@@ -116,8 +104,7 @@ struct DB2IndexEntry
struct DB2IndexData
{
- DB2IndexDataInfo Info;
- std::unique_ptr<DB2IndexEntry[]> Entries;
+ std::vector<DB2IndexEntry> Entries;
};
DB2FieldMeta::DB2FieldMeta(bool isSigned, DBCFormer type, char const* name)
@@ -175,6 +162,7 @@ public:
virtual void LoadColumnData(std::unique_ptr<DB2SectionHeader[]> sections, std::unique_ptr<DB2FieldEntry[]> fields, std::unique_ptr<DB2ColumnMeta[]> columnMeta,
std::unique_ptr<std::unique_ptr<DB2PalletValue[]>[]> palletValues, std::unique_ptr<std::unique_ptr<DB2PalletValue[]>[]> palletArrayValues,
std::unique_ptr<std::unordered_map<uint32, uint32>[]> commonValues) = 0;
+ virtual void SkipEncryptedSection(uint32 section) = 0;
virtual bool LoadTableData(DB2FileSource* source, uint32 section) = 0;
virtual bool LoadCatalogData(DB2FileSource* source, uint32 section) = 0;
virtual void SetAdditionalData(std::vector<uint32> idTable, std::vector<DB2RecordCopy> copyTable, std::vector<DB2IndexData> parentIndexes) = 0;
@@ -192,7 +180,7 @@ public:
private:
friend class DB2Record;
- virtual unsigned char const* GetRawRecordData(uint32 recordNumber) const = 0;
+ virtual unsigned char const* GetRawRecordData(uint32 recordNumber, uint32 const* section) const = 0;
virtual uint32 RecordGetId(uint8 const* record, uint32 recordIndex) const = 0;
virtual uint8 RecordGetUInt8(uint8 const* record, uint32 field, uint32 arrayIndex) const = 0;
virtual uint16 RecordGetUInt16(uint8 const* record, uint32 field, uint32 arrayIndex) const = 0;
@@ -214,6 +202,7 @@ public:
void LoadColumnData(std::unique_ptr<DB2SectionHeader[]> sections, std::unique_ptr<DB2FieldEntry[]> fields, std::unique_ptr<DB2ColumnMeta[]> columnMeta,
std::unique_ptr<std::unique_ptr<DB2PalletValue[]>[]> palletValues, std::unique_ptr<std::unique_ptr<DB2PalletValue[]>[]> palletArrayValues,
std::unique_ptr<std::unordered_map<uint32, uint32>[]> commonValues) override;
+ void SkipEncryptedSection(uint32 /*section*/) override { }
bool LoadTableData(DB2FileSource* source, uint32 section) override;
bool LoadCatalogData(DB2FileSource* /*source*/, uint32 /*section*/) override { return true; }
void SetAdditionalData(std::vector<uint32> idTable, std::vector<DB2RecordCopy> copyTable, std::vector<DB2IndexData> parentIndexes) override;
@@ -231,7 +220,8 @@ public:
private:
void FillParentLookup(char* dataTable);
- uint8 const* GetRawRecordData(uint32 recordNumber) const override;
+ uint32 GetRecordSection(uint32 recordNumber) const;
+ unsigned char const* GetRawRecordData(uint32 recordNumber, uint32 const* section) const override;
uint32 RecordGetId(uint8 const* record, uint32 recordIndex) const override;
uint8 RecordGetUInt8(uint8 const* record, uint32 field, uint32 arrayIndex) const override;
uint16 RecordGetUInt16(uint8 const* record, uint32 field, uint32 arrayIndex) const override;
@@ -265,18 +255,19 @@ private:
class DB2FileLoaderSparseImpl final : public DB2FileLoaderImpl
{
public:
- DB2FileLoaderSparseImpl(char const* fileName, DB2FileLoadInfo const* loadInfo, DB2Header const* header);
+ DB2FileLoaderSparseImpl(char const* fileName, DB2FileLoadInfo const* loadInfo, DB2Header const* header, DB2FileSource* source);
~DB2FileLoaderSparseImpl();
void LoadColumnData(std::unique_ptr<DB2SectionHeader[]> sections, std::unique_ptr<DB2FieldEntry[]> fields, std::unique_ptr<DB2ColumnMeta[]> columnMeta,
std::unique_ptr<std::unique_ptr<DB2PalletValue[]>[]> palletValues, std::unique_ptr<std::unique_ptr<DB2PalletValue[]>[]> palletArrayValues,
std::unique_ptr<std::unordered_map<uint32, uint32>[]> commonValues) override;
- bool LoadTableData(DB2FileSource* source, uint32 section) override;
+ void SkipEncryptedSection(uint32 section) override;
+ bool LoadTableData(DB2FileSource* source, uint32 section) override { return true; }
bool LoadCatalogData(DB2FileSource* source, uint32 section) override;
- void SetAdditionalData(std::vector<uint32> /*idTable*/, std::vector<DB2RecordCopy> /*copyTable*/, std::vector<DB2IndexData> /*parentIndexes*/) override { }
+ void SetAdditionalData(std::vector<uint32> /*idTable*/, std::vector<DB2RecordCopy> /*copyTable*/, std::vector<DB2IndexData> /*parentIndexes*/) override;
char* AutoProduceData(uint32& records, char**& indexTable, std::vector<char*>& stringPool) override;
char* AutoProduceStrings(char** indexTable, uint32 indexTableSize, uint32 locale) override;
- void AutoProduceRecordCopies(uint32 /*records*/, char** /*indexTable*/, char* /*dataTable*/) override { }
+ void AutoProduceRecordCopies(uint32 /*records*/, char** /*indexTable*/, char* /*dataTable*/) override;
DB2Record GetRecord(uint32 recordNumber) const override;
DB2RecordCopy GetRecordCopy(uint32 copyNumber) const override;
uint32 GetRecordCount() const override;
@@ -287,7 +278,9 @@ public:
bool IsSignedField(uint32 field) const override;
private:
- uint8 const* GetRawRecordData(uint32 recordNumber) const override;
+ void FillParentLookup(char* dataTable);
+ uint32 GetRecordSection(uint32 recordNumber) const;
+ unsigned char const* GetRawRecordData(uint32 recordNumber, uint32 const* section) const override;
uint32 RecordGetId(uint8 const* record, uint32 recordIndex) const override;
uint8 RecordGetUInt8(uint8 const* record, uint32 field, uint32 arrayIndex) const override;
uint16 RecordGetUInt16(uint8 const* record, uint32 field, uint32 arrayIndex) const override;
@@ -309,12 +302,17 @@ private:
char const* _fileName;
DB2FileLoadInfo const* _loadInfo;
DB2Header const* _header;
- std::size_t _dataStart;
- std::unique_ptr<uint8[]> _data;
+ DB2FileSource* const _source;
+ std::size_t _totalRecordSize;
+ uint16 _maxRecordSize;
+ std::unique_ptr<uint8[]> _recordBuffer;
std::unique_ptr<DB2SectionHeader[]> _sections;
std::unique_ptr<DB2FieldEntry[]> _fields;
std::unique_ptr<std::size_t[]> _fieldAndArrayOffsets;
- std::unique_ptr<DB2CatalogEntry[]> _catalog;
+ std::vector<uint32> _catalogIds;
+ std::vector<DB2CatalogEntry> _catalog;
+ std::vector<DB2RecordCopy> _copyTable;
+ std::vector<DB2IndexData> _parentIndexes;
};
DB2FileLoaderRegularImpl::DB2FileLoaderRegularImpl(char const* fileName, DB2FileLoadInfo const* loadInfo, DB2Header const* header) :
@@ -409,122 +407,134 @@ char* DB2FileLoaderRegularImpl::AutoProduceData(uint32& records, char**& indexTa
}
uint32 offset = 0;
+ uint32 y = 0;
- for (uint32 y = 0; y < _header->RecordCount; y++)
+ for (uint32 section = 0; section < _header->SectionCount; ++section)
{
- unsigned char const* rawRecord = GetRawRecordData(y);
- if (!rawRecord)
+ DB2SectionHeader const& sectionHeader = GetSection(section);
+ if (sectionHeader.TactId)
+ {
+ offset += recordsize * sectionHeader.RecordCount;
+ y += sectionHeader.RecordCount;
continue;
+ }
- uint32 indexVal = RecordGetId(rawRecord, y);
+ for (uint32 sr = 0; sr < sectionHeader.RecordCount; ++sr, ++y)
+ {
+ unsigned char const* rawRecord = GetRawRecordData(y, &section);
+ if (!rawRecord)
+ continue;
- indexTable[indexVal] = &dataTable[offset];
+ uint32 indexVal = RecordGetId(rawRecord, y);
- uint32 fieldIndex = 0;
- if (!_loadInfo->Meta->HasIndexFieldInData())
- {
- *((uint32*)(&dataTable[offset])) = indexVal;
- offset += 4;
- ++fieldIndex;
- }
+ indexTable[indexVal] = &dataTable[offset];
+
+ uint32 fieldIndex = 0;
+ if (!_loadInfo->Meta->HasIndexFieldInData())
+ {
+ *((uint32*)(&dataTable[offset])) = indexVal;
+ offset += 4;
+ ++fieldIndex;
+ }
- uint32 stringFieldOffset = 0;
+ uint32 stringFieldOffset = 0;
- for (uint32 x = 0; x < _header->FieldCount; ++x)
- {
- for (uint32 z = 0; z < _loadInfo->Meta->Fields[x].ArraySize; ++z)
+ for (uint32 x = 0; x < _header->FieldCount; ++x)
{
- switch (_loadInfo->TypesString[fieldIndex])
+ for (uint32 z = 0; z < _loadInfo->Meta->Fields[x].ArraySize; ++z)
{
- case FT_FLOAT:
- *((float*)(&dataTable[offset])) = RecordGetFloat(rawRecord, x, z);
- offset += 4;
- break;
- case FT_INT:
- *((uint32*)(&dataTable[offset])) = RecordGetVarInt<uint32>(rawRecord, x, z);
- offset += 4;
- break;
- case FT_BYTE:
- *((uint8*)(&dataTable[offset])) = RecordGetUInt8(rawRecord, x, z);
- offset += 1;
- break;
- case FT_SHORT:
- *((uint16*)(&dataTable[offset])) = RecordGetUInt16(rawRecord, x, z);
- offset += 2;
- break;
- case FT_LONG:
- *((uint64*)(&dataTable[offset])) = RecordGetUInt64(rawRecord, x, z);
- offset += 8;
- break;
- case FT_STRING:
- case FT_STRING_NOT_LOCALIZED:
+ switch (_loadInfo->TypesString[fieldIndex])
{
- // 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;
+ case FT_FLOAT:
+ *((float*)(&dataTable[offset])) = RecordGetFloat(rawRecord, x, z);
+ offset += 4;
+ break;
+ case FT_INT:
+ *((uint32*)(&dataTable[offset])) = RecordGetVarInt<uint32>(rawRecord, x, z);
+ offset += 4;
+ break;
+ case FT_BYTE:
+ *((uint8*)(&dataTable[offset])) = RecordGetUInt8(rawRecord, x, z);
+ offset += 1;
+ break;
+ case FT_SHORT:
+ *((uint16*)(&dataTable[offset])) = RecordGetUInt16(rawRecord, x, z);
+ offset += 2;
+ break;
+ case FT_LONG:
+ *((uint64*)(&dataTable[offset])) = RecordGetUInt64(rawRecord, x, z);
+ offset += 8;
+ 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 for field %s",
+ _loadInfo->TypesString[fieldIndex], _fileName, _loadInfo->Fields[fieldIndex].Name);
+ break;
}
- default:
- ASSERT(false, "Unknown format character '%c' found in %s meta for field %s",
- _loadInfo->TypesString[fieldIndex], _fileName, _loadInfo->Fields[fieldIndex].Name);
- break;
+ ++fieldIndex;
}
- ++fieldIndex;
}
- }
- for (uint32 x = _header->FieldCount; x < _loadInfo->Meta->FieldCount; ++x)
- {
- for (uint32 z = 0; z < _loadInfo->Meta->Fields[x].ArraySize; ++z)
+ for (uint32 x = _header->FieldCount; x < _loadInfo->Meta->FieldCount; ++x)
{
- switch (_loadInfo->TypesString[fieldIndex])
+ for (uint32 z = 0; z < _loadInfo->Meta->Fields[x].ArraySize; ++z)
{
- case FT_FLOAT:
- *((float*)(&dataTable[offset])) = 0;
- offset += 4;
- break;
- case FT_INT:
- *((uint32*)(&dataTable[offset])) = 0;
- offset += 4;
- break;
- case FT_BYTE:
- *((uint8*)(&dataTable[offset])) = 0;
- offset += 1;
- break;
- case FT_SHORT:
- *((uint16*)(&dataTable[offset])) = 0;
- offset += 2;
- break;
- case FT_LONG:
- *((uint64*)(&dataTable[offset])) = 0;
- offset += 8;
- break;
- case FT_STRING:
- case FT_STRING_NOT_LOCALIZED:
+ switch (_loadInfo->TypesString[fieldIndex])
{
- // 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;
+ case FT_FLOAT:
+ *((float*)(&dataTable[offset])) = 0;
+ offset += 4;
+ break;
+ case FT_INT:
+ *((uint32*)(&dataTable[offset])) = 0;
+ offset += 4;
+ break;
+ case FT_BYTE:
+ *((uint8*)(&dataTable[offset])) = 0;
+ offset += 1;
+ break;
+ case FT_SHORT:
+ *((uint16*)(&dataTable[offset])) = 0;
+ offset += 2;
+ break;
+ case FT_LONG:
+ *((uint64*)(&dataTable[offset])) = 0;
+ offset += 8;
+ 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 for field %s",
+ _loadInfo->TypesString[fieldIndex], _fileName, _loadInfo->Fields[fieldIndex].Name);
+ break;
}
- default:
- ASSERT(false, "Unknown format character '%c' found in %s meta for field %s",
- _loadInfo->TypesString[fieldIndex], _fileName, _loadInfo->Fields[fieldIndex].Name);
- break;
+ ++fieldIndex;
}
- ++fieldIndex;
}
}
}
@@ -557,72 +567,84 @@ char* DB2FileLoaderRegularImpl::AutoProduceStrings(char** indexTable, uint32 ind
char* stringPool = new char[_header->StringTableSize];
memcpy(stringPool, _stringTable, _header->StringTableSize);
- for (uint32 y = 0; y < _header->RecordCount; y++)
+ uint32 y = 0;
+
+ for (uint32 section = 0; section < _header->SectionCount; ++section)
{
- unsigned char const* rawRecord = GetRawRecordData(y);
- if (!rawRecord)
+ DB2SectionHeader const& sectionHeader = GetSection(section);
+ if (sectionHeader.TactId)
+ {
+ y += sectionHeader.RecordCount;
continue;
+ }
- uint32 indexVal = RecordGetId(rawRecord, y);
- if (indexVal >= indexTableSize)
- continue;
+ for (uint32 sr = 0; sr < sectionHeader.RecordCount; ++sr, ++y)
+ {
+ unsigned char const* rawRecord = GetRawRecordData(y, &section);
+ if (!rawRecord)
+ continue;
- char* recordData = indexTable[indexVal];
+ uint32 indexVal = RecordGetId(rawRecord, y);
+ if (indexVal >= indexTableSize)
+ continue;
- uint32 offset = 0;
- uint32 fieldIndex = 0;
- if (!_loadInfo->Meta->HasIndexFieldInData())
- {
- offset += 4;
- ++fieldIndex;
- }
+ char* recordData = indexTable[indexVal];
- for (uint32 x = 0; x < _loadInfo->Meta->FieldCount; ++x)
- {
- for (uint32 z = 0; z < _loadInfo->Meta->Fields[x].ArraySize; ++z)
+ uint32 offset = 0;
+ uint32 fieldIndex = 0;
+ if (!_loadInfo->Meta->HasIndexFieldInData())
+ {
+ offset += 4;
+ ++fieldIndex;
+ }
+
+ for (uint32 x = 0; x < _loadInfo->Meta->FieldCount; ++x)
{
- switch (_loadInfo->TypesString[fieldIndex])
+ for (uint32 z = 0; z < _loadInfo->Meta->Fields[x].ArraySize; ++z)
{
- case FT_FLOAT:
- case FT_INT:
- offset += 4;
- break;
- case FT_BYTE:
- offset += 1;
- break;
- case FT_SHORT:
- offset += 2;
- break;
- case FT_LONG:
- offset += 8;
- break;
- case FT_STRING:
+ switch (_loadInfo->TypesString[fieldIndex])
{
- // fill only not filled entries
- LocalizedString* db2str = *(LocalizedString**)(&recordData[offset]);
- if (db2str->Str[locale] == nullStr)
+ case FT_FLOAT:
+ case FT_INT:
+ offset += 4;
+ break;
+ case FT_BYTE:
+ offset += 1;
+ break;
+ case FT_SHORT:
+ offset += 2;
+ break;
+ case FT_LONG:
+ offset += 8;
+ break;
+ case FT_STRING:
+ {
+ // fill only not filled entries
+ LocalizedString* db2str = *(LocalizedString * *)(&recordData[offset]);
+ if (db2str->Str[locale] == nullStr)
+ {
+ char const* st = RecordGetString(rawRecord, x, z);
+ db2str->Str[locale] = stringPool + (st - (char const*)_stringTable);
+ }
+
+ offset += sizeof(char*);
+ break;
+ }
+ case FT_STRING_NOT_LOCALIZED:
{
+ char** db2str = (char**)(&recordData[offset]);
char const* st = RecordGetString(rawRecord, x, z);
- db2str->Str[locale] = stringPool + (st - (char const*)_stringTable);
+ *db2str = stringPool + (st - (char const*)_stringTable);
+ offset += sizeof(char*);
+ break;
}
-
- offset += sizeof(char*);
- break;
- }
- case FT_STRING_NOT_LOCALIZED:
- {
- char** db2str = (char**)(&recordData[offset]);
- char const* st = RecordGetString(rawRecord, x, z);
- *db2str = stringPool + (st - (char const*)_stringTable);
- offset += sizeof(char*);
- break;
+ default:
+ ASSERT(false, "Unknown format character '%c' found in %s meta for field %s",
+ _loadInfo->TypesString[fieldIndex], _fileName, _loadInfo->Fields[fieldIndex].Name);
+ break;
}
- default:
- ASSERT(false, "Unknown format character '%c' found in %s meta for field %s",
- _loadInfo->TypesString[fieldIndex], _fileName, _loadInfo->Fields[fieldIndex].Name);
- break;
+ ++fieldIndex;
}
- ++fieldIndex;
}
}
}
@@ -652,7 +674,7 @@ void DB2FileLoaderRegularImpl::FillParentLookup(char* dataTable)
{
int32 parentIdOffset = _loadInfo->Meta->GetParentIndexFieldOffset();
uint32 recordSize = _loadInfo->Meta->GetRecordSize();
- for (uint32 i = 0; i < _parentIndexes[0].Info.NumEntries; ++i)
+ for (std::size_t i = 0; i < _parentIndexes[0].Entries.size(); ++i)
{
uint32 parentId = _parentIndexes[0].Entries[i].ParentId;
char* recordData = &dataTable[_parentIndexes[0].Entries[i].RecordIndex * recordSize];
@@ -698,11 +720,29 @@ uint32 DB2FileLoaderRegularImpl::GetRecordCopyCount() const
return _copyTable.size();
}
-uint8 const* DB2FileLoaderRegularImpl::GetRawRecordData(uint32 recordNumber) const
+uint32 DB2FileLoaderRegularImpl::GetRecordSection(uint32 recordNumber) const
+{
+ uint32 section = 0;
+ for (; section < _header->SectionCount; ++section)
+ {
+ DB2SectionHeader const& sectionHeader = GetSection(section);
+ if (recordNumber < sectionHeader.RecordCount)
+ break;
+
+ recordNumber -= sectionHeader.RecordCount;
+ }
+
+ return section;
+}
+
+unsigned char const* DB2FileLoaderRegularImpl::GetRawRecordData(uint32 recordNumber, uint32 const* section) const
{
if (recordNumber >= _header->RecordCount)
return nullptr;
+ if (GetSection(section ? *section : GetRecordSection(recordNumber)).TactId)
+ return nullptr;
+
return &_data[recordNumber * _header->RecordSize];
}
@@ -873,7 +913,11 @@ uint32 DB2FileLoaderRegularImpl::GetMaxId() const
uint32 maxId = 0;
for (uint32 row = 0; row < _header->RecordCount; ++row)
{
- uint32 id = RecordGetId(GetRawRecordData(row), row);
+ unsigned char const* rawRecord = GetRawRecordData(row, nullptr);
+ if (!rawRecord)
+ continue;
+
+ uint32 id = RecordGetId(rawRecord, row);
if (id > maxId)
maxId = id;
}
@@ -885,6 +929,7 @@ uint32 DB2FileLoaderRegularImpl::GetMaxId() const
maxId = id;
}
+ ASSERT(maxId <= _header->MaxId);
return maxId;
}
@@ -927,12 +972,14 @@ bool DB2FileLoaderRegularImpl::IsSignedField(uint32 field) const
return false;
}
-DB2FileLoaderSparseImpl::DB2FileLoaderSparseImpl(char const* fileName, DB2FileLoadInfo const* loadInfo, DB2Header const* header) :
+DB2FileLoaderSparseImpl::DB2FileLoaderSparseImpl(char const* fileName, DB2FileLoadInfo const* loadInfo, DB2Header const* header, DB2FileSource* source) :
_fileName(fileName),
_loadInfo(loadInfo),
_header(header),
- _dataStart(0),
- _fieldAndArrayOffsets(Trinity::make_unique<std::size_t[]>(loadInfo->Meta->FieldCount + loadInfo->FieldCount - (!loadInfo->Meta->HasIndexFieldInData() ? 1 : 0)))
+ _source(source),
+ _totalRecordSize(0),
+ _maxRecordSize(0),
+ _fieldAndArrayOffsets(loadInfo ? (Trinity::make_unique<std::size_t[]>(loadInfo->Meta->FieldCount + loadInfo->FieldCount - (!loadInfo->Meta->HasIndexFieldInData() ? 1 : 0))) : nullptr)
{
}
@@ -948,23 +995,46 @@ void DB2FileLoaderSparseImpl::LoadColumnData(std::unique_ptr<DB2SectionHeader[]>
_fields = std::move(fields);
}
-bool DB2FileLoaderSparseImpl::LoadTableData(DB2FileSource* source, uint32 section)
+void DB2FileLoaderSparseImpl::SkipEncryptedSection(uint32 section)
{
- if (section != 0)
- return false;
-
- _dataStart = source->GetPosition();
- _data = Trinity::make_unique<uint8[]>(_sections[0].CatalogDataOffset - _dataStart);
- return source->Read(_data.get(), _sections[0].CatalogDataOffset - _dataStart);
+ _catalogIds.resize(_catalogIds.size() + _sections[section].CatalogDataCount);
+ _catalog.resize(_catalog.size() + _sections[section].CatalogDataCount);
}
bool DB2FileLoaderSparseImpl::LoadCatalogData(DB2FileSource* source, uint32 section)
{
- if (section != 0)
+ source->SetPosition(_sections[section].CatalogDataOffset);
+
+ std::size_t oldSize = _catalog.size();
+ _catalogIds.resize(oldSize + _sections[section].CatalogDataCount);
+ if (!source->Read(&_catalogIds[oldSize], sizeof(uint32) * _sections[section].CatalogDataCount))
+ return false;
+
+ if (_sections[section].CopyTableCount)
+ {
+ std::size_t oldCopyTableSize = _copyTable.size();
+ _copyTable.resize(oldCopyTableSize + _sections[section].CopyTableCount);
+ if (!source->Read(&_copyTable[oldSize], sizeof(DB2RecordCopy) * _sections[section].CopyTableCount))
+ return false;
+ }
+
+ _catalog.resize(oldSize + _sections[section].CatalogDataCount);
+ if (!source->Read(&_catalog[oldSize], sizeof(DB2CatalogEntry) * _sections[section].CatalogDataCount))
return false;
- _catalog = Trinity::make_unique<DB2CatalogEntry[]>(_header->MaxId - _header->MinId + 1);
- return source->Read(_catalog.get(), sizeof(DB2CatalogEntry) * (_header->MaxId - _header->MinId + 1));
+ for (uint32 i = 0; i < _sections[section].CatalogDataCount; ++i)
+ {
+ _totalRecordSize += _catalog[oldSize + i].RecordSize;
+ _maxRecordSize = std::max(_maxRecordSize, _catalog[oldSize + i].RecordSize);
+ }
+
+ return true;
+}
+
+void DB2FileLoaderSparseImpl::SetAdditionalData(std::vector<uint32> /*idTable*/, std::vector<DB2RecordCopy> /*copyTable*/, std::vector<DB2IndexData> parentIndexes)
+{
+ _parentIndexes = std::move(parentIndexes);
+ _recordBuffer = Trinity::make_unique<uint8[]>(_maxRecordSize);
}
char* DB2FileLoaderSparseImpl::AutoProduceData(uint32& maxId, char**& indexTable, std::vector<char*>& stringPool)
@@ -974,18 +1044,7 @@ char* DB2FileLoaderSparseImpl::AutoProduceData(uint32& maxId, char**& indexTable
//get struct size and index pos
uint32 recordsize = _loadInfo->Meta->GetRecordSize();
-
- uint32 offsetCount = _header->MaxId - _header->MinId + 1;
- uint32 records = 0;
- uint32 expandedDataSize = 0;
- for (uint32 i = 0; i < offsetCount; ++i)
- {
- if (_catalog[i].FileOffset && _catalog[i].RecordSize)
- {
- ++records;
- expandedDataSize += _catalog[i].RecordSize;
- }
- }
+ uint32 records = _catalog.size();
using index_entry_t = char*;
@@ -993,7 +1052,7 @@ char* DB2FileLoaderSparseImpl::AutoProduceData(uint32& maxId, char**& indexTable
indexTable = new index_entry_t[maxId];
memset(indexTable, 0, maxId * sizeof(index_entry_t));
- char* dataTable = new char[records * recordsize];
+ char* dataTable = new char[(records + _copyTable.size()) * recordsize];
// we store flat holders pool as single memory block
std::size_t stringFields = _loadInfo->GetStringFieldCount(false);
@@ -1010,91 +1069,153 @@ 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 - (!_loadInfo->Meta->HasIndexFieldInData() ? 4 : 0)) - stringFields * sizeof(char*))];
- memset(stringTable, 0, expandedDataSize - records * ((recordsize - (!_loadInfo->Meta->HasIndexFieldInData() ? 4 : 0)) - stringFields * sizeof(char*)));
+ char* stringTable = new char[_totalRecordSize - records * ((recordsize - (!_loadInfo->Meta->HasIndexFieldInData() ? 4 : 0)) - stringFields * sizeof(char*))];
+ memset(stringTable, 0, _totalRecordSize - records * ((recordsize - (!_loadInfo->Meta->HasIndexFieldInData() ? 4 : 0)) - stringFields * sizeof(char*)));
stringPool.push_back(stringTable);
char* stringPtr = stringTable;
uint32 offset = 0;
uint32 recordNum = 0;
- for (uint32 y = 0; y < offsetCount; ++y)
- {
- unsigned char const* rawRecord = GetRawRecordData(y);
- if (!rawRecord)
- continue;
+ uint32 y = 0;
- uint32 indexVal = RecordGetId(rawRecord, y);
- indexTable[indexVal] = &dataTable[offset];
-
- uint32 fieldIndex = 0;
- if (!_loadInfo->Meta->HasIndexFieldInData())
+ for (uint32 section = 0; section < _header->SectionCount; ++section)
+ {
+ DB2SectionHeader const& sectionHeader = GetSection(section);
+ if (sectionHeader.TactId)
{
- *((uint32*)(&dataTable[offset])) = indexVal;
- offset += 4;
- ++fieldIndex;
+ offset += recordsize * sectionHeader.RecordCount;
+ y += sectionHeader.RecordCount;
+ continue;
}
- uint32 stringFieldOffset = 0;
- for (uint32 x = 0; x < _header->FieldCount; ++x)
+ for (uint32 sr = 0; sr < sectionHeader.CatalogDataCount; ++sr, ++y)
{
- for (uint32 z = 0; z < _loadInfo->Meta->Fields[x].ArraySize; ++z)
+ unsigned char const* rawRecord = GetRawRecordData(y, &section);
+ if (!rawRecord)
+ continue;
+
+ uint32 indexVal = _catalogIds[y];
+ indexTable[indexVal] = &dataTable[offset];
+
+ 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)
{
- switch (_loadInfo->TypesString[fieldIndex])
+ for (uint32 z = 0; z < _loadInfo->Meta->Fields[x].ArraySize; ++z)
{
- case FT_FLOAT:
- *((float*)(&dataTable[offset])) = RecordGetFloat(rawRecord, x, z);
- offset += 4;
- break;
- case FT_INT:
- *((uint32*)(&dataTable[offset])) = RecordGetVarInt(rawRecord, x, z, _loadInfo->Fields[fieldIndex].IsSigned);
- offset += 4;
- break;
- case FT_BYTE:
- *((uint8*)(&dataTable[offset])) = RecordGetUInt8(rawRecord, x, z);
- offset += 1;
- break;
- case FT_SHORT:
- *((uint16*)(&dataTable[offset])) = RecordGetUInt16(rawRecord, x, z);
- offset += 2;
- break;
- case FT_LONG:
- *((uint64*)(&dataTable[offset])) = RecordGetUInt64(rawRecord, x, z);
- offset += 8;
- break;
- case FT_STRING:
+ switch (_loadInfo->TypesString[fieldIndex])
{
- LocalizedString** slot = (LocalizedString**)(&dataTable[offset]);
- *slot = (LocalizedString*)(&stringHoldersPool[stringHoldersRecordPoolSize * recordNum + stringFieldOffset]);
- for (uint32 locale = 0; locale < TOTAL_LOCALES; ++locale)
- if (_header->Locale & (1 << locale))
- (*slot)->Str[locale] = stringPtr;
- strcpy(stringPtr, RecordGetString(rawRecord, x, z));
- stringPtr += strlen(stringPtr) + 1;
- stringFieldOffset += sizeof(LocalizedString);
- offset += sizeof(LocalizedString*);
- break;
+ case FT_FLOAT:
+ *((float*)(&dataTable[offset])) = RecordGetFloat(rawRecord, x, z);
+ offset += 4;
+ break;
+ case FT_INT:
+ *((uint32*)(&dataTable[offset])) = RecordGetVarInt(rawRecord, x, z, _loadInfo->Fields[fieldIndex].IsSigned);
+ offset += 4;
+ break;
+ case FT_BYTE:
+ *((uint8*)(&dataTable[offset])) = RecordGetUInt8(rawRecord, x, z);
+ offset += 1;
+ break;
+ case FT_SHORT:
+ *((uint16*)(&dataTable[offset])) = RecordGetUInt16(rawRecord, x, z);
+ offset += 2;
+ break;
+ case FT_LONG:
+ *((uint64*)(&dataTable[offset])) = RecordGetUInt64(rawRecord, x, z);
+ offset += 8;
+ break;
+ case FT_STRING:
+ {
+ LocalizedString** slot = (LocalizedString * *)(&dataTable[offset]);
+ *slot = (LocalizedString*)(&stringHoldersPool[stringHoldersRecordPoolSize * recordNum + stringFieldOffset]);
+ for (uint32 locale = 0; locale < TOTAL_LOCALES; ++locale)
+ if (_header->Locale & (1 << locale))
+ (*slot)->Str[locale] = stringPtr;
+ strcpy(stringPtr, RecordGetString(rawRecord, x, z));
+ stringPtr += strlen(stringPtr) + 1;
+ stringFieldOffset += sizeof(LocalizedString);
+ offset += sizeof(LocalizedString*);
+ break;
+ }
+ case FT_STRING_NOT_LOCALIZED:
+ {
+ char const*** slot = (char const***)(&dataTable[offset]);
+ *slot = (char const**)(&stringHoldersPool[stringHoldersRecordPoolSize * recordNum + stringFieldOffset]);
+ **slot = stringPtr;
+ strcpy(stringPtr, RecordGetString(rawRecord, x, z));
+ stringPtr += strlen(stringPtr) + 1;
+ stringFieldOffset += sizeof(char*);
+ offset += sizeof(char*);
+ break;
+ }
+ default:
+ ASSERT(false, "Unknown format character '%c' found in %s meta for field %s",
+ _loadInfo->TypesString[fieldIndex], _fileName, _loadInfo->Fields[fieldIndex].Name);
+ break;
}
- case FT_STRING_NOT_LOCALIZED:
+ ++fieldIndex;
+ }
+ }
+
+ for (uint32 x = _header->FieldCount; x < _loadInfo->Meta->FieldCount; ++x)
+ {
+ for (uint32 z = 0; z < _loadInfo->Meta->Fields[x].ArraySize; ++z)
+ {
+ switch (_loadInfo->TypesString[fieldIndex])
{
- char const*** slot = (char const***)(&dataTable[offset]);
- *slot = (char const**)(&stringHoldersPool[stringHoldersRecordPoolSize * recordNum + stringFieldOffset]);
- **slot = stringPtr;
- strcpy(stringPtr, RecordGetString(rawRecord, x, z));
- stringPtr += strlen(stringPtr) + 1;
- stringFieldOffset += sizeof(char*);
- offset += sizeof(char*);
- break;
+ case FT_FLOAT:
+ *((float*)(&dataTable[offset])) = 0;
+ offset += 4;
+ break;
+ case FT_INT:
+ *((uint32*)(&dataTable[offset])) = 0;
+ offset += 4;
+ break;
+ case FT_BYTE:
+ *((uint8*)(&dataTable[offset])) = 0;
+ offset += 1;
+ break;
+ case FT_SHORT:
+ *((uint16*)(&dataTable[offset])) = 0;
+ offset += 2;
+ break;
+ case FT_LONG:
+ *((uint64*)(&dataTable[offset])) = 0;
+ offset += 8;
+ 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 * recordNum + 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 for field %s",
+ _loadInfo->TypesString[fieldIndex], _fileName, _loadInfo->Fields[fieldIndex].Name);
+ break;
}
- default:
- ASSERT(false, "Unknown format character '%c' found in %s meta for field %s",
- _loadInfo->TypesString[fieldIndex], _fileName, _loadInfo->Fields[fieldIndex].Name);
- break;
+ ++fieldIndex;
}
- ++fieldIndex;
}
- }
- ++recordNum;
+ ++recordNum;
+ }
}
return dataTable;
@@ -1122,77 +1243,84 @@ char* DB2FileLoaderSparseImpl::AutoProduceStrings(char** indexTable, uint32 inde
return nullptr;
}
- uint32 offsetCount = _header->MaxId - _header->MinId + 1;
- uint32 records = 0;
- for (uint32 i = 0; i < offsetCount; ++i)
- if (_catalog[i].FileOffset && _catalog[i].RecordSize)
- ++records;
-
+ uint32 records = _catalog.size();
uint32 recordsize = _loadInfo->Meta->GetRecordSize();
std::size_t stringFields = _loadInfo->GetStringFieldCount(true);
- char* stringTable = new char[_sections[0].CatalogDataOffset - _dataStart - records * ((recordsize - (!_loadInfo->Meta->HasIndexFieldInData() ? 4 : 0)) - stringFields * sizeof(char*))];
- memset(stringTable, 0, _sections[0].CatalogDataOffset - _dataStart - records * ((recordsize - (!_loadInfo->Meta->HasIndexFieldInData() ? 4 : 0)) - stringFields * sizeof(char*)));
+ char* stringTable = new char[_totalRecordSize - records * ((recordsize - (!_loadInfo->Meta->HasIndexFieldInData() ? 4 : 0)) - stringFields * sizeof(char*))];
+ memset(stringTable, 0, _totalRecordSize - records * ((recordsize - (!_loadInfo->Meta->HasIndexFieldInData() ? 4 : 0)) - stringFields * sizeof(char*)));
char* stringPtr = stringTable;
- for (uint32 y = 0; y < offsetCount; y++)
+ uint32 y = 0;
+
+ for (uint32 section = 0; section < _header->SectionCount; ++section)
{
- unsigned char const* rawRecord = GetRawRecordData(y);
- if (!rawRecord)
+ DB2SectionHeader const& sectionHeader = GetSection(section);
+ if (sectionHeader.TactId)
+ {
+ y += sectionHeader.RecordCount;
continue;
+ }
- uint32 indexVal = RecordGetId(rawRecord, y);
- if (indexVal >= indexTableSize)
- continue;
+ for (uint32 sr = 0; sr < sectionHeader.CatalogDataCount; ++sr, ++y)
+ {
+ unsigned char const* rawRecord = GetRawRecordData(y, &section);
+ if (!rawRecord)
+ continue;
- char* recordData = indexTable[indexVal];
+ uint32 indexVal = _catalogIds[y];
+ if (indexVal >= indexTableSize)
+ continue;
- uint32 offset = 0;
- uint32 fieldIndex = 0;
- if (!_loadInfo->Meta->HasIndexFieldInData())
- {
- offset += 4;
- ++fieldIndex;
- }
+ char* recordData = indexTable[indexVal];
- for (uint32 x = 0; x < _header->FieldCount; ++x)
- {
- for (uint32 z = 0; z < _loadInfo->Meta->Fields[x].ArraySize; ++z)
+ uint32 offset = 0;
+ uint32 fieldIndex = 0;
+ if (!_loadInfo->Meta->HasIndexFieldInData())
{
- switch (_loadInfo->TypesString[fieldIndex])
+ offset += 4;
+ ++fieldIndex;
+ }
+
+ for (uint32 x = 0; x < _header->FieldCount; ++x)
+ {
+ for (uint32 z = 0; z < _loadInfo->Meta->Fields[x].ArraySize; ++z)
{
- case FT_FLOAT:
- offset += 4;
- break;
- case FT_INT:
- offset += 4;
- break;
- case FT_BYTE:
- offset += 1;
- break;
- case FT_SHORT:
- offset += 2;
- break;
- case FT_LONG:
- offset += 8;
- break;
- case FT_STRING:
+ switch (_loadInfo->TypesString[fieldIndex])
{
- LocalizedString* db2str = *(LocalizedString**)(&recordData[offset]);
- db2str->Str[locale] = stringPtr;
- strcpy(stringPtr, RecordGetString(rawRecord, x, z));
- stringPtr += strlen(stringPtr) + 1;
- offset += sizeof(char*);
- break;
+ case FT_FLOAT:
+ offset += 4;
+ break;
+ case FT_INT:
+ offset += 4;
+ break;
+ case FT_BYTE:
+ offset += 1;
+ break;
+ case FT_SHORT:
+ offset += 2;
+ break;
+ case FT_LONG:
+ offset += 8;
+ break;
+ case FT_STRING:
+ {
+ LocalizedString* db2str = *(LocalizedString * *)(&recordData[offset]);
+ db2str->Str[locale] = stringPtr;
+ strcpy(stringPtr, RecordGetString(rawRecord, x, z));
+ stringPtr += strlen(stringPtr) + 1;
+ offset += sizeof(char*);
+ break;
+ }
+ case FT_STRING_NOT_LOCALIZED:
+ offset += sizeof(char*);
+ break;
+ default:
+ ASSERT(false, "Unknown format character '%c' found in %s meta for field %s",
+ _loadInfo->TypesString[fieldIndex], _fileName, _loadInfo->Fields[fieldIndex].Name);
+ break;
}
- case FT_STRING_NOT_LOCALIZED:
- offset += sizeof(char*);
- break;
- default:
- ASSERT(false, "Unknown format character '%c' found in %s meta for field %s",
- _loadInfo->TypesString[fieldIndex], _fileName, _loadInfo->Fields[fieldIndex].Name);
- break;
+ ++fieldIndex;
}
- ++fieldIndex;
}
}
}
@@ -1200,32 +1328,102 @@ char* DB2FileLoaderSparseImpl::AutoProduceStrings(char** indexTable, uint32 inde
return stringTable;
}
+void DB2FileLoaderSparseImpl::AutoProduceRecordCopies(uint32 records, char** indexTable, char* dataTable)
+{
+ uint32 recordsize = _loadInfo->Meta->GetRecordSize();
+ uint32 offset = _header->RecordCount * recordsize;
+ uint32 idFieldOffset = _loadInfo->Meta->HasIndexFieldInData() ? _loadInfo->Meta->GetIndexFieldOffset() : 0;
+ for (uint32 c = 0; c < GetRecordCopyCount(); ++c)
+ {
+ DB2RecordCopy copy = GetRecordCopy(c);
+ if (copy.SourceRowId && copy.SourceRowId < records && copy.NewRowId < records && indexTable[copy.SourceRowId])
+ {
+ indexTable[copy.NewRowId] = &dataTable[offset];
+ memcpy(indexTable[copy.NewRowId], indexTable[copy.SourceRowId], recordsize);
+ *((uint32*)(&dataTable[offset + idFieldOffset])) = copy.NewRowId;
+ offset += recordsize;
+ }
+ }
+}
+
DB2Record DB2FileLoaderSparseImpl::GetRecord(uint32 recordNumber) const
{
return DB2Record(*this, recordNumber, _fieldAndArrayOffsets.get());
}
-DB2RecordCopy DB2FileLoaderSparseImpl::GetRecordCopy(uint32 /*recordId*/) const
+DB2RecordCopy DB2FileLoaderSparseImpl::GetRecordCopy(uint32 copyNumber) const
{
- return DB2RecordCopy{};
+ if (copyNumber >= GetRecordCopyCount())
+ return DB2RecordCopy{};
+
+ return _copyTable[copyNumber];
}
uint32 DB2FileLoaderSparseImpl::GetRecordCount() const
{
- return _header->MaxId - _header->MinId + 1;
+ return _catalog.size();
}
uint32 DB2FileLoaderSparseImpl::GetRecordCopyCount() const
{
- return 0;
+ return _copyTable.size();
+}
+
+void DB2FileLoaderSparseImpl::FillParentLookup(char* dataTable)
+{
+ int32 parentIdOffset = _loadInfo->Meta->GetParentIndexFieldOffset();
+ uint32 recordSize = _loadInfo->Meta->GetRecordSize();
+ for (std::size_t i = 0; i < _parentIndexes[0].Entries.size(); ++i)
+ {
+ uint32 parentId = _parentIndexes[0].Entries[i].ParentId;
+ char* recordData = &dataTable[_parentIndexes[0].Entries[i].RecordIndex * recordSize];
+
+ switch (_loadInfo->Meta->Fields[_loadInfo->Meta->ParentIndexField].Type)
+ {
+ case FT_SHORT:
+ *reinterpret_cast<uint16*>(&recordData[parentIdOffset]) = uint16(parentId);
+ break;
+ case FT_BYTE:
+ *reinterpret_cast<uint8*>(&recordData[parentIdOffset]) = uint8(parentId);
+ break;
+ case FT_INT:
+ *reinterpret_cast<uint32*>(&recordData[parentIdOffset]) = parentId;
+ break;
+ default:
+ ASSERT(false, "Unhandled parent id type '%c' found in %s", _loadInfo->Meta->Fields[_loadInfo->Meta->ParentIndexField].Type, _fileName);
+ break;
+ }
+ }
+}
+
+uint32 DB2FileLoaderSparseImpl::GetRecordSection(uint32 recordNumber) const
+{
+ uint32 section = 0;
+ for (; section < _header->SectionCount; ++section)
+ {
+ DB2SectionHeader const& sectionHeader = GetSection(section);
+ if (recordNumber < sectionHeader.CatalogDataCount)
+ break;
+
+ recordNumber -= sectionHeader.CatalogDataCount;
+ }
+
+ return section;
}
-uint8 const* DB2FileLoaderSparseImpl::GetRawRecordData(uint32 recordNumber) const
+unsigned char const* DB2FileLoaderSparseImpl::GetRawRecordData(uint32 recordNumber, uint32 const* section) const
{
- if (recordNumber > (_header->MaxId - _header->MinId) || !_catalog[recordNumber].FileOffset || !_catalog[recordNumber].RecordSize)
+ if (recordNumber >= _catalog.size())
+ return nullptr;
+
+ if (GetSection(section ? *section : GetRecordSection(recordNumber)).TactId)
+ return nullptr;
+
+ _source->SetPosition(_catalog[recordNumber].FileOffset);
+ uint8* rawRecord = _recordBuffer.get();
+ if (!_source->Read(rawRecord, _catalog[recordNumber].RecordSize))
return nullptr;
- uint8 const* rawRecord = &_data[_catalog[recordNumber].FileOffset - _dataStart];
CalculateAndStoreFieldOffsets(rawRecord);
return rawRecord;
}
@@ -1235,7 +1433,7 @@ uint32 DB2FileLoaderSparseImpl::RecordGetId(uint8 const* record, uint32 recordIn
if (_loadInfo->Meta->HasIndexFieldInData())
return RecordGetVarInt(record, _loadInfo->Meta->GetIndexField(), 0, false);
- return _header->MinId + recordIndex;
+ return _catalogIds[recordIndex];
}
uint8 DB2FileLoaderSparseImpl::RecordGetUInt8(uint8 const* record, uint32 field, uint32 arrayIndex) const
@@ -1383,7 +1581,7 @@ bool DB2FileLoaderSparseImpl::IsSignedField(uint32 field) const
}
DB2Record::DB2Record(DB2FileLoaderImpl const& db2, uint32 recordIndex, std::size_t* fieldOffsets)
- : _db2(db2), _recordIndex(recordIndex), _recordData(db2.GetRawRecordData(recordIndex)), _fieldOffsets(fieldOffsets)
+ : _db2(db2), _recordIndex(recordIndex), _recordData(db2.GetRawRecordData(recordIndex, nullptr)), _fieldOffsets(fieldOffsets)
{
}
@@ -1500,7 +1698,7 @@ DB2FileLoader::~DB2FileLoader()
delete _impl;
}
-bool DB2FileLoader::Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo)
+bool DB2FileLoader::LoadHeaders(DB2FileSource* source, DB2FileLoadInfo const* loadInfo)
{
if (!source->IsOpen())
return false;
@@ -1528,19 +1726,19 @@ bool DB2FileLoader::Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo)
EndianConvert(_header.PalletDataSize);
EndianConvert(_header.SectionCount);
- if (_header.Signature != 0x32434457) //'WDC2'
+ if (_header.Signature != 0x33434457) //'WDC3'
return false;
- if (_header.LayoutHash != loadInfo->Meta->LayoutHash)
+ if (loadInfo && _header.LayoutHash != loadInfo->Meta->LayoutHash)
return false;
if (_header.ParentLookupCount > 1)
return false;
- if (_header.TotalFieldCount + (loadInfo->Meta->ParentIndexField >= int32(_header.TotalFieldCount) ? 1 : 0) != loadInfo->Meta->FieldCount)
+ if (loadInfo && (_header.TotalFieldCount + (loadInfo->Meta->ParentIndexField >= int32(_header.TotalFieldCount) ? 1 : 0) != loadInfo->Meta->FieldCount))
return false;
- if (_header.ParentLookupCount && loadInfo->Meta->ParentIndexField == -1)
+ if (loadInfo && (_header.ParentLookupCount && loadInfo->Meta->ParentIndexField == -1))
return false;
std::unique_ptr<DB2SectionHeader[]> sections = Trinity::make_unique<DB2SectionHeader[]>(_header.SectionCount);
@@ -1551,11 +1749,11 @@ bool DB2FileLoader::Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo)
uint32 totalParentLookupDataSize = 0;
for (uint32 i = 0; i < _header.SectionCount; ++i)
{
- totalCopyTableSize += sections[i].CopyTableSize;
+ totalCopyTableSize += sections[i].CopyTableCount * sizeof(DB2RecordCopy);
totalParentLookupDataSize += sections[i].ParentLookupDataSize;
}
- if (!(_header.Flags & 0x1))
+ if (loadInfo && !(_header.Flags & 0x1))
{
std::size_t expectedFileSize =
sizeof(DB2Header) +
@@ -1588,10 +1786,13 @@ bool DB2FileLoader::Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo)
if (!source->Read(columnMeta.get(), _header.ColumnMetaSize))
return false;
- ASSERT(!loadInfo->Meta->HasIndexFieldInData() ||
- columnMeta[loadInfo->Meta->IndexField].CompressionType == DB2ColumnCompression::None ||
- columnMeta[loadInfo->Meta->IndexField].CompressionType == DB2ColumnCompression::Immediate ||
- columnMeta[loadInfo->Meta->IndexField].CompressionType == DB2ColumnCompression::SignedImmediate);
+ if (loadInfo)
+ {
+ ASSERT(!loadInfo->Meta->HasIndexFieldInData() ||
+ columnMeta[loadInfo->Meta->IndexField].CompressionType == DB2ColumnCompression::None ||
+ columnMeta[loadInfo->Meta->IndexField].CompressionType == DB2ColumnCompression::Immediate ||
+ columnMeta[loadInfo->Meta->IndexField].CompressionType == DB2ColumnCompression::SignedImmediate);
+ }
palletValues = Trinity::make_unique<std::unique_ptr<DB2PalletValue[]>[]>(_header.TotalFieldCount);
for (uint32 i = 0; i < _header.TotalFieldCount; ++i)
@@ -1643,20 +1844,34 @@ bool DB2FileLoader::Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo)
if (!(_header.Flags & 0x1))
_impl = new DB2FileLoaderRegularImpl(source->GetFileName(), loadInfo, &_header);
else
- _impl = new DB2FileLoaderSparseImpl(source->GetFileName(), loadInfo, &_header);
+ _impl = new DB2FileLoaderSparseImpl(source->GetFileName(), loadInfo, &_header, source);
_impl->LoadColumnData(std::move(sections), std::move(fieldData), std::move(columnMeta), std::move(palletValues), std::move(palletArrayValues), std::move(commonValues));
+ return true;
+}
+
+bool DB2FileLoader::Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo)
+{
+ if (!LoadHeaders(source, loadInfo))
+ return false;
std::vector<uint32> idTable;
std::vector<DB2RecordCopy> copyTable;
std::vector<DB2IndexData> parentIndexes;
- if (!loadInfo->Meta->HasIndexFieldInData() && _header.RecordCount)
+ if (loadInfo && !loadInfo->Meta->HasIndexFieldInData() && _header.RecordCount)
idTable.reserve(_header.RecordCount);
for (uint32 i = 0; i < _header.SectionCount; ++i)
{
DB2SectionHeader const& section = _impl->GetSection(i);
+ if (section.TactId)
+ {
+ _impl->SkipEncryptedSection(i);
+ idTable.resize(idTable.size() + section.IdTableSize / sizeof(uint32));
+ continue;
+ }
+
if (!source->SetPosition(section.FileOffset))
return false;
@@ -1666,22 +1881,25 @@ bool DB2FileLoader::Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo)
if (!_impl->LoadCatalogData(source, i))
return false;
- ASSERT(!loadInfo->Meta->HasIndexFieldInData() || section.IdTableSize == 0);
- ASSERT(loadInfo->Meta->HasIndexFieldInData() || section.IdTableSize == 4 * section.RecordCount);
+ if (loadInfo)
+ {
+ ASSERT(!loadInfo->Meta->HasIndexFieldInData() || section.IdTableSize == 0);
+ ASSERT(loadInfo->Meta->HasIndexFieldInData() || section.IdTableSize == 4 * section.RecordCount);
+ }
- if (!loadInfo->Meta->HasIndexFieldInData() && section.IdTableSize)
+ if (section.IdTableSize)
{
std::size_t idTableSize = idTable.size();
- idTable.resize(idTableSize + section.IdTableSize);
+ idTable.resize(idTableSize + section.IdTableSize / sizeof(uint32));
if (!source->Read(&idTable[idTableSize], section.IdTableSize))
return false;
}
- if (section.CopyTableSize)
+ if (!(_header.Flags & 0x1) && section.CopyTableCount)
{
std::size_t copyTableSize = copyTable.size();
- copyTable.resize(copyTableSize + section.CopyTableSize / sizeof(DB2RecordCopy));
- if (!source->Read(&copyTable[copyTableSize], section.CopyTableSize))
+ copyTable.resize(copyTableSize + section.CopyTableCount);
+ if (!source->Read(&copyTable[copyTableSize], section.CopyTableCount * sizeof(DB2RecordCopy)))
return false;
}
@@ -1690,14 +1908,16 @@ bool DB2FileLoader::Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo)
parentIndexes.resize(_header.ParentLookupCount);
for (uint32 i = 0; i < _header.ParentLookupCount; ++i)
{
- if (!source->Read(&parentIndexes[i].Info, sizeof(DB2IndexDataInfo)))
+ DB2IndexDataInfo indexInfo;
+ if (!source->Read(&indexInfo, sizeof(DB2IndexDataInfo)))
return false;
- if (!parentIndexes[i].Info.NumEntries)
+ if (!indexInfo.NumEntries)
continue;
- parentIndexes[i].Entries = Trinity::make_unique<DB2IndexEntry[]>(parentIndexes[i].Info.NumEntries);
- if (!source->Read(parentIndexes[i].Entries.get(), sizeof(DB2IndexEntry) * parentIndexes[i].Info.NumEntries))
+ std::size_t oldSize = parentIndexes[i].Entries.size();
+ parentIndexes[i].Entries.resize(oldSize + indexInfo.NumEntries);
+ if (!source->Read(&parentIndexes[i].Entries[oldSize], sizeof(DB2IndexEntry) * indexInfo.NumEntries))
return false;
}
}
@@ -1705,16 +1925,19 @@ bool DB2FileLoader::Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo)
_impl->SetAdditionalData(std::move(idTable), std::move(copyTable), std::move(parentIndexes));
- uint32 fieldIndex = 0;
- if (!loadInfo->Meta->HasIndexFieldInData())
+ if (loadInfo)
{
- ASSERT(!loadInfo->Fields[0].IsSigned, "ID must be unsigned");
- ++fieldIndex;
- }
- for (uint32 f = 0; f < loadInfo->Meta->FieldCount; ++f)
- {
- ASSERT(loadInfo->Fields[fieldIndex].IsSigned == _impl->IsSignedField(f), "Mismatched field signedness for field %u (%s)", f, loadInfo->Fields[fieldIndex].Name);
- fieldIndex += loadInfo->Meta->Fields[f].ArraySize;
+ uint32 fieldIndex = 0;
+ if (!loadInfo->Meta->HasIndexFieldInData())
+ {
+ ASSERT(!loadInfo->Fields[0].IsSigned, "ID must be unsigned");
+ ++fieldIndex;
+ }
+ for (uint32 f = 0; f < loadInfo->Meta->FieldCount; ++f)
+ {
+ ASSERT(loadInfo->Fields[fieldIndex].IsSigned == _impl->IsSignedField(f), "Mismatched field signedness for field %u (%s)", f, loadInfo->Fields[fieldIndex].Name);
+ fieldIndex += loadInfo->Meta->Fields[f].ArraySize;
+ }
}
return true;
@@ -1750,6 +1973,11 @@ uint32 DB2FileLoader::GetMaxId() const
return _impl->GetMaxId();
}
+DB2SectionHeader const& DB2FileLoader::GetSectionHeader(uint32 section) const
+{
+ return _impl->GetSection(section);
+}
+
DB2Record DB2FileLoader::GetRecord(uint32 recordNumber) const
{
return _impl->GetRecord(recordNumber);