libaaruformat 1.0
Aaru Data Preservation Suite - Format Library
Loading...
Searching...
No Matches
flux.c File Reference
#include <inttypes.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "aaruformat/context.h"
#include "aaruformat/errors.h"
#include "aaruformat/structs/index.h"
#include "consts.h"
#include "decls.h"
#include "log.h"
#include "utarray.h"
#include "uthash.h"

Go to the source code of this file.

Data Structures

struct  FluxCaptureMapEntry
 Internal hash table entry for flux capture lookup. More...

Functions

static void flux_capture_record_dtor (void *element)
 Destructor callback for FluxCaptureRecord elements in a utarray.
static void flux_map_clear (aaruformat_context *ctx)
 Clear and deallocate the flux capture lookup map.
static int flux_map_add (aaruformat_context *ctx, const FluxCaptureKey *key, uint32_t index)
 Add or update a flux capture entry in the lookup map.
int32_t flux_map_rebuild_from_entries (aaruformat_context *ctx)
 Rebuild the flux capture lookup map from the flux_entries array.
void process_flux_data_block (aaruformat_context *ctx, const IndexEntry *entry)
 Parse and integrate a Flux Data block from the image stream into the context.
static int32_t ensure_flux_entries_loaded (aaruformat_context *ctx)
 Lazy load flux data block if not already loaded.
int32_t aaruf_get_flux_captures (void *context, uint8_t *buffer, size_t *length)
 Retrieve metadata for all flux captures in the image.
int32_t aaruf_write_flux_capture (void *context, uint32_t head, uint16_t track, uint8_t subtrack, uint32_t capture_index, uint64_t data_resolution, uint64_t index_resolution, const uint8_t *data, uint32_t data_length, const uint8_t *index, uint32_t index_length)
 Add a flux capture to the image during write mode.
int32_t aaruf_clear_flux_captures (void *context)
 Clear all flux captures from the context.
static const FluxEntryfind_flux_entry_by_key (const aaruformat_context *ctx, const FluxCaptureKey *key)
 Find a flux entry by its identifier key.
static int32_t read_flux_payload_header (const aaruformat_context *ctx, uint64_t payload_offset, DataStreamPayloadHeader *header)
 Read and validate a flux payload block header from the image stream.
static int32_t read_uncompressed_payload (const aaruformat_context *ctx, size_t cmp_length, size_t raw_length, uint8_t **cmp_buffer, uint8_t **payload)
 Read an uncompressed flux payload from the image stream.
static int32_t read_lzma_compressed_payload (const aaruformat_context *ctx, size_t cmp_length, size_t raw_length, uint8_t **cmp_buffer, uint8_t **payload)
 Read and decompress an LZMA-compressed flux payload from the image stream.
static int32_t validate_flux_payload_crcs (const uint8_t *cmp_buffer, size_t cmp_length, const uint8_t *payload, size_t raw_length, uint64_t expected_cmp_crc, uint64_t expected_raw_crc)
 Validate CRC64 checksums for a flux payload block.
static int32_t extract_flux_data_buffers (const FluxEntry *flux_entry, const uint8_t *payload, size_t raw_length, uint8_t *data_data, uint32_t *data_length, uint8_t *index_data, uint32_t *index_length)
 Extract data and index buffers from decompressed payload and copy to output buffers.
int32_t aaruf_read_flux_capture (void *context, uint32_t head, uint16_t track, uint8_t subtrack, uint32_t capture_index, uint8_t *index_data, uint32_t *index_length, uint8_t *data_data, uint32_t *data_length)
 Read a specific flux capture's data and index buffers from the image.

Variables

static const UT_icd FLUX_CAPTURE_RECORD_ICD = {sizeof(FluxCaptureRecord), NULL, NULL, flux_capture_record_dtor}

Function Documentation

◆ aaruf_clear_flux_captures()

int32_t aaruf_clear_flux_captures ( void * context)

Clear all flux captures from the context.

This function removes all flux captures from the context, freeing all associated memory including the flux_captures utarray, flux_entries array, and the flux capture lookup map. The flux_data_header is zeroed.

This function is useful for resetting the flux capture state, particularly in write mode when starting a new image or when discarding previously added captures.

Parameters
contextPointer to an initialized aaruformat context. Must not be NULL.
Returns
AARUF_STATUS_OK on success, or an error code on failure.
Return values
AARUF_STATUS_OKAll flux captures successfully cleared.
AARUF_ERROR_NOT_AARUFORMATInvalid context or context magic mismatch.
Note
This function is safe to call even if no flux captures are present (no-op).
After this call, ctx->flux_captures, ctx->flux_entries, and ctx->flux_map are all NULL/cleared, and ctx->flux_data_header is zeroed.
The function does not affect the image file itself; it only clears in-memory state. To remove flux data from an image file, the image must be rewritten.
See also
aaruf_write_flux_capture() to add flux captures
aaruf_get_flux_captures() to retrieve flux capture metadata

