コード例 #1
0
ファイル: unix_prim_file.c プロジェクト: ebengt/otp
posix_errno_t efile_get_cwd(ErlNifEnv *env, ERL_NIF_TERM *result) {
    ErlNifBinary result_bin;
    size_t bytes_copied;

    if(!enif_alloc_binary(256, &result_bin)) {
        return ENOMEM;
    }

    while(getcwd((char*)result_bin.data, result_bin.size) == NULL) {
        posix_errno_t saved_errno = errno;

        if(saved_errno != ERANGE) {
            enif_release_binary(&result_bin);
            return saved_errno;
        } else {
            if(!enif_realloc_binary(&result_bin, result_bin.size * 2)) {
                enif_release_binary(&result_bin);
                return ENOMEM;
            }
        }
    }

    /* getcwd(2) guarantees null-termination. */
    bytes_copied = strlen((const char*)result_bin.data);

    if(!enif_realloc_binary(&result_bin, bytes_copied)) {
        enif_release_binary(&result_bin);
        return ENOMEM;
    }

    (*result) = enif_make_binary(env, &result_bin);

    return 0;
}
コード例 #2
0
ファイル: fix_parser_nifs.c プロジェクト: dmitryme/fix_engine
/*-----------------------------------------------------------------------------------------------------------------------*/
static ERL_NIF_TERM msg_to_binary(ErlNifEnv* env, int32_t argc, ERL_NIF_TERM const argv[])
{
   ERL_NIF_TERM parser_res;
   ERL_NIF_TERM msg_res;
   ParserRes* parser = NULL;
   FIXMsg* msg = NULL;
   ERL_NIF_TERM res = get_parser_msg(env, argv[0], &parser_res, &msg_res, &parser, &msg);
   if (res != ok_atom)
   {
      return res;
   }
   int32_t delimiter = 0;
   if (!enif_get_int(env, argv[1], &delimiter) || delimiter <= 0 || delimiter >= 255)
   {
      return make_error(env, FIX_FAILED, "Wrong delimiter.");
   }
   uint32_t reqBuffLen = DEF_BINARY_SIZE;
   ErlNifBinary bin;
   if (!enif_alloc_binary(reqBuffLen, &bin))
   {
      return make_error(env, FIX_FAILED, "Unable to allocate binary.");
   }
   FIXError* error = NULL;
   pthread_rwlock_rdlock(&parser->lock);
   if (FIX_FAILED == fix_msg_to_str(msg, (char)delimiter, (char*)bin.data, bin.size, &reqBuffLen, &error))
   {
      if (reqBuffLen > bin.size) // realloc needed
      {
         if (!enif_realloc_binary(&bin, reqBuffLen))
         {
            res = make_error(env, FIX_FAILED, "Unable to reallocate binary.");
         }
         if (FIX_FAILED == fix_msg_to_str(msg, (char)delimiter, (char*)bin.data, bin.size, &reqBuffLen, &error))
         {
            res = make_parser_error(env, fix_error_get_code(error), fix_error_get_text(error));
            fix_error_free(error);
         }
      }
      else
      {
         res = make_parser_error(env, fix_error_get_code(error), fix_error_get_text(error));
         fix_error_free(error);
      }
   }
   pthread_rwlock_unlock(&parser->lock);
   if (res != ok_atom)
   {
      enif_release_binary(&bin);
      return res;
   }
   if (bin.size > reqBuffLen)
   {
      enif_realloc_binary(&bin, reqBuffLen);
   }
   ERL_NIF_TERM bin_term = enif_make_binary(env, &bin);
   enif_release_binary(&bin);
   return enif_make_tuple2(env, ok_atom, bin_term);
}
コード例 #3
0
ファイル: prim_file_nif.c プロジェクト: cypherfox/otp
/** @brief Reads an entire file into \c result, stopping after \c size bytes or
 * EOF. It will read until EOF if size is 0. */
