aboutsummaryrefslogtreecommitdiff
path: root/src/common/DataStores/DB2FileLoader.h
blob: 70b6afc2081be4e74ad27eb60fdf2ef43c7cc2e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/*
 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef DB2_FILE_LOADER_H
#define DB2_FILE_LOADER_H

#include "Define.h"
#include <string>
#include <vector>

class DB2FileLoaderImpl;
struct DB2FieldMeta;
struct DB2Meta;

#pragma pack(push, 1)

struct DB2Header
{
    uint32 Signature;
    uint32 RecordCount;
    uint32 FieldCount;
    uint32 RecordSize;
    uint32 StringTableSize;
    uint32 TableHash;
    uint32 LayoutHash;
    uint32 MinId;
    uint32 MaxId;
    uint32 Locale;
    uint16 Flags;
    int16 IndexField;
    uint32 TotalFieldCount;
    uint32 PackedDataOffset;
    uint32 ParentLookupCount;
    uint32 ColumnMetaSize;
    uint32 CommonDataSize;
    uint32 PalletDataSize;
    uint32 SectionCount;
};

struct DB2SectionHeader
{
    uint64 TactId;
    uint32 FileOffset;
    uint32 RecordCount;
    uint32 StringTableSize;
    uint32 CatalogDataOffset;
    uint32 IdTableSize;
    uint32 ParentLookupDataSize;
    uint32 CatalogDataCount;
    uint32 CopyTableCount;
};

#pragma pack(pop)

struct TC_COMMON_API DB2FieldMeta
{
    DB2FieldMeta(bool isSigned, DBCFormer type, char const* name);

    bool IsSigned;
    DBCFormer Type;
    char const* Name;
};

struct TC_COMMON_API DB2FileLoadInfo
{
    DB2FileLoadInfo();
    DB2FileLoadInfo(DB2FieldMeta const* fields, std::size_t fieldCount, DB2Meta const* meta);

    uint32 GetStringFieldCount(bool localizedOnly) const;
    std::pair<int32/*fieldIndex*/, int32/*arrayIndex*/> GetFieldIndexByName(char const* fieldName) const;
    int32 GetFieldIndexByMetaIndex(uint32 metaIndex) const;

    DB2FieldMeta const* Fields;
    std::size_t FieldCount;
    DB2Meta const* Meta;
    std::string TypesString;
};

enum class DB2EncryptedSectionHandling
{
    Skip,
    Process
};

struct TC_COMMON_API DB2FileSource
{
    virtual ~DB2FileSource();

    // Returns true when the source is open for reading
    virtual bool IsOpen() const = 0;

    // Reads numBytes bytes from source and places them into buffer
    // Returns true if numBytes was read successfully
    virtual bool Read(void* buffer, std::size_t numBytes) = 0;

    // Returns current read position in file
    virtual int64 GetPosition() const = 0;

    virtual bool SetPosition(int64 position) = 0;

    virtual int64 GetFileSize() const = 0;

    virtual char const* GetFileName() const = 0;

    virtual DB2EncryptedSectionHandling HandleEncryptedSection(DB2SectionHeader const& sectionHeader) const = 0;
};

class TC_COMMON_API DB2Record
{
public:
    DB2Record(DB2FileLoaderImpl const& db2, uint32 recordIndex, std::size_t* fieldOffsets);
    ~DB2Record();

    operator bool();

    uint32 GetId() const;

    uint8 GetUInt8(uint32 field, uint32 arrayIndex) const;
    uint8 GetUInt8(char const* fieldName) const;
    uint16 GetUInt16(uint32 field, uint32 arrayIndex) const;
    uint16 GetUInt16(char const* fieldName) const;
    uint32 GetUInt32(uint32 field, uint32 arrayIndex) const;
    uint32 GetUInt32(char const* fieldName) const;
    int32 GetInt32(uint32 field, uint32 arrayIndex) const;
    int32 GetInt32(char const* fieldName) const;
    uint64 GetUInt64(uint32 field, uint32 arrayIndex) const;
    uint64 GetUInt64(char const* fieldName) const;
    float GetFloat(uint32 field, uint32 arrayIndex) const;
    float GetFloat(char const* fieldName) const;
    char const* GetString(uint32 field, uint32 arrayIndex) const;
    char const* GetString(char const* fieldName) const;

    // Creates its own heap allocated copy of _fieldOffsets
    // by default _fieldOffets point to a shared array inside Loader to avoid heap allocations
    // meaning that only one instance of DB2Record has valid offsets if the file is sparse
    void MakePersistent();

private:
    DB2FileLoaderImpl const& _db2;
    uint32 _recordIndex;
    unsigned char const* _recordData;
    std::size_t* _fieldOffsets;
};

#pragma pack(push, 1)
struct DB2RecordCopy
{
    uint32 NewRowId = 0;
    uint32 SourceRowId = 0;
};
#pragma pack(pop)

class TC_COMMON_API DB2FileLoader
{
public:
    DB2FileLoader();
    ~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);
    char* AutoProduceData(uint32& count, char**& indexTable, std::vector<char*>& stringPool);
    char* AutoProduceStrings(char** indexTable, uint32 indexTableSize, uint32 locale);
    void AutoProduceRecordCopies(uint32 records, char** indexTable, char* dataTable);

    uint32 GetCols() const { return _header.TotalFieldCount; }
    uint32 GetRecordCount() const;
    uint32 GetRecordCopyCount() const;
    uint32 GetTableHash() const { return _header.TableHash; }
    uint32 GetLayoutHash() const { return _header.LayoutHash; }
    uint32 GetMaxId() const;

    DB2Header const& GetHeader() const { return _header; }
    DB2SectionHeader const& GetSectionHeader(uint32 section) const;
    DB2Record GetRecord(uint32 recordNumber) const;
    DB2RecordCopy GetRecordCopy(uint32 copyNumber) const;

private:
    DB2FileLoaderImpl* _impl;
    DB2Header _header;
};

#endif