96 lines
2.9 KiB
C
96 lines
2.9 KiB
C
/**
|
|
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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "rjp_array.h"
|
|
#include "rjp_internal.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){
|
|
RJP_array* j = &dest->array;
|
|
if(!j->num_elements)
|
|
return NULL;
|
|
|
|
--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 = &(array->array.elements->value);
|
|
}
|
|
void rjp_delete_array_iterator(RJP_array_iterator* it){
|
|
it->current = NULL;
|
|
}
|
|
RJP_value* rjp_get_element(const RJP_value* array){
|
|
return &array->array.elements->value;
|
|
}
|
|
RJP_value* rjp_array_iterator_current(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 ? &(curr->next->value) : NULL;
|
|
return it->current;
|
|
}
|
|
RJP_value* rjp_array_iterator_peek(RJP_array_iterator* it){
|
|
RJP_array_element* curr = (RJP_array_element*)it->current;
|
|
return curr ? &(curr->next->value) : NULL;
|
|
}
|