]> git.evergreen-ils.org Git - Evergreen.git/blob - OpenSRF/src/utils/utils.c
moved some of the utility code out that has no other dependencies, used
[Evergreen.git] / OpenSRF / src / utils / utils.c
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 #include <sys/timeb.h>
7 #include "utils.h"
8
9 inline void* safe_malloc( int size ) {
10         void* ptr = (void*) malloc( size );
11         if( ptr == NULL ) {
12                 perror("safe_malloc(): Out of Memory" );
13                 exit(99);
14         }
15         memset( ptr, 0, size );
16         return ptr;
17 }
18
19 /* utility method for profiling */
20 double get_timestamp_millis() {
21         struct timeb t;
22         ftime(&t);
23         double time     = ( 
24                 (int)t.time     + ( ((double)t.millitm) / 1000 ) );
25         return time;
26 }
27
28
29 // ---------------------------------------------------------------------------------
30 // Flesh out a ubiqitous growing string buffer
31 // ---------------------------------------------------------------------------------
32
33 growing_buffer* buffer_init(int num_initial_bytes) {
34
35         if( num_initial_bytes > BUFFER_MAX_SIZE ) {
36                 return NULL;
37         }
38
39
40         size_t len = sizeof(growing_buffer);
41
42         growing_buffer* gb = (growing_buffer*) safe_malloc(len);
43
44         gb->n_used = 0;/* nothing stored so far */
45         gb->size = num_initial_bytes;
46         gb->buf = (char *) safe_malloc(gb->size + 1);
47
48         return gb;
49 }
50
51 int buffer_fadd(growing_buffer* gb, const char* format, ... ) {
52
53         if(!gb || !format) return 0; 
54
55         va_list args;
56
57         int len = strlen(format) + 1024;
58         char buf[len];
59         memset(buf, 0, len);
60
61         va_start(args, format);
62         vsnprintf(buf, len - 1, format, args);
63         va_end(args);
64
65         return buffer_add(gb, buf);
66
67 }
68
69
70 int buffer_add(growing_buffer* gb, char* data) {
71
72
73         if( ! gb || ! data  ) { return 0; }
74         int data_len = strlen( data );
75
76         if( data_len == 0 ) { return 0; }
77         int total_len = data_len + gb->n_used;
78
79         while( total_len >= gb->size ) {
80                 gb->size *= 2;
81         }
82
83         if( gb->size > BUFFER_MAX_SIZE ) {
84                 fprintf(stderr, "Buffer reached MAX_SIZE of %d", BUFFER_MAX_SIZE );
85                 buffer_free( gb );
86                 return 0;
87         }
88
89         char* new_data = (char*) safe_malloc( gb->size );
90
91         strcpy( new_data, gb->buf );
92         free( gb->buf );
93         gb->buf = new_data;
94
95         strcat( gb->buf, data );
96         gb->n_used = total_len;
97         return total_len;
98 }
99
100
101 int buffer_reset( growing_buffer *gb){
102         if( gb == NULL ) { return 0; }
103         if( gb->buf == NULL ) { return 0; }
104         memset( gb->buf, 0, gb->size );
105         gb->n_used = 0;
106         return 1;
107 }
108
109 int buffer_free( growing_buffer* gb ) {
110         if( gb == NULL ) 
111                 return 0;
112         free( gb->buf );
113         free( gb );
114         return 1;
115 }
116
117 char* buffer_data( growing_buffer *gb) {
118         return strdup( gb->buf );
119 }
120
121
122 int buffer_add_char(growing_buffer* gb, char c) {
123         char buf[2];
124         buf[0] = c;
125         buf[1] = '\0';
126         buffer_add(gb, buf);
127         return 1;
128 }
129
130
131
132 char* uescape( const char* string, int size, int full_escape ) {
133
134         growing_buffer* buf = buffer_init(size + 64);
135         int idx = 0;
136         long unsigned int c = 0;
137
138         while (string[idx]) {
139         
140                 c ^= c;
141                 
142                 if ((string[idx] & 0xF0) == 0xF0) {
143                         c = string[idx]<<18;
144
145                         if( size - idx < 4 ) return NULL;
146                         
147                         idx++;
148                         c |= (string[idx] & 0x3F)<<12;
149                         
150                         idx++;
151                         c |= (string[idx] & 0x3F)<<6;
152                         
153                         idx++;
154                         c |= (string[idx] & 0x3F);
155                         
156                         c ^= 0xFF000000;
157                         
158                         buffer_fadd(buf, "\\u%0.4x", c);
159
160                 } else if ((string[idx] & 0xE0) == 0xE0) {
161                         c = string[idx]<<12;
162                         if( size - idx < 3 ) return NULL;
163                         
164                         idx++;
165                         c |= (string[idx] & 0x3F)<<6;
166                         
167                         idx++;
168                         c |= (string[idx] & 0x3F);
169                         
170                         c ^= 0xFFF80000;
171                         
172                         buffer_fadd(buf, "\\u%0.4x", c);
173
174                 } else if ((string[idx] & 0xC0) == 0xC0) {
175                         // Two byte char
176                         c = string[idx]<<6;
177                         if( size - idx < 2 ) return NULL;
178                         
179                         idx++;
180                         c |= (string[idx] & 0x3F);
181                         
182                         c ^= 0xFFFFF000;
183                         
184                         buffer_fadd(buf, "\\u%0.4x", c);
185
186                 } else {
187                         c = string[idx];
188
189                         /* escape the usual suspects */
190                         if(full_escape) {
191                                 switch(c) {
192                                         case '"':
193                                                 buffer_add_char(buf, '\\');
194                                                 buffer_add_char(buf, '"');
195                                                 break;
196         
197                                         case '\b':
198                                                 buffer_add_char(buf, '\\');
199                                                 buffer_add_char(buf, 'b');
200                                                 break;
201         
202                                         case '\f':
203                                                 buffer_add_char(buf, '\\');
204                                                 buffer_add_char(buf, 'f');
205                                                 break;
206         
207                                         case '\t':
208                                                 buffer_add_char(buf, '\\');
209                                                 buffer_add_char(buf, 't');
210                                                 break;
211         
212                                         case '\n':
213                                                 buffer_add_char(buf, '\\');
214                                                 buffer_add_char(buf, 'n');
215                                                 break;
216         
217                                         case '\r':
218                                                 buffer_add_char(buf, '\\');
219                                                 buffer_add_char(buf, 'r');
220                                                 break;
221
222                                         default:
223                                                 buffer_add_char(buf, c);
224                                 }
225
226                         } else {
227                                 buffer_add_char(buf, c);
228                         }
229                 }
230
231                 idx++;
232         }
233
234         char* d = buffer_data(buf);
235         buffer_free(buf);
236         return d;
237 }
238