The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/hfsplus/unicode.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 hfsplus_unistr *s1, const 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 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                 if (!cc || cc > 0x7f) {
   76                         size = utf8_wctomb(op, cc ? cc : 0x2400, tmp);
   77                         if (size == -1) {
   78                                 /* ignore */
   79                         } else {
   80                                 op += size;
   81                                 tmp -= size;
   82                         }
   83                 } else {
   84                         *op++ = (u8) cc;
   85                         tmp--;
   86                 }
   87                 ip++;
   88                 ustrlen--;
   89         }
   90         *len = (char *)op - astr;
   91         if (ustrlen)
   92                 return -ENAMETOOLONG;
   93         return 0;
   94 }
   95 
   96 int hfsplus_asc2uni(hfsplus_unistr *ustr, const char *astr, int len)
   97 {
   98         int tmp;
   99         wchar_t c;
  100         u16 outlen = 0;
  101 
  102         while (outlen <= HFSPLUS_MAX_STRLEN && len > 0) {
  103                 if (*astr & 0x80) {
  104                         tmp = utf8_mbtowc(&c, astr, len);
  105                         if (tmp < 0) {
  106                                 astr++;
  107                                 len--;
  108                                 continue;
  109                         } else {
  110                                 astr += tmp;
  111                                 len -= tmp;
  112                         }
  113                         if (c == 0x2400)
  114                                 c = 0;
  115                 } else {
  116                         c = *astr++;
  117                         len--;
  118                 }
  119                 ustr->unicode[outlen] = cpu_to_be16(c);
  120                 outlen++;
  121         }
  122         ustr->length = cpu_to_be16(outlen);
  123         if (len > 0)
  124                 return -ENAMETOOLONG;
  125         return 0;
  126 }

Cache object: 7d4d0bdb10e00cb062b9fe90ee38ebb5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.