catalogxref.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:4k
源码类别:

OpenGL

开发平台:

Visual C++

  1. // catalogxref.cpp
  2. //
  3. // Copyright (C) 2001, Chris Laurel <claurel@shatters.net>
  4. //
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (at your option) any later version.
  9. #include <cctype>
  10. #include <algorithm>
  11. #include <celutil/util.h>
  12. #include "catalogxref.h"
  13. #include "stardb.h"
  14. using namespace std;
  15. CatalogCrossReference::CatalogCrossReference()
  16. {
  17. }
  18. CatalogCrossReference::~CatalogCrossReference()
  19. {
  20. }
  21. string CatalogCrossReference::getPrefix() const
  22. {
  23.     return prefix;
  24. }
  25. void CatalogCrossReference::setPrefix(const string& _prefix)
  26. {
  27.     prefix = _prefix;
  28. }
  29. bool operator<(const CatalogCrossReference::Entry& a,
  30.                const CatalogCrossReference::Entry& b)
  31. {
  32.     return a.catalogNumber < b.catalogNumber;
  33. }
  34. struct XrefEntryPredicate
  35. {
  36.     int dummy;
  37.     XrefEntryPredicate() : dummy(0) {};
  38.     bool operator()(const CatalogCrossReference::Entry& a,
  39.                     const CatalogCrossReference::Entry& b) const
  40.     {
  41.         return a.catalogNumber < b.catalogNumber;
  42.     }
  43. };
  44. Star* CatalogCrossReference::lookup(uint32 catalogNumber) const
  45. {
  46.     Entry e;
  47.     e.catalogNumber = catalogNumber;
  48.     e.star = NULL;
  49.     XrefEntryPredicate pred;
  50.     vector<Entry>::const_iterator iter = lower_bound(entries.begin(),
  51.                                                      entries.end(), e, pred);
  52.     if (iter != entries.end() && iter->catalogNumber == catalogNumber)
  53.         return iter->star;
  54.     else
  55.         return NULL;
  56. }
  57. Star* CatalogCrossReference::lookup(const string& name) const
  58. {
  59.     uint32 catalogNumber = parse(name);
  60.     if (catalogNumber == InvalidCatalogNumber)
  61.         return NULL;
  62.     else
  63.         return lookup(catalogNumber);
  64. }
  65. uint32 CatalogCrossReference::parse(const string& name) const
  66. {
  67.     if (compareIgnoringCase(name, prefix, prefix.length()) != 0)
  68.         return InvalidCatalogNumber;
  69.     unsigned int i = prefix.length();
  70.     unsigned int n = 0;
  71.     bool readDigit = false;
  72.     // Optional space between prefix and number
  73.     if (name[i] == ' ')
  74.         i++;
  75.     while (isdigit(name[i]))
  76.     {
  77.         n = n * 10 + ((unsigned int) name[i] - (unsigned int) '0');
  78.         readDigit = true;
  79.         // Limited to 24 bits
  80.         if (n >= 0x1000000)
  81.             return InvalidCatalogNumber;
  82.     }
  83.     // Must have read at least one digit
  84.     if (!readDigit)
  85.         return InvalidCatalogNumber;
  86.     // Check for garbage at the end of the string
  87.     if (i != prefix.length())
  88.         return InvalidCatalogNumber;
  89.     else
  90.         return n;
  91. }
  92. void CatalogCrossReference::addEntry(uint32 catalogNumber, Star* star)
  93. {
  94.     Entry e;
  95.     e.catalogNumber = catalogNumber;
  96.     e.star = star;
  97.     entries.insert(entries.end(), e);
  98. }
  99. void CatalogCrossReference::sortEntries()
  100. {
  101.     XrefEntryPredicate pred;
  102.     sort(entries.begin(), entries.end(), pred);
  103. }
  104. void CatalogCrossReference::reserve(size_t n)
  105. {
  106.     if (n > entries.size())
  107.         entries.reserve(n);
  108. }
  109. static uint32 readUint32(istream& in)
  110. {
  111.     unsigned char b[4];
  112.     in.read(reinterpret_cast<char*>(b), 4);
  113.     return ((uint32) b[3] << 24) + ((uint32) b[2] << 16)
  114.         + ((uint32) b[1] << 8) + (uint32) b[0];
  115. }
  116. CatalogCrossReference* ReadCatalogCrossReference(istream& in,
  117.                                                  const StarDatabase& stardb)
  118. {
  119.     CatalogCrossReference* xref = new CatalogCrossReference();
  120.     uint32 nEntries = readUint32(in);
  121.     if (!in.good())
  122.     {
  123.         delete xref;
  124.         return NULL;
  125.     }
  126.     xref->reserve(nEntries);
  127.     for (uint32 i = 0; i < nEntries; i++)
  128.     {
  129.         uint32 catNo1 = readUint32(in);
  130.         uint32 catNo2 = readUint32(in);
  131.         Star* star = stardb.find(catNo2);
  132.         if (star != NULL)
  133.             xref->addEntry(catNo1, star);
  134.     }
  135.     return xref;
  136. }