↑ 1 #include <string.h>
↑ 2 #include <stdlib.h>
↑ 3 #include <stdio.h>
↑ 4 #include "rh_buffer.h"
↑ 5 #include "rh_string.h"
↑ 6
↑ 7 #define MAP_WANT_HTTP_URI MAP_HTTP_URI
↑ 8 #include "rh_charmap.h"
↑ 9
↑ 10 #ifndef RH_BUFFER_ALIGN
↑ 11 # define RH_BUFFER_ALIGN 32
↑ 12 #endif
↑ 13
↑ 14 void rh_buffer_init (rh_buffer_t *buffer)
↑ 15 {
↑ 16 memset (buffer, 0, sizeof(*buffer) );
↑ 17 }
↑ 18
↑ 19 void rh_buffer_destroy (rh_buffer_t *buffer)
↑ 20 {
↑ 21 if (!(buffer->flags & RH_BUFFER_CONST) && buffer->data) {
↑ 22 free (buffer->data);
↑ 23 }
↑ 24
↑ 25 rh_buffer_init(buffer);
↑ 26 }
↑ 27
↑ 28 int rh_buffer_reset (rh_buffer_t *buffer)
↑ 29 {
↑ 30 char *data;
↑ 31
↑ 32 if (buffer->flags & RH_BUFFER_CONST) {
↑ 33 memset (buffer, 0, sizeof(*buffer));
↑ 34 return 0;
↑ 35 }
↑ 36
↑ 37 buffer->used = 0;
↑ 38
↑ 39 if (buffer->size < RH_BUFFER_ALIGN+1)
↑ 40 return 0;
↑ 41
↑ 42 data = realloc(buffer->data, RH_BUFFER_ALIGN);
↑ 43 if (NULL == data)
↑ 44 return -1;
↑ 45
↑ 46 buffer->data = data;
↑ 47 buffer->size = RH_BUFFER_ALIGN;
↑ 48
↑ 49 return 0;
↑ 50 }
↑ 51
↑ 52 int rh_buffer_reserve (rh_buffer_t *buffer, size_t size)
↑ 53 {
↑ 54 char *data;
↑ 55
↑ 56 if (buffer->flags & RH_BUFFER_CONST)
↑ 57 return -1;
↑ 58
↑ 59 size = size + RH_BUFFER_ALIGN - (size % RH_BUFFER_ALIGN);
↑ 60
↑ 61 if (buffer->size - buffer->used >= size)
↑ 62 return 0;
↑ 63
↑ 64 size += buffer->used;
↑ 65
↑ 66 size = size + RH_BUFFER_ALIGN - (size % RH_BUFFER_ALIGN);
↑ 67
↑ 68 data = realloc (buffer->data, size);
↑ 69 if (NULL == data)
↑ 70 return -1;
↑ 71
↑ 72 buffer->data = data;
↑ 73 buffer->size = size;
↑ 74
↑ 75 return 0;
↑ 76 }
↑ 77
↑ 78 int rh_buffer_append (rh_buffer_t *buffer, const void *src, size_t nsrc)
↑ 79 {
↑ 80 if (rh_buffer_reserve(buffer, nsrc + 1))
↑ 81 return -1;
↑ 82 #if 1
↑ 83 rh_memcpy (buffer->data + buffer->used, src, nsrc);
↑ 84 #else
↑ 85 memcpy (buffer->data + buffer->used, src, nsrc);
↑ 86 #endif
↑ 87
↑ 88 buffer->used += nsrc;
↑ 89
↑ 90 return 0;
↑ 91 }
↑ 92
↑ 93 int rh_buffer_append_ch (rh_buffer_t *buffer, int ch, size_t count)
↑ 94 {
↑ 95 if (rh_buffer_reserve(buffer, count))
↑ 96 return -1;
↑ 97
↑ 98 if (count == 1) {
↑ 99 buffer->data[buffer->used++] = ch;
↑100 } else {
↑101 memset (buffer->data + buffer->used, ch, count);
↑102 buffer->used += count;
↑103 }
↑104
↑105 return 0;
↑106 }
↑107
↑108 /*
↑109 *
↑110 * appends a buffer uri hex encoded:
↑111 *
↑112 * "hello my friend" -> "hello%20my%20friend"
↑113 *
↑114 */
↑115
↑116 int rh_buffer_append_encode_uri (rh_buffer_t *buffer,
↑117 const char *src, size_t nsrc)
↑118 {
↑119 const char *hex = "0123456789abcdef";
↑120
↑121 if (rh_buffer_reserve(buffer, nsrc + 32))
↑122 return -1;
↑123
↑124 while (nsrc) {
↑125 size_t space_left;
↑126
↑127 for ( space_left = rh_buffer_size(buffer);
↑128 nsrc && space_left > 2;
↑129 --space_left, --nsrc)
↑130 {
↑131 unsigned char ch;
↑132
↑133 ch = *src++;
↑134
↑135 if (MAP_HTTP_URI[ch]) {
↑136 buffer->data[buffer->used++] = ch;
↑137 continue;
↑138 }
↑139
↑140 buffer->data[buffer->used++] = '%';
↑141
↑142 /* hex points to a string.
↑143 *
↑144 * the calculations (ch / 16, ch % 16) returns
↑145 * always a number between 0 and 15.
↑146 *
↑147 * this means moving hex to the right character
↑148 * and then dereferencing it to a character useable
↑149 * for coping into buffer.
↑150 *
↑151 */
↑152 buffer->data[buffer->used++] = *( hex + (ch / 16) );
↑153 buffer->data[buffer->used++] = *( hex + (ch % 16) );
↑154 }
↑155
↑156 if (0 == nsrc)
↑157 return 0;
↑158
↑159 if (rh_buffer_reserve(buffer, nsrc + 32))
↑160 return -1;
↑161 }
↑162
↑163 return 0;
↑164 }
↑165
↑166 void rh_buffer_set_const (rh_buffer_t *buffer, const void *src, size_t nsrc)
↑167 {
↑168 buffer->hash = 0;
↑169 buffer->used = buffer->size = nsrc;
↑170 buffer->data = (char*)src;
↑171 buffer->flags = RH_BUFFER_CONST;
↑172 }
↑173
↑174 size_t rh_buffer_hashcase (rh_buffer_t *buffer)
↑175 {
↑176 return (buffer->hash = rh_hashcase33 (buffer->data, buffer->used));
↑177 }
syntax highlighted by Code2HTML, v. 0.9.1