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.
22 #include <sys/timeb.h>
25 inline void* safe_malloc( int size ) {
26 void* ptr = (void*) malloc( size );
28 perror("safe_malloc(): Out of Memory" );
31 memset( ptr, 0, size );
35 /* utility method for profiling */
36 double get_timestamp_millis() {
40 (int)t.time + ( ((double)t.millitm) / 1000 ) );
45 /* setting/clearing file flags */
46 int set_fl( int fd, int flags ) {
50 if( (val = fcntl( fd, F_GETFL, 0) ) < 0 ) {
51 fprintf(stderr, "fcntl F_GETFL error");
57 if( fcntl( fd, F_SETFL, val ) < 0 ) {
58 fprintf(stderr, "fcntl F_SETFL error");
64 int clr_fl( int fd, int flags ) {
68 if( (val = fcntl( fd, F_GETFL, 0) ) < 0 ) {
69 fprintf(stderr, "fcntl F_GETFL error" );
75 if( fcntl( fd, F_SETFL, val ) < 0 ) {
76 fprintf( stderr, "fcntl F_SETFL error" );
82 // ---------------------------------------------------------------------------------
83 // Flesh out a ubiqitous growing string buffer
84 // ---------------------------------------------------------------------------------
86 growing_buffer* buffer_init(int num_initial_bytes) {
88 if( num_initial_bytes > BUFFER_MAX_SIZE ) {
93 size_t len = sizeof(growing_buffer);
95 growing_buffer* gb = (growing_buffer*) safe_malloc(len);
97 gb->n_used = 0;/* nothing stored so far */
98 gb->size = num_initial_bytes;
99 gb->buf = (char *) safe_malloc(gb->size + 1);
104 int buffer_fadd(growing_buffer* gb, const char* format, ... ) {
106 if(!gb || !format) return 0;
110 int len = strlen(format) + 1024;
114 va_start(args, format);
115 vsnprintf(buf, len - 1, format, args);
118 return buffer_add(gb, buf);
123 int buffer_add(growing_buffer* gb, char* data) {
126 if( ! gb || ! data ) { return 0; }
127 int data_len = strlen( data );
129 if( data_len == 0 ) { return 0; }
130 int total_len = data_len + gb->n_used;
132 while( total_len >= gb->size ) {
136 if( gb->size > BUFFER_MAX_SIZE ) {
137 fprintf(stderr, "Buffer reached MAX_SIZE of %d", BUFFER_MAX_SIZE );
142 char* new_data = (char*) safe_malloc( gb->size );
144 strcpy( new_data, gb->buf );
148 strcat( gb->buf, data );
149 gb->n_used = total_len;
154 int buffer_reset( growing_buffer *gb){
155 if( gb == NULL ) { return 0; }
156 if( gb->buf == NULL ) { return 0; }
157 memset( gb->buf, 0, gb->size );
162 int buffer_free( growing_buffer* gb ) {
170 char* buffer_data( growing_buffer *gb) {
171 return strdup( gb->buf );
175 int buffer_add_char(growing_buffer* gb, char c) {
185 char* uescape( const char* string, int size, int full_escape ) {
187 growing_buffer* buf = buffer_init(size + 64);
189 long unsigned int c = 0;
191 while (string[idx]) {
195 if ((string[idx] & 0xF0) == 0xF0) {
198 if( size - idx < 4 ) return NULL;
201 c |= (string[idx] & 0x3F)<<12;
204 c |= (string[idx] & 0x3F)<<6;
207 c |= (string[idx] & 0x3F);
211 buffer_fadd(buf, "\\u%0.4x", c);
213 } else if ((string[idx] & 0xE0) == 0xE0) {
215 if( size - idx < 3 ) return NULL;
218 c |= (string[idx] & 0x3F)<<6;
221 c |= (string[idx] & 0x3F);
225 buffer_fadd(buf, "\\u%0.4x", c);
227 } else if ((string[idx] & 0xC0) == 0xC0) {
230 if( size - idx < 2 ) return NULL;
233 c |= (string[idx] & 0x3F);
237 buffer_fadd(buf, "\\u%0.4x", c);
242 /* escape the usual suspects */
246 buffer_add_char(buf, '\\');
247 buffer_add_char(buf, '"');
251 buffer_add_char(buf, '\\');
252 buffer_add_char(buf, 'b');
256 buffer_add_char(buf, '\\');
257 buffer_add_char(buf, 'f');
261 buffer_add_char(buf, '\\');
262 buffer_add_char(buf, 't');
266 buffer_add_char(buf, '\\');
267 buffer_add_char(buf, 'n');
271 buffer_add_char(buf, '\\');
272 buffer_add_char(buf, 'r');
276 buffer_add_char(buf, c);
280 buffer_add_char(buf, c);
287 char* d = buffer_data(buf);