size_t zt_bstream_read(zt_bstream_t bs, char *buf, size_t len, char size, char tag UNUSED) { zt_assert(bs); zt_assert(buf); bs->offt = _array_get(bs->data, buf, bs->offt, (len * size), bs->flipendian); return 0; }
int32_t array_clone(struct array* array_src, struct array* array_dst){ uint32_t i; int32_t result = -1; struct arrayPage* page_src; struct arrayPage* page_dst; array_dst->buffer = malloc(array_src->nb_allocated_byte); if (array_dst->buffer == NULL){ log_err("unable to allocate memory"); return result; } memcpy(array_dst->buffer, array_src->buffer, array_src->nb_filled_byte); array_dst->nb_allocated_byte = array_src->nb_allocated_byte; array_dst->nb_filled_byte = array_src->nb_filled_byte; array_dst->nb_element = array_src->nb_element; array_dst->element_size = array_src->element_size; array_dst->nb_element_per_page = array_src->nb_element_per_page; if (_array_clone(&(array_src->pages), &(array_dst->pages))){ log_err("unable to clone _array pages"); free(array_dst->buffer); return result; } for (i = 0; i < _array_get_length(array_dst->pages); i++){ page_src = (struct arrayPage*)_array_get(array_src->pages, i); page_dst = (struct arrayPage*)_array_get(array_dst->pages, i); page_dst->buffer = malloc(page_src->nb_allocated_byte); if (page_dst->buffer == NULL){ log_err_m("unable to allocate memory for page %u", i); return result; } memcpy(page_dst->buffer, page_src->buffer, page_src->nb_filled_byte); } result = 0; return result; }
void array_clean(struct array* array){ uint32_t i; struct arrayPage* page; free(array->buffer); for (i = 0; i < _array_get_length(array->pages); i++){ page = (struct arrayPage*)_array_get(array->pages, i); free(page->buffer); } _array_clean(&(array->pages)); }
void array_empty(struct array* array){ uint32_t i; struct arrayPage* page; array->nb_filled_byte = 0; array->nb_element = 0; for (i = 0; i < _array_get_length(array->pages); i++){ page = (struct arrayPage*)_array_get(array->pages, i); free(page->buffer); } _array_empty(&(array->pages)); }
int32_t array_copy(struct array* array_src, struct array* array_dst, uint32_t offset, uint32_t nb_element){ int32_t result = -1; uint32_t nb_remaining_element; char* buffer; uint32_t nb_allocated_element; uint32_t nb_allocated_byte; uint32_t nb_copied_byte; uint32_t nb_copied_element; struct arrayPage page; uint32_t copy_index_src; char* copy_ptr_src; struct arrayPage* page_src; if (array_src->element_size != array_dst->element_size || array_src->nb_element_per_page != array_dst->nb_element_per_page){ log_err("copy between arrays of different element size is a dangerous thing -> abort"); return result; } if (array_src->nb_element < offset + nb_element){ log_err("source array does not contain required elements -> abort"); return result; } nb_remaining_element = nb_element; while (nb_remaining_element > 0){ nb_allocated_element = ((ARRAY_DEFAULT_PAGE_SIZE - array_dst->nb_filled_byte) / array_dst->element_size > nb_remaining_element) ? nb_remaining_element : ((ARRAY_DEFAULT_PAGE_SIZE - array_dst->nb_filled_byte) / array_dst->element_size); nb_allocated_byte = ((array_dst->nb_filled_byte + nb_allocated_element * array_dst->element_size) / ARRAY_DEFAULT_ALLOC_SIZE + ((!((array_dst->nb_filled_byte + nb_allocated_element * array_dst->element_size) % ARRAY_DEFAULT_ALLOC_SIZE)) ? 0 : 1)) * ARRAY_DEFAULT_ALLOC_SIZE; if (nb_allocated_byte > array_dst->nb_allocated_byte){ buffer = realloc(array_dst->buffer, nb_allocated_byte); if (buffer == NULL){ log_err("unable to realloc memory"); break; } array_dst->buffer = buffer; array_dst->nb_allocated_byte = nb_allocated_byte; } nb_copied_element = 0; while (nb_copied_element < nb_allocated_element){ copy_index_src = offset + (nb_element - nb_remaining_element) + nb_copied_element; if (_array_get_length(array_src->pages) * (ARRAY_DEFAULT_PAGE_SIZE / array_src->element_size) <= copy_index_src){ copy_ptr_src = array_src->buffer + (copy_index_src % (ARRAY_DEFAULT_PAGE_SIZE / array_src->element_size)) * array_src->element_size; nb_copied_byte = (nb_allocated_element - nb_copied_element) * array_src->element_size; } else{ page_src = (struct arrayPage*)_array_get(array_src->pages, copy_index_src / (ARRAY_DEFAULT_PAGE_SIZE / array_src->element_size)); copy_ptr_src = page_src->buffer + (copy_index_src % (ARRAY_DEFAULT_PAGE_SIZE / array_src->element_size)) * array_src->element_size; nb_copied_byte = (((nb_allocated_element - nb_copied_element) > ((ARRAY_DEFAULT_PAGE_SIZE / array_src->element_size) - (copy_index_src % (ARRAY_DEFAULT_PAGE_SIZE / array_src->element_size)))) ? ((ARRAY_DEFAULT_PAGE_SIZE / array_src->element_size) - (copy_index_src % (ARRAY_DEFAULT_PAGE_SIZE / array_src->element_size))) : (nb_allocated_element - nb_copied_element)) * array_src->element_size; } memcpy(array_dst->buffer + array_dst->nb_filled_byte, copy_ptr_src, nb_copied_byte); nb_copied_element += nb_copied_byte / array_dst->element_size; array_dst->nb_filled_byte += nb_copied_byte; } array_dst->nb_element += nb_allocated_element; if (array_dst->nb_allocated_byte == ARRAY_DEFAULT_PAGE_SIZE){ page.buffer = array_dst->buffer; page.nb_allocated_byte = array_dst->nb_allocated_byte; page.nb_filled_byte = array_dst->nb_filled_byte; if (_array_add(&(array_dst->pages), &page) < 0){ log_err("unable to archive page"); break; } array_dst->nb_allocated_byte = 0; array_dst->nb_filled_byte = 0; array_dst->buffer = NULL; } nb_remaining_element -= nb_copied_element; } result = (int32_t)(nb_element - nb_remaining_element); return result; }