diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/Common.h | 2 | ||||
-rw-r--r-- | src/common/DataStores/DB2FileLoader.cpp | 91 | ||||
-rw-r--r-- | src/common/DataStores/DB2FileLoader.h | 16 |
3 files changed, 65 insertions, 44 deletions
diff --git a/src/common/Common.h b/src/common/Common.h index f35773e7c70..0a3ab68d39f 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -103,7 +103,7 @@ TC_COMMON_API LocaleConstant GetLocaleByName(std::string const& name); constexpr inline bool IsValidLocale(LocaleConstant locale) { - return locale < TOTAL_LOCALES&& locale != LOCALE_none; + return locale < TOTAL_LOCALES && locale != LOCALE_none; } #pragma pack(push, 1) diff --git a/src/common/DataStores/DB2FileLoader.cpp b/src/common/DataStores/DB2FileLoader.cpp index 529e924e6aa..b45a425617e 100644 --- a/src/common/DataStores/DB2FileLoader.cpp +++ b/src/common/DataStores/DB2FileLoader.cpp @@ -21,6 +21,7 @@ #include "Errors.h" #include "Log.h" #include <sstream> +#include <system_error> enum class DB2ColumnCompression : uint32 { @@ -1027,7 +1028,7 @@ void DB2FileLoaderSparseImpl::SetAdditionalData(std::vector<uint32> /*idTable*/, char* DB2FileLoaderSparseImpl::AutoProduceData(uint32& indexTableSize, char**& indexTable) { if (_loadInfo->Meta->FieldCount != _header->FieldCount) - return nullptr; + throw DB2FileLoadException(Trinity::StringFormat("Found unsupported parent index in sparse db2 %s", _fileName)); //get struct size and index pos uint32 recordsize = _loadInfo->Meta->GetRecordSize(); @@ -1155,7 +1156,7 @@ char* DB2FileLoaderSparseImpl::AutoProduceData(uint32& indexTableSize, char**& i char* DB2FileLoaderSparseImpl::AutoProduceStrings(char** indexTable, uint32 indexTableSize, uint32 locale) { if (_loadInfo->Meta->FieldCount != _header->FieldCount) - return nullptr; + throw DB2FileLoadException(Trinity::StringFormat("Found unsupported parent index in sparse db2 %s", _fileName)); if (!(_header->Locale & (1 << locale))) { @@ -1672,7 +1673,7 @@ void DB2Record::MakePersistent() _fieldOffsets = _db2.RecordCreateDetachedFieldOffsets(_fieldOffsets); } -DB2FileLoader::DB2FileLoader() : _impl(nullptr) +DB2FileLoader::DB2FileLoader() : _impl(nullptr), _header() { } @@ -1681,13 +1682,13 @@ DB2FileLoader::~DB2FileLoader() delete _impl; } -bool DB2FileLoader::LoadHeaders(DB2FileSource* source, DB2FileLoadInfo const* loadInfo) +void DB2FileLoader::LoadHeaders(DB2FileSource* source, DB2FileLoadInfo const* loadInfo) { if (!source->IsOpen()) - return false; + throw std::system_error(std::make_error_code(std::errc::no_such_file_or_directory)); if (!source->Read(&_header, sizeof(DB2Header))) - return false; + throw DB2FileLoadException("Failed to read header"); EndianConvert(_header.Signature); EndianConvert(_header.RecordCount); @@ -1710,23 +1711,27 @@ bool DB2FileLoader::LoadHeaders(DB2FileSource* source, DB2FileLoadInfo const* lo EndianConvert(_header.SectionCount); if (_header.Signature != 0x33434457) //'WDC3' - return false; + throw DB2FileLoadException(Trinity::StringFormat("Incorrect file signature in %s, expected 'WDC3', got %c%c%c%c", source->GetFileName(), + char(_header.Signature & 0xFF), char((_header.Signature >> 8) & 0xFF), char((_header.Signature >> 16) & 0xFF), char((_header.Signature >> 24) & 0xFF))); if (loadInfo && _header.LayoutHash != loadInfo->Meta->LayoutHash) - return false; + throw DB2FileLoadException(Trinity::StringFormat("Incorrect layout hash in %s, expected 0x%08X, got 0x%08X (possibly wrong client version)", + source->GetFileName(), loadInfo->Meta->LayoutHash, _header.LayoutHash)); if (_header.ParentLookupCount > 1) - return false; + throw DB2FileLoadException(Trinity::StringFormat("Too many parent lookups in %s, only one is allowed, got %u", + source->GetFileName(), _header.ParentLookupCount)); if (loadInfo && (_header.TotalFieldCount + (loadInfo->Meta->ParentIndexField >= int32(_header.TotalFieldCount) ? 1 : 0) != loadInfo->Meta->FieldCount)) - return false; + throw DB2FileLoadException(Trinity::StringFormat("Incorrect number of fields in %s, expected %u, got %u", + source->GetFileName(), loadInfo->Meta->FieldCount, _header.TotalFieldCount + (loadInfo->Meta->ParentIndexField >= int32(_header.TotalFieldCount) ? 1 : 0))); if (loadInfo && (_header.ParentLookupCount && loadInfo->Meta->ParentIndexField == -1)) - return false; + throw DB2FileLoadException(Trinity::StringFormat("Unexpected parent lookup found in %s", source->GetFileName())); std::unique_ptr<DB2SectionHeader[]> sections = std::make_unique<DB2SectionHeader[]>(_header.SectionCount); if (_header.SectionCount && !source->Read(sections.get(), sizeof(DB2SectionHeader) * _header.SectionCount)) - return false; + throw DB2FileLoadException(Trinity::StringFormat("Unable to read section headers from %s", source->GetFileName())); uint32 totalCopyTableSize = 0; uint32 totalParentLookupDataSize = 0; @@ -1742,9 +1747,9 @@ bool DB2FileLoader::LoadHeaders(DB2FileSource* source, DB2FileLoadInfo const* lo sizeof(DB2Header) + sizeof(DB2SectionHeader) * _header.SectionCount + sizeof(DB2FieldEntry) * _header.FieldCount + - _header.RecordCount * _header.RecordSize + + int64(_header.RecordSize) * _header.RecordCount + _header.StringTableSize + - (loadInfo->Meta->IndexField == -1 ? _header.RecordCount * sizeof(uint32) : 0) + + (loadInfo->Meta->IndexField == -1 ? sizeof(uint32) * _header.RecordCount : 0) + totalCopyTableSize + _header.ColumnMetaSize + _header.PalletDataSize + @@ -1752,12 +1757,12 @@ bool DB2FileLoader::LoadHeaders(DB2FileSource* source, DB2FileLoadInfo const* lo totalParentLookupDataSize; if (source->GetFileSize() != expectedFileSize) - return false; + throw DB2FileLoadException(Trinity::StringFormat("%s failed size consistency check, expected " SZFMTD ", got " SZFMTD, expectedFileSize, source->GetFileSize())); } std::unique_ptr<DB2FieldEntry[]> fieldData = std::make_unique<DB2FieldEntry[]>(_header.FieldCount); if (!source->Read(fieldData.get(), sizeof(DB2FieldEntry) * _header.FieldCount)) - return false; + throw DB2FileLoadException(Trinity::StringFormat("Unable to read field information from %s", source->GetFileName())); std::unique_ptr<DB2ColumnMeta[]> columnMeta; std::unique_ptr<std::unique_ptr<DB2PalletValue[]>[]> palletValues; @@ -1767,14 +1772,15 @@ bool DB2FileLoader::LoadHeaders(DB2FileSource* source, DB2FileLoadInfo const* lo { columnMeta = std::make_unique<DB2ColumnMeta[]>(_header.TotalFieldCount); if (!source->Read(columnMeta.get(), _header.ColumnMetaSize)) - return false; + throw DB2FileLoadException(Trinity::StringFormat("Unable to read field metadata from %s", source->GetFileName())); - if (loadInfo) + if (loadInfo && loadInfo->Meta->HasIndexFieldInData()) { - 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 (columnMeta[loadInfo->Meta->IndexField].CompressionType != DB2ColumnCompression::None + && columnMeta[loadInfo->Meta->IndexField].CompressionType != DB2ColumnCompression::Immediate + && columnMeta[loadInfo->Meta->IndexField].CompressionType != DB2ColumnCompression::SignedImmediate) + throw DB2FileLoadException(Trinity::StringFormat("Invalid compression type for index field in %s, expected one of None (0), Immediate (1), SignedImmediate (5), got %u", + source->GetFileName(), uint32(columnMeta[loadInfo->Meta->IndexField].CompressionType))); } palletValues = std::make_unique<std::unique_ptr<DB2PalletValue[]>[]>(_header.TotalFieldCount); @@ -1785,7 +1791,7 @@ bool DB2FileLoader::LoadHeaders(DB2FileSource* source, DB2FileLoadInfo const* lo palletValues[i] = std::make_unique<DB2PalletValue[]>(columnMeta[i].AdditionalDataSize / sizeof(DB2PalletValue)); if (!source->Read(palletValues[i].get(), columnMeta[i].AdditionalDataSize)) - return false; + throw DB2FileLoadException(Trinity::StringFormat("Unable to read field pallet values from %s for field %u", source->GetFileName(), i)); } palletArrayValues = std::make_unique<std::unique_ptr<DB2PalletValue[]>[]>(_header.TotalFieldCount); @@ -1796,7 +1802,7 @@ bool DB2FileLoader::LoadHeaders(DB2FileSource* source, DB2FileLoadInfo const* lo palletArrayValues[i] = std::make_unique<DB2PalletValue[]>(columnMeta[i].AdditionalDataSize / sizeof(DB2PalletValue)); if (!source->Read(palletArrayValues[i].get(), columnMeta[i].AdditionalDataSize)) - return false; + throw DB2FileLoadException(Trinity::StringFormat("Unable to read field pallet array values from %s for field %u", source->GetFileName(), i)); } std::unique_ptr<std::unique_ptr<DB2CommonValue[]>[]> commonData = std::make_unique<std::unique_ptr<DB2CommonValue[]>[]>(_header.TotalFieldCount); @@ -1811,7 +1817,7 @@ bool DB2FileLoader::LoadHeaders(DB2FileSource* source, DB2FileLoadInfo const* lo commonData[i] = std::make_unique<DB2CommonValue[]>(columnMeta[i].AdditionalDataSize / sizeof(DB2CommonValue)); if (!source->Read(commonData[i].get(), columnMeta[i].AdditionalDataSize)) - return false; + throw DB2FileLoadException(Trinity::StringFormat("Unable to read field common values from %s for field %u", source->GetFileName(), i)); uint32 numExtraValuesForField = columnMeta[i].AdditionalDataSize / sizeof(DB2CommonValue); for (uint32 record = 0; record < numExtraValuesForField; ++record) @@ -1830,13 +1836,11 @@ bool DB2FileLoader::LoadHeaders(DB2FileSource* source, DB2FileLoadInfo const* lo _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) +void DB2FileLoader::Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo) { - if (!LoadHeaders(source, loadInfo)) - return false; + LoadHeaders(source, loadInfo); std::vector<uint32> idTable; std::vector<DB2RecordCopy> copyTable; @@ -1872,18 +1876,24 @@ bool DB2FileLoader::Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo) } if (!source->SetPosition(section.FileOffset)) - return false; + throw DB2FileLoadException(Trinity::StringFormat("Unable to change %s read position for section %u", source->GetFileName(), i)); if (!_impl->LoadTableData(source, i)) - return false; + throw DB2FileLoadException(Trinity::StringFormat("Unable to read section table data from %s for section %u", source->GetFileName(), i)); if (!_impl->LoadCatalogData(source, i)) - return false; + throw DB2FileLoadException(Trinity::StringFormat("Unable to read section catalog data from %s for section %u", source->GetFileName(), i)); if (loadInfo) { - ASSERT(!loadInfo->Meta->HasIndexFieldInData() || section.IdTableSize == 0); - ASSERT(loadInfo->Meta->HasIndexFieldInData() || section.IdTableSize == 4 * section.RecordCount); + if (loadInfo->Meta->HasIndexFieldInData()) + { + if (section.IdTableSize != 0) + throw DB2FileLoadException(Trinity::StringFormat("Unexpected id table found in %s for section %u", source->GetFileName(), i)); + } + else if (section.IdTableSize != 4 * section.RecordCount) + throw DB2FileLoadException(Trinity::StringFormat("Unexpected id table size in %s for section %u, expected %u, got %u", + source->GetFileName(), i, 4 * section.RecordCount, section.IdTableSize)); } if (section.IdTableSize) @@ -1891,7 +1901,7 @@ bool DB2FileLoader::Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo) std::size_t idTableSize = idTable.size(); idTable.resize(idTableSize + section.IdTableSize / sizeof(uint32)); if (!source->Read(&idTable[idTableSize], section.IdTableSize)) - return false; + throw DB2FileLoadException(Trinity::StringFormat("Unable to read non-inline record ids from %s for section %u", source->GetFileName(), i)); } if (!(_header.Flags & 0x1) && section.CopyTableCount) @@ -1899,7 +1909,7 @@ bool DB2FileLoader::Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo) std::size_t copyTableSize = copyTable.size(); copyTable.resize(copyTableSize + section.CopyTableCount); if (!source->Read(©Table[copyTableSize], section.CopyTableCount * sizeof(DB2RecordCopy))) - return false; + throw DB2FileLoadException(Trinity::StringFormat("Unable to read record copies from %s for section %u", source->GetFileName(), i)); } if (_header.ParentLookupCount) @@ -1909,14 +1919,14 @@ bool DB2FileLoader::Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo) { DB2IndexDataInfo indexInfo; if (!source->Read(&indexInfo, sizeof(DB2IndexDataInfo))) - return false; + throw DB2FileLoadException(Trinity::StringFormat("Unable to read parent lookup info from %s for section %u", source->GetFileName(), i)); if (!indexInfo.NumEntries) continue; parentIndexesForSection[j].Entries.resize(indexInfo.NumEntries); if (!source->Read(parentIndexesForSection[j].Entries.data(), sizeof(DB2IndexEntry) * indexInfo.NumEntries)) - return false; + throw DB2FileLoadException(Trinity::StringFormat("Unable to read parent lookup content from %s for section %u", source->GetFileName(), i)); } } } @@ -1933,12 +1943,11 @@ bool DB2FileLoader::Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo) } for (uint32 f = 0; f < loadInfo->Meta->FieldCount; ++f) { - ASSERT(loadInfo->Fields[fieldIndex].IsSigned == _impl->IsSignedField(f), "Mismatched field signedness for field %u (%s) in %s", f, loadInfo->Fields[fieldIndex].Name, source->GetFileName()); + ASSERT(loadInfo->Fields[fieldIndex].IsSigned == _impl->IsSignedField(f), + "Field %s in %s must be %s", loadInfo->Fields[fieldIndex].Name, source->GetFileName(), _impl->IsSignedField(f) ? "signed" : "unsigned"); fieldIndex += loadInfo->Meta->Fields[f].ArraySize; } } - - return true; } char* DB2FileLoader::AutoProduceData(uint32& indexTableSize, char**& indexTable) diff --git a/src/common/DataStores/DB2FileLoader.h b/src/common/DataStores/DB2FileLoader.h index 6f0bca5ee5b..72a5f66768d 100644 --- a/src/common/DataStores/DB2FileLoader.h +++ b/src/common/DataStores/DB2FileLoader.h @@ -19,6 +19,7 @@ #define DB2_FILE_LOADER_H #include "Common.h" +#include <exception> #include <string> #include <vector> @@ -163,6 +164,17 @@ struct DB2RecordCopy }; #pragma pack(pop) +class TC_COMMON_API DB2FileLoadException : public std::exception +{ +public: + DB2FileLoadException(std::string msg) : _msg(std::move(msg)) { } + + char const* what() const noexcept override { return _msg.c_str(); } + +private: + std::string _msg; +}; + class TC_COMMON_API DB2FileLoader { public: @@ -170,8 +182,8 @@ public: ~DB2FileLoader(); // loadInfo argument is required when trying to read data from the file - bool LoadHeaders(DB2FileSource* source, DB2FileLoadInfo const* loadInfo); - bool Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo); + void LoadHeaders(DB2FileSource* source, DB2FileLoadInfo const* loadInfo); + void Load(DB2FileSource* source, DB2FileLoadInfo const* loadInfo); char* AutoProduceData(uint32& indexTableSize, char**& indexTable); char* AutoProduceStrings(char** indexTable, uint32 indexTableSize, LocaleConstant locale); void AutoProduceRecordCopies(uint32 records, char** indexTable, char* dataTable); |