Feature #1436

Please consider this addition to resolv.rb which adds methods for resolving LOC resources

Added by JB Smith almost 5 years ago. Updated about 1 year ago.

[ruby-core:23361]
Status:Closed
Priority:Normal
Assignee:Akira Tanaka
Category:core
Target version:next minor

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

Associated revisions

Revision 40162
Added by Akira Tanaka about 1 year ago

  • lib/resolv.rb: Support LOC resources. [Feature #1436] by JB Smith.

History

#1 Updated by Akira Tanaka almost 5 years ago

  • Assignee set to Akira Tanaka

=begin

=end

#2 Updated by Yuki Sonoda almost 5 years ago

  • Target version set to 2.0.0

=begin

=end

#3 Updated by Yusuke Endoh about 4 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

#4 Updated by Shyouhei Urabe over 3 years ago

  • Status changed from Open to Assigned

=begin

=end

#5 Updated by Yusuke Endoh about 2 years ago

Hello, akr

Any update here?

Yusuke Endoh mame@tsg.ne.jp

#6 Updated by Akira Tanaka over 1 year ago

  • Target version changed from 2.0.0 to next minor

#7 Updated by Akira Tanaka about 1 year 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. [Feature #1436] by JB Smith.

Also available in: Atom PDF