1 // SPDX-License-Identifier: LGPL-2.1-or-later 2 /* 3 * Copyright (C) 2022-2024 Cyril Hrubis <metan@ucw.cz> 4 */ 5 6 #include <stddef.h> 7 #include <ujson_utf.h> 8 ujson_utf8_next_chsz(const char * str,size_t off)9int8_t ujson_utf8_next_chsz(const char *str, size_t off) 10 { 11 char ch = str[off]; 12 uint8_t len = 0; 13 14 if (!ch) 15 return 0; 16 17 if (UJSON_UTF8_IS_ASCII(ch)) 18 return 1; 19 20 if (UJSON_UTF8_IS_2BYTE(ch)) { 21 len = 2; 22 goto ret; 23 } 24 25 if (UJSON_UTF8_IS_3BYTE(ch)) { 26 len = 3; 27 goto ret; 28 } 29 30 if (UJSON_UTF8_IS_4BYTE(ch)) { 31 len = 4; 32 goto ret; 33 } 34 35 return -1; 36 ret: 37 if (!UJSON_UTF8_IS_NBYTE(str[off+1])) 38 return -1; 39 40 if (len > 2 && !UJSON_UTF8_IS_NBYTE(str[off+2])) 41 return -1; 42 43 if (len > 3 && !UJSON_UTF8_IS_NBYTE(str[off+3])) 44 return -1; 45 46 return len; 47 } 48 ujson_utf8_prev_chsz(const char * str,size_t off)49int8_t ujson_utf8_prev_chsz(const char *str, size_t off) 50 { 51 char ch; 52 53 if (!off) 54 return 0; 55 56 ch = str[--off]; 57 58 if (UJSON_UTF8_IS_ASCII(ch)) 59 return 1; 60 61 if (!UJSON_UTF8_IS_NBYTE(ch)) 62 return -1; 63 64 if (off < 1) 65 return -1; 66 67 ch = str[--off]; 68 69 if (UJSON_UTF8_IS_2BYTE(ch)) 70 return 2; 71 72 if (!UJSON_UTF8_IS_NBYTE(ch)) 73 return -1; 74 75 if (off < 1) 76 return -1; 77 78 ch = str[--off]; 79 80 if (UJSON_UTF8_IS_3BYTE(ch)) 81 return 3; 82 83 if (!UJSON_UTF8_IS_NBYTE(ch)) 84 return -1; 85 86 if (off < 1) 87 return -1; 88 89 ch = str[--off]; 90 91 if (UJSON_UTF8_IS_4BYTE(ch)) 92 return 4; 93 94 return -1; 95 } 96 ujson_utf8_strlen(const char * str)97size_t ujson_utf8_strlen(const char *str) 98 { 99 size_t cnt = 0; 100 101 while (ujson_utf8_next(&str)) 102 cnt++; 103 104 return cnt; 105 } 106