Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

DBIndex.cpp

Go to the documentation of this file.
00001 /*
00002  * DBIndex.cpp
00003  *
00004  * Part of Fly! Legacy project
00005  *
00006  * Copyright 2003 Chris Wallace
00007  *
00008  * Fly! Legacy is free software; you can redistribute it and/or modify
00009  *   it under the terms of the GNU General Public License as published by
00010  *   the Free Software Foundation; either version 2 of the License, or
00011  *   (at your option) any later version.
00012  *
00013  * Fly! Legacy is distributed in the hope that it will be useful,
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *   GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  *   along with Fly! Legacy; if not, write to the Free Software
00020  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 // Loader which takes an open PODFILE* reference to the DBI file
00076 //
00077 void CDatabaseIndex::Load (PODFILE* f)
00078 {
00079   int i;
00080 
00081   // Read DBI Header
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   // Key ID must be byte-flipped after harmonization with CPU type
00095   ReadULong (f, &header.keyId);
00096   header.keyId = ulEndianBig32(header.keyId);
00097 */
00098 
00099   // Key type is unsigned char but stored in file as an unsigned long
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   // Assign key data fields
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       // Allocate index multimap
00120       stringIndex = new multimap<string,unsigned long>;
00121 
00122       // Parse DBI items as strings
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       // Allocate index multimap
00142       doubleIndex = new multimap<double,unsigned long>;
00143 
00144       // Parse DBI items as double floats
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       // Allocate index multimap
00162       intIndex = new multimap<long,unsigned long>;
00163 
00164       // Parse DBI items as long integers
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 // Constructor which accepts a const char* filename of the DBI file
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 // Data access function to get the number of records in the index
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 // Data access function to get the index key Tag
00218 //
00219 Tag CDatabaseIndex::GetKeyId (void)
00220 {
00221   return keyId;
00222 }
00223 
00224 //
00225 // Data access function to get the index key type
00226 //
00227 char CDatabaseIndex::GetKeyType (void)
00228 {
00229   return keyType;
00230 }
00231 
00232 //
00233 // Data access function to get the index key length
00234 //
00235 unsigned long CDatabaseIndex::GetKeyLength (void)
00236 {
00237   return keyLength;
00238 }
00239 
00240 //
00241 // Search the index for the specified value
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 // Search the index for the specified value
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 // Search the index for the specified value
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 // Search the index for the specified value
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   // \todo Dump index details
00316 }
SourceForge.net Logo Documentation generated by doxygen