_EOC = object()
-def loads(v):
+def loads(v, sets=False):
if len(v) == 0:
raise NotEnoughData(1)
if v[0] == TagEOC:
ret = []
v = v[1:]
while True:
- i, v = loads(v)
+ i, v = loads(v, sets=sets)
if i == _EOC:
break
ret.append(i)
ret = {}
v = v[1:]
kPrev = ""
+ allNILs = True
while True:
k, v = loads(v)
if k == _EOC:
raise DecodeError("non-string key")
if (len(k) < len(kPrev)) or ((len(k) == len(kPrev)) and (k <= kPrev)):
raise DecodeError("unsorted keys")
- i, v = loads(v)
+ i, v = loads(v, sets=sets)
if k == _EOC:
raise DecodeError("unexpected EOC")
ret[k] = i
kPrev = k
+ if i is not None:
+ allNILs = False
+ if sets and allNILs:
+ ret = set(ret.keys())
return ret, v
if v[0] == TagBlob:
if len(v) < 1+8:
raise DecodeError("unexpected tag")
return Blob(l, b"".join(raws)), v
raise DecodeError("unknown tag")
+
+
+if __name__ == "__main__":
+ from argparse import ArgumentParser
+ from argparse import FileType
+ parser = ArgumentParser(description="Decode YAC file")
+ parser.add_argument("--nosets", action="store_true",
+ help="Do not fold NIL-valued maps to sets")
+ parser.add_argument("file", type=FileType("rb"))
+ args = parser.parse_args()
+ data = args.file.read()
+ data, tail = loads(data, sets=not args.nosets)
+ from pprint import pprint
+ pprint(data)
+ if tail != b"":
+ print("tail:", tail.hex())