示例#1
0
文件: ei_x_encode.c 项目: caox/otp
int ei_x_encode_string_len(ei_x_buff* x, const char* s, int len)
{
    int i = x->index;
    ei_encode_string_len(NULL, &i, s, len);
    if (!x_fix_buff(x, i))
	return -1;
    return ei_encode_string_len(x->buff, &x->index, s, len);
}
示例#2
0
文件: ei_fake_prog.c 项目: caox/otp
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;
}
示例#3
0
文件: erlxsl.c 项目: chinnurtb/erlxsl
/*
This function is called from erlang:port_call/3. It works a lot like the control call-back,
but uses the external term format for input and output.
- command is an integer, obtained from the call from erlang (the second argument to erlang:port_call/3).
- buf and len provide the arguments to the call (the third argument to erlang:port_call/3). They're decoded using ei.
- rbuf points to a return buffer, rlen bytes long.

The return data (written to *rbuf) should be a valid erlang term in the external term format. This is converted to an
erlang term and returned by erlang:port_call/3 to the caller. If more space than rlen bytes is needed to return data,
*rbuf can be set to memory allocated with driver_alloc. This memory will be freed automatically after call has returned.
The return value (of this callback function) is the number of bytes returned in *rbuf. If ERL_DRV_ERROR_GENERAL is returned
(or in fact, anything < 0), erlang:port_call/3 will throw a BAD_ARG.

THIS IMPLEMENTATION of the callback handles two kinds of commands, INIT_COMMAND and ENGINE_COMMAND. An INIT_COMMAND should
only be issued once during the lifecycle of the driver, *before* any data is sent to the port using port_command/port_control.
The INIT_COMMAND causes the driver to load the specified shared library and call a predefined entry point (see the
erlxsl_driver header file for details) to initialize an XslEngine structure.

TODO: document ENGINE_COMMAND.
TODO: locking during ENGINE_COMMAND calls
TODO: support the transform command here as well - small binaries (which we can't/won't share/refcount) can be passed and copied...
*/
static int
call(ErlDrvData drv_data, unsigned int command, char *buf,
    int len, char **rbuf, int rlen, unsigned int *flags) {

    int i;
    int type;
    int size;
    int index = 0;
    int rindex = 0;
    /*int arity;
     *
    char cmd[MAXATOMLEN];*/
    char *data;
    DriverState state;
    DriverHandle *d = (DriverHandle*)drv_data;

    ei_decode_version(buf, &index, &i);
    if (command == INIT_COMMAND) {
        ei_get_type(buf, &index, &type, &size);
        INFO("ei_get_type %s of size = %i\n", ((char*)&type), size);
        // TODO: pull options tuple instead
        data = ALLOC(size + 1);
        ei_decode_string(buf, &index, data);
        INFO("Driver received data %s\n", data);
        state = init_provider(d, data);
    } else if (command == ENGINE_COMMAND) {
        DriverContext *ctx = ALLOC(sizeof(DriverContext));
        // ErlDrvPort port = (ErlDrvPort)d->port;
        // XslEngine *engine = (XslEngine*)d->engine;
        // ErlDrvTermData callee_pid = driver_caller(port);
        Command *cmd = init_command(NULL, ctx, NULL, init_iov(Text, 0, NULL));

        state = decode_ei_cmd(cmd, buf, &index);
        if (state == Success) {
            XslEngine *engine = (XslEngine*)d->engine;
            if (engine->command != NULL) {
                EngineState enstate = engine->command(cmd);
                if (enstate == Ok) {
                    state = Success;
                }
            }
        }
        /*ei_get_type(buf, &index, &type, &size);
        INFO("ei_get_type %s of size = %i\n", ((char*)&type), size);
        data = ALLOC(size + 1);
        ei_decode_string(buf, &index, data);*/
    } else {
        state = UnknownCommand;
    }

    ei_encode_version(*rbuf, &rindex);
    if (state == InitOk) {
        INFO("Provider configured with library %s\n", d->loader->name);
#ifdef _DRV_SASL_LOGGING
        // TODO: pull the logging_port and install it....
#endif
        ei_encode_atom(*rbuf, &rindex, "configured");
    } else if (state == Success) {
        ei_encode_tuple_header(*rbuf, &rindex, 2);
        ei_encode_atom(*rbuf, &rindex, "ok");
        if (state == OutOfMemory) {
            ei_encode_string(*rbuf, &rindex, heap_space_exhausted);
        } else if (state == UnknownCommand) {
            ei_encode_string(*rbuf, &rindex, unknown_command);
        } else {
            const char *err = (d->loader)->error_message;
            ei_encode_string_len(*rbuf, &rindex, err, strlen(err));
        }
    } else {
        ei_encode_tuple_header(*rbuf, &rindex, 2);
        ei_encode_atom(*rbuf, &rindex, "error");
        if (state == OutOfMemory) {
            ei_encode_string(*rbuf, &rindex, heap_space_exhausted);
        } else if (state == UnknownCommand) {
            ei_encode_string(*rbuf, &rindex, unknown_command);
        } else {
            const char *err = (d->loader)->error_message;
            ei_encode_string_len(*rbuf, &rindex, err, strlen(err));
        }
    }
    DRV_FREE(data);
    return(rindex);
};