Definition at line 790 of file flux.c.

References AARU_CALL, AARU_EXPORT, AARU_MAGIC, AARUF_ERROR_NOT_AARUFORMAT, AARUF_STATUS_OK, FATAL, aaruformat_context::flux_captures, aaruformat_context::flux_data_header, aaruformat_context::flux_entries, flux_map_clear(), aaruformat_context::magic, and TRACE.

◆ aaruf_get_flux_captures()

int32_t aaruf_get_flux_captures ( void * context,
uint8_t * buffer,
size_t * length )

Retrieve metadata for all flux captures in the image.

This function retrieves metadata for all flux captures stored in the AaruFormat image. The metadata includes head, track, subtrack, captureIndex, indexResolution, and dataResolution for each capture, but does not include the actual flux data or index buffers (use aaruf_read_flux_capture() to retrieve those).

The function can be called with a NULL buffer to determine the required buffer size. In this case, the required length is written to *length and AARUF_ERROR_BUFFER_TOO_SMALL is returned.

Parameters
contextPointer to an initialized aaruformat context opened for reading. Must not be NULL.
bufferPointer to a buffer to receive the FluxCaptureMeta array. May be NULL to query the required size.
lengthPointer to the size of the buffer (in bytes). On input, must contain the buffer size. On output, contains the required size (if buffer is too small) or the actual size written. Must not be NULL.
Returns
AARUF_STATUS_OK on success, or an error code on failure.
Return values
AARUF_STATUS_OKMetadata successfully retrieved and written to buffer.
AARUF_ERROR_NOT_AARUFORMATInvalid context or context magic mismatch.
AARUF_ERROR_FLUX_DATA_NOT_FOUNDImage contains no flux captures.
AARUF_ERROR_BUFFER_TOO_SMALLBuffer is NULL or too small; *length contains the required size.
Note
The buffer must be large enough to hold ctx->flux_data_header.entries * sizeof(FluxCaptureMeta) bytes.
The returned metadata array is in the same order as the flux entries in the FluxDataBlock (on-disk order).
This function only returns metadata; use aaruf_read_flux_capture() to retrieve the actual flux data and index buffers.
Flux entries are loaded on-demand (lazy loading) the first time this function or aaruf_read_flux_capture() is called, avoiding unnecessary I/O during image opening.
See also
aaruf_read_flux_capture() to retrieve actual flux data for a specific capture
FluxCaptureMeta for the structure of each metadata entry

Definition at line 497 of file flux.c.

References AARU_CALL, AARU_EXPORT, AARU_MAGIC, AARUF_ERROR_BUFFER_TOO_SMALL, AARUF_ERROR_FLUX_DATA_NOT_FOUND, AARUF_ERROR_NOT_AARUFORMAT, AARUF_STATUS_OK, FluxCaptureMeta::captureIndex, FluxEntry::captureIndex, FluxCaptureMeta::dataResolution, FluxEntry::dataResolution, ensure_flux_entries_loaded(), FluxHeader::entries, FATAL, aaruformat_context::flux_data_header, aaruformat_context::flux_entries, FluxCaptureMeta::head, FluxEntry::head, FluxCaptureMeta::indexResolution, FluxEntry::indexResolution, aaruformat_context::magic, FluxCaptureMeta::subtrack, FluxEntry::subtrack, TRACE, FluxCaptureMeta::track, and FluxEntry::track.

◆ aaruf_read_flux_capture()

int32_t aaruf_read_flux_capture ( void * context,
uint32_t head,
uint16_t track,
uint8_t subtrack,
uint32_t capture_index,
uint8_t * index_data,
uint32_t * index_length,
uint8_t * data_data,
uint32_t * data_length )

Read a specific flux capture's data and index buffers from the image.

This function retrieves the actual flux data and index buffers for a specific flux capture identified by its head, track, subtrack, and capture_index. The function locates the corresponding FluxEntry in the flux_entries array (using the lookup map for efficiency), converts the payloadOffset (stored divided by block alignment) to an absolute file offset using blockAlignmentShift from FluxHeader, seeks to the DataStreamPayloadBlock at the specified offset, reads and decompresses the payload, validates CRC64 checksums, and extracts the data and index buffers.

The function supports both uncompressed and LZMA-compressed payload blocks. CRC64 validation is performed on both the compressed and uncompressed data.

