36 StringValueRangeProcessor::operator()(
string &begin,
string &end)
39 if (prefix && begin.empty()) {
44 end.erase(0,
str.size());
45 }
else if (!prefix && end.empty()) {
50 begin.resize(begin.size() -
str.size());
57 begin.erase(0,
str.size());
60 end.erase(0,
str.size());
68 end.resize(end.size() -
str.size());
71 begin.resize(begin.size() -
str.size());
85 if (s.size() < 5 || s.size() > 10)
return false;
86 size_t i = s.find_first_not_of(
"0123456789");
87 if (i < 1 || i > 2 || !(s[i] ==
'/' || s[i] ==
'-' || s[i] ==
'.'))
89 size_t j = s.find_first_not_of(
"0123456789", i + 1);
90 if (j - (i + 1) < 1 || j - (i + 1) > 2 ||
91 !(s[j] ==
'/' || s[j] ==
'-' || s[j] ==
'.'))
93 if (s.size() - j > 4 + 1)
return false;
94 if (s.find_first_not_of(
"0123456789", j + 1) != string::npos)
97 if (x1 < 1 || x1 > 31)
return false;
98 x2 = atoi(s.c_str() + i + 1);
99 if (x2 < 1 || x2 > 31)
return false;
100 y = atoi(s.c_str() + j + 1);
109 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
115 if (m == -1)
return true;
116 if (m > 12 || m < 1)
return false;
125 return (s.find_first_not_of(
"0123456789") == 4 &&
126 s.find_first_not_of(
"0123456789", 5) == 7 &&
127 s.find_first_not_of(
"0123456789", 8) == string::npos &&
129 (s[4] ==
'-' || s[4] ==
'.' || s[4] ==
'/'));
142 p[w] =
'0' + (v % 10);
156 DateValueRangeProcessor::operator()(
string &begin,
string &end)
158 if (StringValueRangeProcessor::operator()(begin, end) ==
BAD_VALUENO)
161 if ((begin.size() == 8 || begin.size() == 0) &&
162 (end.size() == 8 || end.size() == 0) &&
163 begin.find_first_not_of(
"0123456789") == string::npos &&
164 end.find_first_not_of(
"0123456789") == string::npos) {
168 if ((begin.size() == 10 || begin.size() == 0) &&
169 (end.size() == 10 || end.size() == 0)) {
173 if (!begin.empty()) {
192 if (!prefer_mdy &&
vet_dm(b_d, b_m) &&
vet_dm(e_d, e_m) &&
193 (b_y != e_y || b_m < e_m || (b_m == e_m && b_d <= e_d))) {
196 (b_y != e_y || b_d < e_d || (b_d == e_d && b_m <= e_m))) {
199 }
else if (prefer_mdy &&
vet_dm(b_d, b_m) &&
vet_dm(e_d, e_m) &&
200 (b_y != e_y || b_m < e_m || (b_m == e_m && b_d <= e_d))) {
207 if (!begin.empty()) {
210 if (b_y < epoch_year) b_y += 100;
213 begin.assign(buf, 8);
218 if (e_y < epoch_year) e_y += 100;
227 NumberValueRangeProcessor::operator()(
string &begin,
string &end)
229 if (StringValueRangeProcessor::operator()(begin, end) ==
BAD_VALUENO)
235 if (!begin.empty()) {
237 const char * startptr = begin.c_str();
239 beginnum = strtod(startptr, &endptr);
240 if (endptr != startptr + begin.size())
253 const char * startptr = end.c_str();
255 double endnum = strtod(startptr, &endptr);
256 if (endptr != startptr + end.size())
265 if (!begin.empty()) {
273 RangeProcessor::check_range(
const string& b,
const string& e)
276 return operator()(b, e);
278 size_t off_b = 0, len_b = string::npos;
279 size_t off_e = 0, len_e = string::npos;
284 if (repeated && prefix && b.empty()) {
290 }
else if (repeated && !prefix && e.empty()) {
295 len_b = b.size() -
str.size();
313 len_e = e.size() -
str.size();
316 len_b = b.size() -
str.size();
320 return operator()(
string(b, off_b, len_b),
string(e, off_e, len_e));
327 RangeProcessor::operator()(
const string& b,
const string& e)
335 DateRangeProcessor::operator()(
const string& b,
const string& e)
337 if ((b.size() == 8 || b.size() == 0) &&
338 (e.size() == 8 || e.size() == 0) &&
339 b.find_first_not_of(
"0123456789") == string::npos &&
340 e.find_first_not_of(
"0123456789") == string::npos) {
342 return RangeProcessor::operator()(b, e);
344 if ((b.size() == 10 || b.size() == 0) &&
345 (e.size() == 10 || e.size() == 0)) {
348 string begin = b, end = e;
350 if (!begin.empty()) {
358 return RangeProcessor::operator()(begin, end);
370 if (!prefer_mdy &&
vet_dm(b_d, b_m) &&
vet_dm(e_d, e_m) &&
371 (b_y != e_y || b_m < e_m || (b_m == e_m && b_d <= e_d))) {
374 (b_y != e_y || b_d < e_d || (b_d == e_d && b_m <= e_m))) {
377 }
else if (prefer_mdy &&
vet_dm(b_d, b_m) &&
vet_dm(e_d, e_m) &&
378 (b_y != e_y || b_m < e_m || (b_m == e_m && b_d <= e_d))) {
385 char buf_b[8], buf_e[8];
386 size_t len_b = 0, len_e = 0;
390 if (b_y < epoch_year) b_y += 100;
398 if (e_y < epoch_year) e_y += 100;
403 return RangeProcessor::operator()(
string(buf_b, len_b),
404 string(buf_e, len_e));
412 NumberRangeProcessor::operator()(
const string& b,
const string& e)
419 const char * startptr = b.c_str();
421 num_b = strtod(startptr, &endptr);
422 if (endptr != startptr + b.size() || errno) {
433 const char * startptr = e.c_str();
435 num_e = strtod(startptr, &endptr);
436 if (endptr != startptr + e.size() || errno) {
445 return RangeProcessor::operator()(
Class representing a query.
@ OP_VALUE_RANGE
Match only documents where a value slot is within a given range.
@ OP_VALUE_GE
Match only documents where a value slot is >= a given value.
@ OP_INVALID
Construct an invalid query.
string str(int value)
Convert int to std::string.
The Xapian namespace contains public interfaces for the Xapian library.
const valueno BAD_VALUENO
Reserved value to indicate "no valueno".
std::string sortable_serialise(double value)
Convert a floating point number to a string, preserving sort order.
static bool decode_xxy(const string &s, int &x1, int &x2, int &y)
unsigned valueno
The number for a value slot in a document.
static bool vet_dm(int d, int m)
static const char max_month_length[12]
static void format_int_fixed_width(char *p, int v, int w)
static void format_yyyymmdd(char *p, int y, int m, int d)
static bool is_yyyy_mm_dd(const string &s)
parsing a user query string to build a Xapian::Query object
Various handy helpers which std::string really should provide.
bool endswith(const std::string &s, char sfx)
bool startswith(const std::string &s, char pfx)