1 __all__ = ['seqToKV', 'kvToSeq', 'dictToKV', 'kvToDict']
2
3 from openid import oidutil
4
5 import types
6
8 """Represent a sequence of pairs of strings as newline-terminated
9 key:value pairs. The pairs are generated in the order given.
10
11 @param seq: The pairs
12 @type seq: [(str, (unicode|str))]
13
14 @return: A string representation of the sequence
15 @rtype: str
16 """
17 def err(msg):
18 formatted = 'seqToKV warning: %s: %r' % (msg, seq)
19 if strict:
20 raise ValueError(formatted)
21 else:
22 oidutil.log(formatted)
23
24 lines = []
25 for k, v in seq:
26 if isinstance(k, types.StringType):
27 k = k.decode('UTF8')
28 elif not isinstance(k, types.UnicodeType):
29 err('Converting key to string: %r' % k)
30 k = str(k)
31
32 if '\n' in k:
33 raise ValueError(
34 'Invalid input for seqToKV: key contains newline: %r' % (k,))
35
36 if ':' in k:
37 raise ValueError(
38 'Invalid input for seqToKV: key contains colon: %r' % (k,))
39
40 if k.strip() != k:
41 err('Key has whitespace at beginning or end: %r' % k)
42
43 if isinstance(v, types.StringType):
44 v = v.decode('UTF8')
45 elif not isinstance(v, types.UnicodeType):
46 err('Converting value to string: %r' % v)
47 v = str(v)
48
49 if '\n' in v:
50 raise ValueError(
51 'Invalid input for seqToKV: value contains newline: %r' % (v,))
52
53 if v.strip() != v:
54 err('Value has whitespace at beginning or end: %r' % v)
55
56 lines.append(k + ':' + v + '\n')
57
58 return ''.join(lines).encode('UTF8')
59
61 """
62
63 After one parse, seqToKV and kvToSeq are inverses, with no warnings::
64
65 seq = kvToSeq(s)
66 seqToKV(kvToSeq(seq)) == seq
67 """
68 def err(msg):
69 formatted = 'kvToSeq warning: %s: %r' % (msg, data)
70 if strict:
71 raise ValueError(formatted)
72 else:
73 oidutil.log(formatted)
74
75 lines = data.split('\n')
76 if lines[-1]:
77 err('Does not end in a newline')
78 else:
79 del lines[-1]
80
81 pairs = []
82 line_num = 0
83 for line in lines:
84 line_num += 1
85
86
87 if not line.strip():
88 continue
89
90 pair = line.split(':', 1)
91 if len(pair) == 2:
92 k, v = pair
93 k_s = k.strip()
94 if k_s != k:
95 fmt = ('In line %d, ignoring leading or trailing '
96 'whitespace in key %r')
97 err(fmt % (line_num, k))
98
99 if not k_s:
100 err('In line %d, got empty key' % (line_num,))
101
102 v_s = v.strip()
103 if v_s != v:
104 fmt = ('In line %d, ignoring leading or trailing '
105 'whitespace in value %r')
106 err(fmt % (line_num, v))
107
108 pairs.append((k_s.decode('UTF8'), v_s.decode('UTF8')))
109 else:
110 err('Line %d does not contain a colon' % line_num)
111
112 return pairs
113
118
121