The function can be called with NULL data buffers to determine the required buffer sizes. In this case, the required lengths are written to *data_length and *index_length, and AARUF_ERROR_BUFFER_TOO_SMALL is returned.

Parameters
contextPointer to an initialized aaruformat context opened for reading. Must not be NULL.
headHead number of the flux capture to retrieve.
trackTrack number of the flux capture to retrieve.
subtrackSubtrack number of the flux capture to retrieve.
capture_indexCapture index of the flux capture to retrieve.
index_dataPointer to a buffer to receive the index buffer. May be NULL to query the required size.
index_lengthPointer to the size of the index buffer (in bytes). On input, must contain the buffer size. On output, contains the required size (if buffer is too small) or the actual size written. Must not be NULL.
data_dataPointer to a buffer to receive the data buffer. May be NULL to query the required size.
data_lengthPointer to the size of the data buffer (in bytes). On input, must contain the buffer size. On output, contains the required size (if buffer is too small) or the actual size written. Must not be NULL.
Returns
AARUF_STATUS_OK on success, or an error code on failure.
Return values
AARUF_STATUS_OKFlux capture data successfully retrieved and written to buffers.
AARUF_ERROR_NOT_AARUFORMATInvalid context, context magic mismatch, or invalid image stream.
AARUF_ERROR_FLUX_DATA_NOT_FOUNDNo flux captures in image or specified capture not found.
AARUF_ERROR_BUFFER_TOO_SMALLOne or both buffers are NULL or too small; *data_length and *index_length contain required sizes.
AARUF_ERROR_CANNOT_READ_BLOCKFailed to seek to payload or read payload header.
AARUF_ERROR_CANNOT_DECOMPRESS_BLOCKLZMA decompression failed or invalid compression format.
AARUF_ERROR_INVALID_BLOCK_CRCCRC64 checksum mismatch (compressed or uncompressed).
AARUF_ERROR_INCORRECT_DATA_SIZEPayload section length exceeds 32-bit limits.
AARUF_ERROR_NOT_ENOUGH_MEMORYMemory allocation failed for decompression buffers.
AARUF_ERROR_UNSUPPORTED_COMPRESSIONUnsupported compression type in payload header.
Note
The function first attempts to locate the flux entry using the lookup map (O(1) lookup). If the map is not available or the entry is not found, it falls back to a linear search through flux_entries (O(n)).
The payload data is stored as [data_buffer][index_buffer] concatenated, with indexOffset indicating where the index buffer starts.
Both buffers must be large enough to hold the respective data. The function validates buffer sizes before copying data.
The caller is responsible for freeing the returned buffers if they were allocated by the caller.
CRC64 validation is performed on both compressed and uncompressed data to ensure data integrity.
See also
aaruf_get_flux_captures() to retrieve metadata for all flux captures
aaruf_write_flux_capture() to add flux captures during write mode
DataStreamPayloadHeader for the structure of payload blocks

Definition at line 1201 of file flux.c.

References AARU_CALL, AARU_EXPORT, AARU_MAGIC, AARUF_ERROR_BUFFER_TOO_SMALL, AARUF_ERROR_FLUX_DATA_NOT_FOUND, AARUF_ERROR_NOT_AARUFORMAT, AARUF_ERROR_UNSUPPORTED_COMPRESSION, AARUF_STATUS_OK, FluxHeader::blockAlignmentShift, FluxEntry::captureIndex, DataStreamPayloadHeader::cmpCrc64, DataStreamPayloadHeader::cmpLength, DataStreamPayloadHeader::compression, DataStreamPayloadHeader::crc64, ensure_flux_entries_loaded(), FluxHeader::entries, extract_flux_data_buffers(), FATAL, find_flux_entry_by_key(), aaruformat_context::flux_data_header, aaruformat_context::flux_entries, FluxEntry::head, aaruformat_context::imageStream, DataStreamPayloadHeader::length, Lzma, aaruformat_context::magic, None, FluxEntry::payloadOffset, read_flux_payload_header(), read_lzma_compressed_payload(), read_uncompressed_payload(), FluxEntry::subtrack, TRACE, FluxEntry::track, and validate_flux_payload_crcs().

◆ aaruf_write_flux_capture()

int32_t aaruf_write_flux_capture ( void * context,
uint32_t head,
uint16_t track,
uint8_t subtrack,
uint32_t capture_index,
uint64_t data_resolution,
uint64_t index_resolution,
const uint8_t * data,
uint32_t data_length,
const uint8_t * index,
uint32_t index_length )

Add a flux capture to the image during write mode.