static posix_errno_t read_file(efile_data_t *d, size_t size, ErlNifBinary *result) {
    size_t initial_buffer_size;
    ssize_t bytes_read;

    if(size == 0) {
        initial_buffer_size = 16 << 10;
    } else {
        initial_buffer_size = size;
    }

    if(!enif_alloc_binary(initial_buffer_size, result)) {
        return ENOMEM;
    }

    bytes_read = 0;

    for(;;) {
        ssize_t block_bytes_read;
        SysIOVec read_vec[1];

        read_vec[0].iov_base = result->data + bytes_read;
        read_vec[0].iov_len = result->size - bytes_read;

        block_bytes_read = efile_readv(d, read_vec, 1);

        if(block_bytes_read < 0) {
            enif_release_binary(result);
            return d->posix_errno;
        }

        bytes_read += block_bytes_read;

        if(block_bytes_read < (result->size - bytes_read)) {
            /* EOF */
            break;
        } else if(bytes_read == size) {
            break;
        }

        if(!enif_realloc_binary(result, bytes_read * 2)) {
            enif_release_binary(result);
            return ENOMEM;
        }
    }

    /* The file may have shrunk since we queried its size, so we have to do
     * this even when the size is known. */
    if(bytes_read < result->size && !enif_realloc_binary(result, bytes_read)) {
        ERTS_INTERNAL_ERROR("Failed to shrink read_file result.");
    }

    return 0;
}
コード例 #4
0
ファイル: dh.c プロジェクト: KennethL/otp
ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{/* (OthersPublicKey, MyPrivateKey, DHParams=[P,G]) */
    BIGNUM *other_pub_key = NULL,
        *dh_p = NULL,
        *dh_g = NULL;
    DH *dh_priv = DH_new();

    /* Check the arguments and get
          my private key (dh_priv),
          the peer's public key (other_pub_key),
          the parameters p & q
    */

    {
        BIGNUM *dummy_pub_key = NULL,
               *priv_key = NULL;
        ERL_NIF_TERM head, tail;

        if (!get_bn_from_bin(env, argv[0], &other_pub_key)
            || !get_bn_from_bin(env, argv[1], &priv_key)
            || !enif_get_list_cell(env, argv[2], &head, &tail)
            || !get_bn_from_bin(env, head, &dh_p)
            || !enif_get_list_cell(env, tail, &head, &tail)
            || !get_bn_from_bin(env, head, &dh_g)
            || !enif_is_empty_list(env, tail)

            /* Note: DH_set0_key() does not allow setting only the
             * private key, although DH_compute_key() does not use the
             * public key. Work around this limitation by setting
             * the public key to a copy of the private key.
             */
            || !(dummy_pub_key = BN_dup(priv_key))
            || !DH_set0_key(dh_priv, dummy_pub_key, priv_key)
            || !DH_set0_pqg(dh_priv, dh_p, NULL, dh_g)
            ) {
            if (dh_p) BN_free(dh_p);
            if (dh_g) BN_free(dh_g);
            if (other_pub_key) BN_free(other_pub_key);
            if (dummy_pub_key) BN_free(dummy_pub_key);
            if (priv_key) BN_free(priv_key);
            return enif_make_badarg(env);
        }
    }
    {
        ErlNifBinary ret_bin;
        int size;

        enif_alloc_binary(DH_size(dh_priv), &ret_bin);
        size = DH_compute_key(ret_bin.data, other_pub_key, dh_priv);
        BN_free(other_pub_key);
        DH_free(dh_priv);
        if (size<=0) {
            enif_release_binary(&ret_bin);
            return atom_error;
        }

        if (size != ret_bin.size) enif_realloc_binary(&ret_bin, size);
        return enif_make_binary(env, &ret_bin);
    }
}
コード例 #5
0
ファイル: erlsha2_nif.c プロジェクト: T0ha/biten
static ERL_NIF_TERM
context_fini(ErlNifEnv* env, Context* ctx, size_t dsize, ChunkHandler handler)
{
    ERL_NIF_TERM result;
    ctx->bitlen += ctx->count*8;
    pad(0, 0, ctx);
    handler(ctx, ctx->bytes);
    if (ctx->count > ctx->size) {
        handler(ctx, ctx->bytes + ctx->size);
    }
#ifndef WORDS_BIGENDIAN
    {
        int i;
        if (ctx->size == PADDED_SIZE_2XX_BYTES) {
            uint32_t* hash = (uint32_t*)ctx->digest.data;
            for (i = 0; i < ctx->digest.size/sizeof(*hash); ++i) {
                hash[i] = BYTESWAP32(hash[i]);
            }
        } else {
            uint64_t* hash = (uint64_t*)ctx->digest.data;
            for (i = 0; i < ctx->digest.size/sizeof(*hash); ++i) {
                hash[i] = BYTESWAP64(hash[i]);
            }
        }
    }
#endif
    if (ctx->digest.size != dsize) {
        enif_realloc_binary(&ctx->digest, dsize);
    }
    result = enif_make_binary(env, &ctx->digest);
    ctx->digest.size = 0;
    return result;
}
コード例 #6
0
ファイル: ucrypto_ec.c プロジェクト: ahf/erlang-ucrypto
ERL_NIF_TERM ucrypto_ec_sign_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    unsigned int length;
    struct ec_key_handle *handle = NULL;
    ErlNifBinary data;
    ErlNifBinary signature;

    if (! enif_get_resource(env, argv[0], ec_key_resource, (void **)&handle))
        return enif_make_badarg(env);

    if (! enif_inspect_iolist_as_binary(env, argv[1], &data))
        return enif_make_badarg(env);

    if (! handle->key)
        return enif_make_tuple2(env, ATOM_ERROR, ATOM_UNINITIALIZED_KEY);

    length = ECDSA_size(handle->key);

    if (! enif_alloc_binary(length, &signature))
        return ATOM_ERROR;

    if (! ECDSA_sign(0, data.data, data.size, signature.data, &length, handle->key))
        return ATOM_ERROR;

    if (! enif_realloc_binary(&signature, length))
        return ATOM_ERROR;

    return enif_make_binary(env, &signature);
}
コード例 #7
0
ファイル: serctl.c プロジェクト: jj1bdx/srly
    static ERL_NIF_TERM
