Skip to content

Commit

Permalink
LOC is now parsed (but wire format is still wrong, I think).
Browse files Browse the repository at this point in the history
  • Loading branch information
tobez committed Apr 29, 2011
1 parent 193800f commit e9cf6b1
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 4 deletions.
129 changes: 125 additions & 4 deletions loc.c
Expand Up @@ -19,21 +19,47 @@
#include "carp.h" #include "carp.h"
#include "rr.h" #include "rr.h"


static uint8_t double2loc_format(double val)
{
if (val > 1000000000) {
return (((uint8_t)(val / 1000000000)) << 4) | 9;
} else if (val > 100000000) {
return (((uint8_t)(val / 100000000)) << 4) | 8;
} else if (val > 10000000) {
return (((uint8_t)(val / 10000000)) << 4) | 7;
} else if (val > 1000000) {
return (((uint8_t)(val / 1000000)) << 4) | 6;
} else if (val > 100000) {
return (((uint8_t)(val / 100000)) << 4) | 5;
} else if (val > 10000) {
return (((uint8_t)(val / 10000)) << 4) | 4;
} else if (val > 1000) {
return (((uint8_t)(val / 1000)) << 4) | 3;
} else if (val > 100) {
return (((uint8_t)(val / 100)) << 4) | 2;
} else if (val > 10) {
return (((uint8_t)(val / 10)) << 4) | 1;
} else {
return (((uint8_t)(val)) << 4);
}

}

