18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * cifs_unicode: Unicode kernel case support 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Function: 68c2ecf20Sopenharmony_ci * Convert a unicode character to upper or lower case using 78c2ecf20Sopenharmony_ci * compressed tables. 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * Copyright (c) International Business Machines Corp., 2000,2009 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * Notes: 128c2ecf20Sopenharmony_ci * These APIs are based on the C library functions. The semantics 138c2ecf20Sopenharmony_ci * should match the C functions but with expanded size operands. 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * The upper/lower functions are based on a table created by mkupr. 168c2ecf20Sopenharmony_ci * This is a compressed table of upper and lower case conversion. 178c2ecf20Sopenharmony_ci */ 188c2ecf20Sopenharmony_ci#ifndef _CIFS_UNICODE_H 198c2ecf20Sopenharmony_ci#define _CIFS_UNICODE_H 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#include <asm/byteorder.h> 228c2ecf20Sopenharmony_ci#include <linux/types.h> 238c2ecf20Sopenharmony_ci#include <linux/nls.h> 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#define UNIUPR_NOLOWER /* Example to not expand lower case tables */ 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci/* 288c2ecf20Sopenharmony_ci * Windows maps these to the user defined 16 bit Unicode range since they are 298c2ecf20Sopenharmony_ci * reserved symbols (along with \ and /), otherwise illegal to store 308c2ecf20Sopenharmony_ci * in filenames in NTFS 318c2ecf20Sopenharmony_ci */ 328c2ecf20Sopenharmony_ci#define UNI_ASTERISK (__u16) ('*' + 0xF000) 338c2ecf20Sopenharmony_ci#define UNI_QUESTION (__u16) ('?' + 0xF000) 348c2ecf20Sopenharmony_ci#define UNI_COLON (__u16) (':' + 0xF000) 358c2ecf20Sopenharmony_ci#define UNI_GRTRTHAN (__u16) ('>' + 0xF000) 368c2ecf20Sopenharmony_ci#define UNI_LESSTHAN (__u16) ('<' + 0xF000) 378c2ecf20Sopenharmony_ci#define UNI_PIPE (__u16) ('|' + 0xF000) 388c2ecf20Sopenharmony_ci#define UNI_SLASH (__u16) ('\\' + 0xF000) 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci/* 418c2ecf20Sopenharmony_ci * Macs use an older "SFM" mapping of the symbols above. Fortunately it does 428c2ecf20Sopenharmony_ci * not conflict (although almost does) with the mapping above. 438c2ecf20Sopenharmony_ci */ 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci#define SFM_DOUBLEQUOTE ((__u16) 0xF020) 468c2ecf20Sopenharmony_ci#define SFM_ASTERISK ((__u16) 0xF021) 478c2ecf20Sopenharmony_ci#define SFM_QUESTION ((__u16) 0xF025) 488c2ecf20Sopenharmony_ci#define SFM_COLON ((__u16) 0xF022) 498c2ecf20Sopenharmony_ci#define SFM_GRTRTHAN ((__u16) 0xF024) 508c2ecf20Sopenharmony_ci#define SFM_LESSTHAN ((__u16) 0xF023) 518c2ecf20Sopenharmony_ci#define SFM_PIPE ((__u16) 0xF027) 528c2ecf20Sopenharmony_ci#define SFM_SLASH ((__u16) 0xF026) 538c2ecf20Sopenharmony_ci#define SFM_SPACE ((__u16) 0xF028) 548c2ecf20Sopenharmony_ci#define SFM_PERIOD ((__u16) 0xF029) 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci/* 578c2ecf20Sopenharmony_ci * Mapping mechanism to use when one of the seven reserved characters is 588c2ecf20Sopenharmony_ci * encountered. We can only map using one of the mechanisms at a time 598c2ecf20Sopenharmony_ci * since otherwise readdir could return directory entries which we would 608c2ecf20Sopenharmony_ci * not be able to open 618c2ecf20Sopenharmony_ci * 628c2ecf20Sopenharmony_ci * NO_MAP_UNI_RSVD = do not perform any remapping of the character 638c2ecf20Sopenharmony_ci * SFM_MAP_UNI_RSVD = map reserved characters using SFM scheme (MAC compatible) 648c2ecf20Sopenharmony_ci * SFU_MAP_UNI_RSVD = map reserved characters ala SFU ("mapchars" option) 658c2ecf20Sopenharmony_ci * 668c2ecf20Sopenharmony_ci */ 678c2ecf20Sopenharmony_ci#define NO_MAP_UNI_RSVD 0 688c2ecf20Sopenharmony_ci#define SFM_MAP_UNI_RSVD 1 698c2ecf20Sopenharmony_ci#define SFU_MAP_UNI_RSVD 2 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci/* Just define what we want from uniupr.h. We don't want to define the tables 728c2ecf20Sopenharmony_ci * in each source file. 738c2ecf20Sopenharmony_ci */ 748c2ecf20Sopenharmony_ci#ifndef UNICASERANGE_DEFINED 758c2ecf20Sopenharmony_cistruct UniCaseRange { 768c2ecf20Sopenharmony_ci wchar_t start; 778c2ecf20Sopenharmony_ci wchar_t end; 788c2ecf20Sopenharmony_ci signed char *table; 798c2ecf20Sopenharmony_ci}; 808c2ecf20Sopenharmony_ci#endif /* UNICASERANGE_DEFINED */ 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci#ifndef UNIUPR_NOUPPER 838c2ecf20Sopenharmony_ciextern signed char CifsUniUpperTable[512]; 848c2ecf20Sopenharmony_ciextern const struct UniCaseRange CifsUniUpperRange[]; 858c2ecf20Sopenharmony_ci#endif /* UNIUPR_NOUPPER */ 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci#ifndef UNIUPR_NOLOWER 888c2ecf20Sopenharmony_ciextern signed char CifsUniLowerTable[512]; 898c2ecf20Sopenharmony_ciextern const struct UniCaseRange CifsUniLowerRange[]; 908c2ecf20Sopenharmony_ci#endif /* UNIUPR_NOLOWER */ 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci#ifdef __KERNEL__ 938c2ecf20Sopenharmony_ciint cifs_from_utf16(char *to, const __le16 *from, int tolen, int fromlen, 948c2ecf20Sopenharmony_ci const struct nls_table *cp, int map_type); 958c2ecf20Sopenharmony_ciint cifs_utf16_bytes(const __le16 *from, int maxbytes, 968c2ecf20Sopenharmony_ci const struct nls_table *codepage); 978c2ecf20Sopenharmony_ciint cifs_strtoUTF16(__le16 *, const char *, int, const struct nls_table *); 988c2ecf20Sopenharmony_cichar *cifs_strndup_from_utf16(const char *src, const int maxlen, 998c2ecf20Sopenharmony_ci const bool is_unicode, 1008c2ecf20Sopenharmony_ci const struct nls_table *codepage); 1018c2ecf20Sopenharmony_ciextern int cifsConvertToUTF16(__le16 *target, const char *source, int maxlen, 1028c2ecf20Sopenharmony_ci const struct nls_table *cp, int mapChars); 1038c2ecf20Sopenharmony_ciextern int cifs_remap(struct cifs_sb_info *cifs_sb); 1048c2ecf20Sopenharmony_ciextern __le16 *cifs_strndup_to_utf16(const char *src, const int maxlen, 1058c2ecf20Sopenharmony_ci int *utf16_len, const struct nls_table *cp, 1068c2ecf20Sopenharmony_ci int remap); 1078c2ecf20Sopenharmony_ci#endif 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ciwchar_t cifs_toupper(wchar_t in); 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci/* 1128c2ecf20Sopenharmony_ci * UniStrcat: Concatenate the second string to the first 1138c2ecf20Sopenharmony_ci * 1148c2ecf20Sopenharmony_ci * Returns: 1158c2ecf20Sopenharmony_ci * Address of the first string 1168c2ecf20Sopenharmony_ci */ 1178c2ecf20Sopenharmony_cistatic inline __le16 * 1188c2ecf20Sopenharmony_ciUniStrcat(__le16 *ucs1, const __le16 *ucs2) 1198c2ecf20Sopenharmony_ci{ 1208c2ecf20Sopenharmony_ci __le16 *anchor = ucs1; /* save a pointer to start of ucs1 */ 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci while (*ucs1++) ; /* To end of first string */ 1238c2ecf20Sopenharmony_ci ucs1--; /* Return to the null */ 1248c2ecf20Sopenharmony_ci while ((*ucs1++ = *ucs2++)) ; /* copy string 2 over */ 1258c2ecf20Sopenharmony_ci return anchor; 1268c2ecf20Sopenharmony_ci} 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci/* 1298c2ecf20Sopenharmony_ci * UniStrchr: Find a character in a string 1308c2ecf20Sopenharmony_ci * 1318c2ecf20Sopenharmony_ci * Returns: 1328c2ecf20Sopenharmony_ci * Address of first occurrence of character in string 1338c2ecf20Sopenharmony_ci * or NULL if the character is not in the string 1348c2ecf20Sopenharmony_ci */ 1358c2ecf20Sopenharmony_cistatic inline wchar_t * 1368c2ecf20Sopenharmony_ciUniStrchr(const wchar_t *ucs, wchar_t uc) 1378c2ecf20Sopenharmony_ci{ 1388c2ecf20Sopenharmony_ci while ((*ucs != uc) && *ucs) 1398c2ecf20Sopenharmony_ci ucs++; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci if (*ucs == uc) 1428c2ecf20Sopenharmony_ci return (wchar_t *) ucs; 1438c2ecf20Sopenharmony_ci return NULL; 1448c2ecf20Sopenharmony_ci} 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci/* 1478c2ecf20Sopenharmony_ci * UniStrcmp: Compare two strings 1488c2ecf20Sopenharmony_ci * 1498c2ecf20Sopenharmony_ci * Returns: 1508c2ecf20Sopenharmony_ci * < 0: First string is less than second 1518c2ecf20Sopenharmony_ci * = 0: Strings are equal 1528c2ecf20Sopenharmony_ci * > 0: First string is greater than second 1538c2ecf20Sopenharmony_ci */ 1548c2ecf20Sopenharmony_cistatic inline int 1558c2ecf20Sopenharmony_ciUniStrcmp(const wchar_t *ucs1, const wchar_t *ucs2) 1568c2ecf20Sopenharmony_ci{ 1578c2ecf20Sopenharmony_ci while ((*ucs1 == *ucs2) && *ucs1) { 1588c2ecf20Sopenharmony_ci ucs1++; 1598c2ecf20Sopenharmony_ci ucs2++; 1608c2ecf20Sopenharmony_ci } 1618c2ecf20Sopenharmony_ci return (int) *ucs1 - (int) *ucs2; 1628c2ecf20Sopenharmony_ci} 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci/* 1658c2ecf20Sopenharmony_ci * UniStrcpy: Copy a string 1668c2ecf20Sopenharmony_ci */ 1678c2ecf20Sopenharmony_cistatic inline wchar_t * 1688c2ecf20Sopenharmony_ciUniStrcpy(wchar_t *ucs1, const wchar_t *ucs2) 1698c2ecf20Sopenharmony_ci{ 1708c2ecf20Sopenharmony_ci wchar_t *anchor = ucs1; /* save the start of result string */ 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci while ((*ucs1++ = *ucs2++)) ; 1738c2ecf20Sopenharmony_ci return anchor; 1748c2ecf20Sopenharmony_ci} 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci/* 1778c2ecf20Sopenharmony_ci * UniStrlen: Return the length of a string (in 16 bit Unicode chars not bytes) 1788c2ecf20Sopenharmony_ci */ 1798c2ecf20Sopenharmony_cistatic inline size_t 1808c2ecf20Sopenharmony_ciUniStrlen(const wchar_t *ucs1) 1818c2ecf20Sopenharmony_ci{ 1828c2ecf20Sopenharmony_ci int i = 0; 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci while (*ucs1++) 1858c2ecf20Sopenharmony_ci i++; 1868c2ecf20Sopenharmony_ci return i; 1878c2ecf20Sopenharmony_ci} 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci/* 1908c2ecf20Sopenharmony_ci * UniStrnlen: Return the length (in 16 bit Unicode chars not bytes) of a 1918c2ecf20Sopenharmony_ci * string (length limited) 1928c2ecf20Sopenharmony_ci */ 1938c2ecf20Sopenharmony_cistatic inline size_t 1948c2ecf20Sopenharmony_ciUniStrnlen(const wchar_t *ucs1, int maxlen) 1958c2ecf20Sopenharmony_ci{ 1968c2ecf20Sopenharmony_ci int i = 0; 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci while (*ucs1++) { 1998c2ecf20Sopenharmony_ci i++; 2008c2ecf20Sopenharmony_ci if (i >= maxlen) 2018c2ecf20Sopenharmony_ci break; 2028c2ecf20Sopenharmony_ci } 2038c2ecf20Sopenharmony_ci return i; 2048c2ecf20Sopenharmony_ci} 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci/* 2078c2ecf20Sopenharmony_ci * UniStrncat: Concatenate length limited string 2088c2ecf20Sopenharmony_ci */ 2098c2ecf20Sopenharmony_cistatic inline wchar_t * 2108c2ecf20Sopenharmony_ciUniStrncat(wchar_t *ucs1, const wchar_t *ucs2, size_t n) 2118c2ecf20Sopenharmony_ci{ 2128c2ecf20Sopenharmony_ci wchar_t *anchor = ucs1; /* save pointer to string 1 */ 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci while (*ucs1++) ; 2158c2ecf20Sopenharmony_ci ucs1--; /* point to null terminator of s1 */ 2168c2ecf20Sopenharmony_ci while (n-- && (*ucs1 = *ucs2)) { /* copy s2 after s1 */ 2178c2ecf20Sopenharmony_ci ucs1++; 2188c2ecf20Sopenharmony_ci ucs2++; 2198c2ecf20Sopenharmony_ci } 2208c2ecf20Sopenharmony_ci *ucs1 = 0; /* Null terminate the result */ 2218c2ecf20Sopenharmony_ci return (anchor); 2228c2ecf20Sopenharmony_ci} 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci/* 2258c2ecf20Sopenharmony_ci * UniStrncmp: Compare length limited string 2268c2ecf20Sopenharmony_ci */ 2278c2ecf20Sopenharmony_cistatic inline int 2288c2ecf20Sopenharmony_ciUniStrncmp(const wchar_t *ucs1, const wchar_t *ucs2, size_t n) 2298c2ecf20Sopenharmony_ci{ 2308c2ecf20Sopenharmony_ci if (!n) 2318c2ecf20Sopenharmony_ci return 0; /* Null strings are equal */ 2328c2ecf20Sopenharmony_ci while ((*ucs1 == *ucs2) && *ucs1 && --n) { 2338c2ecf20Sopenharmony_ci ucs1++; 2348c2ecf20Sopenharmony_ci ucs2++; 2358c2ecf20Sopenharmony_ci } 2368c2ecf20Sopenharmony_ci return (int) *ucs1 - (int) *ucs2; 2378c2ecf20Sopenharmony_ci} 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci/* 2408c2ecf20Sopenharmony_ci * UniStrncmp_le: Compare length limited string - native to little-endian 2418c2ecf20Sopenharmony_ci */ 2428c2ecf20Sopenharmony_cistatic inline int 2438c2ecf20Sopenharmony_ciUniStrncmp_le(const wchar_t *ucs1, const wchar_t *ucs2, size_t n) 2448c2ecf20Sopenharmony_ci{ 2458c2ecf20Sopenharmony_ci if (!n) 2468c2ecf20Sopenharmony_ci return 0; /* Null strings are equal */ 2478c2ecf20Sopenharmony_ci while ((*ucs1 == __le16_to_cpu(*ucs2)) && *ucs1 && --n) { 2488c2ecf20Sopenharmony_ci ucs1++; 2498c2ecf20Sopenharmony_ci ucs2++; 2508c2ecf20Sopenharmony_ci } 2518c2ecf20Sopenharmony_ci return (int) *ucs1 - (int) __le16_to_cpu(*ucs2); 2528c2ecf20Sopenharmony_ci} 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci/* 2558c2ecf20Sopenharmony_ci * UniStrncpy: Copy length limited string with pad 2568c2ecf20Sopenharmony_ci */ 2578c2ecf20Sopenharmony_cistatic inline wchar_t * 2588c2ecf20Sopenharmony_ciUniStrncpy(wchar_t *ucs1, const wchar_t *ucs2, size_t n) 2598c2ecf20Sopenharmony_ci{ 2608c2ecf20Sopenharmony_ci wchar_t *anchor = ucs1; 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci while (n-- && *ucs2) /* Copy the strings */ 2638c2ecf20Sopenharmony_ci *ucs1++ = *ucs2++; 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci n++; 2668c2ecf20Sopenharmony_ci while (n--) /* Pad with nulls */ 2678c2ecf20Sopenharmony_ci *ucs1++ = 0; 2688c2ecf20Sopenharmony_ci return anchor; 2698c2ecf20Sopenharmony_ci} 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci/* 2728c2ecf20Sopenharmony_ci * UniStrncpy_le: Copy length limited string with pad to little-endian 2738c2ecf20Sopenharmony_ci */ 2748c2ecf20Sopenharmony_cistatic inline wchar_t * 2758c2ecf20Sopenharmony_ciUniStrncpy_le(wchar_t *ucs1, const wchar_t *ucs2, size_t n) 2768c2ecf20Sopenharmony_ci{ 2778c2ecf20Sopenharmony_ci wchar_t *anchor = ucs1; 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci while (n-- && *ucs2) /* Copy the strings */ 2808c2ecf20Sopenharmony_ci *ucs1++ = __le16_to_cpu(*ucs2++); 2818c2ecf20Sopenharmony_ci 2828c2ecf20Sopenharmony_ci n++; 2838c2ecf20Sopenharmony_ci while (n--) /* Pad with nulls */ 2848c2ecf20Sopenharmony_ci *ucs1++ = 0; 2858c2ecf20Sopenharmony_ci return anchor; 2868c2ecf20Sopenharmony_ci} 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci/* 2898c2ecf20Sopenharmony_ci * UniStrstr: Find a string in a string 2908c2ecf20Sopenharmony_ci * 2918c2ecf20Sopenharmony_ci * Returns: 2928c2ecf20Sopenharmony_ci * Address of first match found 2938c2ecf20Sopenharmony_ci * NULL if no matching string is found 2948c2ecf20Sopenharmony_ci */ 2958c2ecf20Sopenharmony_cistatic inline wchar_t * 2968c2ecf20Sopenharmony_ciUniStrstr(const wchar_t *ucs1, const wchar_t *ucs2) 2978c2ecf20Sopenharmony_ci{ 2988c2ecf20Sopenharmony_ci const wchar_t *anchor1 = ucs1; 2998c2ecf20Sopenharmony_ci const wchar_t *anchor2 = ucs2; 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci while (*ucs1) { 3028c2ecf20Sopenharmony_ci if (*ucs1 == *ucs2) { 3038c2ecf20Sopenharmony_ci /* Partial match found */ 3048c2ecf20Sopenharmony_ci ucs1++; 3058c2ecf20Sopenharmony_ci ucs2++; 3068c2ecf20Sopenharmony_ci } else { 3078c2ecf20Sopenharmony_ci if (!*ucs2) /* Match found */ 3088c2ecf20Sopenharmony_ci return (wchar_t *) anchor1; 3098c2ecf20Sopenharmony_ci ucs1 = ++anchor1; /* No match */ 3108c2ecf20Sopenharmony_ci ucs2 = anchor2; 3118c2ecf20Sopenharmony_ci } 3128c2ecf20Sopenharmony_ci } 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ci if (!*ucs2) /* Both end together */ 3158c2ecf20Sopenharmony_ci return (wchar_t *) anchor1; /* Match found */ 3168c2ecf20Sopenharmony_ci return NULL; /* No match */ 3178c2ecf20Sopenharmony_ci} 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_ci#ifndef UNIUPR_NOUPPER 3208c2ecf20Sopenharmony_ci/* 3218c2ecf20Sopenharmony_ci * UniToupper: Convert a unicode character to upper case 3228c2ecf20Sopenharmony_ci */ 3238c2ecf20Sopenharmony_cistatic inline wchar_t 3248c2ecf20Sopenharmony_ciUniToupper(register wchar_t uc) 3258c2ecf20Sopenharmony_ci{ 3268c2ecf20Sopenharmony_ci register const struct UniCaseRange *rp; 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci if (uc < sizeof(CifsUniUpperTable)) { 3298c2ecf20Sopenharmony_ci /* Latin characters */ 3308c2ecf20Sopenharmony_ci return uc + CifsUniUpperTable[uc]; /* Use base tables */ 3318c2ecf20Sopenharmony_ci } else { 3328c2ecf20Sopenharmony_ci rp = CifsUniUpperRange; /* Use range tables */ 3338c2ecf20Sopenharmony_ci while (rp->start) { 3348c2ecf20Sopenharmony_ci if (uc < rp->start) /* Before start of range */ 3358c2ecf20Sopenharmony_ci return uc; /* Uppercase = input */ 3368c2ecf20Sopenharmony_ci if (uc <= rp->end) /* In range */ 3378c2ecf20Sopenharmony_ci return uc + rp->table[uc - rp->start]; 3388c2ecf20Sopenharmony_ci rp++; /* Try next range */ 3398c2ecf20Sopenharmony_ci } 3408c2ecf20Sopenharmony_ci } 3418c2ecf20Sopenharmony_ci return uc; /* Past last range */ 3428c2ecf20Sopenharmony_ci} 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci/* 3458c2ecf20Sopenharmony_ci * UniStrupr: Upper case a unicode string 3468c2ecf20Sopenharmony_ci */ 3478c2ecf20Sopenharmony_cistatic inline __le16 * 3488c2ecf20Sopenharmony_ciUniStrupr(register __le16 *upin) 3498c2ecf20Sopenharmony_ci{ 3508c2ecf20Sopenharmony_ci register __le16 *up; 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci up = upin; 3538c2ecf20Sopenharmony_ci while (*up) { /* For all characters */ 3548c2ecf20Sopenharmony_ci *up = cpu_to_le16(UniToupper(le16_to_cpu(*up))); 3558c2ecf20Sopenharmony_ci up++; 3568c2ecf20Sopenharmony_ci } 3578c2ecf20Sopenharmony_ci return upin; /* Return input pointer */ 3588c2ecf20Sopenharmony_ci} 3598c2ecf20Sopenharmony_ci#endif /* UNIUPR_NOUPPER */ 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci#ifndef UNIUPR_NOLOWER 3628c2ecf20Sopenharmony_ci/* 3638c2ecf20Sopenharmony_ci * UniTolower: Convert a unicode character to lower case 3648c2ecf20Sopenharmony_ci */ 3658c2ecf20Sopenharmony_cistatic inline wchar_t 3668c2ecf20Sopenharmony_ciUniTolower(register wchar_t uc) 3678c2ecf20Sopenharmony_ci{ 3688c2ecf20Sopenharmony_ci register const struct UniCaseRange *rp; 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci if (uc < sizeof(CifsUniLowerTable)) { 3718c2ecf20Sopenharmony_ci /* Latin characters */ 3728c2ecf20Sopenharmony_ci return uc + CifsUniLowerTable[uc]; /* Use base tables */ 3738c2ecf20Sopenharmony_ci } else { 3748c2ecf20Sopenharmony_ci rp = CifsUniLowerRange; /* Use range tables */ 3758c2ecf20Sopenharmony_ci while (rp->start) { 3768c2ecf20Sopenharmony_ci if (uc < rp->start) /* Before start of range */ 3778c2ecf20Sopenharmony_ci return uc; /* Uppercase = input */ 3788c2ecf20Sopenharmony_ci if (uc <= rp->end) /* In range */ 3798c2ecf20Sopenharmony_ci return uc + rp->table[uc - rp->start]; 3808c2ecf20Sopenharmony_ci rp++; /* Try next range */ 3818c2ecf20Sopenharmony_ci } 3828c2ecf20Sopenharmony_ci } 3838c2ecf20Sopenharmony_ci return uc; /* Past last range */ 3848c2ecf20Sopenharmony_ci} 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci/* 3878c2ecf20Sopenharmony_ci * UniStrlwr: Lower case a unicode string 3888c2ecf20Sopenharmony_ci */ 3898c2ecf20Sopenharmony_cistatic inline wchar_t * 3908c2ecf20Sopenharmony_ciUniStrlwr(register wchar_t *upin) 3918c2ecf20Sopenharmony_ci{ 3928c2ecf20Sopenharmony_ci register wchar_t *up; 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_ci up = upin; 3958c2ecf20Sopenharmony_ci while (*up) { /* For all characters */ 3968c2ecf20Sopenharmony_ci *up = UniTolower(*up); 3978c2ecf20Sopenharmony_ci up++; 3988c2ecf20Sopenharmony_ci } 3998c2ecf20Sopenharmony_ci return upin; /* Return input pointer */ 4008c2ecf20Sopenharmony_ci} 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci#endif 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_ci#endif /* _CIFS_UNICODE_H */ 405