]> git.evergreen-ils.org Git - working/Evergreen.git/blob - OpenSRF/src/utils/utils.c
adding utility methods
[working/Evergreen.git] / OpenSRF / src / utils / utils.c
1 /*
2 Copyright (C) 2005  Georgia Public Library Service 
3 Bill Erickson <highfalutin@gmail.com>
4 Mike Rylander <mrylander@gmail.com>
5
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 */
16
17 #include "utils.h"
18
19 inline void* safe_malloc( int size ) {
20         void* ptr = (void*) malloc( size );
21         if( ptr == NULL ) {
22                 perror("safe_malloc(): Out of Memory" );
23                 exit(99);
24         }
25         memset( ptr, 0, size );
26         return ptr;
27 }
28
29
30
31 /* utility method for profiling */
32 double get_timestamp_millis() {
33         //struct timeb t;
34         struct timeval tv;
35         gettimeofday(&tv, NULL);
36         //ftime(&t);
37 //      double time     = (int)t.time   + ( ((double)t.millitm) / 1000 )  + ( ((double)tv.tv_usec / 1000000) );
38         double time     = (int)tv.tv_sec        + ( ((double)tv.tv_usec / 1000000) );
39         return time;
40 }
41
42
43 /* setting/clearing file flags */
44 int set_fl( int fd, int flags ) {
45         
46         int val;
47
48         if( (val = fcntl( fd, F_GETFL, 0) ) < 0 ) {
49                 fprintf(stderr, "fcntl F_GETFL error");
50                 return -1;
51         }
52
53         val |= flags;
54
55         if( fcntl( fd, F_SETFL, val ) < 0 ) {
56                 fprintf(stderr, "fcntl F_SETFL error");
57                 return -1;
58         }
59         return 0;
60 }
61         
62 int clr_fl( int fd, int flags ) {
63         
64         int val;
65
66         if( (val = fcntl( fd, F_GETFL, 0) ) < 0 ) {
67                 fprintf(stderr, "fcntl F_GETFL error" );
68                 return -1;
69         }
70
71         val &= ~flags;
72
73         if( fcntl( fd, F_SETFL, val ) < 0 ) {
74                 fprintf( stderr, "fcntl F_SETFL error" );
75                 return -1;
76         }
77         return 0;
78 }
79
80 long va_list_size(const char* format, va_list args) {
81         int len = 0;
82         len = vsnprintf(NULL, 0, format, args);
83         va_end(args);
84         len += 2;
85         return len;
86 }
87
88
89 char* va_list_to_string(const char* format, ...) {
90
91         long len = 0;
92         va_list args;
93         va_list a_copy;
94
95         va_copy(a_copy, args);
96
97         va_start(args, format);
98         len = va_list_size(format, args);
99
100         char buf[len];
101         memset(buf, 0, len);
102
103         va_start(a_copy, format);
104         vsnprintf(buf, len - 1, format, a_copy);
105         va_end(a_copy);
106         return strdup(buf);
107 }
108
109 // ---------------------------------------------------------------------------------
110 // Flesh out a ubiqitous growing string buffer
111 // ---------------------------------------------------------------------------------
112
113 growing_buffer* buffer_init(int num_initial_bytes) {
114
115         if( num_initial_bytes > BUFFER_MAX_SIZE ) return NULL;
116
117         size_t len = sizeof(growing_buffer);
118
119         growing_buffer* gb = (growing_buffer*) safe_malloc(len);
120
121         gb->n_used = 0;/* nothing stored so far */
122         gb->size = num_initial_bytes;
123         gb->buf = (char *) safe_malloc(gb->size + 1);
124
125         return gb;
126 }
127
128
129 int buffer_fadd(growing_buffer* gb, const char* format, ... ) {
130
131         if(!gb || !format) return 0; 
132
133         long len = 0;
134         va_list args;
135         va_list a_copy;
136
137         va_copy(a_copy, args);
138
139         va_start(args, format);
140         len = va_list_size(format, args);
141
142         char buf[len];
143         memset(buf, 0, len);
144
145         va_start(a_copy, format);
146         vsnprintf(buf, len - 1, format, a_copy);
147         va_end(a_copy);
148
149         return buffer_add(gb, buf);
150
151 }
152
153 int buffer_add(growing_buffer* gb, char* data) {
154
155
156         if( ! gb || ! data  ) { return 0; }
157         int data_len = strlen( data );
158
159         if( data_len == 0 ) { return 0; }
160         int total_len = data_len + gb->n_used;
161
162         while( total_len >= gb->size ) {
163                 gb->size *= 2;
164         }
165
166         if( gb->size > BUFFER_MAX_SIZE ) {
167                 fprintf(stderr, "Buffer reached MAX_SIZE of %d", BUFFER_MAX_SIZE );
168                 buffer_free( gb );
169                 return 0;
170         }
171
172         char* new_data = (char*) safe_malloc( gb->size );
173
174         strcpy( new_data, gb->buf );
175         free( gb->buf );
176         gb->buf = new_data;
177
178         strcat( gb->buf, data );
179         gb->n_used = total_len;
180         return total_len;
181 }
182
183
184 int buffer_reset( growing_buffer *gb){
185         if( gb == NULL ) { return 0; }
186         if( gb->buf == NULL ) { return 0; }
187         memset( gb->buf, 0, gb->size );
188         gb->n_used = 0;
189         return 1;
190 }
191
192 int buffer_free( growing_buffer* gb ) {
193         if( gb == NULL ) 
194                 return 0;
195         free( gb->buf );
196         free( gb );
197         return 1;
198 }
199
200 char* buffer_data( growing_buffer *gb) {
201         return strdup( gb->buf );
202 }
203
204
205 int buffer_add_char(growing_buffer* gb, char c) {
206         char buf[2];
207         buf[0] = c;
208         buf[1] = '\0';
209         buffer_add(gb, buf);
210         return 1;
211 }
212
213
214
215 char* uescape( const char* string, int size, int full_escape ) {
216
217         growing_buffer* buf = buffer_init(size + 64);
218         int idx = 0;
219         long unsigned int c = 0;
220
221         while (string[idx]) {
222         
223                 c ^= c;
224                 
225                 if ((string[idx] & 0xF0) == 0xF0) {
226                         c = string[idx]<<18;
227
228                         if( size - idx < 4 ) return NULL;
229                         
230                         idx++;
231                         c |= (string[idx] & 0x3F)<<12;
232                         
233                         idx++;
234                         c |= (string[idx] & 0x3F)<<6;
235                         
236                         idx++;
237                         c |= (string[idx] & 0x3F);
238                         
239                         c ^= 0xFF000000;
240                         
241                         buffer_fadd(buf, "\\u%0.4x", c);
242
243                 } else if ((string[idx] & 0xE0) == 0xE0) {
244                         c = string[idx]<<12;
245                         if( size - idx < 3 ) return NULL;
246                         
247                         idx++;
248                         c |= (string[idx] & 0x3F)<<6;
249                         
250                         idx++;
251                         c |= (string[idx] & 0x3F);
252                         
253                         c ^= 0xFFF80000;
254                         
255                         buffer_fadd(buf, "\\u%0.4x", c);
256
257                 } else if ((string[idx] & 0xC0) == 0xC0) {
258                         // Two byte char
259                         c = string[idx]<<6;
260                         if( size - idx < 2 ) return NULL;
261                         
262                         idx++;
263                         c |= (string[idx] & 0x3F);
264                         
265                         c ^= 0xFFFFF000;
266                         
267                         buffer_fadd(buf, "\\u%0.4x", c);
268
269                 } else {
270                         c = string[idx];
271
272                         /* escape the usual suspects */
273                         if(full_escape) {
274                                 switch(c) {
275                                         case '"':
276                                                 buffer_add_char(buf, '\\');
277                                                 buffer_add_char(buf, '"');
278                                                 break;
279         
280                                         case '\b':
281                                                 buffer_add_char(buf, '\\');
282                                                 buffer_add_char(buf, 'b');
283                                                 break;
284         
285                                         case '\f':
286                                                 buffer_add_char(buf, '\\');
287                                                 buffer_add_char(buf, 'f');
288                                                 break;
289         
290                                         case '\t':
291                                                 buffer_add_char(buf, '\\');
292                                                 buffer_add_char(buf, 't');
293                                                 break;
294         
295                                         case '\n':
296                                                 buffer_add_char(buf, '\\');
297                                                 buffer_add_char(buf, 'n');
298                                                 break;
299         
300                                         case '\r':
301                                                 buffer_add_char(buf, '\\');
302                                                 buffer_add_char(buf, 'r');
303                                                 break;
304
305                                         default:
306                                                 buffer_add_char(buf, c);
307                                 }
308
309                         } else {
310                                 buffer_add_char(buf, c);
311                         }
312                 }
313
314                 idx++;
315         }
316
317         char* d = buffer_data(buf);
318         buffer_free(buf);
319         return d;
320 }
321
322
323 // A function to turn a process into a daemon and set it's process name in ps/top
324 int daemonize() {
325         int f = fork();
326
327         if (f == -1) {
328                 perror("Failed to fork!");
329                 return -1;
330
331         } else if (f == 0) { // We're in the child now...
332                 setsid();
333                 return 0;
334
335         } else { // We're in the parent...
336                 exit(0);
337         }
338 }
339
340 int stringisnum(char* s) {
341         char* w = (char*) malloc(strlen(s) * sizeof(char*));
342         bzero(w, strlen(s));
343         strtol(s, &w, 10);
344         if(strlen(w) > 0)  
345                 return 0;
346         return 1;
347 }
348         
349
350
351 char* file_to_string(char* filename) {
352
353         if(!filename) return NULL;
354
355         int len = 1024;
356         char buf[len];
357         bzero(buf, len);
358         growing_buffer* gb = buffer_init(len);
359
360         FILE* file = fopen(filename, "r");
361         if(!file) {
362                 perror("Unable to open file in json_parse_file()");
363                 return NULL;
364         }
365
366         while(fgets(buf, len - 1, file)) {
367                 buffer_add(gb, buf);
368                 bzero(buf, len);
369         }
370
371         char* data = buffer_data(gb);
372         buffer_free(gb);
373         return data;
374 }
375