The endianness of an OBIDMS is now stored in an informations file that
is read when opening the OBIDMS.
This commit is contained in:
166
src/obidms.c
166
src/obidms.c
@ -23,6 +23,7 @@
|
||||
#include "obidebug.h"
|
||||
#include "obidmscolumn.h"
|
||||
#include "private_at_functions.h"
|
||||
#include "obilittlebigman.h"
|
||||
|
||||
|
||||
#define DEBUG_LEVEL 0 // TODO has to be defined somewhere else (cython compil flag?)
|
||||
@ -54,6 +55,44 @@
|
||||
static char* build_directory_name(const char* dms_name);
|
||||
|
||||
|
||||
/**
|
||||
* Internal function building the informations file name from an OBIDMS name.
|
||||
*
|
||||
* The function builds the file name for the informations file of an OBIDMS.
|
||||
*
|
||||
* @warning The returned pointer has to be freed by the caller.
|
||||
*
|
||||
* @param dms_name The name of the OBIDMS.
|
||||
*
|
||||
* @returns A pointer to the file name.
|
||||
* @retval NULL if an error occurred.
|
||||
*
|
||||
* @since November 2015
|
||||
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
||||
*/
|
||||
static char* build_infos_file_name(const char* dms_name);
|
||||
|
||||
|
||||
/**
|
||||
* Internal function creating the file containing basic informations on the OBIDMS.
|
||||
*
|
||||
* This file contains:
|
||||
* - The endianness of the platform
|
||||
*
|
||||
* @warning The returned pointer has to be freed by the caller.
|
||||
*
|
||||
* @param dms_file_descriptor The file descriptor for the OBIDMS directory.
|
||||
* @param dms_name The name of the OBIDMS.
|
||||
*
|
||||
* @retval 0 if the operation was successfully completed.
|
||||
* @retval -1 if an error occurred.
|
||||
*
|
||||
* @since November 2015
|
||||
* @author Celine Mercier (celine.mercier@metabarcoding.org)
|
||||
*/
|
||||
int create_dms_infos_file(int dms_file_descriptor, const char* dms_name);
|
||||
|
||||
|
||||
/************************************************************************
|
||||
*
|
||||
* D E F I N I T I O N O F T H E P R I V A T E F U N C T I O N S
|
||||
@ -85,6 +124,74 @@ static char* build_directory_name(const char* dms_name)
|
||||
}
|
||||
|
||||
|
||||
static char* build_infos_file_name(const char* dms_name)
|
||||
{
|
||||
char* file_name;
|
||||
|
||||
// Build file name
|
||||
if (asprintf(&file_name, "%s_infos", dms_name) < 0)
|
||||
{
|
||||
obi_set_errno(OBIDMS_MEMORY_ERROR);
|
||||
obidebug(1, "\nProblem building an informations file name");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return file_name;
|
||||
}
|
||||
|
||||
|
||||
int create_dms_infos_file(int dms_file_descriptor, const char* dms_name)
|
||||
{
|
||||
char* file_name;
|
||||
int infos_file_descriptor;
|
||||
off_t file_size;
|
||||
bool little_endian;
|
||||
|
||||
file_size = sizeof(bool);
|
||||
|
||||
// Create file name
|
||||
file_name = build_infos_file_name(dms_name);
|
||||
if (file_name == NULL)
|
||||
return -1;
|
||||
|
||||
// Create file
|
||||
infos_file_descriptor = openat(dms_file_descriptor, file_name, O_RDWR | O_CREAT | O_EXCL, 0777);
|
||||
if (infos_file_descriptor < 0)
|
||||
{
|
||||
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
|
||||
obidebug(1, "\nError creating an informations file");
|
||||
free(file_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(file_name);
|
||||
|
||||
// Truncate the infos file to the right size
|
||||
if (ftruncate(infos_file_descriptor, file_size) < 0)
|
||||
{
|
||||
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
|
||||
obidebug(1, "\nError truncating an informations file");
|
||||
close(infos_file_descriptor);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Write endianness
|
||||
little_endian = obi_is_little_endian();
|
||||
if (write(infos_file_descriptor, &little_endian, sizeof(bool)) < ((ssize_t) sizeof(bool)))
|
||||
{
|
||||
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
|
||||
obidebug(1, "\nError writing the endianness in an informations file");
|
||||
close(infos_file_descriptor);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Close file
|
||||
close(infos_file_descriptor);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* D E F I N I T I O N O F T H E P U B L I C F U N C T I O N S
|
||||
@ -116,8 +223,8 @@ int obi_dms_exists(const char* dms_name)
|
||||
OBIDMS_p obi_create_dms(const char* dms_name)
|
||||
{
|
||||
char* directory_name;
|
||||
DIR* dms_dir;
|
||||
int dms_file_descriptor;
|
||||
DIR* dms_dir;
|
||||
int dms_file_descriptor;
|
||||
|
||||
// Build and check the directory name
|
||||
directory_name = build_directory_name(dms_name);
|
||||
@ -160,13 +267,17 @@ OBIDMS_p obi_create_dms(const char* dms_name)
|
||||
}
|
||||
|
||||
// Create the arrays directory
|
||||
if (mkdirat(dms_file_descriptor, ARRAY_DIR_NAME, 00777) < 0)
|
||||
if (mkdirat(dms_file_descriptor, ARRAYS_DIR_NAME, 00777) < 0)
|
||||
{
|
||||
obi_set_errno(OBI_ARRAY_ERROR);
|
||||
obidebug(1, "\nProblem creating an arrays directory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Create the informations file
|
||||
if (create_dms_infos_file(dms_file_descriptor, dms_name) < 0)
|
||||
return NULL;
|
||||
|
||||
return obi_open_dms(dms_name);
|
||||
}
|
||||
|
||||
@ -175,6 +286,10 @@ OBIDMS_p obi_open_dms(const char* dms_name)
|
||||
{
|
||||
OBIDMS_p dms;
|
||||
char* directory_name;
|
||||
char* infos_file_name;
|
||||
int infos_file_descriptor;
|
||||
bool little_endian_dms;
|
||||
bool little_endian_platform;
|
||||
|
||||
dms = NULL;
|
||||
|
||||
@ -224,7 +339,7 @@ OBIDMS_p obi_open_dms(const char* dms_name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get file descriptor of DMS directory to open the arrays directory
|
||||
// Get and store file descriptor of DMS directory to open the informations file
|
||||
dms->dir_fd = dirfd(dms->directory);
|
||||
if (dms->dir_fd < 0)
|
||||
{
|
||||
@ -235,8 +350,45 @@ OBIDMS_p obi_open_dms(const char* dms_name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Open informations file to check endianness
|
||||
infos_file_name = build_infos_file_name(dms_name);
|
||||
infos_file_descriptor = openat(dms->dir_fd, infos_file_name, O_RDONLY, 0777);
|
||||
if (infos_file_descriptor < 0)
|
||||
{
|
||||
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
|
||||
obidebug(1, "\nError opening an informations file");
|
||||
closedir(dms->directory);
|
||||
free(dms);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free(infos_file_name);
|
||||
|
||||
// Check endianness of the platform and DMS
|
||||
little_endian_platform = obi_is_little_endian();
|
||||
if (read(infos_file_descriptor, &little_endian_dms, sizeof(bool)) < ((ssize_t) sizeof(bool)))
|
||||
{
|
||||
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
|
||||
obidebug(1, "\nError reading the endianness in an informations file");
|
||||
close(infos_file_descriptor);
|
||||
closedir(dms->directory);
|
||||
free(dms);
|
||||
return NULL;
|
||||
}
|
||||
if (little_endian_platform != little_endian_dms)
|
||||
{
|
||||
obi_set_errno(OBIDMS_BAD_ENDIAN_ERROR);
|
||||
obidebug(1, "\nError: The DMS and the platform have different endianness");
|
||||
close(infos_file_descriptor);
|
||||
closedir(dms->directory);
|
||||
free(dms);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
close(infos_file_descriptor);
|
||||
|
||||
// Open the arrays directory
|
||||
dms->array_directory = private_opendirat(dms->dir_fd, ARRAY_DIR_NAME);
|
||||
dms->array_directory = private_opendirat(dms->dir_fd, ARRAYS_DIR_NAME);
|
||||
if (dms->array_directory == NULL)
|
||||
{
|
||||
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
|
||||
@ -251,9 +403,9 @@ OBIDMS_p obi_open_dms(const char* dms_name)
|
||||
if (dms->array_dir_fd < 0)
|
||||
{
|
||||
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
|
||||
obidebug(1, "\nError opening the arrays directory");
|
||||
closedir(dms->directory);
|
||||
obidebug(1, "\nError getting the file descriptor of the arrays directory");
|
||||
closedir(dms->array_directory);
|
||||
closedir(dms->directory);
|
||||
free(dms);
|
||||
return NULL;
|
||||
}
|
||||
|
Reference in New Issue
Block a user