This function adds a new flux capture to the image being written. The capture includes both data and index buffers, along with metadata specifying the head, track, subtrack, capture index, and resolution information for both streams.

The function copies the provided data and index buffers into internal storage (utarray) and creates a corresponding FluxEntry in the flux_entries array. The actual payload data is written to the image later during image finalization (in write_flux_blocks() and write_flux_capture_payload()).

The flux capture lookup map is updated to enable efficient retrieval of the capture by its identifier tuple.

Parameters
contextPointer to an initialized aaruformat context opened for writing. Must not be NULL.
headHead number the flux capture corresponds to.
trackTrack number the flux capture corresponds to.
subtrackSubtrack number the flux capture corresponds to.
capture_indexCapture index, allowing multiple captures for the same location.
data_resolutionResolution in picoseconds for the data stream.
index_resolutionResolution in picoseconds for the index stream.
dataPointer to the flux data buffer. May be NULL if data_length is 0.
data_lengthLength of the data buffer in bytes.
indexPointer to the flux index buffer. May be NULL if index_length is 0.
index_lengthLength of the index buffer in bytes.
Returns
AARUF_STATUS_OK on success, or an error code on failure.
Return values
AARUF_STATUS_OKFlux capture successfully added to the context.
AARUF_ERROR_NOT_AARUFORMATInvalid context or context magic mismatch.
AARUF_READ_ONLYContext is not in write mode.
AARUF_ERROR_INCORRECT_DATA_SIZEInvalid buffer pointers or combined size exceeds UINT32_MAX.
AARUF_ERROR_NOT_ENOUGH_MEMORYMemory allocation failed for buffers or map entry.
Note
The function copies the data and index buffers; the caller retains ownership of the original buffers and may free them after this call.
The combined size of data_length + index_length must not exceed UINT32_MAX.
The maximum number of flux captures is limited to UINT16_MAX (65535).
The payloadOffset field in the FluxEntry is set to 0 initially and is populated later when the payload block is written during image finalization.
If adding the capture to the lookup map fails, the function performs cleanup and restores the previous state.
See also
aaruf_read_flux_capture() to read flux captures from an image
aaruf_clear_flux_captures() to remove all flux captures
write_flux_blocks() for when payload blocks are written

Definition at line 616 of file flux.c.

References AARU_CALL, AARU_EXPORT, AARU_MAGIC, aaruf_crc64_data(), AARUF_ERROR_INCORRECT_DATA_SIZE, AARUF_ERROR_NOT_AARUFORMAT, AARUF_ERROR_NOT_ENOUGH_MEMORY, AARUF_READ_ONLY, AARUF_STATUS_OK, FluxEntry::captureIndex, FluxHeader::crc64, FluxCaptureRecord::data_buffer, FluxCaptureRecord::data_length, FluxEntry::dataResolution, aaruformat_context::dirty_flux_block, FluxHeader::entries, FluxCaptureRecord::entry, FATAL, FLUX_CAPTURE_RECORD_ICD, aaruformat_context::flux_captures, aaruformat_context::flux_data_header, aaruformat_context::flux_entries, flux_map_add(), FluxDataBlock, FluxEntry::head, FluxHeader::identifier, FluxCaptureRecord::index_buffer, FluxCaptureRecord::index_length, FluxEntry::indexOffset, FluxEntry::indexResolution, aaruformat_context::is_writing, aaruformat_context::magic, FluxEntry::payloadOffset, FluxEntry::subtrack, TRACE, and FluxEntry::track.

◆ ensure_flux_entries_loaded()

int32_t ensure_flux_entries_loaded ( aaruformat_context * ctx)
static

Lazy load flux data block if not already loaded.

This helper function checks if flux entries are loaded, and if not, finds the FluxDataBlock in the index and loads it. This enables lazy loading of flux entries only when they are actually needed.

Parameters
ctxPointer to the aaruformat context. Must not be NULL.
Returns
AARUF_STATUS_OK if flux entries are loaded (or no flux data exists), or an error code on failure.

Definition at line 415 of file flux.c.

References AARUF_ERROR_FLUX_DATA_NOT_FOUND, AARUF_STATUS_OK, IndexEntry::blockType, FluxHeader::entries, aaruformat_context::flux_data_header, aaruformat_context::flux_entries, FluxDataBlock, aaruformat_context::index_entries, and process_flux_data_block().

Referenced by aaruf_get_flux_captures(), and aaruf_read_flux_capture().

◆ extract_flux_data_buffers()

int32_t extract_flux_data_buffers ( const FluxEntry * flux_entry,
const uint8_t * payload,
size_t raw_length,
uint8_t * data_data,
uint32_t * data_length,
uint8_t * index_data,
uint32_t * index_length )
static

