Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  linux/fs/hfsplus/unicode.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Brad Boyer (flar@allandria.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * (C) 2003 Ardis Technologies <roman@ardistech.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Handler routines for unicode strings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/nls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "hfsplus_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "hfsplus_raw.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) /* Fold the case of a unicode char, given the 16 bit value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) /* Returns folded char, or 0 if ignorable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) static inline u16 case_fold(u16 c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	u16 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	tmp = hfsplus_case_fold_table[c >> 8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	if (tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 		tmp = hfsplus_case_fold_table[tmp + (c & 0xff)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 		tmp = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	return tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) /* Compare unicode strings, return values like normal strcmp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) int hfsplus_strcasecmp(const struct hfsplus_unistr *s1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 		       const struct hfsplus_unistr *s2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	u16 len1, len2, c1, c2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	const hfsplus_unichr *p1, *p2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	len1 = be16_to_cpu(s1->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	len2 = be16_to_cpu(s2->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	p1 = s1->unicode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	p2 = s2->unicode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		c1 = c2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		while (len1 && !c1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 			c1 = case_fold(be16_to_cpu(*p1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 			p1++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 			len1--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		while (len2 && !c2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 			c2 = case_fold(be16_to_cpu(*p2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 			p2++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 			len2--;
^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) 		if (c1 != c2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 			return (c1 < c2) ? -1 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		if (!c1 && !c2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) /* Compare names as a sequence of 16-bit unsigned integers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) int hfsplus_strcmp(const struct hfsplus_unistr *s1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		   const struct hfsplus_unistr *s2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	u16 len1, len2, c1, c2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	const hfsplus_unichr *p1, *p2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	len1 = be16_to_cpu(s1->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	len2 = be16_to_cpu(s2->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	p1 = s1->unicode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	p2 = s2->unicode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	for (len = min(len1, len2); len > 0; len--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		c1 = be16_to_cpu(*p1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		c2 = be16_to_cpu(*p2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		if (c1 != c2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 			return c1 < c2 ? -1 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		p1++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		p2++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	return len1 < len2 ? -1 :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	       len1 > len2 ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) #define Hangul_SBase	0xac00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) #define Hangul_LBase	0x1100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) #define Hangul_VBase	0x1161
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) #define Hangul_TBase	0x11a7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) #define Hangul_SCount	11172
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) #define Hangul_LCount	19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) #define Hangul_VCount	21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) #define Hangul_TCount	28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) #define Hangul_NCount	(Hangul_VCount * Hangul_TCount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static u16 *hfsplus_compose_lookup(u16 *p, u16 cc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	int i, s, e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	s = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	e = p[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	if (!e || cc < p[s * 2] || cc > p[e * 2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		i = (s + e) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		if (cc > p[i * 2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			s = i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		else if (cc < p[i * 2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			e = i - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 			return hfsplus_compose_table + p[i * 2 + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	} while (s <= e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int hfsplus_uni2asc(struct super_block *sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		const struct hfsplus_unistr *ustr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		char *astr, int *len_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	const hfsplus_unichr *ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	struct nls_table *nls = HFSPLUS_SB(sb)->nls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	u8 *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	u16 cc, c0, c1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	u16 *ce1, *ce2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	int i, len, ustrlen, res, compose;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	op = astr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	ip = ustr->unicode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	ustrlen = be16_to_cpu(ustr->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	len = *len_p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	ce1 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	compose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	while (ustrlen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		c0 = be16_to_cpu(*ip++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		ustrlen--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		/* search for single decomposed char */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		if (likely(compose))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 			ce1 = hfsplus_compose_lookup(hfsplus_compose_table, c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		if (ce1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 			cc = ce1[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			cc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		if (cc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 			/* start of a possibly decomposed Hangul char */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 			if (cc != 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 			if (!ustrlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 				goto same;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 			c1 = be16_to_cpu(*ip) - Hangul_VBase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			if (c1 < Hangul_VCount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 				/* compose the Hangul char */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 				cc = (c0 - Hangul_LBase) * Hangul_VCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 				cc = (cc + c1) * Hangul_TCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 				cc += Hangul_SBase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 				ip++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 				ustrlen--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 				if (!ustrlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 					goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 				c1 = be16_to_cpu(*ip) - Hangul_TBase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 				if (c1 > 0 && c1 < Hangul_TCount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 					cc += c1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 					ip++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 					ustrlen--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 			/* main loop for common case of not composed chars */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 			if (!ustrlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 				goto same;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			c1 = be16_to_cpu(*ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 			if (likely(compose))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 				ce1 = hfsplus_compose_lookup(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 					hfsplus_compose_table, c1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 			if (ce1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 			switch (c0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 			case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 				c0 = 0x2400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 			case '/':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 				c0 = ':';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 			res = nls->uni2char(c0, op, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 			if (res < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 				if (res == -ENAMETOOLONG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 					goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 				*op = '?';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 				res = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			op += res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 			len -= res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			c0 = c1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 			ip++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			ustrlen--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		ce2 = hfsplus_compose_lookup(ce1, c0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		if (ce2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 			i = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 			while (i < ustrlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 				ce1 = hfsplus_compose_lookup(ce2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 					be16_to_cpu(ip[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 				if (!ce1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 				i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 				ce2 = ce1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			cc = ce2[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 			if (cc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 				ip += i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 				ustrlen -= i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) same:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		switch (c0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 			cc = 0x2400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		case '/':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			cc = ':';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 			cc = c0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		res = nls->uni2char(cc, op, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		if (res < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			if (res == -ENAMETOOLONG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 			*op = '?';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 			res = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		op += res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		len -= res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	res = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	*len_p = (char *)op - astr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)  * Convert one or more ASCII characters into a single unicode character.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)  * Returns the number of ASCII characters corresponding to the unicode char.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) static inline int asc2unichar(struct super_block *sb, const char *astr, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 			      wchar_t *uc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	int size = HFSPLUS_SB(sb)->nls->char2uni(astr, len, uc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	if (size <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		*uc = '?';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		size = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	switch (*uc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	case 0x2400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		*uc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	case ':':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		*uc = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* Decomposes a non-Hangul unicode character. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static u16 *hfsplus_decompose_nonhangul(wchar_t uc, int *size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	int off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	off = hfsplus_decompose_table[(uc >> 12) & 0xf];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	if (off == 0 || off == 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	off = hfsplus_decompose_table[off + ((uc >> 8) & 0xf)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	if (!off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	off = hfsplus_decompose_table[off + ((uc >> 4) & 0xf)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	if (!off)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	off = hfsplus_decompose_table[off + (uc & 0xf)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	*size = off & 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	if (*size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	return hfsplus_decompose_table + (off / 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)  * Try to decompose a unicode character as Hangul. Return 0 if @uc is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)  * precomposed Hangul, otherwise return the length of the decomposition.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)  * This function was adapted from sample code from the Unicode Standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)  * Annex #15: Unicode Normalization Forms, version 3.2.0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)  * Copyright (C) 1991-2018 Unicode, Inc.  All rights reserved.  Distributed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)  * under the Terms of Use in http://www.unicode.org/copyright.html.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static int hfsplus_try_decompose_hangul(wchar_t uc, u16 *result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	int l, v, t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	index = uc - Hangul_SBase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	if (index < 0 || index >= Hangul_SCount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	l = Hangul_LBase + index / Hangul_NCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	v = Hangul_VBase + (index % Hangul_NCount) / Hangul_TCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	t = Hangul_TBase + index % Hangul_TCount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	result[0] = l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	result[1] = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	if (t != Hangul_TBase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		result[2] = t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		return 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	return 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /* Decomposes a single unicode character. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static u16 *decompose_unichar(wchar_t uc, int *size, u16 *hangul_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	u16 *result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	/* Hangul is handled separately */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	result = hangul_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	*size = hfsplus_try_decompose_hangul(uc, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	if (*size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		result = hfsplus_decompose_nonhangul(uc, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) int hfsplus_asc2uni(struct super_block *sb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		    struct hfsplus_unistr *ustr, int max_unistr_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		    const char *astr, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	int size, dsize, decompose;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	u16 *dstr, outlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	wchar_t c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	u16 dhangul[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	while (outlen < max_unistr_len && len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		size = asc2unichar(sb, astr, len, &c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		if (decompose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 			dstr = decompose_unichar(c, &dsize, dhangul);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 			dstr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		if (dstr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 			if (outlen + dsize > max_unistr_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 			do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 				ustr->unicode[outlen++] = cpu_to_be16(*dstr++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 			} while (--dsize > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 			ustr->unicode[outlen++] = cpu_to_be16(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 		astr += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		len -= size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	ustr->length = cpu_to_be16(outlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	if (len > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		return -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)  * Hash a string to an integer as appropriate for the HFS+ filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)  * Composed unicode characters are decomposed and case-folding is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)  * if the appropriate bits are (un)set on the superblock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	struct super_block *sb = dentry->d_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	const char *astr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	const u16 *dstr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	int casefold, decompose, size, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	unsigned long hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	wchar_t c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	u16 c2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	u16 dhangul[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	casefold = test_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	hash = init_name_hash(dentry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	astr = str->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	len = str->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	while (len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		int dsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		size = asc2unichar(sb, astr, len, &c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		astr += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		len -= size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		if (decompose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 			dstr = decompose_unichar(c, &dsize, dhangul);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 			dstr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		if (dstr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 			do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 				c2 = *dstr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 				if (casefold)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 					c2 = case_fold(c2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 				if (!casefold || c2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 					hash = partial_name_hash(c2, hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 			} while (--dsize > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 			c2 = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 			if (casefold)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 				c2 = case_fold(c2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 			if (!casefold || c2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 				hash = partial_name_hash(c2, hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	str->hash = end_name_hash(hash);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)  * Compare strings with HFS+ filename ordering.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)  * Composed unicode characters are decomposed and case-folding is performed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)  * if the appropriate bits are (un)set on the superblock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) int hfsplus_compare_dentry(const struct dentry *dentry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		unsigned int len, const char *str, const struct qstr *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	struct super_block *sb = dentry->d_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	int casefold, decompose, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	int dsize1, dsize2, len1, len2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	const u16 *dstr1, *dstr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	const char *astr1, *astr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	u16 c1, c2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	wchar_t c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	u16 dhangul_1[3], dhangul_2[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	casefold = test_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	astr1 = str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	len1 = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	astr2 = name->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	len2 = name->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	dsize1 = dsize2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	dstr1 = dstr2 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	while (len1 > 0 && len2 > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		if (!dsize1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 			size = asc2unichar(sb, astr1, len1, &c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 			astr1 += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 			len1 -= size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 			if (decompose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 				dstr1 = decompose_unichar(c, &dsize1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 							  dhangul_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 			if (!decompose || !dstr1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 				c1 = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 				dstr1 = &c1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 				dsize1 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		if (!dsize2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 			size = asc2unichar(sb, astr2, len2, &c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 			astr2 += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 			len2 -= size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 			if (decompose)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 				dstr2 = decompose_unichar(c, &dsize2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 							  dhangul_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 			if (!decompose || !dstr2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 				c2 = c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 				dstr2 = &c2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 				dsize2 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		c1 = *dstr1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		c2 = *dstr2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		if (casefold) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 			c1 = case_fold(c1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 			if (!c1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 				dstr1++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 				dsize1--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 			c2 = case_fold(c2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 			if (!c2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 				dstr2++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 				dsize2--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		if (c1 < c2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 			return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		else if (c1 > c2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 			return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 		dstr1++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 		dsize1--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		dstr2++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		dsize2--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	if (len1 < len2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	if (len1 > len2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }