File: kvform.rb

package info (click to toggle)
ruby-openid 2.1.8debian-6
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 1,676 kB
  • sloc: ruby: 16,506; xml: 219; sh: 24; makefile: 2
file content (136 lines) | stat: -rw-r--r-- 3,340 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

module OpenID

  class KVFormError < Exception
  end

  module Util

    def Util.seq_to_kv(seq, strict=false)
      # Represent a sequence of pairs of strings as newline-terminated
      # key:value pairs. The pairs are generated in the order given.
      #
      # @param seq: The pairs
      #
      # returns a string representation of the sequence
      err = lambda { |msg|
        msg = "seq_to_kv warning: #{msg}: #{seq.inspect}"
        if strict
          raise KVFormError, msg
        else
          Util.log(msg)
        end
      }

      lines = []
      seq.each { |k, v|
        if !k.is_a?(String)
          err.call("Converting key to string: #{k.inspect}")
          k = k.to_s
        end

        if !k.index("\n").nil?
          raise KVFormError, "Invalid input for seq_to_kv: key contains newline: #{k.inspect}"
        end

        if !k.index(":").nil?
          raise KVFormError, "Invalid input for seq_to_kv: key contains colon: #{k.inspect}"
        end

        if k.strip() != k
          err.call("Key has whitespace at beginning or end: #{k.inspect}")
        end

        if !v.is_a?(String)
          err.call("Converting value to string: #{v.inspect}")
          v = v.to_s
        end

        if !v.index("\n").nil?
          raise KVFormError, "Invalid input for seq_to_kv: value contains newline: #{v.inspect}"
        end

        if v.strip() != v
          err.call("Value has whitespace at beginning or end: #{v.inspect}")
        end

        lines << k + ":" + v + "\n"
      }

      return lines.join("")
    end

    def Util.kv_to_seq(data, strict=false)
      # After one parse, seq_to_kv and kv_to_seq are inverses, with no
      # warnings:
      #
      # seq = kv_to_seq(s)
      # seq_to_kv(kv_to_seq(seq)) == seq
      err = lambda { |msg|
        msg = "kv_to_seq warning: #{msg}: #{data.inspect}"
        if strict
          raise KVFormError, msg
        else
          Util.log(msg)
        end
      }

      lines = data.split("\n")
      if data.length == 0
        return []
      end

      if data[-1].chr != "\n"
        err.call("Does not end in a newline")
        # We don't expect the last element of lines to be an empty
        # string because split() doesn't behave that way.
      end

      pairs = []
      line_num = 0
      lines.each { |line|
        line_num += 1

        # Ignore blank lines
        if line.strip() == ""
          next
        end

        pair = line.split(':', 2)
        if pair.length == 2
          k, v = pair
          k_s = k.strip()
          if k_s != k
            msg = "In line #{line_num}, ignoring leading or trailing whitespace in key #{k.inspect}"
            err.call(msg)
          end

          if k_s.length == 0
            err.call("In line #{line_num}, got empty key")
          end

          v_s = v.strip()
          if v_s != v
            msg = "In line #{line_num}, ignoring leading or trailing whitespace in value #{v.inspect}"
            err.call(msg)
          end

          pairs << [k_s, v_s]
        else
          err.call("Line #{line_num} does not contain a colon")
        end
      }

      return pairs
    end

    def Util.dict_to_kv(d)
      return seq_to_kv(d.entries.sort)
    end

    def Util.kv_to_dict(s)
      seq = kv_to_seq(s)
      return Hash[*seq.flatten]
    end
  end
end