#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(">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; icurrent = 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; icurrent = 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; icurrent = 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. } } */