obidmscolumn_str.c 5.51 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
 */


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

#include "obidmscolumn.h"
Celine Mercier's avatar
Celine Mercier committed
17
#include "obiview.h"
18 19 20
#include "obitypes.h"
#include "obierrno.h"
#include "obidebug.h"
Celine Mercier's avatar
Celine Mercier committed
21
#include "obiblob_indexer.h"
22 23


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


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

33
int obi_column_set_obistr_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx, char* value)
34
{
Celine Mercier's avatar
Celine Mercier committed
35 36
	Obi_blob_p 	value_b;
	index_t     idx;
37

38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
	// 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;
	}

54 55 56
	// Update lines used
	if ((line_nb+1) > (column->header)->lines_used)
		(column->header)->lines_used = line_nb+1;
57

58
	// Encode the value on a byte array with a header
59
	value_b = obi_str_to_blob(value);
60 61 62
	if (value_b == NULL)
		return -1;

Celine Mercier's avatar
Celine Mercier committed
63 64
	// Add in the indexer
	idx = obi_indexer_add(column->indexer, value_b);
65 66 67 68
	if (idx == -1)
		return -1;

	// Add the value's index in the column
Celine Mercier's avatar
Celine Mercier committed
69
	*(((index_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx) = idx;
70

71
	free(value_b);
72

73 74 75 76
	return 0;
}


Celine Mercier's avatar
Celine Mercier committed
77 78 79 80 81 82 83 84 85 86
int obi_column_set_obistr_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, char* value)
{
	// Check that the view is not read-only
	if (view->read_only)
	{
		obi_set_errno(OBIVIEW_ERROR);
		obidebug(1, "\nError trying to set a value in a column in a read-only view");
		return -1;
	}

87
	if ((view->line_selection != NULL) || (!(column->writable)))	// TODO why check here writable?
Celine Mercier's avatar
Celine Mercier committed
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
	{
		// Get the right line number
		if (column->writable)
			line_nb = *(((index_t*) ((view->line_selection)->data)) + line_nb);

		column = obi_view_clone_column(view, (column->header)->name);
		if (column == NULL)
		{
			obidebug(1, "\nError trying to clone a column to modify it");
			return -1;
		}
	}

	if ((line_nb+1) > view->line_count)
	{
		if (obi_view_update_lines(view, (line_nb+1)) < 0)
			return -1;
	}

	if (obi_column_set_obistr_with_elt_idx(column, line_nb, element_idx, value) < 0)
		return -1;

	return 0;
}


114
const char* obi_column_get_obistr_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx)
115
{
116
	index_t          idx;
117
	Obi_blob_p value_b;
118

Celine Mercier's avatar
Celine Mercier committed
119
	if ((line_nb+1) > ((column->header)->line_count))
120
	{
121
		obi_set_errno(OBICOL_UNKNOWN_ERROR);
Celine Mercier's avatar
Celine Mercier committed
122 123
		obidebug(1, "\nError trying to get a value that is beyond the current number of lines used in the column");
		return OBIStr_NA;
124
	}
125

Celine Mercier's avatar
Celine Mercier committed
126
	idx = *(((index_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx);
127 128 129

	// Check NA
	if (idx == OBIIdx_NA)
Celine Mercier's avatar
Celine Mercier committed
130
		return OBIStr_NA;
131

Celine Mercier's avatar
Celine Mercier committed
132
	value_b = obi_indexer_get(column->indexer, idx);
133

134
	return obi_blob_to_str(value_b);
135 136
}

137

Celine Mercier's avatar
Celine Mercier committed
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
const char* obi_column_get_obistr_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx)
{
	if ((line_nb+1) > (view->line_count))
	{
		obi_set_errno(OBICOL_UNKNOWN_ERROR);
		obidebug(1, "\nError trying to get a value that is beyond the current line count of the view");
		return OBIStr_NA;
	}

	if (view->line_selection)
		line_nb = *(((index_t*) ((view->line_selection)->data)) + line_nb);

	return obi_column_get_obistr_with_elt_idx(column, line_nb, element_idx);
}


154
int obi_column_set_obistr_with_elt_name(OBIDMS_column_p column, index_t line_nb, const char* element_name, char* value)
155
{
156
	index_t element_idx;
157
	element_idx = obi_column_get_element_index_from_name(column, element_name);
158
	if (element_idx == OBIIdx_NA)
159
		return -1;
Celine Mercier's avatar
Celine Mercier committed
160 161 162 163 164 165 166 167 168 169
	obi_column_set_obistr_with_elt_idx(column, line_nb, element_idx, value);
	return 0;
}


int obi_column_set_obistr_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name, char* value)
{
	index_t element_idx;
	element_idx = obi_column_get_element_index_from_name(column, element_name);
	if (element_idx == OBIIdx_NA)
170
		return -1;
Celine Mercier's avatar
Celine Mercier committed
171
	obi_column_set_obistr_with_elt_idx_in_view(view, column, line_nb, element_idx, value);
172 173 174 175
	return 0;
}


176
const char* obi_column_get_obistr_with_elt_name(OBIDMS_column_p column, index_t line_nb, const char* element_name)
177
{
178
	index_t element_idx;
179

180
	element_idx = obi_column_get_element_index_from_name(column, element_name);
181
	if (element_idx == OBIIdx_NA)
Celine Mercier's avatar
Celine Mercier committed
182
		return OBIStr_NA;
183
	return obi_column_get_obistr_with_elt_idx(column, line_nb, element_idx);
184
}
185

Celine Mercier's avatar
Celine Mercier committed
186 187 188 189 190 191 192 193 194 195 196

const char* obi_column_get_obistr_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, const char* element_name)
{
	index_t element_idx;

	element_idx = obi_column_get_element_index_from_name(column, element_name);
	if (element_idx == OBIIdx_NA)
		return OBIStr_NA;
	return obi_column_get_obistr_with_elt_idx_in_view(view, column, line_nb, element_idx);
}