linux/fs/jfs/jfs_unicode.c
<<
>>
Prefs
   1/*
   2 *   Copyright (C) International Business Machines Corp., 2000-2004
   3 *
   4 *   This program is free software;  you can redistribute it and/or modify
   5 *   it under the terms of the GNU General Public License as published by
   6 *   the Free Software Foundation; either version 2 of the License, or
   7 *   (at your option) any later version.
   8 *
   9 *   This program is distributed in the hope that it will be useful,
  10 *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
  11 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  12 *   the GNU General Public License for more details.
  13 *
  14 *   You should have received a copy of the GNU General Public License
  15 *   along with this program;  if not, write to the Free Software
  16 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17 */
  18
  19#include <linux/fs.h>
  20#include <linux/slab.h>
  21#include "jfs_incore.h"
  22#include "jfs_filsys.h"
  23#include "jfs_unicode.h"
  24#include "jfs_debug.h"
  25
  26/*
  27 * NAME:        jfs_strfromUCS()
  28 *
  29 * FUNCTION:    Convert little-endian unicode string to character string
  30 *
  31 */
  32int jfs_strfromUCS_le(char *to, const __le16 * from,
  33                      int len, struct nls_table *codepage)
  34{
  35        int i;
  36        int outlen = 0;
  37        static int warn_again = 5;      /* Only warn up to 5 times total */
  38        int warn = !!warn_again;        /* once per string */
  39
  40        if (codepage) {
  41                for (i = 0; (i < len) && from[i]; i++) {
  42                        int charlen;
  43                        charlen =
  44                            codepage->uni2char(le16_to_cpu(from[i]),
  45                                               &to[outlen],
  46                                               NLS_MAX_CHARSET_SIZE);
  47                        if (charlen > 0)
  48                                outlen += charlen;
  49                        else
  50                                to[outlen++] = '?';
  51                }
  52        } else {
  53                for (i = 0; (i < len) && from[i]; i++) {
  54                        if (unlikely(le16_to_cpu(from[i]) & 0xff00)) {
  55                                to[i] = '?';
  56                                if (unlikely(warn)) {
  57                                        warn--;
  58                                        warn_again--;
  59                                        printk(KERN_ERR
  60                        "non-latin1 character 0x%x found in JFS file name\n",
  61                                               le16_to_cpu(from[i]));
  62                                        printk(KERN_ERR
  63                                "mount with iocharset=utf8 to access\n");
  64                                }
  65
  66                        }
  67                        else
  68                                to[i] = (char) (le16_to_cpu(from[i]));
  69                }
  70                outlen = i;
  71        }
  72        to[outlen] = 0;
  73        return outlen;
  74}
  75
  76/*
  77 * NAME:        jfs_strtoUCS()
  78 *
  79 * FUNCTION:    Convert character string to unicode string
  80 *
  81 */
  82static int jfs_strtoUCS(wchar_t * to, const unsigned char *from, int len,
  83                struct nls_table *codepage)
  84{
  85        int charlen;
  86        int i;
  87
  88        if (codepage) {
  89                for (i = 0; len && *from; i++, from += charlen, len -= charlen)
  90                {
  91                        charlen = codepage->char2uni(from, len, &to[i]);
  92                        if (charlen < 1) {
  93                                jfs_err("jfs_strtoUCS: char2uni returned %d.",
  94                                        charlen);
  95                                jfs_err("charset = %s, char = 0x%x",
  96                                        codepage->charset, *from);
  97                                return charlen;
  98                        }
  99                }
 100        } else {
 101                for (i = 0; (i < len) && from[i]; i++)
 102                        to[i] = (wchar_t) from[i];
 103        }
 104
 105        to[i] = 0;
 106        return i;
 107}
 108
 109/*
 110 * NAME:        get_UCSname()
 111 *
 112 * FUNCTION:    Allocate and translate to unicode string
 113 *
 114 */
 115int get_UCSname(struct component_name * uniName, struct dentry *dentry)
 116{
 117        struct nls_table *nls_tab = JFS_SBI(dentry->d_sb)->nls_tab;
 118        int length = dentry->d_name.len;
 119
 120        if (length > JFS_NAME_MAX)
 121                return -ENAMETOOLONG;
 122
 123        uniName->name =
 124            kmalloc((length + 1) * sizeof(wchar_t), GFP_NOFS);
 125
 126        if (uniName->name == NULL)
 127                return -ENOMEM;
 128
 129        uniName->namlen = jfs_strtoUCS(uniName->name, dentry->d_name.name,
 130                                       length, nls_tab);
 131
 132        if (uniName->namlen < 0) {
 133                kfree(uniName->name);
 134                return uniName->namlen;
 135        }
 136
 137        return 0;
 138}
 139