|
libaaruformat 1.0
Aaru Data Preservation Suite - Format Library
|
Parsing, conversion and serialization helpers for Lisa (Apple Lisa / Profile / Priam / Sony) disk block tags. More...
Go to the source code of this file.
Macros | |
| #define | SONY_BLOCK_NUMBER_MASK 0x07FFU |
| #define | SONY_BLOCK_VALID_FLAG 0x8000U |
| #define | SONY_BLOCK_ALLOWED_MASK (SONY_BLOCK_VALID_FLAG | SONY_BLOCK_NUMBER_MASK) |
| Preserve valid bit + 11-bit index. | |
Functions | |
| sony_tag | bytes_to_sony_tag (const uint8_t *bytes) |
| Parse a 12-byte Sony tag record into a sony_tag structure. | |
| priam_tag | bytes_to_priam_tag (const uint8_t *bytes) |
| Parse a 24-byte Priam tag record into a priam_tag structure. | |
| profile_tag | bytes_to_profile_tag (const uint8_t *bytes) |
| Parse a 20-byte Profile tag record into a profile_tag structure. | |
| profile_tag | sony_tag_to_profile (const sony_tag tag) |
| Convert a sony_tag to a profile_tag representation. | |
| priam_tag | sony_tag_to_priam (const sony_tag tag) |
| Convert a sony_tag to a priam_tag representation. | |
| priam_tag | profile_tag_to_priam (const profile_tag tag) |
| Convert a profile_tag to a priam_tag. | |
| sony_tag | profile_tag_to_sony (const profile_tag tag) |
| Convert a profile_tag to a sony_tag. | |
| sony_tag | priam_tag_to_sony (const priam_tag tag) |
| Convert a priam_tag to a sony_tag. | |
| profile_tag | priam_tag_to_profile (const priam_tag tag) |
| Convert a priam_tag to a profile_tag. | |
| uint8_t * | profile_tag_to_bytes (const profile_tag tag) |
| Serialize a profile_tag into a newly allocated 20-byte big-endian on-disk representation. | |
| uint8_t * | priam_tag_to_bytes (const priam_tag tag) |
| Serialize a priam_tag into a newly allocated 24-byte big-endian on-disk representation. | |
| uint8_t * | sony_tag_to_bytes (sony_tag tag) |
| Serialize a sony_tag into a newly allocated 12-byte big-endian on-disk representation. | |
Parsing, conversion and serialization helpers for Lisa (Apple Lisa / Profile / Priam / Sony) disk block tags.
The Lisa operating system and related peripheral disk formats (Sony 3.5" diskettes, ProFile hard disks, Priam drives) store per-block (or per-page) metadata in compact on-disk "tag" records. These records use mixed-size big-endian integer fields and bit fields to describe allocation chains, relative/absolute page numbering, volume numbers, versions, and (for some variants) checksums and disk sizing.
This module provides:
Endianness: All multi-byte numeric fields in the on-disk tag formats are stored big-endian. The helper routines perform the necessary byte shifting and masking; the resulting structure fields are in host endianness.
Memory management: The serialization functions ( *_tag_to_bytes ) allocate new byte buffers using calloc(). The caller owns the returned pointer and must free() it when no longer needed. Parsing functions do not allocate dynamic memory; they return structures by value.
Validation: For performance and low-level usage reasons, the parsing routines do not perform NULL pointer checks nor length validation on the input byte arrays. Supplying a NULL pointer or insufficient bytes is undefined behavior. If such safety is required, perform validation before calling these functions.
Sentinel mapping: Sony tag next/prev block fields are 11-bit values (masked with 0x7FF) with the value 0x7FF meaning end-of-chain (or no previous). In the wider Profile/Priam formats these become 24-bit fields, with 0xFFFFFF used for the same semantic meaning. Conversion helpers transparently translate between these sentinel values.
Bit fields: The structures define C bit fields for compact representation (e.g., kind, reserved, valid_chk, used_bytes). The parsing and serialization routines reconstruct / pack these manually through masking and shifting because on-disk layout may not match compiler bit-field packing. This provides portability irrespective of platform-specific bit-field ordering.
Definition in file lisa_tag.c.
| #define SONY_BLOCK_ALLOWED_MASK (SONY_BLOCK_VALID_FLAG | SONY_BLOCK_NUMBER_MASK) |
Preserve valid bit + 11-bit index.
Definition at line 68 of file lisa_tag.c.
Referenced by bytes_to_sony_tag(), and sony_tag_to_bytes().
| #define SONY_BLOCK_NUMBER_MASK 0x07FFU |
Definition at line 66 of file lisa_tag.c.
Referenced by priam_tag_to_sony(), profile_tag_to_sony(), sony_tag_to_priam(), and sony_tag_to_profile().
| #define SONY_BLOCK_VALID_FLAG 0x8000U |
Definition at line 67 of file lisa_tag.c.
| priam_tag bytes_to_priam_tag | ( | const uint8_t * | bytes | ) |
Parse a 24-byte Priam tag record into a priam_tag structure.
Priam tags extend the Profile tag with an additional 4-byte disk_size field. This routine decodes all bit fields, separating the valid checksum flag (bit 7 of byte 6) from the 15-bit used_bytes value.
| bytes | Pointer to at least 24 consecutive bytes containing a raw Priam tag. |
Definition at line 112 of file lisa_tag.c.
References priam_tag::abs_page, priam_tag::checksum, priam_tag::disk_size, priam_tag::file_id, priam_tag::kind, priam_tag::next_block, priam_tag::prev_block, priam_tag::rel_page, priam_tag::reserved, priam_tag::used_bytes, priam_tag::valid_chk, priam_tag::version, and priam_tag::volume.
Referenced by aaruf_write_sector_long().
| profile_tag bytes_to_profile_tag | ( | const uint8_t * | bytes | ) |
Parse a 20-byte Profile tag record into a profile_tag structure.
A Profile tag is similar to Priam but without the trailing disk_size field. Multi-byte numeric values are big-endian.
| bytes | Pointer to at least 20 consecutive bytes containing a raw Profile tag. |
Definition at line 142 of file lisa_tag.c.
References profile_tag::abs_page, profile_tag::checksum, profile_tag::file_id, profile_tag::kind, profile_tag::next_block, profile_tag::prev_block, profile_tag::rel_page, profile_tag::reserved, profile_tag::used_bytes, profile_tag::valid_chk, profile_tag::version, and profile_tag::volume.
Referenced by aaruf_write_sector_long().
| sony_tag bytes_to_sony_tag | ( | const uint8_t * | bytes | ) |
Parse a 12-byte Sony tag record into a sony_tag structure.
Field extraction follows the documented on-disk layout (big-endian). The next/prev block numbers are masked to 11 bits (0x7FF) since only those bits are defined in the Sony tag format. The reserved bits are preserved in the structure's reserved member for round-tripping if needed.
| bytes | Pointer to at least 12 consecutive bytes containing a raw Sony tag as read from disk. |
Definition at line 82 of file lisa_tag.c.
References sony_tag::file_id, sony_tag::kind, sony_tag::next_block, sony_tag::prev_block, sony_tag::rel_page, sony_tag::reserved, SONY_BLOCK_ALLOWED_MASK, sony_tag::version, and sony_tag::volume.
Referenced by aaruf_write_sector_long().
| uint8_t * priam_tag_to_bytes | ( | const priam_tag | tag | ) |
Serialize a priam_tag into a newly allocated 24-byte big-endian on-disk representation.
Layout matches bytes_to_priam_tag(). Includes the final 4-byte disk_size field. Packing rules for used_bytes and valid_chk mirror those used in profile_tag_to_bytes().
| tag | Priam tag to serialize. |
| NULL | Allocation failure. |
Definition at line 409 of file lisa_tag.c.
References priam_tag::abs_page, priam_tag::checksum, priam_tag::disk_size, priam_tag::file_id, priam_tag::kind, priam_tag::next_block, priam_tag::prev_block, priam_tag::rel_page, priam_tag::reserved, priam_tag::used_bytes, priam_tag::valid_chk, priam_tag::version, and priam_tag::volume.
Referenced by aaruf_write_sector_long().
| profile_tag priam_tag_to_profile | ( | const priam_tag | tag | ) |
Convert a priam_tag to a profile_tag.
Copies overlapping fields, omitting the Priam-specific disk_size. Useful when reusing Priam metadata in a context that expects Profile tag semantics.
| tag | Source Priam tag. |
Definition at line 325 of file lisa_tag.c.
References priam_tag::abs_page, profile_tag::abs_page, priam_tag::checksum, profile_tag::checksum, priam_tag::file_id, profile_tag::file_id, priam_tag::kind, profile_tag::kind, priam_tag::next_block, profile_tag::next_block, priam_tag::prev_block, profile_tag::prev_block, priam_tag::rel_page, profile_tag::rel_page, priam_tag::reserved, profile_tag::reserved, priam_tag::used_bytes, profile_tag::used_bytes, priam_tag::valid_chk, profile_tag::valid_chk, priam_tag::version, profile_tag::version, priam_tag::volume, and profile_tag::volume.
Referenced by aaruf_write_sector_long().
Convert a priam_tag to a sony_tag.
See profile_tag_to_sony(); Priam-only fields (abs_page, checksum, used_bytes, valid_chk, disk_size) are discarded. 0xFFFFFF chain terminators become 0x7FF; other values are truncated to 11 bits.
| tag | Source Priam tag. |
Definition at line 291 of file lisa_tag.c.
References priam_tag::file_id, sony_tag::file_id, priam_tag::kind, sony_tag::kind, priam_tag::next_block, sony_tag::next_block, priam_tag::prev_block, sony_tag::prev_block, priam_tag::rel_page, sony_tag::rel_page, priam_tag::reserved, sony_tag::reserved, SONY_BLOCK_NUMBER_MASK, priam_tag::version, sony_tag::version, priam_tag::volume, and sony_tag::volume.
Referenced by aaruf_write_sector_long().
| uint8_t * profile_tag_to_bytes | ( | const profile_tag | tag | ) |
Serialize a profile_tag into a newly allocated 20-byte big-endian on-disk representation.
Bit/byte packing mirrors bytes_to_profile_tag(). The 24-bit next_block, prev_block and abs_page values are written most-significant byte first. The used_bytes high 7 bits and valid_chk flag are packed into the first byte of the 16-bit used_bytes field as per on-disk layout.
| tag | Profile tag to serialize. |
| NULL | Allocation failure (caller should check before use). |
Definition at line 357 of file lisa_tag.c.
References profile_tag::abs_page, profile_tag::checksum, profile_tag::file_id, profile_tag::kind, profile_tag::next_block, profile_tag::prev_block, profile_tag::rel_page, profile_tag::reserved, profile_tag::used_bytes, profile_tag::valid_chk, profile_tag::version, and profile_tag::volume.
Referenced by aaruf_write_sector_long().
| priam_tag profile_tag_to_priam | ( | const profile_tag | tag | ) |
Convert a profile_tag to a priam_tag.
Copies all overlapping fields directly. The Priam-only disk_size field remains zero unless modified later.
| tag | Source Profile tag. |
Definition at line 228 of file lisa_tag.c.
References priam_tag::abs_page, profile_tag::abs_page, priam_tag::checksum, profile_tag::checksum, priam_tag::file_id, profile_tag::file_id, priam_tag::kind, profile_tag::kind, priam_tag::next_block, profile_tag::next_block, priam_tag::prev_block, profile_tag::prev_block, priam_tag::rel_page, profile_tag::rel_page, priam_tag::reserved, profile_tag::reserved, priam_tag::used_bytes, profile_tag::used_bytes, priam_tag::valid_chk, profile_tag::valid_chk, priam_tag::version, profile_tag::version, priam_tag::volume, and profile_tag::volume.
Referenced by aaruf_write_sector_long().
| sony_tag profile_tag_to_sony | ( | const profile_tag | tag | ) |
Convert a profile_tag to a sony_tag.
Narrows 24-bit next/prev block numbers to 11 bits. A value of 0xFFFFFF (end-of-chain sentinel) is mapped back to 0x7FF. Any non-sentinel value is truncated to its lower 11 bits. Fields without Sony equivalents are dropped.
| tag | Source Profile tag. |
Definition at line 257 of file lisa_tag.c.
References profile_tag::file_id, sony_tag::file_id, profile_tag::kind, sony_tag::kind, profile_tag::next_block, sony_tag::next_block, profile_tag::prev_block, sony_tag::prev_block, profile_tag::rel_page, sony_tag::rel_page, profile_tag::reserved, sony_tag::reserved, SONY_BLOCK_NUMBER_MASK, profile_tag::version, sony_tag::version, profile_tag::volume, and sony_tag::volume.
Referenced by aaruf_write_sector_long().
| uint8_t * sony_tag_to_bytes | ( | sony_tag | tag | ) |
Serialize a sony_tag into a newly allocated 12-byte big-endian on-disk representation.
The next_block and prev_block fields are masked to 11 bits (0x7FF) during packing. Caller should ensure sentinel semantics are already encoded (i.e., use 0x7FF for end-of-chain) prior to calling.
| tag | Sony tag to serialize. |
| NULL | Allocation failure. |
Definition at line 466 of file lisa_tag.c.
References sony_tag::file_id, sony_tag::kind, sony_tag::next_block, sony_tag::prev_block, sony_tag::rel_page, sony_tag::reserved, SONY_BLOCK_ALLOWED_MASK, sony_tag::version, and sony_tag::volume.
Referenced by aaruf_write_sector_long().
Convert a sony_tag to a priam_tag representation.
Similar to sony_tag_to_profile() but returns a Priam tag. Priam-specific fields (abs_page, checksum, used_bytes, valid_chk, disk_size, reserved) are zero-initialized. 0x7FF next/prev sentinels expand to 0xFFFFFF.
| tag | Source Sony tag. |
Definition at line 201 of file lisa_tag.c.
References priam_tag::file_id, sony_tag::file_id, priam_tag::kind, sony_tag::kind, priam_tag::next_block, sony_tag::next_block, priam_tag::prev_block, sony_tag::prev_block, priam_tag::rel_page, sony_tag::rel_page, priam_tag::reserved, sony_tag::reserved, SONY_BLOCK_NUMBER_MASK, priam_tag::version, sony_tag::version, priam_tag::volume, and sony_tag::volume.
Referenced by aaruf_write_sector_long().
| profile_tag sony_tag_to_profile | ( | const sony_tag | tag | ) |
Convert a sony_tag to a profile_tag representation.
Sony tags contain a reduced-width (11-bit) next/prev block. To preserve chain termination semantics, values of 0x7FF are translated to 0xFFFFFF (24-bit "no next/prev" sentinel). Other values are copied verbatim into the wider fields. Only fields common to both formats are populated; Profile-specific fields (abs_page, checksum, used_bytes, valid_chk, reserved) remain zero-initialized.
| tag | Source Sony tag. |
Definition at line 173 of file lisa_tag.c.
References profile_tag::file_id, sony_tag::file_id, profile_tag::kind, sony_tag::kind, profile_tag::next_block, sony_tag::next_block, profile_tag::prev_block, sony_tag::prev_block, profile_tag::rel_page, sony_tag::rel_page, profile_tag::reserved, sony_tag::reserved, SONY_BLOCK_NUMBER_MASK, profile_tag::version, sony_tag::version, profile_tag::volume, and sony_tag::volume.
Referenced by aaruf_write_sector_long().