You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
4.2 KiB

  1. /* Created 07/March/2004 Chandrashekhar Mullaparthi
  2. $Id: ibrowse_drv.c,v 1.1 2005/05/05 22:28:28 chandrusf Exp $
  3. Erlang Linked in driver to URL encode a set of data
  4. */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include "erl_driver.h"
  9. static ErlDrvData ibrowse_drv_start(ErlDrvPort port, char* buff);
  10. static void ibrowse_drv_stop(ErlDrvData handle);
  11. static void ibrowse_drv_command(ErlDrvData handle, char *buff, int bufflen);
  12. static void ibrowse_drv_finish(void);
  13. static int ibrowse_drv_control(ErlDrvData handle, unsigned int command,
  14. char* buf, int count, char** res, int res_size);
  15. /* The driver entry */
  16. static ErlDrvEntry ibrowse_driver_entry = {
  17. NULL, /* init, N/A */
  18. ibrowse_drv_start, /* start, called when port is opened */
  19. ibrowse_drv_stop, /* stop, called when port is closed */
  20. NULL, /* output, called when erlang has sent */
  21. NULL, /* ready_input, called when input descriptor
  22. ready */
  23. NULL, /* ready_output, called when output
  24. descriptor ready */
  25. "ibrowse_drv", /* char *driver_name, the argument
  26. to open_port */
  27. NULL, /* finish, called when unloaded */
  28. NULL, /* void * that is not used (BC) */
  29. ibrowse_drv_control, /* control, port_control callback */
  30. NULL, /* timeout, called on timeouts */
  31. NULL, /* outputv, vector output interface */
  32. NULL,
  33. NULL,
  34. NULL, /* call, synchronous call to driver */
  35. NULL
  36. };
  37. typedef struct ibrowse_drv_data {
  38. unsigned int count;
  39. void *alloc_ptr;
  40. } State;
  41. static State *ibrowse_drv_data;
  42. DRIVER_INIT(ibrowse_drv)
  43. {
  44. ibrowse_drv_data = NULL;
  45. return &ibrowse_driver_entry;
  46. }
  47. static ErlDrvData ibrowse_drv_start(ErlDrvPort port, char *buff)
  48. {
  49. State *state;
  50. state = driver_alloc(sizeof(State));
  51. state->count = 0;
  52. state->alloc_ptr = NULL;
  53. ibrowse_drv_data = state;
  54. return ((ErlDrvData) state);
  55. }
  56. void ibrowse_drv_stop(ErlDrvData desc)
  57. {
  58. return;
  59. }
  60. static int ibrowse_drv_control(ErlDrvData handle, unsigned int command,
  61. char *buf, int bufflen, char **rbuf, int rlen)
  62. {
  63. State* state = (State *) handle;
  64. unsigned int j = 0, i = 0;
  65. unsigned int temp = 0, rlen_1 = 0;
  66. char* replybuf;
  67. fprintf(stderr, "alloc_ptr -> %d\n", state->alloc_ptr);
  68. /* if(state->alloc_ptr != NULL) */
  69. /* { */
  70. /* driver_free(state->alloc_ptr); */
  71. /* } */
  72. /* Calculate encoded length. If same as bufflen, it means there is
  73. no encoding to do. Do return an empty list */
  74. rlen_1 = calc_encoded_length(buf, bufflen);
  75. if(rlen_1 == bufflen)
  76. {
  77. *rbuf = NULL;
  78. state->alloc_ptr = NULL;
  79. return 0;
  80. }
  81. *rbuf = driver_alloc(rlen_1);
  82. state->alloc_ptr = *rbuf;
  83. fprintf(stderr, "*rbuf -> %d\n", *rbuf);
  84. replybuf = *rbuf;
  85. for(i=0;i<bufflen;i++)
  86. {
  87. temp = buf[i];
  88. if( 'a' <= temp && temp <= 'z'
  89. || 'A' <= temp && temp <= 'Z'
  90. || '0' <= temp && temp <= '9'
  91. || temp == '-' || temp == '_' || temp == '.' )
  92. {
  93. replybuf[j++] = temp;
  94. /* printf("j -> %d\n", j); */
  95. }
  96. else
  97. {
  98. replybuf[j++] = 37;
  99. /* printf("temp -> %d\n", temp);
  100. printf("d2h(temp >> 4) -> %d\n", d2h(temp >> 4));
  101. printf("d2h(temp & 15) -> %d\n", d2h(temp & 15)); */
  102. replybuf[j++] = d2h(temp >> 4);
  103. replybuf[j++] = d2h(temp & 15);
  104. /* printf("j -> %d\n", j); */
  105. }
  106. }
  107. return rlen_1;
  108. }
  109. /* Calculates the length of the resulting buffer if a string is URL encoded */
  110. int calc_encoded_length(char* buf, int bufflen)
  111. {
  112. unsigned int count=0, i=0, temp=0;
  113. for(i=0;i<bufflen;i++)
  114. {
  115. temp = buf[i];
  116. if( 'a' <= temp && temp <= 'z'
  117. || 'A' <= temp && temp <= 'Z'
  118. || '0' <= temp && temp <= '9'
  119. || temp == '-' || temp == '_' || temp == '.' )
  120. {
  121. count++;
  122. }
  123. else
  124. {
  125. count = count+3;
  126. }
  127. }
  128. return count;
  129. }
  130. /* Converts an integer in the range 1-15 into it's ascii value
  131. 1 -> 49 (ascii value of 1)
  132. 10 -> 97 (ascii value of a)
  133. */
  134. int d2h(unsigned int i)
  135. {
  136. if( i < 10 )
  137. {
  138. return i + 48;
  139. }
  140. else
  141. {
  142. return i + 97 - 10;
  143. }
  144. }