def initialize(hostname)
hostname.is_a?(String) or
(hostname.respond_to?(:to_str) && (hostname = hostname.to_str).is_a?(String)) or
raise TypeError, "#{hostname.class} is not a String"
if hostname.start_with?(DOT)
raise ArgumentError, "domain name must not start with a dot: #{hostname}"
end
case hostname
when /\A([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\z/
@ipaddr = IPAddr.new($1)
@uri_host = @hostname = @ipaddr.to_s
@domain = @tld = nil
return
when /\A([0-9A-Fa-f:]*:[0-9A-Fa-f:]*:[0-9A-Fa-f:]*)\z/,
/\A\[([0-9A-Fa-f:]*:[0-9A-Fa-f:]*:[0-9A-Fa-f:]*)\]\z/
@ipaddr = IPAddr.new($1)
@hostname = @ipaddr.to_s
@uri_host = "[#{@hostname}]"
@domain = @tld = nil
return
end
@ipaddr = nil
@hostname = DomainName.normalize(hostname)
@uri_host = @hostname
if last_dot = @hostname.rindex(DOT)
@tld = @hostname[(last_dot + 1)..-1]
else
@tld = @hostname
end
etld_data = DomainName.etld_data
if @canonical_tld_p = etld_data.key?(@tld)
subdomain = domain = nil
parent = @hostname
loop {
case etld_data[parent]
when 0
@domain = domain if domain
return
when -1
@domain = subdomain if subdomain
return
when 1
@domain = parent
return
end
subdomain = domain
domain = parent
pos = @hostname.index(DOT, -domain.length) or break
parent = @hostname[(pos + 1)..-1]
}
else
if last_dot
if penultimate_dot = @hostname.rindex(DOT, last_dot - 1)
@domain = @hostname[(penultimate_dot + 1)..-1]
else
@domain = @hostname
end
else
@domain = @tld
end
end
end