1
/******************************************************
2
The dynamically allocated array
6
Created 2/5/1996 Heikki Tuuri
7
*******************************************************/
9
#define DYN_BLOCK_MAGIC_N 375767
10
#define DYN_BLOCK_FULL_FLAG 0x1000000UL
12
/****************************************************************
13
Adds a new block to a dyn array. */
18
/* out: created block */
19
dyn_array_t* arr); /* in: dyn array */
22
/****************************************************************
23
Gets the first block in a dyn array. */
26
dyn_array_get_first_block(
27
/*======================*/
28
dyn_array_t* arr) /* in: dyn array */
33
/****************************************************************
34
Gets the last block in a dyn array. */
37
dyn_array_get_last_block(
38
/*=====================*/
39
dyn_array_t* arr) /* in: dyn array */
41
if (arr->heap == NULL) {
46
return(UT_LIST_GET_LAST(arr->base));
49
/************************************************************************
50
Gets the next block in a dyn array. */
53
dyn_array_get_next_block(
54
/*=====================*/
55
/* out: pointer to next, NULL if end of list */
56
dyn_array_t* arr, /* in: dyn array */
57
dyn_block_t* block) /* in: dyn array block */
61
if (arr->heap == NULL) {
67
return(UT_LIST_GET_NEXT(list, block));
70
/************************************************************************
71
Gets the number of used bytes in a dyn array block. */
76
/* out: number of bytes used */
77
dyn_block_t* block) /* in: dyn array block */
81
return((block->used) & ~DYN_BLOCK_FULL_FLAG);
84
/************************************************************************
85
Gets pointer to the start of data in a dyn array block. */
90
/* out: pointer to data */
91
dyn_block_t* block) /* in: dyn array block */
98
/*************************************************************************
99
Initializes a dynamic array. */
104
/* out: initialized dyn array */
105
dyn_array_t* arr) /* in: pointer to a memory buffer of
106
size sizeof(dyn_array_t) */
109
#if DYN_ARRAY_DATA_SIZE >= DYN_BLOCK_FULL_FLAG
110
# error "DYN_ARRAY_DATA_SIZE >= DYN_BLOCK_FULL_FLAG"
118
arr->magic_n = DYN_BLOCK_MAGIC_N;
123
/****************************************************************
124
Frees a dynamic array. */
129
dyn_array_t* arr) /* in: dyn array */
131
if (arr->heap != NULL) {
132
mem_heap_free(arr->heap);
140
/*************************************************************************
141
Makes room on top of a dyn array and returns a pointer to the added element.
142
The caller must copy the element to the pointer returned. */
147
/* out: pointer to the element */
148
dyn_array_t* arr, /* in: dynamic array */
149
ulint size) /* in: size in bytes of the element */
155
ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
156
ut_ad(size <= DYN_ARRAY_DATA_SIZE);
162
if (used + size > DYN_ARRAY_DATA_SIZE) {
163
/* Get the last array block */
165
block = dyn_array_get_last_block(arr);
168
if (used + size > DYN_ARRAY_DATA_SIZE) {
169
block = dyn_array_add_block(arr);
174
block->used = used + size;
175
ut_ad(block->used <= DYN_ARRAY_DATA_SIZE);
177
return((block->data) + used);
180
/*************************************************************************
181
Makes room on top of a dyn array and returns a pointer to a buffer in it.
182
After copying the elements, the caller must close the buffer using
188
/* out: pointer to the buffer */
189
dyn_array_t* arr, /* in: dynamic array */
190
ulint size) /* in: size in bytes of the buffer; MUST be
191
smaller than DYN_ARRAY_DATA_SIZE! */
197
ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
198
ut_ad(size <= DYN_ARRAY_DATA_SIZE);
204
if (used + size > DYN_ARRAY_DATA_SIZE) {
205
/* Get the last array block */
207
block = dyn_array_get_last_block(arr);
210
if (used + size > DYN_ARRAY_DATA_SIZE) {
211
block = dyn_array_add_block(arr);
213
ut_a(size <= DYN_ARRAY_DATA_SIZE);
217
ut_ad(block->used <= DYN_ARRAY_DATA_SIZE);
219
ut_ad(arr->buf_end == 0);
221
arr->buf_end = used + size;
223
return((block->data) + used);
226
/*************************************************************************
227
Closes the buffer returned by dyn_array_open. */
232
dyn_array_t* arr, /* in: dynamic array */
233
byte* ptr) /* in: buffer space from ptr up was not used */
238
ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
240
block = dyn_array_get_last_block(arr);
242
ut_ad(arr->buf_end + block->data >= ptr);
244
block->used = ptr - block->data;
246
ut_ad(block->used <= DYN_ARRAY_DATA_SIZE);
253
/****************************************************************
254
Returns pointer to an element in dyn array. */
257
dyn_array_get_element(
258
/*==================*/
259
/* out: pointer to element */
260
dyn_array_t* arr, /* in: dyn array */
261
ulint pos) /* in: position of element as bytes
268
ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
270
/* Get the first array block */
271
block = dyn_array_get_first_block(arr);
273
if (arr->heap != NULL) {
274
used = dyn_block_get_used(block);
276
while (pos >= used) {
278
block = UT_LIST_GET_NEXT(list, block);
281
used = dyn_block_get_used(block);
286
ut_ad(dyn_block_get_used(block) >= pos);
288
return(block->data + pos);
291
/****************************************************************
292
Returns the size of stored data in a dyn array. */
295
dyn_array_get_data_size(
296
/*====================*/
297
/* out: data size in bytes */
298
dyn_array_t* arr) /* in: dyn array */
304
ut_ad(arr->magic_n == DYN_BLOCK_MAGIC_N);
306
if (arr->heap == NULL) {
311
/* Get the first array block */
312
block = dyn_array_get_first_block(arr);
314
while (block != NULL) {
315
sum += dyn_block_get_used(block);
316
block = dyn_array_get_next_block(arr, block);
322
/************************************************************
323
Pushes n bytes to a dyn array. */
328
dyn_array_t* arr, /* in: dyn array */
329
const byte* str, /* in: string to write */
330
ulint len) /* in: string length */
335
if (len > DYN_ARRAY_DATA_SIZE) {
336
n_copied = DYN_ARRAY_DATA_SIZE;
341
memcpy(dyn_array_push(arr, n_copied), str, n_copied);