File: ZoneIndex.cc

package info (click to toggle)
xtide 2.9.5-3
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 2,996 kB
  • ctags: 2,141
  • sloc: cpp: 20,379; sh: 1,044; makefile: 224; yacc: 114; lex: 58
file content (93 lines) | stat: -rw-r--r-- 2,564 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// $Id: ZoneIndex.cc 2641 2007-09-02 21:31:02Z flaterco $	

/*  ZoneIndex  Index stations by zone for xttpd.

    Copyright (C) 1998  David Flater.

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "common.hh"
#include "ZoneIndex.hh"


ZoneIndex::ZInode * const ZoneIndex::ZImap::lookup (const Dstr &zone) {
  assert (zone.length());

  ZImap::iterator xactmatch = find (zone);
  if (xactmatch != end())
    return &(xactmatch->second);

  for (ZImap::iterator it = begin(); it != end(); ++it)
    // ":America/New_York" %= ":America/"
    if ((zone %= it->first) && (it->first.back() == '/'))
      return it->second.subzones.lookup (zone);

  return NULL;
}


ZoneIndex::ZInode * const ZoneIndex::operator[] (const Dstr &zone) {
  if (zone.length())
    return top.subzones.lookup (zone);
  return &top;
}


ZoneIndex::ZInode &ZoneIndex::makezone (const Dstr &zone) {
  assert (zone.length());
  assert (zone.back() != '/');
  ZInode *tryit = operator[](zone);
  if (tryit)
    return *tryit;
  else {
    Dstr smallzone (zone), addzone (zone);
    int i;
    // Find the level that already exists.
    while ((i = smallzone.strrchr ('/')) != -1) {
      if (i == (int)smallzone.length() - 1) {
        addzone = smallzone;
        smallzone -= i;
      } else {
        smallzone -= i+1;
        if ((tryit = operator[](smallzone)))
          break;
      }
    }
    // Add one more level.
    if (tryit)
      (void) tryit->subzones[addzone];
    else
      (void) top.subzones[addzone];
    // Repeat till done.
    return makezone (zone);
  }
}


void ZoneIndex::add (StationRef *sr) {
  assert (sr);
  const Dstr &zone = sr->timezone;
  assert (!zone.isNull());
  makezone(zone).stationIndex.push_back (sr);
}


void ZoneIndex::add (const StationIndex &stationIndex) {
  Global::log ("Building zone index...", LOG_NOTICE);
  for (unsigned long i=0; i<stationIndex.size(); ++i)
    add (stationIndex[i]);
}

// Cleanup2006 Cruft CloseEnough