Files
y_project/yjson_t/src/json_t/json_t.c
T

1244 lines
38 KiB
C

#include "json_t/json_t.h"
bool is_js_space(char c){
//printf("c=|%c|[%d]\n",c,c);
if(c == ' ') return true;
if(c == '\t') return true;
if(c == '\n') return true;
if(c == '\r') return true;
return false;
}
void set_index_(struct js_value *js, size_t index){
if(js->code_type == jstype_object)
js->type.object.index = index;
else if(js->code_type == jstype_array)
js->type.array.index = index;
}
long get_index_(struct js_value *js){
if(js->code_type == jstype_object)
return js->type.object.index;
if(js->code_type == jstype_array)
return js->type.array.index;
return -1;
}
struct js_value * next_(struct js_value *js){
if(js->code_type == jstype_object){
return js->type.object.next_object;
}
if(js->code_type == jstype_array){
return js->type.array.next_element;
}
return NULL;
}
struct js_value * prev_(struct js_value *js){
if(js->code_type == jstype_object){
return js->type.object.prev_object;
}
if(js->code_type == jstype_array){
return js->type.array.prev_element;
}
return NULL;
}
void free_js_value__(struct js_value *js){
if(js->code_type == jstype_string){
free(js->type.string);
}else if(js->code_type == jstype_object){
// free_js_value(js->type.object.key);
free_js_value(js->type.object.value);
struct js_value *tmpV = js->type.object.next_object;
js->type.object.next_object = NULL;
struct js_value *ttmp;
while(tmpV){
ttmp = tmpV;
tmpV = ttmp->type.object.next_object ; //next_(ttmp);
ttmp->type.object.next_object = NULL;
//print_js_value(ttmp);
free_js_value(ttmp);
}
if(js->type.object.index == 0 && js->type.object.iter){
free(js->type.object.iter);
js->type.object.iter = NULL;
}
}else if(js->code_type == jstype_array){
free_js_value(js->type.array.value);
struct js_value *tmpV = js->type.array.next_element;
js->type.array.next_element = NULL;
struct js_value *ttmp;
while(tmpV){
ttmp = tmpV;
tmpV = ttmp->type.array.next_element ; //next_(ttmp);
ttmp->type.array.next_element = NULL;
//print_js_value(ttmp);
free_js_value(ttmp);
}
if(js->type.array.index == 0 && js->type.array.iter){
free(js->type.array.iter);
js->type.array.iter = NULL;
}
}
free(js);
}
void _free_js_value_no_free_iter(struct js_value *js){
if(js!=NULL){
if(js->code_type == jstype_number){
free(js);
}else if(js->code_type == jstype_string){
free(js->type.string);
free(js);
}else if(js->code_type == jstype_bool){
free(js);
}else if(js->code_type == jstype_null){
free(js);
}else if(js->code_type == jstype_object){
struct js_value *tmpjs = NULL;
while(js){
tmpjs=js;
_free_js_value_no_free_iter(tmpjs->type.object.value);
js = tmpjs->type.object.next_object;
free(tmpjs);
}
}else if(js->code_type == jstype_array){
struct js_value *tmpjs = NULL;
while(js){
tmpjs = js;
_free_js_value_no_free_iter(tmpjs->type.array.value);
js = tmpjs->type.array.next_element; // next_(tmpjs);
free(tmpjs);
}
}
}
}
void free_js_value(struct js_value *js){
if(js!=NULL){
if(js->code_type == jstype_number){
free(js);
}else if(js->code_type == jstype_string){
free(js->type.string);
free(js);
}else if(js->code_type == jstype_bool){
free(js);
}else if(js->code_type == jstype_null){
free(js);
}else if(js->code_type == jstype_object){
struct js_value *tmpjs = NULL;
while(js){
tmpjs=js;
if((tmpjs->type.object.iter != NULL) && (tmpjs->type.object.prev_object == NULL)){
free(tmpjs->type.object.iter);
}
if(tmpjs->type.object.key)
free(tmpjs->type.object.key);
free_js_value(tmpjs->type.object.value);
js = tmpjs->type.object.next_object;
free(tmpjs);
}
}else if(js->code_type == jstype_array){
struct js_value *tmpjs = NULL;
while(js){
tmpjs = js;
if((tmpjs->type.array.iter!=NULL) && (tmpjs->type.array.prev_element == NULL)){
free(tmpjs->type.array.iter);
}
free_js_value(tmpjs->type.array.value);
js = tmpjs->type.array.next_element; // next_(tmpjs);
free(tmpjs);
}
}
}
}
struct js_value * create_js_value_string(char * input, struct js_value * parent){
struct js_value * js = malloc(sizeof(struct js_value));
js->parent = parent;
/*
if(*input == '"')
js->str_value = input+1;
else*/
js->str_value = input;
js->code_type = jstype_string;
char *cur = js->str_value;
//if(*input == '"') ++cur;
for(;*cur && *cur!='"'; ++cur);
if(*cur=='\0'){
fprintf(stderr, "error string format, \" missing\n");
free(js);
return NULL;
}
js->length = cur - js->str_value;
js->type.string = malloc(js->length + 1);
strncpy(js->type.string, js->str_value, js->length);
js->type.string[js->length]='\0';
return js;
}
struct js_value * create_js_value_number(char * input, struct js_value * parent){
struct js_value * js = malloc(sizeof(struct js_value));
js->parent = parent;
js->str_value = input;
js->code_type = jstype_number;
char *end;
js->type.number = strtold(input, &end);
js->length = end - input;
// printf("\nend_num:%s, num:%s, lenN:%ld\n",end,input, js->length);
return js;
}
struct js_value * create_js_value_null(char * input, struct js_value * parent){
struct js_value * js = malloc(sizeof(struct js_value));
js->parent = parent;
js->str_value = input;
js->code_type = jstype_null;
js->length = 4;
return js;
}
struct js_value * create_js_value_true(char * input, struct js_value * parent){
struct js_value * js = malloc(sizeof(struct js_value));
js->parent = parent;
js->str_value = input;
js->code_type = jstype_bool;
js->type.boolean = true;
js->length = 4;
return js;
}
struct js_value * create_js_value_false(char * input, struct js_value * parent){
struct js_value * js = malloc(sizeof(struct js_value));
js->parent = parent;
js->str_value = input;
js->code_type = jstype_bool;
js->type.boolean = false;
js->length = 5;
return js;
}
struct js_value * create_js_value_array(char * _input, struct js_value * parent){
struct js_value * js_parent = malloc(sizeof(struct js_value));
struct js_value * js, *tmp_js;
js = js_parent;
char *input = _input;
if(*_input == '[')
input = _input + 1;
char *cur = input;
for(long depth = 1; *cur != '\0' && depth != 0; ++cur){
if(*cur == '[') ++depth;
if(*cur == ']') --depth;
}
js->length = cur - input;
// printf("\na]input ==%s, len:%ld\n",input,js->length);
js->type.array.next_element = NULL;
js->type.array.prev_element = NULL;
js->type.array.index = 0;
js->type.array.iter = malloc(sizeof(struct js_iterator));
js->type.array.iter->size = js->type.array.index + 1;
js->type.array.iter->begin = js;
js->type.array.iter->end = js;
js->type.array.iter->current = js;
if(parent == NULL)
js->type.array.depth= 0;
else
js->type.array.depth = parent->type.array.depth + 1;
// js->index = 0;
js->str_value = input;
js->code_type = jstype_array;
cur = input;
for(; is_js_space(*cur); ++cur);
if(*cur == ']'){
js->type.array.value = create_js_value_null(NULL, js); // NULL;
js->type.array.value->length = cur - input + 1;
js->type.array.next_element = NULL;
js->parent = parent;
//js->type.object.key_length = cur - input;
//js->type.array.value = NULL;
return js;
}
while(cur < input + js_parent->length )
{
// printf("aa::%c\n",*cur);
if(*cur == ','){
++cur;
tmp_js = malloc(sizeof(struct js_value));
//for(; is_js_space(*cur); ++cur);
tmp_js->str_value = cur;// + 1;
tmp_js->code_type = jstype_array;
char *ccur = cur;
for(; *ccur != '\0' && *ccur != ',' ; ++ccur){
if(*ccur == '{'){ // to ignore ',' in the object
++ccur;
for(long depth = 1; *ccur != '\0' && depth != 0; ++ccur){
if(*ccur == '{') ++depth;
if(*ccur == '}') --depth;
}
//break;
}
if(*ccur == ']')
break;
if(*cur == '['){// to ignore ',' in the list
++ccur;
for(long depth = 1; *ccur != '\0' && depth != 0; ++ccur){
if(*ccur == '[') ++depth;
if(*ccur == ']') --depth;
}
//break;
}
if(*cur == '"'){ // to ignore ',' in "string value"
for(; *ccur != '\0' || *ccur !='"'; ++ccur);
}
}
tmp_js->length = ccur - cur;
tmp_js->type.array.prev_element = js;
tmp_js->type.array.next_element = NULL;
tmp_js->type.array.iter = js_parent->type.array.iter;
tmp_js->type.array.index = js->type.array.index + 1;
//tmp_js->type.object.iter = NULL;
js->type.array.next_element = tmp_js;
js= tmp_js;
if(parent == NULL)
js->type.array.depth= 0;
else
js->type.array.depth = parent->type.array.depth + 1;
js_parent->type.array.iter->size = js->type.array.index + 1;
js_parent->type.array.iter->end = js;
js_parent->type.array.iter->current = js;
}else{
}
js->parent = parent;
for(; is_js_space(*cur); ++cur);
// value section
char *str_value = cur; // + js->type.object.key->length;
js->type.array.value = create_js_value(str_value, js);
//cur = str_value + js->type.array.value->length + (js->type.array.value->code_type != jstype_number) ; //1 ;
cur = str_value + js->type.array.value->length + (js->type.array.value->code_type == jstype_string) ; //1 ;
// printf("<a>>strVal:%s\n",cur);
if(js->type.array.value->code_type == jstype_string)
for(; is_js_space(*cur) || *cur=='"' || *cur=='}' || *cur == ']'; ++cur);
else
for(; is_js_space(*cur) || *cur=='}' || *cur == ']'; ++cur);
}
return js_parent;
}
struct js_value * create_js_value(char *_input, struct js_value *parent){
char *input = _input;
for(; is_js_space(*input); ++input){}
//printf("\n>>strVal:%s\n",input);
if(*input == '"'){
return create_js_value_string(input+1, parent);
}else if(strncmp(input,"true",4) == 0){
return create_js_value_true(input, parent);
}else if(strncmp(input,"false",5) == 0){
return create_js_value_false(input, parent);
}else if(strncmp(input,"null",4) == 0){
return create_js_value_null(input, parent);
}else if(*input == '{'){
return create_js_value_object(input + 1, parent);
}else if(*input == '['){
return create_js_value_array(input + 1, parent);
}else /*if(isdigit(*input))*/{
return create_js_value_number(input, parent);
}
}
struct js_value * create_js_value_object(char *_input /*, struct js_value *prev*/, struct js_value * parent){
struct js_value * js_parent = malloc(sizeof(struct js_value));
struct js_value * js, *tmp_js;
js = js_parent;
char *input = _input;
if(*_input == '{')
input = _input + 1;
char *cur = input;
for(long depth = 1; *cur != '\0' && depth != 0; ++cur){
if(*cur == '{') ++depth;
if(*cur == '}') --depth;
}
js->length = cur - input;
js->type.object.next_object = NULL;
js->type.object.prev_object = NULL;
js->type.object.index = 0;
js->type.object.iter = malloc(sizeof(struct js_iterator));
js->type.object.iter->size = js->type.object.index + 1;
js->type.object.iter->begin = js;
js->type.object.iter->end = js;
js->type.object.iter->current = js;
if(parent == NULL)
js->type.object.depth = 0;
else
js->type.object.depth = parent->type.object.depth + 1;
js->str_value = input;
js->code_type = jstype_object;
cur = input;
for(; is_js_space(*cur); ++cur);
if(*cur == '}'){
js->type.object.value = create_js_value_null(NULL, js);// NULL;
js->type.object.value->length = cur - input;
js->type.object.key_length = 0;
js->type.object.key = NULL;
js->type.object.next_object = NULL;
js->parent = parent;
return js;
}
while(cur < input + js_parent->length)
{
if(*cur == ','){
++cur;
tmp_js = malloc(sizeof(struct js_value));
//for(; is_js_space(*cur); ++cur);
tmp_js->str_value = cur ;//+ 1;
tmp_js->code_type = jstype_object;
char *ccur = cur;
for(; *ccur != '\0' && *ccur != ',' ; ++ccur){
if(*ccur == '{'){ // to ignore ',' in the object
++ccur;
for(long depth = 1; *ccur != '\0' && depth != 0; ++ccur){
if(*ccur == '{') ++depth;
if(*ccur == '}') --depth;
}
//break;
}
if(*ccur == '}')
break;
if(*cur == '['){// to ignore ',' in the list
++ccur;
for(long depth = 1; *ccur != '\0' && depth != 0; ++ccur){
if(*ccur == '[') ++depth;
if(*ccur == ']') --depth;
}
//break;
}
if(*cur == '"'){ // to ignore ',' in "string value"
for(; *ccur != '\0' || *ccur !='"'; ++ccur);
}
}
tmp_js->length = ccur - cur;
tmp_js->type.object.prev_object = js;
tmp_js->type.object.next_object = NULL;
tmp_js->type.object.iter = js_parent->type.object.iter;
tmp_js->type.object.index = js->type.object.index + 1;
js->type.object.next_object = tmp_js;
js= tmp_js;
if(parent == NULL)
js->type.object.depth = 0;
else
js->type.object.depth = parent->type.object.depth + 1;
js_parent->type.object.iter->size = js->type.object.index + 1;
js_parent->type.object.iter->end = js;
js_parent->type.object.iter->current = js;
}else{
}
js->parent = parent;
for(; is_js_space(*cur); ++cur);
// key section
// js->type.object.key = create_js_value_string(cur, js);
if(*cur == '"'){
++cur;
}else{// no key ! problem format
printf("debug: format json error, no string with \" symbole as key\n");
free(js->type.object.iter);
free(js);
return NULL;
}
char *key = cur;
// /1/js->type.object.key = cur;
for(; *cur && *cur != '"'; ++cur);
if(*cur=='\0'){// no \" ! problem format
printf("debug: format json error: no \" symbole after key!\n");
free(js->type.object.iter);
free(js);
return NULL;
}
//js->key = cur;
//for(; *cur != '"'; ++cur);
//js->key_length = cur - js->key;
// /1/js->type.object.key_length = cur - js->type.object.key;
js->type.object.key_length = cur - key ;
js->type.object.key = malloc(js->type.object.key_length+1);
memcpy(js->type.object.key,key,js->type.object.key_length);
*(js->type.object.key + js->type.object.key_length) ='\0';
//js->type.object.key = cur;
for(; *cur && *cur != ':'; ++cur);
if(*cur=='\0'){// no \" ! problem format
printf("debug: format json error, no : after key\n");
free(js->type.object.key);
free(js->type.object.iter);
free(js);
return NULL;
}
++cur;
for(; is_js_space(*cur); ++cur);
// printf("cur=%s| lenKey :%ld \n",cur,js->type.object.key_length);
// value section
char *str_value = cur; // + js->type.object.key->length;
js->type.object.value = create_js_value(str_value, js);
if(js->type.object.value==NULL){
fprintf(stderr,"debug: format json error value\n");
free(js->type.object.key);
free(js->type.object.iter);
free(js);
return NULL;
}
//printf("\n[<<<: cur:%s\n(js->type.object.value->code_type != jstype_number)=%d\n",cur,(js->type.object.value->code_type != jstype_number));
cur = str_value + js->type.object.value->length + (js->type.object.value->code_type == jstype_string); // ((js->type.object.value->code_type < jstype_bool)||(js->type.object.value->code_type > jstype_number));// 1 ;
//printf("\n[>>>: cur:%s\n",cur);
if(js->type.object.value->code_type == jstype_string)
for(; is_js_space(*cur) || *cur=='"' || *cur=='}' || *cur == ']'; ++cur);
else
for(; is_js_space(*cur) || *cur=='}' || *cur == ']'; ++cur);
}
return js_parent;
}
void create_copy_js_iterator(struct js_iterator **_dstit, struct js_iterator *srcit){
if(*_dstit == NULL){
*_dstit = malloc(sizeof(struct js_iterator));
}
struct js_iterator * dstit = *_dstit;
dstit->size = srcit->size;
// dstit->next_ = srcit->next_;
// dstit->prev_ = srcit->prev_;
// dstit->set_index_ = srcit->set_index_;
// dstit->get_index_ = srcit->get_index_;
dstit->begin = srcit->begin;
dstit->end = srcit->end;
dstit->current = srcit->current;
}
void setup_js_iterator(struct js_iterator **_iter, struct js_value * js){
if(js->code_type == jstype_object || js->code_type == jstype_array ) {
if(*_iter == NULL){
*_iter = malloc(sizeof(struct js_iterator));
}
struct js_iterator *iter = *_iter ;
// iter->next_ = next_;
// iter->prev_ = prev_;
// iter->set_index_ = set_index_;
// iter->get_index_ = get_index_;
iter->begin = js;
struct js_value *tmpjs = js;
//struct js_value *tmpit = iter->begin;
//size_t index = 0;
while(tmpjs){
//iter->set_index_(tmpjs, index);
//++index;
iter->size = get_index_(tmpjs);
iter->end = tmpjs;
iter->current = tmpjs;
tmpjs = next_(tmpjs);
}
//return iter;
}
//return NULL;
}
long get_size_(struct js_value *js){
if(js->code_type < jstype_object) return -1;
if(js->code_type == jstype_object) return js->type.object.iter->size;
return js->type.array.iter->size;
}
long move_current_iter_to_index_(struct js_value *js, size_t index){
if(js->code_type < jstype_object) return -1;
if(js->code_type == jstype_object){
struct js_iterator *iter = js->type.object.iter;
if(index == js->type.object.index) return index;
long size = iter->size;
if(index >= size ){
iter->current = iter->end;
return size - 1;
}
long from_current_index = iter->current->type.object.index - index;
size_t abs_cur_diff = abs(from_current_index);
size_t array_diff_index[3] = {index, abs_cur_diff , size - 1 - index};
size_t index_nearest = ARG_MIN_ARRAY_TYPE_SIZE_T(array_diff_index, 3);
if(index_nearest == 0){
iter->current = iter->begin;
for(size_t i=0; i<array_diff_index[0]; ++i) iter->current = iter->current->type.object.next_object;//next_(iter->current);
}
else if(index_nearest == 2){
iter->current = iter->end;
for(size_t i=0; i < array_diff_index[2]; ++i) iter->current = iter->current->type.object.prev_object;//prev_(iter->current);
}else if(from_current_index >= 0)
for(size_t i=0; i < array_diff_index[1]; ++i) iter->current = iter->current->type.object.prev_object;//prev_(iter->current); prev_(iter->current);
else
for(size_t i=0; i < array_diff_index[1]; ++i) iter->current = iter->current->type.object.next_object;//next_(iter->current); next_(iter->current);
return index;
}else{
struct js_iterator *iter = js->type.array.iter;
if(index == js->type.array.index) return index;
long size = iter->size;
if(index >= size ){
iter->current = iter->end;
return size - 1;
}
long from_current_index = iter->current->type.array.index - index;
size_t abs_cur_diff = abs(from_current_index);
size_t array_diff_index[3] = {index, abs_cur_diff , size - 1 - index};
size_t index_nearest = ARG_MIN_ARRAY_TYPE_SIZE_T(array_diff_index, 3);
if(index_nearest == 0){
iter->current = iter->begin;
for(size_t i=0; i<array_diff_index[0]; ++i) iter->current = iter->current->type.array.next_element;//next_(iter->current);
}
else if(index_nearest == 2){
iter->current = iter->end;
for(size_t i=0; i < array_diff_index[2]; ++i) iter->current = iter->current->type.array.prev_element;//prev_(iter->current);
}else if(from_current_index >= 0)
for(size_t i=0; i < array_diff_index[1]; ++i) iter->current = iter->current->type.array.prev_element;//prev_(iter->current); prev_(iter->current);
else
for(size_t i=0; i < array_diff_index[1]; ++i) iter->current = iter->current->type.array.next_element;//next_(iter->current); next_(iter->current);
return index;
}
#if 0
struct js_iterator *iter = get_iterator_(js);
if(index == get_index_(iter->current)) return index;
//if(js->begin_list == NULL) return 0;
long size = get_size_(js);
if(index >= size){
iter->current = iter->end;
//js->current_index = js->size - 1;
return size - 1;
}
long from_current_index = get_index_(iter->current) - index;
size_t abs_cur_diff = abs(from_current_index);
size_t array_diff_index[3] = {index, abs_cur_diff , size - 1 - index};
size_t index_nearest = ARG_MIN_ARRAY_TYPE_SIZE_T(array_diff_index, 3);
if(index_nearest == 0){
iter->current = iter->begin;
for(size_t i=0; i<array_diff_index[0]; ++i) iter->current = next_(iter->current);
}
else if(index_nearest == 2){
iter->current = iter->end;
for(size_t i=0; i < array_diff_index[2]; ++i) iter->current = prev_(iter->current);
}else if(from_current_index >= 0)
for(size_t i=0; i < array_diff_index[1]; ++i) iter->current = prev_(iter->current);
else
for(size_t i=0; i < array_diff_index[1]; ++i) iter->current = next_(iter->current);
return index;
#endif
}
struct js_value * get_js_value_of_index_(size_t index, struct js_value *js){
if(move_current_iter_to_index_(js, index) >=0)
return get_iterator_(js)->current;
return NULL;
}
void set_next_(struct js_value * dstjs, struct js_value * jsnxt){
if(dstjs->code_type == jstype_object){
struct js_value *tmpjs = dstjs->type.object.next_object;
struct js_iterator *iter = dstjs->type.object.iter;
size_t last_index = dstjs->type.object.index;
if(jsnxt->code_type == jstype_object){
dstjs->type.object.next_object = jsnxt;
struct js_iterator *it_er = jsnxt->type.object.iter;
jsnxt->type.object.prev_object = dstjs;
while(jsnxt){
jsnxt->type.object.iter = iter;
jsnxt->type.object.index = ++last_index;
jsnxt = jsnxt->type.object.next_object;
}
if(tmpjs == NULL && it_er){
iter->end = it_er->end;
}else{
while(tmpjs){
tmpjs->type.object.index = ++last_index;
tmpjs = tmpjs->type.object.next_object;
}
}
iter->size = last_index + 1;
if(it_er){
free(it_er);
}
}
}
else if(dstjs->code_type == jstype_array){
struct js_value *tmpjs = dstjs->type.array.next_element;
struct js_iterator *iter = dstjs->type.array.iter;
size_t last_index = dstjs->type.array.index;
if(jsnxt->code_type == jstype_array){
dstjs->type.array.next_element = jsnxt;
struct js_iterator *it_er = jsnxt->type.array.iter;
jsnxt->type.array.prev_element= dstjs;
while(jsnxt){
jsnxt->type.array.iter = iter;
jsnxt->type.array.index = ++last_index;
jsnxt = jsnxt->type.array.next_element;
}
if(tmpjs == NULL && it_er){
iter->end = it_er->end;
}else{
while(tmpjs){
tmpjs->type.array.index = ++last_index;
tmpjs = tmpjs->type.array.next_element;
}
}
iter->size = last_index + 1;
if(it_er){
free(it_er);
}
}
}
}
void set_prev_(struct js_value ** _dst, struct js_value * jsprv){
struct js_value *dst = *_dst;
if(dst->code_type == jstype_object){
struct js_value *tmpjs = dst->type.object.prev_object;//, *ttmpjs;
//ttmpjs = dst;
//while(prev_(ttmpjs)) ttmpjs = prev_(ttmpjs);
//struct js_iterator *iter = ttmpjs->type.object.iter;
struct js_iterator *iter = dst->type.object.iter;
jsprv->type.object.iter = iter;
dst->type.object.prev_object = jsprv;
jsprv->type.object.prev_object = tmpjs;
jsprv->type.object.index = dst->type.object.index;
jsprv->type.object.prev_object = tmpjs;
size_t last_index = dst->type.object.index;
struct js_value *ttmp = jsprv;
while(next_(ttmp)){
ttmp->type.object.index = (++last_index);
ttmp = next_(ttmp);
if(iter) ++(iter->size);// = last_index + 1;
}
ttmp->type.object.next_object = dst;
if(tmpjs){
tmpjs->type.object.next_object = jsprv;
}else{// dst prev null (top)
*_dst = jsprv;
//(*_dst)->type.object.iter = iter; // malloc(sizeof(struct js_iterator));
//(*_dst)->type.object.iter->begin = jsprv;
if(iter){
iter->begin = jsprv;
// (*_dst)->type.object.iter->end = iter->end;
// (*_dst)->type.object.iter->current = iter->current;
// (*_dst)->type.object.iter->size = iter->size; // + (last_index + 1 - dst->type.object.index);
}
//iter = (*_dst)->type.object.iter;
}
tmpjs = dst;
while(tmpjs){
tmpjs->type.object.index = (++last_index);
tmpjs = next_(tmpjs);
//if(iter) {
// iter->size = last_index + 1;
// iter->end = tmpjs;
//}
}
}else if(dst->code_type == jstype_array){
struct js_value *tmpjs = dst->type.array.prev_element;//, *ttmpjs;
//ttmpjs = dst;
//while(prev_(ttmpjs)) ttmpjs = prev_(ttmpjs);
//struct js_iterator *iter = ttmpjs->type.array.iter;
struct js_iterator *iter = dst->type.array.iter;
jsprv->type.array.iter = iter;
dst->type.array.prev_element = jsprv;
jsprv->type.array.prev_element = tmpjs;
jsprv->type.array.index = dst->type.array.index;
jsprv->type.array.prev_element = tmpjs;
size_t last_index = dst->type.array.index;
struct js_value *ttmp = jsprv;
while(next_(ttmp)){
ttmp->type.array.index = (++last_index);
ttmp = next_(ttmp);
if(iter) ++(iter->size);// = last_index + 1;
}
ttmp->type.array.next_element = dst;
if(tmpjs){
tmpjs->type.array.next_element = jsprv;
}else{// dst prev null (top)
*_dst = jsprv;
//(*_dst)->type.array.iter = malloc(sizeof(struct js_iterator));
//(*_dst)->type.array.iter->begin = jsprv;
if(iter){
iter->begin = jsprv;
//(*_dst)->type.array.iter->end = iter->end;
//(*_dst)->type.array.iter->current = iter->current;
//(*_dst)->type.array.iter->size = iter->size; // + (last_index + 1 - dst->type.array.index);
}
//iter = (*_dst)->type.array.iter;
}
tmpjs = dst;
while(tmpjs){
++(tmpjs->type.array.index);
tmpjs = next_(tmpjs);
}
}
}
void add_js_value_index(size_t index, struct js_value *js_to_add, struct js_value **js_org){
if((*js_org)->code_type >= jstype_object && (*js_org)->code_type == js_to_add->code_type ){
struct js_value /**tmpjs = *js_org,*/ *ttmp=NULL;
/*while(tmpjs){// TO DO : use iter to optimize
if(get_index_(tmpjs) == index){
// printf("broken, index:%ld\n",index);
break;
}
ttmp = tmpjs;
tmpjs = next_(tmpjs);
}*/
ttmp = get_js_value_of_index_(index, *js_org);
if(ttmp != *js_org){
// printf("not NULL\n");
set_next_(ttmp,js_to_add);
}else{
set_prev_(js_org, js_to_add);
}
}
}
void delete_index_js_value(size_t index, struct js_value **js_org){
if((*js_org) && ( (*js_org)->code_type >= jstype_object) ){
struct js_value *ttmp=NULL;
ttmp = get_js_value_of_index_(index, *js_org);
if(ttmp && ((*js_org)->code_type == jstype_object)){
struct js_iterator *iter = (*js_org)->type.object.iter;
struct js_value *prevJS = ttmp->type.object.prev_object;
struct js_value *nextJS = ttmp->type.object.next_object;
if(prevJS){
prevJS->type.object.next_object = nextJS;
}else{
iter->begin = nextJS;
}
if(iter->current == ttmp){
iter->current = (nextJS ? nextJS : prevJS) ;
}
if(nextJS){
nextJS->type.object.prev_object = prevJS;
}else{
iter->end = prevJS;
}
if(ttmp == *js_org){
*js_org = nextJS;
iter->begin = nextJS;
}
while(nextJS){
--(nextJS->type.object.index);
nextJS = nextJS->type.object.next_object;
}
--(iter->size);
ttmp->type.object.next_object = NULL;
ttmp->type.object.prev_object = NULL;
if(*js_org){
ttmp->type.object.iter = NULL;
}
free_js_value(ttmp);
}else{
struct js_iterator *iter = (*js_org)->type.array.iter;
struct js_value *prevJS = ttmp->type.array.prev_element;
struct js_value *nextJS = ttmp->type.array.next_element;
if(prevJS){
prevJS->type.array.next_element = nextJS;
}else{
iter->begin = nextJS;
}
if(iter->current == ttmp){
iter->current = (nextJS ? nextJS : prevJS) ;
}
if(nextJS){
nextJS->type.array.prev_element = prevJS;
}else{
iter->end = prevJS;
}
if(ttmp == *js_org){
*js_org = nextJS;
iter->begin = nextJS;
}
while(nextJS){
--(nextJS->type.array.index);
nextJS = nextJS->type.array.next_element;
}
--(iter->size);
ttmp->type.array.next_element = NULL;
ttmp->type.array.prev_element = NULL;
if(*js_org)
ttmp->type.array.iter = NULL;
free_js_value(ttmp);
}
}
}
struct js_iterator * get_iterator_(struct js_value *js){
if(js->code_type == jstype_object) return js->type.object.iter;
if(js->code_type == jstype_array) return js->type.array.iter;
return NULL;
}
void set_iterator_(struct js_value *js, struct js_iterator *iter){
if(js->code_type == jstype_object) js->type.object.iter = iter;
if(js->code_type == jstype_array) js->type.array.iter = iter;
}
void append_js_value(struct js_value *dst, char *input){/* if object type: input = { "key" : value }, if key already exists value replace the old value! */
if(dst){
if(dst->code_type < jstype_object || get_iterator_(dst) == NULL) return;
struct js_value *newval = create_js_value(input, dst->parent);
if(newval->code_type != dst->code_type) {
free_js_value(newval);
return;
}
struct js_iterator *iter = get_iterator_(dst);
set_next_(iter->end, newval);
}
}
char * original_string_js_value(struct js_value *js){
char *ret = malloc(js->length+1);
strncpy(ret,js->str_value,js->length);
ret[js->length] = '\0';
return ret;
}
//lret=strlen(buf);
#define UPDATE_RET_N_PUSH_Y_STRING(local_size, global_size, m_str, y_string_b_uf, buf)\
(y_string_b_uf) = create_y_ptr_STRING((buf), (local_size));\
(global_size) += (local_size);\
push_back_list_y_ptr_STRING((m_str), (y_string_b_uf));\
// printf("debug:global_size=%ld, local_size=%ld, buf=%s / / %d / /\n",(global_size),(local_size),(buf), js->code_type);
/* tab_depth = number of tabulationfor values, */
long int sprint_js_value_to_y_string_list(struct main_list_y_ptr_STRING *m_str, struct js_value *js, char sep, int tab_depth){
long int global_size = 0, local_size;
//char *buf = malloc(js->length);
//printf("debug: js->length = %ld\n",js->length);
char buf[500]; memset(buf,0,500);
y_ptr_STRING y_string_b_uf;
if(js->code_type == jstype_number){
//memset(buf,0,499);
local_size = sprintf(buf,"%Lf",js->type.number);
UPDATE_RET_N_PUSH_Y_STRING(local_size, global_size, m_str, y_string_b_uf, buf)
}else if(js->code_type == jstype_string){
//memset(buf,0,499);
local_size = sprintf(buf,"\"%s\"",js->type.string);
UPDATE_RET_N_PUSH_Y_STRING(local_size, global_size, m_str, y_string_b_uf, buf)
}else if(js->code_type == jstype_bool){
//memset(buf,0,499);
local_size = sprintf(buf,"%s",js->type.boolean ? "true" : "false");
UPDATE_RET_N_PUSH_Y_STRING(local_size, global_size, m_str, y_string_b_uf, buf)
}else if(js->code_type == jstype_null){
//memset(buf,0,499);
local_size = sprintf(buf,"%s","null");
UPDATE_RET_N_PUSH_Y_STRING(local_size, global_size, m_str, y_string_b_uf, buf)
}else if(js->code_type == jstype_object){
struct js_value *tmpjs = js;
while(tmpjs){
if(tmpjs->type.object.prev_object == NULL){
local_size = sprintf(buf,"%c%*c{ ",sep,tab_depth*(tmpjs->type.object.depth),' ');
UPDATE_RET_N_PUSH_Y_STRING(local_size, global_size, m_str, y_string_b_uf, buf)
}
local_size = sprintf(buf,"%c%*c\"%s\" : ",sep, tab_depth*(tmpjs->type.object.depth),' ', tmpjs->type.object.key);
UPDATE_RET_N_PUSH_Y_STRING(local_size, global_size, m_str, y_string_b_uf, buf)
global_size += sprint_js_value_to_y_string_list(m_str, tmpjs->type.object.value, sep, tab_depth );
if(tmpjs->type.object.next_object == NULL){
local_size = sprintf(buf,"%c%*c} ",sep,tab_depth*(tmpjs->type.object.depth),' '); //printf(" }");
UPDATE_RET_N_PUSH_Y_STRING(local_size, global_size, m_str, y_string_b_uf, buf)
}else{
//memset(buf,0,499);
local_size = sprintf(buf,", ");
UPDATE_RET_N_PUSH_Y_STRING(local_size, global_size, m_str, y_string_b_uf, buf)
}
//printf("\n");
tmpjs = tmpjs->type.object.next_object;
}
}else if(js->code_type == jstype_array){
struct js_value *tmpjs = js;
while(tmpjs){
if(tmpjs->type.array.prev_element == NULL){
//memset(buf,0,499);
local_size = sprintf(buf, "%c%*c[ ",sep,tab_depth*(tmpjs->type.array.depth),' ');
UPDATE_RET_N_PUSH_Y_STRING(local_size, global_size, m_str, y_string_b_uf, buf)
}
if(tmpjs->type.array.value->code_type < jstype_object ) {
//memset(buf,0,499);
local_size = sprintf(buf,"%c%*c ",sep,tab_depth*(tmpjs->type.array.depth),' ');
UPDATE_RET_N_PUSH_Y_STRING(local_size, global_size, m_str, y_string_b_uf, buf)
}
global_size += sprint_js_value_to_y_string_list(m_str,tmpjs->type.array.value,sep,tab_depth);
if(tmpjs->type.array.next_element == NULL){ //printf(" ]");
//memset(buf,0,499);
local_size = sprintf(buf,"%c%*c] ",sep,tab_depth*(tmpjs->type.array.depth),' ');
UPDATE_RET_N_PUSH_Y_STRING(local_size, global_size, m_str, y_string_b_uf, buf)
}else{
//memset(buf,0,499);
local_size = sprintf(buf,", ");
UPDATE_RET_N_PUSH_Y_STRING(local_size, global_size, m_str, y_string_b_uf, buf)
}
tmpjs = tmpjs->type.array.next_element; // next_(tmpjs);
}
}
//free(buf);
return global_size;
}
/* dstString can be NULL ! (it's better)*/
long int sprint_js_value(char **dstString, struct js_value *js, char sep, int tab_depth){
struct main_list_y_ptr_STRING *m_str=create_var_list_y_ptr_STRING();
// remove_all_ptr_type_list_y_ptr_STRING(m_str);
long int ret = sprint_js_value_to_y_string_list(m_str,js,sep, tab_depth);
copy_list_y_ptr_STRING_to_one_string(dstString , m_str);
//printf("debug:%s\n",*dstString);
purge_ptr_type_list_y_ptr_STRING(m_str);
return ret;
}
/* dstString can be NULL ! (it's better)*/
long int sprint_one_line_js_value(char **dstString, struct js_value *js){
struct main_list_y_ptr_STRING *m_str=create_var_list_y_ptr_STRING();
// remove_all_ptr_type_list_y_ptr_STRING(m_str);
long int ret = sprint_js_value_to_y_string_list(m_str,js,' ', 1);
copy_list_y_ptr_STRING_to_one_string(dstString , m_str);
//printf("debug:%s\n",*dstString);
purge_ptr_type_list_y_ptr_STRING(m_str);
return ret;
}
void print_js_value(struct js_value *js){
if(js->code_type == jstype_number){
printf("%Lf",js->type.number);
}else if(js->code_type == jstype_string){
printf("\"%s\"",js->type.string);
}else if(js->code_type == jstype_bool){
printf("%s",js->type.boolean ? "true" : "false");
}else if(js->code_type == jstype_null){
printf("%s","null");
}else if(js->code_type == jstype_object){
struct js_value *tmpjs = js;
while(tmpjs){
if(tmpjs->type.object.prev_object == NULL){
printf("\n%*c{ ",4*(tmpjs->type.object.depth),' ');
}
/*
char key[tmpjs->type.object.key_length + 1];
strncpy(key, tmpjs->type.object.key, tmpjs->type.object.key_length);
key[tmpjs->type.object.key_length]='\0';
printf("\n%*c%s : ", 4*(tmpjs->type.object.depth),' ', key );
*/
printf("\n%*c\"%s\" : ", 4*(tmpjs->type.object.depth),' ', tmpjs->type.object.key);
print_js_value(tmpjs->type.object.value);
if(tmpjs->type.object.next_object == NULL)
printf("\n%*c} ",4*(tmpjs->type.object.depth),' '); //printf(" }");
else printf(", ");
//printf("\n");
tmpjs = tmpjs->type.object.next_object;
}
}else if(js->code_type == jstype_array){
struct js_value *tmpjs = js;
while(tmpjs){
if(tmpjs->type.array.prev_element == NULL){
printf("\n%*c[ ",4*(tmpjs->type.array.depth),' ');
}
if(tmpjs->type.array.value->code_type < jstype_object )
printf("\n%*c ",4*(tmpjs->type.array.depth),' ');
print_js_value(tmpjs->type.array.value);
if(tmpjs->type.array.next_element == NULL) //printf(" ]");
printf("\n%*c] ",4*(tmpjs->type.array.depth),' ');
else printf(", ");
tmpjs = tmpjs->type.array.next_element; // next_(tmpjs);
}
}
}
struct js_value * value_of_(struct js_value * js){
if(js->code_type == jstype_object){
return js->type.object.value;
}
if(js->code_type == jstype_array){
return js->type.array.value;
}
return NULL;
}
struct js_value *get_js_value_of_key(char * key, struct js_value *js ){
if(js->code_type == jstype_object){
struct js_value *tmp = js;
while(tmp){
if(strncmp(key,tmp->type.object.key, tmp->type.object.key_length) == 0){
js->type.object.iter->current = tmp;
return tmp; //tmp->type.object.value == value_of_(tmp);
}
tmp = tmp->type.object.next_object;//next_(tmp);
}
}
return NULL;
}
void delete_key_js_value(char * key, struct js_value **js_org){
struct js_value *js = get_js_value_of_key(key, *js_org);
if(js){
delete_index_js_value(js->type.object.index, js_org);
}
}
size_t js_org_str_length(struct js_value *js){
// if string add 2 \" values
return js->length+1+2*(js->code_type == 0);
}
/*
void set_value_of_key(char *key, char * value, struct js_value *js ){
if(js->code_type != jstype_object)
return;
struct js_value *valjs = get_js_value_of_key(key, js);
if(valjs){
struct js_value *tmp = valjs->type.object.value;
valjs->type.object.value = create_js_value(value, valjs);
free_js_value(tmp);
}else{
js->type.object.
}
}
*/