Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  *  linux/fs/hfsplus/unicode.c
  3  *
  4  * Copyright (C) 2001
  5  * Brad Boyer (flar@allandria.com)
  6  * (C) 2003 Ardis Technologies <roman@ardistech.com>
  7  *
  8  * Handler routines for unicode strings
  9  */
 10 
 11 #include <linux/types.h>
 12 #include <linux/nls.h>
 13 #include "hfsplus_fs.h"
 14 #include "hfsplus_raw.h"
 15 
 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)
 19 {
 20         u16 tmp;
 21 
 22         tmp = case_fold_table[(c>>8)];
 23         if (tmp)
 24                 tmp = case_fold_table[tmp + (c & 0xFF)];
 25         else
 26                 tmp = c;
 27         return tmp;
 28 }
 29 
 30 /* Compare unicode strings, return values like normal strcmp */
 31 int hfsplus_unistrcmp(const struct hfsplus_unistr *s1, const struct hfsplus_unistr *s2)
 32 {
 33         u16 len1, len2, c1, c2;
 34         const hfsplus_unichr *p1, *p2;
 35 
 36         len1 = be16_to_cpu(s1->length);
 37         len2 = be16_to_cpu(s2->length);
 38         p1 = s1->unicode;
 39         p2 = s2->unicode;
 40 
 41         while (1) {
 42                 c1 = c2 = 0;
 43 
 44                 while (len1 && !c1) {
 45                         c1 = case_fold(be16_to_cpu(*p1));
 46                         p1++;
 47                         len1--;
 48                 }
 49                 while (len2 && !c2) {
 50                         c2 = case_fold(be16_to_cpu(*p2));
 51                         p2++;
 52                         len2--;
 53                 }
 54 
 55                 if (c1 != c2)
 56                         return (c1 < c2) ? -1 : 1;
 57                 if (!c1 && !c2)
 58                         return 0;
 59         }
 60 }
 61 
 62 int hfsplus_uni2asc(const struct hfsplus_unistr *ustr, char *astr, int *len)
 63 {
 64         const hfsplus_unichr *ip;
 65         u8 *op;
 66         u16 ustrlen, cc;
 67         int size, tmp;
 68 
 69         op = astr;
 70         ip = ustr->unicode;
 71         ustrlen = be16_to_cpu(ustr->length);
 72         tmp = *len;
 73         while (ustrlen > 0 && tmp > 0) {
 74                 cc = be16_to_cpu(*ip);
 75                 switch (cc) {
 76                 case 0:
 77                         cc = 0x2400;
 78                         break;
 79                 case '/':
 80                         cc = ':';
 81                         break;
 82                 }
 83                 if (cc > 0x7f) {
 84                         size = utf8_wctomb(op, cc, tmp);
 85                         if (size == -1) {
 86                                 /* ignore */
 87                         } else {
 88                                 op += size;
 89                                 tmp -= size;
 90                         }
 91                 } else {
 92                         *op++ = (u8) cc;
 93                         tmp--;
 94                 }
 95                 ip++;
 96                 ustrlen--;
 97         }
 98         *len = (char *)op - astr;
 99         if (ustrlen)
100                 return -ENAMETOOLONG;
101         return 0;
102 }
103 
104 int hfsplus_asc2uni(struct hfsplus_unistr *ustr, const char *astr, int len)
105 {
106         int tmp;
107         wchar_t c;
108         u16 outlen = 0;
109 
110         while (outlen <= HFSPLUS_MAX_STRLEN && len > 0) {
111                 if (*astr & 0x80) {
112                         tmp = utf8_mbtowc(&c, astr, len);
113                         if (tmp < 0) {
114                                 astr++;
115                                 len--;
116                                 continue;
117                         } else {
118                                 astr += tmp;
119                                 len -= tmp;
120                         }
121                 } else {
122                         c = *astr++;
123                         len--;
124                 }
125                 switch (c) {
126                 case 0x2400:
127                         c = 0;
128                         break;
129                 case ':':
130                         c = '/';
131                         break;
132                 }
133                 ustr->unicode[outlen] = cpu_to_be16(c);
134                 outlen++;
135         }
136         ustr->length = cpu_to_be16(outlen);
137         if (len > 0)
138                 return -ENAMETOOLONG;
139         return 0;
140 }
141 
  This page was automatically generated by the LXR engine.