(cls, bio)
| 261 | |
| 262 | @classmethod |
| 263 | def read(cls, bio): |
| 264 | _meta = cls() |
| 265 | |
| 266 | _meta.meta_size = struct.unpack('<I', bio.read(4))[0] |
| 267 | _meta.data_version = struct.unpack('B', bio.read(1))[0] |
| 268 | # Usually same as manifest version, but can be different |
| 269 | # e.g. if JSON manifest has been converted to binary manifest. |
| 270 | _meta.feature_level = struct.unpack('<I', bio.read(4))[0] |
| 271 | # As far as I can tell this was used for very old manifests that didn't use chunks at all |
| 272 | _meta.is_file_data = struct.unpack('B', bio.read(1))[0] == 1 |
| 273 | # 0 for most apps, generally not used |
| 274 | _meta.app_id = struct.unpack('<I', bio.read(4))[0] |
| 275 | _meta.app_name = read_fstring(bio) |
| 276 | _meta.build_version = read_fstring(bio) |
| 277 | _meta.launch_exe = read_fstring(bio) |
| 278 | _meta.launch_command = read_fstring(bio) |
| 279 | |
| 280 | # This is a list though I've never seen more than one entry |
| 281 | entries = struct.unpack('<I', bio.read(4))[0] |
| 282 | for _ in range(entries): |
| 283 | _meta.prereq_ids.append(read_fstring(bio)) |
| 284 | |
| 285 | _meta.prereq_name = read_fstring(bio) |
| 286 | _meta.prereq_path = read_fstring(bio) |
| 287 | _meta.prereq_args = read_fstring(bio) |
| 288 | |
| 289 | # Manifest version 18 with data version >= 1 stores build ID |
| 290 | if _meta.data_version >= 1: |
| 291 | _meta._build_id = read_fstring(bio) |
| 292 | # Manifest version 21 with data version >= 2 stores uninstall commands |
| 293 | if _meta.data_version >= 2: |
| 294 | _meta.uninstall_action_path = read_fstring(bio) |
| 295 | _meta.uninstall_action_args = read_fstring(bio) |
| 296 | |
| 297 | if (size_read := bio.tell()) != _meta.meta_size: |
| 298 | logger.warning(f'Did not read entire manifest metadata! Version: {_meta.data_version}, ' |
| 299 | f'{_meta.meta_size - size_read} bytes missing, skipping...') |
| 300 | bio.seek(_meta.meta_size - size_read, 1) |
| 301 | # downgrade version to prevent issues during serialisation |
| 302 | _meta.data_version = 0 |
| 303 | |
| 304 | return _meta |
| 305 | |
| 306 | def write(self, bio): |
| 307 | meta_start = bio.tell() |
nothing calls this directly
no test coverage detected