~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbms/src/cslib/CSStrUtil.cc

This patch completes the first step in the splitting of
the XA resource manager API from the storage engine API,
as outlined in the specification here:

http://drizzle.org/wiki/XaStorageEngine

* Splits plugin::StorageEngine into a base StorageEngine
  class and two derived classes, TransactionalStorageEngine
  and XaStorageEngine.  XaStorageEngine derives from
  TransactionalStorageEngine and creates the XA Resource
  Manager API for storage engines.

  - The methods moved from StorageEngine to TransactionalStorageEngine
    include releaseTemporaryLatches(), startConsistentSnapshot(), 
    commit(), rollback(), setSavepoint(), releaseSavepoint(),
    rollbackToSavepoint() and hasTwoPhaseCommit()
  - The methods moved from StorageEngine to XaStorageEngine
    include recover(), commitXid(), rollbackXid(), and prepare()

* Places all static "EngineVector"s into their proper
  namespaces (typedefs belong in header files, not implementation files)
  and places all static methods corresponding
  to either only transactional engines or only XA engines
  into their respective files in /drizzled/plugin/

* Modifies the InnoDB "handler" files to extend plugin::XaStorageEngine
  and not plugin::StorageEngine

The next step, as outlined in the wiki spec page above, is to isolate
the XA Resource Manager API into its own plugin class and modify
plugin::XaStorageEngine to implement plugin::XaResourceManager via
composition.  This is necessary to enable building plugins which can
participate in an XA transaction *without having to have that plugin
implement the entire storage engine API*

Show diffs side-by-side

added added

removed removed

Lines of Context:
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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
 
 
29
 
#include "CSConfig.h"
30
 
#include <inttypes.h>
31
 
 
32
 
#include <stdlib.h>
33
 
#include <stdio.h>
34
 
#include <string.h>
35
 
#include <ctype.h>
36
 
 
37
 
#ifndef OS_WINDOWS
38
 
#include <fnmatch.h>
39
 
#endif
40
 
 
41
 
#include "CSDefs.h"
42
 
#include "CSStrUtil.h"
43
 
#include "CSMemory.h"
44
 
#include "CSGlobal.h"
45
 
 
46
 
const char *cs_version()
47
 
{
48
 
        static char version[124];
49
 
        
50
 
        if (!version[0]) {
51
 
                snprintf(version, 124, "%s(Built %s %s)", VERSION, __DATE__, __TIME__);
52
 
        }
53
 
        
54
 
        return version;
55
 
}
56
 
 
57
 
void cs_strcpy(size_t size, char *to, const char *from, size_t len)
58
 
{
59
 
        if (size > 0) {
60
 
                size--;
61
 
                if (len > size)
62
 
                        len = size;
63
 
                memcpy(to, from, len);
64
 
                to[len] = 0;
65
 
        }
66
 
}
67
 
 
68
 
void cs_strcpy(size_t size, char *to, const char *from)
69
 
{
70
 
        if (size > 0) {
71
 
                size--;
72
 
                while (*from && size--)
73
 
                        *to++ = *from++;
74
 
                *to = 0;
75
 
        }
76
 
}
77
 
 
78
 
/* This function adds '...' to the end of the string.
79
 
 * if it does not fit!
80
 
 */
81
 
void cs_strcpy_dottt(size_t size, char *d, const char *s, size_t len)
82
 
{
83
 
        if (len+1 <= size) {
84
 
                cs_strcpy(size, d, s, len);
85
 
                return;
86
 
        }
87
 
        if (size < 5) {
88
 
                /* Silly, but anyway... */
89
 
                cs_strcpy(size, d, "...");
90
 
                return;
91
 
        }
92
 
        memcpy(d, s, size-4);
93
 
        memcpy(d+size-4, "...", 3);
94
 
        d[size-1] = 0;
95
 
}
96
 
 
97
 
void cs_strcpy_left(size_t size, char *to, const char *from, char ch)
98
 
