oceanbase

Форк
0
/
easy_string.c 
562 строки · 12.0 Кб
1
#include "util/easy_string.h"
2

3
static char *easy_sprintf_num(char *buf, char *last, uint64_t ui64, char zero, int hexadecimal, int width, int sign);
4
static char *easy_fill_space(int width, char *buf, char *fstart, char *last);
5

6
char *easy_strncpy(char *dst, const char *src, size_t n)
7
{
8
    if (!n || !dst)
9
        return NULL;
10

11
    const uint64_t          himagic = __UINT64_C(0x8080808080808080);
12
    const uint64_t          lomagic = __UINT64_C(0x0101010101010101);
13
    const uint64_t          *nsrc = (const uint64_t *)src;
14
    const uint64_t          *nend = nsrc + (--n / 8);
15
    uint64_t                *ndst = (uint64_t *)dst;
16

17
    while (nsrc != nend) {
18
        uint64_t                k = *nsrc;
19

20
        if (((k - lomagic) & ~k & himagic) != 0) {
21
            const char              *cp = (const char *) nsrc;
22

23
            if (cp[0] == 0) {
24
                n = 0;
25
                break;
26
            }
27

28
            if (cp[1] == 0) {
29
                n = 1;
30
                break;
31
            }
32

33
            if (cp[2] == 0) {
34
                n = 2;
35
                break;
36
            }
37

38
            if (cp[3] == 0) {
39
                n = 3;
40
                break;
41
            }
42

43
            if (cp[4] == 0) {
44
                n = 4;
45
                break;
46
            }
47

48
            if (cp[5] == 0) {
49
                n = 5;
50
                break;
51
            }
52

53
            if (cp[6] == 0) {
54
                n = 6;
55
                break;
56
            }
57

58
            n = 7;
59
            break;
60
        }
61

62
        *ndst++ = k;
63
        nsrc ++;
64
    }
65

66
    const char              *nsrc2 = (const char *) nsrc;
67

68
    char                    *ndst2 = (char *) ndst;
69

70
    switch (n & 7) {
71
    case 7:
72
        *ndst2++ = *nsrc2++;
73

74
    case 6:
75
        *ndst2++ = *nsrc2++;
76

77
    case 5:
78
        *ndst2++ = *nsrc2++;
79

80
    case 4:
81
        *ndst2++ = *nsrc2++;
82

83
    case 3:
84
        *ndst2++ = *nsrc2++;
85

86
    case 2:
87
        *ndst2++ = *nsrc2++;
88

89
    case 1:
90
        *ndst2++ = *nsrc2++;
91
    };
92

93
    *ndst2 = '\0';
94

95
    return dst;
96
}
97

98
/**
99
 * 把char转成hex
100
 */
101
char *easy_string_tohex(const char *str, int n, char *result, int size)
102
{
103
    int                     i, j = 0;
104
    static char             hexconvtab[] = "0123456789ABCDEF";
105
    const unsigned char     *p = (const unsigned char *)str;
106

107
    n = easy_min((size - 1) / 2, n);
108

109
    for (i = 0; i < n; i++) {
110
        result[j++] = hexconvtab[p[i] >> 4];
111
        result[j++] = hexconvtab[p[i] & 0xf];
112
    }
113

114
    result[j] = '\0';
115

116
    return result;
117
}
118

119
/**
120
 * 转成大写
121
 */
122
char *easy_string_toupper(char *str)
123
{
124
    char                    *p = str;
125

126
    while (*p) {
127
        if ((*p) >= 'a' && (*p) <= 'z')
128
            (*p) -= 32;
129

130
        p ++;
131
    }
132

133
    return str;
134
}
135

136
/**
137
 * 转成小写
138
 */
139
char *easy_string_tolower(char *str)
140
{
141
    char                    *p = str;
142

143
    while (*p) {
144
        if ((*p) >= 'A' && (*p) <= 'Z')
145
            (*p) += 32;
146

147
        p ++;
148
    }
149

150
    return str;
151
}
152

153
/**
154
 * 把首字母转成大写,其余转成小写
155
 */
156
char *easy_string_capitalize(char *str, int len)
157
{
158
    char                    *p = str;
159
    int                     first = 1;
160
    char                    *end = str + len;
161

162
    while (p < end) {
163
        if ((*p) >= 'A' && (*p) <= 'Z') {
164
            if (!first)(*p) += 32;
165

166
            first = 0;
167
        } else if ((*p) >= 'a' && (*p) <= 'z') {
168
            if (first)(*p) -= 32;
169

170
            first = 0;
171
        } else if ((*p) == '-' || (*p) == '_') {
172
            first = 1;
173
        }
174

175
        p ++;
176
    }
177

178
    return str;
179
}
180

181
/**
182
 * 转成byte可读的KMGTPE
183
 */
