Пример #1
0
int gt_close(GtFileP file) {
    tcsetattr(file->fd, TCSADRAIN, &file->oldtio);
    int ret = close(file->fd);
    driver_free(file);
    return ret;
}
Пример #2
0
// 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;
}
Пример #3
0
static void egd_drv_stop(ErlDrvData handle) {
    egd_data* d = (egd_data*)handle;
    image_destroy(d);
    driver_free((char*)handle);
}
Пример #4
0
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; */
}
Пример #5
0
wxETreeItemData::~wxETreeItemData()
{
  driver_free(bin);
}
Пример #6
0
// Called by the emulator when the driver is stopping.
static void
stop_driver(ErlDrvData drv_data) {

    driver_free(drv_data);
};
Пример #7
0
static void
enm_finish()
{
    driver_free(enm_sockets);
}
Пример #8
0
void
testcase_drv_stop(ErlDrvData drv_data)
{
    testcase_cleanup((TestCaseState_t *) drv_data);
    driver_free((void *) drv_data);
}
Пример #9
0
void testcase_free(void *ptr)
{
    driver_free(ptr);
}
Пример #10
0
void dterm_finish(dterm_t* p)
{
    if (p->base != p->data)
	driver_free(p->base);
    dterm_reset_links(p);
}
Пример #11
0
void dterm_free(dterm_t* p)
{
    dterm_finish(p);
    if (p->dyn_alloc)
	driver_free(p);
}
Пример #12
0
static void free_s(char* s)
{
    driver_free(s);
}
Пример #13
0
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;
}
Пример #14
0
// function ehecatl_driver_stop, stops the erlang port-driver
static void ehecatl_driver_stop(ErlDrvData handle)
{
    driver_free((char*)handle);
}
Пример #15
0
static void echo_drv_stop(EchoDrvData *data_p) {
    driver_free(data_p);
}
Пример #16
0
// 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);
}
Пример #17
0
void free_error(spidermonkey_state *state) {
  driver_free(state->error->offending_source);
  driver_free(state->error->msg);
  driver_free(state->error);
  state->error = NULL;
}
Пример #18
0
static void iconv_erl_stop(ErlDrvData handle)
{
   driver_free((char*)handle);
}
Пример #19
0
static void stop(ErlDrvData handle) {
    baberl_drv_t* driver_data = (baberl_drv_t*) handle;
    driver_free(driver_data);
}
Пример #20
0
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);
}
Пример #22
0
static void expat_erl_stop(ErlDrvData handle)
{
   XML_ParserFree(((expat_data *)handle)->parser);
   driver_free((char*)handle);
}
Пример #23
0
static void iconvdrv_stop(ErlDrvData drv_data)
{
    t_iconvdrv *iv = (t_iconvdrv*) drv_data;
    driver_free(iv);
}
Пример #24
0
static void yaws_sendfile_drv_stop(ErlDrvData handle)
{
    Desc* d = (Desc*)handle;
    hashtable_destroy(d->xfer_table, 1);
    driver_free(d);
}
Пример #25
0
wxeFifo::~wxeFifo() {
  // dealloc all memory buffers
  driver_free(m_q);
}
Пример #26
0
void rdma_drv_buffers_free(RdmaDrvBuffers *buffers) {
    if (buffers->buffers) {
        driver_free(buffers->buffers);
        buffers->buffers = NULL;
    }
}
Пример #27
0
static void stop(ErlDrvData drv_data)
{
    driver_free((void *) drv_data);
}
Пример #28
0
static void zlib_free(void* data, void* addr)
{
    driver_free(addr);
}
Пример #29
0
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;
};
Пример #30
0
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;
}