The endianness of an OBIDMS is now stored in an informations file that

is read when opening the OBIDMS.
This commit is contained in:
Celine Mercier
2015-11-16 14:37:51 +01:00
parent 6579566c6e
commit e8417b4f6f
5 changed files with 165 additions and 15 deletions

View File

@ -66,12 +66,12 @@ cdef class OBIDMS :
cpdef close(self) :
#TODO close all columns
#TODO close all columns (needs to be discussed)
if (obi_close_dms(self.pointer)) < 0 :
raise Exception("Problem closing an OBIDMS")
cpdef dict list(self):
cpdef dict list(self): # TDODO This is a temporary function that will be rewritten
# Declarations
cdef object p
@ -100,13 +100,12 @@ cdef class OBIDMS :
data_type = bytes2str(name_data_type(header.data_type))
line_count = header.line_count
creation_date = bytes2str(obi_column_format_date(header.creation_date))
obi_unmap_header(header) # TODO check if error? but C will already warn and there's nothing to do
obi_unmap_header(header)
latest_version = obi_column_get_latest_version_from_name(self.pointer, column_name_b)
dms[column_name]['data_type'] = data_type
dms[column_name]['latest_version'] = latest_version
dms[column_name]['line_count'] = line_count
dms[column_name]['creation_date'] = creation_date
# TODO : actually get all the informations in the header
print("{:<30} {:<12} {:<25} {:<30} {:<40}".format(column_name, data_type, latest_version, line_count, creation_date))
return dms

View File

@ -15,7 +15,6 @@ from ..capi.obitypes cimport const_char_p, \
cdef extern from "obidmscolumn.h" nogil:
struct OBIDMS_column_header_t:
bint little_endian
size_t header_size
size_t data_size
index_t line_count

View File

@ -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;
}

View File

@ -26,7 +26,7 @@
#define OBIDMS_MAX_NAME (2048) /**< The maximum length of an OBIDMS name.
*/
#define ARRAY_DIR_NAME "arrays" /**< The name of the arrays directory.
#define ARRAYS_DIR_NAME "arrays" /**< The name of the arrays directory.
*/

View File

@ -339,7 +339,7 @@ static obiversion_t create_version_file(OBIDMS_column_directory_p column_directo
return -1;
}
// Position offset to 0 to prepare for writing
// Position offset to 0 to prepare for writing // TODO Unnecessary?
if (lseek(version_file_descriptor, 0, SEEK_SET) != 0)
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
@ -358,7 +358,7 @@ static obiversion_t create_version_file(OBIDMS_column_directory_p column_directo
}
// Prepare for unlocking
if (lseek(version_file_descriptor, 0, SEEK_SET) != 0)
if (lseek(version_file_descriptor, 0, SEEK_SET) != 0) // TODO Unnecessary?
{
obi_set_errno(OBICOL_UNKNOWN_ERROR);
obidebug(1, "\nError preparing a version file for unlocking");