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);