/* Created 07/March/2004 Chandrashekhar Mullaparthi $Id: ibrowse_drv.c,v 1.1 2005/05/05 22:28:28 chandrusf Exp $ Erlang Linked in driver to URL encode a set of data */ #include #include #include #include "erl_driver.h" static ErlDrvData ibrowse_drv_start(ErlDrvPort port, char* buff); static void ibrowse_drv_stop(ErlDrvData handle); static void ibrowse_drv_command(ErlDrvData handle, char *buff, int bufflen); static void ibrowse_drv_finish(void); static int ibrowse_drv_control(ErlDrvData handle, unsigned int command, char* buf, int count, char** res, int res_size); /* The driver entry */ static ErlDrvEntry ibrowse_driver_entry = { NULL, /* init, N/A */ ibrowse_drv_start, /* start, called when port is opened */ ibrowse_drv_stop, /* stop, called when port is closed */ NULL, /* output, called when erlang has sent */ NULL, /* ready_input, called when input descriptor ready */ NULL, /* ready_output, called when output descriptor ready */ "ibrowse_drv", /* char *driver_name, the argument to open_port */ NULL, /* finish, called when unloaded */ NULL, /* void * that is not used (BC) */ ibrowse_drv_control, /* control, port_control callback */ NULL, /* timeout, called on timeouts */ NULL, /* outputv, vector output interface */ NULL, NULL, NULL, /* call, synchronous call to driver */ NULL }; typedef struct ibrowse_drv_data { unsigned int count; void *alloc_ptr; } State; static State *ibrowse_drv_data; DRIVER_INIT(ibrowse_drv) { ibrowse_drv_data = NULL; return &ibrowse_driver_entry; } static ErlDrvData ibrowse_drv_start(ErlDrvPort port, char *buff) { State *state; state = driver_alloc(sizeof(State)); state->count = 0; state->alloc_ptr = NULL; ibrowse_drv_data = state; return ((ErlDrvData) state); } void ibrowse_drv_stop(ErlDrvData desc) { return; } static int ibrowse_drv_control(ErlDrvData handle, unsigned int command, char *buf, int bufflen, char **rbuf, int rlen) { State* state = (State *) handle; unsigned int j = 0, i = 0; unsigned int temp = 0, rlen_1 = 0; char* replybuf; fprintf(stderr, "alloc_ptr -> %d\n", state->alloc_ptr); /* if(state->alloc_ptr != NULL) */ /* { */ /* driver_free(state->alloc_ptr); */ /* } */ /* Calculate encoded length. If same as bufflen, it means there is no encoding to do. Do return an empty list */ rlen_1 = calc_encoded_length(buf, bufflen); if(rlen_1 == bufflen) { *rbuf = NULL; state->alloc_ptr = NULL; return 0; } *rbuf = driver_alloc(rlen_1); state->alloc_ptr = *rbuf; fprintf(stderr, "*rbuf -> %d\n", *rbuf); replybuf = *rbuf; for(i=0;i %d\n", j); */ } else { replybuf[j++] = 37; /* printf("temp -> %d\n", temp); printf("d2h(temp >> 4) -> %d\n", d2h(temp >> 4)); printf("d2h(temp & 15) -> %d\n", d2h(temp & 15)); */ replybuf[j++] = d2h(temp >> 4); replybuf[j++] = d2h(temp & 15); /* printf("j -> %d\n", j); */ } } return rlen_1; } /* Calculates the length of the resulting buffer if a string is URL encoded */ int calc_encoded_length(char* buf, int bufflen) { unsigned int count=0, i=0, temp=0; for(i=0;i 49 (ascii value of 1) 10 -> 97 (ascii value of a) */ int d2h(unsigned int i) { if( i < 10 ) { return i + 48; } else { return i + 97 - 10; } }