/* format a string into an ei_x_buff, except the version token */ static int eiformat(const char** fmt, union arg** args, ei_x_buff* x) { const char* p = *fmt; int res; ei_x_buff x2; while (isspace((int)*p)) ++p; switch (*p) { case '~': res = pformat(&p, args, x); break; case '[': res = ei_x_new(&x2); if (res >= 0) res = plist(&p, args, &x2, 0); if (res > 0) res = ei_x_encode_list_header(x, res); if (res >= 0) res = ei_x_append(x, &x2); ei_x_free(&x2); break; case '{': res = ei_x_new(&x2); if (res >= 0) res = ptuple(&p, args, &x2, 0); if (res >= 0) res = ei_x_encode_tuple_header(x, res); if (res >= 0) res = ei_x_append(x, &x2); ei_x_free(&x2); break; case '"': res = pstring(&p, x); break; case '\'': res = pquotedatom(&p, x); break; default: if (isdigit((int)*p)) res = pdigit(&p, x); else if ((*p == '-' || *p == '+') && isdigit((int)*(p+1))) res = pdigit(&p, x); else if (islower((int)*p)) res = patom(&p, x); else res = -1; break; /* Variables */ } *fmt = p; return res; }
static int current_tree_finished(struct exmpp_xml_ctx *ctx) { ei_x_buff *trees; trees = ctx->complete_trees; if (trees == NULL) { /* Allocate the complete trees list. */ trees = driver_alloc(sizeof(*trees)); if (trees == NULL) return (-1); ei_x_new_with_version(trees); ctx->complete_trees = trees; } /* Append the current tree to the complete trees list. */ ei_x_encode_list_header(trees, 1); ei_x_append(trees, ctx->current_tree); ctx->complete_trees_ready = 1; /* Reset the current tree. */ reset_current_tree(ctx); return (0); }
void *erlXML_StartElementHandler(expat_data *d, const XML_Char *name, const XML_Char **atts) { int i; ei_x_encode_list_header(&event_buf, 1); ei_x_encode_tuple_header(&event_buf, 2); ei_x_encode_long(&event_buf, XML_START); ei_x_encode_tuple_header(&event_buf, 2); encode_name(name); ei_x_append(&event_buf, &xmlns_buf); ei_x_free(&xmlns_buf); ei_x_new(&xmlns_buf); for (i = 0; atts[i]; i += 2) {} if (i > 0) { ei_x_encode_list_header(&event_buf, i/2); for (i = 0; atts[i]; i += 2) { ei_x_encode_tuple_header(&event_buf, 2); encode_name(atts[i]); ei_x_encode_binary(&event_buf, atts[i+1], strlen(atts[i+1])); } } ei_x_encode_empty_list(&event_buf); return NULL; }
int ei_x_encode_k(ei_x_buff* x, K r, QOpts* opts) { EI(ei_x_encode_tuple_header(x, 2)); ei_x_buff* types = x; ei_x_buff values; EI(ei_x_new(&values)); EIC(ei_x_encode_k_tv(types, &values, r, opts), ei_x_free(&values)); // cleanup expression // TODO - JMS - is there a way to do this without deep copying data? EIC(ei_x_append(types, &values), ei_x_free(&values)); // cleanup expression EI(ei_x_free(&values)); return 0; }
static void cmd_ei_rpc(char* buf, int len) { int index = 0, n; long fd; erlang_pid pid; ei_x_buff x, rpc_x; int r; char mod[MAXATOMLEN], func[MAXATOMLEN]; #if 0 && defined(__WIN32__) DebugBreak(); #endif if (ei_decode_long(buf, &index, &fd) < 0) fail("expected long"); if (ei_decode_pid(buf, &index, &pid) < 0) fail("expected pid (node)"); if (ei_decode_tuple_header(buf, &index, &n) < 0 && n < 2) fail("expected tuple {module, function}"); if (ei_decode_atom(buf, &index, mod) < 0) fail("expected atom (module)"); if (ei_decode_atom(buf, &index, func) < 0) fail("expected atom (function)"); message("pid %s %d %d %d\n", pid.node, pid.num, pid.serial, pid.creation); message("{%s, %s}\n", mod, func); if (ei_x_new(&rpc_x) < 0) fail("ei_x_new"); if (ei_rpc(&ec, fd, mod, func, &buf[index], len - index, &rpc_x) < 0) fail("ei_rpc"); if (ei_x_new_with_version(&x) < 0) fail("ei_x_new_with_version"); if (ei_x_append(&x, &rpc_x) < 0) fail("append"); send_bin_term(&x); /*send_errno_result(ei_send(&ec, fd, &pid, x.buff, x.index));*/ ei_x_free(&x); ei_x_free(&rpc_x); }
int main(void) #endif { ErlConnect conp; Erl_IpAddr thisipaddr = (Erl_IpAddr)0; FILE *fp = (FILE *)0; char* charp = "foo"; double *doublep = NULL; double doublex = 0.0; ei_cnode xec; ei_reg *ei_regp = NULL; ei_term eterm; ei_x_buff eix; erlang_big *bigp = NULL; erlang_fun efun; erlang_msg *msgp = NULL; erlang_msg emsg; erlang_pid *pidp = NULL; erlang_pid epid; erlang_port eport; erlang_ref eref; erlang_trace etrace; int *intp = NULL; int intx = 0; long *longp = NULL; long longx = 0; short creation = 0; struct ei_reg_stat *ei_reg_statp = NULL; struct ei_reg_tabstat *ei_reg_tabstatp = NULL; struct hostent *hostp = NULL; unsigned char * ucharp = (unsigned char *)"foo"; unsigned long *ulongp = NULL; unsigned long ulongx = 0; void *voidp = NULL; #ifndef VXWORKS EI_LONGLONG *longlongp = (EI_LONGLONG*)NULL; EI_LONGLONG longlongx = 0; EI_ULONGLONG *ulonglongp = (EI_ULONGLONG*)NULL; EI_ULONGLONG ulonglongx = 0; #endif enum erlang_char_encoding enc; intx = erl_errno; ei_connect_init(&xec, charp, charp, creation); ei_connect_xinit (&xec, charp, charp, charp, thisipaddr, charp, creation); ei_connect(&xec, charp); ei_xconnect (&xec, thisipaddr, charp); ei_receive(intx, ucharp, intx); ei_receive_msg(intx, &emsg, &eix); ei_xreceive_msg(intx, &emsg, &eix); ei_send(intx, &epid, charp, intx); ei_reg_send(&xec, intx, charp, charp, intx); ei_rpc(&xec, intx, charp, charp, charp, intx, &eix); ei_rpc_to(&xec, intx, charp, charp, charp, intx); ei_rpc_from(&xec, intx, intx, &emsg, &eix); ei_publish(&xec, intx); ei_accept(&xec, intx, &conp); ei_unpublish(&xec); ei_thisnodename(&xec); ei_thishostname(&xec); ei_thisalivename(&xec); ei_self(&xec); ei_gethostbyname(charp); ei_gethostbyaddr(charp, intx, intx); ei_gethostbyname_r(charp, hostp, charp, intx, intp); ei_gethostbyaddr_r(charp, intx, intx, hostp, charp, intx, intp); ei_encode_version(charp, intp); ei_x_encode_version(&eix); ei_encode_long(charp, intp, longx); ei_x_encode_long(&eix, longx); ei_encode_ulong(charp, intp, ulongx); ei_x_encode_ulong(&eix, ulongx); ei_encode_double(charp, intp, doublex); ei_x_encode_double(&eix, doublex); ei_encode_boolean(charp, intp, intx); ei_x_encode_boolean(&eix, intx); ei_encode_char(charp, intp, 'a'); ei_x_encode_char(&eix, 'a'); ei_encode_string(charp, intp, charp); ei_encode_string_len(charp, intp, charp, intx); ei_x_encode_string(&eix, charp); ei_x_encode_string_len(&eix, charp, intx); ei_encode_atom(charp, intp, charp); ei_encode_atom_as(charp, intp, charp, ERLANG_LATIN1, ERLANG_UTF8); ei_encode_atom_len(charp, intp, charp, intx); ei_encode_atom_len_as(charp, intp, charp, intx, ERLANG_ASCII, ERLANG_LATIN1); ei_x_encode_atom(&eix, charp); ei_x_encode_atom_as(&eix, charp, ERLANG_LATIN1, ERLANG_UTF8); ei_x_encode_atom_len(&eix, charp, intx); ei_x_encode_atom_len_as(&eix, charp, intx, ERLANG_LATIN1, ERLANG_UTF8); ei_encode_binary(charp, intp, (void *)0, longx); ei_x_encode_binary(&eix, (void*)0, intx); ei_encode_pid(charp, intp, &epid); ei_x_encode_pid(&eix, &epid); ei_encode_fun(charp, intp, &efun); ei_x_encode_fun(&eix, &efun); ei_encode_port(charp, intp, &eport); ei_x_encode_port(&eix, &eport); ei_encode_ref(charp, intp, &eref); ei_x_encode_ref(&eix, &eref); ei_encode_trace(charp, intp, &etrace); ei_x_encode_trace(&eix, &etrace); ei_encode_tuple_header(charp, intp, intx); ei_x_encode_tuple_header(&eix, longx); ei_encode_list_header(charp, intp, intx); ei_x_encode_list_header(&eix, longx); /* #define ei_encode_empty_list(buf,i) ei_encode_list_header(buf,i,0) */ ei_x_encode_empty_list(&eix); ei_get_type(charp, intp, intp, intp); ei_get_type_internal(charp, intp, intp, intp); ei_decode_version(charp, intp, intp); ei_decode_long(charp, intp, longp); ei_decode_ulong(charp, intp, ulongp); ei_decode_double(charp, intp, doublep); ei_decode_boolean(charp, intp, intp); ei_decode_char(charp, intp, charp); ei_decode_string(charp, intp, charp); ei_decode_atom(charp, intp, charp); ei_decode_atom_as(charp, intp, charp, MAXATOMLEN_UTF8, ERLANG_WHATEVER, &enc, &enc); ei_decode_binary(charp, intp, (void *)0, longp); ei_decode_fun(charp, intp, &efun); free_fun(&efun); ei_decode_pid(charp, intp, &epid); ei_decode_port(charp, intp, &eport); ei_decode_ref(charp, intp, &eref); ei_decode_trace(charp, intp, &etrace); ei_decode_tuple_header(charp, intp, intp); ei_decode_list_header(charp, intp, intp); ei_decode_ei_term(charp, intp, &eterm); ei_print_term(fp, charp, intp); ei_s_print_term(&charp, charp, intp); ei_x_format(&eix, charp); ei_x_format_wo_ver(&eix, charp); ei_x_new(&eix); ei_x_new_with_version(&eix); ei_x_free(&eix); ei_x_append(&eix, &eix); ei_x_append_buf(&eix, charp, intx); ei_skip_term(charp, intp); ei_reg_open(intx); ei_reg_resize(ei_regp, intx); ei_reg_close(ei_regp); ei_reg_setival(ei_regp, charp, longx); ei_reg_setfval(ei_regp, charp, doublex); ei_reg_setsval(ei_regp, charp, charp); ei_reg_setpval(ei_regp, charp, voidp, intx); ei_reg_setval(ei_regp, charp, intx); ei_reg_getival(ei_regp, charp); ei_reg_getfval(ei_regp, charp); ei_reg_getsval(ei_regp, charp); ei_reg_getpval(ei_regp, charp, intp); ei_reg_getval(ei_regp, charp, intx); ei_reg_markdirty(ei_regp, charp); ei_reg_delete(ei_regp, charp); ei_reg_stat(ei_regp, charp, ei_reg_statp); ei_reg_tabstat(ei_regp, ei_reg_tabstatp); ei_reg_dump(intx, ei_regp, charp, intx); ei_reg_restore(intx, ei_regp, charp); ei_reg_purge(ei_regp); #if defined(HAVE_GMP_H) && defined(HAVE_LIBGMP) { mpz_t obj; ei_decode_bignum(charp, intp, obj); ei_encode_bignum(charp, intp, obj); ei_x_encode_bignum(&eix, obj); } #endif /* HAVE_GMP_H && HAVE_LIBGMP */ #ifndef VXWORKS ei_decode_longlong(charp, intp, longlongp); ei_decode_ulonglong(charp, intp, ulonglongp); ei_encode_longlong(charp, intp, longlongx); ei_encode_ulonglong(charp, intp, ulonglongx); ei_x_encode_longlong(&eix, longlongx); ei_x_encode_ulonglong(&eix, ulonglongx); #endif #ifdef USE_EI_UNDOCUMENTED ei_decode_intlist(charp, intp, longp, intp); ei_receive_encoded(intx, &charp, intp, msgp, intp); ei_send_encoded(intx, pidp, charp, intx); ei_send_reg_encoded(intx, pidp, charp, charp, intx); ei_decode_big(charp, intp, bigp); ei_big_comp(bigp, bigp); ei_big_to_double(bigp, doublep); ei_small_to_big(intx, bigp); ei_alloc_big(intx); ei_free_big(bigp); #endif /* USE_EI_UNDOCUMENTED */ return BUFSIZ + EAGAIN + EHOSTUNREACH + EIO + EI_BIN + EI_DELET + EI_DIRTY + EI_FLT + EI_FORCE + EI_INT + EI_NOPURGE + EI_STR + EMSGSIZE + ENOMEM + ERL_ERROR + ERL_EXIT + ERL_LINK + ERL_MSG + ERL_NO_TIMEOUT + ERL_REG_SEND + ERL_SEND + ERL_TICK + ERL_TIMEOUT + ERL_UNLINK + ETIMEDOUT + MAXATOMLEN; }
int enter_element(struct exmpp_xml_ctx *ctx, const char *ns, int ns_len, const char *elem, int elem_len, void *declared_nss, void *attributes) { int ret; ei_x_buff *tree; /* * This function build the #xmlel record: * {xmlel, NS, Declared_NS, Name, Attributes, Children} * * Construction of "Delcared_NS" and "Attributes" are made by * helper functions but they're walked through by callbacks inside * driver's code. * * Note that "Children" may not be built here but by following * calls to this same function. */ tree = ctx->current_tree; /* * If we're not at the required depth, we treat each node * independently. * * For instance in XMPP, if ctx->root_depth is 1, a stand-alone * term will be made right away with a <stream> opening tag. But * for a <message> element, we will build a complete tree including * children. */ if (ctx->root_depth == -1 || ctx->depth <= ctx->root_depth) { /* We're above root depth (or the feature is disabled), * so we start a new Erlang term each time. */ /* The current_tree buffer was reset by * current_tree_finished(). */ } else { /* We're under root depth, thus we continue with the * current tree. */ ei_x_encode_list_header(tree, 1); } /* Start an #xmlel record. */ ei_x_encode_tuple_header(tree, 6); ei_x_encode_atom(tree, "xmlel"); /* Check if the namespace is known and encode it. */ encode_ns(ctx, tree, ns, ns_len); if (ctx->make_declared_nss != NULL) { /* Call a caller-provided function to walk the declared * namespaces list. */ ret = ctx->make_declared_nss(ctx, declared_nss); if (ret != 0) return (ret); } else if (declared_nss != NULL) { /* The caller doesn't provided a callback but an already * formatted list. We just have to append it to the tree. */ ei_x_append(tree, (ei_x_buff *)declared_nss); } /* Terminate the declared namespaces Erlang list. */ ei_x_encode_empty_list(tree); /* Check if the element is known and encode it. */ encode_elem(ctx, tree, elem, elem_len); /* Call a caller-provided function to walk the attributes list. */ if (ctx->make_attributes != NULL) { ret = ctx->make_attributes(ctx, attributes); if (ret != 0) return (ret); } /* Terminate the attributes Erlang list. */ ei_x_encode_empty_list(tree); /* Handle the tree if it's ready to ship. */ if (ctx->root_depth == -1 || ctx->depth < ctx->root_depth) { /* Stand-alone elements are moved to the final list. */ ei_x_encode_atom(tree, "undefined"); current_tree_finished(ctx); } /* Update depth. */ ctx->depth++; return (0); }