nif_ioctl(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    SRLY_STATE *sp = NULL;
    unsigned long req = 0;
    ErlNifBinary arg = {0};


    if (!enif_get_resource(env, argv[0], SRLY_STATE_RESOURCE, (void **)&sp))
        return enif_make_badarg(env);

    if (!enif_get_ulong(env, argv[1], &req))
        return enif_make_badarg(env);

    if (!enif_inspect_binary(env, argv[2], &arg))
        return enif_make_badarg(env);

    /* Make the binary mutable for in/out args */
    if (!enif_realloc_binary(&arg, arg.size))
        return error_tuple(env, ENOMEM);

    if (ioctl(sp->fd, req, arg.data) < 0)
        return error_tuple(env, errno);

    return enif_make_tuple2(env,
        atom_ok,
        enif_make_binary(env, &arg));
}
コード例 #8
0
ファイル: i18n_string.cpp プロジェクト: alepharchives/i18n
/**
 * NIFs
 */
inline void do_from_utf8(
    ErlNifBinary  in,
    ErlNifBinary& out, 
    int32_t& ulen,
    UErrorCode& status) 
{
    status = U_ZERO_ERROR;
    if (!enif_alloc_binary(FROM_ULEN(ulen), &out)) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }

    u_strFromUTF8(
        (UChar*) out.data,       /* dest */
        ulen,                    /* capacity */
        &ulen,                   /* len of result */
        (char*)   in.data,       /* src */
        (int32_t) in.size,       /* len of src */
        &status);                /* error code */

    if (U_FAILURE(status)) {
        enif_release_binary(&out);
        return;
    }

    if (FROM_ULEN(ulen) != out.size) {
        /* shrink binary if it was too large */
        enif_realloc_binary(&out, FROM_ULEN(ulen));
    }
}
コード例 #9
0
ファイル: procket.c プロジェクト: ExaServe/procket
    static ERL_NIF_TERM
nif_sendmsg(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    int s = -1;
    ErlNifBinary msg = {0};
    int flags = 0;

    ssize_t n = 0;

    if (!enif_get_int(env, argv[0], &s))
        return enif_make_badarg(env);

    if (!enif_inspect_binary(env, argv[1], &msg))
        return enif_make_badarg(env);

    if (!enif_get_int(env, argv[2], &flags))
        return enif_make_badarg(env);

    if (msg.size != sizeof(struct msghdr))
        return enif_make_badarg(env);

    /* Make the binary mutable */
    if (!enif_realloc_binary(&msg, msg.size))
        return error_tuple(env, ENOMEM);

    n = sendmsg(s, (const struct msghdr *)msg.data, flags);

    if (n < 0)
        return error_tuple(env, errno);

    return enif_make_tuple3(env,
            atom_ok,
            enif_make_ulong(env, n),
            enif_make_binary(env, &msg));
}
コード例 #10
0
ファイル: serctl.c プロジェクト: jj1bdx/srly
    static ERL_NIF_TERM
