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
Updated by mame (Yusuke Endoh) over 14 years ago
=begin
Hi, akr
2009/5/6 JB Smith redmine@ruby-lang.org:
Please consider this diff which would add support to resolv.rb to permit parsing of LOC resources.
What do you think about this proposal?
I'm not familiar with both resolv.rb and the proposed feature, but
I feel the patch is innocent; it seems just to add a feature.
Let us know current status or reason why the ticket is left, if any.
--
Yusuke ENDOH mame@tsg.ne.jp
=end
Updated by shyouhei (Shyouhei Urabe) about 14 years ago
- Status changed from Open to Assigned
=begin
=end
Updated by mame (Yusuke Endoh) almost 13 years ago
Updated by akr (Akira Tanaka) about 12 years ago
- Target version changed from 2.0.0 to 2.6
Updated by akr (Akira Tanaka) over 11 years ago
- Status changed from Assigned to Closed
- % Done changed from 0 to 100
This issue was solved with changeset r40162.
JB, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.
- lib/resolv.rb: Support LOC resources.
[ruby-core:23361] [Feature #1436] by JB Smith.