Project

General

Profile

Actions

Feature #1436

closed

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

Added by jabo (JB Smith) almost 15 years ago. Updated almost 11 years ago.

Status:
Closed
Target version:
[ruby-core:23361]

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

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0