130 size_t read_bytes = 0;
136 FATAL(
"Invalid context or image stream.");
144 FATAL(
"Could not seek to %" PRIu64
" as indicated by index entry...", entry->
offset);
154 TRACE(
"Could not read tape files header, continuing...");
160 TRACE(
"Incorrect identifier for data block at position %" PRIu64
"\n", entry->
offset);
169 FATAL(
"Could not allocate memory for tape files block, continuing...");
173 if(read_bytes != tape_file_header.
entries)
176 FATAL(
"Could not read tape files block, continuing...");
182 if(crc64 != tape_file_header.
crc64)
184 TRACE(
"Incorrect CRC found: 0x%" PRIx64
" found, expected 0x%" PRIx64
", continuing...", crc64,
185 tape_file_header.
crc64);
193 for(uint32_t i = 0; i < tape_file_header.
entries; i++)
197 if(hash_entry == NULL)
199 FATAL(
"Could not allocate memory for tape file hash entry");
204 hash_entry->
key = (uint64_t)entries[i].Partition << 32 | entries[i].File;
211 HASH_REPLACE(hh, ctx->
tape_files, key,
sizeof(uint64_t), hash_entry, old_entry);
215 if(old_entry != NULL)
217 TRACE(
"Replaced existing tape file entry for partition %u, file %u", entries[i].Partition, entries[i].File);
221 TRACE(
"Added new tape file entry for partition %u, file %u", entries[i].Partition, entries[i].File);
351 size_t read_bytes = 0;
357 FATAL(
"Invalid context or image stream.");
365 FATAL(
"Could not seek to %" PRIu64
" as indicated by index entry...", entry->
offset);
375 TRACE(
"Could not read tape partitions header, continuing...");
381 TRACE(
"Incorrect identifier for data block at position %" PRIu64
"\n", entry->
offset);
390 FATAL(
"Could not allocate memory for tape partitions block, continuing...");
394 if(read_bytes != tape_partition_header.
entries)
397 FATAL(
"Could not read tape partitions block, continuing...");
403 if(crc64 != tape_partition_header.
crc64)
405 TRACE(
"Incorrect CRC found: 0x%" PRIx64
" found, expected 0x%" PRIx64
", continuing...", crc64,
406 tape_partition_header.
crc64);
414 for(uint32_t i = 0; i < tape_partition_header.
entries; i++)
418 if(hash_entry == NULL)
420 FATAL(
"Could not allocate memory for tape partition hash entry");
432 HASH_REPLACE(hh, ctx->
tape_partitions, key,
sizeof(uint8_t), hash_entry, old_entry);
436 if(old_entry != NULL)
438 TRACE(
"Replaced existing tape partition entry for partition %u", entries[i].Number);
442 TRACE(
"Added new tape partition entry for partition %u", entries[i].Number);
573 uint64_t *starting_block, uint64_t *ending_block)
575 TRACE(
"Entering aaruf_get_tape_file(%p, %d, %d, %llu, %llu)", context, partition, file, *starting_block,
582 FATAL(
"Invalid context");
584 TRACE(
"Exiting aaruf_get_tape_file() = AARUF_ERROR_NOT_AARUFORMAT");
593 FATAL(
"Invalid context");
595 TRACE(
"Exiting aaruf_get_tape_file() = AARUF_ERROR_NOT_AARUFORMAT");
599 uint64_t key = (uint64_t)partition << 32 | file;
601 HASH_FIND(hh, ctx->
tape_files, &key,
sizeof(uint64_t), entry);
605 TRACE(
"Tape file not found");
612 TRACE(
"Exiting aaruf_get_tape_file(%p, %d, %d, %llu, %llu) = AARUF_STATUS_OK", context, partition, file,
613 *starting_block, *ending_block);
774 const uint64_t starting_block,
const uint64_t ending_block)
776 TRACE(
"Entering aaruf_set_tape_file(%p, %d, %d, %llu, %llu)", context, partition, file, starting_block,
783 FATAL(
"Invalid context");
785 TRACE(
"Exiting aaruf_set_tape_file() = AARUF_ERROR_NOT_AARUFORMAT");
794 FATAL(
"Invalid context");
796 TRACE(
"Exiting aaruf_set_tape_file() = AARUF_ERROR_NOT_AARUFORMAT");
803 FATAL(
"Trying to write a read-only image");
805 TRACE(
"Exiting aaruf_set_tape_file() = AARUF_READ_ONLY");
811 if(hash_entry == NULL)
813 FATAL(
"Could not allocate memory for tape file hash entry");
815 TRACE(
"Exiting aaruf_set_tape_file() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
820 hash_entry->
key = (uint64_t)partition << 32 | file;
830 HASH_REPLACE(hh, ctx->
tape_files, key,
sizeof(uint64_t), hash_entry, old_entry);
834 if(old_entry != NULL)
836 TRACE(
"Replaced existing tape file entry for partition %u, file %u", partition, file);
840 TRACE(
"Added new tape file entry for partition %u, file %u", partition, file);
842 TRACE(
"Exiting aaruf_set_tape_file(%p, %d, %d, %llu, %llu) = AARUF_STATUS_OK", context, partition, file,
843 starting_block, ending_block);
987 uint64_t *starting_block, uint64_t *ending_block)
989 TRACE(
"Entering aaruf_get_tape_partition(%p, %d, %llu, %llu)", context, partition, *starting_block, *ending_block);
995 FATAL(
"Invalid context");
997 TRACE(
"Exiting aaruf_get_tape_partition() = AARUF_ERROR_NOT_AARUFORMAT");
1006 FATAL(
"Invalid context");
1008 TRACE(
"Exiting aaruf_get_tape_partition() = AARUF_ERROR_NOT_AARUFORMAT");
1012 uint8_t key = partition;
1018 TRACE(
"Tape partition not found");
1025 TRACE(
"Exiting aaruf_get_tape_partition(%p, %d, %llu, %llu) = AARUF_STATUS_OK", context, partition, *starting_block,
1201 const uint64_t starting_block,
const uint64_t ending_block)
1203 TRACE(
"Entering aaruf_set_tape_partition(%p, %d, %llu, %llu)", context, partition, starting_block, ending_block);
1209 FATAL(
"Invalid context");
1211 TRACE(
"Exiting aaruf_set_tape_partition() = AARUF_ERROR_NOT_AARUFORMAT");
1220 FATAL(
"Invalid context");
1222 TRACE(
"Exiting aaruf_set_tape_partition() = AARUF_ERROR_NOT_AARUFORMAT");
1229 FATAL(
"Trying to write a read-only image");
1231 TRACE(
"Exiting aaruf_set_tape_partition() = AARUF_READ_ONLY");
1237 if(hash_entry == NULL)
1239 FATAL(
"Could not allocate memory for tape partition hash entry");
1241 TRACE(
"Exiting aaruf_set_tape_partition() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
1246 hash_entry->
key = partition;
1255 HASH_REPLACE(hh, ctx->
tape_partitions, key,
sizeof(uint8_t), hash_entry, old_entry);
1259 if(old_entry != NULL)
1261 TRACE(
"Replaced existing tape partition entry for partition %u", partition);
1265 TRACE(
"Added new tape partition entry for partition %u", partition);
1267 TRACE(
"Exiting aaruf_set_tape_partition(%p, %d, %llu, %llu) = AARUF_STATUS_OK", context, partition, starting_block,
1321 TRACE(
"Entering aaruf_get_all_tape_files(%p, %p, %zu)", context, buffer, (length ? *length : 0));
1326 FATAL(
"Invalid context");
1327 TRACE(
"Exiting aaruf_get_all_tape_files() = AARUF_ERROR_NOT_AARUFORMAT");
1336 FATAL(
"Invalid context");
1337 TRACE(
"Exiting aaruf_get_all_tape_files() = AARUF_ERROR_NOT_AARUFORMAT");
1343 FATAL(
"Image contains no tape files");
1344 TRACE(
"Exiting aaruf_get_all_tape_files() = AARUF_ERROR_TAPE_FILE_NOT_FOUND");
1349 const size_t count = HASH_COUNT(ctx->
tape_files);
1352 if(buffer == NULL || length == NULL || *length < required_size)
1354 if(length) *length = required_size;
1355 TRACE(
"Buffer too small for tape files, required %zu bytes", required_size);
1356 TRACE(
"Exiting aaruf_get_all_tape_files() = AARUF_ERROR_BUFFER_TOO_SMALL");
1371 *length = required_size;
1373 TRACE(
"Exiting aaruf_get_all_tape_files(%p, %p, %zu) = AARUF_STATUS_OK", context, buffer, *length);
1423 TRACE(
"Entering aaruf_get_all_tape_partitions(%p, %p, %zu)", context, buffer, (length ? *length : 0));
1428 FATAL(
"Invalid context");
1429 TRACE(
"Exiting aaruf_get_all_tape_partitions() = AARUF_ERROR_NOT_AARUFORMAT");
1438 FATAL(
"Invalid context");
1439 TRACE(
"Exiting aaruf_get_all_tape_partitions() = AARUF_ERROR_NOT_AARUFORMAT");
1445 FATAL(
"Image contains no tape partitions");
1446 TRACE(
"Exiting aaruf_get_all_tape_partitions() = AARUF_ERROR_TAPE_PARTITION_NOT_FOUND");
1454 if(buffer == NULL || length == NULL || *length < required_size)
1456 if(length) *length = required_size;
1457 TRACE(
"Buffer too small for tape partitions, required %zu bytes", required_size);
1458 TRACE(
"Exiting aaruf_get_all_tape_partitions() = AARUF_ERROR_BUFFER_TOO_SMALL");
1473 *length = required_size;
1475 TRACE(
"Exiting aaruf_get_all_tape_partitions(%p, %p, %zu) = AARUF_STATUS_OK", context, buffer, *length);
#define AARU_MAGIC
Magic identifier for AaruFormat container (ASCII "AARUFRMT").
struct TapeFileHashEntry tapeFileHashEntry
uint64_t aaruf_crc64_data(const uint8_t *data, uint32_t len)
@ TapePartitionBlock
Block containing list of partitions for a tape image.
@ TapeFileBlock
Block containing list of files for a tape image.
#define AARUF_ERROR_TAPE_PARTITION_NOT_FOUND
Requested tape partition not present in image.
#define AARUF_STATUS_OK
Sector present and read without uncorrectable errors.
#define AARUF_READ_ONLY
Operation requires write mode but context is read-only.
#define AARUF_ERROR_NOT_ENOUGH_MEMORY
Memory allocation failure (critical).
#define AARUF_ERROR_TAPE_FILE_NOT_FOUND
Requested tape file number not present in image.
#define AARUF_ERROR_NOT_AARUFORMAT
Input file/stream failed magic or structural validation.
#define AARUF_ERROR_BUFFER_TOO_SMALL
Caller-supplied buffer insufficient for data.
static int aaruf_fseek(FILE *stream, aaru_off_t offset, int origin)
static aaru_off_t aaruf_ftell(FILE *stream)
uint64_t ImageSize
Size of the image payload in bytes (excludes headers/metadata).
Single index entry describing a block's type, (optional) data classification, and file offset.
uint64_t offset
Absolute byte offset in the image where the referenced block header begins.
Describes a single logical file on a tape medium.
uint32_t File
File number (unique within the partition).
uint64_t LastBlock
Last block of the file (inclusive).
uint64_t FirstBlock
First block of the file (inclusive).
uint8_t Partition
Partition number containing this file.
uint64_t key
Composite key: partition << 32 | file.
TapeFileEntry fileEntry
The actual tape file data.
Describes a single physical partition on a tape medium.
uint64_t LastBlock
Last block in the partition (inclusive).
uint64_t FirstBlock
First block in the partition (inclusive).
uint8_t Number
Partition number (unique identifier for this partition).
uint8_t key
Key: partition.
TapePartitionEntry partitionEntry
The actual tape partition data.
Master context representing an open or in‑creation Aaru image.
tapeFileHashEntry * tape_files
Hash table root for tape files.
bool dirty_tape_partition_block
True if tape partition block should be written during close.
bool is_writing
True if context opened/created for writing.
uint64_t magic
File magic (AARU_MAGIC) post-open.
FILE * imageStream
Underlying FILE* stream (binary mode).
bool dirty_tape_file_block
True if tape file block should be written during close.
ImageInfo image_info
Exposed high-level image info summary.
TapePartitionHashEntry * tape_partitions
Hash table root for tape partitions.
int32_t aaruf_set_tape_file(void *context, const uint8_t partition, const uint32_t file, const uint64_t starting_block, const uint64_t ending_block)
Sets or updates the block range for a specific tape file in an Aaru tape image.
int32_t aaruf_get_all_tape_partitions(const void *context, uint8_t *buffer, size_t *length)
Retrieves all tape partition entries from the image.
int32_t aaruf_get_tape_file(const void *context, const uint8_t partition, const uint32_t file, uint64_t *starting_block, uint64_t *ending_block)
Retrieves the block range for a specific tape file from an Aaru tape image.
void process_tape_files_block(aaruformat_context *ctx, const IndexEntry *entry)
Processes a tape file metadata block from the image stream.
int32_t aaruf_get_tape_partition(const void *context, const uint8_t partition, uint64_t *starting_block, uint64_t *ending_block)
Retrieves the block range for a specific tape partition from an Aaru tape image.
int32_t aaruf_set_tape_partition(void *context, const uint8_t partition, const uint64_t starting_block, const uint64_t ending_block)
Sets or updates the block range for a specific tape partition in an Aaru tape image.
void process_tape_partitions_block(aaruformat_context *ctx, const IndexEntry *entry)
Processes a tape partition metadata block from the image stream.
int32_t aaruf_get_all_tape_files(const void *context, uint8_t *buffer, size_t *length)
Retrieves all tape file entries from the image.