#ifndef RDATA_GENERIC_LOC_29_C
#define RDATA_GENERIC_LOC_29_C
static inline isc_result_t
totext_loc(ARGS_TOTEXT) {
int d1, m1, s1, fs1;
int d2, m2, s2, fs2;
unsigned long latitude;
unsigned long longitude;
unsigned long altitude;
int north;
int east;
int below;
isc_region_t sr;
char buf[sizeof("89 59 59.999 N 179 59 59.999 E "
"42849672.95m 90000000m 90000000m 90000000m")];
char sbuf[sizeof("90000000m")];
char hbuf[sizeof("90000000m")];
char vbuf[sizeof("90000000m")];
unsigned char size, hp, vp;
unsigned long poweroften[8] = { 1, 10, 100, 1000,
10000, 100000, 1000000, 10000000 };
UNUSED(tctx);
REQUIRE(rdata->type == dns_rdatatype_loc);
REQUIRE(rdata->length != 0);
dns_rdata_toregion(rdata, &sr);
if (sr.base[0] != 0)
return (ISC_R_NOTIMPLEMENTED);
REQUIRE(rdata->length == 16);
size = sr.base[1];
INSIST((size&0x0f) < 10 && (size>>4) < 10);
if ((size&0x0f)> 1) {
snprintf(sbuf, sizeof(sbuf),
"%lum", (size>>4) * poweroften[(size&0x0f)-2]);
} else {
snprintf(sbuf, sizeof(sbuf),
"0.%02lum", (size>>4) * poweroften[(size&0x0f)]);
}
hp = sr.base[2];
INSIST((hp&0x0f) < 10 && (hp>>4) < 10);
if ((hp&0x0f)> 1) {
snprintf(hbuf, sizeof(hbuf),
"%lum", (hp>>4) * poweroften[(hp&0x0f)-2]);
} else {
snprintf(hbuf, sizeof(hbuf),
"0.%02lum", (hp>>4) * poweroften[(hp&0x0f)]);
}
vp = sr.base[3];
INSIST((vp&0x0f) < 10 && (vp>>4) < 10);
if ((vp&0x0f)> 1) {
snprintf(vbuf, sizeof(vbuf),
"%lum", (vp>>4) * poweroften[(vp&0x0f)-2]);
} else {
snprintf(vbuf, sizeof(vbuf),
"0.%02lum", (vp>>4) * poweroften[(vp&0x0f)]);
}
isc_region_consume(&sr, 4);
latitude = uint32_fromregion(&sr);
isc_region_consume(&sr, 4);
if (latitude >= 0x80000000) {
north = 1;
latitude -= 0x80000000;
} else {
north = 0;
latitude = 0x80000000 - latitude;
}
fs1 = (int)(latitude % 1000);
latitude /= 1000;
s1 = (int)(latitude % 60);
latitude /= 60;
m1 = (int)(latitude % 60);
latitude /= 60;
d1 = (int)latitude;
INSIST(latitude <= 90U);
longitude = uint32_fromregion(&sr);
isc_region_consume(&sr, 4);
if (longitude >= 0x80000000) {
east = 1;
longitude -= 0x80000000;
} else {
east = 0;
longitude = 0x80000000 - longitude;
}
fs2 = (int)(longitude % 1000);
longitude /= 1000;
s2 = (int)(longitude % 60);
longitude /= 60;
m2 = (int)(longitude % 60);
longitude /= 60;
d2 = (int)longitude;
INSIST(longitude <= 180U);
altitude = uint32_fromregion(&sr);
isc_region_consume(&sr, 4);
if (altitude < 10000000U) {
below = 1;
altitude = 10000000 - altitude;
} else {
below =0;
altitude -= 10000000;
}
snprintf(buf, sizeof(buf),
"%d %d %d.%03d %s %d %d %d.%03d %s %s%lu.%02lum %s %s %s",
d1, m1, s1, fs1, north ? "N" : "S",
d2, m2, s2, fs2, east ? "E" : "W",
below ? "-" : "", altitude/100, altitude % 100,
sbuf, hbuf, vbuf);
return (isc_str_tobuffer(buf, target));
}
static inline isc_result_t
fromwire_loc(ARGS_FROMWIRE) {
isc_region_t sr;
unsigned char c;
unsigned long latitude;
unsigned long longitude;
REQUIRE(type == dns_rdatatype_loc);
UNUSED(type);
UNUSED(rdclass);
UNUSED(dctx);
UNUSED(options);
isc_buffer_activeregion(source, &sr);
if (sr.length < 1)
return (ISC_R_UNEXPECTEDEND);
if (sr.base[0] != 0) {
isc_buffer_forward(source, sr.length);
return (isc_mem_tobuffer(target, sr.base, sr.length));
}
if (sr.length < 16)
return (ISC_R_UNEXPECTEDEND);
c = sr.base[1];
if (c != 0)
if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0)
return (ISC_R_RANGE);
c = sr.base[2];
if (c != 0)
if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0)
return (ISC_R_RANGE);
c = sr.base[3];
if (c != 0)
if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0)
return (ISC_R_RANGE);
isc_region_consume(&sr, 4);
latitude = uint32_fromregion(&sr);
if (latitude < (0x80000000UL - 90 * 3600000) ||
latitude > (0x80000000UL + 90 * 3600000))
return (ISC_R_RANGE);
isc_region_consume(&sr, 4);
longitude = uint32_fromregion(&sr);
if (longitude < (0x80000000UL - 180 * 3600000) ||
longitude > (0x80000000UL + 180 * 3600000))
return (ISC_R_RANGE);
isc_buffer_activeregion(source, &sr);
isc_buffer_forward(source, 16);
return (isc_mem_tobuffer(target, sr.base, 16));
}
static inline isc_result_t
towire_loc(ARGS_TOWIRE) {
UNUSED(cctx);
REQUIRE(rdata->type == dns_rdatatype_loc);
REQUIRE(rdata->length != 0);
return (isc_mem_tobuffer(target, rdata->data, rdata->length));
}
#endif