Module: Virginity::Vcard21::Reader

Included in:
DirectoryInformation
Defined in:
lib/virginity/vcard21/reader.rb

Overview

for DirectoryInformation

Constant Summary collapse

LATIN1 =
"ISO-8859-1"
UNSUPPORTED_CONTROL_CHARS =
/\x01|\x02|\x03|\x04|\x05|\x06|\x07|\x08|\x0e|\x0f|\x10|\x11|\x12|\x13|\x14|\x15|\x16|\x17|\x18|\x19|\x1a|\x1b|\x1c|\x1d|\x1e|\x1f|\x7f/

Instance Method Summary collapse

Instance Method Details

#convert_base64_to_b!(line) ⇒ Object



34
35
36
37
38
39
# File 'lib/virginity/vcard21/reader.rb', line 34

def convert_base64_to_b!(line)
  line[:params] ||= []
  line[:params].delete_if { |p| Vcard21::base64_param?(p) }
  line[:params] << Param.new("ENCODING", "b")
  line
end

#convert_charsets!(line) ⇒ Object



41
42
43
44
45
46
47
# File 'lib/virginity/vcard21/reader.rb', line 41

def convert_charsets!(line)
  line[:params] ||= []
  charset = line[:params].find { |p| p.key == "CHARSET" }
  line[:value] = line[:value].force_encoding(charset.value).encode
  line[:params].delete charset
  line
end

#fix_vcard21_line!(line) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/virginity/vcard21/reader.rb', line 77

def fix_vcard21_line!(line)
  unless line[:params].nil?
    reencode_quoted_printable!(line) if line[:params].any? { |p| Vcard21::qp_param?(p) }
    convert_base64_to_b!(line) if line[:params].any? { |p| Vcard21::base64_param?(p) }
    convert_charsets!(line) if line[:params].any? { |p| p.key == "CHARSET" }
  end
  guess_charset!(line)
  if position = line[:value] =~ UNSUPPORTED_CONTROL_CHARS
    raise "unsupported control character in line #{line.inspect} at character #{position}: 0x#{line[:value][position].to_s(16)}"
  end
  line
end

#from_vcard21(string) ⇒ Object



10
11
12
13
14
# File 'lib/virginity/vcard21/reader.rb', line 10

def from_vcard21(string)
  dirinfo = DirectoryInformation.new
  dirinfo.lines = lines_from_vcard21(string)
  dirinfo
end

#guess_charset!(line) ⇒ Object



58
59
60
# File 'lib/virginity/vcard21/reader.rb', line 58

def guess_charset!(line)
  line[:value] = guess_charset_for_part!(line[:value])
end

#guess_charset_for_part!(s) ⇒ Object



50
51
52
53
54
55
56
# File 'lib/virginity/vcard21/reader.rb', line 50

def guess_charset_for_part!(s)
  s.force_encoding(Encoding::UTF_8) if s.encoding == Encoding::BINARY
  return s if s.valid_encoding?

  s = s.dup.force_encoding(LATIN1).encode
  raise Virginity::InvalidEncoding, "can't fix #{s.to_s.inspect}" unless s.valid_encoding?
end

#line21_parts(string) ⇒ Object



62
63
64
65
66
67
68
69
70
# File 'lib/virginity/vcard21/reader.rb', line 62

def line21_parts(string)
  parser = Vcard21::Parser.new(string+"\n")
  line = parser.parse_item
  fix_vcard21_line!(line)
  group = line[:groups] ? line[:groups].first : nil
  [group, line[:name], line[:params] || [], line[:value]]
rescue
  raise ParseError, string.inspect
end

#lines_from_vcard21(string, options = {}) ⇒ Object



92
93
94
95
96
97
98
99
# File 'lib/virginity/vcard21/reader.rb', line 92

def lines_from_vcard21(string, options = {})
  lines = Vcard21::Parser.new(string, options).parse!
  lines.each { |line| fix_vcard21_line!(line) }
  lines.map do |line|
    group = line[:groups].nil? ? nil : line[:groups].first
    ContentLine.new(line[:name], line[:value], line[:params] || [], group, :no_deep_copy => true)
  end
end

#read_21_line(string) ⇒ Object



72
73
74
75
# File 'lib/virginity/vcard21/reader.rb', line 72

def read_21_line(string)
  group, name, params, value = line21_parts(string)
  ContentLine.new(name, value, params, group)
end

#reencode_quoted_printable!(line) ⇒ Object

remove QUOTED-PRINTABLE-encoding



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/virginity/vcard21/reader.rb', line 17

def reencode_quoted_printable!(line)
  line[:params] ||= []
  line[:params].delete_if { |p| Vcard21::qp_param?(p) }
  # FIXME encoding. reencoding could fail because the characters are not encodable as text
  if line[:value].include?(";") # if the unencoded value contains ";" it's a list
    v = line[:value].split(";").map { |e| EncodingDecoding::decode_quoted_printable(e) }
    line[:value] = EncodingDecoding::encode_text_list(v, ";")
  elsif line[:value].include?(",")
    v = line[:value].split(",").map { |e| EncodingDecoding::decode_quoted_printable(e) }
    line[:value] = EncodingDecoding::encode_text_list(v, ",")
  else
    v = EncodingDecoding::decode_quoted_printable(line[:value])
    line[:value] = EncodingDecoding::encode_text(v)
  end
  line
end