IDS peak ICV v1.1.0
Loading...
Searching...
No Matches
deserializer.py
Go to the documentation of this file.
1from __future__ import annotations
2import json
3from typing import TextIO, cast
4
6from ids_peak_icv.exceptions import IOException
8from ids_peak_icv.exceptions import NotSupportedException, CorruptedException
9from ids_peak_icv.serialization.serializer import SerializationType
10
11
13 """!
14 @brief
15 A deserializer that reads serialized data and reconstructs
16 IArchive objects.
17
18 Currently, only JSON is supported.
19
20 Example::
21
22 deserializer = Deserializer()
23 with open("input.json", "r") as f:
24 archive = deserializer.read(f)
25 archive.get("id", int) # 42
26 archive.get("name", str) # 'example'
27
28 @since ids_peak_icv 1.0
29 @ingroup ids_peak_icv_python_serialization
30 """
31
32 def __init__(self, serialization_type: SerializationType = SerializationType.JSON) -> None:
33 """!
34 @brief
35 Initializes a deserializer instance.
36
37 @param serialization_type: The format to use for deserialization.
38 Defaults to :class:`SerializationType.JSON`.
39
40 @since ids_peak_icv 1.0
41 """
42 self._type = serialization_type
43
44 # -------------------------------------------------------------------------
45
46 def read(self, stream: TextIO) -> IArchive:
47 """!
48 @brief
49 Reads serialized data from the given text stream and returns
50 a reconstructed IArchive.
51
52 @param stream: The input stream to read from (e.g., file).
53 @return A new :class:`Archive` containing the deserialized data.
54 @exception NotSupportedException: If the serialization format is unsupported
55 or the JSON is invalid.
56 @exception IOException: If the parsing fails.
57
58 @since ids_peak_icv 1.0
59 """
60 if self._type != SerializationType.JSON:
61 raise NotSupportedException(f"Serialization type {self._type} is not supported.")
62
63 data = stream.read()
64 try:
65 parsed = json.loads(data)
66 except json.JSONDecodeError as e:
67 raise IOException(f"Failed to parse JSON: {e}")
68
69 archive = Archive()
70 self._populate_archive(archive, parsed)
71 return archive
72
73 # -------------------------------------------------------------------------
74
75 def _populate_archive(self, archive: Archive, data: list | dict) -> None:
76 """!
77 @brief
78 Recursively populates an Archive with parsed JSON data.
79
80 @param archive: The archive to populate.
81 @param data: Parsed JSON data (dict, list, scalar).
82 @exception CorruptedException: If the format of the given data is invalid.
83 """
84 if not isinstance(data, dict):
85 raise CorruptedException("Root of serialized data must be a JSON object.")
86
87 for key, value in data.items():
88 if isinstance(value, dict):
89 nested = Archive()
90 self._populate_archive(nested, value)
91 archive.set(key, nested)
92 elif isinstance(value, list):
93 if value and isinstance(value[0], dict):
94 nested_list = []
95 for item in value:
96 nested = Archive()
97 self._populate_archive(nested, item)
98 nested_list.append(nested)
99 archive.set(key, cast(list[IArchive], nested_list))
100 else:
101 archive.set(key, value)
102 else:
103 archive.set(key, value)
Thrown when input data or a file is malformed, unreadable, or otherwise corrupted.
Thrown when a file input/output operation fails.
Thrown when a requested operation is not implemented or supported.
Definition exceptions.py:71
A simple key-value store with type checking, similar to a dict.
Definition archive.py:11
A deserializer that reads serialized data and reconstructs IArchive objects.
None _populate_archive(self, Archive archive, list|dict data)
Recursively populates an Archive with parsed JSON data.
None __init__(self, SerializationType serialization_type=SerializationType.JSON)
Initializes a deserializer instance.
IArchive read(self, TextIO stream)
Reads serialized data from the given text stream and returns a reconstructed IArchive.