lib/iana/protocol.rb

Summary

Maintainability
A
35 mins
Test Coverage
#!/usr/bin/env ruby
# encoding: UTF-8
# vim: expandtab tabstop=2 softtabstop=2 shiftwidth=2

# lib/iana/protocol.rb

# rubygems
require 'nokogiri'

module IANA
  class Protocol
    SOURCE = "http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml"

    attr_reader :protocol, :name, :description, :references

    def initialize(protocol, name, description, xref)
      @protocol, @name, @description, @references = protocol, name, description, xref
    end

    def protocol; @protocol; end
    def number; @protocol; end
    def name; @name; end
    def description; @description; end
    def references; @references; end

    def self.source
      @source ||= open(SOURCE).read
    end

    # Download IANA protocols list in XML format, return list
    # http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml
    def self.iana_list
      protocols = {}
      begin
        doc = Nokogiri::XML(source)
        doc.css('registry/registry/record').each do |r|
          value = r.css('value').text

          low,high = value.split('-').map(&:to_i)
          high ||= low

          name = r.css('name').text
          name = nil if !name.nil? && name.empty?

          description = r.css('description').text
          description = nil if !description.nil? && description.empty?

          # references
          xref = r.css('xref').collect {|ref| ref['data'] }.compact

          # create an entry for each range element
          (high-low+1).times do |i|
            protocols[low+i] = Protocol.new(low+i, name, description, xref)
          end
        end
      end
      return protocols
    end

    # Look up protocol definition in iana_list
    def self.[](arg)
      raise ArgumentError, 'protocol number must be an Fixnum' if arg.class != Fixnum
      iana_list[arg]
    end
  end
end

raise RuntimeError, 'This library is for require only' if $0 == __FILE__