184
char *easy_string_format_size(double byte, char *buffer, int size)
185
{
186
    static const char       units[] = " KMGTPEZY";
187

188
    int                     idx = 0;
189

190
    while (byte >= 1024) {
191
        byte /= 1024;
192
        idx ++;
193
    }
194

195
    buffer[0] = '\0';
196

197
    if (idx == 0)
198
        lnprintf(buffer, size, "%.2f", byte);
199
    else if (idx < 9)
200
        lnprintf(buffer, size, "%.2f %cB", byte, units[idx]);
201

202
    return buffer;
203
}
204

205
/**
206
 * 把copy string
207
 */
208
char *easy_strcpy(char *dest, const char *src)
209
{
210
    int                     len = strlen(src);
211
    return easy_memcpy(dest, src, len);
212
}
213

214
/**
215
 * 把number转成string
216
 */
217
#define EASY_NUM_LEN 32
218
char *easy_num_to_str(char *dest, int len, uint64_t number)
219
{
220
    char                    t[EASY_NUM_LEN], *p, *end;
221

222
    p = end = t + EASY_NUM_LEN;
223

224
    if (number <= 0xffffffffU) {
225
        uint32_t                v = number;
226

227
        do {
228
            *--p = (char)(v % 10 + '0');
229
        } while (v /= 10);
230
    } else {
231
        do {
232
            *--p = (char)(number % 10 + '0');
233
        } while (number /= 10);
234
    }
235

236
    while (p < end) *dest ++ = *p ++;
237

238
    *dest = '\0';
239
    return dest;
240
}
241

242
/**
243
 * lnprintf
244
 */
245
int lnprintf(char *str, size_t size, const char *fmt, ...)
246
{
247
    int                     ret;
248
    va_list                 args;
249

250
    va_start(args, fmt);
251
    ret = easy_vsnprintf(str, size, fmt, args);
252
    va_end(args);
253

254
    return ret;
255
}
256

257
/**
258
 * easy_vsnprintf
259
 */
260
int easy_vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
261
{
262
    char                    *p, zero;
263
    double                  f, scale;
264
    int64_t                 i64;
265
    uint64_t                ui64;
266
    int                     width, sign, hex, frac_width, slen, width_sign;
267
    char                    *last, *start, *fstart;
268
    char                    length_modifier;
269

270
    start = buf;
271
    last = buf + size - 1;
272

273
    while (*fmt && buf < last) {
274

275
        if (*fmt == '%') {
276

277
            zero = (char)((*++fmt == '0') ? '0' : ' ');
278
            width_sign = ((*fmt == '-') ? (fmt++, -1) : 1);
279
            width = 0;
280
            sign = 1;
281
            hex = 0;
282
            frac_width = 6;
283
            slen = -1;
284
            length_modifier = '0';
285
            fstart = buf;
286

287
            while (*fmt >= '0' && *fmt <= '9') {
288
                width = width * 10 + *fmt++ - '0';
289
            }
290

291
            width                   *= width_sign;
292

293
            // width
294
            switch (*fmt) {
295
            case '.':
296
                fmt++;
297

298
                if (*fmt != '*') {
299
                    frac_width = 0;
300

301
                    while (*fmt >= '0' && *fmt <= '9') {
302
                        frac_width = frac_width * 10 + *fmt++ - '0';
303
                    }
304

305
                    break;
306
                }
307

308
            case '*':
309
                slen = va_arg(args, size_t);
310
                fmt++;
311
                break;
312

313
            case 'l':
314
                fmt++;
315
#ifdef _LP64
316
                length_modifier ++;
317
#endif
318

319
                if (*fmt == 'l') {
320
                    length_modifier ++;
321
                    fmt ++;
322
                }
323

324
                break;
325

326
            default:
327
                break;
328
            }
329

330
            // type
331
            switch (*fmt) {
332
            case 's':
333
                p = va_arg(args, char *);
334

335
                if (slen < 0) {
336
                    slen = last - buf;
337
                } else {
338
                    slen = easy_min(((size_t)(last - buf)), slen);
339
                }
340

341
                while (slen-- > 0 && p && *p) {
342
                    *buf++ = *p++;
343
                }
344

345
                if (width > 0 && (buf - fstart) < width) {
346
                    p = easy_min(fstart + width, last);
347
                    buf -= (fstart + width - p);
348

349
                    while (buf > fstart) {
350
                        *--p = *--buf;
351
                    }
352

353
                    while (p > fstart) *--p = ' ';
354

355
                    buf = easy_min(fstart + width, last);
356
                }
357

358
                buf = easy_fill_space(width, buf, fstart, last);
359
                fmt++;
360

361
                continue;
362

363
            case 'x':
364
                hex = 1;
365

366
            case 'X':
367
                if (!hex) hex = 2;
368

369
            case 'u':
370
                sign = 0;
371

372
                if (length_modifier == '0') {
373
                    ui64 = (uint64_t) va_arg(args, uint32_t);
374
                } else {
375
                    ui64 = (uint64_t) va_arg(args, uint64_t);
376
                }
377

378
                break;
379

380
            case 'd':
381
                if (length_modifier == '0') {
382
                    i64 = (int64_t) va_arg(args, int);
383
                } else {
384
                    i64 = (int64_t) va_arg(args, int64_t);
385
                }
386

387
                break;
388

389
            case 'f':
390
                f = va_arg(args, double);
391

392
                if (f < 0) {
393
                    sign = -1;
394
                    f = -f;
395
                } else {
396
                    sign = 0;
397
                }
398

399
                ui64 = (int64_t) f;
400

401
                slen = width - frac_width - (frac_width ? 1 : 0);
402
                buf = easy_sprintf_num(buf, last, ui64, zero, 0, slen, sign);
403

404
                if (frac_width) {
405

406
                    if (buf < last) {
407
                        *buf++ = '.';
408
                    }
409

410
                    if (frac_width > 16) frac_width = 16;
411

412
                    scale = 1.0;
413

414
                    for (sign = frac_width; sign; sign--) {
415
                        scale                   *= 10.0;
416
                    }
417

418
                    ui64 = (uint64_t)((f - (int64_t) ui64) * scale + 0.5);
419

420
                    buf = easy_sprintf_num(buf, last, ui64, '0', 0, frac_width, 0);
421
                }
422

423
                buf = easy_fill_space(width, buf, fstart, last);
424

425
                fmt++;
426

427
                continue;
428

429
            case 'p':
430
                ui64 = (uintptr_t) va_arg(args, void *);
431
                hex = 1;
432
                sign = 0;
433
                zero = '0';
434
                width = 0;
435

436
                if (buf + 2 < last) {
437
                    *buf++ = '0';
438
                    *buf++ = 'x';
439
                }
440

441
                break;
442

443
            case 'c':
444
                i64 = va_arg(args, int);
445
                *buf++ = (char)(i64 & 0xff);
446
                fmt++;
447

448
                continue;
449

450
            case '%':
451
                *buf++ = '%';
452
                fmt++;
453

454
                continue;
455

456
            default:
457
                *buf++ = *fmt++;
458

459
                continue;
460
            }
461

462
            if (sign) {
463
                if (i64 < 0) {
464
                    sign = -1;
465
                    ui64 = (uint64_t) - i64;
466
                } else {
467
                    sign = 0;
468
                    ui64 = (uint64_t) i64;
469
                }
470
            }
471

472
            buf = easy_sprintf_num(buf, last, ui64, zero, hex, width, sign);
473
            buf = easy_fill_space(width, buf, fstart, last);
474

475
            fmt++;
476

477
        } else {
478
            *buf++ = *fmt++;
479
        }
480
    }
481

482
    *buf = '\0';
483

484
    return (buf - start);
485
}
486

