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