Extract data and index buffers from decompressed payload and copy to output buffers.

Parameters
flux_entryPointer to the flux entry containing index offset information. Must not be NULL.
payloadPointer to the decompressed payload buffer. Can be NULL if raw_length is 0.
raw_lengthLength of the decompressed payload.
data_dataOutput buffer for data portion. Can be NULL for size query.
data_lengthInput/output parameter for data buffer size/required size. Must not be NULL.
index_dataOutput buffer for index portion. Can be NULL for size query.
index_lengthInput/output parameter for index buffer size/required size. Must not be NULL.
Returns
AARUF_STATUS_OK on success, or an error code on failure.

Definition at line 1088 of file flux.c.

References AARUF_ERROR_BUFFER_TOO_SMALL, AARUF_ERROR_INCORRECT_DATA_SIZE, AARUF_ERROR_INVALID_BLOCK_CRC, AARUF_STATUS_OK, FATAL, FluxEntry::indexOffset, and TRACE.

Referenced by aaruf_read_flux_capture().

◆ find_flux_entry_by_key()

const FluxEntry * find_flux_entry_by_key ( const aaruformat_context * ctx,
const FluxCaptureKey * key )
static

Find a flux entry by its identifier key.

Parameters
ctxPointer to the aaruformat context containing flux data. Must not be NULL.
keyPointer to the FluxCaptureKey identifying the flux capture. Must not be NULL.
Returns
Pointer to the matching FluxEntry, or NULL if not found.

Definition at line 833 of file flux.c.

References FluxCaptureKey::captureIndex, FluxEntry::captureIndex, FluxHeader::entries, aaruformat_context::flux_data_header, aaruformat_context::flux_entries, aaruformat_context::flux_map, FluxCaptureKey::head, FluxEntry::head, FluxCaptureMapEntry::index, FluxCaptureKey::subtrack, FluxEntry::subtrack, FluxCaptureKey::track, and FluxEntry::track.

Referenced by aaruf_read_flux_capture().

◆ flux_capture_record_dtor()

void flux_capture_record_dtor ( void * element)
static

Destructor callback for FluxCaptureRecord elements in a utarray.

This function is used by the utarray library to clean up dynamically allocated memory when a FluxCaptureRecord is removed from or when the array is freed. It safely frees both the data_buffer and index_buffer fields if they are non-NULL, and then nullifies the pointers to prevent double-free errors.

Parameters
elementPointer to the FluxCaptureRecord element to destroy. May be NULL.
Note
This function is registered with utarray via FLUX_CAPTURE_RECORD_ICD and is called automatically by utarray_free() and utarray_erase() operations.

Definition at line 54 of file flux.c.

References FluxCaptureRecord::data_buffer, and FluxCaptureRecord::index_buffer.

◆ flux_map_add()

int flux_map_add ( aaruformat_context * ctx,
const FluxCaptureKey * key,
uint32_t index )
static

Add or update a flux capture entry in the lookup map.

This function adds a new entry to the UTHASH-based flux capture lookup map, or updates an existing entry if a matching key is already present. The map enables O(1) lookup of flux captures by their (head, track, subtrack, captureIndex) identifier tuple.

If an entry with the same key already exists, its index is updated to the new value. If no entry exists, a new FluxCaptureMapEntry is allocated and added to the map.

Parameters
ctxPointer to the aaruformat context containing the flux_map. Must not be NULL.
keyPointer to the FluxCaptureKey identifying the flux capture (head, track, subtrack, captureIndex). Must not be NULL.
indexThe array index in ctx->flux_entries that corresponds to this flux capture.
Returns
0 on success, -1 on memory allocation failure.
Note
On allocation failure, the function returns -1 and the map remains unchanged.
This function is used internally during map rebuilding and when adding new flux captures in write mode.

Definition at line 122 of file flux.c.

References aaruformat_context::flux_map, FluxCaptureMapEntry::index, and FluxCaptureMapEntry::key.

Referenced by aaruf_write_flux_capture(), and flux_map_rebuild_from_entries().

◆ flux_map_clear()

void flux_map_clear ( aaruformat_context * ctx)
static

Clear and deallocate the flux capture lookup map.

This function iterates through all entries in the UTHASH-based flux capture lookup map, removes each entry from the hash table, frees its memory, and sets the map pointer to NULL. This is used during cleanup operations and when rebuilding the map from scratch.

The function is safe to call even if the map is already NULL or empty.

Parameters
ctxPointer to the aaruformat context containing the flux_map to clear. Must not be NULL.
Note
This function does not free the flux_entries array or flux_captures utarray; it only clears the hash table used for O(1) lookup of flux captures.

