From 0837a549b77441ce70e4c037061be9a7471e1bad Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Tue, 4 Oct 2022 20:32:26 +0100 Subject: [PATCH] Use uthash for media tags handling. --- include/aaruformat/context.h | 20 +++++++-------- src/close.c | 26 ++++++------------- src/open.c | 48 ++++++++++-------------------------- src/read.c | 33 +++++++++++-------------- tool/info.c | 11 +++++++++ 5 files changed, 55 insertions(+), 83 deletions(-) diff --git a/include/aaruformat/context.h b/include/aaruformat/context.h index 818be35..6f404f7 100644 --- a/include/aaruformat/context.h +++ b/include/aaruformat/context.h @@ -46,6 +46,14 @@ typedef struct Checksums uint8_t* spamsum; } Checksums; +typedef struct mediaTagEntry +{ + uint8_t* data; + int32_t type; + uint32_t length; + UT_hash_handle hh; +} mediaTagEntry; + typedef struct aaruformatContext { uint64_t magic; @@ -53,8 +61,6 @@ typedef struct aaruformatContext uint8_t libraryMinorVersion; FILE* imageStream; AaruHeader header; - struct dataLinkedList* mediaTagsHead; - struct dataLinkedList* mediaTagsTail; uint8_t* sectorPrefix; uint8_t* sectorPrefixCorrected; uint8_t* sectorSuffix; @@ -84,17 +90,9 @@ typedef struct aaruformatContext struct CacheHeader blockHeaderCache; struct CacheHeader blockCache; struct Checksums checksums; + struct mediaTagEntry* mediaTags; } aaruformatContext; -typedef struct dataLinkedList -{ - struct dataLinkedList* previous; - struct dataLinkedList* next; - uint8_t* data; - int32_t type; - uint32_t length; -} dataLinkedList; - typedef struct DumpHardwareEntriesWithData { DumpHardwareEntry entry; diff --git a/src/close.c b/src/close.c index ca1574b..8446849 100644 --- a/src/close.c +++ b/src/close.c @@ -28,7 +28,9 @@ int aaruf_close(void* context) { - int i; + int i; + mediaTagEntry* mediaTag; + mediaTagEntry* tmpMediaTag; if(context == NULL) { @@ -65,28 +67,14 @@ int aaruf_close(void* context) free(ctx->mode2Subheaders); ctx->mode2Subheaders = NULL; - if(ctx->mediaTagsTail != NULL) + if(ctx->mediaTags != NULL) { - dataLinkedList* mediaTag = ctx->mediaTagsTail; - - while(mediaTag->previous != NULL) + HASH_ITER(hh, ctx->mediaTags, mediaTag, tmpMediaTag) { + HASH_DEL(ctx->mediaTags, mediaTag); free(mediaTag->data); - mediaTag->data = NULL; - mediaTag = mediaTag->previous; - free(mediaTag->next); - mediaTag->next = NULL; + free(mediaTag); } - - ctx->mediaTagsTail = NULL; - } - - if(ctx->mediaTagsHead != NULL) - { - free(ctx->mediaTagsHead->data); - ctx->mediaTagsHead->data = NULL; - free(ctx->mediaTagsHead); - ctx->mediaTagsHead = NULL; } #ifdef __linux__ // TODO: Implement diff --git a/src/open.c b/src/open.c index bd861eb..c6e6864 100644 --- a/src/open.c +++ b/src/open.c @@ -47,6 +47,8 @@ void* aaruf_open(const char* filepath) size_t lzmaSize; ChecksumHeader checksum_header; ChecksumEntry* checksum_entry; + mediaTagEntry* mediaTag; + mediaTagEntry* oldMediaTag; ctx = (aaruformatContext*)malloc(sizeof(aaruformatContext)); memset(ctx, 0, sizeof(aaruformatContext)); @@ -400,8 +402,6 @@ void* aaruf_open(const char* filepath) break; } - dataLinkedList* mediaTag = NULL; - // Check if it's not a media tag, but a sector tag, and fill the appropriate table then switch(idxEntries[i].dataType) { @@ -439,50 +439,28 @@ void* aaruf_open(const char* filepath) break; case CompactDiscMode2Subheader: ctx->mode2Subheaders = data; break; default: - if(ctx->mediaTagsHead != NULL) - { - mediaTag = ctx->mediaTagsHead; - while(mediaTag != NULL) - { - if(mediaTag->type == blockHeader.type) - { - fprintf(stderr, - "libaaruformat: Media tag type %d duplicated, removing previous entry...\n", - blockHeader.type); - free(mediaTag->data); - mediaTag->data = data; - break; - } - - mediaTag = mediaTag->next; - } - } - - // If the mediaTag is NULL means we have arrived the end of the list without finding a duplicate - // or the list was empty - if(mediaTag != NULL) break; - - mediaTag = (dataLinkedList*)malloc(sizeof(dataLinkedList)); + mediaTag = (mediaTagEntry*)malloc(sizeof(mediaTagEntry)); if(mediaTag == NULL) { - fprintf(stderr, "libaaruformat: Cannot allocate memory for media tag list entry.\n"); + fprintf(stderr, "libaaruformat: Cannot allocate memory for media tag entry.\n"); break; } - memset(mediaTag, 0, sizeof(dataLinkedList)); + memset(mediaTag, 0, sizeof(mediaTagEntry)); mediaTag->type = aaruf_get_media_tag_type_for_datatype(blockHeader.type); mediaTag->data = data; mediaTag->length = blockHeader.length; - if(ctx->mediaTagsHead == NULL) { ctx->mediaTagsHead = mediaTag; } - else - { - mediaTag->previous = ctx->mediaTagsTail; - ctx->mediaTagsTail->next = mediaTag; - } + HASH_REPLACE_INT(ctx->mediaTags, type, mediaTag, oldMediaTag); - ctx->mediaTagsTail = mediaTag; + if(oldMediaTag != NULL) + { + fprintf(stderr, "libaaruformat: Replaced media tag with type %d\n", oldMediaTag->type); + free(oldMediaTag->data); + free(oldMediaTag); + oldMediaTag = NULL; + } break; } diff --git a/src/read.c b/src/read.c index 36bfa72..9f7203d 100644 --- a/src/read.c +++ b/src/read.c @@ -24,7 +24,7 @@ int32_t aaruf_read_media_tag(void* context, uint8_t* data, int32_t tag, uint32_t* length) { aaruformatContext* ctx; - dataLinkedList* item; + mediaTagEntry* item; if(context == NULL) return AARUF_ERROR_NOT_AARUFORMAT; @@ -33,27 +33,24 @@ int32_t aaruf_read_media_tag(void* context, uint8_t* data, int32_t tag, uint32_t // Not a libaaruformat context if(ctx->magic != AARU_MAGIC) return AARUF_ERROR_NOT_AARUFORMAT; - item = ctx->mediaTagsHead; + HASH_FIND_INT(ctx->mediaTags, &tag, item); - while(item != NULL) + if(item == NULL) { - if(item->type == tag) - { - if(data == NULL || *length < item->length) - { - *length = item->length; - return AARUF_ERROR_BUFFER_TOO_SMALL; - } - - *length = item->length; - memcpy(data, item->data, item->length); - } - - item = item->next; + *length = 0; + return AARUF_ERROR_MEDIA_TAG_NOT_PRESENT; } - *length = 0; - return AARUF_ERROR_MEDIA_TAG_NOT_PRESENT; + if(data == NULL || *length < item->length) + { + *length = item->length; + return AARUF_ERROR_BUFFER_TOO_SMALL; + } + + *length = item->length; + memcpy(data, item->data, item->length); + + return AARUF_STATUS_OK; } int32_t aaruf_read_sector(void* context, uint64_t sectorAddress, uint8_t* data, uint32_t* length) diff --git a/tool/info.c b/tool/info.c index 37f610b..03103c7 100644 --- a/tool/info.c +++ b/tool/info.c @@ -31,6 +31,8 @@ int info(char* path) char* strBuffer; UErrorCode u_error_code; uint i, j; + mediaTagEntry* mediaTag; + mediaTagEntry* tmpMediaTag; ctx = aaruf_open(path); @@ -532,6 +534,15 @@ int info(char* path) if(ctx->checksums.hasSpamSum) printf("SpamSum: %s\n", ctx->checksums.spamsum); + if(ctx->mediaTags != NULL) + { + printf("Media tags:\n"); + HASH_ITER(hh, ctx->mediaTags, mediaTag, tmpMediaTag) + { + printf("\tType %d is %d bytes long.\n", mediaTag->type, mediaTag->length); + } + } + aaruf_close(ctx); return 0;