ruby-changes:28110
From: akr <ko1@a...>
Date: Sat, 6 Apr 2013 23:52:56 +0900 (JST)
Subject: [ruby-changes:28110] akr:r40162 (trunk): * lib/resolv.rb: Support LOC resources.
akr 2013-04-06 23:52:48 +0900 (Sat, 06 Apr 2013) New Revision: 40162 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=40162 Log: * lib/resolv.rb: Support LOC resources. [ruby-core:23361] [Feature #1436] by JB Smith. Modified files: trunk/ChangeLog trunk/NEWS trunk/lib/resolv.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 40161) +++ ChangeLog (revision 40162) @@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sat Apr 6 23:40:40 2013 Tanaka Akira <akr@f...> + + * lib/resolv.rb: Support LOC resources. + [ruby-core:23361] [Feature #1436] by JB Smith. + Sat Apr 6 23:38:09 2013 Naohisa Goto <ngotogenome@g...> * addr2line.c: quad_t and u_quad_t is not available on Solaris. Index: lib/resolv.rb =================================================================== --- lib/resolv.rb (revision 40161) +++ lib/resolv.rb (revision 40162) @@ -1980,6 +1980,97 @@ class Resolv https://github.com/ruby/ruby/blob/trunk/lib/resolv.rb#L1980 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 @@ -1987,7 +2078,7 @@ class Resolv https://github.com/ruby/ruby/blob/trunk/lib/resolv.rb#L2078 end ClassInsensitiveTypes = [ # :nodoc: - NS, CNAME, SOA, PTR, HINFO, MINFO, MX, TXT, ANY + NS, CNAME, SOA, PTR, HINFO, MINFO, MX, TXT, LOC, ANY ] ## @@ -2488,6 +2579,223 @@ class Resolv https://github.com/ruby/ruby/blob/trunk/lib/resolv.rb#L2579 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. Index: NEWS =================================================================== --- NEWS (revision 40161) +++ NEWS (revision 40162) @@ -50,6 +50,7 @@ with all sufficient information, see the https://github.com/ruby/ruby/blob/trunk/NEWS#L50 * New methods: * Resolv::DNS.fetch_resource * One-shot multicast DNS support + * Support LOC resources * Rinda::RingServer, Rinda::RingFinger * Rinda now supports multicast sockets. See Rinda::RingServer and -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/