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.



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
# File 'lib/protocol/caldav/content_line.rb', line 21

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

  return nil unless 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)
    next unless key
    val = val[1..-2] if val&.start_with?('"') && val&.end_with?('"')
    params[key.upcase] = val || ''
  end

  [name, params, value]
end

.split_params(str) ⇒ Object

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



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

def split_params(str)
  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
  parts << current unless current.empty?
  parts
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.



14
15
16
# File 'lib/protocol/caldav/content_line.rb', line 14

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