Definition at line 84 of file flux.c.

References aaruformat_context::flux_map.

Referenced by aaruf_clear_flux_captures(), flux_map_rebuild_from_entries(), and process_flux_data_block().

◆ flux_map_rebuild_from_entries()

int32_t flux_map_rebuild_from_entries ( aaruformat_context * ctx)

Rebuild the flux capture lookup map from the flux_entries array.

This function clears any existing flux capture lookup map and rebuilds it from the ctx->flux_entries array. The map provides O(1) lookup of flux captures by their (head, track, subtrack, captureIndex) identifier tuple, which is used by aaruf_read_flux_capture() and other flux access functions.

The function iterates through all entries in ctx->flux_entries and adds each one to the hash table, mapping its identifier to its array index. If any entry fails to be added (due to memory allocation failure), the entire map is cleared and an error is returned.

Parameters
ctxPointer to the aaruformat context containing flux_entries and flux_map. Must not be NULL.
Returns
AARUF_STATUS_OK on success, or AARUF_ERROR_NOT_ENOUGH_MEMORY if memory allocation fails during map construction.
Return values
AARUF_STATUS_OKThe map was successfully rebuilt (or no entries to process).
AARUF_ERROR_NOT_ENOUGH_MEMORYMemory allocation failed; the map is cleared.
Note
If ctx->flux_entries is NULL or ctx->flux_data_header.entries is 0, the function clears the map and returns AARUF_STATUS_OK (no-op).
On failure, the map is cleared to ensure a consistent state.
This function is called automatically by process_flux_data_block() after successfully reading flux entries from the image.
See also
flux_map_clear() for clearing the map
flux_map_add() for adding individual entries
process_flux_data_block() for when this is called during image opening

Definition at line 171 of file flux.c.

References AARUF_ERROR_NOT_ENOUGH_MEMORY, AARUF_STATUS_OK, FluxEntry::captureIndex, FluxHeader::entries, FATAL, aaruformat_context::flux_data_header, aaruformat_context::flux_entries, flux_map_add(), flux_map_clear(), FluxEntry::head, FluxEntry::subtrack, and FluxEntry::track.

Referenced by process_flux_data_block(), and write_flux_blocks().

◆ process_flux_data_block()

void process_flux_data_block ( aaruformat_context * ctx,
const IndexEntry * entry )

Parse and integrate a Flux Data block from the image stream into the context.

This function seeks to the byte offset specified by the supplied entry, reads a FluxHeader followed by the declared number of FluxEntry records, validates the block through its CRC64, rebuilds the flux capture lookup map, and populates multiple fields in the provided ctx:

  • ctx->flux_data_header (identifier, entries, crc64)
  • ctx->flux_entries (raw array with ALL flux entries in on-disk order)
  • ctx->flux_capture_map (hash table mapping (head, track, subtrack, captureIndex) to entry indices)
  • ctx->imageInfo.ImageSize (incremented by sizeof(FluxEntry) * entries)

Before reading new data, the function performs cleanup of any existing flux-related state:

  • Frees and clears ctx->flux_captures if it exists (write-mode remnants)
  • Frees and clears ctx->flux_entries if it exists (from previous calls or partial reads)
  • Clears ctx->flux_capture_map (via flux_map_clear())
  • Zeros ctx->flux_data_header

After successfully reading and validating the flux entries, the function rebuilds the in-memory flux capture lookup map by calling flux_map_rebuild_from_entries(). This map enables O(1) lookup of flux captures by their identifiers (head, track, subtrack, captureIndex), which is used by aaruf_read_flux_capture() and other flux access functions.

The function is intended for internal library use and is NOT part of the stable public API (no versioning guarantees). It is called on-demand (lazy loading) when flux data is first accessed, rather than during image opening, to avoid unnecessary I/O if flux data is never used.

Processing Flow:

  1. Validation: Check ctx and ctx->imageStream are valid
  2. Cleanup: Free existing flux_captures, flux_entries, and clear flux_capture_map
  3. Seek: Seek to entry->offset in the image stream
  4. Read Header: Read FluxHeader structure
  5. Validate Identifier: Verify identifier == FluxDataBlock
  6. Allocate Entries: Allocate memory for flux_entries array
  7. Read Entries: Read all FluxEntry structures from the stream
  8. Validate CRC64: Compute and verify CRC64 checksum over entries
  9. Rebuild Map: Call flux_map_rebuild_from_entries() to build lookup map
  10. Update ImageSize: Increment ctx->image_info.ImageSize

