Use uthash for media tags handling.

This commit is contained in:
2022-10-04 20:32:26 +01:00
parent 303b870410
commit 0837a549b7
5 changed files with 55 additions and 83 deletions

View File

@@ -46,6 +46,14 @@ typedef struct Checksums
uint8_t* spamsum; uint8_t* spamsum;
} Checksums; } Checksums;
typedef struct mediaTagEntry
{
uint8_t* data;
int32_t type;
uint32_t length;
UT_hash_handle hh;
} mediaTagEntry;
typedef struct aaruformatContext typedef struct aaruformatContext
{ {
uint64_t magic; uint64_t magic;
@@ -53,8 +61,6 @@ typedef struct aaruformatContext
uint8_t libraryMinorVersion; uint8_t libraryMinorVersion;
FILE* imageStream; FILE* imageStream;
AaruHeader header; AaruHeader header;
struct dataLinkedList* mediaTagsHead;
struct dataLinkedList* mediaTagsTail;
uint8_t* sectorPrefix; uint8_t* sectorPrefix;
uint8_t* sectorPrefixCorrected; uint8_t* sectorPrefixCorrected;
uint8_t* sectorSuffix; uint8_t* sectorSuffix;
@@ -84,17 +90,9 @@ typedef struct aaruformatContext
struct CacheHeader blockHeaderCache; struct CacheHeader blockHeaderCache;
struct CacheHeader blockCache; struct CacheHeader blockCache;
struct Checksums checksums; struct Checksums checksums;
struct mediaTagEntry* mediaTags;
} aaruformatContext; } aaruformatContext;
typedef struct dataLinkedList
{
struct dataLinkedList* previous;
struct dataLinkedList* next;
uint8_t* data;
int32_t type;
uint32_t length;
} dataLinkedList;
typedef struct DumpHardwareEntriesWithData typedef struct DumpHardwareEntriesWithData
{ {
DumpHardwareEntry entry; DumpHardwareEntry entry;

View File

@@ -29,6 +29,8 @@
int aaruf_close(void* context) int aaruf_close(void* context)
{ {
int i; int i;
mediaTagEntry* mediaTag;
mediaTagEntry* tmpMediaTag;
if(context == NULL) if(context == NULL)
{ {
@@ -65,28 +67,14 @@ int aaruf_close(void* context)
free(ctx->mode2Subheaders); free(ctx->mode2Subheaders);
ctx->mode2Subheaders = NULL; ctx->mode2Subheaders = NULL;
if(ctx->mediaTagsTail != NULL) if(ctx->mediaTags != NULL)
{ {
dataLinkedList* mediaTag = ctx->mediaTagsTail; HASH_ITER(hh, ctx->mediaTags, mediaTag, tmpMediaTag)
while(mediaTag->previous != NULL)
{ {
HASH_DEL(ctx->mediaTags, mediaTag);
free(mediaTag->data); free(mediaTag->data);
mediaTag->data = NULL; free(mediaTag);
mediaTag = mediaTag->previous;
free(mediaTag->next);
mediaTag->next = NULL;
} }
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 #ifdef __linux__ // TODO: Implement

View File

@@ -47,6 +47,8 @@ void* aaruf_open(const char* filepath)
size_t lzmaSize; size_t lzmaSize;
ChecksumHeader checksum_header; ChecksumHeader checksum_header;
ChecksumEntry* checksum_entry; ChecksumEntry* checksum_entry;
mediaTagEntry* mediaTag;
mediaTagEntry* oldMediaTag;
ctx = (aaruformatContext*)malloc(sizeof(aaruformatContext)); ctx = (aaruformatContext*)malloc(sizeof(aaruformatContext));
memset(ctx, 0, sizeof(aaruformatContext)); memset(ctx, 0, sizeof(aaruformatContext));
@@ -400,8 +402,6 @@ void* aaruf_open(const char* filepath)
break; break;
} }
dataLinkedList* mediaTag = NULL;
// Check if it's not a media tag, but a sector tag, and fill the appropriate table then // Check if it's not a media tag, but a sector tag, and fill the appropriate table then
switch(idxEntries[i].dataType) switch(idxEntries[i].dataType)
{ {
@@ -439,50 +439,28 @@ void* aaruf_open(const char* filepath)
break; break;
case CompactDiscMode2Subheader: ctx->mode2Subheaders = data; break; case CompactDiscMode2Subheader: ctx->mode2Subheaders = data; break;
default: default:
if(ctx->mediaTagsHead != NULL) mediaTag = (mediaTagEntry*)malloc(sizeof(mediaTagEntry));
{
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));
if(mediaTag == NULL) 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; break;
} }
memset(mediaTag, 0, sizeof(dataLinkedList)); memset(mediaTag, 0, sizeof(mediaTagEntry));
mediaTag->type = aaruf_get_media_tag_type_for_datatype(blockHeader.type); mediaTag->type = aaruf_get_media_tag_type_for_datatype(blockHeader.type);
mediaTag->data = data; mediaTag->data = data;
mediaTag->length = blockHeader.length; mediaTag->length = blockHeader.length;
if(ctx->mediaTagsHead == NULL) { ctx->mediaTagsHead = mediaTag; } HASH_REPLACE_INT(ctx->mediaTags, type, mediaTag, oldMediaTag);
else
{
mediaTag->previous = ctx->mediaTagsTail;
ctx->mediaTagsTail->next = mediaTag;
}
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; break;
} }

View File

@@ -24,7 +24,7 @@
int32_t aaruf_read_media_tag(void* context, uint8_t* data, int32_t tag, uint32_t* length) int32_t aaruf_read_media_tag(void* context, uint8_t* data, int32_t tag, uint32_t* length)
{ {
aaruformatContext* ctx; aaruformatContext* ctx;
dataLinkedList* item; mediaTagEntry* item;
if(context == NULL) return AARUF_ERROR_NOT_AARUFORMAT; if(context == NULL) return AARUF_ERROR_NOT_AARUFORMAT;
@@ -33,12 +33,14 @@ int32_t aaruf_read_media_tag(void* context, uint8_t* data, int32_t tag, uint32_t
// Not a libaaruformat context // Not a libaaruformat context
if(ctx->magic != AARU_MAGIC) return AARUF_ERROR_NOT_AARUFORMAT; 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)
{ {
*length = 0;
return AARUF_ERROR_MEDIA_TAG_NOT_PRESENT;
}
if(data == NULL || *length < item->length) if(data == NULL || *length < item->length)
{ {
*length = item->length; *length = item->length;
@@ -47,13 +49,8 @@ int32_t aaruf_read_media_tag(void* context, uint8_t* data, int32_t tag, uint32_t
*length = item->length; *length = item->length;
memcpy(data, item->data, item->length); memcpy(data, item->data, item->length);
}
item = item->next; return AARUF_STATUS_OK;
}
*length = 0;
return AARUF_ERROR_MEDIA_TAG_NOT_PRESENT;
} }
int32_t aaruf_read_sector(void* context, uint64_t sectorAddress, uint8_t* data, uint32_t* length) int32_t aaruf_read_sector(void* context, uint64_t sectorAddress, uint8_t* data, uint32_t* length)

View File

@@ -31,6 +31,8 @@ int info(char* path)
char* strBuffer; char* strBuffer;
UErrorCode u_error_code; UErrorCode u_error_code;
uint i, j; uint i, j;
mediaTagEntry* mediaTag;
mediaTagEntry* tmpMediaTag;
ctx = aaruf_open(path); 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->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); aaruf_close(ctx);
return 0; return 0;