nif_open(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifBinary dev;
    SRLY_STATE *sp = NULL;

    if (!enif_inspect_iolist_as_binary(env, argv[0], (ErlNifBinary *)&dev))
        return enif_make_badarg(env);

    sp = enif_alloc_resource(SRLY_STATE_RESOURCE, sizeof(SRLY_STATE));
    if (sp == NULL)
        return error_tuple(env, ENOMEM);

    if (!enif_realloc_binary(&dev, dev.size+1))
        return enif_make_badarg(env);

    dev.data[dev.size-1] = '\0';

    sp->fd = open((char *)dev.data, O_RDWR|O_NOCTTY|O_NONBLOCK);

    if (sp->fd < 0 || isatty(sp->fd) != 1) {
        int err = errno;
        enif_release_resource(sp);
        return error_tuple(env, err);
    }

    return enif_make_tuple2(env,
            atom_ok,
            enif_make_resource(env, sp));
}
コード例 #11
0
ファイル: i18n_string.cpp プロジェクト: alepharchives/i18n
inline void do_to_title(
    ErlNifBinary  in,
    ErlNifBinary& out, 
    int32_t& ulen,
    UBreakIterator* iter,
    const char* locale,
    UErrorCode& status) 
{
    status = U_ZERO_ERROR;
    if (!enif_alloc_binary(FROM_ULEN(ulen), &out)) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    ulen = u_strToTitle(
            (UChar*) out.data,   /* src */
            ulen,                /* len of src */
            (UChar*) in.data, 
            TO_ULEN(in.size),
            iter,               /* Iterator */
            locale, 
            &status);

    if (status == U_BUFFER_OVERFLOW_ERROR) {
        /* enlarge buffer if it was too small */
        enif_release_binary(&out);
        return;
    }

    if (FROM_ULEN(ulen) != out.size) {
        /* shrink binary if it was too large */
        enif_realloc_binary(&out, FROM_ULEN(ulen));
    }
}
コード例 #12
0
ファイル: serctl.c プロジェクト: jj1bdx/srly
    static ERL_NIF_TERM
nif_read(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    SRLY_STATE *sp = NULL;
    unsigned long len = 0;

    ErlNifBinary buf = {0};
    ssize_t bufsz = 0;


    if (!enif_get_resource(env, argv[0], SRLY_STATE_RESOURCE, (void **)&sp))
        return enif_make_badarg(env);

    if (!enif_get_ulong(env, argv[1], &len))
        return enif_make_badarg(env);

    if (!enif_alloc_binary(len, &buf))
        return error_tuple(env, ENOMEM);

    if ( (bufsz = read(sp->fd, buf.data, buf.size)) < 0) {
        int err = errno;
        enif_release_binary(&buf);
        return error_tuple(env, err);
    }

    if (bufsz < buf.size && !enif_realloc_binary(&buf, bufsz)) {
        enif_release_binary(&buf);
        return error_tuple(env, ENOMEM);
    }

    return enif_make_tuple2(env, atom_ok, enif_make_binary(env, &buf));
}
コード例 #13
0
ファイル: i18n_string.cpp プロジェクト: alepharchives/i18n
inline void do_case(
    ErlNifBinary  in,
    ErlNifBinary& out, 
    int32_t& ulen,
    case_fun_ptr fun,
    const char* locale,
    UErrorCode& status) 
{
    status = U_ZERO_ERROR;
    if (!enif_alloc_binary(FROM_ULEN(ulen), &out)) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }
    ulen = fun(
            (UChar*) out.data,   /* src */
            ulen,                /* len of src */
            (UChar*) in.data, 
            TO_ULEN(in.size),
            locale, 
            &status);

    if (U_FAILURE(status)) {
        enif_release_binary(&out);
        return;
    }

    if (FROM_ULEN(ulen) != out.size) {
        /* shrink binary if it was too large */
        enif_realloc_binary(&out, FROM_ULEN(ulen));
    }
}
コード例 #14
0
ファイル: i18n_string.cpp プロジェクト: alepharchives/i18n
inline void do_to_utf8(
    ErlNifBinary  in,
    ErlNifBinary& out, 
    int32_t& len,
    UErrorCode& status) 
{
    status = U_ZERO_ERROR;
    if (!enif_alloc_binary(len, &out)) {
        status = U_MEMORY_ALLOCATION_ERROR;
        return;
    }

    u_strToUTF8( 
        (char*) out.data,  /* dest */
        len, 
        &len, 
        (const UChar*) in.data, /* src */
        TO_ULEN(in.size),       /* len of src */
        &status);

    if (U_FAILURE(status)) {
        enif_release_binary(&out);
        return;
    }

    if (len != (int32_t) out.size) {
        /* shrink binary if it was too large */
        enif_realloc_binary(&out, len);
    }
}
コード例 #15
0
ファイル: procket.c プロジェクト: alepharchives/procket
// int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
    static ERL_NIF_TERM
