~drizzle-trunk/drizzle/development

1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
1
/* Copyright (c) 2008 PrimeBase Technologies GmbH, Germany
2
 *
3
 * PrimeBase Media Stream for MySQL
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
 *
19
 * Original author: Paul McCullagh (H&G2JCtL)
20
 * Continued development: Barry Leslie
21
 *
22
 * 2007-05-21
23
 *
24
 * CORE SYSTEM:
25
 * Simple utility functions.
26
 *
27
 */
28
1548.2.3 by Barry.Leslie at PrimeBase
Added drizzle event observer class to PBMS as well as a lot of mostly minor changes for drizzle compatability.
29
#include "CSConfig.h"
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
30
#include <inttypes.h>
31
32
#include <stdio.h>
33
#include <string.h>
34
#include <ctype.h>
35
36
#include "CSDefs.h"
37
#include "CSStrUtil.h"
38
#include "CSMemory.h"
39
#include "CSGlobal.h"
40
41
void cs_strcpy(size_t size, char *to, const char *from, size_t len)
42
{
43
	if (size > 0) {
44
		size--;
45
		if (len > size)
46
			len = size;
47
		memcpy(to, from, len);
48
		to[len] = 0;
49
	}
50
}
51
52
void cs_strcpy(size_t size, char *to, const char *from)
53
{
54
	if (size > 0) {
55
		size--;
56
		while (*from && size--)
57
			*to++ = *from++;
58
		*to = 0;
59
	}
60
}
61
62
void cs_strcpy_left(size_t size, char *to, const char *from, char ch)
63
{
64
	if (size > 0) {
65
		size--;
66
		while (*from && size-- && *from != ch)
67
			*to++ = *from++;
68
		*to = 0;
69
	}
70
}
71
72
void cs_strcpy_right(size_t size, char *to, const char *from, char ch)
73
{
74
	if (size > 0) {
75
		size--;
76
		while (*from && *from != ch)
77
			from++;
78
		if (*from == ch)
79
			from++;
80
		while (*from && size-- && *from != ch)
81
			*to++ = *from++;
82
		*to = 0;
83
	}
84
}
85
86
void cs_strcat(size_t size, char *to, const char *from)
87
{
88
	while (*to && size--) to++;
89
	cs_strcpy(size, to, from);
90
}
91
92
void cs_strcat(size_t size, char *to, char ch)
93
{
94
	while (*to && size--) to++;
95
	if (size >= 1) {
96
		*to = ch;
97
		*(to+1) = 0;
98
	}
99
}
100
101
void cs_strcat(char **to, const char *to_cat)
102
{
103
	size_t len = strlen(*to) + strlen(to_cat) + 1;
104
	
105
	cs_realloc((void **) to, len);
106
	strcat(*to, to_cat);
107
}
108
109
void cs_strcat(size_t size, char *to, int i)
110
{
111
	char buffer[20];
112
	
113
	snprintf(buffer, 20, "%d", i);
114
	cs_strcat(size, to, buffer);
115
}
116
117
void cs_strcat(size_t size, char *to, uint32_t i)
118
{
119
	char buffer[20];
120
	
121
	snprintf(buffer, 20, "%"PRIu32"", i);
122
	cs_strcat(size, to, buffer);
123
}
124
125
void cs_strcat(size_t size, char *to, uint64_t i)
126
{
1548.2.26 by Barry.Leslie at PrimeBase
Bug fix for buffer size goof.
127
	char buffer[40];
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
128
	
129
	snprintf(buffer, 40, "%"PRIu64"", i);
130
	cs_strcat(size, to, buffer);
131
}
132
133
void cs_strcat_left(size_t size, char *to, const char *from, char ch)
134
{
135
	while (*to && size--) to++;
136
	cs_strcpy_left(size, to, from, ch);
137
}
138
139
void cs_strcat_right(size_t size, char *to, const char *from, char ch)
140
{
141
	while (*to && size--) to++;
142
	cs_strcpy_right(size, to, from, ch);
143
}
144
145
void cs_strcat_hex(size_t size, char *to, uint64_t i)
146
{
147
	char buffer[80];
148
	
149
	snprintf(buffer, 80, "%"PRIx64"", i);
150
	cs_strcat(size, to, buffer);
151
}
152
153
void cs_format_context(size_t size, char *buffer, const char *func, const char *file, int line)
154
{
155
	char *ptr;
156
157
	if (func) {
158
		cs_strcpy(size, buffer, func);
159
		// If the "pretty" function includes parameters, remove them:
160
		if ((ptr = strchr(buffer, '(')))
161
			*ptr = 0;
162
		cs_strcat(size, buffer, "(");
163
	}
164
	else
165
		*buffer = 0;
166
	if (file) {
167
		cs_strcat(size, buffer, cs_last_name_of_path(file));
168
		if (line) {
169
			cs_strcat(size, buffer, ":");
170
			cs_strcat(size, buffer, line);
171
		}
172
	}
173
	if (func)
174
		cs_strcat(size, buffer, ")");
175
}
176
177
/* This function returns "" if the path ends with a dir char */
178
char *cs_last_name_of_path(const char *path, int count)
179
{
180
	size_t		length;
181
	const char	*ptr;
182
183
	length = strlen(path);
184
	if (!length)
185
		return((char *) path);
186
	ptr = path + length - 1;
187
	while (ptr != path) {
188
		if (IS_DIR_CHAR(*ptr)) {
189
			count--;
190
			if (!count)
191
				break;
192
		}
193
		ptr--;
194
	}
195
	if (IS_DIR_CHAR(*ptr)) ptr++;
196
	return((char *) ptr);
197
}
198
199
char *cs_last_name_of_path(const char *path)
200
{
201
	return cs_last_name_of_path(path, 1);
202
}
203
204
/* This function returns the last name component, even if the path ends with a dir char */
205
char *cs_last_directory_of_path(char *path)
206
{
207
	size_t	length;
208
	char	*ptr;
209
210
	length = strlen(path);
211
	if (!length)
212
		return(path);
213
	ptr = path + length - 1;
214
	if (IS_DIR_CHAR(*ptr))
215
		ptr--;
216
	while (ptr != path && !IS_DIR_CHAR(*ptr)) ptr--;
217
	if (IS_DIR_CHAR(*ptr)) ptr++;
218
	return(ptr);
219
}
220
221
const char *cs_find_extension(const char *file_name)
222
{
223
	const char	*ptr;
224
225
	for (ptr = file_name + strlen(file_name) - 1; ptr >= file_name; ptr--) {
226
		if (IS_DIR_CHAR(*ptr))
227
			break;
228
		if (*ptr == '.')
229
			return ptr + 1;
230
	}
231
	return NULL;
232
}
233
234
void cs_remove_extension(char *file_name)
235
{
236
	char *ptr = (char *) cs_find_extension(file_name);
237
238
	if (ptr)
239
		*(ptr - 1) = 0;
240
}
241
242
bool cs_is_extension(const char *file_name, const char *ext)
243
{
244
	const char *ptr;
245
246
	if ((ptr = cs_find_extension(file_name)))
247
		return strcmp(ptr, ext) == 0;
248
	return false;
249
}
250
251
/*
252
 * Optionally remove a trailing directory delimiter (If the directory name consists of one
253
 * character, the directory delimiter is not removed).
254
 */
