1 /* $OpenBSD: ntfs_conv.c,v 1.2 2003/05/20 03:23:11 mickey Exp $ */ 2 /* $NetBSD: ntfs_conv.c,v 1.1 2002/12/23 17:38:32 jdolecek Exp $ */ 3 4 /*- 5 * Copyright (c) 2001 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the NetBSD 19 * Foundation, Inc. and its contributors. 20 * 4. Neither the name of The NetBSD Foundation nor the names of its 21 * contributors may be used to endorse or promote products derived 22 * from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 27 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 28 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 * POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37 /* 38 * File name recode stuff. 39 * 40 * The utf-8 routines were derived from basesrc/lib/libc/locale/utf2.c. 41 */ 42 43 #include <sys/cdefs.h> 44 #ifdef __KERNEL_RCSID 45 __KERNEL_RCSID(0, "$NetBSD: ntfs_conv.c,v 1.1 2002/12/23 17:38:32 jdolecek Exp $"); 46 #endif 47 48 #include <sys/param.h> 49 #include <sys/systm.h> 50 #include <sys/namei.h> 51 #include <sys/proc.h> 52 #include <sys/kernel.h> 53 #include <sys/vnode.h> 54 #include <sys/mount.h> 55 #include <sys/buf.h> 56 #include <sys/file.h> 57 #include <sys/malloc.h> 58 #include <sys/lock.h> 59 #if defined(__FreeBSD__) 60 #include <machine/clock.h> 61 #endif 62 63 #include <miscfs/specfs/specdev.h> 64 65 /* #define NTFS_DEBUG 1 */ 66 #if defined(__FreeBSD__) || defined(__NetBSD__) 67 #include <fs/ntfs/ntfs.h> 68 #include <fs/ntfs/ntfsmount.h> 69 #include <fs/ntfs/ntfs_inode.h> 70 #include <fs/ntfs/ntfs_vfsops.h> 71 #include <fs/ntfs/ntfs_subr.h> 72 #include <fs/ntfs/ntfs_compr.h> 73 #include <fs/ntfs/ntfs_ihash.h> 74 #else 75 #include <ntfs/ntfs.h> 76 #include <ntfs/ntfsmount.h> 77 #include <ntfs/ntfs_inode.h> 78 #include <ntfs/ntfs_vfsops.h> 79 #include <ntfs/ntfs_subr.h> 80 #include <ntfs/ntfs_compr.h> 81 #include <ntfs/ntfs_ihash.h> 82 #endif 83 84 /* UTF-8 encoding stuff */ 85 86 static const int _utf_count[16] = { 87 1, 1, 1, 1, 1, 1, 1, 1, 88 0, 0, 0, 0, 2, 2, 3, 0, 89 }; 90 91 /* 92 * Read one wide character off the string, shift the string pointer 93 * and return the character. 94 */ 95 wchar 96 ntfs_utf8_wget(const char **str) 97 { 98 int c; 99 wchar rune = 0; 100 const char *s = *str; 101 102 c = _utf_count[(s[0] >> 4) & 0xf]; 103 if (c == 0) { 104 c = 1; 105 goto encoding_error; 106 } 107 108 switch (c) { 109 case 1: 110 rune = s[0] & 0xff; 111 break; 112 case 2: 113 if ((s[1] & 0xc0) != 0x80) 114 goto encoding_error; 115 rune = ((s[0] & 0x1F) << 6) | (s[1] & 0x3F); 116 break; 117 case 3: 118 if ((s[1] & 0xC0) != 0x80 || (s[2] & 0xC0) != 0x80) 119 goto encoding_error; 120 rune = ((s[0] & 0x1F) << 12) | ((s[1] & 0x3F) << 6) 121 | (s[2] & 0x3F); 122 break; 123 } 124 125 encoding_error: 126 *str = *str + c; 127 return rune; 128 } 129 130 /* 131 * Encode wide character and write it to the string. 'n' specifies 132 * how much space there is in the string. Returns number of bytes written 133 * to the target string. 134 */ 135 int 136 ntfs_utf8_wput(char *s, size_t n, wchar wc) 137 { 138 if (wc & 0xf800) { 139 if (n < 3) { 140 /* bound check failure */ 141 ddprintf(("ntfs_utf8_wput: need 3 bytes\n")); 142 return 0; 143 } 144 145 s[0] = 0xE0 | ((wc >> 12) & 0x0F); 146 s[1] = 0x80 | ((wc >> 6) & 0x3F); 147 s[2] = 0x80 | ((wc) & 0x3F); 148 return 3; 149 } else { 150 if (wc & 0x0780) { 151 if (n < 2) { 152 /* bound check failure */ 153 ddprintf(("ntfs_utf8_wput: need 2 bytes\n")); 154 return 0; 155 } 156 157 s[0] = 0xC0 | ((wc >> 6) & 0x1F); 158 s[1] = 0x80 | ((wc) & 0x3F); 159 return 2; 160 } else { 161 if (n < 1) { 162 /* bound check failure */ 163 ddprintf(("ntfs_utf8_wput: need 1 byte\n")); 164 return 0; 165 } 166 167 s[0] = wc; 168 return 1; 169 } 170 } 171 } 172 173 /* 174 * Compare two wide characters, returning 1, 0, -1 if the first is 175 * bigger, equal or lower than the second. 176 */ 177 int 178 ntfs_utf8_wcmp(wchar wc1, wchar wc2) 179 { 180 /* no conversions needed for utf8 */ 181 182 if (wc1 == wc2) 183 return 0; 184 else 185 return (int) wc1 - (int) wc2; 186 } 187