int gt_close(GtFileP file) { tcsetattr(file->fd, TCSADRAIN, &file->oldtio); int ret = close(file->fd); driver_free(file); return ret; }
// create shader program from vertex and fragment components, either one is // optional GLuint gl_create_program(char *vertex_file, char *fragment_file, char *name) { GLint status = GL_FALSE; GLuint program = glCreateProgram(); GLuint vshader, fshader; if(vertex_file) { char *vs = read_source(vertex_file); if(vs == 0) { glDeleteProgram(program); return 0; } vshader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vshader, 1, &vs, NULL); driver_free(vs); glCompileShader(vshader); printShaderInfoLog(vshader, "vertex"); glAttachShader(program, vshader); } if(fragment_file) { char *fs = read_source(fragment_file); if(fs == 0) { if(vertex_file) glDeleteShader(vshader); glDeleteProgram(program); return 0; } fshader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fshader, 1, &fs, NULL); driver_free(fs); glCompileShader(fshader); printShaderInfoLog(fshader, "fragment"); glAttachShader(program, fshader); } glLinkProgram(program); printProgramInfoLog(program, name); glGetProgramiv(program, GL_LINK_STATUS, &status); if(status != GL_TRUE) { if(vertex_file) glDeleteShader(vshader); if(fragment_file) glDeleteShader(fshader); glDeleteProgram(program); return 0; } return program; }
static void egd_drv_stop(ErlDrvData handle) { egd_data* d = (egd_data*)handle; image_destroy(d); driver_free((char*)handle); }
static void reg_from_erlang(ErlDrvData clientData, char* buf, ErlDrvSizeT count) { RegPort* rp = (RegPort *) clientData; int cmd; HKEY hkey; LONG result; DWORD nameSize; DWORD type; /* Type of data in buffer. */ DWORD valueSize; /* Size of value buffer. */ cmd = buf[0]; buf++, count--; switch (cmd) { case CMD_GET_CURRENT: state_reply(rp, rp->hkey_root, rp->key, rp->key_size); break; case CMD_OPEN_KEY: { char* key; HKEY newKey; /* * [HKEY(DWORD), KeyString(string)] */ hkey = (HKEY) get_int32(buf+0); rp->hkey_root = hkey; key = buf+4; result = RegOpenKeyEx(hkey, key, 0, rp->sam, &newKey); if (result == ERROR_SUCCESS) { RegCloseKey(rp->hkey); rp->hkey = newKey; driver_free(rp->key); rp->key_size = strlen(key); rp->key = driver_alloc(rp->key_size+1); strcpy(rp->key, key); } reply(rp, result); return; } break; case CMD_CREATE_KEY: { char* key; HKEY newKey; DWORD disposition; hkey = (HKEY) get_int32(buf+0); rp->hkey_root = hkey; key = buf+4; result = RegCreateKeyEx(hkey, key, 0, "", 0, rp->sam, NULL, &newKey, &disposition); if (result == ERROR_SUCCESS) { RegCloseKey(rp->hkey); rp->hkey = newKey; driver_free(rp->key); rp->key_size = strlen(key); rp->key = driver_alloc(rp->key_size+1); strcpy(rp->key, key); } reply(rp, result); return; } break; case CMD_GET_ALL_SUBKEYS: { int i; i = 0; for (;;) { nameSize = rp->name_buf_size; result = RegEnumKeyEx(rp->hkey, i, rp->name_buf, &nameSize, NULL, NULL, NULL, NULL); if (result == ERROR_MORE_DATA) { rp->name_buf_size *= 2; rp->name_buf = driver_realloc(rp->name_buf, rp->name_buf_size); continue; } else if (result == ERROR_NO_MORE_ITEMS) { reply(rp, ERROR_SUCCESS); return; } else if (result != ERROR_SUCCESS) { reply(rp, result); return; } key_reply(rp, rp->name_buf, nameSize); i++; } } break; case CMD_GET_VALUE: do { valueSize = rp->value_buf_size; result = RegQueryValueEx(rp->hkey, buf, NULL, &type, rp->value_buf, &valueSize); } while (!fix_value_result(rp, result, type, buf, strlen(buf), rp->value_buf, valueSize)); break; case CMD_GET_ALL_VALUES: { int i; i = 0; for (;;) { nameSize = rp->name_buf_size; valueSize = rp->value_buf_size; result = RegEnumValue(rp->hkey, i, rp->name_buf, &nameSize, NULL, &type, rp->value_buf, &valueSize); if (result == ERROR_NO_MORE_ITEMS) { reply(rp, ERROR_SUCCESS); return; } if (fix_value_result(rp, result, type, rp->name_buf, nameSize, rp->value_buf, valueSize)) { i++; } } } break; case CMD_SET_VALUE: { LPSTR name; DWORD dword; /* * [Type(DWORD), Name(string), Value(bytes)] */ type = get_int32(buf); buf += 4; count -= 4; name = buf; nameSize = strlen(buf) + 1; buf += nameSize; count -= nameSize; if (type == REG_DWORD) { /* * Must pass a pointer to a DWORD in host byte order. */ dword = get_int32(buf); buf = (char *) &dword; ASSERT(count == 4); } result = RegSetValueEx(rp->hkey, name, 0, type, buf, (DWORD)count); reply(rp, result); } break; case CMD_DELETE_KEY: result = RegDeleteKey(rp->hkey, NULL); reply(rp, result); break; case CMD_DELETE_VALUE: result = RegDeleteValue(rp->hkey, buf); reply(rp, result); break; } /* return 1; */ }
wxETreeItemData::~wxETreeItemData() { driver_free(bin); }
// Called by the emulator when the driver is stopping. static void stop_driver(ErlDrvData drv_data) { driver_free(drv_data); };
static void enm_finish() { driver_free(enm_sockets); }
void testcase_drv_stop(ErlDrvData drv_data) { testcase_cleanup((TestCaseState_t *) drv_data); driver_free((void *) drv_data); }
void testcase_free(void *ptr) { driver_free(ptr); }
void dterm_finish(dterm_t* p) { if (p->base != p->data) driver_free(p->base); dterm_reset_links(p); }
void dterm_free(dterm_t* p) { dterm_finish(p); if (p->dyn_alloc) driver_free(p); }
static void free_s(char* s) { driver_free(s); }
static ErlDrvSSizeT call(ErlDrvData edd, unsigned int cmd, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen, unsigned int *flags) { dnssd_drv_t* dd = (dnssd_drv_t*) edd; int version, out_len, index, rindex, local_only; DNSServiceErrorType err; char* out_atom_text; ei_term arg, name, type, domain, txt, host, hostport; char *name_tmp, *type_tmp, *domain_tmp, *txt_tmp, *host_tmp; /* don't allow reuse */ if (dd->sd_ref) return -1; index = 0; dd->sd_ref = NULL; ei_decode_version(buf, &index, &version); ei_decode_ei_term(buf, &index, &arg); if (cmd == DNSSD_CMD_ENUM) { if (arg.ei_type == ERL_ATOM_EXT) { if (strncmp(arg.value.atom_name, "browse", 6) == 0) { // init for enum browse err = DNSServiceEnumerateDomains(&dd->sd_ref, kDNSServiceFlagsBrowseDomains, kDNSServiceInterfaceIndexAny, (DNSServiceDomainEnumReply) EnumReply, dd); } else if (strncmp(arg.value.atom_name,"reg", 3) == 0) { // init for enum reg err = DNSServiceEnumerateDomains(&dd->sd_ref, kDNSServiceFlagsRegistrationDomains, kDNSServiceInterfaceIndexAny, (DNSServiceDomainEnumReply) EnumReply, dd); } else { goto badarg; } } else { goto badarg; } } else if (cmd == DNSSD_CMD_BROWSE) { if (!arg.ei_type == ERL_TUPLE || arg.arity != 2) goto badarg; /* decode type */ ei_decode_ei_term(buf, &index, &type); if (type.ei_type != ERL_BINARY_EXT) goto badarg; index += 5; // skip tag + 4 byte size type_tmp = (char*)driver_alloc(type.size + 1); memset(type_tmp, 0, type.size + 1); memcpy(type_tmp, buf + index, type.size); index += type.size; /* decode domain */ ei_decode_ei_term(buf, &index, &domain); if (domain.ei_type != ERL_BINARY_EXT) { driver_free(type_tmp); goto badarg; } index += 5; // skip tag + 4 byte size domain_tmp = (char *) driver_alloc(domain.size + 1); memset(domain_tmp, 0, domain.size + 1); memcpy(domain_tmp, buf + index, domain.size); err = DNSServiceBrowse(&dd->sd_ref, 0, // Flags kDNSServiceInterfaceIndexAny, type_tmp, domain_tmp, (DNSServiceBrowseReply) BrowseReply, dd); driver_free(type_tmp); driver_free(domain_tmp); } else if (cmd == DNSSD_CMD_RESOLVE) { if (!arg.ei_type == ERL_TUPLE || arg.arity != 3) goto badarg; /* decode name */ ei_decode_ei_term(buf, &index, &name); if (name.ei_type != ERL_BINARY_EXT) goto badarg; index += 5; // skip tag + 4 byte size name_tmp = (char *) driver_alloc(name.size + 1); memset(name_tmp, 0, name.size + 1); memcpy(name_tmp, buf + index, name.size); index += name.size; /* decode type */ ei_decode_ei_term(buf, &index, &type); if (type.ei_type != ERL_BINARY_EXT) { driver_free(name_tmp); goto badarg; } index += 5; // skip tag + 4 byte size type_tmp = (char *) driver_alloc(type.size + 1); memset(type_tmp, 0, type.size + 1); memcpy(type_tmp, buf + index, type.size); index += type.size; /* decode domain */ ei_decode_ei_term(buf, &index, &domain); if (domain.ei_type != ERL_BINARY_EXT) { driver_free(name_tmp); driver_free(type_tmp); goto badarg; } index += 5; // skip tag + 4 byte size domain_tmp = (char *) driver_alloc(domain.size + 1); memset(domain_tmp, 0, domain.size + 1); memcpy(domain_tmp, buf + index, domain.size); /* start op */ err = DNSServiceResolve(&dd->sd_ref, 0, // Flags kDNSServiceInterfaceIndexAny, name_tmp, type_tmp, domain_tmp, (DNSServiceResolveReply) ResolveReply, dd); driver_free(name_tmp); driver_free(type_tmp); driver_free(domain_tmp); } else if (cmd == DNSSD_CMD_REGISTER) { if (!arg.ei_type == ERL_TUPLE || arg.arity != 6) goto badarg; /* decode name */ ei_decode_ei_term(buf, &index, &name); if (name.ei_type != ERL_BINARY_EXT) goto badarg; index += 5; // skip tag + 4 byte size name_tmp = (char *) driver_alloc(name.size + 1); memset(name_tmp, 0, name.size + 1); memcpy(name_tmp, buf + index, name.size); index += name.size; /* decode type */ ei_decode_ei_term(buf, &index, &type); if (type.ei_type != ERL_BINARY_EXT) { driver_free(name_tmp); goto badarg; } index += 5; // skip tag + 4 byte size type_tmp = (char *) driver_alloc(type.size + 1); memset(type_tmp, 0, type.size + 1); memcpy(type_tmp, buf + index, type.size); index += type.size; /* decode domain */ ei_decode_ei_term(buf, &index, &domain); if (domain.ei_type != ERL_BINARY_EXT) { driver_free(name_tmp); driver_free(type_tmp); goto badarg; } index += 5; // skip tag + 4 byte size domain_tmp = (char *) driver_alloc(domain.size + 1); memset(domain_tmp, 0, domain.size + 1); memcpy(domain_tmp, buf + index, domain.size); index += domain.size; /* decode host */ ei_decode_ei_term(buf, &index, &host); if (host.ei_type != ERL_BINARY_EXT) { driver_free(name_tmp); driver_free(type_tmp); driver_free(domain_tmp); goto badarg; } index += 5; // skip tag + 4 byte size host_tmp = (char *) driver_alloc(host.size + 1); memset(host_tmp, 0, host.size + 1); memcpy(host_tmp, buf + index, host.size); index += host.size; /* decode port */ ei_decode_ei_term(buf, &index, &hostport); if (hostport.ei_type != ERL_INTEGER_EXT && hostport.ei_type != ERL_SMALL_INTEGER_EXT) { driver_free(name_tmp); driver_free(type_tmp); driver_free(domain_tmp); driver_free(host_tmp); goto badarg; } /* decode txt */ ei_decode_ei_term(buf, &index, &txt); if (txt.ei_type != ERL_BINARY_EXT) { driver_free(name_tmp); driver_free(type_tmp); driver_free(domain_tmp); driver_free(host_tmp); goto badarg; } index += 5; // skip tag + 4 byte size txt_tmp = (char *) driver_alloc(txt.size + 1); memset(txt_tmp, 0, txt.size + 1); memcpy(txt_tmp, buf + index, txt.size); local_only = (0 == strcmp("localhost", host_tmp)); err = DNSServiceRegister(&dd->sd_ref, 0, // Flags local_only ? -1 : 0, // Interface: local / any name_tmp, type_tmp, local_only ? "local" : domain_tmp, host_tmp, htons(hostport.value.i_val), txt.size, txt_tmp, (DNSServiceRegisterReply) RegisterReply, dd); driver_free(name_tmp); driver_free(type_tmp); driver_free(domain_tmp); driver_free(host_tmp); driver_free(txt_tmp); } else { goto badarg; } rindex = 0; out_len = 0; ei_encode_version(NULL, &out_len); if (err == kDNSServiceErr_NoError) { #ifdef __WIN32__ dd->event = WSACreateEvent(); WSAEventSelect(DNSServiceRefSockFD(dd->sd_ref), dd->event, FD_READ); driver_select(dd->erl_port, dd->event, ERL_DRV_READ, 1); #else driver_select(dd->erl_port, (ErlDrvEvent)(size_t) DNSServiceRefSockFD(dd->sd_ref), ERL_DRV_READ, 1); #endif out_atom_text = "ok"; ei_encode_atom(NULL, &out_len, out_atom_text); if(rlen < out_len) { *rbuf = driver_alloc(out_len); rlen = out_len; } ei_encode_version(*rbuf, &rindex); ei_encode_atom(*rbuf, &rindex, out_atom_text); return out_len; } else { out_atom_text = "error"; ei_encode_tuple_header(NULL, &out_len, 2); ei_encode_atom(NULL, &out_len, out_atom_text); ei_encode_long(NULL, &out_len, 1337); if(rlen < out_len) { *rbuf = driver_alloc(out_len); rlen = out_len; } ei_encode_version(*rbuf, &rindex); ei_encode_tuple_header(*rbuf, &rindex, 2); ei_encode_atom(*rbuf, &rindex, out_atom_text); ei_encode_long(*rbuf, &rindex, (long) err); return out_len; } badarg: return -1; }
// function ehecatl_driver_stop, stops the erlang port-driver static void ehecatl_driver_stop(ErlDrvData handle) { driver_free((char*)handle); }
static void echo_drv_stop(EchoDrvData *data_p) { driver_free(data_p); }
// Driver Stop static void stop(ErlDrvData handle) { bdb_drv_t* driver_data = (bdb_drv_t*) handle; driver_data->db->close(driver_data->db, 0); driver_free(driver_data); }
void free_error(spidermonkey_state *state) { driver_free(state->error->offending_source); driver_free(state->error->msg); driver_free(state->error); state->error = NULL; }
static void iconv_erl_stop(ErlDrvData handle) { driver_free((char*)handle); }
static void stop(ErlDrvData handle) { baberl_drv_t* driver_data = (baberl_drv_t*) handle; driver_free(driver_data); }
static ErlDrvSSizeT iconv_erl_control(ErlDrvData drv_data, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen) { int i; int size; int index = 0; int avail; size_t inleft, outleft; ErlDrvBinary *b; char *from, *to, *string, *stmp, *rstring, *rtmp; iconv_t cd; int invalid_utf8_as_latin1 = 0; ei_decode_version(buf, &index, &i); ei_decode_tuple_header(buf, &index, &i); ei_get_type(buf, &index, &i, &size); from = driver_alloc(size + 1); ei_decode_string(buf, &index, from); ei_get_type(buf, &index, &i, &size); to = driver_alloc(size + 1); ei_decode_string(buf, &index, to); ei_get_type(buf, &index, &i, &size); stmp = string = driver_alloc(size + 1); ei_decode_string(buf, &index, string); /* 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) { cd = iconv_open("ascii", "ascii"); if (cd == (iconv_t) -1) { *rbuf = (char*)(b = driver_alloc_binary(size)); memcpy(b->orig_bytes, string, size); driver_free(from); driver_free(to); driver_free(string); return size; } } outleft = avail = 4*size; inleft = size; rtmp = rstring = driver_alloc(avail); 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--; } }
static void example_drv_stop(ErlDrvData handle) { driver_free((char*)handle); }
static void expat_erl_stop(ErlDrvData handle) { XML_ParserFree(((expat_data *)handle)->parser); driver_free((char*)handle); }
static void iconvdrv_stop(ErlDrvData drv_data) { t_iconvdrv *iv = (t_iconvdrv*) drv_data; driver_free(iv); }
static void yaws_sendfile_drv_stop(ErlDrvData handle) { Desc* d = (Desc*)handle; hashtable_destroy(d->xfer_table, 1); driver_free(d); }
wxeFifo::~wxeFifo() { // dealloc all memory buffers driver_free(m_q); }
void rdma_drv_buffers_free(RdmaDrvBuffers *buffers) { if (buffers->buffers) { driver_free(buffers->buffers); buffers->buffers = NULL; } }
static void stop(ErlDrvData drv_data) { driver_free((void *) drv_data); }
static void zlib_free(void* data, void* addr) { driver_free(addr); }
static int control(ErlDrvData handle, unsigned int command, char* buf, int count, char** res, int res_size) { tcbdb_drv_t *driver = (tcbdb_drv_t*)handle; TCBDB *bdb = driver->bdb; int index = 1, tp, sz, version; char key[MAX_KEY_SIZE], value[MAX_VALUE_SIZE]; long key_size, value_size; long long long_tmp; bool rs; const char *value_tmp = NULL; ei_x_buff x; ei_x_new_with_version(&x); if (bdb == NULL && command != OPEN) return ei_error(&x, "database_not_opened", res, res_size); ei_decode_version(buf, &index, &version); switch (command) { case OPEN: // open(Filepath::string()) if (bdb == NULL) { ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_STRING_EXT) return ei_error(&x, "invalid_argument", res, res_size); TCBDB *bdb = tcbdbnew(); tcbdbsetmutex(bdb); tcbdbsetcache(bdb, 104800, 51200); tcbdbsetxmsiz(bdb, 1048576); tcbdbtune(bdb, 0, 0, 0, 7, -1, BDBTLARGE); char *file = driver_alloc(sz + 1); ei_decode_string(buf, &index, file); rs = tcbdbopen(bdb, file, BDBOWRITER | BDBOCREAT); driver_free(file); if (!rs) return ei_error(&x, tcbdberrmsg(tcbdbecode(bdb)), res, res_size); driver->bdb = bdb; ei_x_encode_atom(&x, "ok"); } else return ei_error(&x, "database already opened", res, res_size); break; case CLOSE: tcbdbclose(bdb); tcbdbdel(bdb); driver->bdb = NULL; ei_x_encode_atom(&x, "ok"); break; case PUT: case PUTDUP: case PUTCAT: case PUTKEEP: // put({Key::binary(), Value::binary()}) ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_SMALL_TUPLE_EXT || sz != 2) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_tuple_header(buf, &index, &sz); ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_BINARY_EXT || sz > MAX_KEY_SIZE) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_binary(buf, &index, &key[0], &key_size); ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_BINARY_EXT) return ei_error(&x, "invalid_argument", res, res_size); if (sz <= MAX_VALUE_SIZE) { ei_decode_binary(buf, &index, &value[0], &value_size); switch (command) { case PUT: rs = tcbdbput(bdb, &key[0], key_size, &value[0], value_size); break; case PUTDUP: rs = tcbdbputdup(bdb, &key[0], key_size, &value[0], value_size); break; case PUTCAT: rs = tcbdbputcat(bdb, &key[0], key_size, &value[0], value_size); break; default: rs = tcbdbputkeep(bdb, &key[0], key_size, &value[0], value_size); } } else { void *p = driver_alloc(sz); if (p) { ei_decode_binary(buf, &index, p, &value_size); switch (command) { case PUT: rs = tcbdbput(bdb, &key[0], key_size, p, value_size); break; case PUTDUP: rs = tcbdbputdup(bdb, &key[0], key_size, p, value_size); break; case PUTCAT: rs = tcbdbputcat(bdb, &key[0], key_size, p, value_size); break; default: rs = tcbdbputkeep(bdb, &key[0], key_size, p, value_size); } driver_free(p); } else return ei_error(&x, "too long value", res, res_size); }; if (!rs) return ei_error(&x, tcbdberrmsg(tcbdbecode(bdb)), res, res_size); ei_x_encode_atom(&x, "ok"); break; case GET: // get(Key::binary()) -> {ok, Value} | {error, not_found} ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_BINARY_EXT || sz > MAX_KEY_SIZE) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_binary(buf, &index, &key[0], &key_size); value_tmp = tcbdbget3(bdb, &key[0], key_size, &sz); ei_x_encode_tuple_header(&x, 2); if (value_tmp != NULL) { ei_x_encode_atom(&x, "ok"); ei_x_encode_binary(&x, value_tmp, sz); } else { ei_x_encode_atom(&x, "error"); ei_x_encode_atom(&x, "not_found"); } break; case GETDUP: // get(Key::binary()) -> {ok, Values} ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_BINARY_EXT || sz > MAX_KEY_SIZE) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_binary(buf, &index, &key[0], &key_size); TCLIST *vals = tcbdbget4(bdb, key, key_size); if (vals) { ei_x_encode_tuple_header(&x, 2); ei_x_encode_atom(&x, "ok"); int j; for (j=0; j<tclistnum(vals); j++) { value_tmp = tclistval(vals, j, &sz); ei_x_encode_list_header(&x, 1); ei_x_encode_binary(&x, value_tmp, sz); } tclistdel(vals); ei_x_encode_empty_list(&x); } else { ei_x_encode_tuple_header(&x, 2); ei_x_encode_atom(&x, "ok"); ei_x_encode_empty_list(&x); } break; case REMOVE: // remove(Keys::list()) // remove(Key::binary()) // remove({Key::binary(), Value::binary()}) ei_get_type(buf, &index, &tp, &sz); if (tp == ERL_LIST_EXT) { int count, j; ei_decode_list_header(buf, &index, &count); for (j=0; j<count; j++) { ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_BINARY_EXT || sz > MAX_KEY_SIZE) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_binary(buf, &index, &key[0], &key_size); if (!tcbdbout3(bdb, &key[0], key_size)) return ei_error(&x, tcbdberrmsg(tcbdbecode(bdb)), res, res_size); } ei_x_encode_atom(&x, "ok"); } else if (tp == ERL_BINARY_EXT && sz <= MAX_KEY_SIZE) { ei_decode_binary(buf, &index, &key[0], &key_size); tcbdbout3(bdb, &key[0], key_size); ei_x_encode_atom(&x, "ok"); } else if (tp == ERL_SMALL_TUPLE_EXT && sz == 2) { ei_decode_tuple_header(buf, &index, &sz); // get key ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_BINARY_EXT || sz > MAX_KEY_SIZE) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_binary(buf, &index, &key[0], &key_size); // get value ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_BINARY_EXT || sz > MAX_VALUE_SIZE) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_binary(buf, &index, &value[0], &value_size); // remove by key&value BDBCUR *cur = tcbdbcurnew(bdb); if (!tcbdbcurjump(cur, &key[0], key_size)) return ei_error(&x, "record_not_found", res, res_size); bool removed = false, not_found = false; while (!removed && !not_found) { int cur_key_size, cur_val_size; const void *curkey = tcbdbcurkey3(cur, &cur_key_size); if (cur_key_size == key_size && memcmp(curkey, key, key_size) == 0) { const void *curval = tcbdbcurval3(cur, &cur_val_size); if (cur_val_size == value_size && memcmp(curval, value, value_size) == 0) { tcbdbcurout(cur); removed = true; } else if (!tcbdbcurnext(cur)) not_found = true; } else not_found = true; } if (not_found) ei_x_encode_atom(&x, "not_found"); else ei_x_encode_atom(&x, "ok"); } else return ei_error(&x, "invalid_argument", res, res_size); break; case RANGE: /* * range({Prefix::binary(), limit:integer()}) * range({StartKey::binary(), BeginInclusion::boolean(), EndKey::binary(), EndInclusion::binary(), limit:integer()}) */ ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_SMALL_TUPLE_EXT || sz < 2) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_tuple_header(buf, &index, &sz); ei_get_type(buf, &index, &tp, &sz); if (tp == ERL_BINARY_EXT && sz <= MAX_KEY_SIZE) { char keys[MAX_KEY_SIZE], keyf[MAX_KEY_SIZE]; long keys_size, keyf_size; int keys_inc, keyf_inc; long max = -1; TCLIST *range; ei_decode_binary(buf, &index, &keys[0], &keys_size); ei_get_type(buf, &index, &tp, &sz); if (tp == ERL_ATOM_EXT) { // range ei_decode_boolean(buf, &index, &keys_inc); ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_BINARY_EXT || sz > MAX_KEY_SIZE) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_binary(buf, &index, &keyf[0], &keyf_size); ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_ATOM_EXT) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_boolean(buf, &index, &keyf_inc); ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_INTEGER_EXT) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_long(buf, &index, &max); range = tcbdbrange(bdb, &keys[0], keys_size, keys_inc == 1, &keyf[0], keyf_size, keyf_inc == 1, max); } else if (tp == ERL_INTEGER_EXT) { // prefix ei_get_type(buf, &index, &tp, &sz); if (tp != ERL_INTEGER_EXT) return ei_error(&x, "invalid_argument", res, res_size); ei_decode_long(buf, &index, &max); range = tcbdbfwmkeys(bdb, &keys[0], keys_size, max); } else return ei_error(&x, "invalid_argument", res, res_size); const char *key; int key_size, value_size; int idx, cnt = 0, rcount = tclistnum(range); ei_x_encode_tuple_header(&x, 2); ei_x_encode_atom(&x, "ok"); BDBCUR *cur = tcbdbcurnew(bdb); for (idx=0; idx<rcount; idx++) { key = tclistval(range, idx, &key_size); TCLIST *vals = tcbdbget4(bdb, key, key_size); if (vals) { int j; for (j=0; j<tclistnum(vals); j++) { ei_x_encode_list_header(&x, 1); value_tmp = tclistval(vals, j, &value_size); ei_x_encode_binary(&x, value_tmp, value_size); if (max >= 0 && ++cnt >= max) break; } tclistdel(vals); } idx++; } tcbdbcurdel(cur); tclistdel(range); ei_x_encode_empty_list(&x); } else return ei_error(&x, "invalid_argument", res, res_size); break; case SYNC: // sync() if (!tcbdbsync(bdb)) return ei_error(&x, tcbdberrmsg(tcbdbecode(bdb)), res, res_size); ei_x_encode_atom(&x, "ok"); break; case INFO: // info() ei_x_encode_tuple_header(&x, 3); ei_x_encode_atom(&x, "ok"); long_tmp = tcbdbrnum(bdb); ei_x_encode_longlong(&x, long_tmp); long_tmp = tcbdbfsiz(bdb); ei_x_encode_longlong(&x, long_tmp); break; case ITERATE: // Read(none) -> {ok, Key} | {error, not_found} // Read(Key::binary()) -> {ok, Key} | {error, not_found} ei_get_type(buf, &index, &tp, &sz); BDBCUR *cur = tcbdbcurnew(bdb); if (tp == ERL_BINARY_EXT && sz <= MAX_KEY_SIZE) { ei_decode_binary(buf, &index, &key[0], &key_size); rs = tcbdbcurjump(cur, &key[0], key_size) && tcbdbcurnext(cur); } else rs = tcbdbcurfirst(cur); if (rs) { int key_size; const char *key = tcbdbcurkey3(cur, &key_size); ei_x_encode_tuple_header(&x, 2); ei_x_encode_atom(&x, "ok"); ei_x_encode_binary(&x, key, key_size); tcbdbcurdel(cur); } else { tcbdbcurdel(cur); return ei_error(&x, "not_found", res, res_size); } break; case VANISH: // vanish() -> ok if (!tcbdbvanish(bdb)) return ei_error(&x, tcbdberrmsg(tcbdbecode(bdb)), res, res_size); ei_x_encode_atom(&x, "ok"); break; case BACKUP: // backup(path::string()) -> ok | {error, Reason} ei_get_type(buf, &index, &tp, &sz); if (tp == ERL_STRING_EXT) { char *file = driver_alloc(sz + 1); ei_decode_string(buf, &index, file); if (tcbdbcopy(driver->bdb, file)) ei_x_encode_atom(&x, "ok"); else return ei_error(&x, tcbdberrmsg(tcbdbecode(bdb)), res, res_size); } else return ei_error(&x, "invalid_argument", res, res_size); break; default: return ei_error(&x, "invalid_command", res, res_size); } if (res_size < x.index) (*res) = (char *)driver_alloc(x.index); int n = x.index; memcpy(*res, x.buff, x.index); ei_x_free(&x); return n; };
int erl_tess_impl(char* buff, ErlDrvPort port, ErlDrvTermData caller) { ErlDrvBinary* bin; int i; GLdouble* new_vertices; int *vertices; int num_vertices; GLdouble *n; int n_pos, AP, res; num_vertices = * (int *) buff; buff += 8; /* Align */ n = (double *) buff; buff += 8*3; bin = driver_alloc_binary(num_vertices*6*sizeof(GLdouble)); new_vertices = tess_coords = (double *) bin->orig_bytes; memcpy(tess_coords,buff,num_vertices*3*sizeof(GLdouble)); tess_alloc_vertex = tess_coords + num_vertices*3; #if 0 fprintf(stderr, "n=%d\r\n", num_vertices); #endif vertices = (int *) driver_alloc(sizeof(int) * 16*num_vertices); tess_vertices = vertices; gluTessNormal(tess, n[0], n[1], n[2]); gluTessBeginPolygon(tess, 0); gluTessBeginContour(tess); for (i = 0; i < num_vertices; i++) { gluTessVertex(tess, tess_coords+3*i, tess_coords+3*i); } gluTessEndContour(tess); gluTessEndPolygon(tess); n_pos = (tess_vertices - vertices); AP = 0; ErlDrvTermData *rt; rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData) * (13+n_pos*2)); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); for(i=0; i < n_pos; i++) { rt[AP++] = ERL_DRV_INT; rt[AP++] = (int) vertices[i]; }; rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = n_pos+1; rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) bin; rt[AP++] = (tess_alloc_vertex-new_vertices)*sizeof(GLdouble); rt[AP++] = 0; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Return tuple {list, Bin} rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Result tuple res = driver_send_term(port,caller,rt,AP); /* fprintf(stderr, "List %d: %d %d %d \r\n", */ /* res, */ /* n_pos, */ /* (tess_alloc_vertex-new_vertices)*sizeof(GLdouble), */ /* num_vertices*6*sizeof(GLdouble)); */ driver_free_binary(bin); driver_free(vertices); driver_free(rt); return 0; }