00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00032 #include "../Include/Globals.h"
00033 #include "../Include/Database.h"
00034 #include "../Include/Pod.h"
00035 #include <map>
00036
00037 using namespace std;
00038
00039
00040 typedef struct {
00041 unsigned long signature;
00042 unsigned long unknown0;
00043 unsigned long unknown1;
00044 unsigned long checksum;
00045 unsigned long nRecords;
00046 unsigned long recLength;
00047 unsigned long dummy[8];
00048 Tag keyId;
00049 unsigned char keyType;
00050 unsigned long keyLength;
00051 } DBIHeader;
00052
00053
00054 CDatabaseIndex::CDatabaseIndex (const char* dbiFilename)
00055 {
00056 keyId = 0;
00057 keyType = 0;
00058 keyLength = 0;
00059
00060 stringIndex = NULL;
00061 doubleIndex = NULL;
00062 intIndex = NULL;
00063
00064 Load (dbiFilename);
00065 }
00066
00067 CDatabaseIndex::~CDatabaseIndex ()
00068 {
00069 if (stringIndex != NULL) delete stringIndex;
00070 if (doubleIndex != NULL) delete doubleIndex;
00071 if (intIndex != NULL) delete intIndex;
00072 }
00073
00074
00075
00076
00077 void CDatabaseIndex::Load (PODFILE* f)
00078 {
00079 int i;
00080
00081
00082 DBIHeader header;
00083 ReadULong (f, &header.signature);
00084 ReadULong (f, &header.unknown0);
00085 ReadULong (f, &header.unknown1);
00086 ReadULong (f, &header.checksum);
00087 ReadULong (f, &header.nRecords);
00088 ReadULong (f, &header.recLength);
00089 for (i=0; i<8; i++) ReadULong (f, &header.dummy[i]);
00090
00091
00093
00094
00095
00096
00097
00098
00099
00100 unsigned char keyTypeRaw;
00101 ReadUChar (f, &keyTypeRaw);
00102 ReadUChar (f, &keyTypeRaw);
00103 header.keyType = keyTypeRaw;
00104 ReadUChar (f, &keyTypeRaw);
00105 ReadUChar (f, &keyTypeRaw);
00106
00107 ReadULong (f, &header.keyLength);
00108
00109
00110 keyId = header.keyId;
00111 keyType = header.keyType;
00112 keyLength = header.keyLength;
00113
00114 unsigned long offset;
00115
00116 switch (keyType) {
00117 case 'C':
00118 {
00119
00120 stringIndex = new multimap<string,unsigned long>;
00121
00122
00123 char *s = new char[keyLength+1];
00124 for (unsigned long i=0; i<header.nRecords; i++) {
00125 memset (s, 0, keyLength+1);
00126 pread (s, keyLength, 1, f);
00127 ReadULong (f, &offset);
00128
00129 pair<string,unsigned long> p;
00130 p.first = s;
00131 p.second = offset;
00132
00133 stringIndex->insert (p);
00134 }
00135 delete[] s;
00136 }
00137 break;
00138
00139 case 'D':
00140 {
00141
00142 doubleIndex = new multimap<double,unsigned long>;
00143
00144
00145 double d;
00146 for (unsigned long i=0; i<header.nRecords; i++) {
00147 ReadDouble (f, &d);
00148 ReadULong (f, &offset);
00149
00150 pair<double,unsigned long> p;
00151 p.first = d;
00152 p.second = offset;
00153
00154 doubleIndex->insert (p);
00155 }
00156 }
00157 break;
00158
00159 case 'I':
00160 {
00161
00162 intIndex = new multimap<long,unsigned long>;
00163
00164
00165 long d;
00166 for (unsigned long i=0; i<header.nRecords; i++) {
00167 ReadLong (f, &d);
00168 ReadULong (f, &offset);
00169
00170 pair<long,unsigned long> p;
00171 p.first = d;
00172 p.second = offset;
00173
00174 intIndex->insert (p);
00175 }
00176 }
00177 break;
00178 }
00179 }
00180
00181
00182
00183
00184 void CDatabaseIndex::Load (const char* dbiFilename)
00185 {
00186 char fullFilename[64];
00187 strcpy (fullFilename, "Database\\");
00188 strcat (fullFilename, dbiFilename);
00189 PODFILE *p = popen (&globals->pfs, fullFilename);
00190
00191 if (p) {
00192 Load (p);
00193 pclose (p);
00194 }
00195 }
00196
00197
00198
00199
00200
00201 int CDatabaseIndex::GetNumItems ()
00202 {
00203 int rc = 0;
00204
00205 if (stringIndex != NULL) {
00206 rc = stringIndex->size();
00207 } else if (doubleIndex != NULL) {
00208 rc = doubleIndex->size();
00209 } else if (intIndex != NULL) {
00210 rc = intIndex->size();
00211 }
00212
00213 return rc;
00214 }
00215
00216
00217
00218
00219 Tag CDatabaseIndex::GetKeyId (void)
00220 {
00221 return keyId;
00222 }
00223
00224
00225
00226
00227 char CDatabaseIndex::GetKeyType (void)
00228 {
00229 return keyType;
00230 }
00231
00232
00233
00234
00235 unsigned long CDatabaseIndex::GetKeyLength (void)
00236 {
00237 return keyLength;
00238 }
00239
00240
00241
00242
00243 unsigned long CDatabaseIndex::Search (const char* key)
00244 {
00245 unsigned long rc = 0;
00246
00247 if (stringIndex != NULL) {
00248 stringRange = stringIndex->equal_range (key);
00249 }
00250
00251 stringIter = stringRange.first;
00252 if (stringIter != stringIndex->end()) {
00253 rc = stringIter->second;
00254 }
00255
00256 return rc;
00257 }
00258
00259
00260
00261
00262 unsigned long CDatabaseIndex::Search (double key)
00263 {
00264 unsigned long rc = 0;
00265
00266 if (doubleIndex != NULL) {
00267 doubleRange = doubleIndex->equal_range (key);
00268 }
00269
00270 if (doubleRange.first != doubleIndex->end()) {
00271 rc = (doubleRange.first)->second;
00272 }
00273
00274 return rc;
00275 }
00276
00277
00278
00279
00280
00281 unsigned long CDatabaseIndex::Search (long key)
00282 {
00283 unsigned long rc = 0;
00284
00285 if (intIndex != NULL) {
00286 intRange = intIndex->equal_range (key);
00287 }
00288
00289 if (intRange.first != intIndex->end()) {
00290 rc = (intRange.first)->second;
00291 }
00292
00293 return rc;
00294 }
00295
00296
00297
00298
00299 unsigned long CDatabaseIndex::SearchNext (void)
00300 {
00301 unsigned long rc = 0;
00302
00303 if (stringIndex != NULL) {
00304 stringIter++;
00305 if (stringIter != stringIndex->end()) {
00306 rc = stringIter->second;
00307 }
00308 }
00309
00310 return rc;
00311 }
00312
00313 void CDatabaseIndex::Dump (FILE *f)
00314 {
00315
00316 }