{
99
 
        if (size > 0) {
100
 
                size--;
101
 
                while (*from && size-- && *from != ch)
102
 
                        *to++ = *from++;
103
 
                *to = 0;
104
 
        }
105
 
}
106
 
 
107
 
void cs_strcpy_right(size_t size, char *to, const char *from, char ch)
108
 
{
109
 
        if (size > 0) {
110
 
                size--;
111
 
                while (*from && *from != ch)
112
 
                        from++;
113
 
                if (*from == ch)
114
 
                        from++;
115
 
                while (*from && size-- && *from != ch)
116
 
                        *to++ = *from++;
117
 
                *to = 0;
118
 
        }
119
 
}
120
 
 
121
 
void cs_strcat(size_t size, char *to, const char *from)
122
 
{
123
 
        while (*to && size--) to++;
124
 
        cs_strcpy(size, to, from);
125
 
}
126
 
 
127
 
void cs_strcat(size_t size, char *to, char ch)
128
 
{
129
 
        while (*to && size--) to++;
130
 
        if (size >= 1) {
131
 
                *to = ch;
132
 
                *(to+1) = 0;
133
 
        }
134
 
}
135
 
 
136
 
void cs_strcat(char **to, const char *to_cat)
137
 
{
138
 
        size_t len = strlen(*to) + strlen(to_cat) + 1;
139
 
        
140
 
        cs_realloc((void **) to, len);
141
 
        strcat(*to, to_cat);
142
 
}
143
 
 
144
 
void cs_strcat(size_t size, char *to, int i)
145
 
{
146
 
        char buffer[20];
147
 
        
148
 
        snprintf(buffer, 20, "%d", i);
149
 
        cs_strcat(size, to, buffer);
150
 
}
151
 
 
152
 
void cs_strcat(size_t size, char *to, uint32_t i)
153
 
{
154
 
        char buffer[20];
155
 
        
156
 
        snprintf(buffer, 20, "%"PRIu32"", i);
157
 
        cs_strcat(size, to, buffer);
158
 
}
159
 
 
160
 
void cs_strcat(size_t size, char *to, uint64_t i)
161
 
{
162
 
        char buffer[40];
163
 
        
164
 
        snprintf(buffer, 40, "%"PRIu64"", i);
165
 
        cs_strcat(size, to, buffer);
166
 
}
167
 
 
168
 
void cs_strcat_left(size_t size, char *to, const char *from, char ch)
169
 
{
170
 
        while (*to && size--) to++;
171
 
        cs_strcpy_left(size, to, from, ch);
172
 
}
173
 
 
174
 
void cs_strcat_right(size_t size, char *to, const char *from, char ch)
175
 
{
176
 
        while (*to && size--) to++;
177
 
        cs_strcpy_right(size, to, from, ch);
178
 
}
179
 
 
180
 
void cs_strcat_hex(size_t size, char *to, uint64_t i)
181
 
{
182
 
        char buffer[80];
183
 
        
184
 
        snprintf(buffer, 80, "%"PRIx64"", i);
185
 
        cs_strcat(size, to, buffer);
186
 
}
187
 
 
188
 
void cs_format_context(size_t size, char *buffer, const char *func, const char *file, int line)
189
 
{
190
 
        char *ptr;
191
 
 
192
 
        if (func) {
193
 
                cs_strcpy(size, buffer, func);
194
 
                // If the "pretty" function includes parameters, remove them:
195
 
                if ((ptr = strchr(buffer, '(')))
196
 
                        *ptr = 0;
197
 
                cs_strcat(size, buffer, "(");
198
 
        }
199
 
        else
200
 
                *buffer = 0;
201
 
        if (file) {
202
 
                cs_strcat(size, buffer, cs_last_name_of_path(file));
203
 
                if (line) {
204
 
                        cs_strcat(size, buffer, ":");
205
 
                        cs_strcat(size, buffer, line);
206
 
                }
207
 
        }
208
 
        if (func)
209
 
                cs_strcat(size, buffer, ")");
210
 
}
211
 
 
212
 
int cs_path_depth(const char *path)
213
 
