/* Invoke user callback as cb(data, undefined) */ static void http_disconnect_cb(void *arg) { struct espconn *conn = (struct espconn *) arg; struct http_ctx *ctx = (struct http_ctx *) conn->proto.tcp; v7_val_t data, cb_args; char *body; int i; v7_val_t res; body = ctx->resp; for (i = 0; i + 3 < ctx->resp_pos; i++) { if (memcmp(ctx->resp + i, "\r\n\r\n", 4) == 0) { body = ctx->resp + i + 4; break; } } cb_args = v7_create_object(v7); v7_own(v7, &cb_args); data = v7_create_string(v7, body, ctx->resp_pos - (body - ctx->resp), 1); v7_own(v7, &data); http_free(conn); v7_array_set(v7, cb_args, 0, ctx->cb); v7_array_set(v7, cb_args, 1, data); v7_disown(v7, &data); if (v7_exec_with(v7, &res, "this[0](this[1])", cb_args) != V7_OK) { v7_fprintln(stderr, v7, res); } v7_disown(v7, &cb_args); v7_disown(v7, &ctx->cb); }
V7_PRIVATE void init_regex(struct v7 *v7) { val_t ctor = v7_create_cfunction_ctor(v7, v7->regexp_prototype, Regex_ctor, 1); val_t lastIndex = v7_create_dense_array(v7); v7_set_property(v7, v7->global_object, "RegExp", 6, V7_PROPERTY_DONT_ENUM, ctor); set_cfunc_prop(v7, v7->regexp_prototype, "exec", Regex_exec); set_cfunc_prop(v7, v7->regexp_prototype, "test", Regex_test); v7_set_property(v7, v7->regexp_prototype, "global", 6, V7_PROPERTY_GETTER, v7_create_cfunction(Regex_global)); v7_set_property(v7, v7->regexp_prototype, "ignoreCase", 10, V7_PROPERTY_GETTER, v7_create_cfunction(Regex_ignoreCase)); v7_set_property(v7, v7->regexp_prototype, "multiline", 9, V7_PROPERTY_GETTER, v7_create_cfunction(Regex_multiline)); v7_set_property(v7, v7->regexp_prototype, "source", 6, V7_PROPERTY_GETTER, v7_create_cfunction(Regex_source)); v7_array_set(v7, lastIndex, 0, v7_create_cfunction(Regex_get_lastIndex)); v7_array_set(v7, lastIndex, 1, v7_create_cfunction(Regex_set_lastIndex)); v7_set_property(v7, v7->regexp_prototype, "lastIndex", 9, V7_PROPERTY_GETTER | V7_PROPERTY_SETTER, lastIndex); }
/* * If resolved successfuly it will connect. Otherwise invokes * user callback as cb(undefined, error_message) */ static void http_get_dns_cb(const char *name, ip_addr_t *ipaddr, void *arg) { /* WIP: for now return the dns address as if it were the `get` response */ struct espconn *conn = (struct espconn *) arg; struct http_ctx *ctx = (struct http_ctx *) conn->proto.tcp; static char err_msg[] = "cannot resolve"; if (ipaddr == NULL) { v7_val_t res, cb_args = v7_create_object(v7); v7_own(v7, &cb_args); v7_array_set(v7, cb_args, 0, ctx->cb); v7_array_set(v7, cb_args, 1, v7_create_string(v7, err_msg, sizeof(err_msg), 1)); http_free(conn); if (v7_exec_with(v7, &res, "this[0](undefined, this[1])", cb_args) != V7_OK) { v7_fprintln(stderr, v7, res); } v7_disown(v7, &cb_args); v7_disown(v7, &ctx->body); /* body has not been sent yet */ v7_disown(v7, &ctx->cb); } else { memcpy(conn->proto.tcp->remote_ip, &ipaddr->addr, 4); conn->proto.tcp->remote_port = ctx->port; conn->proto.tcp->local_port = espconn_port(); espconn_regist_connectcb(conn, http_connect_cb); espconn_regist_disconcb(conn, http_disconnect_cb); espconn_regist_reconcb(conn, http_error_cb); espconn_connect(conn); } }
void sj_http_error_callback(struct v7 *v7, v7_val_t cb, int err_no) { char err_msg[128]; v7_val_t res, cb_args; cb_args = v7_create_object(v7); v7_own(v7, &cb_args); snprintf(err_msg, sizeof(err_msg), "connection error: %d\n", err_no); v7_array_set(v7, cb_args, 0, cb); v7_array_set(v7, cb_args, 1, v7_create_string(v7, err_msg, sizeof(err_msg), 1)); if (v7_exec_with(v7, &res, "this[0](undefined, this[1])", cb_args) != V7_OK) { v7_fprintln(stderr, v7, res); } v7_disown(v7, &cb_args); }
/* Invoke user callback as cb(undefined, err_msg) */ static void http_error_cb(void *arg, int8_t err) { struct espconn *conn = (struct espconn *) arg; struct http_ctx *ctx = (struct http_ctx *) conn->proto.tcp; char err_msg[128]; v7_val_t res, cb_args; cb_args = v7_create_object(v7); v7_own(v7, &cb_args); snprintf(err_msg, sizeof(err_msg), "connection error: %d\n", err); v7_array_set(v7, cb_args, 0, ctx->cb); v7_array_set(v7, cb_args, 1, v7_create_string(v7, err_msg, sizeof(err_msg), 1)); http_free(conn); if (v7_exec_with(v7, &res, "this[0](undefined, this[1])", cb_args) != V7_OK) { v7_fprintln(stderr, v7, res); } v7_disown(v7, &cb_args); }
static void invoke_cb(struct user_data *ud, const char *name, v7_val_t ev) { struct v7 *v7 = ud->v7; v7_val_t met = v7_get(v7, ud->ws, name, ~0); if (!v7_is_undefined(met)) { v7_val_t res, args = v7_create_array(v7); v7_array_set(v7, args, 0, ev); if (v7_apply(v7, &res, met, v7_create_undefined(), args) != V7_OK) { /* TODO(mkm): make it print stack trace */ fprintf(stderr, "cb threw an exception\n"); } } }
void sj_http_success_callback(struct v7 *v7, v7_val_t cb, const char *data, size_t data_len) { v7_val_t datav, cb_args; v7_val_t res; cb_args = v7_create_object(v7); v7_own(v7, &cb_args); datav = v7_create_string(v7, data, data_len, 1); v7_own(v7, &datav); v7_array_set(v7, cb_args, 0, cb); v7_array_set(v7, cb_args, 1, datav); v7_disown(v7, &datav); if (v7_exec_with(v7, &res, "this[0](this[1])", cb_args) != V7_OK) { v7_fprintln(stderr, v7, res); } v7_disown(v7, &cb_args); v7_disown(v7, &cb); }
/* Callback for json_walk() */ static void frozen_cb(void *data, const char *name, size_t name_len, const char *path, const struct json_token *token) { struct json_parse_ctx *ctx = (struct json_parse_ctx *) data; v7_val_t v = V7_UNDEFINED; (void) path; v7_own(ctx->v7, &v); switch (token->type) { case JSON_TYPE_STRING: v = v7_mk_string(ctx->v7, token->ptr, token->len, 1 /* copy */); break; case JSON_TYPE_NUMBER: v = v7_mk_number(ctx->v7, cs_strtod(token->ptr, NULL)); break; case JSON_TYPE_TRUE: v = v7_mk_boolean(ctx->v7, 1); break; case JSON_TYPE_FALSE: v = v7_mk_boolean(ctx->v7, 0); break; case JSON_TYPE_NULL: v = V7_NULL; break; case JSON_TYPE_OBJECT_START: v = v7_mk_object(ctx->v7); break; case JSON_TYPE_ARRAY_START: v = v7_mk_array(ctx->v7); break; case JSON_TYPE_OBJECT_END: case JSON_TYPE_ARRAY_END: { /* Object or array has finished: deallocate its frame */ ctx->frame = free_json_frame(ctx, ctx->frame); } break; default: LOG(LL_ERROR, ("Wrong token type %d\n", token->type)); break; } if (!v7_is_undefined(v)) { if (name != NULL && name_len != 0) { /* Need to define a property on the current object/array */ if (v7_is_object(ctx->frame->val)) { v7_set(ctx->v7, ctx->frame->val, name, name_len, v); } else if (v7_is_array(ctx->v7, ctx->frame->val)) { /* * TODO(dfrank): consult name_len. Currently it's not a problem due to * the implementation details of frozen, but it might change */ int idx = (int) cs_strtod(name, NULL); v7_array_set(ctx->v7, ctx->frame->val, idx, v); } else { LOG(LL_ERROR, ("Current value is neither object nor array\n")); } } else { /* This is a root value */ assert(ctx->frame == NULL); /* * This value will also be the overall result of JSON parsing * (it's already owned by the `v7_alt_json_parse()`) */ ctx->result = v; } if (token->type == JSON_TYPE_OBJECT_START || token->type == JSON_TYPE_ARRAY_START) { /* New object or array has just started, so we need to allocate a frame * for it */ struct json_parse_frame *new_frame = alloc_json_frame(ctx, v); new_frame->up = ctx->frame; ctx->frame = new_frame; } } v7_disown(ctx->v7, &v); }