1 /* $OpenBSD: ntfs_conv.c,v 1.5 2008/06/26 05:42:20 ray 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 * 17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 /* 31 * File name recode stuff. 32 * 33 * The utf-8 routines were derived from src/lib/libc/locale/utf2.c. 34 */ 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/namei.h> 39 #include <sys/proc.h> 40 #include <sys/kernel.h> 41 #include <sys/vnode.h> 42 #include <sys/mount.h> 43 #include <sys/buf.h> 44 #include <sys/file.h> 45 #include <sys/malloc.h> 46 #include <sys/lock.h> 47 #if defined(__FreeBSD__) 48 #include <machine/clock.h> 49 #endif 50 51 #include <miscfs/specfs/specdev.h> 52 53 /* #define NTFS_DEBUG 1 */ 54 #if defined(__FreeBSD__) || defined(__NetBSD__) 55 #include <fs/ntfs/ntfs.h> 56 #include <fs/ntfs/ntfsmount.h> 57 #include <fs/ntfs/ntfs_inode.h> 58 #include <fs/ntfs/ntfs_vfsops.h> 59 #include <fs/ntfs/ntfs_subr.h> 60 #include <fs/ntfs/ntfs_compr.h> 61 #include <fs/ntfs/ntfs_ihash.h> 62 #else 63 #include <ntfs/ntfs.h> 64 #include <ntfs/ntfsmount.h> 65 #include <ntfs/ntfs_inode.h> 66 #include <ntfs/ntfs_vfsops.h> 67 #include <ntfs/ntfs_subr.h> 68 #include <ntfs/ntfs_compr.h> 69 #include <ntfs/ntfs_ihash.h> 70 #endif 71 72 /* UTF-8 encoding stuff */ 73 74 static const int _utf_count[16] = { 75 1, 1, 1, 1, 1, 1, 1, 1, 76 0, 0, 0, 0, 2, 2, 3, 0, 77 }; 78 79 /* 80 * Read one wide character off the string, shift the string pointer 81 * and return the character. 82 */ 83 wchar 84 ntfs_utf8_wget(const char **str) 85 { 86 int c; 87 wchar rune = 0; 88 const char *s = *str; 89 90 c = _utf_count[(s[0] >> 4) & 0xf]; 91 if (c == 0) { 92 c = 1; 93 goto encoding_error; 94 } 95 96 switch (c) { 97 case 1: 98 rune = s[0] & 0xff; 99 break; 100 case 2: 101 if ((s[1] & 0xc0) != 0x80) 102 goto encoding_error; 103 rune = ((s[0] & 0x1F) << 6) | (s[1] & 0x3F); 104 break; 105 case 3: 106 if ((s[1] & 0xC0) != 0x80 || (s[2] & 0xC0) != 0x80) 107 goto encoding_error; 108 rune = ((s[0] & 0x1F) << 12) | ((s[1] & 0x3F) << 6) 109 | (s[2] & 0x3F); 110 break; 111 } 112 113 encoding_error: 114 *str = *str + c; 115 return rune; 116 } 117 118 /* 119 * Encode wide character and write it to the string. 'n' specifies 120 * how much space there is in the string. Returns number of bytes written 121 * to the target string. 122 */ 123 int 124 ntfs_utf8_wput(char *s, size_t n, wchar wc) 125 { 126 if (wc & 0xf800) { 127 if (n < 3) { 128 /* bound check failure */ 129 ddprintf(("ntfs_utf8_wput: need 3 bytes\n")); 130 return 0; 131 } 132 133 s[0] = 0xE0 | ((wc >> 12) & 0x0F); 134 s[1] = 0x80 | ((wc >> 6) & 0x3F); 135 s[2] = 0x80 | ((wc) & 0x3F); 136 return 3; 137 } else { 138 if (wc & 0x0780) { 139 if (n < 2) { 140 /* bound check failure */ 141 ddprintf(("ntfs_utf8_wput: need 2 bytes\n")); 142 return 0; 143 } 144 145 s[0] = 0xC0 | ((wc >> 6) & 0x1F); 146 s[1] = 0x80 | ((wc) & 0x3F); 147 return 2; 148 } else { 149 if (n < 1) { 150 /* bound check failure */ 151 ddprintf(("ntfs_utf8_wput: need 1 byte\n")); 152 return 0; 153 } 154 155 s[0] = wc; 156 return 1; 157 } 158 } 159 } 160 161 /* 162 * Compare two wide characters, returning 1, 0, -1 if the first is 163 * bigger, equal or lower than the second. 164 */ 165 int 166 ntfs_utf8_wcmp(wchar wc1, wchar wc2) 167 { 168 /* no conversions needed for utf8 */ 169 170 if (wc1 == wc2) 171 return 0; 172 else 173 return (int) wc1 - (int) wc2; 174 } 175