root/fs/hfs/trans.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hfs_mac2asc
  2. hfs_asc2mac

   1 /*
   2  *  linux/fs/hfs/trans.c
   3  *
   4  * Copyright (C) 1995-1997  Paul H. Hargrove
   5  * This file may be distributed under the terms of the GNU General Public License.
   6  *
   7  * This file contains routines for converting between the Macintosh
   8  * character set and various other encodings.  This includes dealing
   9  * with ':' vs. '/' as the path-element separator.
  10  */
  11 
  12 #include <linux/types.h>
  13 #include <linux/nls.h>
  14 
  15 #include "hfs_fs.h"
  16 
  17 /*================ Global functions ================*/
  18 
  19 /*
  20  * hfs_mac2asc()
  21  *
  22  * Given a 'Pascal String' (a string preceded by a length byte) in
  23  * the Macintosh character set produce the corresponding filename using
  24  * the 'trivial' name-mangling scheme, returning the length of the
  25  * mangled filename.  Note that the output string is not NULL
  26  * terminated.
  27  *
  28  * The name-mangling works as follows:
  29  * The character '/', which is illegal in Linux filenames is replaced
  30  * by ':' which never appears in HFS filenames.  All other characters
  31  * are passed unchanged from input to output.
  32  */
  33 int hfs_mac2asc(struct super_block *sb, char *out, const struct hfs_name *in)
  34 {
  35         struct nls_table *nls_disk = HFS_SB(sb)->nls_disk;
  36         struct nls_table *nls_io = HFS_SB(sb)->nls_io;
  37         const char *src;
  38         char *dst;
  39         int srclen, dstlen, size;
  40 
  41         src = in->name;
  42         srclen = in->len;
  43         if (srclen > HFS_NAMELEN)
  44                 srclen = HFS_NAMELEN;
  45         dst = out;
  46         dstlen = HFS_MAX_NAMELEN;
  47         if (nls_io) {
  48                 wchar_t ch;
  49 
  50                 while (srclen > 0) {
  51                         if (nls_disk) {
  52                                 size = nls_disk->char2uni(src, srclen, &ch);
  53                                 if (size <= 0) {
  54                                         ch = '?';
  55                                         size = 1;
  56                                 }
  57                                 src += size;
  58                                 srclen -= size;
  59                         } else {
  60                                 ch = *src++;
  61                                 srclen--;
  62                         }
  63                         if (ch == '/')
  64                                 ch = ':';
  65                         size = nls_io->uni2char(ch, dst, dstlen);
  66                         if (size < 0) {
  67                                 if (size == -ENAMETOOLONG)
  68                                         goto out;
  69                                 *dst = '?';
  70                                 size = 1;
  71                         }
  72                         dst += size;
  73                         dstlen -= size;
  74                 }
  75         } else {
  76                 char ch;
  77 
  78                 while (--srclen >= 0)
  79                         *dst++ = (ch = *src++) == '/' ? ':' : ch;
  80         }
  81 out:
  82         return dst - out;
  83 }
  84 
  85 /*
  86  * hfs_asc2mac()
  87  *
  88  * Given an ASCII string (not null-terminated) and its length,
  89  * generate the corresponding filename in the Macintosh character set
  90  * using the 'trivial' name-mangling scheme, returning the length of
  91  * the mangled filename.  Note that the output string is not NULL
  92  * terminated.
  93  *
  94  * This routine is a inverse to hfs_mac2triv().
  95  * A ':' is replaced by a '/'.
  96  */
  97 void hfs_asc2mac(struct super_block *sb, struct hfs_name *out, const struct qstr *in)
  98 {
  99         struct nls_table *nls_disk = HFS_SB(sb)->nls_disk;
 100         struct nls_table *nls_io = HFS_SB(sb)->nls_io;
 101         const char *src;
 102         char *dst;
 103         int srclen, dstlen, size;
 104 
 105         src = in->name;
 106         srclen = in->len;
 107         dst = out->name;
 108         dstlen = HFS_NAMELEN;
 109         if (nls_io) {
 110                 wchar_t ch;
 111 
 112                 while (srclen > 0) {
 113                         size = nls_io->char2uni(src, srclen, &ch);
 114                         if (size < 0) {
 115                                 ch = '?';
 116                                 size = 1;
 117                         }
 118                         src += size;
 119                         srclen -= size;
 120                         if (ch == ':')
 121                                 ch = '/';
 122                         if (nls_disk) {
 123                                 size = nls_disk->uni2char(ch, dst, dstlen);
 124                                 if (size < 0) {
 125                                         if (size == -ENAMETOOLONG)
 126                                                 goto out;
 127                                         *dst = '?';
 128                                         size = 1;
 129                                 }
 130                                 dst += size;
 131                                 dstlen -= size;
 132                         } else {
 133                                 *dst++ = ch > 0xff ? '?' : ch;
 134                                 dstlen--;
 135                         }
 136                 }
 137         } else {
 138                 char ch;
 139 
 140                 if (dstlen > srclen)
 141                         dstlen = srclen;
 142                 while (--dstlen >= 0)
 143                         *dst++ = (ch = *src++) == ':' ? '/' : ch;
 144         }
 145 out:
 146         out->len = dst - (char *)out->name;
 147         dstlen = HFS_NAMELEN - out->len;
 148         while (--dstlen >= 0)
 149                 *dst++ = 0;
 150 }

/* [<][>][^][v][top][bottom][index][help] */