From 9a2a6691b09baae28bd81c2e25425217793b1dbb Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Fri, 11 Feb 2022 15:44:28 +0100 Subject: [PATCH] tlv: Function for flattening the list-of-dict output of TLV decoder Before: { "FcpTemplate": [ { "FileDescriptor": { "shareable": true, "file_type": "df", "structure": "no_info_given" } }, { "FileIdentifier": "3f00" }, { "ProprietaryInformation": [ { "UiccCharacteristics": "71" }, { "AvailableMemory": 123052 } ] }, { "LifeCycleStatusInteger": "operational_activated" }, { "SecurityAttribReferenced": { "ef_arr_file_id": "2f06", "ef_arr_record_nr": 2 } }, { "PinStatusTemplate_DO": [ { "PS_DO": "40" }, { "KeyReference": 1 }, { "KeyReference": 129 } ] }, { "TotalFileSize": 187809 } ] } After: { "FcpTemplate": { "FileDescriptor": { "shareable": true, "file_type": "df", "structure": "no_info_given" }, "FileIdentifier": "3f00", "ProprietaryInformation": { "UiccCharacteristics": "71", "AvailableMemory": 123052 }, "LifeCycleStatusInteger": "operational_activated", "SecurityAttribReferenced": { "ef_arr_file_id": "2f06", "ef_arr_record_nr": 2 }, "PinStatusTemplate_DO": { "PS_DO": "40", "KeyReference": 129 }, "TotalFileSize": 187809 } } Change-Id: Ia5ad8f1d3b0d47ebdb1856b0feaba120bad3eef9 --- pySim/tlv.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/pySim/tlv.py b/pySim/tlv.py index ba1aa9fe..71338ab0 100644 --- a/pySim/tlv.py +++ b/pySim/tlv.py @@ -404,3 +404,30 @@ class TLV_IE_Collection(metaclass=TlvCollectionMeta): def to_tlv(self): return self.to_bytes() + + +def flatten_dict_lists(inp): + """hierarchically flatten each list-of-dicts into a single dict. This is useful to + make the output of hierarchical TLV decoder structures flatter and more easy to read.""" + def are_all_elements_dict(l): + for e in l: + if not isinstance(e, dict): + return False + return True + + if isinstance(inp, list): + if are_all_elements_dict(inp): + # flatten into one shared dict + newdict = {} + for e in inp: + key = list(e.keys())[0] + newdict[key] = e[key] + inp = newdict + # process result as any native dict + return {k:flatten_dict_lists(inp[k]) for k in inp.keys()} + else: + return [flatten_dict_lists(x) for x in inp] + elif isinstance(inp, dict): + return {k:flatten_dict_lists(inp[k]) for k in inp.keys()} + else: + return inp