255
bool cs_remove_dir_char(char *dir_name)
256
{
257
	size_t length;
258
	
259
	length = strlen(dir_name);
260
	if (length > 1) {
261
		if (IS_DIR_CHAR(dir_name[length - 1])) {
262
			dir_name[length - 1] = '\0';
263
			return true;
264
		}
265
	}
266
	return false;
267
}
268
269
void cs_remove_last_name_of_path(char *path)
270
{
271
	char *ptr;
272
273
	if ((ptr = cs_last_name_of_path(path)))
274
		*ptr = 0;
275
}
276
1548.2.23 by Barry.Leslie at PrimeBase
And more cleanup.
277
static void cs_remove_last_directory_of_path(char *path)
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
278
{
279
	char *ptr;
280
281
	if ((ptr = cs_last_directory_of_path(path)))
282
		*ptr = 0;
283
}
284
285
bool cs_add_dir_char(size_t max, char *path)
286
{
287
	size_t slen = strlen(path);
288
289
	if (slen >= max)
290
		return false;
291
292
	if (slen == 0) {
293
		/* If no path is given we will be at the current working directory, under UNIX we must
294
		 * NOT add a directory delimiter character:
295
		 */
296
		return false;
297
	}
298
299
	if (!IS_DIR_CHAR(path[slen - 1])) {
300
		path[slen] = CS_DIR_CHAR;
301
		path[slen + 1] = '\0';
302
		return true;
303
	}
304
	return false;
305
}
306
307
bool cs_is_absolute(const char *path)
308
{
309
	return IS_DIR_CHAR(*path);
310
}
311
312
void cs_add_name_to_path(size_t max, char *path, const char *name)
313
{
314
	char *end_ptr = path + max - 1;
315
316
	cs_add_dir_char(max, path);
317
	path = path + strlen(path);
318
319
	if (IS_DIR_CHAR(*name))
320
		name++;
321
	while (*name && !IS_DIR_CHAR(*name) && path < end_ptr)
322
		*path++ = *name++;
323
	*path = 0;
324
}
325
326
const char *cs_next_name_of_path(const char *path)
327
{
328
	if (IS_DIR_CHAR(*path))
329
		path++;
330
	while (*path && !IS_DIR_CHAR(*path))
331
		path++;
332
	if (IS_DIR_CHAR(*path))
333
		path++;
334
	return path;
335
}
336
1548.2.23 by Barry.Leslie at PrimeBase
And more cleanup.
337
static void cs_adjust_absolute_path(size_t max, char *path, const char *rel_path)
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
338
{
339
	while (*rel_path) {
340
		if (*rel_path == '.') {
341
			if (*(rel_path + 1) == '.') {
342
				if (!*(rel_path + 2) || IS_DIR_CHAR(*(rel_path + 2))) {
343
					/* ..: move up one: */
344
					cs_remove_last_directory_of_path(path);
345
					goto loop;
346
				}
347
			}
348
			else {
349
				if (!*(rel_path + 1) || IS_DIR_CHAR(*(rel_path + 1)))
350
					/* .: stay here: */
351
					goto loop;
352
			}
353
		}
354
355
		/* Change to this directory: */
356
		cs_add_name_to_path(max, path, rel_path);
357
		loop:
358
		rel_path = cs_next_name_of_path(rel_path);
359
	}
360
}
361
362
void cs_make_absolute_path(size_t max, char *path, const char *rel_path, const char *cwd)
363
{
364
	if (cs_is_absolute(rel_path))
365
		cs_strcpy(max, path, rel_path);
366
	else {
367
		/* Path is relative to the current directory */
368
		cs_strcpy(max, path, cwd);
369
		cs_adjust_absolute_path(max, path, rel_path);
370
	}
371
	cs_remove_dir_char(path);
372
}
373
374
char *cs_strdup(const char *in_str)
375
{
376
	char *str;
377
	
378
	if (!in_str)
379
		return NULL;
380
381
	str = (char *) cs_malloc(strlen(in_str) + 1);
382
	strcpy(str, in_str);
383
	return str;
384
}
385
386
char *cs_strdup(int i)
387
{
388
	char buffer[20];
389
	char *str;
390
391
	snprintf(buffer, 20, "%d", i);
392
	str = (char *) cs_malloc(strlen(buffer) + 1);
393
	strcpy(str, buffer);
394
	return str;
395
}
396
397
char *cs_strdup(const char *in_str, size_t len)
398
{
399
	char *str;
400
	
401
	if (!in_str)
402
		return NULL;
403
404
	str = (char *) cs_malloc(len + 1);
405
	memcpy(str, in_str, len);
406
	str[len] = 0;
407
	return str;
408
}
409
410
bool cs_starts_with(const char *cstr, const char *w_cstr)
411
{
412
	while (*cstr && *w_cstr) {
413
		if (*cstr != *w_cstr)
414
			return false;
415
		cstr++;
416
		w_cstr++;
417
	}
418
	return *cstr || !*w_cstr;
419
}
420
421
void cs_replace_string(size_t size, char *into, const char ch, const char *str)
422
{
423
	char *ptr;
424
425
	if ((ptr = strchr(into, ch))) {
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
426
		size_t len = strlen(into);
427
		size_t len2 = strlen(str);
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
428
		
1548.2.2 by Barry.Leslie at PrimeBase
A lot of minor changes to clean up the code and to get it to build with Drizzle.
429
		if ((len + len2) > size)
1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
430
			len2 = size - len;
431
		
432
		memmove(ptr+1, ptr+len2, len - (ptr - into + 1));
433
		memcpy(ptr, str, len2);
434
		into[len + len2 - 1] = 0;
435
	}
436
}
437
438
uint64_t cs_str_to_word8(const char *ptr, bool *overflow)
439
{
440
	uint64_t value = 0;
441
442
	if (overflow)
443
		*overflow = false;
444
	while (*ptr == '0') ptr++;
445
	if (!*ptr)
446
		value = (uint64_t) 0;
447
	else {
448
		sscanf(ptr, "%"PRIu64"", &value);
449
		if (!value && overflow)
450
			*overflow = true;
451
	}
452
	return value;
453
}
454
455
int64_t cs_str_to_int8(const char *ptr, bool *overflow)
456
{
457
	int64_t value = 0;
458
459
	if (overflow)
460
		*overflow = false;
461
	while (*ptr == '0') ptr++;
462
	if (!*ptr)
463
		value = (int64_t) 0;
464
	else {
465
		sscanf(ptr, "%"PRId64"", &value);
466
		if (!value && overflow)
467
			*overflow = true;
468
	}
469
	return value;
470
}
471
472
int64_t cs_byte_size_to_int8(const char *ptr)
473
{
474
	char	number[101], *num_ptr;
475
	int64_t	size;
476
477
	while (*ptr && isspace(*ptr))
478
		ptr++;
479
480
	num_ptr = number;
481
	while (*ptr && isdigit(*ptr)) {
482
		if (num_ptr < number+100) {
483
			*num_ptr = *ptr;
484
			num_ptr++;
485
		}
486
		ptr++;
487
	}
488
	*num_ptr = 0;
489
	size = cs_str_to_int8(number, NULL);
490
491
	while (*ptr && isspace(*ptr))
492
		ptr++;
493
	
494
	switch (toupper(*ptr)) {
495
		case 'G':
496
			size *= 1024LL * 1024LL * 1024LL;
497
			break;
498
		case 'M':
499
			size *= 1024LL * 1024LL;
500
			break;
501
		case 'K':
502
			size *= 1024LL;
503
			break;
504
	}
505
	
506
	return size;
507
}
508
509
510
/*--------------------------------------------------------------------------------------------------*/
511
size_t cs_hex_to_bin(size_t size, void *bin, size_t len, const char *hex)
512
{	
513
	unsigned char *bin_ptr, *hex_ptr, c, val;
514
	size_t result = 0;
515
516
	if (len %2)  /* The hex string must be an even number of bytes. */
517
		len--;
518
		
519
	if (len > (2 *size)) {
520
		len = 2 * size;
521
	} 
522
			
523
	bin_ptr = (unsigned char *) bin;	
524
	hex_ptr = (unsigned char *) hex;	
525
526
	
527
	for (; len > 0; len--, hex_ptr++) {
528
		c = *hex_ptr;
529
		if ((c >= '0') && (c <= '9')) {
530
			val = c - '0';
531
		}
532
		else {
533
			c = toupper(c);
534
			if ((c >= 'A') && (c <= 'F')) {
535
				val = c - 'A' + 10;
536
			}
537
			else
538
				return(result);
539
		}
540
		
541
		if ( len & 0X01) {
542
			*bin_ptr += val;
543
			bin_ptr++;
544
			result++;
545
		}
546
		else {
547
			*bin_ptr = val << 4;
548
		}
549
	}
550
	
551
	return(result);
552
}
553
	
