^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) International Business Machines Corp., 2000-2002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Portions Copyright (C) Christoph Hellwig, 2001-2002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #ifndef _H_JFS_UNICODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #define _H_JFS_UNICODE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/byteorder.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "jfs_types.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) typedef struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) wchar_t start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) wchar_t end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) signed char *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) } UNICASERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) extern signed char UniUpperTable[512];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) extern UNICASERANGE UniUpperRange[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) extern int get_UCSname(struct component_name *, struct dentry *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) extern int jfs_strfromUCS_le(char *, const __le16 *, int, struct nls_table *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define free_UCSname(COMP) kfree((COMP)->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * UniStrcpy: Copy a string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static inline wchar_t *UniStrcpy(wchar_t * ucs1, const wchar_t * ucs2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) wchar_t *anchor = ucs1; /* save the start of result string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) while ((*ucs1++ = *ucs2++));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) return anchor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * UniStrncpy: Copy length limited string with pad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static inline __le16 *UniStrncpy_le(__le16 * ucs1, const __le16 * ucs2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) __le16 *anchor = ucs1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) while (n-- && *ucs2) /* Copy the strings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) *ucs1++ = *ucs2++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) while (n--) /* Pad with nulls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) *ucs1++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return anchor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * UniStrncmp_le: Compare length limited string - native to little-endian
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static inline int UniStrncmp_le(const wchar_t * ucs1, const __le16 * ucs2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (!n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return 0; /* Null strings are equal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) while ((*ucs1 == __le16_to_cpu(*ucs2)) && *ucs1 && --n) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) ucs1++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) ucs2++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return (int) *ucs1 - (int) __le16_to_cpu(*ucs2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * UniStrncpy_to_le: Copy length limited string with pad to little-endian
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static inline __le16 *UniStrncpy_to_le(__le16 * ucs1, const wchar_t * ucs2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) __le16 *anchor = ucs1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) while (n-- && *ucs2) /* Copy the strings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) *ucs1++ = cpu_to_le16(*ucs2++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) while (n--) /* Pad with nulls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) *ucs1++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return anchor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * UniStrncpy_from_le: Copy length limited string with pad from little-endian
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static inline wchar_t *UniStrncpy_from_le(wchar_t * ucs1, const __le16 * ucs2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) size_t n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) wchar_t *anchor = ucs1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) while (n-- && *ucs2) /* Copy the strings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) *ucs1++ = __le16_to_cpu(*ucs2++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) while (n--) /* Pad with nulls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) *ucs1++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return anchor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * UniToupper: Convert a unicode character to upper case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static inline wchar_t UniToupper(wchar_t uc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) UNICASERANGE *rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (uc < sizeof(UniUpperTable)) { /* Latin characters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) return uc + UniUpperTable[uc]; /* Use base tables */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) rp = UniUpperRange; /* Use range tables */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) while (rp->start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (uc < rp->start) /* Before start of range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return uc; /* Uppercase = input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (uc <= rp->end) /* In range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) return uc + rp->table[uc - rp->start];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) rp++; /* Try next range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return uc; /* Past last range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * UniStrupr: Upper case a unicode string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static inline wchar_t *UniStrupr(wchar_t * upin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) wchar_t *up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) up = upin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) while (*up) { /* For all characters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) *up = UniToupper(*up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) up++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return upin; /* Return input pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #endif /* !_H_JFS_UNICODE */