* under the License.␊ |
* ␊ |
* @APPLE_LICENSE_HEADER_END@␊ |
*/␊ |
/*␊ |
* HFSCompare.c - Functions for working with and comparing HFS nams.␊ |
*␊ |
* Copyright (c) 1999-2000 Apple Computer, Inc.␊ |
* HFSCompare.c - Functions for working with and comparing HFS nams.␊ |
*␊ |
* DRI: Josh de Cesare␊ |
* Copyright (c) 1999-2000 Apple Computer, Inc.␊ |
*␊ |
* DRI: Josh de Cesare␊ |
*/␊ |
␊ |
#include <sl.h>␊ |
|
␊ |
#if ! UNCOMPRESSED␊ |
␊ |
static unsigned short *␊ |
UncompressStructure(struct compressed_block *bp, int count, int size)␊ |
static unsigned short *UncompressStructure(struct compressed_block *bp, int count, int size)␊ |
{␊ |
unsigned short *out = malloc(size);␊ |
unsigned short *op = out;␊ |
unsigned short data;␊ |
int i, j;␊ |
␉int i, j;␊ |
␊ |
for (i=0; i<count; i++, bp++) {␊ |
// If this happens (it shouldn't) please fix size and/or double check that count really is␊ |
// the number of elements in the array.␊ |
// This was a very hard bug to find, so please leave this code here.␊ |
if(out + size <= op + bp->count)␊ |
{␊ |
stop("HFS+ Unicode tables are malformed\n");␊ |
}␊ |
data = bp->data;␊ |
for (j=0; j<bp->count; j++) {␊ |
*op++ = data;␊ |
if (bp->type == kTypeAscending) data++;␊ |
else if (bp->type == kTypeAscending256) data += 256;␊ |
}␊ |
}␊ |
return out;␊ |
␉unsigned short *out = malloc(size);␊ |
␊ |
␉if (out)␊ |
␉{␊ |
␉␉unsigned short *op = out;␊ |
␉␉unsigned short data;␊ |
␊ |
␉␉for (i = 0; i < count; i++, bp++)␊ |
␉␉{␊ |
␉␉␉// If this happens (it shouldn't) please fix size and/or double check that count really is␊ |
␉␉␉// the number of elements in the array.␊ |
␉␉␉ // This was a very hard bug to find, so please leave this code here.␊ |
␉␉␉if(out + size <= op + bp->count)␊ |
␉␉␉{␊ |
␉␉␉␉stop("HFS+ Unicode tables are malformed\n");␊ |
␉␉␉}␊ |
␊ |
␉␉␉data = bp->data;␊ |
␊ |
␉␉␉for (j = 0; j < bp->count; j++)␊ |
␉␉␉{␊ |
␉␉␉␉*op++ = data;␊ |
␊ |
␉␉␉␉if (bp->type == kTypeAscending)␊ |
␉␉␉␉{␊ |
␉␉␉␉␉data++;␊ |
␉␉␉␉}␊ |
␉␉␉␉else if (bp->type == kTypeAscending256)␊ |
␉␉␉␉{␊ |
␉␉␉␉␉data += 256;␊ |
␉␉␉␉}␊ |
␉␉␉}␊ |
␉␉}␊ |
␊ |
␉␉return out;␊ |
␉}␊ |
␊ |
␉return NULL;␊ |
}␊ |
␊ |
static void␊ |
InitCompareTables(void)␊ |
static void InitCompareTables(void)␊ |
{␊ |
if (gCompareTable == 0) {␊ |
gCompareTable = UncompressStructure(gCompareTableCompressed,␊ |
␉if (gCompareTable == 0)␊ |
␉{␊ |
␉␉gCompareTable = UncompressStructure(gCompareTableCompressed,␊ |
kCompareTableNBlocks, kCompareTableDataSize);␊ |
gLowerCaseTable = UncompressStructure(gLowerCaseTableCompressed,␊ |
␉␉gLowerCaseTable = UncompressStructure(gLowerCaseTableCompressed,␊ |
kLowerCaseTableNBlocks, kLowerCaseTableDataSize);␊ |
}␊ |
␉}␊ |
}␊ |
␊ |
#endif /* ! UNCOMPRESSED */␊ |
␊ |
//_______________________________________________________________________␊ |
//␊ |
//␊ |
//␉Routine:␉FastRelString␊ |
//␊ |
//␉Output:␉␉returns -1 if str1 < str2␊ |
//␉␉␉␉returns 1 if str1 > str2␊ |
//␉␉␉␉return␉ 0 if equal␊ |
//␊ |
//_______________________________________________________________________␊ |
//␊ |
␊ |
int32_t␉FastRelString(u_int8_t * str1, u_int8_t * str2)␊ |
{␊ |
|
␉length2 = *(str2++);␊ |
␊ |
␉if (length == length2)␊ |
␉{␊ |
␉␉bestGuess = 0;␊ |
␉}␊ |
␉else if (length < length2)␊ |
␉{␊ |
␉␉bestGuess = -1;␊ |
␉}␊ |
␉else␊ |
␉{␊ |
␉␉bestGuess = 1;␊ |
|
␉␉␉bSortWord = gCompareTable[bChar];␊ |
␊ |
␉␉␉if (aSortWord > bSortWord)␊ |
␉␉␉{␊ |
␉␉␉␉return 1;␊ |
␉␉␉}␊ |
␊ |
␉␉␉if (aSortWord < bSortWord)␊ |
␉␉␉{␊ |
␉␉␉␉return -1;␊ |
␉␉␉}␊ |
␉␉}␊ |
␊ |
␉␉/*␊ |
|
//␉␉␉return 1;␊ |
//␊ |
␊ |
int32_t FastUnicodeCompare( u_int16_t * str1, register u_int32_t length1,␊ |
u_int16_t * str2, register u_int32_t length2, int byte_order )␊ |
int32_t FastUnicodeCompare( u_int16_t * str1, register u_int32_t length1, u_int16_t * str2, register u_int32_t length2, int byte_order )␊ |
{␊ |
␉register u_int16_t c1,c2;␊ |
␉register u_int16_t temp;␊ |
|
InitCompareTables();␊ |
#endif␊ |
␊ |
␉while (1) {␊ |
␉while (1)␊ |
␉{␊ |
␉␉/* Set default values for c1, c2 in case there are no more valid chars */␊ |
␉␉c1 = 0;␊ |
␉␉c2 = 0;␊ |
␊ |
␉␉/* Find next non-ignorable char from str1, or zero if no more */␊ |
␉␉while (length1 && c1 == 0) {␊ |
␉␉while (length1 && c1 == 0)␊ |
␉␉{␊ |
␉␉␉if (byte_order == OSBigEndian)␊ |
␉␉␉{␊ |
␉␉␉␉c1 = SWAP_BE16(*(str1++));␊ |
␉␉␉}␊ |
␉␉␉else␊ |
␉␉␉{␊ |
␉␉␉␉c1 = SWAP_LE16(*(str1++));␊ |
␉␉␉}␊ |
␊ |
␉␉␉--length1;␊ |
␉␉␉if ((temp = gLowerCaseTable[c1>>8]) != 0)␉␉// is there a subtable for this upper byte?␊ |
␉␉␉␉c1 = gLowerCaseTable[temp + (c1 & 0x00FF)];␉// yes, so fold the char␊ |
␉␉}␊ |
␊ |
␉␉/* Find next non-ignorable char from str2, or zero if no more */␊ |
␉␉while (length2 && c2 == 0) {␊ |
␉␉while (length2 && c2 == 0)␊ |
␉␉{␊ |
␉␉␉if (byte_order == OSBigEndian)␊ |
␉␉␉{␊ |
␉␉␉␉c2 = SWAP_BE16(*(str2++));␊ |
␉␉␉}␊ |
␉␉␉else␊ |
␉␉␉{␊ |
␉␉␉␉c2 = SWAP_LE16(*(str2++));␊ |
␉␉␉}␊ |
␉␉␉--length2;␊ |
␉␉␉if ((temp = gLowerCaseTable[c2>>8]) != 0)␉␉// is there a subtable for this upper byte?␊ |
␉␉␉␉c2 = gLowerCaseTable[temp + (c2 & 0x00FF)];␉// yes, so fold the char␊ |
␉␉␉if ((temp = gLowerCaseTable[c2>>8]) != 0)␉␉// Is there a subtable for this upper byte?␊ |
␉␉␉{␊ |
␉␉␉␉c2 = gLowerCaseTable[temp + (c2 & 0x00FF)];␉// Yes, so fold the char␊ |
␉␉␉}␊ |
␉␉}␊ |
␊ |
␉␉if (c1 != c2)␉/* found a difference, so stop looping */␊ |
␉␉if (c1 != c2)␉/* Found a difference, so stop looping */␊ |
␉␉{␊ |
␉␉␉break;␊ |
␉␉␊ |
␉␉if (c1 == 0)␉␉/* did we reach the end of both strings at the same time? */␊ |
␉␉␉return 0;␉/* yes, so strings are equal */␊ |
␉␉}␊ |
␊ |
␉␉if (c1 == 0)␉␉/* Did we reach the end of both strings at the same time? */␊ |
␉␉{␊ |
␉␉␉return 0;␉/* Yes, so strings are equal */␊ |
␉␉}␊ |
␉}␊ |
␉␊ |
␉if (c1 < c2)␊ |
␉{␊ |
␉␉return -1;␊ |
␉}␊ |
␉else␊ |
␉{␊ |
␉␉return 1;␊ |
␉}␊ |
}␊ |
␊ |
␊ |
|
// BinaryUnicodeCompare - Compare two Unicode strings; produce a relative ordering␊ |
// Compared using a 16-bit binary comparison (no case folding)␊ |
//␊ |
int32_t BinaryUnicodeCompare (u_int16_t * str1, u_int32_t length1,␊ |
u_int16_t * str2, u_int32_t length2)␊ |
int32_t BinaryUnicodeCompare(u_int16_t * str1, u_int32_t length1, u_int16_t * str2, u_int32_t length2)␊ |
{␊ |
register u_int16_t c1, c2;␊ |
int32_t bestGuess;␊ |
u_int32_t length;␊ |
␉register u_int16_t c1, c2;␊ |
␉int32_t bestGuess = 0;␊ |
␉u_int32_t length;␊ |
␊ |
bestGuess = 0;␊ |
␉if (length1 < length2)␊ |
␉{␊ |
␉␉length = length1;␊ |
␉␉--bestGuess;␊ |
␉}␊ |
␉else if (length1 > length2)␊ |
␉{␊ |
␉␉length = length2;␊ |
␉␉++bestGuess;␊ |
␉}␊ |
␉else␊ |
␉{␊ |
␉␉length = length1;␊ |
␉}␊ |
␊ |
if (length1 < length2) {␊ |
length = length1;␊ |
--bestGuess;␊ |
} else if (length1 > length2) {␊ |
length = length2;␊ |
++bestGuess;␊ |
} else {␊ |
length = length1;␊ |
}␊ |
␉while (length--)␊ |
␉{␊ |
␉␉c1 = *(str1++);␊ |
␉␉c2 = *(str2++);␊ |
␊ |
while (length--) {␊ |
c1 = *(str1++);␊ |
c2 = *(str2++);␊ |
␉␉if (c1 > c2)␊ |
␉␉{␊ |
␉␉␉return (1);␊ |
␉␉}␊ |
␊ |
if (c1 > c2)␊ |
return (1);␊ |
if (c1 < c2)␊ |
return (-1);␊ |
}␊ |
␉␉if (c1 < c2)␊ |
␉␉{␊ |
␉␉␉return (-1);␊ |
␉␉}␊ |
␉}␊ |
␊ |
return (bestGuess);␊ |
␉return (bestGuess);␊ |
}␊ |
␊ |
␊ |
|
* requires a maximum of three 3 bytes per UCS-2 character. Only the␊ |
* shortest encoding required to represent the significant UCS-2 bits␊ |
* is legal.␊ |
* ␊ |
*␊ |
* UTF-8 Multibyte Codes␊ |
*␊ |
* Bytes Bits UCS-2 Min UCS-2 Max UTF-8 Byte Sequence (binary)␊ |
|
* bufsize is the size of the output buffer in bytes␊ |
*/␊ |
void␊ |
utf_encodestr( const u_int16_t * ucsp, int ucslen,␊ |
u_int8_t * utf8p, u_int32_t bufsize, int byte_order )␊ |
utf_encodestr( const u_int16_t * ucsp, int ucslen, u_int8_t * utf8p, u_int32_t bufsize, int byte_order )␊ |
{␊ |
␉u_int8_t *bufend;␊ |
␉u_int16_t ucs_ch;␊ |
␊ |
␉bufend = utf8p + bufsize;␊ |
␊ |
␉while (ucslen-- > 0) {␊ |
␉while (ucslen-- > 0)␊ |
␉{␊ |
if (byte_order == OSBigEndian)␊ |
␉␉{␊ |
␉␉ ucs_ch = SWAP_BE16(*ucsp++);␊ |
else␊ |
}␊ |
␉␉else␊ |
␉␉{␊ |
ucs_ch = SWAP_LE16(*ucsp++);␊ |
␉␉}␊ |
␊ |
␉␉if (ucs_ch < 0x0080) {␊ |
␉␉if (ucs_ch < 0x0080)␊ |
␉␉{␊ |
␉␉␉if (utf8p >= bufend)␊ |
␉␉␉{␊ |
␉␉␉␉break;␊ |
␉␉␉}␊ |
␊ |
␉␉␉if (ucs_ch == '\0')␊ |
␉␉␉␉continue;␉/* skip over embedded NULLs */␊ |
␉␉␉{␊ |
␉␉␉␉continue;␉/* Skip over embedded NULLs */␊ |
␉␉␉}␊ |
␊ |
␉␉␉*utf8p++ = ucs_ch;␊ |
␊ |
␉␉} else if (ucs_ch < 0x800) {␊ |
␉␉}␊ |
␉␉else if (ucs_ch < 0x800)␊ |
␉␉{␊ |
␉␉␉if ((utf8p + 1) >= bufend)␊ |
␉␉␉{␊ |
␉␉␉␉break;␊ |
␉␉␉*utf8p++ = (ucs_ch >> 6) | 0xc0;␊ |
␉␉␉*utf8p++ = (ucs_ch & 0x3f) | 0x80;␊ |
␉␉␉}␊ |
␊ |
␉␉} else {␊ |
␉␉␉*utf8p++ = ((ucs_ch >> 6) | 0xc0);␊ |
␉␉␉*utf8p++ = ((ucs_ch & 0x3f) | 0x80);␊ |
␉␉}␊ |
␉␉else␊ |
␉␉{␊ |
␉␉␉if ((utf8p + 2) >= bufend)␊ |
␉␉␉{␊ |
␉␉␉␉break;␊ |
␉␉␉*utf8p++ = (ucs_ch >> 12) | 0xe0;␊ |
␉␉␉*utf8p++ = ((ucs_ch >> 6) & 0x3f) | 0x80;␊ |
␉␉␉*utf8p++ = ((ucs_ch) & 0x3f) | 0x80;␊ |
␉␉␉}␊ |
␊ |
␉␉␉*utf8p++ = ((ucs_ch >> 12) | 0xe0);␊ |
␉␉␉*utf8p++ = (((ucs_ch >> 6) & 0x3f) | 0x80);␊ |
␉␉␉*utf8p++ = ((ucs_ch & 0x3f) | 0x80);␊ |
␉␉}␊ |
␉}␊ |
␊ |
|
␉bufstart = ucsp;␊ |
␉bufend = (u_int16_t *)((u_int8_t *)ucsp + bufsize);␊ |
␊ |
␉while ((byte = *utf8p++) != '\0') {␊ |
␉while ((byte = *utf8p++) != '\0')␊ |
␉{␊ |
␉␉if (ucsp >= bufend)␊ |
␉␉{␊ |
␉␉␉break;␊ |
␉␉}␊ |
␊ |
␉␉/* check for ascii */␊ |
␉␉if (byte < 0x80) {␊ |
␉␉/* Check for ASCII */␊ |
␉␉if (byte < 0x80)␊ |
␉␉{␊ |
␉␉␉ucs_ch = byte;␊ |
␉␉␉␊ |
␊ |
if (byte_order == OSBigEndian)␊ |
␉␉ *ucsp++ = SWAP_BE16(ucs_ch);␊ |
else␊ |
*ucsp++ = SWAP_LE16(ucs_ch);␊ |
␉␉␉␊ |
␉␉␉{␊ |
␉␉␉␉*ucsp++ = SWAP_BE16(ucs_ch);␊ |
}␊ |
␉␉␉else␊ |
␉␉␉{␊ |
␉␉␉␉*ucsp++ = SWAP_LE16(ucs_ch);␊ |
␉␉␉}␊ |
␊ |
␉␉␉continue;␊ |
␉␉}␊ |
␊ |
␉␉switch (byte & 0xf0) {␊ |
␉␉/* 2 byte sequence*/␊ |
␉␉case 0xc0:␊ |
␉␉case 0xd0:␊ |
␉␉␉/* extract bits 6 - 10 from first byte */␊ |
␉␉␉ucs_ch = (byte & 0x1F) << 6; ␊ |
␉␉␉break;␊ |
␉␉/* 3 byte sequence*/␊ |
␉␉case 0xe0:␊ |
␉␉␉/* extract bits 12 - 15 from first byte */␊ |
␉␉␉ucs_ch = (byte & 0x0F) << 6;␊ |
␉␉switch (byte & 0xf0)␊ |
␉␉{␊ |
␉␉␉/* 2 byte sequence */␊ |
␉␉␉case 0xc0:␊ |
␉␉␉case 0xd0:␉/* Extract bits 6 - 10 from first byte */␊ |
␉␉␉␉␉␉ucs_ch = ((byte & 0x1F) << 6);␊ |
␉␉␉␉␉␉break;␊ |
␉␉␉/* 3 byte sequence */␊ |
␉␉␉case 0xe0:␊ |
␉␉␉␉␉␉/* Extract bits 12 - 15 from first byte */␊ |
␉␉␉␉␉␉ucs_ch = ((byte & 0x0F) << 6);␊ |
␊ |
␉␉␉/* extract bits 6 - 11 from second byte */␊ |
␉␉␉if (((byte = *utf8p++) & 0xc0) != 0x80)␊ |
␉␉␉␉goto stop;␊ |
␉␉␉␉␉␉/* Extract bits 6 - 11 from second byte */␊ |
␉␉␉␉␉␉if (((byte = *utf8p++) & 0xc0) != 0x80)␊ |
␉␉␉␉␉␉{␊ |
␉␉␉␉␉␉␉goto stop;␊ |
␉␉␉␉␉␉}␊ |
␊ |
␉␉␉ucs_ch += (byte & 0x3F);␊ |
␉␉␉ucs_ch <<= 6;␊ |
␉␉␉break;␊ |
␉␉default:␊ |
␉␉␉goto stop;␊ |
␉␉␉␉␉␉ucs_ch += (byte & 0x3F);␊ |
␉␉␉␉␉␉ucs_ch <<= 6;␊ |
␉␉␉␉␉␉break;␊ |
␉␉␉default:␊ |
␉␉␉␉␉␉goto stop;␊ |
␉␉}␊ |
␊ |
␉␉/* extract bits 0 - 5 from final byte */␊ |
␉␉/* Extract bits 0 - 5 from final byte */␊ |
␉␉if (((byte = *utf8p++) & 0xc0) != 0x80)␊ |
␉␉{␊ |
␉␉␉goto stop;␊ |
␉␉ucs_ch += (byte & 0x3F); ␊ |
␉␉}␊ |
␊ |
␉␉ucs_ch += (byte & 0x3F);␊ |
␊ |
if (byte_order == OSBigEndian)␊ |
*ucsp++ = SWAP_BE16(ucs_ch);␊ |
else␊ |
*ucsp++ = SWAP_LE16(ucs_ch);␊ |
␉␉{␊ |
␉␉␉*ucsp++ = SWAP_BE16(ucs_ch);␊ |
}␊ |
␉␉else␊ |
␉␉{␊ |
␉␉␉*ucsp++ = SWAP_LE16(ucs_ch);␊ |
␉␉}␊ |
␉}␊ |
stop:␊ |
if (byte_order == OSBigEndian)␊ |
*ucslen = SWAP_BE16(ucsp - bufstart);␊ |
else␊ |
*ucslen = SWAP_LE16(ucsp - bufstart);␊ |
␉if (byte_order == OSBigEndian)␊ |
␉{␊ |
␉␉*ucslen = SWAP_BE16(ucsp - bufstart);␊ |
␉}␊ |
␉else␊ |
␉{␊ |
␉␉*ucslen = SWAP_LE16(ucsp - bufstart);␊ |
␉}␊ |
}␊ |