/** rjp Copyright (C) 2018-2020 rexy712 This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "rjp_internal.h" #include "rjp_array.h" #include "rjp_value.h" #include "rjp_array_element.h" #include //memset void irjp_copy_array(RJP_value* dest, const RJP_value* src, const RJP_memory_fns* fns){ dest->array.elements = dest->array.last = NULL; for(RJP_array_element* curr = src->array.elements;curr;curr = curr->next){ RJP_value* copy_mem; copy_mem = rjp_new_element_c(dest, fns); rjp_copy_value_c(copy_mem, &curr->value, fns); } } void irjp_add_element(RJP_array* j, const RJP_memory_fns* fns){ ++j->num_elements; if(!j->elements){ j->elements = fns->alloc(sizeof(RJP_array_element)); memset(j->elements, 0, sizeof(RJP_array_element)); j->last = j->elements; }else{ j->last->next = fns->alloc(sizeof(RJP_array_element)); memset(j->last->next, 0, sizeof(RJP_array_element)); j->last = j->last->next; j->last->prev = j->last; } } RJP_value* rjp_new_element(RJP_value* dest){ return rjp_new_element_c(dest, &irjp_default_memory_fns); } RJP_value* rjp_new_element_c(RJP_value* dest, const RJP_memory_fns* fns){ irjp_add_element(&dest->array, fns); dest->array.last->value.parent = dest; return &dest->array.last->value; } RJP_value* rjp_add_element(RJP_value* dest, RJP_value* src){ return rjp_add_element_c(dest, src, &irjp_default_memory_fns); } RJP_value* rjp_add_element_c(RJP_value* dest, RJP_value* src, const RJP_memory_fns* fns){ RJP_value* newelm = rjp_new_element_c(dest, fns); if(!newelm) return NULL; rjp_move_value(newelm, src); fns->free(src); return newelm; } RJP_value* rjp_remove_element(RJP_value* dest, RJP_value* value){ if(value->parent != dest) return NULL; RJP_array* j = &dest->array; --j->num_elements; RJP_array_element* elem = (RJP_array_element*)value; RJP_array_element* prev = elem->prev; RJP_array_element* next = elem->next; if(prev) prev->next = elem->next; if(next) next->prev = prev; if(elem == j->elements) j->elements = next; if(elem == j->last) j->last = prev; return value; } void rjp_free_element(RJP_value* dest, RJP_value* value){ rjp_free_element_c(dest, value, &irjp_default_memory_fns); } void rjp_free_element_c(RJP_value* dest, RJP_value* value, const RJP_memory_fns* fns){ rjp_remove_element(dest, value); rjp_free_value_c(value, fns); } RJP_index rjp_num_elements(const RJP_value* array){ return array->array.num_elements; } void rjp_init_array_iterator(RJP_array_iterator* iter, const RJP_value* array){ iter->current = (RJP_value*)(array->array.elements); } void rjp_delete_array_iterator(RJP_array_iterator* it){ if(!it) return; it->current = NULL; } RJP_value* rjp_array_iterator_current(const RJP_array_iterator* it){ return it->current; } RJP_value* rjp_array_iterator_next(RJP_array_iterator* it){ RJP_array_element* curr = (RJP_array_element*)it->current; it->current = curr ? (RJP_value*)(curr->next) : NULL; return it->current; } RJP_value* rjp_array_iterator_peek(const RJP_array_iterator* it){ RJP_array_element* curr = (RJP_array_element*)it->current; return curr ? &(curr->next->value) : NULL; }