obidmscolumn_str.c 3.82 KB
Newer Older
1
/****************************************************************************
2
 * OBIDMS_column_str functions                                              *
3 4 5
 ****************************************************************************/

/**
6
 * @file obidsmcolumn_str.c
7
 * @author Celine Mercier
8
 * @date October 28th 2015
9
 * @brief Functions handling OBIColumns containing data in the form of indices referring to character strings.
10 11 12 13 14 15 16 17 18 19
 */


#include <stdlib.h>
#include <stdio.h>

#include "obidmscolumn.h"
#include "obitypes.h"
#include "obierrno.h"
#include "obidebug.h"
20
#include "obiavl.h"
21 22


23
#define DEBUG_LEVEL 0	// TODO has to be defined somewhere else (cython compil flag?)
24 25


26 27 28 29 30 31
/**********************************************************************
 *
 * 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
 *
 **********************************************************************/

32
int obi_column_set_obistr_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx, char* value)
33
{
34 35 36
	byte_t* value_b;
	index_t idx;

37 38 39 40 41 42 43 44
	// Check that the column is not referring another
	if ((column->header)->referring)
	{
		obi_set_errno(OBICOL_UNKNOWN_ERROR);
		obidebug(1, "\nError: Setting a value from a referring column is not allowed. The referred column must be cloned to be modified");
	  	return -1;
	}

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
	// Check that the line number is not greater than the maximum allowed
	if (line_nb >= MAXIMUM_LINE_COUNT)
	{
		obi_set_errno(OBICOL_UNKNOWN_ERROR);
		obidebug(1, "\nError trying to set a value at a line number greater than the maximum allowed");
    	return -1;
	}

	// Check if the file needs to be enlarged
	while ((line_nb+1) > (column->header)->line_count)
	{
		// Enlarge the file
		if (obi_enlarge_column(column) < 0)
	    	return -1;
	}

61 62 63
	// Update lines used
	if ((line_nb+1) > (column->header)->lines_used)
		(column->header)->lines_used = line_nb+1;
64

65 66 67 68 69
	// Encode the value on a byte array with a header
	value_b = obi_str_to_obibytes(value);
	if (value_b == NULL)
		return -1;

70 71
	// Add in the AVL tree
	idx = obi_avl_add(column->avl, value_b);
72 73 74 75
	if (idx == -1)
		return -1;

	// Add the value's index in the column
76
	*(((index_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx) = idx;
77

78
	free(value_b);
79

80 81 82 83
	return 0;
}


84
const char* obi_column_get_obistr_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx)
85
{
86 87
	index_t idx;
	byte_t* value_b;
88
	index_t referring_idx;
89

90
	if ((line_nb+1) > (column->header)->lines_used)
91
	{
92 93
		obi_set_errno(OBICOL_UNKNOWN_ERROR);
		obidebug(1, "\nError trying to get a value that is beyond the current number of lines used");
94
		return "\0";		// TODO
95
	}
96

97 98 99 100 101 102 103
	if ((column->header)->referring)
	{
		referring_idx = *(((index_t*) (column->data)) + line_nb);
		idx = *(((index_t*) ((column->referred_column)->data)) + (referring_idx * ((column->header)->returned_nb_elements_per_line)) + element_idx);
	}
	else
		idx = *(((index_t*) (column->data)) + (line_nb * ((column->header)->stored_nb_elements_per_line)) + element_idx);
104 105 106 107 108

	// Check NA
	if (idx == OBIIdx_NA)
		return "\0";		// TODO

109
	value_b = obi_avl_get(column->avl, idx);
110
	return obi_obibytes_to_str(value_b);
111 112
}

113

114
int obi_column_set_obistr_with_elt_name(OBIDMS_column_p column, index_t line_nb, const char* element_name, char* value)
115
{
116
	index_t element_idx;
117
	element_idx = obi_column_get_element_index_from_name(column, element_name);
118
	if (element_idx == OBIIdx_NA)
119
		return -1;
120 121
	if (obi_column_set_obistr_with_elt_idx(column, line_nb, element_idx, value) < 0)
		return -1;
122 123 124 125
	return 0;
}


126
const char* obi_column_get_obistr_with_elt_name(OBIDMS_column_p column, index_t line_nb, const char* element_name)
127
{
128
	index_t element_idx;
129

130
	element_idx = obi_column_get_element_index_from_name(column, element_name);
131
	if (element_idx == OBIIdx_NA)
132 133
		return "\0";
	return obi_column_get_obistr_with_elt_idx(column, line_nb, element_idx);
134
}
135