-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsimple_array.c
More file actions
152 lines (131 loc) · 3.3 KB
/
simple_array.c
File metadata and controls
152 lines (131 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/* simplified array usage, with resizing and sanity checks
*
* Cameron McBride
* cameron.mcbride AT gmail.com
* January 2013
* */
#pragma once
#ifndef SIMPLE_ARRAY_DEFINED
#define SIMPLE_ARRAY_DEFINED 1
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
#include <check_alloc.c>
#define SA_GROW_BY_FACTOR 2
typedef struct { /* member names chosen to match 'man 3 calloc' */
size_t count; /* count: number of elements */
size_t size; /* size: memory size of each element */
void *data; /* data: pointer to actual storage array */
} simple_array;
static inline void
sa_check_not_null( simple_array const *const sa )
{
if( NULL == sa ) {
fprintf( stderr, "Error: simple_array expected to be NOT NULL!\n" );
assert( NULL == sa );
}
}
void
sa_init( simple_array * const sa, const size_t count, const size_t size )
{
sa_check_not_null( sa );
sa->data = check_alloc( count, size );
sa->count = count;
sa->size = size;
}
void
sa_kill( simple_array * const sa )
{
if( NULL != sa ) {
CHECK_FREE( sa->data );
sa->count = 0;
sa->size = 0;
}
}
simple_array *
sa_alloc( const size_t count, const size_t size )
{
simple_array *sa;
sa = ( simple_array * ) check_alloc( 1, sizeof( simple_array ) );
sa_init( sa, count, size );
return sa;
}
simple_array *
sa_clean( simple_array * sa )
{
sa_kill( sa );
CHECK_FREE( sa );
return NULL;
}
void *
sa_set_length( simple_array * const sa, const size_t new_count )
{
sa_check_not_null( sa );
if( new_count != sa->count ) {
sa->data = check_realloc( sa->data, new_count, sa->size );
if( new_count > sa->count ) {
/* new bounds should be zero filled! */
size_t len;
int8_t *d, *n;
/* sanity check! */
assert( sa->size % sizeof( int8_t ) == 0 );
/* get pointer to new memory location */
d = ( int8_t * ) sa->data;
n = &( d[sa->count * sa->size] );
len = ( new_count - sa->count ) * sa->size;
memset( n, 0, len );
}
sa->count = new_count;
}
return sa->data;
}
void *
sa_ensure_length( simple_array * const sa, const size_t count )
{
sa_check_not_null( sa );
size_t new_count = sa->count;
/* a no-op if we already think it's big enough */
if( sa->count >= count )
return sa->data;
/* for efficiency, try to realloc to a FACTOR of new elements */
while( new_count < count )
new_count *= SA_GROW_BY_FACTOR;
return sa_set_length( sa, new_count );
}
bool
sa_check_length( simple_array const *const sa, const size_t count )
{
sa_check_not_null( sa );
if( sa->count >= count )
return true;
else
return false;
}
void *
sa_data( simple_array const *const sa )
{
sa_check_not_null( sa );
return sa->data;
}
size_t
sa_elcount( simple_array const *const sa )
{
sa_check_not_null( sa );
return sa->count;
}
size_t
sa_elsize( simple_array const *const sa )
{
sa_check_not_null( sa );
return sa->size;
}
size_t
sa_data_memsize( simple_array const *const sa )
{
sa_check_not_null( sa );
return ( sa->size * sa->count );
}
#endif