{
214
 
        int count = 0;
215
 
        while (*path) {
216
 
                if (IS_DIR_CHAR(*path))
217
 
                        count++;
218
 
 
219
 
                path++;
220
 
        }
221
 
        return count;
222
 
}
223
 
 
224
 
static const char *find_wildcard(const char *pattern)
225
 
{
226
 
        bool escaped = false;
227
 
        while (*pattern) {
228
 
                if ((*pattern == '*' || *pattern == '?' ) && !escaped)
229
 
                        return pattern;
230
 
                        
231
 
                if (*pattern == '\\')
232
 
                        escaped = !escaped;
233
 
                else
234
 
                        escaped = false;
235
 
                        
236
 
                pattern++;
237
 
        }
238
 
        
239
 
        return NULL;
240
 
}
241
 
 
242
 
// Check if the path contains any variable components.
243
 
bool cs_fixed_pattern(const char *str)
244
 
{
245
 
        return (find_wildcard(str) == NULL);
246
 
}
247
 
 
248
 
#ifdef OS_WINDOWS
249
 
/* 
250
 
bool cs_match_patern(const char *pattern, const char *str, bool ignore_case)
251
 
{
252
 
        bool escaped = false;
253
 
        
254
 
        while (*pattern && *str) {
255
 
                if ((*pattern == '*' || *pattern == '?' ) && !escaped) {
256
 
                        if (*pattern == '?') {
257
 
                                pattern++;
258
 
                                str++;  
259
 
                                continue;                       
260
 
                        }
261
 
                        
262
 
                        while (*pattern == '*' || *pattern == '?' ) pattern++; // eat the pattern matching characters.
263
 
                        
264
 
                        if (!*pattern) // A * at the end of the pattern matches everything.
265
 
                                return true;
266
 
                                
267
 
                        // This is where it gets complicted.
268
 
                        
269
 
                        coming soon!
270
 
                        
271
 
                }
272
 
                                        
273
 
                if (*pattern == '\\')
274
 
                        escaped = !escaped;
275
 
                else
276
 
                        escaped = false;
277
 
                        
278
 
                if (escaped)
279
 
                        pattern++;
280
 
                else {
281
 
                        if (ignore_case) {
282
 
                                if (toupper(*pattern) != toupper(*str))
283
 
                                        return false;
284
 
                        } else if (*pattern != *str)
285
 
                                return false;
286
 
                        pattern++;
287
 
                        str++;                          
288
 
                }
289
 
                
290
 
        }
291
 
        
292
 
        return ((!*pattern) && (!*str));
293
 
}
294
 
*/
295
 
#else
296
 
bool cs_match_patern(const char *pattern, const char *str, bool ignore_case)
297
 
{
298
 
        return (fnmatch(pattern, str, (ignore_case)?FNM_CASEFOLD:0) == 0);
299
 
}
300
 
#endif
301
 
 
302
 
/* This function returns "" if the path ends with a dir char */
303
 
char *cs_last_name_of_path(const char *path, int count)
304
 
{
305
 
        size_t          length;
306
 
        const char      *ptr;
307
 
 
308
 
        length = strlen(path);
309
 
        if (!length)
310
 
                return((char *) path);
311
 
        ptr = path + length - 1;
312
 
        while (ptr != path) {
313
 
                if (IS_DIR_CHAR(*ptr)) {
314
 
                        count--;
315
 
                        if (!count)
316
 
                                break;
317
 
                }
318
 
                ptr--;
319
 
        }
320
 
        if (IS_DIR_CHAR(*ptr)) ptr++;
321
 
        return((char *) ptr);
322
 
}
323
 
 
324
 
char *cs_last_name_of_path(const char *path)
325
 
{
326
 
        return cs_last_name_of_path(path, 1);
327
 
}
328
 
 
329
 
/* This function returns the last name component, even if the path ends with a dir char */
330
 
char *cs_last_directory_of_path(const char *path)
331
 
