Annotation of XNU/bsd/hfs/hfs_encodings.c, revision 1.1.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.