size_t parse_watch_response (void *ptr, size_t size, size_t nmemb, void *stream) { yajl_val node; yajl_val value; etcd_watch_t *watch = stream; static const char *i_path[] = { "node", "modifiedIndex", NULL }; static const char *k_path[] = { "node", "key", NULL }; static const char *v_path[] = { "node", "value", NULL }; node = yajl_tree_parse(ptr,NULL,0); if (node) { value = my_yajl_tree_get(node,i_path,yajl_t_number); if (value) { watch->index_out = strtoul(YAJL_GET_NUMBER(value), NULL,10); } value = my_yajl_tree_get(node,k_path,yajl_t_string); if (value) { watch->key = strdup(MY_YAJL_GET_STRING(value)); } value = my_yajl_tree_get(node,v_path,yajl_t_string); if (value) { watch->value = strdup(MY_YAJL_GET_STRING(value)); } } return size*nmemb; }
yajl_gen_status GenVal(yajl_gen g, yajl_val v) { yajl_gen_status status; switch (v->type) { case yajl_t_string: return yajl_gen_string(g, (unsigned char*)v->u.string, strlen(v->u.string)); case yajl_t_number: { char buffer[100]; char *num = buffer; size_t len; //if (YAJL_IS_INTEGER(v)) // buggy if (v->u.number.flags & YAJL_NUMBER_INT_VALID) len = sprintf(num, "%lld", YAJL_GET_INTEGER(v)); //else if (YAJL_IS_DOUBLE(v)) // buggy else if (v->u.number.flags & YAJL_NUMBER_DOUBLE_VALID) len = sprintf(num, "%g", YAJL_GET_DOUBLE(v)); else { num = YAJL_GET_NUMBER(v); len = strlen(buffer); } return yajl_gen_number(g, num, len); } case yajl_t_object: status = yajl_gen_map_open(g); if (status != yajl_gen_status_ok) return status; for (size_t i = 0; i < v->u.object.len; i++) { status = yajl_gen_string(g, (unsigned char *)v->u.object.keys[i], strlen(v->u.object.keys[i])); if (status != yajl_gen_status_ok) return status; status = GenVal(g, v->u.object.values[i]); if (status != yajl_gen_status_ok) return status; } return yajl_gen_map_close(g); case yajl_t_array: status = yajl_gen_array_open(g); if (status != yajl_gen_status_ok) return status; for (size_t i = 0; i < v->u.array.len; i++) { status = GenVal(g, v->u.array.values[i]); if (status != yajl_gen_status_ok) return status; } return yajl_gen_array_close(g); case yajl_t_true: return yajl_gen_bool(g, 1); case yajl_t_false: return yajl_gen_bool(g, 0); case yajl_t_null: return yajl_gen_null(g); case yajl_t_any: break; } return yajl_gen_in_error_state; }