194663Sscottl/* 294663Sscottl * Various routines from the OSTA 2.01 specs. Copyrights are included with 394663Sscottl * each code segment. Slight whitespace modifications have been made for 494663Sscottl * formatting purposes. Typos/bugs have been fixed. 594663Sscottl * 694663Sscottl * $FreeBSD$ 794663Sscottl */ 894663Sscottl 994663Sscottl#include <fs/udf/osta.h> 1094663Sscottl 1194663Sscottl/*****************************************************************************/ 12139776Simp/*- 13139776Simp ********************************************************************** 1494663Sscottl * OSTA compliant Unicode compression, uncompression routines. 1594663Sscottl * Copyright 1995 Micro Design International, Inc. 1694663Sscottl * Written by Jason M. Rinn. 1794663Sscottl * Micro Design International gives permission for the free use of the 1894663Sscottl * following source code. 1994663Sscottl */ 2094663Sscottl 2194663Sscottl/*********************************************************************** 2294663Sscottl * Takes an OSTA CS0 compressed unicode name, and converts 2394663Sscottl * it to Unicode. 2494663Sscottl * The Unicode output will be in the byte order 2594663Sscottl * that the local compiler uses for 16-bit values. 2694663Sscottl * NOTE: This routine only performs error checking on the compID. 2794663Sscottl * It is up to the user to ensure that the unicode buffer is large 2894663Sscottl * enough, and that the compressed unicode name is correct. 2994663Sscottl * 3094663Sscottl * RETURN VALUE 3194663Sscottl * 3294663Sscottl * The number of unicode characters which were uncompressed. 3394663Sscottl * A -1 is returned if the compression ID is invalid. 3494663Sscottl */ 3594663Sscottlint 3694663Sscottludf_UncompressUnicode( 3794663Sscottl int numberOfBytes, /* (Input) number of bytes read from media. */ 3894663Sscottl byte *UDFCompressed, /* (Input) bytes read from media. */ 3994663Sscottl unicode_t *unicode) /* (Output) uncompressed unicode characters. */ 4094663Sscottl{ 4194663Sscottl unsigned int compID; 4294663Sscottl int returnValue, unicodeIndex, byteIndex; 4394663Sscottl 4494663Sscottl /* Use UDFCompressed to store current byte being read. */ 4594663Sscottl compID = UDFCompressed[0]; 4694663Sscottl 4794663Sscottl /* First check for valid compID. */ 4894663Sscottl if (compID != 8 && compID != 16) { 4994663Sscottl returnValue = -1; 5094663Sscottl } else { 5194663Sscottl unicodeIndex = 0; 5294663Sscottl byteIndex = 1; 5394663Sscottl 5494663Sscottl /* Loop through all the bytes. */ 5594663Sscottl while (byteIndex < numberOfBytes) { 5694663Sscottl if (compID == 16) { 5794663Sscottl /* Move the first byte to the high bits of the 5894663Sscottl * unicode char. 5994663Sscottl */ 6094663Sscottl unicode[unicodeIndex] = 6194663Sscottl UDFCompressed[byteIndex++] << 8; 6294663Sscottl } else { 6394663Sscottl unicode[unicodeIndex] = 0; 6494663Sscottl } 6594663Sscottl if (byteIndex < numberOfBytes) { 6694663Sscottl /*Then the next byte to the low bits. */ 6794663Sscottl unicode[unicodeIndex] |= 6894663Sscottl UDFCompressed[byteIndex++]; 6994663Sscottl } 7094663Sscottl unicodeIndex++; 7194663Sscottl } 7294663Sscottl returnValue = unicodeIndex; 7394663Sscottl } 7494663Sscottl return(returnValue); 7594663Sscottl} 7694663Sscottl 77122101Sscottl/* 78122101Sscottl * Almost same as udf_UncompressUnicode(). The difference is that 79122101Sscottl * it keeps byte order of unicode string. 80122101Sscottl */ 81122101Sscottlint 82122101Sscottludf_UncompressUnicodeByte( 83122101Sscottl int numberOfBytes, /* (Input) number of bytes read from media. */ 84122101Sscottl byte *UDFCompressed, /* (Input) bytes read from media. */ 85122101Sscottl byte *unicode) /* (Output) uncompressed unicode characters. */ 86122101Sscottl{ 87122101Sscottl unsigned int compID; 88122101Sscottl int returnValue, unicodeIndex, byteIndex; 89122101Sscottl 90122101Sscottl /* Use UDFCompressed to store current byte being read. */ 91122101Sscottl compID = UDFCompressed[0]; 92122101Sscottl 93122101Sscottl /* First check for valid compID. */ 94122101Sscottl if (compID != 8 && compID != 16) { 95122101Sscottl returnValue = -1; 96122101Sscottl } else { 97122101Sscottl unicodeIndex = 0; 98122101Sscottl byteIndex = 1; 99122101Sscottl 100122101Sscottl /* Loop through all the bytes. */ 101122101Sscottl while (byteIndex < numberOfBytes) { 102122101Sscottl if (compID == 16) { 103122101Sscottl /* Move the first byte to the high bits of the 104122101Sscottl * unicode char. 105122101Sscottl */ 106122101Sscottl unicode[unicodeIndex++] = 107122101Sscottl UDFCompressed[byteIndex++]; 108122101Sscottl } else { 109122101Sscottl unicode[unicodeIndex++] = 0; 110122101Sscottl } 111122101Sscottl if (byteIndex < numberOfBytes) { 112122101Sscottl /*Then the next byte to the low bits. */ 113122101Sscottl unicode[unicodeIndex++] = 114122101Sscottl UDFCompressed[byteIndex++]; 115122101Sscottl } 116122101Sscottl } 117122101Sscottl returnValue = unicodeIndex; 118122101Sscottl } 119122101Sscottl return(returnValue); 120122101Sscottl} 121122101Sscottl 12294663Sscottl/*********************************************************************** 12394663Sscottl * DESCRIPTION: 12494663Sscottl * Takes a string of unicode wide characters and returns an OSTA CS0 12594663Sscottl * compressed unicode string. The unicode MUST be in the byte order of 12694663Sscottl * the compiler in order to obtain correct results. Returns an error 12794663Sscottl * if the compression ID is invalid. 12894663Sscottl * 12994663Sscottl * NOTE: This routine assumes the implementation already knows, by 13094663Sscottl * the local environment, how many bits are appropriate and 13194663Sscottl * therefore does no checking to test if the input characters fit 13294663Sscottl * into that number of bits or not. 13394663Sscottl * 13494663Sscottl * RETURN VALUE 13594663Sscottl * 13694663Sscottl * The total number of bytes in the compressed OSTA CS0 string, 13794663Sscottl * including the compression ID. 13894663Sscottl * A -1 is returned if the compression ID is invalid. 13994663Sscottl */ 14094663Sscottlint 14194663Sscottludf_CompressUnicode( 14294663Sscottl int numberOfChars, /* (Input) number of unicode characters. */ 14394663Sscottl int compID, /* (Input) compression ID to be used. */ 14494663Sscottl unicode_t *unicode, /* (Input) unicode characters to compress. */ 14594663Sscottl byte *UDFCompressed) /* (Output) compressed string, as bytes. */ 14694663Sscottl{ 14794663Sscottl int byteIndex, unicodeIndex; 14894663Sscottl 14994663Sscottl if (compID != 8 && compID != 16) { 15094663Sscottl byteIndex = -1; /* Unsupported compression ID ! */ 15194663Sscottl } else { 15294663Sscottl /* Place compression code in first byte. */ 15394663Sscottl UDFCompressed[0] = compID; 15494663Sscottl 15594663Sscottl byteIndex = 1; 15694663Sscottl unicodeIndex = 0; 15794663Sscottl while (unicodeIndex < numberOfChars) { 15894663Sscottl if (compID == 16) { 15994663Sscottl /* First, place the high bits of the char 16094663Sscottl * into the byte stream. 16194663Sscottl */ 16294663Sscottl UDFCompressed[byteIndex++] = 16394663Sscottl (unicode[unicodeIndex] & 0xFF00) >> 8; 16494663Sscottl } 16594663Sscottl /*Then place the low bits into the stream. */ 16694663Sscottl UDFCompressed[byteIndex++] = 16794663Sscottl unicode[unicodeIndex] & 0x00FF; 16894663Sscottl unicodeIndex++; 16994663Sscottl } 17094663Sscottl } 17194663Sscottl return(byteIndex); 17294663Sscottl} 17394663Sscottl 17494663Sscottl/*****************************************************************************/ 17594663Sscottl/* 17694663Sscottl * CRC 010041 17794663Sscottl */ 17894663Sscottlstatic unsigned short crc_table[256] = { 17994663Sscottl 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 18094663Sscottl 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 18194663Sscottl 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 18294663Sscottl 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 18394663Sscottl 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, 18494663Sscottl 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, 18594663Sscottl 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, 18694663Sscottl 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, 18794663Sscottl 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, 18894663Sscottl 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 18994663Sscottl 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 19094663Sscottl 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 19194663Sscottl 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 19294663Sscottl 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 19394663Sscottl 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, 19494663Sscottl 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, 19594663Sscottl 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, 19694663Sscottl 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, 19794663Sscottl 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 19894663Sscottl 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, 19994663Sscottl 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 20094663Sscottl 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 20194663Sscottl 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, 20294663Sscottl 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, 20394663Sscottl 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, 20494663Sscottl 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, 20594663Sscottl 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, 20694663Sscottl 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, 20794663Sscottl 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 20894663Sscottl 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 20994663Sscottl 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 21094663Sscottl 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 21194663Sscottl}; 21294663Sscottl 21394663Sscottlunsigned short 21494663Sscottludf_cksum(s, n) 21594663Sscottl unsigned char *s; 21694663Sscottl int n; 21794663Sscottl{ 21894663Sscottl unsigned short crc=0; 21994663Sscottl 22094663Sscottl while (n-- > 0) 22194663Sscottl crc = crc_table[(crc>>8 ^ *s++) & 0xff] ^ (crc<<8); 22294663Sscottl return crc; 22394663Sscottl} 22494663Sscottl 22594663Sscottl/* UNICODE Checksum */ 22694663Sscottlunsigned short 22794663Sscottludf_unicode_cksum(s, n) 22894663Sscottl unsigned short *s; 22994663Sscottl int n; 23094663Sscottl{ 23194663Sscottl unsigned short crc=0; 23294663Sscottl 23394663Sscottl while (n-- > 0) { 23494663Sscottl /* Take high order byte first--corresponds to a big endian 23594663Sscottl * byte stream. 23694663Sscottl */ 23794663Sscottl crc = crc_table[(crc>>8 ^ (*s>>8)) & 0xff] ^ (crc<<8); 23894663Sscottl crc = crc_table[(crc>>8 ^ (*s++ & 0xff)) & 0xff] ^ (crc<<8); 23994663Sscottl } 24094663Sscottl return crc; 24194663Sscottl} 24294663Sscottl 24394663Sscottl#ifdef MAIN 24494663Sscottlunsigned char bytes[] = { 0x70, 0x6A, 0x77 }; 24594663Sscottl 24694663Sscottlmain() 24794663Sscottl{ 24894663Sscottl unsigned short x; 24994663Sscottl x = cksum(bytes, sizeof bytes); 25094663Sscottl printf("checksum: calculated=%4.4x, correct=%4.4x\en", x, 0x3299); 25194663Sscottl exit(0); 25294663Sscottl} 25394663Sscottl#endif 25494663Sscottl 25594663Sscottl/*****************************************************************************/ 25694663Sscottl#ifdef NEEDS_ISPRINT 257139776Simp/*- 258139776Simp ********************************************************************** 25994663Sscottl * OSTA UDF compliant file name translation routine for OS/2, 26094663Sscottl * Windows 95, Windows NT, Macintosh and UNIX. 26194663Sscottl * Copyright 1995 Micro Design International, Inc. 26294663Sscottl * Written by Jason M. Rinn. 26394663Sscottl * Micro Design International gives permission for the free use of the 26494663Sscottl * following source code. 26594663Sscottl */ 26694663Sscottl 26794663Sscottl/*********************************************************************** 26894663Sscottl * To use these routines with different operating systems. 26994663Sscottl * 27094663Sscottl * OS/2 27194663Sscottl * Define OS2 27294663Sscottl * Define MAXLEN = 254 27394663Sscottl * 27494663Sscottl * Windows 95 27594663Sscottl * Define WIN_95 27694663Sscottl * Define MAXLEN = 255 27794663Sscottl * 27894663Sscottl * Windows NT 27994663Sscottl * Define WIN_NT 28094663Sscottl * Define MAXLEN = 255 28194663Sscottl * 28294663Sscottl * Macintosh: 283193571Srwatson * Define APPLE_MAC. 28494663Sscottl * Define MAXLEN = 31. 28594663Sscottl * 28694663Sscottl * UNIX 28794663Sscottl * Define UNIX. 28894663Sscottl * Define MAXLEN as specified by unix version. 28994663Sscottl */ 29094663Sscottl 29194663Sscottl#define ILLEGAL_CHAR_MARK 0x005F 29294663Sscottl#define CRC_MARK 0x0023 29394663Sscottl#define EXT_SIZE 5 29494663Sscottl#define TRUE 1 29594663Sscottl#define FALSE 0 29694663Sscottl#define PERIOD 0x002E 29794663Sscottl#define SPACE 0x0020 29894663Sscottl 29994663Sscottl/*** PROTOTYPES ***/ 30094663Sscottlint IsIllegal(unicode_t ch); 30194663Sscottl 30294663Sscottl/* Define a function or macro which determines if a Unicode character is 30394663Sscottl * printable under your implementation. 30494663Sscottl */ 30594663Sscottlint UnicodeIsPrint(unicode_t); 30694663Sscottl 30794663Sscottl/*********************************************************************** 30894663Sscottl * Translates a long file name to one using a MAXLEN and an illegal 30994663Sscottl * char set in accord with the OSTA requirements. Assumes the name has 31094663Sscottl * already been translated to Unicode. 31194663Sscottl * 31294663Sscottl * RETURN VALUE 31394663Sscottl * 31494663Sscottl * Number of unicode characters in translated name. 31594663Sscottl */ 31694663Sscottlint UDFTransName( 31794663Sscottl unicode_t *newName, /* (Output)Translated name. Must be of length 31894663Sscottl * MAXLEN */ 31994663Sscottl unicode_t *udfName, /* (Input) Name from UDF volume.*/ 32094663Sscottl int udfLen) /* (Input) Length of UDF Name. */ 32194663Sscottl{ 32294663Sscottl int index, newIndex = 0, needsCRC = FALSE; 32394663Sscottl int extIndex = 0, newExtIndex = 0, hasExt = FALSE; 32494663Sscottl#if defined OS2 || defined WIN_95 || defined WIN_NT 32594663Sscottl int trailIndex = 0; 32694663Sscottl#endif 32794663Sscottl unsigned short valueCRC; 32894663Sscottl unicode_t current; 32994663Sscottl const char hexChar[] = "0123456789ABCDEF"; 33094663Sscottl 33194663Sscottl for (index = 0; index < udfLen; index++) { 33294663Sscottl current = udfName[index]; 33394663Sscottl 33494663Sscottl if (IsIllegal(current) || !UnicodeIsPrint(current)) { 33594663Sscottl needsCRC = TRUE; 33694663Sscottl /* Replace Illegal and non-displayable chars with 33794663Sscottl * underscore. 33894663Sscottl */ 33994663Sscottl current = ILLEGAL_CHAR_MARK; 34094663Sscottl /* Skip any other illegal or non-displayable 34194663Sscottl * characters. 34294663Sscottl */ 34394663Sscottl while(index+1 < udfLen && (IsIllegal(udfName[index+1]) 34494663Sscottl || !UnicodeIsPrint(udfName[index+1]))) { 34594663Sscottl index++; 34694663Sscottl } 34794663Sscottl } 34894663Sscottl 34994663Sscottl /* Record position of extension, if one is found. */ 35094663Sscottl if (current == PERIOD && (udfLen - index -1) <= EXT_SIZE) { 35194663Sscottl if (udfLen == index + 1) { 35294663Sscottl /* A trailing period is NOT an extension. */ 35394663Sscottl hasExt = FALSE; 35494663Sscottl } else { 35594663Sscottl hasExt = TRUE; 35694663Sscottl extIndex = index; 35794663Sscottl newExtIndex = newIndex; 35894663Sscottl } 35994663Sscottl } 36094663Sscottl 36194663Sscottl#if defined OS2 || defined WIN_95 || defined WIN_NT 36294663Sscottl /* Record position of last char which is NOT period or space. */ 36394663Sscottl else if (current != PERIOD && current != SPACE) { 36494663Sscottl trailIndex = newIndex; 36594663Sscottl } 36694663Sscottl#endif 36794663Sscottl 36894663Sscottl if (newIndex < MAXLEN) { 36994663Sscottl newName[newIndex++] = current; 37094663Sscottl } else { 37194663Sscottl needsCRC = TRUE; 37294663Sscottl } 37394663Sscottl } 37494663Sscottl 37594663Sscottl#if defined OS2 || defined WIN_95 || defined WIN_NT 37694663Sscottl /* For OS2, 95 & NT, truncate any trailing periods and\or spaces. */ 37794663Sscottl if (trailIndex != newIndex - 1) { 37894663Sscottl newIndex = trailIndex + 1; 37994663Sscottl needsCRC = TRUE; 38094663Sscottl hasExt = FALSE; /* Trailing period does not make an 38194663Sscottl * extension. */ 38294663Sscottl } 38394663Sscottl#endif 38494663Sscottl 38594663Sscottl if (needsCRC) { 38694663Sscottl unicode_t ext[EXT_SIZE]; 38794663Sscottl int localExtIndex = 0; 38894663Sscottl if (hasExt) { 38994663Sscottl int maxFilenameLen; 39094663Sscottl /* Translate extension, and store it in ext. */ 39194663Sscottl for(index = 0; index<EXT_SIZE && 39294663Sscottl extIndex + index +1 < udfLen; index++ ) { 39394663Sscottl current = udfName[extIndex + index + 1]; 39494663Sscottl if (IsIllegal(current) || 39594663Sscottl !UnicodeIsPrint(current)) { 39694663Sscottl needsCRC = 1; 39794663Sscottl /* Replace Illegal and non-displayable 39894663Sscottl * chars with underscore. 39994663Sscottl */ 40094663Sscottl current = ILLEGAL_CHAR_MARK; 40194663Sscottl /* Skip any other illegal or 40294663Sscottl * non-displayable characters. 40394663Sscottl */ 40494663Sscottl while(index + 1 < EXT_SIZE 40594663Sscottl && (IsIllegal(udfName[extIndex + 40694663Sscottl index + 2]) || 40794663Sscottl !isprint(udfName[extIndex + 40894663Sscottl index + 2]))) { 40994663Sscottl index++; 41094663Sscottl } 41194663Sscottl } 41294663Sscottl ext[localExtIndex++] = current; 41394663Sscottl } 41494663Sscottl 41594663Sscottl /* Truncate filename to leave room for extension and 41694663Sscottl * CRC. 41794663Sscottl */ 41894663Sscottl maxFilenameLen = ((MAXLEN - 5) - localExtIndex - 1); 41994663Sscottl if (newIndex > maxFilenameLen) { 42094663Sscottl newIndex = maxFilenameLen; 42194663Sscottl } else { 42294663Sscottl newIndex = newExtIndex; 42394663Sscottl } 42494663Sscottl } else if (newIndex > MAXLEN - 5) { 42594663Sscottl /*If no extension, make sure to leave room for CRC. */ 42694663Sscottl newIndex = MAXLEN - 5; 42794663Sscottl } 42894663Sscottl newName[newIndex++] = CRC_MARK; /* Add mark for CRC. */ 42994663Sscottl 43094663Sscottl /*Calculate CRC from original filename from FileIdentifier. */ 43194663Sscottl valueCRC = udf_unicode_cksum(udfName, udfLen); 43294663Sscottl /* Convert 16-bits of CRC to hex characters. */ 43394663Sscottl newName[newIndex++] = hexChar[(valueCRC & 0xf000) >> 12]; 43494663Sscottl newName[newIndex++] = hexChar[(valueCRC & 0x0f00) >> 8]; 43594663Sscottl newName[newIndex++] = hexChar[(valueCRC & 0x00f0) >> 4]; 43694663Sscottl newName[newIndex++] = hexChar[(valueCRC & 0x000f)]; 43794663Sscottl 43894663Sscottl /* Place a translated extension at end, if found. */ 43994663Sscottl if (hasExt) { 44094663Sscottl newName[newIndex++] = PERIOD; 44194663Sscottl for (index = 0;index < localExtIndex ;index++ ) { 44294663Sscottl newName[newIndex++] = ext[index]; 44394663Sscottl } 44494663Sscottl } 44594663Sscottl } 44694663Sscottl return(newIndex); 44794663Sscottl} 44894663Sscottl 44994663Sscottl#if defined OS2 || defined WIN_95 || defined WIN_NT 45094663Sscottl/*********************************************************************** 45194663Sscottl * Decides if a Unicode character matches one of a list 45294663Sscottl * of ASCII characters. 45394663Sscottl * Used by OS2 version of IsIllegal for readability, since all of the 45494663Sscottl * illegal characters above 0x0020 are in the ASCII subset of Unicode. 45594663Sscottl * Works very similarly to the standard C function strchr(). 45694663Sscottl * 45794663Sscottl * RETURN VALUE 45894663Sscottl * 45994663Sscottl * Non-zero if the Unicode character is in the given ASCII string. 46094663Sscottl */ 46194663Sscottlint UnicodeInString( 46294663Sscottl unsigned char *string, /* (Input) String to search through. */ 46394663Sscottl unicode_t ch) /* (Input) Unicode char to search for. */ 46494663Sscottl{ 46594663Sscottl int found = FALSE; 46694663Sscottl while (*string != '\0' && found == FALSE) { 46794663Sscottl /* These types should compare, since both are unsigned 46894663Sscottl * numbers. */ 46994663Sscottl if (*string == ch) { 47094663Sscottl found = TRUE; 47194663Sscottl } 47294663Sscottl string++; 47394663Sscottl } 47494663Sscottl return(found); 47594663Sscottl} 47694663Sscottl#endif /* OS2 */ 47794663Sscottl 47894663Sscottl/*********************************************************************** 47994663Sscottl * Decides whether the given character is illegal for a given OS. 48094663Sscottl * 48194663Sscottl * RETURN VALUE 48294663Sscottl * 48394663Sscottl * Non-zero if char is illegal. 48494663Sscottl */ 48594663Sscottlint IsIllegal(unicode_t ch) 48694663Sscottl{ 487193571Srwatson#ifdef APPLE_MAC 48894663Sscottl /* Only illegal character on the MAC is the colon. */ 48994663Sscottl if (ch == 0x003A) { 49094663Sscottl return(1); 49194663Sscottl } else { 49294663Sscottl return(0); 49394663Sscottl } 49494663Sscottl 49594663Sscottl#elif defined UNIX 49694663Sscottl /* Illegal UNIX characters are NULL and slash. */ 49794663Sscottl if (ch == 0x0000 || ch == 0x002F) { 49894663Sscottl return(1); 49994663Sscottl } else { 50094663Sscottl return(0); 50194663Sscottl } 50294663Sscottl 50394663Sscottl#elif defined OS2 || defined WIN_95 || defined WIN_NT 50494663Sscottl /* Illegal char's for OS/2 according to WARP toolkit. */ 50594663Sscottl if (ch < 0x0020 || UnicodeInString("\\/:*?\"<>|", ch)) { 50694663Sscottl return(1); 50794663Sscottl } else { 50894663Sscottl return(0); 50994663Sscottl } 51094663Sscottl#endif 51194663Sscottl} 51294663Sscottl#endif 513