nif_getsockname(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    int s = -1;
    ErlNifBinary addr = {0};
    socklen_t addrlen = 0;


    if (!enif_get_int(env, argv[0], &s))
        return enif_make_badarg(env);

    if (!enif_inspect_binary(env, argv[1], &addr))
        return enif_make_badarg(env);

    /* Make the binary mutable */
    if (!enif_realloc_binary(&addr, addr.size))
        return error_tuple(env, ENOMEM);

    addrlen = addr.size;

    if (getsockname(s, (struct sockaddr *)addr.data, (socklen_t *)&addrlen) < 0)
        return error_tuple(env, errno);

    PROCKET_REALLOC(addr, addrlen);

    return enif_make_tuple2(env,
            atom_ok,
            enif_make_binary(env, &addr));
}
コード例 #16
0
ファイル: wpi.c プロジェクト: alepharchives/wpi
static ERL_NIF_TERM
spi_data_rw_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    int channel, len;
    ErlNifBinary buf;
    ERL_NIF_TERM atom_fail, err_code;

    if (!enif_get_int(env, argv[0], &channel) ||
        !enif_inspect_binary(env, argv[1], &buf) ||
        !enif_get_int(env, argv[2], &len))
    {
        return enif_make_badarg(env);
    }

    enif_realloc_binary(&buf, len);

    int result = wiringPiSPIDataRW(channel, buf.data, len);
    if (result >= 0) {
        return enif_make_tuple2(env,
                                atom_ok,
                                enif_make_binary(env, &buf));
    } else {
        atom_fail = enif_make_atom(env, "failed_to_read_write_data");
        err_code = enif_make_int(env, result);
        enif_release_binary(&buf);
        return enif_make_tuple2(env,
                                atom_error,
                                enif_make_tuple2(env, atom_fail, err_code));
    }
}
コード例 #17
0
ファイル: encoder.c プロジェクト: dixel/jsonx
static void
do_reserve(size_t sz, State *st){
    size_t used = st->cur - st->bin.data;
    size_t t = st->bin.size * 2;
    while( t < used + sz ){
      t *= 2;
    }
    enif_realloc_binary(&st->bin, t);
    st->cur = st->bin.data + used;
}
コード例 #18
0
ファイル: asn1_erl_nif.c プロジェクト: AxisOfEval/otp
static int per_realloc_memory(ErlNifBinary *binary, int amount, unsigned char **ptr) {

    int i = *ptr - binary->data;

    if (!enif_realloc_binary(binary, amount)) {
	/*error handling due to memory allocation failure */
	return ASN1_ERROR;
    } else {
	*ptr = binary->data + i;
    }
    return ASN1_OK;
}
コード例 #19
0
ファイル: cerck.c プロジェクト: alepharchives/cerck
/* 1: password, 2: dictpath */
static ERL_NIF_TERM
nif_check(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    PRIV *priv = NULL;

    ErlNifBinary passwd;
    ErlNifBinary path;

    char *err = NULL;


    priv = (PRIV *)enif_priv_data(env);

    if (!enif_inspect_iolist_as_binary(env, argv[0], &passwd))
        return enif_make_badarg(env);

    if (!enif_inspect_iolist_as_binary(env, argv[1], &path))
        return enif_make_badarg(env);

    /* NULL terminate strings */
    if (!enif_realloc_binary(&passwd, passwd.size+1))
        return atom_enomem;
    if (!enif_realloc_binary(&path, path.size+1))
        return atom_enomem;

    /* passwd.size is now equal to old passwd.size+1 */
    passwd.data[passwd.size-1] = '\0';
    path.data[path.size-1] = '\0';

    enif_mutex_lock(priv->lock);
    err = (char *)FascistCheck((char *)passwd.data, (char *)path.data);
    enif_mutex_unlock(priv->lock);

    (void)memset(passwd.data, '\0', passwd.size);

    enif_release_binary(&passwd);
    enif_release_binary(&path);

    return ( (err == NULL) ? atom_ok : error_tuple(env, err));
}
コード例 #20
0
ファイル: encoder.c プロジェクト: Gustav-Simonsson/jiffy
int
enc_result(Encoder* e, ERL_NIF_TERM* value)
{
    if(e->i != e->curr->size) {
        if(!enif_realloc_binary(e->curr, e->i)) {
            return 0;
        }
    }

    *value = enif_make_binary(e->env, e->curr);
    e->curr = NULL;
    return 1;
}
コード例 #21
0
ファイル: esnappy_nif.cpp プロジェクト: fdmanana/esnappy
    ErlNifBinary& GetBinary()
    {
        size_t allocated = bin.size;

        if (allocated > used) {
            if (!enif_realloc_binary(&bin, used)) {
                enif_release_binary(&bin);
                THROW_EXC("enif_realloc_binary() failed");
            }
        }

        return bin;
    }