{
332
 
        size_t  length;
333
 
        const char      *ptr;
334
 
 
335
 
        length = strlen(path);
336
 
        if (!length)
337
 
                return((char *)path);
338
 
        ptr = path + length - 1;
339
 
        if (IS_DIR_CHAR(*ptr))
340
 
                ptr--;
341
 
        while (ptr != path && !IS_DIR_CHAR(*ptr)) ptr--;
342
 
        if (IS_DIR_CHAR(*ptr)) ptr++;
343
 
        return((char *)ptr);
344
 
}
345
 
 
346
 
const char *cs_find_extension(const char *file_name)
347
 
{
348
 
        const char      *ptr;
349
 
 
350
 
        for (ptr = file_name + strlen(file_name) - 1; ptr >= file_name; ptr--) {
351
 
                if (IS_DIR_CHAR(*ptr))
352
 
                        break;
353
 
                if (*ptr == '.')
354
 
                        return ptr + 1;
355
 
        }
356
 
        return NULL;
357
 
}
358
 
 
359
 
void cs_remove_extension(char *file_name)
360
 
{
361
 
        char *ptr = (char *) cs_find_extension(file_name);
362
 
 
363
 
        if (ptr)
364
 
                *(ptr - 1) = 0;
365
 
}
366
 
 
367
 
bool cs_is_extension(const char *file_name, const char *ext)
368
 
{
369
 
        const char *ptr;
370
 
 
371
 
        if ((ptr = cs_find_extension(file_name)))
372
 
                return strcmp(ptr, ext) == 0;
373
 
        return false;
374
 
}
375
 
 
376
 
/*
377
 
 * Optionally remove a trailing directory delimiter (If the directory name consists of one
378
 
 * character, the directory delimiter is not removed).
379
 
 */
380
 
bool cs_remove_dir_char(char *dir_name)
381
 
{
382
 
        size_t length;
383
 
        
384
 
        length = strlen(dir_name);
385
 
        if (length > 1) {
386
 
                if (IS_DIR_CHAR(dir_name[length - 1])) {
387
 
                        dir_name[length - 1] = '\0';
388
 
                        return true;
389
 
                }
390
 
        }
391
 
        return false;
392
 
}
393
 
 
394
 
void cs_remove_last_name_of_path(char *path)
395
 
{
396
 
        char *ptr;
397
 
 
398
 
        if ((ptr = cs_last_name_of_path(path)))
399
 
                *ptr = 0;
400
 
}
401
 
 
402
 
static void cs_remove_last_directory_of_path(char *path)
403
 
{
404
 
        char *ptr;
405
 
 
406
 
        if ((ptr = cs_last_directory_of_path(path)))
407
 
                *ptr = 0;
408
 
}
409
 
 
410
 
bool cs_add_dir_char(size_t max, char *path)
411
 
{
412
 
        size_t slen = strlen(path);
413
 
 
414
 
        if (slen >= max)
415
 
                return false;
416
 
 
417
 
        if (slen == 0) {
418
 
                /* If no path is given we will be at the current working directory, under UNIX we must
419
 
                 * NOT add a directory delimiter character:
420
 
                 */
421
 
                return false;
422
 
        }
423
 
 
424
 
        if (!IS_DIR_CHAR(path[slen - 1])) {
425
 
                path[slen] = CS_DIR_CHAR;
426
 
                path[slen + 1] = '\0';
427
 
                return true;
428
 
        }
429
 
        return false;
430
 
}
431
 
 
432
 
bool cs_is_absolute(const char *path)
433
 
{
434
 
        return IS_DIR_CHAR(*path);
435
 
}
436
 
 
437
 
void cs_add_name_to_path(size_t max, char *path, const char *name)
438
 
{
439
 
        char *end_ptr = path + max - 1;
440
 
 
441
 
        cs_add_dir_char(max, path);
442
 
        path = path + strlen(path);
443
 
 
444
 
        if (IS_DIR_CHAR(*name))
445
 
                name++;
446
 
        while (*name && !IS_DIR_CHAR(*name) && path < end_ptr)
447
 
                *path++ = *name++;
448
 
        *path = 0;
449
 
}
450
 
 
451
 
