26 #ifdef HAVE_STD_FROM_CHARS_DOUBLE
46 if (s.size() < 5 || s.size() > 10)
return false;
47 const char*
p = s.c_str();
51 x1 = x1 * 10 + (*
p++ -
'0');
53 if (x1 < 1 || x1 > 31)
return false;
55 if (sep !=
'/' && sep !=
'-' && sep !=
'.')
return false;
59 x2 = x2 * 10 + (*
p++ -
'0');
61 if (x2 < 1 || x2 > 31)
return false;
62 if (*
p++ != sep)
return false;
63 if (s.size() - (
p - s.c_str()) > 4)
return false;
66 y = y * 10 + (*
p++ -
'0');
68 return size_t(
p - s.c_str()) == s.size();
76 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
82 if (m == -1)
return true;
83 if (m > 12 || m < 1)
return false;
92 return (s.find_first_not_of(
"0123456789") == 4 &&
93 s.find_first_not_of(
"0123456789", 5) == 7 &&
94 s.find_first_not_of(
"0123456789", 8) == string::npos &&
96 (s[4] ==
'-' || s[4] ==
'.' || s[4] ==
'/'));
109 p[w] =
'0' + (v % 10);
123 RangeProcessor::check_range(
const string& b,
const string& e)
126 return operator()(b, e);
128 size_t off_b = 0, len_b = string::npos;
129 size_t off_e = 0, len_e = string::npos;
134 if (repeated && prefix && b.empty()) {
140 }
else if (repeated && !prefix && e.empty()) {
145 len_b = b.size() -
str.size();
163 len_e = e.size() -
str.size();
166 len_b = b.size() -
str.size();
170 return operator()(
string(b, off_b, len_b),
string(e, off_e, len_e));
177 RangeProcessor::operator()(
const string& b,
const string& e)
185 DateRangeProcessor::operator()(
const string& b,
const string& e)
187 if ((b.size() == 8 || b.size() == 0) &&
188 (e.size() == 8 || e.size() == 0) &&
189 b.find_first_not_of(
"0123456789") == string::npos &&
190 e.find_first_not_of(
"0123456789") == string::npos) {
192 return RangeProcessor::operator()(b, e);
194 if ((b.size() == 10 || b.size() == 0) &&
195 (e.size() == 10 || e.size() == 0)) {
198 string begin = b, end = e;
200 if (!begin.empty()) {
208 return RangeProcessor::operator()(begin, end);
220 if (!prefer_mdy &&
vet_dm(b_d, b_m) &&
vet_dm(e_d, e_m) &&
221 (b_y != e_y || b_m < e_m || (b_m == e_m && b_d <= e_d))) {
224 (b_y != e_y || b_d < e_d || (b_d == e_d && b_m <= e_m))) {
227 }
else if (prefer_mdy &&
vet_dm(b_d, b_m) &&
vet_dm(e_d, e_m) &&
228 (b_y != e_y || b_m < e_m || (b_m == e_m && b_d <= e_d))) {
235 char buf_b[8], buf_e[8];
236 size_t len_b = 0, len_e = 0;
240 if (b_y < epoch_year) b_y += 100;
248 if (e_y < epoch_year) e_y += 100;
253 return RangeProcessor::operator()(
string(buf_b, len_b),
254 string(buf_e, len_e));
262 NumberRangeProcessor::operator()(
const string& b,
const string& e)
268 #ifdef HAVE_STD_FROM_CHARS_DOUBLE
269 const char* startptr = b.data();
270 const char* endptr = startptr + b.size();
271 const auto& r = from_chars(startptr, endptr, num_b);
272 if (r.ec != std::errc() || r.ptr != endptr) {
278 const char * startptr = b.c_str();
280 num_b = strtod(startptr, &endptr);
281 if (endptr != startptr + b.size() || errno) {
292 #ifdef HAVE_STD_FROM_CHARS_DOUBLE
293 const char* startptr = e.data();
294 const char* endptr = startptr + e.size();
295 const auto& r = from_chars(startptr, endptr, num_e);
296 if (r.ec != std::errc() || r.ptr != endptr) {
302 const char * startptr = e.c_str();
304 num_e = strtod(startptr, &endptr);
305 if (endptr != startptr + e.size() || errno) {
315 return RangeProcessor::operator()(
333 for (
int i = 0; i < 4; ++i) {
344 UnitRangeProcessor::operator()(
const string& b,
const string& e)
350 bool b_has_unit =
false;
353 #ifdef HAVE_STD_FROM_CHARS_DOUBLE
354 const char* startptr = b.data();
355 const char* endptr = startptr + b.size();
356 const auto& r = from_chars(startptr, endptr, num_b);
357 if (r.ec != std::errc()) {
364 const char * startptr = b.c_str();
366 num_b = strtod(startptr, &endptr);
375 if (endptr == startptr + b.size() - 1) {
377 if (factor_b == -1) {
390 #ifdef HAVE_STD_FROM_CHARS_DOUBLE
391 const char* startptr = e.data();
392 const char* endptr = startptr + e.size();
393 const auto& r = from_chars(startptr, endptr, num_e);
394 if (r.ec != std::errc()) {
401 const char * startptr = e.c_str();
403 num_e = strtod(startptr, &endptr);
412 if (endptr == startptr + e.size() - 1) {
414 if (factor_e == -1) {
422 if (!b.empty() && !b_has_unit) {
435 if (!b.empty() && !b_has_unit) {
440 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.
std::string sortable_serialise(double value)
Convert a floating point number to a string, preserving sort order.
static const char byte_units[4][2]
static bool decode_xxy(const string &s, int &x1, int &x2, int &y)
static double check_byte_unit(const string &s)
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 string-related helpers.
bool endswith(std::string_view s, char sfx)
bool startswith(std::string_view s, char pfx)