def parse(s)
address_list = AddressListStruct.new([],[])
if Mail::Utilities.blank?(s)
return address_list
end
actions, error = Ragel.parse(:address_lists, s)
if error
raise Mail::Field::ParseError.new(Mail::AddressList, s, error)
end
phrase_s = phrase_e = qstr_s = qstr = comment_s = nil
group_name_s = domain_s = group_name = nil
local_dot_atom_s = local_dot_atom_e = nil
local_dot_atom_pre_comment_e = nil
obs_domain_list_s = nil
address_s = 0
address = AddressStruct.new(nil, nil, [], nil, nil, nil, nil)
actions.each_slice(2) do |action_id, p|
action = Mail::Parsers::Ragel::ACTIONS[action_id]
case action
when :phrase_s then phrase_s = p
when :phrase_e then phrase_e = p-1
when :qstr_s then qstr_s = p
when :qstr_e then qstr = s[qstr_s..(p-1)]
when :comment_s
comment_s = p unless comment_s
when :comment_e
if address
address.comments << s[comment_s..(p-2)]
end
comment_s = nil
when :group_name_s then group_name_s = p
when :group_name_e
if qstr
group = qstr
qstr = nil
else
group = s[group_name_s..(p-1)]
group_name_s = nil
end
address_list.group_names << group
group_name = group
address = AddressStruct.new(nil, nil, [], nil, nil, nil, nil)
address_s = p
address.group = group_name
when :address_s
address_s = p
when :address_e
next if address_s.nil?
if address.local.nil? && local_dot_atom_pre_comment_e && local_dot_atom_s && local_dot_atom_e
if address.domain
address.local = s[local_dot_atom_s..local_dot_atom_e] if address
else
address.local = s[local_dot_atom_s..local_dot_atom_pre_comment_e] if address
end
end
address.raw = s[address_s..(p-1)]
address_list.addresses << address if address
address = AddressStruct.new(nil, nil, [], nil, nil, nil, nil)
address.group = group_name
address_s = nil
when :angle_addr_s
if qstr
address.display_name = Mail::Utilities.unescape(qstr)
qstr = nil
elsif phrase_e
address.display_name = s[phrase_s..phrase_e].strip
phrase_e = phrase_s = nil
end
when :domain_s
domain_s = p
when :domain_e
address.domain = s[domain_s..(p-1)].rstrip if address
when :local_dot_atom_s then local_dot_atom_s = p
when :local_dot_atom_e then local_dot_atom_e = p-1
when :local_dot_atom_pre_comment_e
local_dot_atom_pre_comment_e = p-1
when :local_quoted_string_e
address.local = '"' + qstr + '"' if address
when :obs_domain_list_s then obs_domain_list_s = p
when :obs_domain_list_e
address.obs_domain_list = s[obs_domain_list_s..(p-1)]
else
raise Mail::Field::ParseError.new(Mail::AddressList, s, "Failed to process unknown action: #{action}")
end
end
if address_list.addresses.empty? && address_list.group_names.empty?
raise Mail::Field::ParseError.new(Mail::AddressList, s, "Didn't find any addresses or groups")
end
address_list
end