1 // $Id: ZoneIndex.cc 5749 2014-10-11 19:42:10Z flaterco $ 2 3 /* ZoneIndex Index stations by zone for xttpd. 4 5 Copyright (C) 1998 David Flater. 6 7 This program is free software: you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation, either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #include "libxtide/libxtide.hh" 22 using namespace libxtide; 23 #include "ZoneIndex.hh" 24 25 lookup(const Dstr & zone)26ZoneIndex::ZInode * const ZoneIndex::ZImap::lookup (const Dstr &zone) { 27 assert (zone.length()); 28 29 ZImap::iterator xactmatch = find (zone); 30 if (xactmatch != end()) 31 return &(xactmatch->second); 32 33 for (ZImap::iterator it = begin(); it != end(); ++it) 34 // ":America/New_York" %= ":America/" 35 if ((zone %= it->first) && (it->first.back() == '/')) 36 return it->second.subzones.lookup (zone); 37 38 return NULL; 39 } 40 41 operator [](const Dstr & zone)42ZoneIndex::ZInode * const ZoneIndex::operator[] (const Dstr &zone) { 43 if (zone.length()) 44 return top.subzones.lookup (zone); 45 return ⊤ 46 } 47 48 makezone(const Dstr & zone)49ZoneIndex::ZInode &ZoneIndex::makezone (const Dstr &zone) { 50 assert (zone.length()); 51 assert (zone.back() != '/'); 52 ZInode *tryit = operator[](zone); 53 if (tryit) 54 return *tryit; 55 else { 56 Dstr smallzone (zone), addzone (zone); 57 int i; 58 // Find the level that already exists. 59 while ((i = smallzone.strrchr ('/')) != -1) { 60 if (i == (int)smallzone.length() - 1) { 61 addzone = smallzone; 62 smallzone -= i; 63 } else { 64 smallzone -= i+1; 65 if ((tryit = operator[](smallzone))) 66 break; 67 } 68 } 69 // Add one more level. 70 if (tryit) 71 (void) tryit->subzones[addzone]; 72 else 73 (void) top.subzones[addzone]; 74 // Repeat till done. 75 return makezone (zone); 76 } 77 } 78 79 add(StationRef * sr)80void ZoneIndex::add (StationRef *sr) { 81 assert (sr); 82 const Dstr &zone = sr->timezone; 83 assert (!zone.isNull()); 84 makezone(zone).stationIndex.push_back (sr); 85 } 86 87 add(const StationIndex & stationIndex)88void ZoneIndex::add (const StationIndex &stationIndex) { 89 Global::log ("Building zone index...", LOG_NOTICE); 90 for (unsigned long i=0; i<stationIndex.size(); ++i) 91 add (stationIndex[i]); 92 } 93 94 // Cleanup2006 Cruft CloseEnough 95