示例#1
0
static ERL_NIF_TERM do_write(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
  static PortMidiStream ** stream;

  ErlNifResourceType* streamType = (ErlNifResourceType*)enif_priv_data(env);
  if(!enif_get_resource(env, argv[0], streamType, (PortMidiStream **) &stream)) {
    return enif_make_badarg(env);
  }

  ERL_NIF_TERM erlMessages = argv[1];
  const ERL_NIF_TERM * erlEvent;
  const ERL_NIF_TERM * erlMessage;
  ERL_NIF_TERM erlTuple;

  unsigned int numOfMessages;
  int tupleSize;
  enif_get_list_length(env, erlMessages, &numOfMessages);

  PmEvent events[numOfMessages];
  long int status, note, velocity, timestamp;

  for(unsigned int i = 0; i < numOfMessages; i++) {
    enif_get_list_cell(env, erlMessages, &erlTuple, &erlMessages);
    enif_get_tuple(env, erlTuple, &tupleSize, &erlEvent);

    enif_get_tuple(env, erlEvent[0], &tupleSize, &erlMessage);
    enif_get_long(env, erlMessage[0], &status);
    enif_get_long(env, erlMessage[1], &note);
    enif_get_long(env, erlMessage[2], &velocity);

    enif_get_long(env, erlEvent[1], &timestamp);

    PmEvent event;
    event.message = Pm_Message(status, note, velocity);
    event.timestamp = timestamp;

    events[i] = event;
  }

  PmError writeError;
  writeError = Pm_Write(*stream, events, numOfMessages);

  if (writeError == pmNoError) {
    return enif_make_atom(env, "ok");
  }

  const char * writeErrorMsg;
  writeErrorMsg = Pm_GetErrorText(writeError);

  return enif_make_tuple2(
    env,
    enif_make_atom(env, "error"),
    enif_make_string(env, writeErrorMsg, ERL_NIF_LATIN1)
  );
}
示例#2
0
文件: CAN_nif.c 项目: qoocku/erleos
static ERL_NIF_TERM
_listener (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
  CAN_handle* handle;
  ErlNifPid pid = { 0 }; // NOTE: breaking opaque type!
  enif_get_resource(env, argv[0], CAN_handle_type, (void**) &handle);
  if (handle->threaded) // there is a thread already and some pid!
  {
    pid = handle->receiver;
  }
  if (!enif_get_local_pid(env, argv[1], &handle->receiver)) // NOTE: use lock if pid type is structural!
    {
      handle->threaded = 0;
      return enif_make_badarg(env);
    }
  else
    {
      enif_get_uint(env, argv[2], &handle->chunk_size);
      enif_get_long(env, argv[3], &handle->timeout);
      if (!handle->threaded) // a thread was not created already
        {
          if (enif_thread_create("can_reading_thread",
              &handle->tid,
              _reading_thread,
              handle, 0))
            {
              handle->threaded = 0;
              return enif_make_int(env, -1004);
            }
        }
    }
  return pid.pid ? enif_make_pid(env, &pid) : enif_make_int(env, 0);
}
示例#3
0
static ERL_NIF_TERM emmap_position(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
  mhandle *handle;
  long position;
  long relpos;
  if (argc==3
      && enif_get_resource(env, argv[0], MMAP_RESOURCE, (void**)&handle)
      && enif_get_long(env, argv[2], &relpos)
      && (argv[1] == ATOM_CUR || argv[1] == ATOM_BOF || argv[1] == ATOM_EOF))
    {
      RW_LOCK;

      if (argv[1] == ATOM_BOF) {
        position = 0L + relpos;
      } else if (argv[1] == ATOM_CUR) {
        position = handle->position + relpos;
      } else if (argv[1] == ATOM_EOF) {
        position = handle->len - relpos;
      }

      if (position < 0L || ((unsigned long)position) > handle->len) {
        RW_UNLOCK;
        return enif_make_badarg(env);
      }

      handle->position = position;
      RW_UNLOCK;

      return enif_make_tuple2(env, ATOM_OK, enif_make_ulong(env, position));
    }
  else
    {
      return enif_make_badarg(env);
    }
}
示例#4
0
static ERL_NIF_TERM make_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    union { void* p; long l; } data;
    if (!enif_get_long(env, argv[0], &data.l)) {
	return enif_make_badarg(env);
    }
    return enif_make_resource(env, data.p);
}
示例#5
0
文件: exmagick.c 项目: Xerpa/exmagick
static
ERL_NIF_TERM exmagick_crop (ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
  Image* cropped_image;
  RectangleInfo rect;
  exm_resource_t *resource;

  EXM_INIT;
  ErlNifResourceType *type = (ErlNifResourceType *) enif_priv_data(env);

  if (0 == enif_get_resource(env, argv[0], type, (void **) &resource))
  { EXM_FAIL(ehandler, "invalid handle"); }

  if (resource->image == NULL)
  { EXM_FAIL(ehandler, "image not loaded"); }

  /* build rectangle */
  if (0 == enif_get_long(env, argv[1], &rect.x))
  { EXM_FAIL(ehandler, "x0: bad argument"); }

  if (0 == enif_get_long(env, argv[2], &rect.y))
  { EXM_FAIL(ehandler, "y0: bad argument"); }

  if (0 == enif_get_ulong(env, argv[3], &rect.width))
  { EXM_FAIL(ehandler, "width: bad argument"); }

  if (0 == enif_get_ulong(env, argv[4], &rect.height))
  { EXM_FAIL(ehandler, "height: bad argument"); }

  /* actually crops image */
  cropped_image = CropImage(resource->image, &rect, &resource->e_info);
  if (cropped_image == NULL)
  {
    CatchException(&resource->e_info);
    EXM_FAIL(ehandler, resource->e_info.reason);
  }
  DestroyImage(resource->image);
  resource->image = cropped_image;

  return(enif_make_tuple2(env, enif_make_atom(env, "ok"), argv[0]));

ehandler:
  return(enif_make_tuple2(env, enif_make_atom(env, "error"), exmagick_make_utf8str(env, errmsg)));
}
示例#6
0
static int test_long(ErlNifEnv* env, long i1)
{
    long i2 = 0;
    ERL_NIF_TERM int_term = enif_make_long(env, i1);
    if (!enif_get_long(env,int_term, &i2) || i1 != i2) {
	fprintf(stderr, "test_long(%ld) ...FAILED i2=%ld\r\n", i1, i2);
	return 0;
    }
    return 1;
}
示例#7
0
static ERL_NIF_TERM hash(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
    ErlNifBinary bin;
    long seed;
    int hash;

    if (enif_inspect_binary(env, argv[0], &bin)) {
        int res = enif_get_long(env, argv[1], &seed);
        hash = fnv_hash(bin.data, bin.size, seed);
        return enif_make_int(env, hash);
    }
    return enif_make_atom(env, "badarg");
}
示例#8
0
// convert an erlang term to a python object
// return None if the type can't be converted
static PyObject* pynerl_term_to_obj(ErlNifEnv* env, ERL_NIF_TERM term) {
	int vint;
	Py_ssize_t arity, i;
	long int vlong;
	double vdouble;
	char buff[BUFF_SIZE];
	PyObject* obj;
	ERL_NIF_TERM list, head, tail;
	const ERL_NIF_TERM *terms;

	// TODO: add more types
	if (enif_get_long(env, term, &vlong)) {
		obj = PyLong_FromLong(vlong);
	}
	else if (enif_get_double(env, term, &vdouble)) {
		obj = PyFloat_FromDouble(vlong);
	}
	else if (enif_is_empty_list(env, term)) {
		obj = PyList_New(0);
	}
	else if (enif_get_tuple(env, term, &vint, &terms)) {
		arity = vint;
		obj = PyTuple_New(arity);

		for (i = 0; i < arity; i++) {
			PyTuple_SetItem(obj, i, pynerl_term_to_obj(env, terms[(int)i]));
		}
	}
	else if (enif_is_identical(term, enif_make_atom(env, "true"))) {
		obj = Py_True;
	}
	else if (enif_is_identical(term, enif_make_atom(env, "false"))) {
		obj = Py_False;
	}
	else if (enif_get_string(env, term, buff, BUFF_SIZE, ERL_NIF_LATIN1)) {
		obj = PyUnicode_FromString(buff);
	}
	else if (enif_get_list_cell(env, term, &head, &tail)) {
		obj = PyList_New(0);
		list = term;

		while (enif_get_list_cell(env, list, &head, &tail)) {
			PyList_Append(obj, pynerl_term_to_obj(env, head));
			list = tail;
		}
	}
	else {
		obj = Py_None;
	}

	return obj;
}
示例#9
0
void PCudaFloatBuffer::write(ErlNifEnv *env, ERL_NIF_TERM data) {
    ERL_NIF_TERM head;
    double value;
    long lvalue;

    while (enif_get_list_cell(env, data, &head, &data)) {
        if (enif_get_double(env, head, &value)) {
            this->data->push_back(value);
        }else if (enif_get_long(env, head, &lvalue)) {
            this->data->push_back((double)lvalue);
        }
    }
}
示例#10
0
文件: CAN_nif.c 项目: qoocku/erleos
static ERL_NIF_TERM
_recv  (ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
  CAN_handle* handle;
  unsigned int chunk_size;
  long timeout;
  ERL_NIF_TERM result;
  enif_get_resource(env, argv[0], CAN_handle_type, (void**) &handle);
  enif_get_uint(env, argv[1], &chunk_size);
  enif_get_long(env,argv[2], &timeout);
  result = _receive_can_messages(env, handle, chunk_size, timeout);
  return result;
}
示例#11
0
double
fetch_double(ErlNifEnv* env, ERL_NIF_TERM* items) {
  ERL_NIF_TERM head;
  // Fetch head if possible
  if (! enif_get_list_cell(env, *items, &head, items)) return 0.0;

  long i;
  double d;

  if(enif_get_double(env, head, &d)) return d;
  if(enif_get_long(env, head, &i)) return (double) i;

  return 0.0;
};
示例#12
0
static ERL_NIF_TERM alloc_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifBinary data_bin;
    union { ErlNifResourceType* t; long l;} type;
    union { void* p; long l;} data;
    if (!enif_get_long(env, argv[0], &type.l)
	|| !enif_inspect_binary(env, argv[1], &data_bin)
	|| (data.p = enif_alloc_resource(type.t, data_bin.size))==NULL) {

	return enif_make_badarg(env);
    }
    memcpy(data.p, data_bin.data, data_bin.size);
    return enif_make_long(env, data.l);
}
示例#13
0
文件: cb.c 项目: muut/cberl
void* cb_mtouch_args(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    mtouch_args_t* args = (mtouch_args_t*)enif_alloc(sizeof(mtouch_args_t));

    ERL_NIF_TERM* currKey;
    ERL_NIF_TERM tail;
    ErlNifBinary key_binary;

    if (!enif_get_list_length(env, argv[0], &args->numkeys)) goto error0;
    args->keys = malloc(sizeof(char*) * args->numkeys);
    args->nkeys = malloc(sizeof(size_t) * args->numkeys);
    currKey = malloc(sizeof(ERL_NIF_TERM));
    tail = argv[0];
    int i = 0;
    while(0 != enif_get_list_cell(env, tail, currKey, &tail)) {
        if (!enif_inspect_iolist_as_binary(env, *currKey, &key_binary)) goto error1;
        args->keys[i] = malloc(sizeof(char) * key_binary.size);
        memcpy(args->keys[i], key_binary.data, key_binary.size);
        args->nkeys[i] = key_binary.size;
        i++;
    }

    args->exp = malloc(sizeof(int64_t) * args->numkeys);
    tail = argv[1];
    int i2 = 0;
    while(0 != enif_get_list_cell(env, tail, currKey, &tail)) {
        if (!enif_get_long(env, *currKey, &args->exp[i2])) goto error2;
        i2++;
    }

    free(currKey);

    return (void*)args;

    int f = 0;

    error2:
    free(args->exp);
    error1:
    for(f = 0; f < i; f++) {
        free(args->keys[f]);
    }
    free(args->keys);
    free(args->nkeys);
    error0:
    enif_free(args);

    return NULL;
}
示例#14
0
文件: exmagick.c 项目: Xerpa/exmagick
static
ERL_NIF_TERM exmagick_image_thumb (ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
  long width, height;
  Image* thumb;
  exm_resource_t *resource;

  EXM_INIT;
  ErlNifResourceType *type = (ErlNifResourceType *) enif_priv_data(env);

  if (0 == enif_get_resource(env, argv[0], type, (void **) &resource))
  { EXM_FAIL(ehandler, "invalid handle"); }

  if (resource->image == NULL)
  { EXM_FAIL(ehandler, "image not loaded"); }

  if (0 == enif_get_long(env, argv[1], &width))
  { EXM_FAIL(ehandler, "width: bad argument"); }

  if (0 == enif_get_long(env, argv[2], &height))
  { EXM_FAIL(ehandler, "height: bad argument"); }

  thumb = ThumbnailImage(resource->image, width, height, &resource->e_info);
  if (thumb == NULL)
  {
    CatchException(&resource->e_info);
    EXM_FAIL(ehandler, resource->e_info.reason);
  }
  DestroyImage(resource->image);
  resource->image = thumb;

  return(enif_make_tuple2(env, enif_make_atom(env, "ok"), argv[0]));

ehandler:
  return(enif_make_tuple2(env, enif_make_atom(env, "error"), exmagick_make_utf8str(env, errmsg)));
}
示例#15
0
static ERL_NIF_TERM make_new_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifBinary data_bin;
    union { ErlNifResourceType* t; long l;} type;
    void* data;
    ERL_NIF_TERM ret;
    if (!enif_get_long(env, argv[0], &type.l)
	|| !enif_inspect_binary(env, argv[1], &data_bin)
	|| (data = enif_alloc_resource(type.t, data_bin.size))==NULL) {

	return enif_make_badarg(env);
    }
    ret = enif_make_resource(env, data);
    memcpy(data, data_bin.data, data_bin.size);
    enif_release_resource(data);
    return ret;
}
示例#16
0
static inline int push_nif_number(lua_State* lua, ERL_NIF_TERM message, ErlNifEnv* env)
{
	const int top = lua_gettop(lua);

	int result = 0;

    int intval;
    unsigned int uintval;
    long longval;
    unsigned long ulongval;
    double doubleval;

	luaL_checkstack(lua, 1, ERROR_STACK_MESSAGE);
    if(enif_get_int(env, message, &intval))
    {
    	lua_pushnumber(lua, (double) intval);
        result = 1;
    }
    else if(enif_get_uint(env, message, &uintval))
    {
    	lua_pushnumber(lua, (double) uintval);
        result = 1;
    }
    else if(enif_get_long(env, message, &longval))
    {
    	lua_pushnumber(lua, (double) longval);
        result = 1;
    }
    else if(enif_get_ulong(env, message, &ulongval))
    {
    	lua_pushnumber(lua, (double) ulongval);
        result = 1;
    }
    else if(enif_get_double(env, message, &doubleval))
    {
    	lua_pushnumber(lua, (double) doubleval);
        result = 1;
    }

	assert(lua_gettop(lua) == top+result);

	return result;
}
示例#17
0
static ERL_NIF_TERM get_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifBinary data_bin;
    union { ErlNifResourceType* t; long l; } type;
    union { void* p; long l; } data;

    type.t = NULL;
    if (enif_is_identical(argv[0], atom_binary_resource_type)) {
	type.t = binary_resource_type;
    }
    else {
	enif_get_long(env, argv[0], &type.l);
    }
    if (type.t == NULL 
	|| !enif_get_resource(env, argv[1], type.t, &data.p)) {
	return enif_make_badarg(env);
    }
    enif_alloc_binary(enif_sizeof_resource(data.p), &data_bin);    
    memcpy(data_bin.data, data.p, data_bin.size);
    return enif_make_tuple2(env, enif_make_long(env,data.l),
			    enif_make_binary(env, &data_bin));
}
示例#18
0
static ERL_NIF_TERM do_open(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
  char deviceName[MAXBUFLEN];
  long latency;
  ERL_NIF_TERM streamTerm;
  PortMidiStream **streamAlloc;
  PmError result;

  ErlNifResourceType* streamType = (ErlNifResourceType*)enif_priv_data(env);
  streamAlloc = (PortMidiStream**)enif_alloc_resource(streamType, sizeof(PortMidiStream*));

  enif_get_string(env, argv[0], deviceName, MAXBUFLEN, ERL_NIF_LATIN1);
  enif_get_long(env, argv[1], &latency);

  if((result = findDevice(streamAlloc, deviceName, OUTPUT, latency)) != pmNoError) {
    ERL_NIF_TERM reason = enif_make_atom(env, makePmErrorAtom(result));
    return enif_make_tuple2(env, enif_make_atom(env, "error"), reason);
  }

  streamTerm = enif_make_resource(env, streamAlloc);
  enif_keep_resource(streamAlloc);

  return enif_make_tuple2(env, enif_make_atom(env, "ok"), streamTerm);
}
示例#19
0
文件: eim_nifs.cpp 项目: Jasson/eim
ERL_NIF_TERM derive_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ihandle* handle;
    ERL_NIF_TERM head;
    ERL_NIF_TERM tail;
    char fmt[4];
    
    if(enif_get_resource(env, argv[0], EIM_IMAGE_RESOURCE, (void**)&handle)
    && enif_get_atom_compat(env, argv[1], fmt, 4, ERL_NIF_LATIN1)
    && enif_get_list_cell(env, argv[2], &head, &tail))
    {
        ErlNifBinary new_binary;
        size_t new_length;
        unsigned char *new_blob;
        
        do {
            //todo: error handle
            int tuplec;
            const ERL_NIF_TERM* tuple;
            char type[9];
            if(!enif_get_tuple(env, head, &tuplec, &tuple)
            || !enif_get_atom_compat(env, tuple[0], type, 9, ERL_NIF_LATIN1))
            {
                return enif_make_badarg(env);
            }
            long x, y;
            long width, height;
            long value;
            int rotate;
            char dimension[7];
            switch(type[0])
            {
                case 's'://scale
                    if(!enif_get_atom_compat(env, tuple[1], dimension, 7, ERL_NIF_LATIN1)
                    || !enif_get_long(env, tuple[2], &value))
                    {
                        return enif_make_badarg(env);
                    }
                    if(dimension[0]=='w')
                    {
                        handle->image->scale_width(value);
                    }
                    else if(dimension[0]=='h')
                    {
                        handle->image->scale_height(value);
                    }
                    else
                    {
                        return enif_make_badarg(env);
                    }
                    break;
                case 'c'://crop
                    if(!enif_get_long(env, tuple[1], &width) || !enif_get_long(env, tuple[2], &height)
                    || !enif_get_long(env, tuple[3], &x) || !enif_get_long(env, tuple[4], &y))
                    {
                        return enif_make_badarg(env);
                    }
                    handle->image->crop(width, height, x, y);
                    break;
                case 'm'://max
                    if(!enif_get_atom_compat(env, tuple[1], dimension, 7, ERL_NIF_LATIN1)
                    || !enif_get_long(env, tuple[2], &value))
                    {
                        return enif_make_badarg(env);
                    }
                    if(dimension[0]=='w')
                    {
                        handle->image->max_width(value);
                    }
                    else if(dimension[0]=='h')
                    {
                        handle->image->max_height(value);
                    }
                    else
                    {
                        return enif_make_badarg(env);
                    }
                    break;
                case 'f'://fit
                    if(!enif_get_long(env, tuple[1], &width) || !enif_get_long(env, tuple[2], &height))
                    {
                        return enif_make_badarg(env);
                    }
                    handle->image->fit(width, height);
                    break;
                case 'r'://rotate
                    if(!enif_get_int(env, tuple[1], &rotate))
                    {
                        return enif_make_badarg(env);
                    }
                    switch(rotate)
                    {
                        case 1: handle->image->rotate(EIM_ROTATE_90); break;
                        case 2: handle->image->rotate(EIM_ROTATE_180); break;
                        case 3: handle->image->rotate(EIM_ROTATE_270); break;
                        default:
                            return enif_make_badarg(env);
                    };
                    break;
                case 'b'://box
                    if(!enif_get_long(env, tuple[1], &width) || !enif_get_long(env, tuple[2], &height))
                    {
                        return enif_make_badarg(env);
                    }
                    char float_x[7], float_y[7];
                    char floated;
                    if(enif_get_atom_compat(env, tuple[3], float_x, 7, ERL_NIF_LATIN1))
                    {
                        if(!enif_get_atom_compat(env, tuple[4], float_y, 7, ERL_NIF_LATIN1))
                        {
                            return enif_make_badarg(env);
                        }
                        // can actually write top,left instead of left,top if you want
                        // just helps with typos like that. Just works.
                        switch(float_x[0])
                        {
                            case 'l': floated = EIM_FLOAT_LEFT; break;
                            case 'c': floated = EIM_FLOAT_CENTER; break;
                            case 'r': floated = EIM_FLOAT_RIGHT; break;
                            case 't': floated = EIM_FLOAT_TOP; break;
                            case 'b': floated = EIM_FLOAT_BOTTOM; break;
                            default:
                                return enif_make_badarg(env);
                        }
                        switch(float_y[0])
                        {
                            case 'l': floated ^= EIM_FLOAT_LEFT; break;
                            case 'c': floated ^= EIM_FLOAT_CENTER; break;
                            case 'r': floated ^= EIM_FLOAT_RIGHT; break;
                            case 't': floated ^= EIM_FLOAT_TOP; break;
                            case 'b': floated ^= EIM_FLOAT_BOTTOM; break;
                            default:
                                return enif_make_badarg(env);
                        }
                    }
                    else
                    {
                        floated = EIM_FLOAT_CENTER | EIM_FLOAT_CENTER;
                    }
                    handle->image->box(width, height, floated);
                    break;
                default:
                    return enif_make_badarg(env);
            }
            
        } while(enif_get_list_cell(env, tail, &head, &tail));
        
        EIM_FORMAT eim_format;
        switch(fmt[0])
        {
            case 'j': eim_format = EIM_FORMAT_JPG; break;
            case 'g': eim_format = EIM_FORMAT_GIF; break;
            case 'p': eim_format = EIM_FORMAT_PNG; break;
            default:
                return enif_make_badarg(env);
        }
        try
        {
            new_blob = handle->image->process(eim_format, &new_length);
            enif_alloc_binary_compat(env, new_length, &new_binary);
            memcpy(new_binary.data, new_blob, new_length);
            return enif_make_binary(env, &new_binary);
        }
        catch(const char* msg)
        {
            return enif_make_atom(env, "error");
        }
    }
    else
    {
        return enif_make_badarg(env);
    }
}
示例#20
0
文件: matrix_nif.c 项目: HansN/otp
static int get_number(ErlNifEnv* env, ERL_NIF_TERM term, double* dp)
{
    long i;
    return enif_get_double(env, term, dp) || 
	(enif_get_long(env, term, &i) && (*dp=(double)i, 1));
}
示例#21
0
int
enc_json(Encoder* enc, ERL_NIF_TERM term)
{
    int ival;
    unsigned int uival;
    long lval;
    unsigned long ulval;
    double dval;
    ERL_NIF_TERM head;
    ERL_NIF_TERM tail;
    int arity;
    const ERL_NIF_TERM* tuple;
    
    if(enif_is_atom(enc->env, term))
    {
        return enc_atom(enc, term);
    }
    
    if(enif_is_binary(enc->env, term))
    {
        return enc_binary(enc, term);
    }
    
    if(enif_get_int(enc->env, term, &ival))
    {
        if(yajl_gen_integer(enc->handle, ival) != yajl_gen_status_ok)
        {
            enc->error = enif_make_atom(enc->env, "bad_integer");
            return ERROR;
        }
        return OK;
    }
    
    if(enif_get_uint(enc->env, term, &uival))
    {
        if(yajl_gen_integer(enc->handle, uival) != yajl_gen_status_ok)
        {
            enc->error = enif_make_atom(enc->env, "bad_unsigned_integer");
            return ERROR;
        }
        return OK;
    }
    
    if(enif_get_long(enc->env, term, &lval))
    {
        if(yajl_gen_integer(enc->handle, lval) != yajl_gen_status_ok)
        {
            enc->error = enif_make_atom(enc->env, "bad_long");
            return ERROR;
        }
        return OK;
    }
    
    if(enif_get_ulong(enc->env, term, &ulval))
    {
        if(yajl_gen_integer(enc->handle, ulval) != yajl_gen_status_ok)
        {
            enc->error = enif_make_atom(enc->env, "bad_unsigned_long");
            return ERROR;
        }
        return OK;
    }

    if(enif_get_double(enc->env, term, &dval))
    {
        if(yajl_gen_double(enc->handle, dval) != yajl_gen_status_ok)
        {
            enc->error = enif_make_atom(enc->env, "bad_double");
            return ERROR;
        }
        return OK;
    }

    if(enif_is_empty_list(enc->env, term))
    {
        if(yajl_gen_array_open(enc->handle) != yajl_gen_status_ok)
        {
            enc->error = enif_make_atom(enc->env, "failed_to_open_empty_list");
            return ERROR;
        }
        if(yajl_gen_array_close(enc->handle) != yajl_gen_status_ok)
        {
            enc->error = enif_make_atom(enc->env, "failed_to_close_empty_list");
            return ERROR;
        }
        return OK;
    }

    if(enif_get_list_cell(enc->env, term, &head, &tail))
    {
        return enc_array(enc, head, tail);
    }
    
    if(enif_get_tuple(enc->env, term, &arity, &tuple))
    {
        if(arity == 1)
        {
            if(enif_is_empty_list(enc->env, tuple[0]))
            {
                if(yajl_gen_map_open(enc->handle) != yajl_gen_status_ok)
                {
                    enc->error = enif_make_atom(enc->env,
                                                "failed_to_open_empty_map");
                    return ERROR;
                }
                if(yajl_gen_map_close(enc->handle) != yajl_gen_status_ok)
                {
                    enc->error = enif_make_atom(enc->env,
                                                "failed_to_close_empty_map");
                    return ERROR;
                }
                return OK;
            }
            else if(enif_get_list_cell(enc->env, tuple[0], &head, &tail))
            {
                return enc_map(enc, head, tail);
            }
        }
    }

    enc->error = enif_make_tuple(enc->env, 2,
        enif_make_atom(enc->env, "badarg"),
        term
    );
    return ERROR;
}
示例#22
0
jsval
to_js(ErlNifEnv* env, JSContext* cx, ERL_NIF_TERM term)
{
    int intval;
    unsigned int uintval;
    long longval;
    unsigned long ulongval;
    double doubleval;
    ERL_NIF_TERM head;
    ERL_NIF_TERM tail;
    const ERL_NIF_TERM* tuple;
    int arity;
    
    if(enif_is_atom(env, term))
    {
        return to_js_special(env, cx, term);
    }
    
    if(enif_is_binary(env, term))
    {
        return to_js_string(env, cx, term);
    }
    
    if(enif_is_empty_list(env, term))
    {
        return to_js_empty_array(cx);
    }
    
    if(enif_get_int(env, term, &intval))
    {
        return to_js_number(cx, (double) intval);
    }
    
    if(enif_get_uint(env, term, &uintval))
    {
        return to_js_number(cx, (double) uintval);
    }
    
    if(enif_get_long(env, term, &longval))
    {
        return to_js_number(cx, (double) longval);
    }
    
    if(enif_get_ulong(env, term, &ulongval))
    {
        return to_js_number(cx, (double) ulongval);
    }
    
    if(enif_get_double(env, term, &doubleval))
    {
        return to_js_number(cx, doubleval);
    }
    
	// enif doesn't seem to have any API to decode bignums, so use lower-level functions:
	if(is_big(term) && big_to_double(term, &doubleval) == 0)
	{
		return to_js_number(cx, doubleval);
	}

    if(enif_get_list_cell(env, term, &head, &tail))
    {
        return to_js_array(env, cx, head, tail);
    }
    
    if(enif_get_tuple(env, term, &arity, &tuple))
    {
        if(arity == 1)
        {
            return to_js_object(env, cx, tuple[0]);
        }
    }

    return JSVAL_VOID;
}