construct/tlv: Pass optional 'context' into construct decoder/encoder

The context is some opaque dictionary that can be used by the
constructs; let's allow the caller of parse_construct,  from_bytes,
from_tlv to specify it.

Also, when decoding a TLV_IE_Collection, pass the decode results of
existing siblings via the construct.

Change-Id: I021016aaa09cddf9d36521c1a54b468ec49ff54d
diff --git a/pySim/construct.py b/pySim/construct.py
index 31caf0e..cef9557 100644
--- a/pySim/construct.py
+++ b/pySim/construct.py
@@ -200,13 +200,16 @@
     return r
 
 
-def parse_construct(c, raw_bin_data: bytes, length: typing.Optional[int] = None, exclude_prefix: str = '_'):
+def parse_construct(c, raw_bin_data: bytes, length: typing.Optional[int] = None, exclude_prefix: str = '_', context: dict = {}):
     """Helper function to wrap around normalize_construct() and filter_dict()."""
     if not length:
         length = len(raw_bin_data)
-    parsed = c.parse(raw_bin_data, total_len=length)
+    parsed = c.parse(raw_bin_data, total_len=length, **context)
     return normalize_construct(parsed)
 
+def build_construct(c, decoded_data, context: dict = {}):
+    """Helper function to handle total_len."""
+    return c.build(decoded_data, total_len=None, **context)
 
 # here we collect some shared / common definitions of data types
 LV = Prefixed(Int8ub, HexAdapter(GreedyBytes))