Error & early-return behavior (no exception mechanism, all via logging + early return):

  • NULL ctx or NULL ctx->imageStream: Logs FATAL and returns immediately; context left untouched.
  • Seek failure: FATAL + return; context left untouched (cleanup already performed).
  • FluxHeader read short: flux_data_header zeroed, TRACE logged, return.
  • Identifier mismatch: flux_data_header zeroed, TRACE logged, return.
  • Allocation failure for flux_entries: flux_data_header zeroed, FATAL logged, return.
  • Short read of FluxEntry array: flux_data_header zeroed, allocated flux_entries freed, FATAL logged, return.
  • CRC mismatch: TRACE logged and return; (NOTE: at this point flux_entries remain allocated and flux_data_header retains the just-read values, but the lookup map is not built, so entries are not accessible via lookup functions. Caller may wish to discard them or trigger re-read.)
  • Map rebuild failure: flux_entries freed, flux_data_header zeroed, FATAL logged, return.

Memory management:

  • Frees any pre-existing ctx->flux_captures (utarray) before processing
  • Frees any pre-existing ctx->flux_entries before allocating new ones
  • Allocates ctx->flux_entries with malloc() sized to entries * sizeof(FluxEntry)
  • On certain failure paths (short reads, map rebuild failure) allocated memory is freed
  • On CRC mismatch, allocated memory is kept but map is not built (entries not accessible via lookup)
  • The function is idempotent in terms of memory: it cleans up before processing, so repeated calls will not leak memory. However, the function is expected to be called exactly once per context lifetime during image opening.

Flux Capture Lookup Map: After successfully reading and validating flux entries, the function rebuilds the in-memory hash table (ctx->flux_capture_map) that maps flux capture identifiers to array indices. This enables efficient lookup of flux captures by their (head, track, subtrack, captureIndex) tuple. The map is built using UTHASH and is used by aaruf_read_flux_capture() and other flux access functions. If map rebuild fails, the function cleans up all allocated resources and returns.

Thread safety:

  • Not thread-safe: mutates shared state in ctx without synchronization.
  • Must not be called concurrently with readers/writers referencing the same context.

Preconditions (

Precondition
):
  • ctx != NULL
  • ctx->imageStream is a valid FILE* opened for reading at least up to the block region.
  • entry != NULL and entry->offset points to the start of a well-formed Flux Data block.

Postconditions (

Postcondition
) on success (CRC valid and map rebuilt):
  • ctx->flux_data_header.identifier == FluxDataBlock
  • ctx->flux_data_header.entries > 0 implies ctx->flux_entries != NULL
  • ctx->flux_capture_map is populated with entries mapping identifiers to indices
  • ctx->imageInfo.ImageSize incremented by flux data size
  • ctx->flux_captures == NULL (cleared if it existed)

Limitations / Caveats:

  • No explicit status code: callers infer success by inspecting ctx->flux_data_header.entries and presence of ctx->flux_entries after invocation.
  • In case of CRC mismatch, flux_entries are retained but flux_capture_map is not built, so entries are not accessible via lookup functions. Caller may wish to discard them or trigger re-read.
  • The function is idempotent in terms of memory (cleans up before processing), but is expected to be called exactly once per context lifetime during image opening.

Logging strategy:

  • FATAL used for unrecoverable structural or resource errors (seek failure, allocation failure, map rebuild failure).
  • TRACE used for informational / soft failures (e.g., CRC mismatch, identifier mismatch, short read).

Parameters
ctxMutable pointer to an aaruformatContext receiving parsed flux metadata.
entryPointer to the index entry describing this Flux Data block (offset required; size not strictly used beyond informational logging and sequential reading).
Returns
void This function does not return a status code; errors are reported via logging side effects.
Warning
Absence of a returned status requires defensive post-call validation by the caller.
CRC mismatch leaves possibly invalid data in ctx->flux_entries, and the lookup map is not built, making entries inaccessible via lookup functions.
Map rebuild failure results in complete cleanup of flux-related state, leaving the context without flux data even if the entries were successfully read and validated.
See also
flux_map_rebuild_from_entries() for the map rebuilding logic
flux_map_clear() for the map clearing logic
aaruf_read_flux_capture() for using the lookup map to access flux captures

Definition at line 307 of file flux.c.

References aaruf_crc64_data(), AARUF_STATUS_OK, FluxHeader::crc64, FluxHeader::entries, FATAL, aaruformat_context::flux_captures, aaruformat_context::flux_data_header, aaruformat_context::flux_entries, flux_map_clear(), flux_map_rebuild_from_entries(), FluxDataBlock, FluxHeader::identifier, aaruformat_context::image_info, ImageInfo::ImageSize, aaruformat_context::imageStream, IndexEntry::offset, and TRACE.

