Actions
Feature #1436
closedPlease consider this addition to resolv.rb which adds methods for resolving LOC resources
Description
=begin
Please consider this diff which would add support to resolv.rb to permit parsing of LOC resources.
I would welcome any criticism or guidance that would make this more suitable for inclusion.
Regards,
JB Smith
Index: lib/resolv.rb¶
--- lib/resolv.rb (revision 23349)
+++ lib/resolv.rb (working copy)
@@ -1835,6 +1835,97 @@
end
##
-
# Location resource
-
class LOC < Resource
-
TypeValue = 29 # :nodoc:
-
def initialize(version, ssize, hprecision, vprecision, latitude, longitude, altitude)
-
@version = version
-
@ssize = Resolv::LOC::Size.create(ssize)
-
@hprecision = Resolv::LOC::Size.create(hprecision)
-
@vprecision = Resolv::LOC::Size.create(vprecision)
-
@latitude = Resolv::LOC::Coord.create(latitude)
-
@longitude = Resolv::LOC::Coord.create(longitude)
-
@altitude = Resolv::LOC::Alt.create(altitude)
-
end
-
##
-
# Returns the version value for this LOC record which should always be 00
-
attr_reader :version
-
##
-
# The spherical size of this LOC
-
# in meters using scientific notation as 2 integers of XeY
-
attr_reader :ssize
-
##
-
# The horizontal precision using ssize type values
-
# in meters using scientific notation as 2 integers of XeY
-
# for precision use value/2 e.g. 2m = +/-1m
-
attr_reader :hprecision
-
##
-
# The vertical precision using ssize type values
-
# in meters using scientific notation as 2 integers of XeY
-
# for precision use value/2 e.g. 2m = +/-1m
-
attr_reader :vprecision
-
##
-
# The latitude for this LOC where 2**31 is the equator
-
# in thousandths of an arc second as an unsigned 32bit integer
-
attr_reader :latitude
-
##
-
# The longitude for this LOC where 2**31 is the prime meridian
-
# in thousandths of an arc second as an unsigned 32bit integer
-
attr_reader :longitude
-
##
-
# The altitude of the LOC above a reference sphere whose surface sits 100km below the WGS84 spheroid
-
# in centimeters as an unsigned 32bit integer
-
attr_reader :altitude
-
def encode_rdata(msg) # :nodoc:
-
msg.put_bytes(@version)
-
msg.put_bytes(@ssize.scalar)
-
msg.put_bytes(@hprecision.scalar)
-
msg.put_bytes(@vprecision.scalar)
-
msg.put_bytes(@latitude.coordinates)
-
msg.put_bytes(@longitude.coordinates)
-
msg.put_bytes(@altitude.altitude)
-
end
-
def self.decode_rdata(msg) # :nodoc:
-
version = msg.get_bytes(1)
-
ssize = msg.get_bytes(1)
-
hprecision = msg.get_bytes(1)
-
vprecision = msg.get_bytes(1)
-
latitude = msg.get_bytes(4)
-
longitude = msg.get_bytes(4)
-
altitude = msg.get_bytes(4)
-
return self.new(
-
version,
-
Resolv::LOC::Size.new(ssize),
-
Resolv::LOC::Size.new(hprecision),
-
Resolv::LOC::Size.new(vprecision),
-
Resolv::LOC::Coord.new(latitude,"lat"),
-
Resolv::LOC::Coord.new(longitude,"lon"),
-
Resolv::LOC::Alt.new(altitude)
-
)
-
end
-
end
-
## # A Query type requesting any RR. class ANY < Query
@@ -1842,7 +1933,7 @@
end
ClassInsensitiveTypes = [ # :nodoc:
-
NS, CNAME, SOA, PTR, HINFO, MINFO, MX, TXT, ANY
-
NS, CNAME, SOA, PTR, HINFO, MINFO, MX, TXT, LOC, ANY ] ##
@@ -2260,6 +2351,223 @@
end
end
- module LOC
-
A Resolv::LOC::Size¶
- class Size
-
Regex = /^(\d+\.*\d*)[m]$/
-
##
-
# Creates a new LOC::Size from +arg+ which may be:
-
#
-
# LOC::Size:: returns +arg+.
-
# String:: +arg+ must match the LOC::Size::Regex constant
-
def self.create(arg)
-
case arg
-
when Size
-
return arg
-
when String
-
scalar = ''
-
if Regex =~ arg
-
scalar = [(($1.to_f*(1e2)).to_i.to_s[0].to_i*(2**4)+(($1.to_f*(1e2)).to_i.to_s.length-1))].pack("C")
-
else
-
raise ArgumentError.new("not a properly formed Size string: " + arg)
-
end
-
return Size.new(scalar)
-
else
-
raise ArgumentError.new("cannot interpret as Size: #{arg.inspect}")
-
end
-
end
-
def initialize(scalar)
-
@scalar = scalar
-
end
-
##
-
# The raw size
-
attr_reader :scalar
-
def to_s # :nodoc:
-
s = @scalar.unpack("H2").join.to_s
-
return ((s[0].to_i)*(10**(s[1].to_i-2))).to_s << "m"
-
end
-
def inspect # :nodoc:
-
return "#<#{self.class} #{self.to_s}>"
-
end
-
def ==(other) # :nodoc:
-
return @scalar == other.scalar
-
end
-
def eql?(other) # :nodoc:
-
return self == other
-
end
-
def hash # :nodoc:
-
return @scalar.hash
-
end
- end
-
A Resolv::LOC::Coord¶
- class Coord
-
Regex = /^(\d+)\s(\d+)\s(\d+\.\d+)\s([NESW])$/
-
##
-
# Creates a new LOC::Coord from +arg+ which may be:
-
#
-
# LOC::Coord:: returns +arg+.
-
# String:: +arg+ must match the LOC::Coord::Regex constant
-
def self.create(arg)
-
case arg
-
when Coord
-
return arg
-
when String
-
coordinates = ''
-
if Regex =~ arg && $1<180
-
hemi = ($4[/([NE])/,1]) || ($4[/([SW])/,1]) ? 1 : -1
-
coordinates = [(($1.to_i*(36e5))+($2.to_i*(6e4))+($3.to_f*(1e3)))*hemi+(2**31)].pack("N")
-
(orientation ||= '') << $4[[/NS/],1] ? 'lat' : 'lon'
-
else
-
raise ArgumentError.new("not a properly formed Coord string: " + arg)
-
end
-
return Coord.new(coordinates,orientation)
-
else
-
raise ArgumentError.new("cannot interpret as Coord: #{arg.inspect}")
-
end
-
end
-
def initialize(coordinates,orientation)
-
unless coordinates.kind_of?(String)
-
raise ArgumentError.new("Coord must be a 32bit unsigned integer in hex format: #{coordinates.inspect}")
-
end
-
unless orientation.kind_of?(String) && orientation[/^lon$|^lat$/]
-
raise ArgumentError.new('Coord expects orientation to be a String argument of "lat" or "lon"')
-
end
-
@coordinates = coordinates
-
@orientation = orientation
-
end
-
##
-
# The raw coordinates
-
attr_reader :coordinates
-
## The orientation of the hemisphere as 'lat' or 'lon'
-
attr_reader :orientation
-
def to_s # :nodoc:
-
c = @coordinates.unpack("N").join.to_i
-
val = (c - (2**31)).abs
-
fracsecs = (val % 1e3).to_i.to_s
-
val = val / 1e3
-
secs = (val % 60).to_i.to_s
-
val = val / 60
-
mins = (val % 60).to_i.to_s
-
degs = (val / 60).to_i.to_s
-
posi = (c >= 2**31)
-
case posi
-
when true
-
hemi = @orientation[/^lat$/] ? "N" : "E"
-
else
-
hemi = @orientation[/^lon$/] ? "W" : "S"
-
end
-
return degs << " " << mins << " " << secs << "." << fracsecs << " " << hemi
-
end
-
def inspect # :nodoc:
-
return "#<#{self.class} #{self.to_s}>"
-
end
-
def ==(other) # :nodoc:
-
return @coordinates == other.coordinates
-
end
-
def eql?(other) # :nodoc:
-
return self == other
-
end
-
def hash # :nodoc:
-
return @coordinates.hash
-
end
- end
-
A Resolv::LOC::Alt¶
- class Alt
-
Regex = /^([+-]*\d+\.*\d*)[m]$/
-
##
-
# Creates a new LOC::Alt from +arg+ which may be:
-
#
-
# LOC::Alt:: returns +arg+.
-
# String:: +arg+ must match the LOC::Alt::Regex constant
-
def self.create(arg)
-
case arg
-
when Alt
-
return arg
-
when String
-
altitude = ''
-
if Regex =~ arg
-
altitude = [($1.to_f*(1e2))+(1e7)].pack("N")
-
else
-
raise ArgumentError.new("not a properly formed Alt string: " + arg)
-
end
-
return Alt.new(altitude)
-
else
-
raise ArgumentError.new("cannot interpret as Alt: #{arg.inspect}")
-
end
-
end
-
def initialize(altitude)
-
@altitude = altitude
-
end
-
##
-
# The raw altitude
-
attr_reader :altitude
-
def to_s # :nodoc:
-
a = @altitude.unpack("N").join.to_i
-
return ((a.to_f/1e2)-1e5).to_s + "m"
-
end
-
def inspect # :nodoc:
-
return "#<#{self.class} #{self.to_s}>"
-
end
-
def ==(other) # :nodoc:
-
return @altitude == other.altitude
-
end
-
def eql?(other) # :nodoc:
-
return self == other
-
end
-
def hash # :nodoc:
-
return @altitude.hash
-
end
- end
- end
-
Default resolver to use for Resolv class methods.¶
=end
Actions
Like0
Like0Like0Like0Like0Like0Like0Like0