Skip to content
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

Compute LOC text representation without using floating point for latitude and longitude #15221

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 35 additions & 9 deletions pdns/sillyrecords.cc
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,6 @@ string LOCRecordContent::getZoneRepresentation(bool /* noDot */) const
// convert d_version, d_size, d_horiz/vertpre, d_latitude, d_longitude, d_altitude to:
// 51 59 00.000 N 5 55 00.000 E 4.00m 1.00m 10000.00m 10.00m

double latitude= ((int32_t)((uint32_t)d_latitude - ((uint32_t)1<<31)))/3600000.0;
double longitude=((int32_t)((uint32_t)d_longitude - ((uint32_t)1<<31)))/3600000.0;
double altitude= ((int32_t)d_altitude )/100.0 - 100000;

double size=0.01*((d_size>>4)&0xf);
Expand All @@ -320,15 +318,43 @@ string LOCRecordContent::getZoneRepresentation(bool /* noDot */) const
while(count--)
vertpre*=10;

double remlat=60.0*(latitude-(int)latitude);
double remlong=60.0*(longitude-(int)longitude);
static const boost::format fmt("%d %d %2.03f %c %d %d %2.03f %c %.2fm %.2fm %.2fm %.2fm");
char hemLat = 'N';
uint32_t lat = d_latitude;
if (lat >= 1U << 31) {
lat -= 1U << 31;
}
else {
hemLat = 'S';
lat = (1U << 31) - lat;
}
auto fracLat = lat % 1000;
lat /= 1000;
auto secLat = lat % 60;
lat /= 60;
auto minutesLat = lat % 60;
auto degreesLat = lat / 60;

char hemLon= 'E';
uint32_t lon = d_longitude;
if (lon >= 1U << 31) {
lon -= 1U << 31;
}
else {
hemLon = 'W';
lon = (1U << 31) - lon;
}
auto fracLon = lon % 1000;
lon /= 1000;
auto secLon = lon % 60;
lon /= 60;
auto minutesLon = lon % 60;
auto degreesLon = lon / 60;

static const boost::format fmt("%d %d %d.%03d %c %d %d %d.%03d %c %.2fm %.2fm %.2fm %.2fm");
std::string ret = boost::str(
boost::format(fmt)
% abs((int)latitude) % abs((int) ((latitude-(int)latitude)*60))
% fabs((double)((remlat-(int)remlat)*60.0)) % (latitude>0 ? 'N' : 'S')
% abs((int)longitude) % abs((int) ((longitude-(int)longitude)*60))
% fabs((double)((remlong-(int)remlong)*60.0)) % (longitude>0 ? 'E' : 'W')
% degreesLat % minutesLat % secLat % fracLat % hemLat
% degreesLon % minutesLon % secLon % fracLon % hemLon
% altitude % size
% horizpre % vertpre
);
Expand Down
6 changes: 6 additions & 0 deletions pdns/test-dnsrecords_cc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,13 @@ BOOST_AUTO_TEST_CASE(test_record_types) {
(CASE_L(QType::LOC, "32 7 19 S 116 2 25 E 10m", "32 7 19.000 S 116 2 25.000 E 10.00m 1.00m 10000.00m 10.00m", "\x00\x12\x16\x13\x79\x1b\x7d\x28\x98\xe6\x48\x68\x00\x98\x9a\x68"))
(CASE_L(QType::LOC, "42 21 54 N 71 06 18 W -24m 30m", "42 21 54.000 N 71 6 18.000 W -24.00m 30.00m 10000.00m 10.00m", "\x00\x33\x16\x13\x89\x17\x2d\xd0\x70\xbe\x15\xf0\x00\x98\x8d\x20"))
(CASE_L(QType::LOC, "42 21 43.952 N 71 5 6.344 W -24m 1m 200m", "42 21 43.952 N 71 5 6.344 W -24.00m 1.00m 200.00m 10.00m", "\x00\x12\x24\x13\x89\x17\x06\x90\x70\xbf\x2d\xd8\x00\x98\x8d\x20"))
(CASE_L(QType::LOC, "57 9 0.000 N 2 7 9.998 W 0.00m 0.00m 0.00m 0.00m", "57 9 0.000 N 2 7 9.998 W 0.00m 0.00m 0.00m 0.00m", "\x00\x00\x00\x00\x8c\x43\x57\xe0\x7f\x8b\x93\x52\x00\x98\x96\x80"))
(CASE_L(QType::LOC, "57 8 59.999 N 2 7 9.998 W 0.00m 0.00m 0.00m 0.00m", "57 8 59.999 N 2 7 9.998 W 0.00m 0.00m 0.00m 0.00m", "\x00\x00\x00\x00\x8c\x43\x57\xdf\x7f\x8b\x93\x52\x00\x98\x96\x80"))
// local name
(CASE_L(QType::LOC, "51 11 60.000 N 2 12 5.080 W 0.00m 0.00m 0.00m 0.00m", "51 12 0.000 N 2 12 5.080 W 0.00m 0.00m 0.00m 0.00m", "\x00\x00\x00\x00\x8a\xfc\x80\x00\x7f\x87\x12\xa8\x00\x98\x96\x80"))
(CASE_L(QType::LOC, "51 11 59.999 N 2 12 5.080 W 0.00m 0.00m 0.00m 0.00m", "51 11 59.999 N 2 12 5.080 W 0.00m 0.00m 0.00m 0.00m", "\x00\x00\x00\x00\x8a\xfc\x7f\xff\x7f\x87\x12\xa8\x00\x98\x96\x80"))
(CASE_L(QType::LOC, "49 18 0.000 N 10 35 0.000 E 409.00m 1.00m 10000.00m 10.00m", "49 18 0.000 N 10 35 0.000 E 409.00m 1.00m 10000.00m 10.00m", "\x00\x12\x16\x13\x8a\x94\x21\x40\x82\x45\x5c\x20\x00\x99\x36\x44"))
(CASE_L(QType::LOC, "49 18 0.000 S 10 35 0.000 W 409.00m 1.00m 10000.00m 10.00m", "49 18 0.000 S 10 35 0.000 W 409.00m 1.00m 10000.00m 10.00m", "\x00\x12\x16\x13\x75\x6b\xde\xc0\x7d\xba\xa3\xe0\x00\x99\x36\x44"))
(CASE_S(QType::SRV, "10 10 5060 sip.rec.test.", "\x00\x0a\x00\x0a\x13\xc4\x03sip\x03rec\x04test\x00"))
// non-local name
(CASE_S(QType::SRV, "10 10 5060 sip.example.com.", "\x00\x0a\x00\x0a\x13\xc4\x03sip\x07""example\x03""com\x00"))
Expand Down
Loading