Referenced by ensure_flux_entries_loaded().

◆ read_flux_payload_header()

int32_t read_flux_payload_header ( const aaruformat_context * ctx,
uint64_t payload_offset,
DataStreamPayloadHeader * header )
static

Read and validate a flux payload block header from the image stream.

Parameters
ctxPointer to the aaruformat context. Must not be NULL.
payload_offsetFile offset where the payload block starts.
headerOutput parameter for the read header. Must not be NULL.
Returns
AARUF_STATUS_OK on success, or an error code on failure.

Definition at line 865 of file flux.c.

References AARUF_ERROR_CANNOT_READ_BLOCK, AARUF_STATUS_OK, DataStreamPayloadBlock, DataStreamPayloadHeader::dataType, FATAL, FluxData, DataStreamPayloadHeader::identifier, aaruformat_context::imageStream, and TRACE.

Referenced by aaruf_read_flux_capture().

◆ read_lzma_compressed_payload()

int32_t read_lzma_compressed_payload ( const aaruformat_context * ctx,
size_t cmp_length,
size_t raw_length,
uint8_t ** cmp_buffer,
uint8_t ** payload )
static

Read and decompress an LZMA-compressed flux payload from the image stream.

Parameters
ctxPointer to the aaruformat context. Must not be NULL.
cmp_lengthCompressed length including LZMA properties.
raw_lengthExpected uncompressed length.
cmp_bufferOutput parameter for compressed buffer pointer (caller must free). Can be NULL if allocation fails.
payloadOutput parameter for decompressed payload buffer pointer (caller must free). Can be NULL if allocation fails.
Returns
AARUF_STATUS_OK on success, or an error code on failure.

Definition at line 971 of file flux.c.

References AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK, AARUF_ERROR_CANNOT_READ_BLOCK, AARUF_ERROR_NOT_ENOUGH_MEMORY, aaruf_lzma_decode_buffer(), AARUF_STATUS_OK, FATAL, aaruformat_context::imageStream, LZMA_PROPERTIES_LENGTH, and TRACE.

Referenced by aaruf_read_flux_capture().

◆ read_uncompressed_payload()

int32_t read_uncompressed_payload ( const aaruformat_context * ctx,
size_t cmp_length,
size_t raw_length,
uint8_t ** cmp_buffer,
uint8_t ** payload )
static

Read an uncompressed flux payload from the image stream.

Parameters
ctxPointer to the aaruformat context. Must not be NULL.
cmp_lengthCompressed length (should equal raw_length for uncompressed).
raw_lengthUncompressed length.
cmp_bufferOutput parameter for compressed buffer pointer (caller must free). Can be NULL if allocation fails.
payloadOutput parameter for payload buffer pointer (same as cmp_buffer for uncompressed).
Returns
AARUF_STATUS_OK on success, or an error code on failure.

Definition at line 921 of file flux.c.

References AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK, AARUF_ERROR_CANNOT_READ_BLOCK, AARUF_ERROR_NOT_ENOUGH_MEMORY, AARUF_STATUS_OK, FATAL, aaruformat_context::imageStream, and TRACE.

Referenced by aaruf_read_flux_capture().

◆ validate_flux_payload_crcs()

int32_t validate_flux_payload_crcs ( const uint8_t * cmp_buffer,
size_t cmp_length,
const uint8_t * payload,
size_t raw_length,
uint64_t expected_cmp_crc,
uint64_t expected_raw_crc )
static

Validate CRC64 checksums for a flux payload block.

Parameters
cmp_bufferCompressed buffer to validate. Can be NULL if cmp_length is 0.
cmp_lengthCompressed length.
payloadUncompressed payload buffer to validate. Can be NULL if raw_length is 0.
raw_lengthUncompressed length.
expected_cmp_crcExpected CRC64 of compressed data.
expected_raw_crcExpected CRC64 of uncompressed data.
Returns
AARUF_STATUS_OK on success, or AARUF_ERROR_INVALID_BLOCK_CRC on mismatch.

Definition at line 1048 of file flux.c.

References aaruf_crc64_data(), AARUF_ERROR_INVALID_BLOCK_CRC, AARUF_STATUS_OK, FATAL, and TRACE.

Referenced by aaruf_read_flux_capture().

Variable Documentation

◆ FLUX_CAPTURE_RECORD_ICD

const UT_icd FLUX_CAPTURE_RECORD_ICD = {sizeof(FluxCaptureRecord), NULL, NULL, flux_capture_record_dtor}
static

Definition at line 65 of file flux.c.

Referenced by aaruf_write_flux_capture().