mirror of
https://github.com/aaru-dps/libaaruformat.git
synced 2025-12-16 19:24:40 +00:00
Read and traverse the index.
This commit is contained in:
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.13)
|
|||||||
project(libdicformat C)
|
project(libdicformat C)
|
||||||
|
|
||||||
set(CMAKE_C_STANDARD 99)
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
add_compile_definitions(__STDC_FORMAT_MACROS=1)
|
||||||
|
|
||||||
add_library(libdicformat SHARED include/dicformat/consts.h include/dicformat/enums.h include/dic.h include/dicformat.h
|
add_library(libdicformat SHARED include/dicformat/consts.h include/dicformat/enums.h include/dic.h include/dicformat.h
|
||||||
include/dicformat/decls.h include/dicformat/structs.h src/identify.c src/open.c include/dicformat/context.h src/close.c include/dicformat/errors.h)
|
include/dicformat/decls.h include/dicformat/structs.h src/identify.c src/open.c include/dicformat/context.h src/close.c include/dicformat/errors.h)
|
||||||
|
|||||||
@@ -15,6 +15,16 @@ typedef struct dicformatContext
|
|||||||
uint8_t libraryMinorVersion;
|
uint8_t libraryMinorVersion;
|
||||||
FILE *imageStream;
|
FILE *imageStream;
|
||||||
DicHeader header;
|
DicHeader header;
|
||||||
|
struct dataLinkedList *mediaTagsHead;
|
||||||
|
struct dataLinkedList *mediaTagsTail;
|
||||||
} dicformatContext;
|
} dicformatContext;
|
||||||
|
|
||||||
|
typedef struct dataLinkedList
|
||||||
|
{
|
||||||
|
struct dataLinkedList *previous;
|
||||||
|
struct dataLinkedList *next;
|
||||||
|
unsigned char *data;
|
||||||
|
int type;
|
||||||
|
} dataLinkedList;
|
||||||
|
|
||||||
#endif //LIBDICFORMAT_CONTEXT_H
|
#endif //LIBDICFORMAT_CONTEXT_H
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ typedef enum
|
|||||||
/** Block containing a deduplication table */
|
/** Block containing a deduplication table */
|
||||||
DeDuplicationTable = 0X2A544444,
|
DeDuplicationTable = 0X2A544444,
|
||||||
/** Block containing the index */
|
/** Block containing the index */
|
||||||
Index = 0X58444E49,
|
IndexBlock = 0X58444E49,
|
||||||
/** Block containing logical geometry */
|
/** Block containing logical geometry */
|
||||||
GeometryBlock = 0x4D4F4547,
|
GeometryBlock = 0x4D4F4547,
|
||||||
/** Block containing metadata */
|
/** Block containing metadata */
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#define DICF_ERROR_NOT_DICFORMAT -1
|
#define DICF_ERROR_NOT_DICFORMAT -1
|
||||||
#define DICF_ERROR_FILE_TOO_SMALL -2
|
#define DICF_ERROR_FILE_TOO_SMALL -2
|
||||||
#define DICF_ERROR_INCOMPATIBLE_VERSION -2
|
#define DICF_ERROR_INCOMPATIBLE_VERSION -3
|
||||||
|
#define DICF_ERROR_CANNOT_READ_INDEX -4
|
||||||
|
|
||||||
#endif //LIBDICFORMAT_ERRORS_H
|
#endif //LIBDICFORMAT_ERRORS_H
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ typedef struct IndexHeader
|
|||||||
typedef struct IndexEntry
|
typedef struct IndexEntry
|
||||||
{
|
{
|
||||||
/**Type of item pointed by this entry */
|
/**Type of item pointed by this entry */
|
||||||
uint32_t uint32_t;
|
uint32_t blockType;
|
||||||
/**Type of data contained by the block pointed by this entry */
|
/**Type of data contained by the block pointed by this entry */
|
||||||
uint16_t dataType;
|
uint16_t dataType;
|
||||||
/**Offset in file where item is stored */
|
/**Offset in file where item is stored */
|
||||||
|
|||||||
83
src/open.c
83
src/open.c
@@ -34,12 +34,21 @@
|
|||||||
#include <dicformat.h>
|
#include <dicformat.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// TODO: Check CRC64 on structures
|
||||||
|
// TODO: ImageInfo
|
||||||
void *open(const char *filepath)
|
void *open(const char *filepath)
|
||||||
{
|
{
|
||||||
dicformatContext *ctx = malloc(sizeof(dicformatContext));
|
dicformatContext *ctx = malloc(sizeof(dicformatContext));
|
||||||
int errorNo;
|
int errorNo;
|
||||||
size_t readBytes;
|
size_t readBytes;
|
||||||
|
long pos;
|
||||||
|
IndexHeader idxHeader;
|
||||||
|
IndexEntry *idxEntries;
|
||||||
|
|
||||||
|
memset(ctx, 0, sizeof(dicformatContext));
|
||||||
|
|
||||||
if(ctx == NULL)
|
if(ctx == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -82,14 +91,78 @@ void *open(const char *filepath)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fprintf(stderr,
|
||||||
|
"libdicformat: Opening image version %d.%d",
|
||||||
|
ctx->header.imageMajorVersion,
|
||||||
|
ctx->header.imageMinorVersion);
|
||||||
|
|
||||||
|
// Read the index header
|
||||||
|
pos = fseek(ctx->imageStream, ctx->header.indexOffset, SEEK_CUR);
|
||||||
|
if(pos < 0)
|
||||||
|
{
|
||||||
|
free(ctx);
|
||||||
|
errno = DICF_ERROR_CANNOT_READ_INDEX;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = ftell(ctx->imageStream);
|
||||||
|
if(pos != ctx->header.indexOffset)
|
||||||
|
{
|
||||||
|
free(ctx);
|
||||||
|
errno = DICF_ERROR_CANNOT_READ_INDEX;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
readBytes = fread(&idxHeader, sizeof(IndexHeader), 1, ctx->imageStream);
|
||||||
|
|
||||||
|
if(readBytes != sizeof(IndexHeader) || idxHeader.identifier != IndexBlock)
|
||||||
|
{
|
||||||
|
free(ctx);
|
||||||
|
errno = DICF_ERROR_CANNOT_READ_INDEX;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "libdicformat: Index at %"PRIu64" contains %d entries", ctx->header.indexOffset, idxHeader.entries);
|
||||||
|
|
||||||
|
idxEntries = malloc(sizeof(IndexEntry) * idxHeader.entries);
|
||||||
|
|
||||||
|
if(idxEntries == NULL)
|
||||||
|
{
|
||||||
|
errorNo = errno;
|
||||||
|
free(ctx);
|
||||||
|
errno = errorNo;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(idxEntries, 0, sizeof(IndexEntry) * idxHeader.entries);
|
||||||
|
readBytes = fread(idxEntries, sizeof(IndexEntry), idxHeader.entries, ctx->imageStream);
|
||||||
|
|
||||||
|
if(readBytes != sizeof(IndexEntry) * idxHeader.entries)
|
||||||
|
{
|
||||||
|
free(idxEntries);
|
||||||
|
free(ctx);
|
||||||
|
errno = DICF_ERROR_CANNOT_READ_INDEX;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < idxHeader.entries; i++)
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
"libdicformat: Block type %4s with data type %4s is indexed to be at %"PRIu64"",
|
||||||
|
(char *)&idxEntries[i].blockType,
|
||||||
|
(char *)&idxEntries[i].dataType,
|
||||||
|
idxEntries[i].offset);
|
||||||
|
}
|
||||||
|
|
||||||
ctx->magic = DIC_MAGIC;
|
ctx->magic = DIC_MAGIC;
|
||||||
ctx->libraryMajorVersion = LIBDICFORMAT_MAJOR_VERSION;
|
ctx->libraryMajorVersion = LIBDICFORMAT_MAJOR_VERSION;
|
||||||
ctx->libraryMinorVersion = LIBDICFORMAT_MINOR_VERSION;
|
ctx->libraryMinorVersion = LIBDICFORMAT_MINOR_VERSION;
|
||||||
|
|
||||||
fprintf(stderr,
|
free(idxEntries);
|
||||||
"libdicformat: Opened image version %d.%d",
|
|
||||||
ctx->header.imageMajorVersion,
|
|
||||||
ctx->header.imageMinorVersion);
|
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user