synology_apm_repo.sdk.format.headers module

The generic 64-byte IndexHeader shell shared by every binary format in this project (FORMAT-SPEC.md: header-shell):

offset  size  field
0       4     magic (ASCII)
4       2     major (BE u16)
6       2     minor (BE u16)
8       52    format-specific payload
60      4     header CRC32 (BE u32) = crc32(0, buf, 60)

Validation order (identical for every format, FORMAT-SPEC.md: header-shell): magic, then header CRC, then major-only version acceptance on read. Minor is never checked when reading — any minor is accepted.

This is deliberately not a declarative field-table framework (no metaclass magic): this module owns exactly the 64-byte shell (magic / CRC / version); each format-specific module (bucket.py, composition.py, …) decodes its own payload fields directly at their known offsets and calls back into parse_index_header for the shared shell checks.

class synology_apm_repo.sdk.format.headers.IndexHeader(magic, major, minor, raw)

Bases: object

The validated generic shell of a 64-byte header. raw is the full 64 bytes, for format-specific modules to slice their own payload fields out of without re-reading the file.

magic: bytes
major: int
minor: int
raw: bytes
synology_apm_repo.sdk.format.headers.parse_index_header(data, *, expect_magic, max_major=None, spec=None)

Validate and parse the generic 64-byte header shell at the start of data (data may be longer — only the first 64 bytes are consulted).

Minor is never checked on the read path.

Raises:
synology_apm_repo.sdk.format.headers.parse_json_payload_header(data, *, expect_magic, spec=None, payload_kind='payload')

Shared shell for a format whose 64-byte header (validated via parse_index_header) is immediately followed by a CRC32’d JSON payload: json_crc (BE u32) at offset 8, data_size (BE u64) at offset 12, payload at [HEADER_LEN, HEADER_LEN + data_size). repo_info/repo_transaction share exactly this shell and differ only in what’s inside the JSON body.

Parameters:

payload_kind (str) – Names the payload in an error message (e.g. "repo_info"); has no other effect.

Raises:
  • FormatError – The payload is shorter than data_size declares.

  • DataCorruptError – A payload CRC mismatch (in addition to parse_index_header’s own magic/header-CRC checks).

synology_apm_repo.sdk.format.headers.compute_crc32(data)

zlib.crc32(data) & 0xFFFFFFFF — the masked-to-unsigned-32-bit form every whole-buffer CRC32 check in this project compares against. Factored out of verify_crc32 so its raise-or-pass check and format.redundancy.attempt_repair’s own boolean comparison (which needs the value itself, not a raise) share one masking rule instead of each computing it independently.

synology_apm_repo.sdk.format.headers.verify_crc32(data, expected, *, label, spec=None)

Raise DataCorruptError unless compute_crc32(data) matches expected — the CRC32-verify-or-raise shape shared by every binary format in this project (headers, JSON payloads, composition records, chunk maps, SizeStore).

Parameters:

label (str) – Names the checked region in the error message (e.g. "header", "payload", "RecordHead").

Raises:

DataCorruptError – The computed CRC32 doesn’t match expected.