Annotation of XNU/bsd/hfs/hfs_encodings.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * "Portions Copyright (c) 2000 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.0 (the 'License'). You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License."
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: #include <sys/param.h>
        !            26: #include <sys/systm.h>
        !            27: #include <sys/kernel.h>
        !            28: #include <sys/lock.h>
        !            29: #include <sys/malloc.h>
        !            30: #include <sys/queue.h>
        !            31: 
        !            32: #include "hfs.h"
        !            33: 
        !            34: 
        !            35: /* hfs encoding converter list */
        !            36: SLIST_HEAD(encodinglst, hfs_encoding) hfs_encoding_list = {0};
        !            37: decl_simple_lock_data(,hfs_encoding_list_slock);
        !            38: 
        !            39: 
        !            40: /* hfs encoding converter entry */
        !            41: struct hfs_encoding {
        !            42:        SLIST_ENTRY(hfs_encoding)  link;
        !            43:        int                     refcount;
        !            44:        int                     kmod_id;
        !            45:        UInt32                  encoding;
        !            46:        hfs_to_unicode_func_t   get_unicode_func;
        !            47:        unicode_to_hfs_func_t   get_hfsname_func;
        !            48: };
        !            49: 
        !            50: /* XXX We should use an "official" interface! */
        !            51: extern kern_return_t kmod_destroy(host_t host, kmod_t id);
        !            52: extern struct host realhost;
        !            53: 
        !            54: #define MAX_HFS_UNICODE_CHARS  (15*5)
        !            55: 
        !            56: static int mac_roman_to_unicode(Str31 hfs_str, UniChar *uni_str, UInt32 maxCharLen, UInt32 *usedCharLen);
        !            57: 
        !            58: static int unicode_to_mac_roman(UniChar *uni_str, UInt32 unicodeChars, Str31 hfs_str);
        !            59: 
        !            60: 
        !            61: void
        !            62: hfs_converterinit(void)
        !            63: {
        !            64:        SLIST_INIT(&hfs_encoding_list);
        !            65:        simple_lock_init(&hfs_encoding_list_slock);
        !            66: 
        !            67:        /*
        !            68:         * add resident MacRoman converter and take a reference
        !            69:         * since its always "loaded".
        !            70:         */
        !            71:        hfs_addconverter(0, kTextEncodingMacRoman, mac_roman_to_unicode, unicode_to_mac_roman);
        !            72:        SLIST_FIRST(&hfs_encoding_list)->refcount++;
        !            73: }
        !            74: 
        !            75: 
        !            76: /*
        !            77:  * hfs_addconverter - add an HFS encoding converter
        !            78:  *
        !            79:  * This is called exclusivly by kernel loadable modules
        !            80:  * (like HFS_Japanese.kmod) to register hfs encoding
        !            81:  * conversion routines.
        !            82:  *
        !            83:  */
        !            84: int
        !            85: hfs_addconverter(int id, UInt32 encoding, hfs_to_unicode_func_t get_unicode, unicode_to_hfs_func_t get_hfsname)
        !            86: {
        !            87:        struct hfs_encoding *encp;
        !            88:        
        !            89:        MALLOC(encp, struct hfs_encoding *, sizeof(struct hfs_encoding), M_TEMP, M_WAITOK);
        !            90: 
        !            91:        simple_lock(&hfs_encoding_list_slock);
        !            92: 
        !            93:        encp->link.sle_next = NULL;
        !            94:        encp->refcount = 0;
        !            95:        encp->encoding = encoding;
        !            96:        encp->get_unicode_func = get_unicode;
        !            97:        encp->get_hfsname_func = get_hfsname;
        !            98:        encp->kmod_id = id;
        !            99:        SLIST_INSERT_HEAD(&hfs_encoding_list, encp, link);
        !           100: 
        !           101:        simple_unlock(&hfs_encoding_list_slock);
        !           102:        return (0);
        !           103: }
        !           104: 
        !           105: 
        !           106: /*
        !           107:  * hfs_remconverter - remove an HFS encoding converter
        !           108:  *
        !           109:  * Can be called by a kernel loadable module's finalize
        !           110:  * routine to remove an encoding converter so that the
        !           111:  * module (i.e. the code) can be unloaded.
        !           112:  *
        !           113:  * However, in the normal case, the removing and unloading
        !           114:  * of these converters is done in hfs_relconverter.
        !           115:  * The call is initiated from within the kernel during the unmounting of an hfs voulume.
        !           116:  */
        !           117: int
        !           118: hfs_remconverter(int id, UInt32 encoding)
        !           119: {
        !           120:        struct hfs_encoding *encp;
        !           121:        int busy = 0;
        !           122: 
        !           123:        simple_lock(&hfs_encoding_list_slock);
        !           124:        SLIST_FOREACH(encp, &hfs_encoding_list, link) {
        !           125:                if (encp->encoding == encoding && encp->kmod_id == id) {
        !           126:                        encp->refcount--;
        !           127:                        
        !           128:                        /* if converter is no longer in use, release it */
        !           129:                        if (encp->refcount <= 0 && encp->kmod_id != 0) {
        !           130:                                SLIST_REMOVE(&hfs_encoding_list, encp, hfs_encoding, link);
        !           131:                                FREE(encp, M_TEMP);
        !           132:                        } else {
        !           133:                                busy = 1;
        !           134:                        }
        !           135:                        break;
        !           136:                }
        !           137:        }
        !           138:        simple_unlock(&hfs_encoding_list_slock);
        !           139: 
        !           140:        return (busy);
        !           141: }
        !           142: 
        !           143: 
        !           144: /*
        !           145:  * hfs_getconverter - get HFS encoding converters
        !           146:  *
        !           147:  * Normally called during the mounting of an hfs voulume.
        !           148:  */
        !           149: int
        !           150: hfs_getconverter(UInt32 encoding, hfs_to_unicode_func_t *get_unicode, unicode_to_hfs_func_t *get_hfsname)
        !           151: {
        !           152:        struct hfs_encoding *encp;
        !           153:        int found = 0;
        !           154: 
        !           155:        simple_lock(&hfs_encoding_list_slock);
        !           156:        SLIST_FOREACH(encp, &hfs_encoding_list, link) {
        !           157:                if (encp->encoding == encoding) {
        !           158:                        found = 1;
        !           159:                        *get_unicode = encp->get_unicode_func;
        !           160:                        *get_hfsname = encp->get_hfsname_func;
        !           161:                        ++encp->refcount;
        !           162:                        break;
        !           163:                }
        !           164:        }
        !           165:        simple_unlock(&hfs_encoding_list_slock);
        !           166: 
        !           167:        if (!found) {
        !           168:                *get_unicode = NULL;
        !           169:                *get_hfsname = NULL;
        !           170:                return (EINVAL);
        !           171:        }
        !           172:        
        !           173:        return (0);
        !           174: }
        !           175: 
        !           176: 
        !           177: /*
        !           178:  * hfs_relconverter - release interest in an HFS encoding converter
        !           179:  *
        !           180:  * Normally called during the unmounting of an hfs voulume.
        !           181:  */
        !           182: int
        !           183: hfs_relconverter(UInt32 encoding)
        !           184: {
        !           185:        struct hfs_encoding *encp;
        !           186:        int found = 0;
        !           187: 
        !           188:        simple_lock(&hfs_encoding_list_slock);
        !           189:        SLIST_FOREACH(encp, &hfs_encoding_list, link) {
        !           190:                if (encp->encoding == encoding) {
        !           191:                        found = 1;
        !           192:                        encp->refcount--;
        !           193:                        
        !           194:                        /* if converter is no longer in use, release it */
        !           195:                        if (encp->refcount <= 0 && encp->kmod_id != 0) {
        !           196:                                int id = encp->kmod_id;
        !           197: 
        !           198:                                SLIST_REMOVE(&hfs_encoding_list, encp, hfs_encoding, link);
        !           199:                                FREE(encp, M_TEMP);
        !           200:                                encp = NULL;
        !           201: 
        !           202:                                simple_unlock(&hfs_encoding_list_slock);
        !           203:                                kmod_destroy(&realhost, id);
        !           204:                                simple_lock(&hfs_encoding_list_slock);
        !           205:                        }
        !           206:                        break;
        !           207:                }
        !           208:        }
        !           209:        simple_unlock(&hfs_encoding_list_slock);
        !           210: 
        !           211:        return (found ? 0 : EINVAL);
        !           212: }
        !           213: 
        !           214: 
        !           215: /*
        !           216:  * Convert HFS encoded string into UTF-8
        !           217:  *
        !           218:  * Unicode output is fully decomposed
        !           219:  * '/' chars are converted to ':'
        !           220:  */
        !           221: int
        !           222: hfs_to_utf8(ExtendedVCB *vcb, Str31 hfs_str, ByteCount maxDstLen, ByteCount *actualDstLen, unsigned char* dstStr)
        !           223: {
        !           224:        int error;
        !           225:        UniChar uniStr[MAX_HFS_UNICODE_CHARS];
        !           226:        ItemCount uniCount;
        !           227:        hfs_to_unicode_func_t hfs_get_unicode = VCBTOHFS(vcb)->hfs_get_unicode;
        !           228: 
        !           229:        error = hfs_get_unicode(hfs_str, uniStr, MAX_HFS_UNICODE_CHARS, &uniCount);
        !           230: 
        !           231:        if (error == 0)
        !           232:                error = ConvertUnicodeToUTF8(uniCount * sizeof(UniChar), uniStr, maxDstLen, actualDstLen, dstStr);
        !           233: 
        !           234:        return error;
        !           235: }
        !           236: 
        !           237: 
        !           238: /*
        !           239:  * Convert UTF-8 string into HFS encoding
        !           240:  *
        !           241:  * ':' chars are converted to '/'
        !           242:  * Assumes input represents fully decomposed Unicode
        !           243:  */
        !           244: int
        !           245: utf8_to_hfs(ExtendedVCB *vcb, ByteCount srcLen, const unsigned char* srcStr, Str31 dstStr)
        !           246: {
        !           247:        int error;
        !           248:        UniChar uniStr[MAX_HFS_UNICODE_CHARS];
        !           249:        ItemCount uniCount;
        !           250:        unicode_to_hfs_func_t hfs_get_hfsname = VCBTOHFS(vcb)->hfs_get_hfsname;
        !           251: 
        !           252:        error = ConvertUTF8ToUnicode(srcLen, srcStr, sizeof(uniStr), &uniCount, uniStr);
        !           253:        if (error == 0)
        !           254:                error = hfs_get_hfsname(uniStr, uniCount/sizeof(UniChar), dstStr);
        !           255: 
        !           256:        return error;
        !           257: }
        !           258: 
        !           259: 
        !           260: 
        !           261: /*
        !           262:  * HFS MacRoman to/from Unicode conversions are built into the kernel
        !           263:  * All others hfs encodings are loadable.
        !           264:  */
        !           265: 
        !           266: /* 0x00A0 - 0x00FF = Latin 1 Supplement (30 total) */
        !           267: static UInt8 gLatin1Table[] = {
        !           268:   /*             0     1     2     3     4     5     6     7     8     9     A     B     C     D     E     F  */
        !           269:   /* 0x00A0 */ 0xCA, 0xC1, 0xA2, 0xA3, 0xDB, 0xB4,  '?', 0xA4, 0xAC, 0xA9, 0xBB, 0xC7, 0xC2,  '?', 0xA8, 0xF8,
        !           270:   /* 0x00B0 */ 0xA1, 0XB1,  '?',  '?', 0xAB, 0xB5, 0xA6, 0xe1, 0xFC,  '?', 0xBC, 0xC8,  '?',  '?',  '?', 0xC0,
        !           271:   /* 0x00C0 */  '?',  '?',  '?',  '?',  '?',  '?', 0xAE,  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',
        !           272:   /* 0x00D0 */  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?', 0xAF,  '?',  '?',  '?',  '?',  '?',  '?', 0xA7,
        !           273:   /* 0x00E0 */  '?',  '?',  '?',  '?',  '?',  '?', 0xBE,  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',
        !           274:   /* 0x00F0 */  '?',  '?',  '?',  '?',  '?',  '?',  '?', 0xD6, 0xBF,  '?',  '?',  '?',  '?',  '?',  '?',  '?'
        !           275: };
        !           276: 
        !           277: /* 0x02C0 - 0x02DF = Spacing Modifiers (8 total) */
        !           278: static UInt8 gSpaceModsTable[] = {
        !           279:   /*             0     1     2     3     4     5     6     7     8     9     A     B     C     D     E     F  */
        !           280:   /* 0x02C0 */  '?',  '?',  '?',  '?',  '?',  '?', 0xF6, 0xFF,  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',
        !           281:   /* 0x02D0 */  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?', 0xF9, 0xFA, 0xFB, 0xFE, 0xF7, 0xFD,  '?',  '?'
        !           282: };
        !           283: 
        !           284: /* 0x2010 - 0x20AF = General Punctuation (17 total) */
        !           285: static UInt8 gPunctTable[] = {
        !           286:   /*             0     1     2     3     4     5     6     7     8     9     A     B     C     D     E     F  */
        !           287:   /* 0x2010 */  '?',  '?',  '?', 0xd0, 0xd1,  '?',  '?',  '?', 0xd4, 0xd5, 0xe2,  '?', 0xd2, 0xd3, 0xe3,  '?',
        !           288:   /* 0x2020 */ 0xa0, 0xe0, 0xa5,  '?',  '?',  '?', 0xc9,  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',
        !           289:   /* 0x2030 */ 0xe4,  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?', 0xdc, 0xdd,  '?',  '?',  '?',  '?',  '?',
        !           290:   /* 0x2040 */  '?',  '?',  '?',  '?', 0xda,  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',
        !           291:   /* 0x2050 */  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',
        !           292:   /* 0x2060 */  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',
        !           293:   /* 0x2070 */  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',
        !           294:   /* 0x2080 */  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',
        !           295:   /* 0x2090 */  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',
        !           296:   /* 0x20A0 */  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?', 0xdb,  '?',  '?',  '?'
        !           297: };
        !           298: 
        !           299: /* 0x22xx = Mathematical Operators (11 total) */
        !           300: static UInt8 gMathTable[] = {
        !           301:   /*             0     1     2     3     4     5     6     7     8     9     A     B     C     D     E     F  */
        !           302:   /* 0x2200 */  '?',  '?', 0xb6,  '?',  '?',  '?', 0xc6,  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?', 0xb8,
        !           303:   /* 0x2210 */  '?', 0xb7,  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?', 0xc3,  '?',  '?',  '?', 0xb0,  '?',
        !           304:   /* 0x2220 */  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?', 0xba,  '?',  '?',  '?',  '?',
        !           305:   /* 0x2230 */  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',
        !           306:   /* 0x2240 */  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?', 0xc5,  '?',  '?',  '?',  '?',  '?',  '?',  '?',
        !           307:   /* 0x2250 */  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',
        !           308:   /* 0x2260 */ 0xad,  '?',  '?',  '?', 0xb2, 0xb3,  '?',  '?'
        !           309: };
        !           310: 
        !           311: /* */
        !           312: static UInt8 gReverseCombTable[] = {
        !           313:   /*             0     1     2     3     4     5     6     7     8     9     A     B     C     D     E     F  */
        !           314:   /* 0x40 */   0xDA, 0x40, 0xDA, 0xDA, 0xDA, 0x56, 0xDA, 0xDA, 0xDA, 0x6C, 0xDA, 0xDA, 0xDA, 0xDA, 0x82, 0x98,
        !           315:   /* 0x50 */   0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xAE, 0xDA, 0xDA, 0xDA, 0xC4, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA,
        !           316:   /* 0x60 */   0xDA, 0x4B, 0xDA, 0xDA, 0xDA, 0x61, 0xDA, 0xDA, 0xDA, 0x77, 0xDA, 0xDA, 0xDA, 0xDA, 0x8D, 0xA3,
        !           317:   /* 0x70 */   0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xB9, 0xDA, 0xDA, 0xDA, 0xCF, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA,
        !           318: 
        !           319:   /* Combining Diacritical Marks (0x0300 - 0x030A) */
        !           320:   /*              0     1     2     3     4     5     6     7     8     9     A  */
        !           321:   /*  'A'   */
        !           322:   /* 0x0300 */ 0xCB, 0xE7, 0xE5, 0xCC,  '?',  '?',  '?',  '?', 0x80,  '?', 0x81,
        !           323: 
        !           324:   /*  'a'   */
        !           325:   /* 0x0300 */ 0x88, 0x87, 0x89, 0x8B,  '?',  '?',  '?',  '?', 0x8A,  '?', 0x8C,
        !           326: 
        !           327:   /*  'E'   */
        !           328:   /* 0x0300 */ 0xE9, 0x83, 0xE6,  '?',  '?',  '?',  '?',  '?', 0xE8,  '?',  '?',
        !           329: 
        !           330:   /*  'e'   */
        !           331:   /* 0x0300 */ 0x8F, 0x8E, 0x90,  '?',  '?',  '?',  '?',  '?', 0x91,  '?',  '?',
        !           332: 
        !           333:   /*  'I'   */
        !           334:   /* 0x0300 */ 0xED, 0xEA, 0xEB,  '?',  '?',  '?',  '?',  '?', 0xEC,  '?',  '?',
        !           335: 
        !           336:   /*  'i'   */
        !           337:   /* 0x0300 */ 0x93, 0x92, 0x94,  '?',  '?',  '?',  '?',  '?', 0x95,  '?',  '?',
        !           338: 
        !           339:   /*  'N'   */
        !           340:   /* 0x0300 */  '?',  '?',  '?', 0x84,  '?',  '?',  '?',  '?',  '?',  '?',  '?',
        !           341: 
        !           342:   /*  'n'   */
        !           343:   /* 0x0300 */  '?',  '?',  '?', 0x96,  '?',  '?',  '?',  '?',  '?',  '?',  '?',
        !           344: 
        !           345:   /*  'O'   */
        !           346:   /* 0x0300 */ 0xF1, 0xEE, 0xEF, 0xCD,  '?',  '?',  '?',  '?', 0x85,  '?',  '?',
        !           347: 
        !           348:   /*  'o'   */
        !           349:   /* 0x0300 */ 0x98, 0x97, 0x99, 0x9B,  '?',  '?',  '?',  '?', 0x9A,  '?',  '?',
        !           350: 
        !           351:   /*  'U'   */
        !           352:   /* 0x0300 */ 0xF4, 0xF2, 0xF3,  '?',  '?',  '?',  '?',  '?', 0x86,  '?',  '?',
        !           353: 
        !           354:   /*  'u'   */
        !           355:   /* 0x0300 */ 0x9D, 0x9C, 0x9E,  '?',  '?',  '?',  '?',  '?', 0x9F,  '?',  '?',
        !           356: 
        !           357:   /*  'Y'   */
        !           358:   /* 0x0300 */  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?', 0xD9,  '?',  '?',
        !           359: 
        !           360:   /*  'y'   */
        !           361:   /* 0x0300 */  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?', 0xD8,  '?',  '?',
        !           362: 
        !           363:   /*  else  */
        !           364:   /* 0x0300 */  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?',  '?'
        !           365: };
        !           366: 
        !           367: 
        !           368: /*
        !           369:  * Convert Unicode string into HFS MacRoman encoding
        !           370:  *
        !           371:  * Assumes Unicode input is fully decomposed
        !           372:  */
        !           373: static int unicode_to_mac_roman(UniChar *uni_str, UInt32 unicodeChars, Str31 hfs_str)
        !           374: {
        !           375:        UInt8           *p;
        !           376:        const UniChar   *u;
        !           377:        UniChar         c;
        !           378:        UniChar         mask;
        !           379:        UInt16          inputChars;
        !           380:        UInt16          pascalChars;
        !           381:        OSErr           result = noErr;
        !           382:        UInt8           lsb;
        !           383:        UInt8           prevChar;
        !           384:        UInt8           mc;
        !           385: 
        !           386:        mask = (UniChar) 0xFF80;
        !           387:        p = &hfs_str[1];
        !           388:        u = uni_str;
        !           389:        inputChars = unicodeChars;
        !           390:        pascalChars = prevChar = 0;
        !           391:        
        !           392:        while (inputChars) {
        !           393:                c = *(u++);
        !           394:                lsb = (UInt8) c;
        !           395: 
        !           396:                /*
        !           397:                 * If its not 7-bit ascii, then we need to map it
        !           398:                 */
        !           399:                if ( c & mask ) {
        !           400:                        mc = '?';
        !           401:                        switch (c & 0xFF00) {
        !           402:                        case 0x0000:
        !           403:                                if (lsb >= 0xA0)
        !           404:                                        mc = gLatin1Table[lsb - 0xA0];
        !           405:                                break;
        !           406: 
        !           407:                        case 0x0200:
        !           408:                                if (lsb >= 0xC0 && lsb <= 0xDF)
        !           409:                                        mc = gSpaceModsTable[lsb - 0xC0];
        !           410:                                break;
        !           411: 
        !           412:                        case 0x2000:
        !           413:                                if (lsb >= 0x10 && lsb <= 0xAF)
        !           414:                                        mc = gPunctTable[lsb- 0x10];
        !           415:                                break;
        !           416: 
        !           417:                        case 0x2200:
        !           418:                                if (lsb <= 0x68)
        !           419:                                        mc = gMathTable[lsb];
        !           420:                                break;
        !           421: 
        !           422:                        case 0x0300:
        !           423:                                if (c <= 0x030A) {
        !           424:                                        if (prevChar >= 'A' && prevChar < 'z') {
        !           425:                                                mc = gReverseCombTable[gReverseCombTable[prevChar - 0x40] + lsb];
        !           426:                                                --p;    /* backup over base char */
        !           427:                                                --pascalChars;
        !           428:                                        }
        !           429:                                } else {
        !           430:                                        switch (c) {
        !           431:                                        case 0x0327:    /* combining cedilla */
        !           432:                                                if (prevChar == 'C')
        !           433:                                                        mc = 0x82;
        !           434:                                                else if (prevChar == 'c')
        !           435:                                                        mc = 0x8D;
        !           436:                                                else
        !           437:                                                        break;
        !           438:                                                --p;    /* backup over base char */
        !           439:                                                --pascalChars;
        !           440:                                                break;
        !           441: 
        !           442:                                        case 0x03A9: mc = 0xBD; break;  /* omega */
        !           443: 
        !           444:                                        case 0x03C0: mc = 0xB9; break;  /* pi */
        !           445:                                        }
        !           446:                                }
        !           447:                                break;
        !           448:                                
        !           449:                        default:
        !           450:                                switch (c) {
        !           451:                                case 0x0131: mc = 0xf5; break;  /* dotless i */
        !           452: 
        !           453:                                case 0x0152: mc = 0xce; break;  /* OE */
        !           454: 
        !           455:                                case 0x0153: mc = 0xcf; break;  /* oe */
        !           456: 
        !           457:                                case 0x0192: mc = 0xc4; break;  /* � */
        !           458: 
        !           459:                                case 0x2122: mc = 0xaa; break;  /* TM */
        !           460: 
        !           461:                                case 0x25ca: mc = 0xd7; break;  /* diamond */
        !           462: 
        !           463:                                case 0xf8ff: mc = 0xf0; break;  /* apple logo */
        !           464: 
        !           465:                                case 0xfb01: mc = 0xde; break;  /* fi */
        !           466: 
        !           467:                                case 0xfb02: mc = 0xdf; break;  /* fl */
        !           468:                                }
        !           469:                        } /* end switch (c & 0xFF00) */
        !           470:                        
        !           471:                        /*
        !           472:                         * If we have an unmapped character then we need to mangle the name...
        !           473:                         */
        !           474:                        if (mc == '?')
        !           475:                                result = kTECUsedFallbacksStatus;
        !           476:                        
        !           477:                        prevChar = 0;
        !           478:                        lsb = mc;
        !           479: 
        !           480:                } else {
        !           481:                        prevChar = lsb;
        !           482:                }
        !           483: 
        !           484:                if (pascalChars >= 31)
        !           485:                        break;
        !           486: 
        !           487:                *(p++) = lsb;
        !           488:                ++pascalChars;
        !           489:                --inputChars;
        !           490: 
        !           491:        } /* end while */
        !           492:        
        !           493:        hfs_str[0] = pascalChars;
        !           494:        
        !           495:        if (inputChars > 0)
        !           496:                result = kTECOutputBufferFullStatus;    /* ran out of room! */
        !           497: 
        !           498:        return result;
        !           499: }
        !           500: 
        !           501: 
        !           502: static UniChar gHiBitBaseUnicode[128] = {
        !           503:   /* 0x80 */   0x0041, 0x0041, 0x0043, 0x0045, 0x004e, 0x004f, 0x0055, 0x0061, 
        !           504:   /* 0x88 */   0x0061, 0x0061, 0x0061, 0x0061, 0x0061, 0x0063, 0x0065, 0x0065, 
        !           505:   /* 0x90 */   0x0065, 0x0065, 0x0069, 0x0069, 0x0069, 0x0069, 0x006e, 0x006f, 
        !           506:   /* 0x98 */   0x006f, 0x006f, 0x006f, 0x006f, 0x0075, 0x0075, 0x0075, 0x0075, 
        !           507:   /* 0xa0 */   0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, 
        !           508:   /* 0xa8 */   0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8, 
        !           509:   /* 0xb0 */   0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211, 
        !           510:   /* 0xb8 */   0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x03a9, 0x00e6, 0x00f8, 
        !           511:   /* 0xc0 */   0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x2206, 0x00ab, 
        !           512:   /* 0xc8 */   0x00bb, 0x2026, 0x00a0, 0x0041, 0x0041, 0x004f, 0x0152, 0x0153, 
        !           513:   /* 0xd0 */   0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25ca, 
        !           514:   /* 0xd8 */   0x0079, 0x0059, 0x2044, 0x20ac, 0x2039, 0x203a, 0xfb01, 0xfb02, 
        !           515:   /* 0xe0 */   0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x0041, 0x0045, 0x0041, 
        !           516:   /* 0xe8 */   0x0045, 0x0045, 0x0049, 0x0049, 0x0049, 0x0049, 0x004f, 0x004f, 
        !           517:   /* 0xf0 */   0xf8ff, 0x004f, 0x0055, 0x0055, 0x0055, 0x0131, 0x02c6, 0x02dc, 
        !           518:   /* 0xf8 */   0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7
        !           519: };
        !           520: 
        !           521: static UniChar gHiBitCombUnicode[128] = {
        !           522:   /* 0x80 */   0x0308, 0x030a, 0x0327, 0x0301, 0x0303, 0x0308, 0x0308, 0x0301, 
        !           523:   /* 0x88 */   0x0300, 0x0302, 0x0308, 0x0303, 0x030a, 0x0327, 0x0301, 0x0300, 
        !           524:   /* 0x90 */   0x0302, 0x0308, 0x0301, 0x0300, 0x0302, 0x0308, 0x0303, 0x0301, 
        !           525:   /* 0x98 */   0x0300, 0x0302, 0x0308, 0x0303, 0x0301, 0x0300, 0x0302, 0x0308, 
        !           526:   /* 0xa0 */   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
        !           527:   /* 0xa8 */   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
        !           528:   /* 0xb0 */   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
        !           529:   /* 0xb8 */   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
        !           530:   /* 0xc0 */   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
        !           531:   /* 0xc8 */   0x0000, 0x0000, 0x0000, 0x0300, 0x0303, 0x0303, 0x0000, 0x0000, 
        !           532:   /* 0xd0 */   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
        !           533:   /* 0xd8 */   0x0308, 0x0308, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
        !           534:   /* 0xe0 */   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0302, 0x0302, 0x0301, 
        !           535:   /* 0xe8 */   0x0308, 0x0300, 0x0301, 0x0302, 0x0308, 0x0300, 0x0301, 0x0302, 
        !           536:   /* 0xf0 */   0x0000, 0x0300, 0x0301, 0x0302, 0x0300, 0x0000, 0x0000, 0x0000, 
        !           537:   /* 0xf8 */   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
        !           538: };
        !           539: 
        !           540: 
        !           541: /*
        !           542:  * Convert HFS MacRoman encoded string into Unicode
        !           543:  *
        !           544:  * Unicode output is fully decomposed
        !           545:  */
        !           546: static int mac_roman_to_unicode(Str31 hfs_str, UniChar *uni_str,
        !           547:                                UInt32 maxCharLen, UInt32 *unicodeChars)
        !           548: {
        !           549:        const UInt8  *p;
        !           550:        UniChar  *u;
        !           551:        UInt16  pascalChars;
        !           552:        UInt8  c;
        !           553: 
        !           554:        p = hfs_str;
        !           555:        u = uni_str;
        !           556: 
        !           557:        *unicodeChars = pascalChars = *(p++);   /* pick up length byte */
        !           558: 
        !           559:        while (pascalChars--) {
        !           560:                c = *(p++);
        !           561: 
        !           562:                if ( (SInt8) c >= 0 ) {         /* check if seven bit ascii */
        !           563:                        *(u++) = (UniChar) c;   /* just pad high byte with zero */
        !           564:                } else { /* its a hi bit character */
        !           565:                        UniChar uc;
        !           566: 
        !           567:                        c &= 0x7F;
        !           568:                        *(u++) = uc = gHiBitBaseUnicode[c];
        !           569:                        
        !           570:                        /*
        !           571:                         * if the unicode character we get back is an alpha char
        !           572:                         * then we must have an additional combining character
        !           573:                         */
        !           574:                        if ((uc <= (UniChar) 'z') && (uc >= (UniChar) 'A')) {
        !           575:                                *(u++) = gHiBitCombUnicode[c];
        !           576:                                ++(*unicodeChars);
        !           577:                        }
        !           578:                }
        !           579:        }
        !           580:        
        !           581:        return noErr;
        !           582: }
        !           583: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.