static ERL_NIF_TERM nif_pcap_stats(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { EWPCAP_STATE *ep = NULL; struct pcap_stat ps = {0}; if (!enif_get_resource(env, argv[0], EWPCAP_RESOURCE, (void **)&ep) || ep->p == NULL) return enif_make_badarg(env); if (pcap_stats(ep->p, &ps)) return enif_make_tuple2(env, atom_error, enif_make_string(env, pcap_geterr(ep->p), ERL_NIF_LATIN1)); return enif_make_tuple2(env, atom_ok, enif_make_tuple5(env, atom_ewpcap_stat, enif_make_uint(env, ps.ps_recv), enif_make_uint(env, ps.ps_drop), enif_make_uint(env, ps.ps_ifdrop), #ifdef WIN32 enif_make_uint(env, ps.bs_capt) #else enif_make_uint(env, 0) #endif )); }
static ERL_NIF_TERM make_error(ErlNifEnv* env, yaml_parser_t *parser) { ERL_NIF_TERM err; switch (parser->error) { case YAML_MEMORY_ERROR: err = enif_make_atom(env, "memory_error"); break; case YAML_PARSER_ERROR: err = enif_make_tuple4(env, enif_make_atom(env, "parser_error"), make_binary(env, (const unsigned char*) parser->problem), enif_make_uint(env, parser->problem_mark.line), enif_make_uint(env, parser->problem_mark.column)); break; case YAML_SCANNER_ERROR: err = enif_make_tuple4(env, enif_make_atom(env, "scanner_error"), make_binary(env, (const unsigned char*) parser->problem), enif_make_uint(env, parser->problem_mark.line), enif_make_uint(env, parser->problem_mark.column)); break; default: err = enif_make_atom(env, "unexpected_error"); break; } return enif_make_tuple2(env, enif_make_atom(env, "error"), err); }
static ERL_NIF_TERM size_of(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { /* size(Matrix) -> {Nrows, Ncols} */ mx_t mx; if (!enif_get_resource(env, argv[0], resource_type, &mx.vp)) { return enif_make_badarg(env); } return enif_make_tuple2(env, enif_make_uint(env, mx.p->nrows), enif_make_uint(env, mx.p->ncols)); }
static ERL_NIF_TERM mem_read(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { unsigned int err, l, i, tmp; char element; int ar; char* ptr; ERL_NIF_TERM list, head, *tpl; err = enif_get_tuple(env, argv[0], &ar, (const ERL_NIF_TERM**)(&tpl)); if (err) { err = nifty_get_ptr(env, tpl[0], (ptr_t*)&ptr); } if (!err) { goto error; } err = enif_get_uint(env, argv[1], &l); if (!err) { goto error; } list = enif_make_list(env, 0); for (i=0;i<l;i++) { element = (char)*(ptr+(l-1)-i); tmp = element & 0xff; head = enif_make_uint(env, tmp); list = enif_make_list_cell(env, head, list); } return list; error: return enif_make_badarg(env); }
static ERL_NIF_TERM keyboard_event_to_map(ErlNifEnv* env, SDL_Event* event, ERL_NIF_TERM map) { enif_make_map_put(env, map, atom_window_id, enif_make_uint(env, event->key.windowID), &map); enif_make_map_put(env, map, atom_state, event->key.state == SDL_RELEASED ? atom_released : atom_pressed, &map); enif_make_map_put(env, map, atom_repeat, event->key.repeat == 0 ? atom_false : atom_true, &map); enif_make_map_put(env, map, atom_scancode, enif_make_uint(env, event->key.keysym.scancode), &map); enif_make_map_put(env, map, atom_sym, enif_make_int(env, event->key.keysym.sym), &map); enif_make_map_put(env, map, atom_mod, keymod_flags_to_list(env, event->key.keysym.mod), &map); return map; }
static ERL_NIF_TERM read_info_nif(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { posix_errno_t posix_errno; efile_fileinfo_t info = {0}; efile_path_t path; int follow_links; if(argc != 2 || !enif_get_int(env, argv[1], &follow_links)) { return enif_make_badarg(env); } if((posix_errno = efile_marshal_path(env, argv[0], &path))) { return posix_error_to_tuple(env, posix_errno); } else if((posix_errno = efile_read_info(&path, follow_links, &info))) { return posix_error_to_tuple(env, posix_errno); } /* #file_info as declared in file.hrl */ return enif_make_tuple(env, 14, am_file_info, enif_make_uint64(env, info.size), efile_filetype_to_atom(info.type), efile_access_to_atom(info.access), enif_make_int64(env, MAX(EFILE_MIN_FILETIME, info.a_time)), enif_make_int64(env, MAX(EFILE_MIN_FILETIME, info.m_time)), enif_make_int64(env, MAX(EFILE_MIN_FILETIME, info.c_time)), enif_make_uint(env, info.mode), enif_make_uint(env, info.links), enif_make_uint(env, info.major_device), enif_make_uint(env, info.minor_device), enif_make_uint(env, info.inode), enif_make_uint(env, info.uid), enif_make_uint(env, info.gid) ); }
ERL_NIF_TERM entry_to_term(ErlNifEnv *env, const git_index_entry *entry) { ErlNifBinary id, path; size_t len; if (geef_oid_bin(&id, &entry->id) < 0) return geef_oom(env); len = strlen(entry->path); if (!enif_alloc_binary(len, &path)) { enif_release_binary(&id); return geef_oom(env); } memcpy(path.data, entry->path, len); return enif_make_tuple(env, 13, atoms.ok, enif_make_int64(env, entry->ctime.seconds), enif_make_int64(env, entry->mtime.seconds), enif_make_uint(env, entry->dev), enif_make_uint(env, entry->ino), enif_make_uint(env, entry->mode), enif_make_uint(env, entry->uid), enif_make_uint(env, entry->gid), enif_make_int64(env, entry->file_size), enif_make_binary(env, &id), enif_make_uint(env, entry->flags), enif_make_uint(env, entry->flags_extended), enif_make_binary(env, &path)); }
static ERL_NIF_TERM mouse_wheel_event_to_map(ErlNifEnv* env, SDL_Event* event, ERL_NIF_TERM map) { enif_make_map_put(env, map, atom_window_id, enif_make_uint(env, event->wheel.windowID), &map); enif_make_map_put(env, map, atom_which, (event->wheel.which == SDL_TOUCH_MOUSEID) ? atom_touch : enif_make_uint(env, event->wheel.which), &map); enif_make_map_put(env, map, atom_x, enif_make_int(env, event->wheel.x), &map); enif_make_map_put(env, map, atom_y, enif_make_int(env, event->wheel.y), &map); enif_make_map_put(env, map, atom_direction, mousewheel_direction_to_atom(event->wheel.direction), &map); return map; }
static int test_uint(ErlNifEnv* env, unsigned i1) { unsigned i2 = 0; ERL_NIF_TERM int_term = enif_make_uint(env, i1); if (!enif_get_uint(env,int_term, &i2) || i1 != i2) { fprintf(stderr, "test_uint(%u) ...FAILED i2=%u\r\n", i1, i2); return 0; } return 1; }
ERL_NIF_TERM geef_index_count(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { geef_index *index; if (!enif_get_resource(env, argv[0], geef_index_type, (void **) &index)) return enif_make_badarg(env); return enif_make_uint(env, git_index_entrycount(index->index)); }
static ERL_NIF_TERM weight_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { unsigned long long input; unsigned int ret; if (!enif_get_uint64(env, argv[0], &input)) { return enif_make_badarg(env); } ret = weight(input); return enif_make_uint(env, ret); }
static ERL_NIF_TERM window_event_to_map(ErlNifEnv* env, SDL_Event* event, ERL_NIF_TERM map) { enif_make_map_put(env, map, atom_window_id, enif_make_uint(env, event->window.windowID), &map); enif_make_map_put(env, map, atom_event, window_event_to_atom(event->window.event), &map); enif_make_map_put(env, map, atom_data1, enif_make_int(env, event->window.data1), &map); enif_make_map_put(env, map, atom_data2, enif_make_int(env, event->window.data2), &map); return map; }
static ERL_NIF_TERM mouse_button_event_to_map(ErlNifEnv* env, SDL_Event* event, ERL_NIF_TERM map) { enif_make_map_put(env, map, atom_window_id, enif_make_uint(env, event->button.windowID), &map); enif_make_map_put(env, map, atom_which, (event->button.which == SDL_TOUCH_MOUSEID) ? atom_touch : enif_make_uint(env, event->button.which), &map); enif_make_map_put(env, map, atom_button, button_to_atom(event->button.button), &map); enif_make_map_put(env, map, atom_state, event->button.state == SDL_RELEASED ? atom_released : atom_pressed, &map); enif_make_map_put(env, map, atom_clicks, enif_make_uint(env, event->button.clicks), &map); enif_make_map_put(env, map, atom_x, enif_make_int(env, event->button.x), &map); enif_make_map_put(env, map, atom_y, enif_make_int(env, event->button.y), &map); return map; }
static ERL_NIF_TERM mouse_motion_event_to_map(ErlNifEnv* env, SDL_Event* event, ERL_NIF_TERM map) { enif_make_map_put(env, map, atom_window_id, enif_make_uint(env, event->motion.windowID), &map); enif_make_map_put(env, map, atom_which, (event->motion.which == SDL_TOUCH_MOUSEID) ? atom_touch : enif_make_uint(env, event->motion.which), &map); enif_make_map_put(env, map, atom_state, mouse_state_to_list(env, event->motion.state), &map); enif_make_map_put(env, map, atom_x, enif_make_int(env, event->motion.x), &map); enif_make_map_put(env, map, atom_y, enif_make_int(env, event->motion.y), &map); enif_make_map_put(env, map, atom_xrel, enif_make_int(env, event->motion.xrel), &map); enif_make_map_put(env, map, atom_yrel, enif_make_int(env, event->motion.yrel), &map); return map; }
ERL_NIF_TERM erlang_murmurhash2_1_impl(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary bin; uint32_t h; if (!check_and_unpack_data(env, argv[0], &bin)) { return enif_make_badarg(env); } h = MurmurHash2(bin.data, bin.size, 0); return enif_make_uint(env, h); }
static ERL_NIF_TERM nif_constant(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { char buf[255] = {0}; const struct SERCTL_DEF *p = NULL; if (enif_get_atom(env, argv[0], buf, sizeof(buf), ERL_NIF_LATIN1) < 1) return enif_make_badarg(env); for (p = serctl_const; p->key != NULL; p++) { if (!strcmp(buf, p->key)) return enif_make_uint(env, p->val); } return atom_undefined; }
static ERL_NIF_TERM xfer2_1(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { int status, val, i; struct spi_ioc_transfer xfer; uint8_t *txbuf, *rxbuf; unsigned int length; ERL_NIF_TERM cell, head, tail, res, list; if (state.fd == -1) return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, "device closed", ERL_NIF_LATIN1)); if (argc != 1 || !enif_is_list(env, argv[0])) return enif_make_badarg(env); if (!enif_get_list_length(env, argv[0], &length)) return enif_make_badarg(env); txbuf = (uint8_t *) enif_alloc(sizeof(uint8_t) * length); rxbuf = (uint8_t *) enif_alloc(sizeof(uint8_t) * length); list = argv[0]; for (i = 0; enif_get_list_cell(env, list, &head, &tail); ++i, list = tail) { if (!enif_get_int(env, head, &val)) { return enif_make_badarg(env); } txbuf[i] = val; } xfer.tx_buf = (unsigned long) txbuf; xfer.rx_buf = (unsigned long) rxbuf; xfer.len = length; status = ioctl(state.fd, SPI_IOC_MESSAGE(1), &xfer); if (status < 0) { enif_free(txbuf); enif_free(rxbuf); return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_string(env, "spi ioc message", ERL_NIF_LATIN1)); } list = enif_make_list(env, 0); for (i = length - 1; i >= 0; --i) { cell = enif_make_uint(env, (unsigned int) rxbuf[i]); list = enif_make_list_cell(env, cell, list); } res = enif_make_tuple2(env, enif_make_atom(env, "ok"), list); enif_free(txbuf); enif_free(rxbuf); return res; }
ERL_NIF_TERM erlang_murmurhash3_x86_32_2_impl(ErlNifEnv* env, int, const ERL_NIF_TERM argv[]) { ErlNifBinary bin; uint32_t h; uint32_t seed; if (!check_and_unpack_data(env, argv[0], &bin)) { return enif_make_badarg(env); } if (!enif_get_uint(env, argv[1], &seed)) { return enif_make_badarg(env); } MurmurHash3_x86_32(bin.data, bin.size, seed, &h); return enif_make_uint(env, h); }
ERL_NIF_TERM as_ldt_lset_size(ErlNifEnv* env, handle_t* handle, void* obj) { ldt_get_args_t* args = (ldt_get_args_t*)obj; as_status res; as_error err; uint32_t nsize; res = aerospike_lset_size(&handle->instance, &err, &args->policy, &args->key, &args->ldt, &nsize); as_ldt_clean_get_args(env, args); if(res != AEROSPIKE_OK) return A_AS_ERROR(env, err); ERL_NIF_TERM returnValue; returnValue = enif_make_uint(env, nsize); return A_OK_VALUE(env, returnValue); }
ERL_NIF_TERM murmurhash_x86_32_impl(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary binary; uint32_t hash; uint32_t seed; // check for valid key arg if( !check_and_unpack_data(env, argv[0], &binary) ) { return enif_make_badarg(env); } // check for valid seed arg if( !enif_get_uint(env, argv[1], &seed) ) { return enif_make_badarg(env); } MurmurHash3_x86_32(binary.data, binary.size, seed, &hash); return enif_make_uint(env, hash); }
static ERL_NIF_TERM bf_encrypt(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary state; uint32_t i, k, m; uint16_t j; uint8_t ciphertext[4 * BCRYPT_WORDS] = "OrpheanBeholderScryDoubt"; uint32_t cdata[BCRYPT_WORDS]; ERL_NIF_TERM encrypted[4 * BCRYPT_WORDS]; /* Initialize our data from argv */ if (argc != 1 || !enif_inspect_binary(env, argv[0], &state)) return enif_make_badarg(env); /* This can be precomputed later */ j = 0; for (i = 0; i < BCRYPT_WORDS; i++) cdata[i] = Blowfish_stream2word(ciphertext, 4 * BCRYPT_WORDS, &j); /* Now do the encryption */ for (k = 0; k < 64; k++) blf_enc((blf_ctx *) state.data, cdata, BCRYPT_WORDS / 2); for (i = 0; i < BCRYPT_WORDS; i++) { ciphertext[4 * i + 3] = cdata[i] & 0xff; cdata[i] = cdata[i] >> 8; ciphertext[4 * i + 2] = cdata[i] & 0xff; cdata[i] = cdata[i] >> 8; ciphertext[4 * i + 1] = cdata[i] & 0xff; cdata[i] = cdata[i] >> 8; ciphertext[4 * i + 0] = cdata[i] & 0xff; } for (m = 0; m < BCRYPT_HASHLEN; m++) { encrypted[m] = enif_make_uint(env, ciphertext[m]); } secure_bzero(state.data, state.size); enif_release_binary(&state); secure_bzero(ciphertext, sizeof(ciphertext)); secure_bzero(cdata, sizeof(cdata)); return enif_make_list_from_array(env, encrypted, BCRYPT_HASHLEN); }
static ERL_NIF_TERM nif_socket_levels(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { const struct procket_define *p = NULL; ERL_NIF_TERM list = {0}; list = enif_make_list(env, 0); for (p = procket_socket_level; p->key != NULL; p++) { list = enif_make_list_cell( env, enif_make_tuple2( env, enif_make_atom(env, p->key), enif_make_uint(env, p->val) ), list); } return list; }
static ERL_NIF_TERM nif_constants(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { const struct SERCTL_DEF *p = NULL; ERL_NIF_TERM list = {0}; list = enif_make_list(env, 0); for (p = serctl_const; p->key != NULL; p++) { list = enif_make_list_cell( env, enif_make_tuple2( env, enif_make_atom(env, p->key), enif_make_uint(env, p->val) ), list); } return list; }
static ERL_NIF_TERM xfer_2(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { unsigned int channel, length; int result, i, val; uint8_t *buffer; ERL_NIF_TERM cell, head, tail, list; if (argc < 2 || !enif_is_number(env, argv[0]) || !enif_is_list(env, argv[1])) { return enif_make_badarg(env); } if (!enif_get_uint(env, argv[0], &channel) || channel < 0 || channel > 1) { return enif_make_badarg(env); } if (!enif_get_list_length(env, argv[1], &length) || length == 0) { return enif_make_badarg(env); } buffer = (uint8_t *) enif_alloc(sizeof(uint8_t) * length); list = argv[1]; for (i = 0; enif_get_list_cell(env, list, &head, &tail); ++i, list = tail) { if (!enif_get_int(env, head, &val)) { return enif_make_badarg(env); } buffer[i] = val; } result = wiringPiSPIDataRW(channel, buffer, length); if (result == -1) { result = errno; enif_free(buffer); return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_int(env, result)); } list = enif_make_list(env, 0); for (i = length - 1; i >= 0; --i) { cell = enif_make_uint(env, (unsigned int) buffer[i]); list = enif_make_list_cell(env, cell, list); } enif_free(buffer); return enif_make_tuple2(env, enif_make_atom(env, "ok"), list); }
ERL_NIF_TERM murmurhash_x86_128_impl(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary binary; uint32_t hash[4] = { 0, 0, 0, 0 }; uint32_t seed; ERL_NIF_TERM parts[4]; // check for valid key arg if( !check_and_unpack_data(env, argv[0], &binary) ) { return enif_make_badarg(env); } // check for valid seed arg if( !enif_get_uint(env, argv[1], &seed) ) { return enif_make_badarg(env); } MurmurHash3_x86_128(binary.data, binary.size, seed, &hash); for( int i = 0; i < 4; i++ ) { parts[i] = enif_make_uint(env, hash[i]); } return enif_make_list_from_array(env, parts, 4); }
static ERL_NIF_TERM make_error(yajl_handle handle, ErlNifEnv* env) { char* yajlError = (char*) yajl_get_error(handle, 0, NULL, 0); ERL_NIF_TERM errMsg; if(yajlError != NULL) { errMsg = enif_make_string(env, yajlError, ERL_NIF_LATIN1); yajl_free_error(handle, (unsigned char*) yajlError); } else { errMsg = enif_make_string(env, "unknown parse error", ERL_NIF_LATIN1); } return enif_make_tuple(env, 2, enif_make_atom(env, "error"), enif_make_tuple(env, 2, enif_make_uint(env, handle->bytesConsumed), errMsg ) ); }
static ERL_NIF_TERM get_config(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { return enif_make_list2(env, enif_make_tuple2(env, enif_make_string(env,"sizes", ERL_NIF_LATIN1), enif_make_tuple6(env, enif_make_uint(env, sizeof(short int)), enif_make_uint(env, sizeof(int)), enif_make_uint(env, sizeof(long int)), enif_make_uint(env, sizeof(long long int)), enif_make_uint(env, sizeof(float)), enif_make_uint(env, sizeof(double)))), enif_make_tuple2(env, enif_make_string(env, "arch", ERL_NIF_LATIN1), enif_make_tuple2(env, #ifdef ENV64BIT enif_make_string(env, "64bit", ERL_NIF_LATIN1), #endif #ifdef ENV32BIT enif_make_string(env, "32bit", ERL_NIF_LATIN1), #endif enif_make_uint(env, sizeof(char*))))); }
/* This undocumented function reads a pointer and then reads the data block * described by said pointer. It was reverse-engineered from the old * implementation so while all tests pass it may not be entirely correct. Our * current understanding is as follows: * * Pointer layout: * * <<Size:1/integer-unit:32, Offset:1/integer-unit:32>> * * Where Offset is the -absolute- address to the data block. * * *) If we fail to read the pointer block in its entirety, we return eof. * *) If the provided max_payload_size is larger than Size, we return eof. * *) If we fail to read any data whatsoever at Offset, we return * {ok, {Size, Offset, eof}} * *) Otherwise, we return {ok, {Size, Offset, Data}}. Note that the size * of Data may be smaller than Size if we encounter EOF before we could * read the entire block. * * On errors we'll return {error, posix()} regardless of whether they * happened before or after reading the pointer block. */ static ERL_NIF_TERM ipread_s32bu_p32bu_nif_impl(efile_data_t *d, ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { Sint64 payload_offset, payload_size; SysIOVec read_vec[1]; Sint64 bytes_read; ErlNifBinary payload; if(argc != 2 || !enif_is_number(env, argv[0]) || !enif_is_number(env, argv[1])) { return enif_make_badarg(env); } { Sint64 max_payload_size, pointer_offset; unsigned char pointer_block[8]; if(!enif_get_int64(env, argv[0], &pointer_offset) || !enif_get_int64(env, argv[1], &max_payload_size) || (pointer_offset < 0 || max_payload_size >= 1u << 31)) { return posix_error_to_tuple(env, EINVAL); } read_vec[0].iov_base = pointer_block; read_vec[0].iov_len = sizeof(pointer_block); bytes_read = efile_preadv(d, pointer_offset, read_vec, 1); if(bytes_read < 0) { return posix_error_to_tuple(env, d->posix_errno); } else if(bytes_read < sizeof(pointer_block)) { return am_eof; } payload_size = (Uint32)get_int32(&pointer_block[0]); payload_offset = (Uint32)get_int32(&pointer_block[4]); if(payload_size > max_payload_size) { return am_eof; } } if(!enif_alloc_binary(payload_size, &payload)) { return posix_error_to_tuple(env, ENOMEM); } read_vec[0].iov_base = payload.data; read_vec[0].iov_len = payload.size; bytes_read = efile_preadv(d, payload_offset, read_vec, 1); if(bytes_read < 0) { return posix_error_to_tuple(env, d->posix_errno); } else if(bytes_read == 0) { enif_release_binary(&payload); return enif_make_tuple2(env, am_ok, enif_make_tuple3(env, enif_make_uint(env, payload_size), enif_make_uint(env, payload_offset), am_eof)); } if(bytes_read < payload.size && !enif_realloc_binary(&payload, bytes_read)) { ERTS_INTERNAL_ERROR("Failed to shrink ipread payload."); } return enif_make_tuple2(env, am_ok, enif_make_tuple3(env, enif_make_uint(env, payload_size), enif_make_uint(env, payload_offset), enif_make_binary(env, &payload))); }
ERL_NIF_TERM blake2bp_hash(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; blake2b_state S[PARALLELISM_DEGREE][1]; blake2b_state FS[1]; ErlNifBinary input, key, salt, personal; uint8_t out[BLAKE2B_OUTBYTES] = {0}; unsigned int outlen; int i; ERL_NIF_TERM tmphash[BLAKE2B_OUTBYTES]; if (argc != 5 || !enif_inspect_binary(env, argv[0], &input) || !enif_inspect_binary(env, argv[1], &key) || !enif_get_uint(env, argv[2], &outlen) || !enif_inspect_binary(env, argv[3], &salt) || !enif_inspect_binary(env, argv[4], &personal)) return enif_make_badarg(env); if (!outlen || outlen > BLAKE2B_OUTBYTES) return -1; if( key.size > BLAKE2B_KEYBYTES ) return -1; for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2bp_init_leaf( S[i], outlen, key.size, i, salt.data, personal.data, salt.size, personal.size) < 0 ) return -1; S[PARALLELISM_DEGREE - 1]->last_node = 1; // mark last node if( key.size > 0 ) { uint8_t block[BLAKE2B_BLOCKBYTES]; memset( block, 0, BLAKE2B_BLOCKBYTES ); memcpy( block, key.data, key.size ); for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES ); secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ } #if defined(_OPENMP) #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE) #else for( size_t id__ = 0; id__ < PARALLELISM_DEGREE; ++id__ ) #endif { #if defined(_OPENMP) size_t id__ = omp_get_thread_num(); #endif uint64_t inlen__ = input.size; const uint8_t *in__ = ( const uint8_t * )input.data; in__ += id__ * BLAKE2B_BLOCKBYTES; while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) { blake2b_update( S[id__], in__, BLAKE2B_BLOCKBYTES ); in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; } if( inlen__ > id__ * BLAKE2B_BLOCKBYTES ) { const size_t left = inlen__ - id__ * BLAKE2B_BLOCKBYTES; const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES; blake2b_update( S[id__], in__, len ); } blake2b_final( S[id__], hash[id__], BLAKE2B_OUTBYTES ); } if( blake2bp_init_root( FS, outlen, key.size, salt.data, personal.data, salt.size, personal.size) < 0 ) return -1; FS->last_node = 1; // Mark as last node for( size_t i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES ); blake2b_final( FS, out, outlen );; for (i = 0; i < outlen; i++) { tmphash[i] = enif_make_uint(env, out[i]); } return enif_make_list_from_array(env, tmphash, outlen); }
ERL_NIF_TERM parse_buffer(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { Parser par; Parser* parser = ∥ ErlNifBinary buffer; if(!enif_inspect_binary(env, argv[0], &buffer)) return enif_make_badarg(env); if(!init_parser(parser, env, argv[0], &buffer, argv[1])) return enif_make_badarg(env); ERL_NIF_TERM reply = argv[2]; ERL_NIF_TERM return_value; parser->remaining_length = buffer.size; parser->pointer = buffer.data + parser->frame_start; while (parser->frame_start < parser->buffer_size) { parser->frame_size = D3I(parser->pointer); parser->pointer += 3; unsigned long seg_num = D1(parser->pointer); parser->pointer += 1; parser->remaining_length -= (parser->frame_size + 4); if (parser->remaining_length < 0) { return_value = enif_make_tuple3(env, parser->atoms->atom_incomplete, reply, enif_make_sub_binary(env, parser->raw, parser->frame_start, parser->buffer_size - parser->frame_start)); break; } if (*parser->pointer == MYSQL_RESP_EOF) { ERL_NIF_TERM remaining_buffer = enif_make_sub_binary(env, parser->raw, parser->frame_start + parser->frame_size + 4, parser->remaining_length); if (parser->frame_size == 5) { unsigned long server_status = D2I(parser->pointer + 3); return_value = enif_make_tuple5(env, parser->atoms->atom_eof, enif_make_uint(env, server_status), enif_make_uint(env, seg_num), reply, remaining_buffer); } else return_value = enif_make_tuple4(env, parser->atoms->atom_eof, enif_make_uint(env, seg_num), reply, remaining_buffer); break; } parser->frame_start += 4; ERL_NIF_TERM row = parse_line(parser); reply = enif_make_list_cell(env, row, reply); parser->frame_start += parser->frame_size; parser->pointer += parser->frame_size; } if (parser->frame_start >= parser->buffer_size) return_value = enif_make_tuple3(env, parser->atoms->atom_incomplete, reply, parser->atoms->atom_empty); destroy_parser(parser); return return_value; }