487
static char *easy_fill_space(int width, char *buf, char *fstart, char *last)
488
{
489
    if (width >= 0 || (buf - fstart) >= -width)
490
        return buf;
491

492
    last = easy_min(fstart - width, last);
493

494
    while (buf < last) {
495
        *buf++ = ' ';
496
    }
497

498
    return buf;
499
}
500

501
/**
502
 * 把number转成字符串
503
 */
504
static char *easy_sprintf_num(char *buf, char *last, uint64_t ui64, char zero, int hexadecimal, int width, int sign)
505
{
506
    char          *p, temp[EASY_NUM_LEN + 1];
507
    int                     len;
508
    uint32_t                ui32;
509
    static char             hex[] = "0123456789abcdef";
510
    static char             HEX[] = "0123456789ABCDEF";
511

512
    p = temp + EASY_NUM_LEN;
513

514
    if (hexadecimal == 0) {
515
        if (ui64 <= (uint32_t) 0xffffffff) {
516
            ui32 = (uint32_t) ui64;
517

518
            do {
519
                *--p = (char)(ui32 % 10 + '0');
520
            } while (ui32 /= 10);
521
        } else {
522
            do {
523
                *--p = (char)(ui64 % 10 + '0');
524
            } while (ui64 /= 10);
525
        }
526
    } else if (hexadecimal == 1) {
527

528
        do {
529
            *--p = hex[(uint32_t)(ui64 & 0xf)];
530
        } while (ui64 >>= 4);
531

532
    } else { /* hexadecimal == 2 */
533

534
        do {
535
            *--p = HEX[(uint32_t)(ui64 & 0xf)];
536
        } while (ui64 >>= 4);
537
    }
538

539
    if (sign) {
540
        if (zero == ' ') {
541
            *--p = '-';
542
        } else if (buf < last) {
543
            *buf++ = '-';
544
            width --;
545
        }
546
    }
547

548
    /* zero or space padding */
549
    len = (temp + EASY_NUM_LEN) - p;
550

551
    while (len++ < width && buf < last) {
552
        *buf++ = zero;
553
    }
554

555
    len = (temp + EASY_NUM_LEN) - p;
556

557
    if (buf + len > last) {
558
        len = last - buf;
559
    }
560

561
    return easy_memcpy(buf, p, len);
562
}
563

564

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.