const char *cs_next_name_of_path(const char *path)
452
 
{
453
 
        if (IS_DIR_CHAR(*path))
454
 
                path++;
455
 
        while (*path && !IS_DIR_CHAR(*path))
456
 
                path++;
457
 
        if (IS_DIR_CHAR(*path))
458
 
                path++;
459
 
        return path;
460
 
}
461
 
 
462
 
static void cs_adjust_absolute_path(size_t max, char *path, const char *rel_path)
463
 
{
464
 
        while (*rel_path) {
465
 
                if (*rel_path == '.') {
466
 
                        if (*(rel_path + 1) == '.') {
467
 
                                if (!*(rel_path + 2) || IS_DIR_CHAR(*(rel_path + 2))) {
468
 
                                        /* ..: move up one: */
469
 
                                        cs_remove_last_directory_of_path(path);
470
 
                                        goto loop;
471
 
                                }
472
 
                        }
473
 
                        else {
474
 
                                if (!*(rel_path + 1) || IS_DIR_CHAR(*(rel_path + 1)))
475
 
                                        /* .: stay here: */
476
 
                                        goto loop;
477
 
                        }
478
 
                }
479
 
 
480
 
                /* Change to this directory: */
481
 
                cs_add_name_to_path(max, path, rel_path);
482
 
                loop:
483
 
                rel_path = cs_next_name_of_path(rel_path);
484
 
        }
485
 
}
486
 
 
487
 
void cs_make_absolute_path(size_t max, char *path, const char *rel_path, const char *cwd)
488
 
{
489
 
        if (cs_is_absolute(rel_path))
490
 
                cs_strcpy(max, path, rel_path);
491
 
        else {
492
 
                /* Path is relative to the current directory */
493
 
                cs_strcpy(max, path, cwd);
494
 
                cs_adjust_absolute_path(max, path, rel_path);
495
 
        }
496
 
        cs_remove_dir_char(path);
497
 
}
498
 
 
499
 
char *cs_strdup(const char *in_str)
500
 
{
501
 
        char *str;
502
 
        
503
 
        if (!in_str)
504
 
                return NULL;
505
 
 
506
 
        str = (char *) cs_malloc(strlen(in_str) + 1);
507
 
        strcpy(str, in_str);
508
 
        return str;
509
 
}
510
 
 
511
 
char *cs_strdup(int i)
512
 
{
513
 
        char buffer[20];
514
 
        char *str;
515
 
 
516
 
        snprintf(buffer, 20, "%d", i);
517
 
        str = (char *) cs_malloc(strlen(buffer) + 1);
518
 
        strcpy(str, buffer);
519
 
        return str;
520
 
}
521
 
 
522
 
char *cs_strdup(const char *in_str, size_t len)
523
 
{
524
 
        char *str;
525
 
        
526
 
        if (!in_str)
527
 
                return NULL;
528
 
 
529
 
        str = (char *) cs_malloc(len + 1);
530
 
 
531
 
        // Allow for allocation of an oversized buffer.
532
 
        size_t str_len = strlen(in_str);
533
 
        if (len > str_len)
534
 
                len = str_len;
535
 
                
536
 
        memcpy(str, in_str, len);
537
 
        str[len] = 0;
538
 
        return str;
539
 
}
540
 
 
541
 
bool cs_starts_with(const char *cstr, const char *w_cstr)
542
 
{
543
 
        while (*cstr && *w_cstr) {
544
 
                if (*cstr != *w_cstr)
545
 
                        return false;
546
 
                cstr++;
547
 
                w_cstr++;
548
 
        }
549
 
        return *cstr || !*w_cstr;
550
 
}
551
 
 
552
 
bool cs_ends_with(const char *cstr, const char *w_cstr)
553
 
