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