ucs2_string.c (2534B)
1// SPDX-License-Identifier: GPL-2.0 2#include <linux/ucs2_string.h> 3#include <linux/module.h> 4 5/* Return the number of unicode characters in data */ 6unsigned long 7ucs2_strnlen(const ucs2_char_t *s, size_t maxlength) 8{ 9 unsigned long length = 0; 10 11 while (*s++ != 0 && length < maxlength) 12 length++; 13 return length; 14} 15EXPORT_SYMBOL(ucs2_strnlen); 16 17unsigned long 18ucs2_strlen(const ucs2_char_t *s) 19{ 20 return ucs2_strnlen(s, ~0UL); 21} 22EXPORT_SYMBOL(ucs2_strlen); 23 24/* 25 * Return the number of bytes is the length of this string 26 * Note: this is NOT the same as the number of unicode characters 27 */ 28unsigned long 29ucs2_strsize(const ucs2_char_t *data, unsigned long maxlength) 30{ 31 return ucs2_strnlen(data, maxlength/sizeof(ucs2_char_t)) * sizeof(ucs2_char_t); 32} 33EXPORT_SYMBOL(ucs2_strsize); 34 35int 36ucs2_strncmp(const ucs2_char_t *a, const ucs2_char_t *b, size_t len) 37{ 38 while (1) { 39 if (len == 0) 40 return 0; 41 if (*a < *b) 42 return -1; 43 if (*a > *b) 44 return 1; 45 if (*a == 0) /* implies *b == 0 */ 46 return 0; 47 a++; 48 b++; 49 len--; 50 } 51} 52EXPORT_SYMBOL(ucs2_strncmp); 53 54unsigned long 55ucs2_utf8size(const ucs2_char_t *src) 56{ 57 unsigned long i; 58 unsigned long j = 0; 59 60 for (i = 0; src[i]; i++) { 61 u16 c = src[i]; 62 63 if (c >= 0x800) 64 j += 3; 65 else if (c >= 0x80) 66 j += 2; 67 else 68 j += 1; 69 } 70 71 return j; 72} 73EXPORT_SYMBOL(ucs2_utf8size); 74 75/* 76 * copy at most maxlength bytes of whole utf8 characters to dest from the 77 * ucs2 string src. 78 * 79 * The return value is the number of characters copied, not including the 80 * final NUL character. 81 */ 82unsigned long 83ucs2_as_utf8(u8 *dest, const ucs2_char_t *src, unsigned long maxlength) 84{ 85 unsigned int i; 86 unsigned long j = 0; 87 unsigned long limit = ucs2_strnlen(src, maxlength); 88 89 for (i = 0; maxlength && i < limit; i++) { 90 u16 c = src[i]; 91 92 if (c >= 0x800) { 93 if (maxlength < 3) 94 break; 95 maxlength -= 3; 96 dest[j++] = 0xe0 | (c & 0xf000) >> 12; 97 dest[j++] = 0x80 | (c & 0x0fc0) >> 6; 98 dest[j++] = 0x80 | (c & 0x003f); 99 } else if (c >= 0x80) { 100 if (maxlength < 2) 101 break; 102 maxlength -= 2; 103 dest[j++] = 0xc0 | (c & 0x7c0) >> 6; 104 dest[j++] = 0x80 | (c & 0x03f); 105 } else { 106 maxlength -= 1; 107 dest[j++] = c & 0x7f; 108 } 109 } 110 if (maxlength) 111 dest[j] = '\0'; 112 return j; 113} 114EXPORT_SYMBOL(ucs2_as_utf8); 115 116MODULE_LICENSE("GPL v2");