1 | #ifndef DBCFILE_H |
---|
2 | #define DBCFILE_H |
---|
3 | #define __STORMLIB_SELF__ |
---|
4 | |
---|
5 | #include <cassert> |
---|
6 | #include <string> |
---|
7 | #include "Stormlib.h" |
---|
8 | |
---|
9 | class DBCFile |
---|
10 | { |
---|
11 | public: |
---|
12 | DBCFile(const std::string &filename); |
---|
13 | ~DBCFile(); |
---|
14 | |
---|
15 | // Open database. It must be openened before it can be used. |
---|
16 | bool open(); |
---|
17 | |
---|
18 | // TODO: Add a close function? |
---|
19 | |
---|
20 | // Database exceptions |
---|
21 | class Exception |
---|
22 | { |
---|
23 | public: |
---|
24 | Exception(const std::string &message): message(message) |
---|
25 | { } |
---|
26 | virtual ~Exception() |
---|
27 | { } |
---|
28 | const std::string &getMessage() {return message;} |
---|
29 | private: |
---|
30 | std::string message; |
---|
31 | }; |
---|
32 | |
---|
33 | // |
---|
34 | class NotFound: public Exception |
---|
35 | { |
---|
36 | public: |
---|
37 | NotFound(): Exception("Key was not found") |
---|
38 | { } |
---|
39 | }; |
---|
40 | |
---|
41 | // Iteration over database |
---|
42 | class Iterator; |
---|
43 | class Record |
---|
44 | { |
---|
45 | public: |
---|
46 | Record& operator= (const Record& r) |
---|
47 | { |
---|
48 | file = r.file; |
---|
49 | offset = r.offset; |
---|
50 | return *this; |
---|
51 | } |
---|
52 | float getFloat(size_t field) const |
---|
53 | { |
---|
54 | assert(field < file.fieldCount); |
---|
55 | return *reinterpret_cast<float*>(offset+field*4); |
---|
56 | } |
---|
57 | unsigned int getUInt(size_t field) const |
---|
58 | { |
---|
59 | assert(field < file.fieldCount); |
---|
60 | return *reinterpret_cast<unsigned int*>(offset+(field*4)); |
---|
61 | } |
---|
62 | int getInt(size_t field) const |
---|
63 | { |
---|
64 | assert(field < file.fieldCount); |
---|
65 | return *reinterpret_cast<int*>(offset+field*4); |
---|
66 | } |
---|
67 | unsigned char getByte(size_t ofs) const |
---|
68 | { |
---|
69 | assert(ofs < file.recordSize); |
---|
70 | return *reinterpret_cast<unsigned char*>(offset+ofs); |
---|
71 | } |
---|
72 | const char *getString(size_t field) const |
---|
73 | { |
---|
74 | assert(field < file.fieldCount); |
---|
75 | size_t stringOffset = getUInt(field); |
---|
76 | assert(stringOffset < file.stringSize); |
---|
77 | //char * tmp = (char*)file.stringTable + stringOffset; |
---|
78 | //unsigned char * tmp2 = file.stringTable + stringOffset; |
---|
79 | return reinterpret_cast<char*>(file.stringTable + stringOffset); |
---|
80 | } |
---|
81 | private: |
---|
82 | Record(DBCFile &file, unsigned char *offset): file(file), offset(offset) {} |
---|
83 | unsigned char *offset; |
---|
84 | DBCFile &file; |
---|
85 | |
---|
86 | friend class DBCFile; |
---|
87 | friend class Iterator; |
---|
88 | }; |
---|
89 | |
---|
90 | /* Iterator that iterates over records */ |
---|
91 | class Iterator |
---|
92 | { |
---|
93 | public: |
---|
94 | Iterator(DBCFile &file, unsigned char *offset): |
---|
95 | record(file, offset) {} |
---|
96 | /// Advance (prefix only) |
---|
97 | Iterator & operator++() { |
---|
98 | record.offset += record.file.recordSize; |
---|
99 | return *this; |
---|
100 | } |
---|
101 | /// Return address of current instance |
---|
102 | Record const & operator*() const { return record; } |
---|
103 | const Record* operator->() const { |
---|
104 | return &record; |
---|
105 | } |
---|
106 | /// Comparison |
---|
107 | bool operator==(const Iterator &b) const |
---|
108 | { |
---|
109 | return record.offset == b.record.offset; |
---|
110 | } |
---|
111 | bool operator!=(const Iterator &b) const |
---|
112 | { |
---|
113 | return record.offset != b.record.offset; |
---|
114 | } |
---|
115 | private: |
---|
116 | Record record; |
---|
117 | }; |
---|
118 | |
---|
119 | // Get record by id |
---|
120 | Record getRecord(size_t id); |
---|
121 | /// Get begin iterator over records |
---|
122 | Iterator begin(); |
---|
123 | /// Get begin iterator over records |
---|
124 | Iterator end(); |
---|
125 | /// Trivial |
---|
126 | size_t getRecordCount() const { return recordCount;} |
---|
127 | size_t getFieldCount() const { return fieldCount; } |
---|
128 | |
---|
129 | private: |
---|
130 | std::string filename; |
---|
131 | size_t recordSize; |
---|
132 | size_t recordCount; |
---|
133 | size_t fieldCount; |
---|
134 | size_t stringSize; |
---|
135 | unsigned char *data; |
---|
136 | unsigned char *stringTable; |
---|
137 | }; |
---|
138 | |
---|
139 | #endif |
---|