/** 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 #include "rjp_internal.h" #include "rjp_array.h" #include "rjp_value.h" #include "rjp_array_element.h" void irjp_copy_array(RJP_value* dest, const RJP_value* src){ 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_add_element(dest); rjp_copy_value(copy_mem, &curr->value); } } void irjp_add_element(RJP_array* j){ ++j->num_elements; if(!j->elements){ j->elements = rjp_calloc(1, sizeof(RJP_array_element)); j->last = j->elements; }else{ j->last->next = rjp_calloc(1, sizeof(RJP_array_element)); j->last = j->last->next; j->last->prev = j->last; } } RJP_value* rjp_add_element(RJP_value* dest){ irjp_add_element(&dest->array); dest->array.last->value.parent = dest; return &dest->array.last->value; } 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_remove_element(dest, value); rjp_free_value(value); } 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; }