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