[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]