static struct rr *loc_parse(char *name, long ttl, int type, char *s) static struct rr *loc_parse(char *name, long ttl, int type, char *s)
{ {
struct rr_loc *rr = getmem(sizeof(*rr)); struct rr_loc *rr = getmem(sizeof(*rr));
long long i; long long i;
int deg; int deg;
int min; int min;
double sec; double sec, val;


/* latitude block */
i = extract_integer(&s, "degrees latitude"); i = extract_integer(&s, "degrees latitude");
if (i < 0) if (i < 0)
return NULL; return NULL;
if (i > 90) if (i > 90)
return bitch("degrees latitude not in the range 0..90"); return bitch("degrees latitude not in the range 0..90");
deg = i; deg = i;

min = 0; min = 0;
sec = 0; sec = 0;
if (isdigit(*s)) { if (isdigit(*s)) {
Expand All @@ -42,10 +68,105 @@ static struct rr *loc_parse(char *name, long ttl, int type, char *s)
return NULL; return NULL;
if (i > 59) if (i > 59)
return bitch("minutes latitude not in the range 0..59"); return bitch("minutes latitude not in the range 0..59");
deg = i; min = i;

if (isdigit(*s)) { /* restricted floating point, starting with a digit */
if (extract_double(&s, "seconds latitude", &sec, 0) < 0)
return NULL;
if (sec < 0 || sec > 59.999)
return bitch("seconds latitude not in the range 0..59.999");
}
}
rr->latitude = sec*1000 + .5 + min*1000*60 + deg*1000*60*60;
if (*s == 'n' || *s == 'N') {
s++;
rr->latitude = 2147483648u + rr->latitude;
} else if (*s == 's' || *s == 'S') {
s++;
rr->latitude = 2147483648u - rr->latitude;
} else {
return bitch("latitude: N or S is expected");
}
if (*s && !isspace(*s) && *s != ';' && *s != ')') {
return bitch("latitude: N or S is expected");
}
s = skip_white_space(s);
if (!s) return NULL;

/* longitude block */
i = extract_integer(&s, "degrees longitude");
if (i < 0)
return NULL;
if (i > 180)
return bitch("degrees longitude not in the range 0..90");
deg = i;
min = 0;
sec = 0;
if (isdigit(*s)) {
i = extract_integer(&s, "minutes longitude");
if (i < 0)
return NULL;
if (i > 59)
return bitch("minutes longitude not in the range 0..59");
min = i;

if (isdigit(*s)) { /* restricted floating point, starting with a digit */
if (extract_double(&s, "seconds longitude", &sec, 0) < 0)
return NULL;
if (sec < 0 || sec > 59.999)
return bitch("seconds longitude not in the range 0..59.999");
}
}
rr->longitude = sec*1000 + .5 + min*1000*60 + deg*1000*60*60;
if (*s == 'e' || *s == 'E') {
s++;
rr->longitude = 2147483648u + rr->longitude;
} else if (*s == 'w' || *s == 'W') {
s++;
rr->longitude = 2147483648u - rr->latitude;
} else {
return bitch("longitude: E or W is expected");
}
if (*s && !isspace(*s) && *s != ';' && *s != ')') {
return bitch("longitude: E or W is expected");
}
s = skip_white_space(s);
if (!s) return NULL;

if (extract_double(&s, "altitude", &val, 1) < 0)
return NULL;
if (val < -100000.00 || val > 42849672.95)
return bitch("altitude is out of supported range");
rr->altitude = (val + 100000.00) * 100 + 0.5;

if (*s) {
if (extract_double(&s, "sphere size", &val, 1) < 0)
return NULL;
if (val < 0 || val > 90000000.00)
return bitch("sphere size is out of supported range");
rr->size = double2loc_format(val * 100 + 0.5);

if (*s) {
if (extract_double(&s, "horizontal precision", &val, 1) < 0)
return NULL;
if (val < 0 || val > 90000000.00)
return bitch("horizontal precision is out of supported range");
rr->horiz_pre = double2loc_format(val * 100 + 0.5);


if (isdigit(*s)) { if (*s) {
if (extract_double(&s, "vertical precision", &val, 1) < 0)
return NULL;
if (val < 0 || val > 90000000.00)
return bitch("vertical precision is out of supported range");
rr->vert_pre = double2loc_format(val * 100 + 0.5);
} else {
rr->vert_pre = double2loc_format(10 * 100 + 0.5);
}
} else {
rr->horiz_pre = double2loc_format(10000 * 100 + 0.5);
} }
} else {
rr->size = double2loc_format(1 * 100 + 0.5);
} }


if (*s) { if (*s) {
Expand Down
47 changes: 47 additions & 0 deletions textparse.c
Expand Up @@ -307,6 +307,53 @@ long long extract_integer(char **input, char *what)
return r; return r;
} }


int extract_double(char **input, char *what, double *val, int skip_m)
{
char *s = *input;
char *end = NULL;
char *stop;
char c;
int saw_m = 0;

while (isdigit(*s) || *s == '+' || *s == '-' || *s == '.')
s++;
if (*s && !isspace(*s) && *s != ';' && *s != ')') {
if (skip_m && (*s == 'm' || *s == 'M')) {
saw_m = 1;
} else {
bitch("%s is not valid", what);
return -1;
}
}
if (!*s) end = s;
c = *s;
*s = '\0';
*val = strtod(*input, &stop);
if (*stop != '\0') {
*s = c;
bitch("%s is not valid", what);
return -1;
}
*s = c;

if (saw_m) {
s++;
if (*s && !isspace(*s) && *s != ';' && *s != ')') {
bitch("%s is not valid", what);
return -1;
}
}

if (end) {
*input = end;
} else {
*input = skip_white_space(s);
if (!*input)
return -1; /* bitching's done elsewhere */
}
return 1;
}

long extract_timevalue(char **input, char *what) long extract_timevalue(char **input, char *what)
{ {
char *s = *input; char *s = *input;
Expand Down
1 change: 1 addition & 0 deletions textparse.h
Expand Up @@ -39,6 +39,7 @@ long extract_timevalue(char **input, char *what);
long long extract_timestamp(char **input, char *what); long long extract_timestamp(char **input, char *what);
int extract_ipv4(char **input, char *what, struct in_addr *addr); int extract_ipv4(char **input, char *what, struct in_addr *addr);
int extract_ipv6(char **input, char *what, struct in6_addr *addr); int extract_ipv6(char **input, char *what, struct in6_addr *addr);
int extract_double(char **input, char *what, double *val, int skip_m);
struct binary_data extract_base32hex_binary_data(char **input, char *what); struct binary_data extract_base32hex_binary_data(char **input, char *what);
struct binary_data extract_base64_binary_data(char **input, char *what); struct binary_data extract_base64_binary_data(char **input, char *what);
struct binary_data extract_text(char **input, char *what); struct binary_data extract_text(char **input, char *what);
Expand Down

0 comments on commit e9cf6b1

Please sign in to comment.