int json_decode (ssr_t *json, json_t *json_array, int json_arr_size) { char *s; size_t n; int j; int rc; s = json->data; n = json->size; j = 0; json_array[j].next = NULL; json_array[j].name.size = 0; json_array[j].name.data = NULL; rc = json_skip_whites(&s, &n); if (rc == -1) {return (-1);} if (*s != '{') { printf("Got '%c', expected '{'\n", *s); return (-1); } rc = json_decode_object(&s, &n, &j, &json_array[0], json_array, json_arr_size); if (rc == -1) {return (-1);} return (j + 1); }
static void hangouts_oauth_with_code_cb(PurpleHttpConnection *http_conn, PurpleHttpResponse *response, gpointer user_data) { HangoutsAccount *ha = user_data; JsonObject *obj; const gchar *raw_response; gsize response_len; PurpleAccount *account = ha->account; raw_response = purple_http_response_get_data(response, &response_len); obj = json_decode_object(raw_response, response_len); if (purple_http_response_is_successful(response) && obj) { ha->access_token = g_strdup(json_object_get_string_member(obj, "access_token")); ha->refresh_token = g_strdup(json_object_get_string_member(obj, "refresh_token")); purple_account_set_remember_password(account, TRUE); hangouts_save_refresh_token_password(account, ha->refresh_token); hangouts_auth_get_session_cookies(ha); } else { if (obj != NULL) { if (json_object_has_member(obj, "error")) { if (g_strcmp0(json_object_get_string_member(obj, "error"), "invalid_grant") == 0) { hangouts_save_refresh_token_password(ha->account, NULL); purple_connection_error(ha->pc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, json_object_get_string_member(obj, "error_description")); } else { purple_connection_error(ha->pc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, json_object_get_string_member(obj, "error_description")); } } else { purple_connection_error(ha->pc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Invalid response")); } } purple_connection_error(ha->pc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Invalid response")); } json_object_unref(obj); }
/* * Decode one item and put it in "res". If "res" is NULL only advance. * Must already have skipped white space. * * Return FAIL for a decoding error. * Return MAYBE for an incomplete message. */ static int json_decode_item(js_read_T *reader, typval_T *res, int options) { char_u *p; int len; fill_numbuflen(reader); p = reader->js_buf + reader->js_used; switch (*p) { case '[': /* array */ return json_decode_array(reader, res, options); case '{': /* object */ return json_decode_object(reader, res, options); case '"': /* string */ return json_decode_string(reader, res); case ',': /* comma: empty item */ if ((options & JSON_JS) == 0) return FAIL; /* FALLTHROUGH */ case NUL: /* empty */ if (res != NULL) { res->v_type = VAR_SPECIAL; res->vval.v_number = VVAL_NONE; } return OK; default: if (VIM_ISDIGIT(*p) || *p == '-') { char_u *sp = p; #ifdef FEAT_FLOAT if (*sp == '-') { ++sp; if (*sp == NUL) return MAYBE; if (!VIM_ISDIGIT(*sp)) return FAIL; } sp = skipdigits(sp); if (*sp == '.' || *sp == 'e' || *sp == 'E') { if (res == NULL) { float_T f; len = string2float(p, &f); } else { res->v_type = VAR_FLOAT; len = string2float(p, &res->vval.v_float); } } else #endif { long nr; vim_str2nr(reader->js_buf + reader->js_used, NULL, &len, 0, /* what */ &nr, NULL, 0); if (res != NULL) { res->v_type = VAR_NUMBER; res->vval.v_number = nr; } } reader->js_used += len; return OK; } if (STRNICMP((char *)p, "false", 5) == 0) { reader->js_used += 5; if (res != NULL) { res->v_type = VAR_SPECIAL; res->vval.v_number = VVAL_FALSE; } return OK; } if (STRNICMP((char *)p, "true", 4) == 0) { reader->js_used += 4; if (res != NULL) { res->v_type = VAR_SPECIAL; res->vval.v_number = VVAL_TRUE; } return OK; } if (STRNICMP((char *)p, "null", 4) == 0) { reader->js_used += 4; if (res != NULL) { res->v_type = VAR_SPECIAL; res->vval.v_number = VVAL_NULL; } return OK; } /* check for truncated name */ len = (int)(reader->js_end - (reader->js_buf + reader->js_used)); if ((len < 5 && STRNICMP((char *)p, "false", len) == 0) || (len < 4 && (STRNICMP((char *)p, "true", len) == 0 || STRNICMP((char *)p, "null", len) == 0))) return MAYBE; break; } if (res != NUL) { res->v_type = VAR_SPECIAL; res->vval.v_number = VVAL_NONE; } return FAIL; }
int json_decode_object (char **s, size_t *n, int *j, json_t *par, json_t *json_array, int json_arr_size) { int rc; json_t *obj; if (**s != '{') {return (-1);} (*s)++; (*n)--; if (!*n) {return (-1);} rc = json_skip_whites(s,n); if ((**s) == '}') { par->value.object = NULL; return (0); } (*j)++; obj = &json_array[*j]; par->value.object = obj; while (1) { obj->next = NULL; rc = json_skip_whites(s, n); if (rc == -1) {return (-1);} if ((**s) != '"') {return (-1);} rc = json_read_string(s, n, &obj->name); if (rc == -1) {return (-1);} (*s)++; (*n)--; if (!*n) {return (-1);} rc = json_skip_whites(s, n); if (rc == -1) {return (-1);} if (**s != ':') {return (-1);} (*s)++; (*n)--; if (!*n) {return (-1);} rc = json_skip_whites(s, n); if (rc == -1) {return (-1);} if (**s == '"') { rc = json_read_string(s, n, &obj->value.string); if (rc == -1) {return (-1);} (*s)++; (*n)--; if (!*n) {return (-1);} obj->type = JSON_STRING; } else if (**s == '{') { rc = json_decode_object(s, n, j, obj, json_array, json_arr_size); if (rc == -1) {return (-1);} (*s)++; (*n)--; if (!*n) {return (-1);} obj->type = JSON_OBJECT; } else {return (-1);} rc = json_skip_whites(s, n); if (rc == -1) {return (-1);} if (**s == '}') { return (0); } if (**s != ',') {;return (-1);} (*s)++; (*n)--; if (!*n) {return (-1);} (*j)++; if (*j == json_arr_size) { return (-1); } obj->next = &json_array[*j]; obj = obj->next; } if (*j == json_arr_size) { return (-1); } }