554
/*--------------------------------------------------------------------------------------------------*/
555
size_t cs_bin_to_hex(size_t size, char *hex, size_t len, const void *bin)
556
{
557
	static uint16_t hex_table[256], initialized = 0;
558
	uint16_t *hex_ptr = (uint16_t *)hex;
559
	unsigned char *bin_ptr = (unsigned char *)bin;
560
	size_t	result = 0;
561
562
	/* init the hex table if required */
563
	if (!initialized) {
564
		char buf[20];
565
		int i;
566
		for ( i=0; i < 256; i++) {
567
			snprintf(buf, 20,"%X", i + 256);
568
			memcpy(&(hex_table[i]), buf +1, 2);
569
		}
570
		
571
		initialized = 1;
572
	}
573
	/*----------------------------------*/	
574
575
	if (size < len *2) {
576
		len = size/2;
577
	}
578
		
579
	result = len *2;
580
		
581
	hex_ptr += len -1;
582
	bin_ptr += len -1;
583
	for (; len != 0; len--, hex_ptr--, bin_ptr--) {
584
		memcpy(hex_ptr, hex_table + *bin_ptr, 2);
585
	}
586
	
587
	// If there is room null terminate the hex string.
588
	if (size > result)
589
		hex[result] = 0;
590
		
591
	return(result);
592
}	
593
594
void cs_strToUpper(char *ptr)
595
{
596
	while (*ptr) {
597
		*ptr = toupper(*ptr);
598
		ptr++;
599
	}
600
}
601
602
void cs_strToLower(char *ptr)
603
{
604
	while (*ptr) {
605
		*ptr = tolower(*ptr);
606
		ptr++;
607
	}
608
}
609