2 Copyright (C) 2005 Georgia Public Library Service
3 Bill Erickson <highfalutin@gmail.com>
4 Mike Rylander <mrylander@gmail.com>
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.
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.
19 inline void* safe_malloc( int size ) {
20 void* ptr = (void*) malloc( size );
22 perror("safe_malloc(): Out of Memory" );
25 memset( ptr, 0, size );
31 /* utility method for profiling */
32 double get_timestamp_millis() {
35 gettimeofday(&tv, NULL);
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) );
43 /* setting/clearing file flags */
44 int set_fl( int fd, int flags ) {
48 if( (val = fcntl( fd, F_GETFL, 0) ) < 0 ) {
49 fprintf(stderr, "fcntl F_GETFL error");
55 if( fcntl( fd, F_SETFL, val ) < 0 ) {
56 fprintf(stderr, "fcntl F_SETFL error");
62 int clr_fl( int fd, int flags ) {
66 if( (val = fcntl( fd, F_GETFL, 0) ) < 0 ) {
67 fprintf(stderr, "fcntl F_GETFL error" );
73 if( fcntl( fd, F_SETFL, val ) < 0 ) {
74 fprintf( stderr, "fcntl F_SETFL error" );
80 long va_list_size(const char* format, va_list args) {
82 len = vsnprintf(NULL, 0, format, args);
89 char* va_list_to_string(const char* format, ...) {
95 va_copy(a_copy, args);
97 va_start(args, format);
98 len = va_list_size(format, args);
103 va_start(a_copy, format);
104 vsnprintf(buf, len - 1, format, a_copy);
109 // ---------------------------------------------------------------------------------
110 // Flesh out a ubiqitous growing string buffer
111 // ---------------------------------------------------------------------------------
113 growing_buffer* buffer_init(int num_initial_bytes) {
115 if( num_initial_bytes > BUFFER_MAX_SIZE ) return NULL;
117 size_t len = sizeof(growing_buffer);
119 growing_buffer* gb = (growing_buffer*) safe_malloc(len);
121 gb->n_used = 0;/* nothing stored so far */
122 gb->size = num_initial_bytes;
123 gb->buf = (char *) safe_malloc(gb->size + 1);
129 int buffer_fadd(growing_buffer* gb, const char* format, ... ) {
131 if(!gb || !format) return 0;
137 va_copy(a_copy, args);
139 va_start(args, format);
140 len = va_list_size(format, args);
145 va_start(a_copy, format);
146 vsnprintf(buf, len - 1, format, a_copy);
149 return buffer_add(gb, buf);
153 int buffer_add(growing_buffer* gb, char* data) {
156 if( ! gb || ! data ) { return 0; }
157 int data_len = strlen( data );
159 if( data_len == 0 ) { return 0; }
160 int total_len = data_len + gb->n_used;
162 while( total_len >= gb->size ) {
166 if( gb->size > BUFFER_MAX_SIZE ) {
167 fprintf(stderr, "Buffer reached MAX_SIZE of %d", BUFFER_MAX_SIZE );
172 char* new_data = (char*) safe_malloc( gb->size );
174 strcpy( new_data, gb->buf );
178 strcat( gb->buf, data );
179 gb->n_used = total_len;
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 );
192 int buffer_free( growing_buffer* gb ) {
200 char* buffer_data( growing_buffer *gb) {
201 return strdup( gb->buf );
205 int buffer_add_char(growing_buffer* gb, char c) {
215 char* uescape( const char* string, int size, int full_escape ) {
217 growing_buffer* buf = buffer_init(size + 64);
219 long unsigned int c = 0;
221 while (string[idx]) {
225 if ((string[idx] & 0xF0) == 0xF0) {
228 if( size - idx < 4 ) return NULL;
231 c |= (string[idx] & 0x3F)<<12;
234 c |= (string[idx] & 0x3F)<<6;
237 c |= (string[idx] & 0x3F);
241 buffer_fadd(buf, "\\u%0.4x", c);
243 } else if ((string[idx] & 0xE0) == 0xE0) {
245 if( size - idx < 3 ) return NULL;
248 c |= (string[idx] & 0x3F)<<6;
251 c |= (string[idx] & 0x3F);
255 buffer_fadd(buf, "\\u%0.4x", c);
257 } else if ((string[idx] & 0xC0) == 0xC0) {
260 if( size - idx < 2 ) return NULL;
263 c |= (string[idx] & 0x3F);
267 buffer_fadd(buf, "\\u%0.4x", c);
272 /* escape the usual suspects */
276 buffer_add_char(buf, '\\');
277 buffer_add_char(buf, '"');
281 buffer_add_char(buf, '\\');
282 buffer_add_char(buf, 'b');
286 buffer_add_char(buf, '\\');
287 buffer_add_char(buf, 'f');
291 buffer_add_char(buf, '\\');
292 buffer_add_char(buf, 't');
296 buffer_add_char(buf, '\\');
297 buffer_add_char(buf, 'n');
301 buffer_add_char(buf, '\\');
302 buffer_add_char(buf, 'r');
306 buffer_add_char(buf, c);
310 buffer_add_char(buf, c);
317 char* d = buffer_data(buf);
323 // A function to turn a process into a daemon and set it's process name in ps/top
328 perror("Failed to fork!");
331 } else if (f == 0) { // We're in the child now...
335 } else { // We're in the parent...
340 int stringisnum(char* s) {
341 char* w = (char*) malloc(strlen(s) * sizeof(char*));
351 char* file_to_string(char* filename) {
353 if(!filename) return NULL;
358 growing_buffer* gb = buffer_init(len);
360 FILE* file = fopen(filename, "r");
362 perror("Unable to open file in json_parse_file()");
366 while(fgets(buf, len - 1, file)) {
371 char* data = buffer_data(gb);