{
554
 
        size_t          len = strlen(cstr);
555
 
        size_t          w_len = strlen(w_cstr);
556
 
        const char      *ptr = cstr + len - 1;
557
 
        const char      *w_ptr = w_cstr + w_len - 1;
558
 
        
559
 
        if (w_len > len)
560
 
                return false;
561
 
 
562
 
        if (w_len == 0)
563
 
                return false;
564
 
 
565
 
        while (w_ptr >= w_cstr) {
566
 
                if (*w_ptr != *ptr)
567
 
                        return false;
568
 
                w_ptr--;
569
 
                ptr--;
570
 
        }
571
 
 
572
 
        return true;
573
 
}
574
 
 
575
 
void cs_replace_string(size_t size, char *into, const char *find_str, const char *str)
576
 
{
577
 
        char *ptr;
578
 
 
579
 
        if ((ptr = strstr(into, find_str))) {
580
 
                size_t len = strlen(into);
581
 
                size_t len2 = strlen(str);
582
 
                size_t len3 = strlen(find_str);
583
 
                
584
 
                if (len + len2 + len3 >= size)
585
 
                        len2 = size - len;
586
 
                
587
 
                memmove(ptr+len2, ptr+len3, len - (ptr + len3 - into));
588
 
                memcpy(ptr, str, len2);
589
 
                into[len + len2 - len3] = 0;
590
 
        }
591
 
}
592
 
 
593
 
void cs_replace_string(size_t size, char *into, const char ch, const char *str)
594
 
{
595
 
        char *ptr;
596
 
 
597
 
        if ((ptr = strchr(into, ch))) {
598
 
                size_t len = strlen(into);
599
 
                size_t len2 = strlen(str);
600
 
                
601
 
                if ((len + len2) > size)
602
 
                        len2 = size - len;
603
 
                
604
 
                memmove(ptr+1, ptr+len2, len - (ptr - into + 1));
605
 
                memcpy(ptr, str, len2);
606
 
                into[len + len2 - 1] = 0;
607
 
        }
608
 
}
609
 
 
610
 
uint64_t cs_str_to_word8(const char *ptr, bool *overflow)
611
 
{
612
 
        uint64_t value = 0;
613
 
 
614
 
        if (overflow)
615
 
                *overflow = false;
616
 
        while (*ptr == '0') ptr++;
617
 
        if (!*ptr)
618
 
                value = (uint64_t) 0;
619
 
        else {
620
 
                sscanf(ptr, "%"PRIu64"", &value);
621
 
                if (!value && overflow)
622
 
                        *overflow = true;
623
 
        }
624
 
        return value;
625
 
}
626
 
 
627
 
int64_t cs_str_to_int8(const char *ptr, bool *overflow)
628
 
{
629
 
        int64_t value = 0;
630
 
 
631
 
        if (overflow)
632
 
                *overflow = false;
633
 
        while (*ptr == '0') ptr++;
634
 
        if (!*ptr)
635
 
                value = (int64_t) 0;
636
 
        else {
637
 
                sscanf(ptr, "%"PRId64"", &value);
638
 
                if (!value && overflow)
639
 
                        *overflow = true;
640
 
        }
641
 
        return value;
642
 
}
643
 
 
644
 
int64_t cs_byte_size_to_int8(const char *ptr, bool *invalid)
645
 
{
646
 
        char    *end_ptr;
647
 
        int64_t size;
648
 
 
649
 
        if (invalid)
650
 
                *invalid = false;
651
 
 
652
 
        while (*ptr && isspace(*ptr))
653
 
                ptr++;
654
 
 
655
 
        if (!isdigit(*ptr) && *ptr != '.')
656
 
                goto failed;
657
 
 
658
 
        size = (int64_t) strtod(ptr, &end_ptr);
659
 
 
660
 
        ptr = end_ptr;
661
 
        while (*ptr && isspace(*ptr))
662
 
                ptr++;
663
 
        
664
 
        switch (toupper(*ptr)) {
665
 
                case 'P':
666
 
                        size *= (int64_t) 1024;
667
 
                case 'T':
668
 
                        size *= (int64_t) 1024;
669
 
                case 'G':
670
 
                        size *= (int64_t) 1024;
671
 
                case 'M':
672
 
                        size *= (int64_t) 1024;
673
 
                case 'K':
674
 
                        size *= (int64_t) 1024;
675
 
                        ptr++;
676
 
                        break;
677
 
                case '\0':
678
 
                        break;
679
 
                default:
680
 
                        goto failed;
681
 
        }
682
 
        
683
 
        if (toupper(*ptr) == 'B')
684
 
                ptr++;
685
 
 
686
 
        while (*ptr && isspace(*ptr))
687
 
                ptr++;
688
 
 
689
 
        if (*ptr)
690
 
                goto failed;
691
 
 
692
 
        return (int64_t) size;
693
 
 
694
 
        failed:
695
 
        if (invalid)
696
 
                *invalid = true;
697
 
        return 0;
698
 
}
699
 
 
700
 
 
701
 
