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

catalogxref.cpp

Go to the documentation of this file.
00001 // catalogxref.cpp
00002 //
00003 // Copyright (C) 2001, Chris Laurel <claurel@shatters.net>
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 
00010 #include <cctype>
00011 #include <algorithm>
00012 #include <celutil/util.h>
00013 #include "catalogxref.h"
00014 #include "stardb.h"
00015 
00016 using namespace std;
00017 
00018 
00019 CatalogCrossReference::CatalogCrossReference()
00020 {
00021 }
00022 
00023 CatalogCrossReference::~CatalogCrossReference()
00024 {
00025 }
00026 
00027 
00028 string CatalogCrossReference::getPrefix() const
00029 {
00030     return prefix;
00031 }
00032 
00033 void CatalogCrossReference::setPrefix(const string& _prefix)
00034 {
00035     prefix = _prefix;
00036 }
00037 
00038 
00039 bool operator<(const CatalogCrossReference::Entry& a,
00040                const CatalogCrossReference::Entry& b)
00041 {
00042     return a.catalogNumber < b.catalogNumber;
00043 }
00044 
00045 struct XrefEntryPredicate
00046 {
00047     int dummy;
00048 
00049     XrefEntryPredicate() : dummy(0) {};
00050 
00051     bool operator()(const CatalogCrossReference::Entry& a,
00052                     const CatalogCrossReference::Entry& b) const
00053     {
00054         return a.catalogNumber < b.catalogNumber;
00055     }
00056 };
00057 
00058 
00059 Star* CatalogCrossReference::lookup(uint32 catalogNumber) const
00060 {
00061     Entry e;
00062     e.catalogNumber = catalogNumber;
00063     e.star = NULL;
00064 
00065     XrefEntryPredicate pred;
00066     vector<Entry>::const_iterator iter = lower_bound(entries.begin(),
00067                                                      entries.end(), e, pred);
00068 
00069     if (iter != entries.end() && iter->catalogNumber == catalogNumber)
00070         return iter->star;
00071     else
00072         return NULL;
00073 }
00074 
00075 
00076 Star* CatalogCrossReference::lookup(const string& name) const
00077 {
00078     uint32 catalogNumber = parse(name);
00079     if (catalogNumber == InvalidCatalogNumber)
00080         return NULL;
00081     else
00082         return lookup(catalogNumber);
00083 }
00084 
00085 
00086 uint32 CatalogCrossReference::parse(const string& name) const
00087 {
00088     if (compareIgnoringCase(name, prefix, prefix.length()) != 0)
00089         return InvalidCatalogNumber;
00090 
00091     unsigned int i = prefix.length();
00092     unsigned int n = 0;
00093     bool readDigit = false;
00094 
00095     // Optional space between prefix and number
00096     if (name[i] == ' ')
00097         i++;
00098 
00099     while (isdigit(name[i]))
00100     {
00101         n = n * 10 + ((unsigned int) name[i] - (unsigned int) '0');
00102         readDigit = true;
00103 
00104         // Limited to 24 bits
00105         if (n >= 0x1000000)
00106             return InvalidCatalogNumber;
00107     }
00108 
00109     // Must have read at least one digit
00110     if (!readDigit)
00111         return InvalidCatalogNumber;
00112 
00113     // Check for garbage at the end of the string
00114     if (i != prefix.length())
00115         return InvalidCatalogNumber;
00116     else
00117         return n;
00118 }
00119 
00120 
00121 void CatalogCrossReference::addEntry(uint32 catalogNumber, Star* star)
00122 {
00123     Entry e;
00124     e.catalogNumber = catalogNumber;
00125     e.star = star;
00126 
00127     entries.insert(entries.end(), e);
00128 }
00129 
00130 void CatalogCrossReference::sortEntries()
00131 {
00132     XrefEntryPredicate pred;
00133     sort(entries.begin(), entries.end(), pred);
00134 }
00135 
00136 void CatalogCrossReference::reserve(size_t n)
00137 {
00138     if (n > entries.size())
00139         entries.reserve(n);
00140 }
00141 
00142 
00143 static uint32 readUint32(istream& in)
00144 {
00145     unsigned char b[4];
00146     in.read(reinterpret_cast<char*>(b), 4);
00147     return ((uint32) b[3] << 24) + ((uint32) b[2] << 16)
00148         + ((uint32) b[1] << 8) + (uint32) b[0];
00149 }
00150 
00151 
00152 CatalogCrossReference* ReadCatalogCrossReference(istream& in,
00153                                                  const StarDatabase& stardb)
00154 {
00155     CatalogCrossReference* xref = new CatalogCrossReference();
00156 
00157     uint32 nEntries = readUint32(in);
00158     if (!in.good())
00159     {
00160         delete xref;
00161         return NULL;
00162     }
00163 
00164     xref->reserve(nEntries);
00165 
00166     for (uint32 i = 0; i < nEntries; i++)
00167     {
00168         uint32 catNo1 = readUint32(in);
00169         uint32 catNo2 = readUint32(in);
00170         Star* star = stardb.find(catNo2);
00171         if (star != NULL)
00172             xref->addEntry(catNo1, star);
00173     }
00174 
00175     return xref;
00176 }

Generated on Sat Jan 14 22:30:26 2006 for Celestia by  doxygen 1.4.1