Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
DB2Store.h
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#ifndef DB2STORE_H
7#define DB2STORE_H
8
9#include "ByteBuffer.h"
10#include "Common.h"
11#include "DB2FileLoader.h"
12#include <vector>
13
16{
17public:
18 virtual ~DB2StorageBase() { }
19
20 uint32 GetHash() const { return tableHash; }
21
22 virtual bool HasRecord(uint32 id) const = 0;
23
24 virtual void WriteRecord(uint32 id, uint32 locale, ByteBuffer& buffer) const = 0;
25
26protected:
28};
29
30template<class T>
31class DB2Storage;
32
33template<class T>
35{
36 return store.LookupEntry(id) != NULL;
37}
38
39template<class T>
40void WriteDB2RecordToPacket(DB2Storage<T> const& store, uint32 id, uint32 locale, ByteBuffer& buffer)
41{
42 uint8 const* entry = (uint8 const*)store.LookupEntry(id);
43 ASSERT(entry);
44
45 std::string format = store.GetFormat();
46 for (uint32 i = 0; i < format.length(); ++i)
47 {
48 switch (format[i])
49 {
50 case FT_IND:
51 case FT_INT:
52 buffer << *(uint32*)entry;
53 entry += 4;
54 break;
55 case FT_FLOAT:
56 buffer << *(float*)entry;
57 entry += 4;
58 break;
59 case FT_BYTE:
60 buffer << *(uint8*)entry;
61 entry += 1;
62 break;
63 case FT_STRING:
64 {
65 LocalizedString* locStr = *(LocalizedString**)entry;
66 if (locStr->Str[locale][0] == '\0')
67 locale = 0;
68
69 char const* str = locStr->Str[locale];
70 size_t len = strlen(str);
71 buffer << uint16(len);
72 if (len)
73 buffer << str;
74 entry += sizeof(char*);
75 break;
76 }
77 case FT_NA:
78 case FT_SORT:
79 buffer << uint32(0);
80 break;
81 case FT_NA_BYTE:
82 buffer << uint8(0);
83 break;
84 }
85 }
86}
87
88template<class T>
90{
91 typedef std::list<char*> StringPoolList;
92 typedef std::vector<T*> DataTableEx;
93 typedef bool(*EntryChecker)(DB2Storage<T> const&, uint32);
95public:
96 DB2Storage(char const* f, EntryChecker checkEntry = NULL, PacketWriter writePacket = NULL) :
97 nCount(0), fieldCount(0), fmt(f), m_dataTable(NULL)
98 {
99 indexTable.asT = NULL;
100 CheckEntry = checkEntry ? checkEntry : (EntryChecker)&DB2StorageHasEntry<T>;
101 WritePacket = writePacket ? writePacket : (PacketWriter)&WriteDB2RecordToPacket<T>;
102 }
103
105
106 bool HasRecord(uint32 id) const { return CheckEntry(*this, id); }
107 T const* LookupEntry(uint32 id) const { return (id >= nCount) ? NULL : indexTable.asT[id]; }
108 uint32 GetNumRows() const { return nCount; }
109 char const* GetFormat() const { return fmt; }
110 uint32 GetFieldCount() const { return fieldCount; }
111 void WriteRecord(uint32 id, uint32 locale, ByteBuffer& buffer) const
112 {
113 WritePacket(*this, id, locale, buffer);
114 }
115
116 T* CreateEntry(uint32 id, bool evenIfExists = false)
117 {
118 if (evenIfExists && LookupEntry(id))
119 return NULL;
120
121 if (id >= nCount)
122 {
123 // reallocate index table
124 char** tmpIdxTable = new char* [id + 1];
125 memset(tmpIdxTable, 0, (id + 1) * sizeof(char*));
126 memcpy(tmpIdxTable, indexTable.asChar, nCount * sizeof(char*));
127 delete[] reinterpret_cast<char*>(indexTable.asT);
128 nCount = id + 1;
129 indexTable.asChar = tmpIdxTable;
130 }
131
132 T* entryDst = new T;
133 m_dataTableEx.push_back(entryDst);
134 indexTable.asT[id] = entryDst;
135 return entryDst;
136 }
137
138 void EraseEntry(uint32 id) { indexTable.asT[id] = NULL; }
139
140 bool Load(char const* fn, uint32 locale)
141 {
142 DB2FileLoader db2;
143 // Check if load was sucessful, only then continue
144 if (!db2.Load(fn, fmt))
145 return false;
146
147 fieldCount = db2.GetCols();
148 tableHash = db2.GetHash();
149
150 // load raw non-string data
151 m_dataTable = reinterpret_cast<T*>(db2.AutoProduceData(fmt, nCount, indexTable.asChar));
152
153 // create string holders for loaded string fields
155
156 // load strings from dbc data
157 m_stringPoolList.push_back(db2.AutoProduceStrings(fmt, (char*)m_dataTable, locale));
158
159 // error in dbc file at loading if NULL
160 return indexTable.asT != NULL;
161 }
162
163 bool LoadStringsFrom(char const* fn, uint32 locale)
164 {
165 // DBC must be already loaded using Load
166 if (!indexTable.asT)
167 return false;
168
169 DB2FileLoader db2;
170 // Check if load was successful, only then continue
171 if (!db2.Load(fn, fmt))
172 return false;
173
174 // load strings from another locale dbc data
175 m_stringPoolList.push_back(db2.AutoProduceStrings(fmt, (char*)m_dataTable, locale));
176
177 return true;
178 }
179
180 void Clear()
181 {
182 if (!indexTable.asT)
183 return;
184
185 delete[] reinterpret_cast<char*>(indexTable.asT);
186 indexTable.asT = NULL;
187
188 delete[] reinterpret_cast<char*>(m_dataTable);
189 m_dataTable = NULL;
190
191 for (typename DataTableEx::iterator itr = m_dataTableEx.begin(); itr != m_dataTableEx.end(); ++itr)
192 delete* itr;
193 m_dataTableEx.clear();
194
195 while (!m_stringPoolList.empty())
196 {
197 delete[] m_stringPoolList.front();
198 m_stringPoolList.pop_front();
199 }
200
201 nCount = 0;
202 }
203
206
207private:
210 char const* fmt;
211 union
212 {
213 T** asT;
214 char** asChar;
219};
220
221#endif
void WriteDB2RecordToPacket(DB2Storage< T > const &store, uint32 id, uint32 locale, ByteBuffer &buffer)
Definition DB2Store.h:40
bool DB2StorageHasEntry(DB2Storage< T > const &store, uint32 id)
Definition DB2Store.h:34
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
@ FT_IND
Definition Define.h:90
@ FT_NA
Definition Define.h:83
@ FT_FLOAT
Definition Define.h:86
@ FT_STRING
Definition Define.h:85
@ FT_SORT
Definition Define.h:89
@ FT_NA_BYTE
Definition Define.h:84
@ FT_INT
Definition Define.h:87
@ FT_BYTE
Definition Define.h:88
std::uint16_t uint16
Definition Define.h:78
#define ASSERT
Definition Errors.h:29
bool Load(const char *filename, const char *fmt)
char * AutoProduceStrings(std::string fmt, char *dataTable, uint32 locale)
char * AutoProduceData(std::string fmt, uint32 &count, char **&indexTable)
uint32 GetHash() const
char * AutoProduceStringsArrayHolders(std::string fmt, char *dataTable)
uint32 GetCols() const
Interface class for common access.
Definition DB2Store.h:16
virtual ~DB2StorageBase()
Definition DB2Store.h:18
uint32 GetHash() const
Definition DB2Store.h:20
virtual void WriteRecord(uint32 id, uint32 locale, ByteBuffer &buffer) const =0
virtual bool HasRecord(uint32 id) const =0
uint32 tableHash
Definition DB2Store.h:27
bool LoadStringsFrom(char const *fn, uint32 locale)
Definition DB2Store.h:163
T * m_dataTable
Definition DB2Store.h:216
T * CreateEntry(uint32 id, bool evenIfExists=false)
Definition DB2Store.h:116
uint32 GetFieldCount() const
Definition DB2Store.h:110
void(* PacketWriter)(DB2Storage< T > const &, uint32, uint32, ByteBuffer &)
Definition DB2Store.h:94
char ** asChar
Definition DB2Store.h:214
StringPoolList m_stringPoolList
Definition DB2Store.h:218
PacketWriter WritePacket
Definition DB2Store.h:205
DB2Storage(char const *f, EntryChecker checkEntry=NULL, PacketWriter writePacket=NULL)
Definition DB2Store.h:96
bool Load(char const *fn, uint32 locale)
Definition DB2Store.h:140
void EraseEntry(uint32 id)
Definition DB2Store.h:138
T const * LookupEntry(uint32 id) const
Definition DB2Store.h:107
uint32 GetNumRows() const
Definition DB2Store.h:108
char const * GetFormat() const
Definition DB2Store.h:109
void Clear()
Definition DB2Store.h:180
void WriteRecord(uint32 id, uint32 locale, ByteBuffer &buffer) const
Definition DB2Store.h:111
bool(* EntryChecker)(DB2Storage< T > const &, uint32)
Definition DB2Store.h:93
uint32 fieldCount
Definition DB2Store.h:209
union DB2Storage::@255306326344120151304235255234327214377351333372 indexTable
uint32 nCount
Definition DB2Store.h:208
bool HasRecord(uint32 id) const
Definition DB2Store.h:106
EntryChecker CheckEntry
Definition DB2Store.h:204
char const * fmt
Definition DB2Store.h:210
std::list< char * > StringPoolList
Definition DB2Store.h:91
std::vector< T * > DataTableEx
Definition DB2Store.h:92
DataTableEx m_dataTableEx
Definition DB2Store.h:217
char const * Str[TOTAL_LOCALES]
Definition Common.h:173