static uint32_t cs_hex_value(char ch)
702
 
{
703
 
        u_char uch = (u_char) ch;
704
 
 
705
 
        if (uch >= '0' && uch <= '9')
706
 
                return uch - '0';
707
 
        if (uch >= 'A' && uch <= 'F')
708
 
                return uch - 'A' + 10; 
709
 
        if (uch >= 'a' && uch <= 'f')
710
 
                return uch - 'a' + 10;
711
 
        return 0;
712
 
}
713
 
 
714
 
size_t cs_hex_to_bin(size_t size, void *v_bin, size_t len, const char *hex)
715
 
{
716
 
        size_t  tot_size = size;
717
 
        uint32_t        val = 0;
718
 
        size_t  shift = 0;
719
 
        u_char *bin = (u_char *) v_bin;
720
 
 
721
 
        if (len & 1)
722
 
                shift = 1;
723
 
        for (size_t i=shift; i<len+shift && size > 0; i++) {
724
 
                if (i & 1) {
725
 
                        val = val | cs_hex_value(*hex);
726
 
                        *bin = val;
727
 
                        bin++;
728
 
                        size--;
729
 
                }
730
 
                else
731
 
                        val = cs_hex_value(*hex) << 4;
732
 
                hex++;
733
 
        }
734
 
        return tot_size - size;
735
 
}
736
 
 
737
 
size_t cs_hex_to_bin(size_t size, void *bin, const char *hex)
738
 
{
739
 
        return cs_hex_to_bin(size, bin, strlen(hex), hex);
740
 
}
741
 
 
742
 
#define HEX_DIGIT(x)    ((x) <= 9 ? '0' + (x) : 'A' + ((x) - 10))
743
 
 
744
 
void cs_bin_to_hex(size_t size, char *hex, size_t len, const void *v_bin)
745
 
{
746
 
        const u_char *bin = (u_char *) v_bin;
747
 
        if (size == 0)
748
 
                return;
749
 
        size--;
750
 
        for (size_t i=0; i<len && size > 0; i++) {
751
 
                *hex = HEX_DIGIT(*bin >> 4);
752
 
                hex++;
753
 
                size--;
754
 
                if (size == 0)
755
 
                        break;
756
 
                *hex = HEX_DIGIT(*bin & 0x0F);
757
 
                hex++;
758
 
                size--;
759
 
                bin++;
760
 
        }
761
 
        *hex = 0;
762
 
}       
763
 
 
764
 
void cs_strToUpper(char *ptr)
765
 
{
766
 
        while (*ptr) {
767
 
                *ptr = toupper(*ptr);
768
 
                ptr++;
769
 
        }
770
 
}
771
 
 
772
 
void cs_strToLower(char *ptr)
773
 
{
774
 
        while (*ptr) {
775
 
                *ptr = tolower(*ptr);
776
 
                ptr++;
777
 
        }
778
 
}
779
 
 
780
 
/*
781
 
 * Return failed if this is not a valid number.
782
 
 */
783
 
bool cs_str_to_value(const char *ptr, uint32_t *value, uint8_t base)
784
 
{
785
 
        char *endptr;
786
 
 
787
 
        *value = strtoul(ptr, &endptr, base);
788
 
        return *endptr ? false : true;
789
 
}
790
 
 
791