Module: Protocol::Caldav::ContentLine

Defined in:
lib/protocol/caldav/content_line.rb

Class Method Summary collapse

Class Method Details

.parse_line(line) ⇒ Object

Parse a single content line into [name, params, value]. Format: NAME;PARAM1=VAL1;PARAM2="VAL2":value The value is everything after the first unquoted colon.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/protocol/caldav/content_line.rb', line 18

def parse_line(line)
  # Find the first colon not inside a quoted parameter value
  in_quotes = false
  colon_idx = nil
  line.each_char.with_index do |ch, i|
    if ch == '"'
      in_quotes = !in_quotes
    elsif ch == ':' && !in_quotes
      colon_idx = i
      break
    end
  end

  if colon_idx
    left = line[0...colon_idx]
    value = line[(colon_idx + 1)..]
    parts = split_params(left)
    name = parts.shift
    params = {}
    parts.each do |param_str|
      key, val = param_str.split('=', 2)
      unless key
        next
      end
      if val&.start_with?('"') && val&.end_with?('"')
        val = val[1..-2]
      end
      params[key.upcase] = val || ''
    end
    [name, params, value]
  else
    nil
  end
end

.split_params(str) ⇒ Object

Split the left side of a content line by semicolons, respecting quoted values.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/protocol/caldav/content_line.rb', line 55

def split_params(str)
  [].tap do |parts|
    current = +''
    in_quotes = false

    str.each_char do |ch|
      if ch == '"'
        in_quotes = !in_quotes
        current << ch
      elsif ch == ';' && !in_quotes
        parts << current
        current = +''
      else
        current << ch
      end
    end

    unless current.empty?
      parts << current
    end
  end
end

.unfold(text) ⇒ Object

Unfold lines per RFC 5545 §3.1: CRLF followed by a single space or tab is removed (the space/tab is part of the folding, not the value). Also normalizes line endings to LF.



11
12
13
# File 'lib/protocol/caldav/content_line.rb', line 11

def unfold(text)
  text.gsub("\r\n", "\n").gsub("\r", "\n").gsub(/\n[ \t]/, '')
end