-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add date field check #169
Add date field check #169
Changes from all commits
83cd13f
d2d435e
0f5bb8d
6395bd0
bf1a586
671cbd3
86dabc8
0e83bc4
5e92646
5424f22
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,9 @@ | |
#include "field.h" | ||
#include "predicates.h" | ||
|
||
bool warden_field_bool(char *buf, size_t n) { | ||
/* Returns TRUE if the buffer we're passed contains a bool, otherwise | ||
* FALSE. */ | ||
bool warden_field_bool(const char *buf, size_t n) { | ||
/* little-endian "false" */ | ||
static const int64_t false_bits = 0x00000065736c6166; | ||
static const int64_t false_mask = 0x000000ffffffffff; | ||
|
@@ -48,7 +50,7 @@ bool warden_field_bool(char *buf, size_t n) { | |
in scientific notation. | ||
|
||
Otherwise returns non_numeric_field. */ | ||
numeric_field warden_field_numeric(char *buf, size_t n) { | ||
numeric_field warden_field_numeric(const char *buf, size_t n) { | ||
size_t i = 0; | ||
int preradix_digits = 0; /* digits before the radix point */ | ||
int exponent_digits = 0; /* digits in the exponent (scientific notation) */ | ||
|
@@ -114,3 +116,63 @@ numeric_field warden_field_numeric(char *buf, size_t n) { | |
/* just cruft on the end after all */ | ||
return non_numeric_field; | ||
} | ||
|
||
|
||
static inline bool is_separator(char c) { | ||
return (c == '-' || c == '/' || c == '.'); | ||
} | ||
|
||
/* Match a year in the 20xx century, in big-endian date format with or | ||
without separators. */ | ||
static inline bool match_ymd(const char *buf, size_t n) { | ||
/* The shortest thing we're willing to call a "date" at this | ||
point is YYYYMMDD. */ | ||
if (n < 8) { | ||
return FALSE; | ||
} | ||
|
||
/* 0xc0 = 0x80 | 0x40 - if these bits are set, the byte is too | ||
high to be a digit or a separator. */ | ||
static const int64_t ymd_mask = 0xc0c0c0c0c0c0ffff; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This code assumes little endian. Wondering if it might not be a good idea to make it a compile error if someone compiles on a big endian system. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is a good idea, will work out how to do that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Linux has <endian.h>. In C projects it usually done with an autoconf On Tue, Jul 19, 2016 at 12:33 PM, Sharif Olorin [email protected]
|
||
/* No 0x80 or 0x40 set anywhere, and the first two bytes must | ||
be "20". */ | ||
static const int64_t ymd_bits = 0x0000000000003032; | ||
int64_t *p = (int64_t *) buf; | ||
|
||
/* First, we drop everything which doesn't start with '20' and | ||
have eight bytes compatible with a YYYYxMMxDD format. */ | ||
if (!(((*p & ymd_mask) == ymd_bits) && is_digit(buf[2]) && is_digit(buf[3]))) { | ||
return FALSE; | ||
} | ||
|
||
/* YYYY-MM-DD */ | ||
if (is_separator(buf[4])) { | ||
return (n >= 10 && | ||
is_digit(buf[5]) && | ||
is_digit(buf[6]) && | ||
is_separator(buf[7]) && | ||
is_digit(buf[8]) && | ||
is_digit(buf[9])); | ||
} | ||
|
||
/* YYYYMMDD */ | ||
return (is_digit(buf[4]) && | ||
is_digit(buf[5]) && | ||
is_digit(buf[6]) && | ||
is_digit(buf[7])); | ||
|
||
} | ||
|
||
/* Returns TRUE if the data in the buffer looks like a date, otherwise | ||
FALSE. | ||
|
||
Currently checks: | ||
|
||
- Fields beginning with big-endian dates. | ||
|
||
FIXME: more supported date formats | ||
*/ | ||
bool warden_field_datetime(const char *buf, size_t n) { | ||
return match_ymd(buf, n); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably want to make that
const char * buf
unless you intend to modify it.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, thanks.