コード例 #22
0
ファイル: unix_prim_file.c プロジェクト: ebengt/otp
posix_errno_t efile_read_link(ErlNifEnv *env, const efile_path_t *path, ERL_NIF_TERM *result) {
    ErlNifBinary result_bin;

    if(!enif_alloc_binary(256, &result_bin)) {
        return ENOMEM;
    }

    for(;;) {
        ssize_t bytes_copied;

        bytes_copied = readlink((const char*)path->data, (char*)result_bin.data,
            result_bin.size);

        if(bytes_copied <= 0) {
            posix_errno_t saved_errno = errno;
            enif_release_binary(&result_bin);
            return saved_errno;
        } else if(bytes_copied < result_bin.size) {
            if(!enif_realloc_binary(&result_bin, bytes_copied)) {
                enif_release_binary(&result_bin);
                return ENOMEM;
            }

            (*result) = enif_make_binary(env, &result_bin);

            return 0;
        }

        /* The result didn't fit into the buffer, so we'll try again with a
         * larger one. */

        if(!enif_realloc_binary(&result_bin, result_bin.size * 2)) {
            enif_release_binary(&result_bin);
            return ENOMEM;
        }
    }
}
コード例 #23
0
ファイル: win_prim_file.c プロジェクト: HansN/otp
/** @brief Converts a native path to the preferred form in "erlang space,"
 * without path-prefixes, forward-slashes, or NUL terminators. */
static int normalize_path_result(ErlNifBinary *path) {
    WCHAR *path_iterator, *path_start, *path_end;
    int length;

    path_start = (WCHAR*)path->data;
    length = wcslen(path_start);

    ASSERT(length < path->size / sizeof(WCHAR));

    /* Get rid of the long-path prefix, if present. */

    if(IS_LONG_UNC_PATH(length, path_start)) {
        /* The first two characters (\\) are the same for both long and short
         * UNC paths. */
        sys_memmove(&path_start[2], &path_start[LP_UNC_PREFIX_LENGTH],
            (length - LP_UNC_PREFIX_LENGTH) * sizeof(WCHAR));

        length -= LP_UNC_PREFIX_LENGTH - 2;
    } else if(IS_LONG_PATH(length, path_start)) {
        length -= LP_PREFIX_LENGTH;

        sys_memmove(path_start, &path_start[LP_PREFIX_LENGTH],
            length * sizeof(WCHAR));
    }

    path_end = &path_start[length];
    path_iterator = path_start;

    /* Convert drive letters to lowercase, if present. */
    if(length >= 2 && path_start[1] == L':') {
        WCHAR drive_letter = path_start[0];

        if(drive_letter >= L'A' && drive_letter <= L'Z') {
            path_start[0] = drive_letter - L'A' + L'a';
        }
    }

    while(path_iterator < path_end) {
        if(*path_iterator == L'\\') {
            *path_iterator = L'/';
        }

        path_iterator++;
    }

    /* Truncate the result to its actual length; we don't want to include the
     * NUL terminator. */
    return enif_realloc_binary(path, length * sizeof(WCHAR));
}
コード例 #24
0
ファイル: esnappy_nif.cpp プロジェクト: fdmanana/esnappy
    char* GetAppendBuffer(size_t len, char*)
    {
        size_t allocated = bin.size;

        if ((used + len) > allocated) {
            size_t sz = len > ALLOC_SIZE ? len + ALLOC_SIZE - (len % ALLOC_SIZE) : ALLOC_SIZE;

            if (!enif_realloc_binary(&bin, allocated + sz)) {
                enif_release_binary(&bin);
                THROW_EXC("enif_realloc_binary() failed");
            }
        }

        return reinterpret_cast<char*>(bin.data + used);
    }
