00001
00002
00003
00004
00005
00006
00007
00008
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
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
00105 if (n >= 0x1000000)
00106 return InvalidCatalogNumber;
00107 }
00108
00109
00110 if (!readDigit)
00111 return InvalidCatalogNumber;
00112
00113
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 }