File: datematchdecider.cc

package info (click to toggle)
xapian-omega 1.0.7-3+lenny2
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 2,424 kB
  • ctags: 744
  • sloc: sh: 9,112; cpp: 7,954; makefile: 245; perl: 119
file content (123 lines) | stat: -rw-r--r-- 3,609 bytes parent folder | download
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* datematchdecider.cc: date filtering using a Xapian::MatchDecider
 *
 * Copyright (C) 2006 Olly Betts
 *
 * 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 2 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, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 */

#include <config.h>

#include <stdlib.h>
#include <string.h>

#include <xapian.h>

#include "datematchdecider.h"
#include "values.h"

using namespace std;

static inline int DIGIT(char ch) { return ch - '0'; }

static inline int DIGIT2(const char *p) {
    return DIGIT(p[0]) * 10 + DIGIT(p[1]);
}

time_t
set_start_or_end(const string & str, char * yyyymmddhhmm, char * yyyymmdd,
		 char * raw4, bool start)
{
    if (str.size() == 8) {
	memcpy(yyyymmdd, str.c_str(), 9);
	memcpy(yyyymmddhhmm, str.c_str(), 8);
	memcpy(yyyymmddhhmm + 8, start ? "0000" : "2359", 5);
    } else if (str.size() == 12) {
	memcpy(yyyymmddhhmm, str.c_str(), 13);
	memcpy(yyyymmdd, str.c_str(), 8);
	yyyymmdd[8] = '\0';
    } else {
	return (time_t)-1;
    }

    struct tm datetime;
    memset(&datetime, 0, sizeof(struct tm));
    datetime.tm_year = (DIGIT2(yyyymmddhhmm) - 19) * 100 + DIGIT2(yyyymmddhhmm + 2);
    datetime.tm_mon = DIGIT2(yyyymmddhhmm + 4) - 1;
    datetime.tm_mday = DIGIT2(yyyymmddhhmm + 6);
    datetime.tm_hour = DIGIT2(yyyymmddhhmm + 8);
    datetime.tm_min = DIGIT2(yyyymmddhhmm + 10);
    time_t secs = mktime(&datetime);
    string tmp = int_to_binary_string(secs);
    memcpy(raw4, tmp.data(), 4);
    return secs;
}

time_t
set_start_or_end(time_t secs, char * yyyymmddhhmm, char * yyyymmdd, char * raw4)
{
    struct tm * tm = gmtime(&secs);
    strftime(yyyymmdd, 9, "%Y%m%d", tm);
    strftime(yyyymmddhhmm, 13, "%Y%m%d%H%M", tm);
    string tmp = int_to_binary_string(secs);
    memcpy(raw4, tmp.data(), 4);
    return secs;
}

DateMatchDecider::DateMatchDecider(Xapian::valueno val_,
				   const string & date_start,
				   const string & date_end,
				   const string & date_span)
	: val(val_)
{
    if (!date_span.empty()) {
	time_t span = atoi(date_span.c_str()) * (24 * 60 * 60);
	if (!date_end.empty()) {
	    time_t endsec = set_end(date_end);
	    set_start(endsec - span);
	} else if (!date_start.empty()) {
	    time_t startsec = set_start(date_start);
	    set_end(startsec + span);
	} else {
	    time_t endsec = time(NULL);
	    set_end(endsec);
	    set_start(endsec - span);
	}
    } else {
	if (date_start.empty()) {
	    set_start(0);
	} else {
	    set_start(date_start);
	}
	if (date_end.empty()) {
	    set_end(time(NULL));
	} else {
	    set_end(date_end);
	}
    }
}

bool
DateMatchDecider::operator()(const Xapian::Document &doc) const
{
    string s(doc.get_value(val));
    if (s.size() == 4) {
	return memcmp(s.data(), s_raw4, 4) >= 0 && memcmp(s.data(), e_raw4, 4) <= 0;
    } else if (s.size() == 8) {
	return memcmp(s.data(), s_yyyymmdd, 8) >= 0 && memcmp(s.data(), e_yyyymmdd, 8) <= 0;
    } else if (s.size() == 12) {
	return memcmp(s.data(), s_yyyymmddhhmm, 12) >= 0 && memcmp(s.data(), e_yyyymmddhhmm, 12) <= 0;
    }
    return true;
}