Skip to content

Commit 679e46b

Browse files
committed
Replace assert with bsp_error_t for bsp_array_t.
1 parent a8c3ee3 commit 679e46b

File tree

13 files changed

+282
-84
lines changed

13 files changed

+282
-84
lines changed

examples/simple_read.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ int main(int argc, char** argv) {
1919
printf("%lu: %d\n", i, values[i]);
2020
}
2121

22-
bsp_destroy_array_t(array);
22+
bsp_destroy_array_t(&array);
2323
H5Fclose(f);
2424

2525
return 0;

examples/simple_write.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,13 @@ int main(int argc, char** argv) {
1111

1212
hid_t f = H5Fcreate(file_name, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
1313

14-
bsp_array_t array = bsp_construct_array_t(1000, BSP_INT32);
14+
bsp_array_t array;
15+
bsp_error_t error = bsp_construct_array_t(&array, 1000, BSP_INT32);
16+
if (error != BSP_SUCCESS) {
17+
printf("Error: Failed to allocate array\n");
18+
H5Fclose(f);
19+
return 1;
20+
}
1521

1622
int* values = (int*) array.data;
1723

@@ -22,7 +28,7 @@ int main(int argc, char** argv) {
2228
bsp_write_array(f, "test", array, 0);
2329

2430
H5Fclose(f);
25-
bsp_destroy_array_t(array);
31+
bsp_destroy_array_t(&array);
2632

2733
return 0;
2834
}

include/binsparse/array.h

Lines changed: 44 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
#pragma once
88

9-
#include <assert.h>
109
#include <binsparse/detail/allocator.h>
1110
#include <binsparse/detail/shm_tools.h>
11+
#include <binsparse/error.h>
1212
#include <binsparse/types.h>
1313
#include <stdlib.h>
1414
#include <string.h>
@@ -28,63 +28,70 @@ static inline bsp_array_t bsp_construct_default_array_t() {
2828
return array;
2929
}
3030

31-
static inline bsp_array_t bsp_construct_array_t(size_t size, bsp_type_t type) {
31+
static inline bsp_error_t bsp_construct_array_t(bsp_array_t* array, size_t size,
32+
bsp_type_t type) {
3233
size_t byte_size = size * bsp_type_size(type);
3334

34-
bsp_array_t array;
35-
array.allocator = bsp_default_allocator;
36-
array.data = array.allocator.malloc(byte_size);
37-
assert(array.data != NULL);
38-
array.size = size;
39-
array.type = type;
35+
array->allocator = bsp_default_allocator;
36+
array->data = array->allocator.malloc(byte_size);
4037

41-
return array;
38+
if (array->data == NULL) {
39+
return BSP_ERROR_MEMORY;
40+
}
41+
42+
array->size = size;
43+
array->type = type;
44+
45+
return BSP_SUCCESS;
4246
}
4347

44-
static inline bsp_array_t bsp_copy_construct_array_t(bsp_array_t other) {
45-
bsp_array_t array = bsp_construct_array_t(other.size, other.type);
46-
memcpy(array.data, other.data, other.size * bsp_type_size(other.type));
48+
static inline bsp_error_t bsp_copy_construct_array_t(bsp_array_t* array,
49+
bsp_array_t other) {
50+
bsp_error_t error = bsp_construct_array_t(array, other.size, other.type);
51+
if (error != BSP_SUCCESS) {
52+
return error;
53+
}
54+
55+
memcpy(array->data, other.data, other.size * bsp_type_size(other.type));
4756

48-
return array;
57+
return BSP_SUCCESS;
4958
}
5059

51-
static inline bsp_array_t bsp_complex_array_to_fp(bsp_array_t other) {
52-
assert(other.type == BSP_COMPLEX_FLOAT32 ||
53-
other.type == BSP_COMPLEX_FLOAT64);
60+
static inline bsp_error_t bsp_complex_array_to_fp(bsp_array_t* array) {
61+
if (array->type != BSP_COMPLEX_FLOAT32 &&
62+
array->type != BSP_COMPLEX_FLOAT64) {
63+
return BSP_ERROR_TYPE;
64+
}
5465

55-
bsp_array_t array;
56-
array.data = other.data;
57-
array.size = other.size * 2;
58-
array.allocator = other.allocator;
66+
array->size = array->size * 2;
5967

60-
if (other.type == BSP_COMPLEX_FLOAT32) {
61-
array.type = BSP_FLOAT32;
68+
if (array->type == BSP_COMPLEX_FLOAT32) {
69+
array->type = BSP_FLOAT32;
6270
} else {
63-
array.type = BSP_FLOAT64;
71+
array->type = BSP_FLOAT64;
6472
}
6573

66-
return array;
74+
return BSP_SUCCESS;
6775
}
6876

69-
static inline bsp_array_t bsp_fp_array_to_complex(bsp_array_t other) {
70-
assert(other.type == BSP_FLOAT32 || other.type == BSP_FLOAT64);
71-
72-
bsp_array_t array;
73-
array.data = other.data;
74-
array.size = other.size / 2;
75-
array.allocator = other.allocator;
77+
static inline bsp_error_t bsp_fp_array_to_complex(bsp_array_t* array) {
78+
if (array->type != BSP_FLOAT32 && array->type != BSP_FLOAT64) {
79+
return BSP_ERROR_TYPE;
80+
}
7681

77-
if (other.type == BSP_FLOAT32) {
78-
array.type = BSP_COMPLEX_FLOAT32;
82+
if (array->type == BSP_FLOAT32) {
83+
array->type = BSP_COMPLEX_FLOAT32;
7984
} else {
80-
array.type = BSP_COMPLEX_FLOAT64;
85+
array->type = BSP_COMPLEX_FLOAT64;
8186
}
8287

83-
return array;
88+
array->size = array->size / 2;
89+
90+
return BSP_SUCCESS;
8491
}
8592

86-
static inline void bsp_destroy_array_t(bsp_array_t array) {
87-
array.allocator.free(array.data);
93+
static inline void bsp_destroy_array_t(bsp_array_t* array) {
94+
array->allocator.free(array->data);
8895
}
8996

9097
static inline bool bsp_array_equal(bsp_array_t x, bsp_array_t y) {

include/binsparse/binsparse.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <binsparse/array.h>
1212
#include <binsparse/convert_matrix.h>
1313
#include <binsparse/detail/detail.h>
14+
#include <binsparse/error.h>
1415
#include <binsparse/generate.h>
1516
#include <binsparse/hdf5_wrapper.h>
1617
#include <binsparse/matrix.h>

include/binsparse/convert_matrix.h

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,25 +37,43 @@ static inline bsp_matrix_t bsp_convert_matrix(bsp_matrix_t matrix,
3737

3838
bsp_type_t index_type = bsp_pick_integer_type(max_dim);
3939

40-
result.values = bsp_copy_construct_array_t(matrix.values);
40+
bsp_error_t error =
41+
bsp_copy_construct_array_t(&result.values, matrix.values);
42+
if (error != BSP_SUCCESS) {
43+
return bsp_construct_default_matrix_t();
44+
}
4145

4246
// There is a corner case with tall and skinny matrices where we need a
4347
// higher width for rowind. In order to keep rowind/colind the same type,
4448
// we might upcast.
4549

4650
if (index_type == matrix.indices_1.type) {
47-
result.indices_1 = bsp_copy_construct_array_t(matrix.indices_1);
51+
error = bsp_copy_construct_array_t(&result.indices_1, matrix.indices_1);
52+
if (error != BSP_SUCCESS) {
53+
bsp_destroy_array_t(&result.values);
54+
return bsp_construct_default_matrix_t();
55+
}
4856
} else {
49-
result.indices_1 =
50-
bsp_construct_array_t(matrix.indices_1.size, index_type);
57+
error = bsp_construct_array_t(&result.indices_1, matrix.indices_1.size,
58+
index_type);
59+
if (error != BSP_SUCCESS) {
60+
bsp_destroy_array_t(&result.values);
61+
return bsp_construct_default_matrix_t();
62+
}
63+
5164
for (size_t i = 0; i < matrix.indices_1.size; i++) {
5265
size_t index;
5366
bsp_array_read(matrix.indices_1, i, index);
5467
bsp_array_write(result.indices_1, i, index);
5568
}
5669
}
5770

58-
result.indices_0 = bsp_construct_array_t(matrix.nnz, index_type);
71+
error = bsp_construct_array_t(&result.indices_0, matrix.nnz, index_type);
72+
if (error != BSP_SUCCESS) {
73+
bsp_destroy_array_t(&result.values);
74+
bsp_destroy_array_t(&result.indices_1);
75+
return bsp_construct_default_matrix_t();
76+
}
5977

6078
for (size_t i = 0; i < matrix.nrows; i++) {
6179
size_t row_begin, row_end;
@@ -109,12 +127,26 @@ static inline bsp_matrix_t bsp_convert_matrix(bsp_matrix_t matrix,
109127
// indices can be copied exactly. Values' type will not change, but
110128
// column indices might, thus the extra branch.
111129

112-
result.values = bsp_copy_construct_array_t(matrix.values);
130+
bsp_error_t error =
131+
bsp_copy_construct_array_t(&result.values, matrix.values);
132+
if (error != BSP_SUCCESS) {
133+
return bsp_construct_default_matrix_t();
134+
}
113135

114136
if (index_type == matrix.indices_1.type) {
115-
result.indices_1 = bsp_copy_construct_array_t(matrix.indices_1);
137+
error =
138+
bsp_copy_construct_array_t(&result.indices_1, matrix.indices_1);
139+
if (error != BSP_SUCCESS) {
140+
bsp_destroy_array_t(&result.values);
141+
return bsp_construct_default_matrix_t();
142+
}
116143
} else {
117-
result.indices_1 = bsp_construct_array_t(matrix.nnz, index_type);
144+
error =
145+
bsp_construct_array_t(&result.indices_1, matrix.nnz, index_type);
146+
if (error != BSP_SUCCESS) {
147+
bsp_destroy_array_t(&result.values);
148+
return bsp_construct_default_matrix_t();
149+
}
118150

119151
for (size_t i = 0; i < matrix.nnz; i++) {
120152
size_t index;
@@ -123,8 +155,13 @@ static inline bsp_matrix_t bsp_convert_matrix(bsp_matrix_t matrix,
123155
}
124156
}
125157

126-
result.pointers_to_1 =
127-
bsp_construct_array_t(matrix.nrows + 1, index_type);
158+
error = bsp_construct_array_t(&result.pointers_to_1, matrix.nrows + 1,
159+
index_type);
160+
if (error != BSP_SUCCESS) {
161+
bsp_destroy_array_t(&result.values);
162+
bsp_destroy_array_t(&result.indices_1);
163+
return bsp_construct_default_matrix_t();
164+
}
128165

129166
bsp_array_t rowptr = result.pointers_to_1;
130167

include/binsparse/error.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2024 Binsparse Developers
3+
*
4+
* SPDX-License-Identifier: BSD-3-Clause
5+
*/
6+
7+
#pragma once
8+
9+
typedef enum bsp_error_t {
10+
BSP_SUCCESS = 0,
11+
12+
// Memory-related failures (malloc, array allocation, etc.)
13+
BSP_ERROR_MEMORY = 1,
14+
15+
// File I/O failures (file not found, read/write errors, HDF5 operations)
16+
BSP_ERROR_IO = 2,
17+
18+
// JSON parsing and metadata errors
19+
BSP_ERROR_FORMAT = 3,
20+
21+
// Invalid input parameters, dimensions, types, etc.
22+
BSP_ERROR_INVALID_INPUT = 4,
23+
24+
// Unsupported operations or not-yet-implemented features
25+
BSP_ERROR_UNSUPPORTED = 5,
26+
27+
// Type-related errors (invalid types, type mismatches)
28+
BSP_ERROR_TYPE = 6,
29+
30+
// Generic internal errors (should-never-happen cases)
31+
BSP_ERROR_INTERNAL = 7
32+
33+
} bsp_error_t;
34+
35+
/**
36+
* Get a human-readable error message for a bsp_error_t code.
37+
*
38+
* @param error The error code
39+
* @return A constant string describing the error
40+
*/
41+
static inline const char* bsp_get_error_string(bsp_error_t error) {
42+
switch (error) {
43+
case BSP_SUCCESS:
44+
return "Success";
45+
case BSP_ERROR_MEMORY:
46+
return "Memory allocation or management error";
47+
case BSP_ERROR_IO:
48+
return "File I/O or HDF5 operation error";
49+
case BSP_ERROR_FORMAT:
50+
return "JSON parsing or metadata format error";
51+
case BSP_ERROR_INVALID_INPUT:
52+
return "Invalid input parameters or data";
53+
case BSP_ERROR_UNSUPPORTED:
54+
return "Unsupported operation or feature";
55+
case BSP_ERROR_TYPE:
56+
return "Data type error or type mismatch";
57+
case BSP_ERROR_INTERNAL:
58+
return "Internal library error";
59+
default:
60+
return "Unknown error";
61+
}
62+
}

include/binsparse/generate.h

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,27 @@ static inline bsp_matrix_t bsp_generate_coo(size_t m, size_t n, size_t nnz,
7474
matrix.nrows = m;
7575
matrix.ncols = n;
7676
matrix.nnz = nnz;
77-
matrix.values = bsp_construct_array_t(nnz, value_type);
78-
matrix.indices_0 = bsp_construct_array_t(nnz, index_type);
79-
matrix.indices_1 = bsp_construct_array_t(nnz, index_type);
77+
78+
bsp_error_t error;
79+
error = bsp_construct_array_t(&matrix.values, nnz, value_type);
80+
if (error != BSP_SUCCESS) {
81+
// Return empty matrix on error
82+
return matrix;
83+
}
84+
85+
error = bsp_construct_array_t(&matrix.indices_0, nnz, index_type);
86+
if (error != BSP_SUCCESS) {
87+
bsp_destroy_array_t(&matrix.values);
88+
return matrix;
89+
}
90+
91+
error = bsp_construct_array_t(&matrix.indices_1, nnz, index_type);
92+
if (error != BSP_SUCCESS) {
93+
bsp_destroy_array_t(&matrix.values);
94+
bsp_destroy_array_t(&matrix.indices_0);
95+
return matrix;
96+
}
97+
8098
matrix.format = BSP_COO;
8199

82100
bsp_array_fill_random(matrix.values, 100);

include/binsparse/hdf5_wrapper.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@
2424
static inline int bsp_write_array(hid_t f, const char* label, bsp_array_t array,
2525
int compression_level) {
2626
if (array.type == BSP_COMPLEX_FLOAT32 || array.type == BSP_COMPLEX_FLOAT64) {
27-
array = bsp_complex_array_to_fp(array);
27+
bsp_error_t error = bsp_complex_array_to_fp(&array);
28+
if (error != BSP_SUCCESS) {
29+
return -3; // Type conversion error
30+
}
2831
}
2932

3033
hsize_t hsize[1];
@@ -198,12 +201,21 @@ static inline bsp_array_t bsp_read_array(hid_t f, const char* label) {
198201

199202
bsp_type_t type = bsp_get_bsp_type(hdf5_type);
200203

201-
bsp_array_t array = bsp_construct_array_t(dims[0], type);
204+
bsp_array_t array = bsp_construct_default_array_t();
205+
bsp_error_t error = bsp_construct_array_t(&array, dims[0], type);
206+
if (error != BSP_SUCCESS) {
207+
H5Dclose(dset);
208+
H5Sclose(fspace);
209+
return bsp_construct_default_array_t();
210+
}
202211

203212
herr_t status = H5Dread(dset, bsp_get_hdf5_native_type(type), H5S_ALL,
204213
H5S_ALL, H5P_DEFAULT, array.data);
205214

206215
if (status < 0) {
216+
bsp_destroy_array_t(&array);
217+
H5Dclose(dset);
218+
H5Sclose(fspace);
207219
return bsp_construct_default_array_t();
208220
}
209221

include/binsparse/matrix.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ static inline bsp_matrix_t bsp_construct_default_matrix_t() {
3939
}
4040

4141
static inline void bsp_destroy_matrix_t(bsp_matrix_t matrix) {
42-
bsp_destroy_array_t(matrix.values);
43-
bsp_destroy_array_t(matrix.indices_0);
44-
bsp_destroy_array_t(matrix.indices_1);
45-
bsp_destroy_array_t(matrix.pointers_to_1);
42+
bsp_destroy_array_t(&matrix.values);
43+
bsp_destroy_array_t(&matrix.indices_0);
44+
bsp_destroy_array_t(&matrix.indices_1);
45+
bsp_destroy_array_t(&matrix.pointers_to_1);
4646
}
4747

4848
static inline size_t bsp_matrix_nbytes(bsp_matrix_t mat) {

0 commit comments

Comments
 (0)