|
12 | 12 |
|
13 | 13 | """bencode.py - bencode encoder + decoder.""" |
14 | 14 |
|
15 | | -from collections import deque |
| 15 | +from collections import deque, OrderedDict |
16 | 16 |
|
17 | 17 | from bencode.BTL import BTFailure |
18 | 18 | from bencode.exceptions import BencodeDecodeError |
@@ -86,13 +86,30 @@ def decode_list(x, f): |
86 | 86 | return r, f + 1 |
87 | 87 |
|
88 | 88 |
|
89 | | -def decode_dict(x, f): |
90 | | - r, f = {}, f + 1 |
| 89 | +def decode_dict(x, f, force_sort=True): |
| 90 | + """ |
| 91 | + decode bencoded data to an OrderedDict |
| 92 | +
|
| 93 | + The BitTorrent standard states that: |
| 94 | + Keys must be strings and appear in sorted order (sorted as raw |
| 95 | + strings, not alphanumerics) |
| 96 | + - http://www.bittorrent.org/beps/bep_0003.html |
| 97 | +
|
| 98 | + Therefore, this function will force the keys to be strings (decoded |
| 99 | + from utf-8), and by default the keys are (re)sorted after reading. |
| 100 | + Set force_sort to False to keep the order of the dictionary as |
| 101 | + represented in x, as many other encoders and decoders do not force this |
| 102 | + property. |
| 103 | + """ |
| 104 | + r, f = OrderedDict(), f + 1 |
91 | 105 |
|
92 | 106 | while x[f : f+1] != b'e': |
93 | 107 | k, f = decode_string(x, f, force_decode_utf8=True) |
94 | 108 | r[k], f = decode_func[x[f : f+1]](x, f) |
95 | 109 |
|
| 110 | + if force_sort: |
| 111 | + r = OrderedDict(sorted(r.items())) |
| 112 | + |
96 | 113 | return r, f + 1 |
97 | 114 |
|
98 | 115 |
|
@@ -209,6 +226,7 @@ def encode_dict(x, r): |
209 | 226 | else: |
210 | 227 | encode_func[bool] = encode_bool |
211 | 228 | encode_func[dict] = encode_dict |
| 229 | + encode_func[OrderedDict] = encode_dict |
212 | 230 | encode_func[int] = encode_int |
213 | 231 | encode_func[list] = encode_list |
214 | 232 | encode_func[str] = encode_string |
|
0 commit comments