|
|
@ -1,162 +0,0 @@ |
|
|
|
/* 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 <stdio.h> |
|
|
|
#include <stdlib.h> |
|
|
|
#include <string.h> |
|
|
|
#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<bufflen;i++) |
|
|
|
{ |
|
|
|
temp = buf[i]; |
|
|
|
if( 'a' <= temp && temp <= 'z' |
|
|
|
|| 'A' <= temp && temp <= 'Z' |
|
|
|
|| '0' <= temp && temp <= '9' |
|
|
|
|| temp == '-' || temp == '_' || temp == '.' ) |
|
|
|
{ |
|
|
|
replybuf[j++] = temp; |
|
|
|
/* printf("j -> %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<bufflen;i++) |
|
|
|
{ |
|
|
|
temp = buf[i]; |
|
|
|
if( 'a' <= temp && temp <= 'z' |
|
|
|
|| 'A' <= temp && temp <= 'Z' |
|
|
|
|| '0' <= temp && temp <= '9' |
|
|
|
|| temp == '-' || temp == '_' || temp == '.' ) |
|
|
|
{ |
|
|
|
count++; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
count = count+3; |
|
|
|
} |
|
|
|
} |
|
|
|
return count; |
|
|
|
} |
|
|
|
|
|
|
|
/* Converts an integer in the range 1-15 into it's ascii value |
|
|
|
1 -> 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; |
|
|
|
} |
|
|
|
} |