Commit c1393675 by Celine Mercier

DNA sequences and character strings are now handled using AVL trees.

parent 1586956d
......@@ -12,7 +12,7 @@
../../../src/obitypes.c
../../../src/private_at_functions.h
../../../src/private_at_functions.c
../../../src/obiarray.h
../../../src/obiarray.c
../../../src/obiavl.h
../../../src/obiavl.c
../../../src/encode.h
../../../src/encode.c
\ No newline at end of file
......@@ -25,7 +25,7 @@ cdef class OBIDMS:
index_t nb_lines=*,
index_t nb_elements_per_line=*,
list elements_names=*,
str array_name=*,
str avl_name=*,
str comments=*)
......
......@@ -133,7 +133,7 @@ cdef class OBIDMS :
index_t nb_lines=0,
index_t nb_elements_per_line=0,
list elements_names=None,
str array_name="default_obiarray",
str avl_name="default_AVL_tree",
str comments=""):
# Declarations
......@@ -263,7 +263,7 @@ cdef class OBIDMS :
referring,
version_number, data_type,
nb_lines, nb_elements_per_line,
elements_names, array_name,
elements_names, avl_name,
comments)
return column
......@@ -284,13 +284,13 @@ cdef class OBIDMS_column :
index_t nb_lines,
index_t nb_elements_per_line,
list elements_names,
str array_name,
str avl_name,
str comments):
# Declarations
cdef bytes column_name_b
cdef bytes dms_name_b
cdef bytes array_name_b
cdef bytes avl_name_b
cdef bytes elements_names_b
cdef bytes comments_b
......@@ -304,7 +304,7 @@ cdef class OBIDMS_column :
# Format the character strings to send them to C functions
column_name_b = str2bytes(column_name)
dms_name_b = str2bytes(self.dms.dms_name)
array_name_b = str2bytes(array_name)
avl_name_b = str2bytes(avl_name)
comments_b = str2bytes(comments)
# Create, clone or open column
......@@ -315,7 +315,7 @@ cdef class OBIDMS_column :
elements_names_b = str2bytes(";".join(elements_names))
self.pointer = obi_create_column(self.dms.pointer, column_name_b, type,
nb_lines, nb_elements_per_line,
elements_names_b, array_name_b, comments_b,
elements_names_b, avl_name_b, comments_b,
referring)
else :
if clone :
......
......@@ -14,5 +14,5 @@
../../../src/obitypes.c
../../../src/private_at_functions.h
../../../src/private_at_functions.c
../../../src/obiarray.h
../../../src/obiarray.c
../../../src/obiavl.h
../../../src/obiavl.c
......@@ -14,5 +14,5 @@
../../../src/obitypes.c
../../../src/private_at_functions.h
../../../src/private_at_functions.c
../../../src/obiarray.h
../../../src/obiarray.c
../../../src/obiavl.h
../../../src/obiavl.c
......@@ -14,5 +14,5 @@
../../../src/obitypes.c
../../../src/private_at_functions.h
../../../src/private_at_functions.c
../../../src/obiarray.h
../../../src/obiarray.c
../../../src/obiavl.h
../../../src/obiavl.c
......@@ -14,5 +14,5 @@
../../../src/obitypes.c
../../../src/private_at_functions.h
../../../src/private_at_functions.c
../../../src/obiarray.h
../../../src/obiarray.c
../../../src/obiavl.h
../../../src/obiavl.c
......@@ -14,5 +14,5 @@
../../../src/obitypes.c
../../../src/private_at_functions.h
../../../src/private_at_functions.c
../../../src/obiarray.h
../../../src/obiarray.c
../../../src/obiavl.h
../../../src/obiavl.c
......@@ -14,5 +14,5 @@
../../../src/obitypes.c
../../../src/private_at_functions.h
../../../src/private_at_functions.c
../../../src/obiarray.h
../../../src/obiarray.c
../../../src/obiavl.h
../../../src/obiavl.c
......@@ -30,7 +30,7 @@ cdef extern from "obidmscolumn.h" nogil:
bint referring
obiversion_t referred_column_version
const_char_p name
const_char_p array_name
const_char_p avl_name
const_char_p comments
ctypedef OBIDMS_column_header_t* OBIDMS_column_header_p
......@@ -47,7 +47,7 @@ cdef extern from "obidmscolumn.h" nogil:
index_t nb_lines,
index_t nb_elements_per_line,
const_char_p elements_names,
const_char_p array_name,
const_char_p avl_name,
const_char_p comments,
bint referring)
......
......@@ -16,7 +16,8 @@
#include <math.h>
#include "encode.h"
#include "obiarray.h"
#include "obierrno.h"
#include "obitypes.h" // For byte_t type
#include "obidebug.h"
......
......@@ -15,7 +15,7 @@
#include <stdint.h>
#include <stdbool.h>
#include "obiarray.h"
#include "obitypes.h"
#define NUC_MASK_2B 0x3 /**< Binary: 11 to use when decoding 2 bits sequences */
......
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
......@@ -247,7 +247,7 @@ OBIDMS_p obi_create_dms(const char* dms_name)
return NULL;
}
// Get file descriptor of DMS directory to create the arrays directory
// Get file descriptor of DMS directory to create the AVL trees directory
dms_dir = opendir(directory_name);
if (dms_dir == NULL)
{
......@@ -267,11 +267,11 @@ OBIDMS_p obi_create_dms(const char* dms_name)
return NULL;
}
// Create the arrays directory
if (mkdirat(dms_file_descriptor, ARRAYS_DIR_NAME, 00777) < 0)
// Create the AVL trees directory
if (mkdirat(dms_file_descriptor, AVL_TREES_DIR_NAME, 00777) < 0)
{
obi_set_errno(OBI_ARRAY_ERROR);
obidebug(1, "\nProblem creating an arrays directory");
obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nProblem creating an AVL trees directory");
return NULL;
}
......@@ -390,24 +390,24 @@ OBIDMS_p obi_open_dms(const char* dms_name)
dms->little_endian = little_endian_dms;
// Open the arrays directory
dms->array_directory = private_opendirat(dms->dir_fd, ARRAYS_DIR_NAME);
if (dms->array_directory == NULL)
// Open the AVL trees directory
dms->avl_directory = private_opendirat(dms->dir_fd, AVL_TREES_DIR_NAME);
if (dms->avl_directory == NULL)
{
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
obidebug(1, "\nError opening the arrays directory");
obidebug(1, "\nError opening the AVL trees directory");
closedir(dms->directory);
free(dms);
return NULL;
}
// Store the array directory's file descriptor
dms->array_dir_fd = dirfd(dms->array_directory);
if (dms->array_dir_fd < 0)
// Store the AVL trees directory's file descriptor
dms->avl_dir_fd = dirfd(dms->avl_directory);
if (dms->avl_dir_fd < 0)
{
obi_set_errno(OBIDMS_UNKNOWN_ERROR);
obidebug(1, "\nError getting the file descriptor of the arrays directory");
closedir(dms->array_directory);
obidebug(1, "\nError getting the file descriptor of the AVL trees directory");
closedir(dms->avl_directory);
closedir(dms->directory);
free(dms);
return NULL;
......@@ -418,10 +418,10 @@ OBIDMS_p obi_open_dms(const char* dms_name)
(dms->opened_columns)->columns = (OBIDMS_column_p*) malloc(MAX_NB_OPENED_COLUMNS*sizeof(OBIDMS_column_p));
(dms->opened_columns)->nb_opened_columns = 0;
// Initialize the list of opened arrays
dms->opened_arrays = (Opened_arrays_list_p) malloc(sizeof(Opened_arrays_list_t));
(dms->opened_arrays)->arrays = (OBIDMS_array_p*) malloc(MAX_NB_OPENED_ARRAYS*sizeof(OBIDMS_array_p));
(dms->opened_arrays)->nb_opened_arrays = 0;
// Initialize the list of opened AVL trees
dms->opened_avls = (Opened_avls_list_p) malloc(sizeof(Opened_avls_list_t));
(dms->opened_avls)->avls = (OBIDMS_avl_p*) malloc(MAX_NB_OPENED_AVL_TREES*sizeof(OBIDMS_avl_p));
(dms->opened_avls)->nb_opened_avls = 0;
return dms;
}
......@@ -454,7 +454,7 @@ int obi_close_dms(OBIDMS_p dms)
while ((dms->opened_columns)->nb_opened_columns > 0)
obi_close_column(*((dms->opened_columns)->columns));
// Close dms and array directories
// Close dms and AVL trees directories
if (closedir(dms->directory) < 0)
{
obi_set_errno(OBIDMS_MEMORY_ERROR);
......@@ -462,10 +462,10 @@ int obi_close_dms(OBIDMS_p dms)
free(dms);
return -1;
}
if (closedir(dms->array_directory) < 0)
if (closedir(dms->avl_directory) < 0)
{
obi_set_errno(OBI_ARRAY_ERROR);
obidebug(1, "\nError closing an array directory");
obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError closing an AVL trees directory");
free(dms);
return -1;
}
......
......@@ -25,14 +25,14 @@
#include "obierrno.h"
#define OBIDMS_MAX_NAME (2048) /**< The maximum length of an OBIDMS name.
*/
#define ARRAYS_DIR_NAME "arrays" /**< The name of the arrays directory.
*/
#define MAX_NB_OPENED_COLUMNS (100) /**< The maximum number of columns open at the same time.
*/
#define MAX_NB_OPENED_ARRAYS (100) /**< The maximum number of arrays open at the same time.
*/
#define OBIDMS_MAX_NAME (2048) /**< The maximum length of an OBIDMS name.
*/
#define AVL_TREES_DIR_NAME "AVL_trees" /**< The name of the AVL trees directory.
*/
#define MAX_NB_OPENED_COLUMNS (100) /**< The maximum number of columns open at the same time.
*/
#define MAX_NB_OPENED_AVL_TREES (100) /**< The maximum number of AVL trees open at the same time.
*/
struct OBIDMS_column; // TODO
......@@ -43,12 +43,12 @@ typedef struct Opened_columns_list {
} Opened_columns_list_t, *Opened_columns_list_p;
struct OBIDMS_array; // TODO
struct OBIDMS_avl; // TODO
typedef struct Opened_arrays_list {
size_t nb_opened_arrays;
struct OBIDMS_array** arrays;
} Opened_arrays_list_t, *Opened_arrays_list_p;
typedef struct Opened_avls_list {
size_t nb_opened_avls;
struct OBIDMS_avl** avls;
} Opened_avls_list_t, *Opened_avls_list_p;
/**
......@@ -67,17 +67,17 @@ typedef struct OBIDMS {
int dir_fd; /**< The file descriptor of the directory entry
* usable to refer and scan the database directory.
*/
DIR* array_directory; /**< A directory entry usable to
* refer and scan the array directory.
DIR* avl_directory; /**< A directory entry usable to
* refer and scan the AVL trees directory.
*/
int array_dir_fd; /**< The file descriptor of the directory entry
* usable to refer and scan the array directory.
int avl_dir_fd; /**< The file descriptor of the directory entry
* usable to refer and scan the AVL trees directory.
*/
bool little_endian; /**< Endianness of the database.
*/
Opened_columns_list_p opened_columns; /**< List of opened columns.
*/
Opened_arrays_list_p opened_arrays; /**< List of opened arrays.
Opened_avls_list_p opened_avls; /**< List of opened AVL trees.
*/
} OBIDMS_t, *OBIDMS_p;
......@@ -105,7 +105,7 @@ int obi_dms_exists(const char* dms_name);
* if a directory with this name does not already exist
* before creating the new database.
*
* A directory to store obiarrays is also created.
* A directory to store AVL trees is also created.
*
* @param dms_name A pointer to a C string containing the name of the database.
* The actual directory name used to store the DMS will be
......
......@@ -29,7 +29,7 @@
#include "obierrno.h"
#include "obidebug.h"
#include "obilittlebigman.h"
#include "obiarray.h"
#include "obiavl.h"
#define DEBUG_LEVEL 0 // TODO has to be defined somewhere else (cython compil flag?)
......@@ -514,14 +514,14 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms,
index_t nb_lines,
index_t nb_elements_per_line,
const char* elements_names,
const char* array_name,
const char* avl_name,
const char* comments,
bool referring)
{
OBIDMS_column_p new_column;
OBIDMS_column_directory_p column_directory;
OBIDMS_column_header_p header;
OBIDMS_array_p array;
OBIDMS_avl_p avl;
size_t file_size;
obiversion_t version_number;
char* column_file_name;
......@@ -552,9 +552,9 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms,
obidebug(1, "\nCan't create column because of invalid data type");
return NULL;
}
if (((data_type == OBI_STR) || (data_type == OBI_SEQ)) && (array_name == NULL))
if (((data_type == OBI_STR) || (data_type == OBI_SEQ)) && (avl_name == NULL))
{
obidebug(1, "\nCan't create column because of empty array name");
obidebug(1, "\nCan't create column because of empty avl name");
return NULL;
}
......@@ -732,20 +732,20 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms,
if (comments != NULL)
strncpy(header->comments, comments, COMMENTS_MAX_LENGTH);
// If the data type is OBI_STR or OBI_SEQ, the associated obi_array is opened or created
// If the data type is OBI_STR or OBI_SEQ, the associated obi_avl is opened or created
if ((returned_data_type == OBI_STR) || (returned_data_type == OBI_SEQ))
{
array = obi_array(dms, array_name);
if (array == NULL)
avl = obi_avl(dms, avl_name);
if (avl == NULL)
{
obidebug(1, "\nError opening or creating the array associated with a column");
obidebug(1, "\nError opening or creating the aVL tree associated with a column");
munmap(new_column->header, header_size);
close(column_file_descriptor);
free(new_column);
return NULL;
}
new_column->array = array;
strncpy(header->array_name, array_name, ARRAY_MAX_NAME);
new_column->avl = avl;
strncpy(header->avl_name, avl_name, AVL_MAX_NAME);
}
// Fill the data with NA values
......@@ -768,7 +768,7 @@ OBIDMS_column_p obi_open_column(OBIDMS_p dms,
{
OBIDMS_column_p column;
OBIDMS_column_directory_p column_directory;
OBIDMS_array_p array;
OBIDMS_avl_p avl;
char* column_file_name;
int column_file_descriptor;
size_t header_size;
......@@ -886,19 +886,19 @@ OBIDMS_column_p obi_open_column(OBIDMS_p dms,
column->writable = false;
// If the data type is OBI_STR or OBI_SEQ, the associated obi_array is opened
// If the data type is OBI_STR or OBI_SEQ, the associated AVL tree is opened
if (((column->header)->returned_data_type == OBI_STR) || ((column->header)->returned_data_type == OBI_SEQ))
{
array = obi_array(dms, (column->header)->array_name);
if (array == NULL)
avl = obi_avl(dms, (column->header)->avl_name);
if (avl == NULL)
{
obidebug(1, "\nError opening the array associated with a column");
obidebug(1, "\nError opening the AVL tree associated with a column");
munmap(column->header, header_size);
close(column_file_descriptor);
free(column);
return NULL;
}
column->array = array;
column->avl = avl;
}
if ((column->header)->referring)
......@@ -973,7 +973,7 @@ OBIDMS_column_p obi_clone_column(OBIDMS_p dms,
nb_lines,
nb_elements_per_line,
(column_to_clone->header)->elements_names,
(column_to_clone->header)->array_name,
(column_to_clone->header)->avl_name,
(column_to_clone->header)->comments,
referring);
......@@ -1052,10 +1052,10 @@ int obi_close_column(OBIDMS_column_p column)
if ((column->header)->referring)
obi_close_column(column->referred_column);
// If the data type is OBI_STR or OBI_SEQ, the associated obi_array is closed
// If the data type is OBI_STR or OBI_SEQ, the associated AVL tree is closed
if (((column->header)->returned_data_type == OBI_STR) || ((column->header)->returned_data_type == OBI_SEQ))
{
if (obi_close_array(column->array) < 0)
if (obi_close_avl(column->avl) < 0)
return -1;
}
......
......@@ -25,7 +25,7 @@
#include "obierrno.h"
#include "obilittlebigman.h"
#include "obidmscolumndir.h"
#include "obiarray.h"
#include "obiavl.h"
#define ONE_IF_ZERO(x) (((x)==0)?1:(x)) /**< If x is equal to 0, x takes the value 1.
......@@ -86,7 +86,7 @@ typedef struct OBIDMS_column_header {
*/
char name[OBIDMS_COLUMN_MAX_NAME+1]; /**< The column name as a NULL terminated string.
*/
char array_name[ARRAY_MAX_NAME+1]; /**< If there is one, the obi_array name as a NULL terminated string.
char avl_name[AVL_MAX_NAME+1]; /**< If there is one, the AVL tree name as a NULL terminated string.
*/
char comments[COMMENTS_MAX_LENGTH+1]; /**< Comments stored as a classical zero end C string.
*/
......@@ -106,7 +106,7 @@ typedef struct OBIDMS_column {
*/
OBIDMS_column_header_p header; /**< A pointer to the header of the column.
*/
OBIDMS_array_p array; /**< A pointer to the array associated with the column if there is one.
OBIDMS_avl_p avl; /**< A pointer to the AVL tree associated with the column if there is one.
*/
struct OBIDMS_column* referred_column; /**< A pointer to the referred column if the column is referring.
*/
......@@ -174,7 +174,7 @@ size_t obi_get_platform_header_size();
* @brief Creates a column.
*
* The minimum data size allocated is one memory page, and the data is initialized to the NA value of the OBIType.
* If there is an array associated with the column, it is opened or created if it does not already exist.
* If there is an AVL tree associated with the column, it is opened or created if it does not already exist.
*
* @warning If there is one element per line, elements_names should be equal to column_name. // TODO change this condition?
*
......@@ -182,9 +182,9 @@ size_t obi_get_platform_header_size();
* @param column_name The name of the new column.
* @param data_type The OBIType code of the data.
* @param nb_lines The number of lines to be stored.
* @param nb_elements_per_line The number of elements per line.
* @param nb_elements_per_line The number of elements per line. // TODO talk about default values
* @param elements_names The names of the elements with ';' as separator.
* @param array_name The name of the array if there is one associated with the column.
* @param avl_name The name of the AVL tree if there is one associated with the column.
* @param comments Optional comments associated with the column.
* @param referring
*
......@@ -200,7 +200,7 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms,
index_t nb_lines,
index_t nb_elements_per_line,
const char* elements_names,
const char* array_name,
const char* avl_name,
const char* comments,
bool referring);
......
......@@ -17,7 +17,7 @@
#include "obitypes.h"
#include "obierrno.h"
#include "obidebug.h"
#include "obiarray.h"
#include "obiavl.h"
#define DEBUG_LEVEL 0 // TODO has to be defined somewhere else (cython compil flag?)
......@@ -67,8 +67,8 @@ int obi_column_set_obiseq_with_elt_idx(OBIDMS_column_p column, index_t line_nb,
if (value_b == NULL)
return -1;
// Add in the obiarray
idx = obi_array_add(column->array, value_b);
// Add in the AVL tree
idx = obi_avl_add(column->avl, value_b);
if (idx == -1)
return -1;
......@@ -106,7 +106,7 @@ const char* obi_column_get_obiseq_with_elt_idx(OBIDMS_column_p column, index_t l
if (idx == OBIIdx_NA)
return "\0"; // TODO
value_b = obi_array_get(column->array, idx);
value_b = obi_avl_get(column->avl, idx);
return obi_obibytes_to_seq(value_b);
}
......
......@@ -23,7 +23,7 @@
/**
* @brief Sets a value in an OBIDMS column containing data in the form of indices referring
* to DNA sequences in an obiarray, using the index of the element in the line.
* to DNA sequences in an AVL tree, using the index of the element in the line.
*
* @warning Pointers returned by obi_open_column() don't allow writing.
*
......@@ -44,7 +44,7 @@ int obi_column_set_obiseq_with_elt_idx(OBIDMS_column_p column, index_t line_nb,
/**
* @brief Recovers a value in an OBIDMS column containing data in the form of indices referring
* to DNA sequences in an obiarray, using the index of the element in the line.
* to DNA sequences in an AVL tree, using the index of the element in the line.
*
* @param column A pointer as returned by obi_create_column().
* @param line_nb The number of the line where the value should be recovered.
......@@ -61,7 +61,7 @@ const char* obi_column_get_obiseq_with_elt_idx(OBIDMS_column_p column, index_t l
/**
* @brief Sets a value in an OBIDMS column containing data in the form of indices referring
* to DNA sequences in an obiarray, using the name of the element in the line.
* to DNA sequences in an AVL tree, using the name of the element in the line.
*
* @warning Pointers returned by obi_open_column() don't allow writing.
*
......@@ -82,7 +82,7 @@ int obi_column_set_obiseq_with_elt_name(OBIDMS_column_p column, index_t line_nb,
/**
* @brief Recovers a value in an OBIDMS column containing data in the form of indices referring
* to DNA sequences in an obiarray, using the name of the element in the line.
* to DNA sequences in an AVL tree, using the name of the element in the line.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be recovered.
......
......@@ -17,7 +17,7 @@
#include "obitypes.h"
#include "obierrno.h"
#include "obidebug.h"
#include "obiarray.h"
#include "obiavl.h"
#define DEBUG_LEVEL 0 // TODO has to be defined somewhere else (cython compil flag?)
......@@ -67,8 +67,8 @@ int obi_column_set_obistr_with_elt_idx(OBIDMS_column_p column, index_t line_nb,
if (value_b == NULL)
return -1;
// Add in the obiarray
idx = obi_array_add(column->array, value_b);
// Add in the AVL tree
idx = obi_avl_add(column->avl, value_b);
if (idx == -1)
return -1;
......@@ -106,7 +106,7 @@ const char* obi_column_get_obistr_with_elt_idx(OBIDMS_column_p column, index_t l
if (idx == OBIIdx_NA)
return "\0"; // TODO
value_b = obi_array_get(column->array, idx);
value_b = obi_avl_get(column->avl, idx);
return obi_obibytes_to_str(value_b);
}
......
......@@ -23,7 +23,7 @@
/**
* @brief Sets a value in an OBIDMS column containing data in the form of indices referring
* to character strings in an obiarray, using the index of the element in the line.
* to character strings in an AVL tree, using the index of the element in the line.
*
* @warning Pointers returned by obi_open_column() don't allow writing.
*
......@@ -44,7 +44,7 @@ int obi_column_set_obistr_with_elt_idx(OBIDMS_column_p column, index_t line_nb,
/**
* @brief Recovers a value in an OBIDMS column containing data in the form of indices referring
* to character strings in an obiarray, using the index of the element in the line.
* to character strings in an AVL tree, using the index of the element in the line.
*
* @param column A pointer as returned by obi_create_column().
* @param line_nb The number of the line where the value should be recovered.
......@@ -61,7 +61,7 @@ const char* obi_column_get_obistr_with_elt_idx(OBIDMS_column_p column, index_t l
/**
* @brief Sets a value in an OBIDMS column containing data in the form of indices referring
* to character strings in an obiarray, using the name of the element in the line.
* to character strings in an AVL tree, using the name of the element in the line.
*
* @warning Pointers returned by obi_open_column() don't allow writing.
*
......@@ -82,7 +82,7 @@ int obi_column_set_obistr_with_elt_name(OBIDMS_column_p column, index_t line_nb,
/**
* @brief Recovers a value in an OBIDMS column containing data in the form of indices referring
* to character strings in an obiarray, using the name of the element in the line.
* to character strings in an AVL tree, using the name of the element in the line.
*
* @param column A pointer as returned by obi_create_column() or obi_clone_column().
* @param line_nb The number of the line where the value should be recovered.
......
......@@ -98,7 +98,7 @@ extern int obi_errno;
*/
#define OBICOL_ACCESS_ERROR (19) /**< Permission error trying to access an OBIDSM column directory
*/
#define OBI_ARRAY_ERROR (20) /** Error while handling an array
#define OBI_AVL_ERROR (20) /** Error while handling an AVL tree
*/
/**@}*/
......
......@@ -56,6 +56,12 @@ typedef double obifloat_t;
typedef char obichar_t;
// TODO same for obistr_t and obiseq_t ?
typedef char byte_t; /**< Defining byte type since the data referred to by AVL trees is stored in bits
* and char (stored on one byte) is the smallest addressable unit.
*/
/**
* @brief Union used to compute the NA value of the OBI_FLOAT OBIType.
*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment