finish up plugin architecture
[csRadar.git] / csrMem.h
1 // Copyright (C) 2021 Harry Godden (hgn)
2
3 // Memory API
4 // ==================================================================================================================
5
6 // Malloc call wrapper that will exit if out of memory (similar to xalloc)
7 void *csr_malloc( size_t size );
8 void *csr_calloc( size_t size );
9
10 // Dynamic arrays (inspired by stb_stretchy_buffer)
11 // ------------------------------------------------
12
13 // Reserve x elements of size to this buffer. Must assign back (like realloc)
14 __attribute__((warn_unused_result))
15 void *csr_sb_reserve( void *arr, u32 amt, u32 esize );
16
17 // Get index of next free data and increment count by 1
18 void *csr_sb_use( void *arr );
19
20 // Increment count by amt
21 void csr_sb_inc( void *arr, u32 amt );
22
23 u32 csr_sb_count( void *arr );
24 void csr_sb_free( void *arr );
25
26 // Does not clear memory / capacity, but resets count to 0
27 void csr_sb_clear( void *arr );
28
29 // Internal
30 void *csr_sb_raw( void *arr );
31 u32 csr_sb_cap( void *arr );
32
33 // djb2 - Dan Bernstein
34 unsigned long djb2( unsigned char const *str );
35
36 // Implementation
37 // ==================================================================================================================
38
39 #ifdef CSR_EXECUTABLE
40
41 void *csr_malloc( size_t size )
42 {
43 void *ret = malloc( size );
44 if( !ret )
45 exit(1);
46 return ret;
47 }
48
49 void *csr_calloc( size_t size )
50 {
51 void *ret = calloc( 1, size );
52 if( !ret )
53 exit(1);
54 return ret;
55 }
56
57 void *csr_sb_raw( void *arr )
58 {
59 return ((u32 *)arr)-3;
60 }
61
62 u32 csr_sb_count( void *arr )
63 {
64 return arr? ((u32 *)csr_sb_raw( arr ))[1]: 0;
65 }
66
67 u32 csr_sb_cap( void *arr )
68 {
69 return arr? ((u32 *)csr_sb_raw( arr ))[0]: 0;
70 }
71
72 void *csr_sb_use( void *arr )
73 {
74 u32 *raw = (u32 *)csr_sb_raw( arr );
75 void *data = ((u8 *)arr) + raw[1]*raw[2];
76
77 raw[1] ++;
78
79 return data;
80 }
81
82 void csr_sb_inc( void *arr, u32 amt )
83 {
84 u32 *raw = (u32 *)csr_sb_raw( arr );
85 raw[1] += amt;
86 }
87
88 void *csr_sb_reserve( void *arr, u32 amt, u32 esize )
89 {
90 u32 cap = arr? csr_sb_cap( arr ): 0;
91 u32 count = arr? csr_sb_count( arr ): 0;
92
93 if( count + amt > cap )
94 {
95 cap = csr_max( count + amt, cap * 2 );
96 u32 *new_ptr = (u32 *)realloc( arr? csr_sb_raw( arr ): NULL, cap * esize + 3*sizeof(u32) );
97
98 if( !new_ptr )
99 abort();
100
101 new_ptr[0] = cap;
102 new_ptr[1] = count;
103 new_ptr[2] = esize;
104
105 return (void *)(new_ptr+3);
106 }
107 else
108 {
109 return arr;
110 }
111 }
112
113 void csr_sb_free( void *arr )
114 {
115 if( arr )
116 {
117 free( csr_sb_raw( arr ) );
118 }
119 }
120
121 void csr_sb_clear( void *arr )
122 {
123 if( arr )
124 {
125 ((u32 *)csr_sb_raw( arr ))[1] = 0;
126 }
127 }
128
129 // djb2 - Dan Bernstein
130 unsigned long djb2( unsigned char const *str )
131 {
132 unsigned long hash = 5381;
133 int c;
134
135 while((c = *str++))
136 hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
137
138 return hash;
139 }
140
141 #endif