2 * linux/fs/hfsplus/unicode.c
5 * Brad Boyer (flar@allandria.com)
6 * (C) 2003 Ardis Technologies <roman@ardistech.com>
8 * Handler routines for unicode strings
11 #include <linux/types.h>
12 #include <linux/nls.h>
13 #include "hfsplus_fs.h"
14 #include "hfsplus_raw.h"
16 /* Fold the case of a unicode char, given the 16 bit value */
17 /* Returns folded char, or 0 if ignorable */
18 static inline u16
case_fold(u16 c
)
22 tmp
= hfsplus_case_fold_table
[c
>> 8];
24 tmp
= hfsplus_case_fold_table
[tmp
+ (c
& 0xff)];
30 /* Compare unicode strings, return values like normal strcmp */
31 int hfsplus_strcasecmp(const struct hfsplus_unistr
*s1
,
32 const struct hfsplus_unistr
*s2
)
34 u16 len1
, len2
, c1
, c2
;
35 const hfsplus_unichr
*p1
, *p2
;
37 len1
= be16_to_cpu(s1
->length
);
38 len2
= be16_to_cpu(s2
->length
);
46 c1
= case_fold(be16_to_cpu(*p1
));
51 c2
= case_fold(be16_to_cpu(*p2
));
57 return (c1
< c2
) ? -1 : 1;
63 /* Compare names as a sequence of 16-bit unsigned integers */
64 int hfsplus_strcmp(const struct hfsplus_unistr
*s1
,
65 const struct hfsplus_unistr
*s2
)
67 u16 len1
, len2
, c1
, c2
;
68 const hfsplus_unichr
*p1
, *p2
;
71 len1
= be16_to_cpu(s1
->length
);
72 len2
= be16_to_cpu(s2
->length
);
76 for (len
= min(len1
, len2
); len
> 0; len
--) {
77 c1
= be16_to_cpu(*p1
);
78 c2
= be16_to_cpu(*p2
);
80 return c1
< c2
? -1 : 1;
85 return len1
< len2
? -1 :
90 #define Hangul_SBase 0xac00
91 #define Hangul_LBase 0x1100
92 #define Hangul_VBase 0x1161
93 #define Hangul_TBase 0x11a7
94 #define Hangul_SCount 11172
95 #define Hangul_LCount 19
96 #define Hangul_VCount 21
97 #define Hangul_TCount 28
98 #define Hangul_NCount (Hangul_VCount * Hangul_TCount)
101 static u16
*hfsplus_compose_lookup(u16
*p
, u16 cc
)
107 if (!e
|| cc
< p
[s
* 2] || cc
> p
[e
* 2])
113 else if (cc
< p
[i
* 2])
116 return hfsplus_compose_table
+ p
[i
* 2 + 1];
121 int hfsplus_uni2asc(struct super_block
*sb
,
122 const struct hfsplus_unistr
*ustr
,
123 char *astr
, int *len_p
)
125 const hfsplus_unichr
*ip
;
126 struct nls_table
*nls
= HFSPLUS_SB(sb
)->nls
;
130 int i
, len
, ustrlen
, res
, compose
;
134 ustrlen
= be16_to_cpu(ustr
->length
);
137 compose
= !test_bit(HFSPLUS_SB_NODECOMPOSE
, &HFSPLUS_SB(sb
)->flags
);
139 while (ustrlen
> 0) {
140 c0
= be16_to_cpu(*ip
++);
142 /* search for single decomposed char */
144 ce1
= hfsplus_compose_lookup(hfsplus_compose_table
, c0
);
145 if (ce1
&& (cc
= ce1
[0])) {
146 /* start of a possibly decomposed Hangul char */
151 c1
= be16_to_cpu(*ip
) - Hangul_VBase
;
152 if (c1
< Hangul_VCount
) {
153 /* compose the Hangul char */
154 cc
= (c0
- Hangul_LBase
) * Hangul_VCount
;
155 cc
= (cc
+ c1
) * Hangul_TCount
;
161 c1
= be16_to_cpu(*ip
) - Hangul_TBase
;
162 if (c1
> 0 && c1
< Hangul_TCount
) {
171 /* main loop for common case of not composed chars */
174 c1
= be16_to_cpu(*ip
);
176 ce1
= hfsplus_compose_lookup(
177 hfsplus_compose_table
, c1
);
188 res
= nls
->uni2char(c0
, op
, len
);
190 if (res
== -ENAMETOOLONG
)
201 ce2
= hfsplus_compose_lookup(ce1
, c0
);
204 while (i
< ustrlen
) {
205 ce1
= hfsplus_compose_lookup(ce2
,
230 res
= nls
->uni2char(cc
, op
, len
);
232 if (res
== -ENAMETOOLONG
)
242 *len_p
= (char *)op
- astr
;
247 * Convert one or more ASCII characters into a single unicode character.
248 * Returns the number of ASCII characters corresponding to the unicode char.
250 static inline int asc2unichar(struct super_block
*sb
, const char *astr
, int len
,
253 int size
= HFSPLUS_SB(sb
)->nls
->char2uni(astr
, len
, uc
);
269 /* Decomposes a single unicode character. */
270 static inline u16
*decompose_unichar(wchar_t uc
, int *size
)
274 off
= hfsplus_decompose_table
[(uc
>> 12) & 0xf];
275 if (off
== 0 || off
== 0xffff)
278 off
= hfsplus_decompose_table
[off
+ ((uc
>> 8) & 0xf)];
282 off
= hfsplus_decompose_table
[off
+ ((uc
>> 4) & 0xf)];
286 off
= hfsplus_decompose_table
[off
+ (uc
& 0xf)];
290 return hfsplus_decompose_table
+ (off
/ 4);
293 int hfsplus_asc2uni(struct super_block
*sb
, struct hfsplus_unistr
*ustr
,
294 const char *astr
, int len
)
296 int size
, dsize
, decompose
;
297 u16
*dstr
, outlen
= 0;
300 decompose
= !test_bit(HFSPLUS_SB_NODECOMPOSE
, &HFSPLUS_SB(sb
)->flags
);
301 while (outlen
< HFSPLUS_MAX_STRLEN
&& len
> 0) {
302 size
= asc2unichar(sb
, astr
, len
, &c
);
304 if (decompose
&& (dstr
= decompose_unichar(c
, &dsize
))) {
305 if (outlen
+ dsize
> HFSPLUS_MAX_STRLEN
)
308 ustr
->unicode
[outlen
++] = cpu_to_be16(*dstr
++);
309 } while (--dsize
> 0);
311 ustr
->unicode
[outlen
++] = cpu_to_be16(c
);
316 ustr
->length
= cpu_to_be16(outlen
);
318 return -ENAMETOOLONG
;
323 * Hash a string to an integer as appropriate for the HFS+ filesystem.
324 * Composed unicode characters are decomposed and case-folding is performed
325 * if the appropriate bits are (un)set on the superblock.
327 int hfsplus_hash_dentry(const struct dentry
*dentry
, const struct inode
*inode
,
330 struct super_block
*sb
= dentry
->d_sb
;
333 int casefold
, decompose
, size
, len
;
338 casefold
= test_bit(HFSPLUS_SB_CASEFOLD
, &HFSPLUS_SB(sb
)->flags
);
339 decompose
= !test_bit(HFSPLUS_SB_NODECOMPOSE
, &HFSPLUS_SB(sb
)->flags
);
340 hash
= init_name_hash();
344 int uninitialized_var(dsize
);
345 size
= asc2unichar(sb
, astr
, len
, &c
);
349 if (decompose
&& (dstr
= decompose_unichar(c
, &dsize
))) {
352 if (!casefold
|| (c2
= case_fold(c2
)))
353 hash
= partial_name_hash(c2
, hash
);
354 } while (--dsize
> 0);
357 if (!casefold
|| (c2
= case_fold(c2
)))
358 hash
= partial_name_hash(c2
, hash
);
361 str
->hash
= end_name_hash(hash
);
367 * Compare strings with HFS+ filename ordering.
368 * Composed unicode characters are decomposed and case-folding is performed
369 * if the appropriate bits are (un)set on the superblock.
371 int hfsplus_compare_dentry(const struct dentry
*parent
,
372 const struct inode
*pinode
,
373 const struct dentry
*dentry
, const struct inode
*inode
,
374 unsigned int len
, const char *str
, const struct qstr
*name
)
376 struct super_block
*sb
= parent
->d_sb
;
377 int casefold
, decompose
, size
;
378 int dsize1
, dsize2
, len1
, len2
;
379 const u16
*dstr1
, *dstr2
;
380 const char *astr1
, *astr2
;
384 casefold
= test_bit(HFSPLUS_SB_CASEFOLD
, &HFSPLUS_SB(sb
)->flags
);
385 decompose
= !test_bit(HFSPLUS_SB_NODECOMPOSE
, &HFSPLUS_SB(sb
)->flags
);
391 dstr1
= dstr2
= NULL
;
393 while (len1
> 0 && len2
> 0) {
395 size
= asc2unichar(sb
, astr1
, len1
, &c
);
400 dstr1
= decompose_unichar(c
, &dsize1
);
401 if (!decompose
|| !dstr1
) {
409 size
= asc2unichar(sb
, astr2
, len2
, &c
);
414 dstr2
= decompose_unichar(c
, &dsize2
);
415 if (!decompose
|| !dstr2
) {
425 if (!(c1
= case_fold(c1
))) {
430 if (!(c2
= case_fold(c2
))) {