コード例 #25
0
ファイル: rsync.c プロジェクト: zinid/erlang-rsync
static ERL_NIF_TERM patch_init(ErlNifEnv* env, int argc,
			       const ERL_NIF_TERM argv[])
{
  state_t *state = init_state();

  if (!enif_inspect_iolist_as_binary(env, argv[0], &state->bin))
    return enif_make_badarg(env);

  enif_realloc_binary(&state->bin, state->bin.size);
  state->job = rs_patch_begin((rs_copy_cb *) &read_callback, state);
  state->type = PATCH;
  ERL_NIF_TERM result = enif_make_resource(env, state);
  enif_release_resource(state);
  return result;
}
コード例 #26
0
ファイル: encoder.c プロジェクト: Gustav-Simonsson/jiffy
static inline int
enc_ensure(Encoder* e, size_t req)
{
    size_t need = e->curr->size;
    while(req >= (need - e->i)) need <<= 1;

    if(need != e->curr->size) {
        if(!enif_realloc_binary(e->curr, need)) {
            return 0;
        }
        e->p = (char*) e->curr->data;
        e->u = (unsigned char*) e->curr->data;
    }

    return 1;
}
コード例 #27
0
ファイル: wlfz_nif.c プロジェクト: Zabrane/wflz-erlang-nif
//--
static 
ERL_NIF_TERM 
nif_compress(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    ErlNifBinary input;

    if(!enif_inspect_iolist_as_binary(env, argv[0], &input)) 
    {
        return(enif_make_badarg(env));
    }

    ErlNifBinary bin;

    // [rad] Figure out maximum compression buffer size.
    uint32_t compressed_bytes = wfLZ_GetMaxCompressedSize(input.size);

    // [rad] Get size of recommended scratchpad.
    uint32_t scratchpad_bytes = wfLZ_GetWorkMemSize();

    if(!enif_alloc_binary(compressed_bytes, &bin))
    {
        return(erlang_produce_error(env, "not_enough_memory"));
    }

    // [rad] Allocate scratchpad buffer.
    uint8_t* scratchpad = malloc(scratchpad_bytes);

    // [rad] Perform compression.
    uint32_t data_comp_size = wfLZ_Compress((const uint8_t* const) input.data, input.size, (uint8_t* const) bin.data, (const uint8_t*) scratchpad, 0);
     
    // [rad] We no longer need scratchpad.
    free(scratchpad);

    if(!data_comp_size)
    {
        return(erlang_produce_error(env, "compression_error"));
    }

    if(!enif_realloc_binary(&bin, data_comp_size)) 
    {
        return(erlang_produce_error(env, "not_enough_memory"));
    }

    return(enif_make_binary(env, &bin));
}
コード例 #28
0
ファイル: win_prim_file.c プロジェクト: c-bik/otp
/** @brief Converts a native path to the preferred form in "erlang space,"
 * without path-prefixes, forward-slashes, or NUL terminators. */
static int normalize_path_result(ErlNifBinary *path) {
    WCHAR *path_iterator, *path_start, *path_end;
    int length;

    path_start = (WCHAR*)path->data;
    length = wcslen(path_start);

    ASSERT(length < path->size / sizeof(WCHAR));

    /* Get rid of the long-path prefix, if present. */
    if(length >= LP_PREFIX_LENGTH) {
        if(!sys_memcmp(path_start, LP_PREFIX, LP_PREFIX_SIZE)) {
            length -= LP_PREFIX_LENGTH;

            sys_memmove(path_start, &path_start[LP_PREFIX_LENGTH],
                length * sizeof(WCHAR));
        }
    }

    path_end = &path_start[length];
    path_iterator = path_start;

    /* Convert drive letters to lowercase, if present. */
    if(length >= 2 && path_start[1] == L':') {
        WCHAR drive_letter = path_start[0];

        if(drive_letter >= L'A' && drive_letter <= L'Z') {
            path_start[0] = drive_letter - L'A' + L'a';
        }
    }

    while(path_iterator < path_end) {
        if(*path_iterator == L'\\') {
            *path_iterator = L'/';
        }

        path_iterator++;
    }

    /* Truncate the result to its actual length; we don't want to include the
     * NUL terminator. */
    return enif_realloc_binary(path, length * sizeof(WCHAR));
}
コード例 #29
0
    static ERL_NIF_TERM
nif_pcap_compile(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
    EWPCAP_STATE *ep = NULL;
    ErlNifBinary filter = {0};
    int optimize = 0;
    u_int32_t netmask = 0;

    struct bpf_program fp = {0};


    if (!enif_get_resource(env, argv[0], EWPCAP_RESOURCE, (void **)&ep)
            || ep->p == NULL)
        return enif_make_badarg(env);

    if (!enif_inspect_iolist_as_binary(env, argv[1], &filter))
        return enif_make_badarg(env);

    if (!enif_get_int(env, argv[2], &optimize))
        return enif_make_badarg(env);

    if (!enif_get_uint(env, argv[3], &netmask))
        return enif_make_badarg(env);

    /* NULL terminate the filter */
    if (!enif_realloc_binary(&filter, filter.size+1))
        return enif_make_tuple2(env, atom_error, atom_enomem);

    filter.data[filter.size-1] = '\0';

    if (pcap_compile(ep->p, &fp, (const char *)filter.data,
                optimize, netmask) != 0)
        return enif_make_tuple2(env,
                atom_error,
                enif_make_string(env, pcap_geterr(ep->p), ERL_NIF_LATIN1));

    if (pcap_setfilter(ep->p, &fp) < 0)
        return enif_make_tuple2(env,
                atom_error,
                enif_make_string(env, pcap_geterr(ep->p), ERL_NIF_LATIN1));

    return atom_ok;
}
コード例 #30
0
ファイル: iconv.c プロジェクト: processone/iconv
static int do_convert(ErlNifEnv* env, char *from, char *to,
                      ErlNifBinary *string, ErlNifBinary *rstring)
{
    char *stmp = (char *) string->data;
    char *rtmp = (char *) rstring->data;
    size_t outleft = rstring->size;
    size_t inleft = string->size;
    int invalid_utf8_as_latin1 = 0;
    iconv_t cd;

    /* Special mode: parse as UTF-8 if possible; otherwise assume it's
      Latin-1.  Makes no difference when encoding. */
    if (strcmp(from, "utf-8+latin-1") == 0) {
        from[5] = '\0';
        invalid_utf8_as_latin1 = 1;
    }
    if (strcmp(to, "utf-8+latin-1") == 0) {
        to[5] = '\0';
    }
    cd = iconv_open(to, from);

    if (cd == (iconv_t) -1) {
        if (enif_realloc_binary(rstring, string->size)) {
            memcpy(rstring->data, string->data, string->size);
            return OK;
        } else {
            return ERR_MEMORY_FAIL;
        }
    }

    while (inleft > 0) {
        if (iconv(cd, &stmp, &inleft, &rtmp, &outleft) == (size_t) -1) {
            if (invalid_utf8_as_latin1 && (*stmp & 0x80) && outleft >= 2) {
                /* Encode one byte of (assumed) Latin-1 into two bytes of UTF-8 */
                *rtmp++ = 0xc0 | ((*stmp & 0xc0) >> 6);
                *rtmp++ = 0x80 | (*stmp & 0x3f);
                outleft -= 2;
            }
            stmp++;
            inleft--;
        }
    }