mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-01-30 08:34:16 +01:00
Merge in unicode changes to read in utf-8 dictionary format
This commit is contained in:
parent
c010a73098
commit
3a1c2572dd
5 changed files with 150 additions and 123 deletions
|
@ -43,8 +43,8 @@ setBlankTile( DictionaryCtxt* dctx )
|
|||
dctx->blankTile = -1; /* no known blank */
|
||||
|
||||
for ( ii = 0; ii < dctx->nFaces; ++ii ) {
|
||||
const XP_UCHAR* facep = dctx->faceStarts[ii];
|
||||
if ( *facep == 0 ) {
|
||||
XP_U16 index = dctx->faceIndices[ii];
|
||||
if ( dctx->faces[index] == 0 ) {
|
||||
XP_ASSERT( dctx->blankTile == -1 ); /* only one passes test? */
|
||||
dctx->blankTile = (XP_S8)ii;
|
||||
#ifndef DEBUG
|
||||
|
@ -84,13 +84,9 @@ dict_getTileValue( const DictionaryCtxt* dict, Tile tile )
|
|||
const XP_UCHAR*
|
||||
dict_getTileString( const DictionaryCtxt* dict, Tile tile )
|
||||
{
|
||||
const XP_UCHAR* start;
|
||||
XP_ASSERT( tile < dict->nFaces );
|
||||
start = dict->faceStarts[tile];
|
||||
if ( IS_SPECIAL(*start) ) {
|
||||
start = dict->chars[(int)*start];
|
||||
}
|
||||
return start;
|
||||
XP_U16 index = dict->faceIndices[tile];
|
||||
return &dict->faces[index];
|
||||
}
|
||||
|
||||
XP_U16
|
||||
|
@ -111,21 +107,38 @@ dict_tilesToString( const DictionaryCtxt* ctxt, const Tile* tiles,
|
|||
XP_U16 nTiles, XP_UCHAR* buf, XP_U16 bufSize )
|
||||
{
|
||||
XP_UCHAR* bufp = buf;
|
||||
XP_UCHAR* end = bufp + bufSize;
|
||||
XP_U16 result = 0;
|
||||
|
||||
if ( bufp != NULL ) {
|
||||
XP_UCHAR* end = bufp + bufSize;
|
||||
while ( nTiles-- ) {
|
||||
Tile tile = *tiles++;
|
||||
const XP_UCHAR* facep = dict_getTileString( ctxt, tile );
|
||||
|
||||
if ( IS_SPECIAL(*facep) ) {
|
||||
XP_UCHAR* chars = ctxt->chars[(XP_U16)*facep];
|
||||
XP_U16 len = XP_STRLEN( chars );
|
||||
if ( bufp + len >= end ) {
|
||||
bufp = NULL;
|
||||
break;
|
||||
}
|
||||
XP_MEMCPY( bufp, chars, len );
|
||||
bufp += len;
|
||||
} else {
|
||||
XP_ASSERT ( tile != ctxt->blankTile ); /* printing blank should be
|
||||
handled by specials
|
||||
mechanism */
|
||||
if ( bufp + 1 >= end ) {
|
||||
bufp = NULL;
|
||||
break;
|
||||
}
|
||||
bufp += XP_SNPRINTF( bufp, end - bufp, XP_S, facep );
|
||||
}
|
||||
}
|
||||
|
||||
if ( bufp < end ) {
|
||||
if ( bufp != NULL && bufp < end ) {
|
||||
*bufp = '\0';
|
||||
result = bufp - buf;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} /* dict_tilesToString */
|
||||
|
||||
|
@ -176,8 +189,8 @@ dict_tilesAreSame( const DictionaryCtxt* dict1, const DictionaryCtxt* dict2 )
|
|||
break;
|
||||
}
|
||||
#else
|
||||
face1 = dict1->faceStarts[ii];
|
||||
face2 = dict2->faceStarts[ii];
|
||||
face1 = dict_getTileString( dict1, ii );
|
||||
face2 = dict_getTileString( dict2, ii );
|
||||
if ( IS_SPECIAL(*face1) != IS_SPECIAL(*face2) ) {
|
||||
break;
|
||||
}
|
||||
|
@ -203,13 +216,13 @@ dict_tilesAreSame( const DictionaryCtxt* dict1, const DictionaryCtxt* dict2 )
|
|||
|
||||
#ifndef XWFEATURE_STANDALONE_ONLY
|
||||
static void
|
||||
unsplitFaces( const DictionaryCtxt* dict, XP_UCHAR* buf, XP_U16* bufsizep )
|
||||
ucharsToNarrow( const DictionaryCtxt* dict, XP_UCHAR* buf, XP_U16* bufsizep )
|
||||
{
|
||||
XP_U16 ii;
|
||||
XP_U16 nUsed = 0;
|
||||
XP_U16 bufsize = *bufsizep;
|
||||
for ( ii = 0; ii < dict->nFaces; ++ii ) {
|
||||
const XP_UCHAR* facep = dict->faceStarts[ii];
|
||||
const XP_UCHAR* facep = dict_getTileString( dict, ii );
|
||||
if ( IS_SPECIAL(*facep) ) {
|
||||
buf[nUsed++] = *facep;
|
||||
} else {
|
||||
|
@ -217,8 +230,9 @@ unsplitFaces( const DictionaryCtxt* dict, XP_UCHAR* buf, XP_U16* bufsizep )
|
|||
}
|
||||
XP_ASSERT( nUsed < bufsize );
|
||||
}
|
||||
buf[nUsed] = 0;
|
||||
*bufsizep = nUsed;
|
||||
} /* unsplitFaces */
|
||||
}
|
||||
|
||||
void
|
||||
dict_writeToStream( const DictionaryCtxt* dict, XWStreamCtxt* stream )
|
||||
|
@ -227,11 +241,9 @@ dict_writeToStream( const DictionaryCtxt* dict, XWStreamCtxt* stream )
|
|||
XP_U16 maxValue = 0;
|
||||
XP_U16 ii, nSpecials;
|
||||
XP_U16 maxCountBits, maxValueBits;
|
||||
XP_UCHAR buf[64];
|
||||
XP_U16 nFaceBytes;
|
||||
|
||||
/* Need to keep format identical for non-utf so new versions can play
|
||||
against old using not UTF8 dicts. The old ones won't even recognize
|
||||
against old using non-UTF8 dicts. The old ones won't even recognize
|
||||
UTF8 dicts as dicts, so there shouldn't be any attempts to connect with
|
||||
them having one open. */
|
||||
stream_putBits( stream, 6, dict->nFaces );
|
||||
|
@ -261,16 +273,14 @@ dict_writeToStream( const DictionaryCtxt* dict, XWStreamCtxt* stream )
|
|||
stream_putBits( stream, maxValueBits, dict->countsAndValues[ii+1] );
|
||||
}
|
||||
|
||||
nFaceBytes = sizeof(buf);
|
||||
unsplitFaces( dict, buf, &nFaceBytes );
|
||||
if ( dict_isUTF8( dict ) ) {
|
||||
/* nBytes == nFaces for non-UTF8 dicts */
|
||||
stream_putU8( stream, nFaceBytes );
|
||||
}
|
||||
stream_putBytes( stream, buf, nFaceBytes );
|
||||
XP_UCHAR buf[64];
|
||||
XP_U16 nBytes = sizeof(buf);
|
||||
ucharsToNarrow( dict, buf, &nBytes );
|
||||
stream_putU8( stream, nBytes );
|
||||
stream_putBytes( stream, buf, nBytes );
|
||||
|
||||
for ( nSpecials = ii = 0; ii < dict->nFaces; ++ii ) {
|
||||
const XP_UCHAR* facep = dict->faceStarts[(Tile)ii];
|
||||
const XP_UCHAR* facep = dict_getTileString( dict, (Tile)ii );
|
||||
if ( IS_SPECIAL( *facep ) ) {
|
||||
stringToStream( stream, dict->chars[nSpecials++] );
|
||||
}
|
||||
|
@ -285,7 +295,7 @@ freeSpecials( DictionaryCtxt* dict )
|
|||
XP_U16 nSpecials;
|
||||
|
||||
for ( nSpecials = tt = 0; tt < dict->nFaces; ++tt ) {
|
||||
const XP_UCHAR* facep = dict->faceStarts[tt];
|
||||
const XP_UCHAR* facep = dict_getTileString( dict, tt );
|
||||
if ( IS_SPECIAL( *facep ) ) {
|
||||
|
||||
XP_ASSERT( !!dict->chars[nSpecials] );
|
||||
|
@ -314,7 +324,7 @@ common_destructor( DictionaryCtxt* dict )
|
|||
|
||||
XP_FREE( dict->mpool, dict->countsAndValues );
|
||||
XP_FREE( dict->mpool, dict->faces );
|
||||
XP_FREE( dict->mpool, dict->faceStarts );
|
||||
XP_FREE( dict->mpool, dict->faceIndices );
|
||||
|
||||
XP_FREE( dict->mpool, dict );
|
||||
} /* common_destructor */
|
||||
|
@ -323,13 +333,10 @@ common_destructor( DictionaryCtxt* dict )
|
|||
void
|
||||
dict_loadFromStream( DictionaryCtxt* dict, XWStreamCtxt* stream )
|
||||
{
|
||||
XP_U16 nFaceBytes, nFaces;
|
||||
XP_U8 nFaces, nFaceBytes;
|
||||
XP_U16 maxCountBits, maxValueBits;
|
||||
XP_U16 ii, nSpecials;
|
||||
XP_UCHAR* localTexts[32];
|
||||
XP_U16 streamVersion = stream_getVersion( stream );
|
||||
XP_Bool isUTF8 = streamVersion >= STREAM_VERS_UTF8;
|
||||
XP_U8 utf8[96];
|
||||
|
||||
XP_ASSERT( !dict->destructor );
|
||||
dict->destructor = common_destructor;
|
||||
|
@ -352,19 +359,14 @@ dict_loadFromStream( DictionaryCtxt* dict, XWStreamCtxt* stream )
|
|||
maxValueBits );
|
||||
}
|
||||
|
||||
if ( isUTF8 ) {
|
||||
nFaceBytes = stream_getU8( stream );
|
||||
} else {
|
||||
nFaceBytes = nFaces;
|
||||
}
|
||||
|
||||
XP_ASSERT( nFaceBytes < VSIZE(utf8) );
|
||||
nFaceBytes = (XP_U8)stream_getU8( stream );
|
||||
XP_U8 utf8[nFaceBytes];
|
||||
stream_getBytes( stream, utf8, nFaceBytes );
|
||||
dict->isUTF8 = isUTF8;
|
||||
dict->isUTF8 = XP_TRUE; /* need to communicate this in stream */
|
||||
dict_splitFaces( dict, utf8, nFaceBytes, nFaces );
|
||||
|
||||
for ( nSpecials = ii = 0; ii < nFaces; ++ii ) {
|
||||
const XP_UCHAR* facep = dict->faceStarts[ii];
|
||||
const XP_UCHAR* facep = dict_getTileString( dict, (Tile)ii );
|
||||
if ( IS_SPECIAL( *facep ) ) {
|
||||
XP_UCHAR* txt = stringFromStream( dict->mpool, stream );
|
||||
XP_ASSERT( !!txt );
|
||||
|
@ -383,7 +385,6 @@ dict_loadFromStream( DictionaryCtxt* dict, XWStreamCtxt* stream )
|
|||
nSpecials * sizeof(*dict->chars) );
|
||||
XP_MEMCPY(dict->chars, localTexts, nSpecials * sizeof(*dict->chars));
|
||||
}
|
||||
|
||||
setBlankTile( dict );
|
||||
} /* dict_loadFromStream */
|
||||
#endif
|
||||
|
@ -406,7 +407,7 @@ dict_isUTF8( const DictionaryCtxt* dict )
|
|||
XP_Bool
|
||||
dict_faceIsBitmap( const DictionaryCtxt* dict, Tile tile )
|
||||
{
|
||||
const XP_UCHAR* facep = dict->faceStarts[tile];
|
||||
const XP_UCHAR* facep = dict_getTileString( dict, tile );
|
||||
return IS_SPECIAL(*facep);
|
||||
} /* dict_faceIsBitmap */
|
||||
|
||||
|
@ -414,7 +415,7 @@ void
|
|||
dict_getFaceBitmaps( const DictionaryCtxt* dict, Tile tile, XP_Bitmaps* bmps )
|
||||
{
|
||||
SpecialBitmaps* bitmaps;
|
||||
const XP_UCHAR* facep = dict->faceStarts[tile];
|
||||
const XP_UCHAR* facep = dict_getTileString( dict, tile );
|
||||
|
||||
XP_ASSERT( dict_faceIsBitmap( dict, tile ) );
|
||||
XP_ASSERT( !!dict->bitmaps );
|
||||
|
|
|
@ -73,7 +73,7 @@ struct DictionaryCtxt {
|
|||
necessarily the entry point for search!! */
|
||||
XP_UCHAR* name;
|
||||
XP_UCHAR* faces;
|
||||
XP_UCHAR** faceStarts;
|
||||
XP_U16* faceIndices;
|
||||
XP_U8* countsAndValues;
|
||||
|
||||
SpecialBitmaps* bitmaps;
|
||||
|
|
|
@ -84,7 +84,7 @@ countSpecials( LinuxDictionaryCtxt* ctxt )
|
|||
XP_U16 ii;
|
||||
|
||||
for ( ii = 0; ii < ctxt->super.nFaces; ++ii ) {
|
||||
if ( IS_SPECIAL(ctxt->super.faceStarts[ii][0] ) ) {
|
||||
if ( IS_SPECIAL(ctxt->super.faces[ctxt->super.faceIndices[ii]] ) ) {
|
||||
++result;
|
||||
}
|
||||
}
|
||||
|
@ -133,21 +133,23 @@ skipBitmaps( LinuxDictionaryCtxt* ctxt, FILE* dictF )
|
|||
nSpecials * sizeof(*texts) );
|
||||
bitmaps = (SpecialBitmaps*)XP_MALLOC( ctxt->super.mpool,
|
||||
nSpecials * sizeof(*bitmaps) );
|
||||
XP_MEMSET( bitmaps, 0, nSpecials * sizeof(*bitmaps) );
|
||||
|
||||
for ( tile = 0; tile < ctxt->super.nFaces; ++tile ) {
|
||||
|
||||
XP_UCHAR* facep = ctxt->super.faceStarts[(short)tile];
|
||||
XP_UCHAR* facep
|
||||
= &ctxt->super.faces[ctxt->super.faceIndices[(short)tile]];
|
||||
if ( IS_SPECIAL(*facep) ) {
|
||||
XP_U16 asIndex = (XP_U16)*facep;
|
||||
XP_U8 txtlen;
|
||||
XP_ASSERT( asIndex < nSpecials );
|
||||
XP_ASSERT( *facep < nSpecials );
|
||||
|
||||
/* get the string */
|
||||
if ( 1 == fread( &txtlen, sizeof(txtlen), 1, dictF ) ) {
|
||||
text = (XP_UCHAR*)XP_MALLOC(ctxt->super.mpool, txtlen+1);
|
||||
if ( 1 == fread( text, txtlen, 1, dictF ) ) {
|
||||
text[txtlen] = '\0';
|
||||
texts[asIndex] = text;
|
||||
texts[(XP_U16)*facep] = text;
|
||||
|
||||
XP_DEBUGF( "skipping bitmaps for " XP_S, texts[asIndex] );
|
||||
|
||||
|
@ -162,29 +164,19 @@ skipBitmaps( LinuxDictionaryCtxt* ctxt, FILE* dictF )
|
|||
ctxt->super.bitmaps = bitmaps;
|
||||
} /* skipBitmaps */
|
||||
|
||||
static void
|
||||
stripZeros( XP_U8* bytes, XP_U16 nFaces )
|
||||
{
|
||||
XP_U16 ii;
|
||||
for ( ii = 0; ii < nFaces; ++ii ) {
|
||||
bytes[ii] = bytes[1+(ii*2)];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dict_splitFaces( DictionaryCtxt* dict, const XP_U8* utf8,
|
||||
XP_U16 nBytes, XP_U16 nFaces )
|
||||
{
|
||||
XP_U16 facesLen = dict->isUTF8? nBytes + nFaces : nFaces * 2;
|
||||
XP_UCHAR* faces = XP_MALLOC( dict->mpool, facesLen );
|
||||
XP_UCHAR** starts = XP_MALLOC( dict->mpool, nFaces * sizeof(starts[0]));
|
||||
XP_UCHAR* faces = XP_MALLOC( dict->mpool, nBytes + nFaces );
|
||||
XP_U16* indices = XP_MALLOC( dict->mpool, nFaces * sizeof(indices[0]));
|
||||
XP_U16 ii;
|
||||
XP_Bool isUTF8 = dict->isUTF8;
|
||||
XP_UCHAR* next = faces;
|
||||
const gchar* bytes = (const gchar*)utf8;
|
||||
|
||||
for ( ii = 0; ii < nFaces; ++ii ) {
|
||||
starts[ii] = next;
|
||||
indices[ii] = next - faces;
|
||||
if ( isUTF8 ) {
|
||||
gchar* cp = g_utf8_offset_to_pointer( bytes, 1 );
|
||||
XP_U16 len = cp - bytes;
|
||||
|
@ -192,15 +184,17 @@ dict_splitFaces( DictionaryCtxt* dict, const XP_U8* utf8,
|
|||
next += len;
|
||||
bytes += len;
|
||||
} else {
|
||||
XP_ASSERT( 0 == *bytes );
|
||||
++bytes; /* skip empty */
|
||||
*next++ = *bytes++;
|
||||
}
|
||||
XP_ASSERT( next < faces + nFaces + nBytes );
|
||||
*next++ = '\0';
|
||||
}
|
||||
XP_ASSERT( next == faces + facesLen );
|
||||
XP_ASSERT( !dict->faces );
|
||||
dict->faces = faces;
|
||||
XP_ASSERT( !dict->faceStarts );
|
||||
dict->faceStarts = starts;
|
||||
XP_ASSERT( !dict->faceIndices );
|
||||
dict->faceIndices = indices;
|
||||
} /* dict_splitFaces */
|
||||
|
||||
static XP_Bool
|
||||
|
@ -213,6 +207,7 @@ initFromDictFile( LinuxDictionaryCtxt* dctx, const char* fileName )
|
|||
FILE* dictF = fopen( fileName, "r" );
|
||||
unsigned short xloc;
|
||||
XP_U16 flags;
|
||||
XP_U16 facesSize;
|
||||
XP_U16 charSize;
|
||||
XP_Bool isUTF8 = XP_FALSE;
|
||||
|
||||
|
@ -272,16 +267,16 @@ initFromDictFile( LinuxDictionaryCtxt* dctx, const char* fileName )
|
|||
|
||||
dctx->super.countsAndValues = XP_MALLOC( dctx->super.mpool,
|
||||
numFaces*2 );
|
||||
facesSize = numFaceBytes;
|
||||
if ( !isUTF8 ) {
|
||||
facesSize /= 2;
|
||||
}
|
||||
|
||||
XP_U8 tmp[numFaceBytes];
|
||||
if ( 1 != fread( tmp, numFaceBytes, 1, dictF ) ) {
|
||||
goto closeAndExit;
|
||||
}
|
||||
|
||||
if ( !isUTF8 ) {
|
||||
stripZeros( tmp, numFaces );
|
||||
numFaceBytes = numFaces;
|
||||
}
|
||||
dict_splitFaces( &dctx->super, tmp, numFaceBytes, numFaces );
|
||||
|
||||
if ( (1 != fread( &xloc, 2, 1, dictF ) )/* read in (dump) the xloc
|
||||
|
@ -351,7 +346,7 @@ freeSpecials( LinuxDictionaryCtxt* ctxt )
|
|||
XP_U16 ii;
|
||||
|
||||
for ( ii = 0; ii < ctxt->super.nFaces; ++ii ) {
|
||||
if ( IS_SPECIAL(ctxt->super.faceStarts[ii][0] ) ) {
|
||||
if ( IS_SPECIAL(ctxt->super.faces[ctxt->super.faceIndices[ii]] ) ) {
|
||||
if ( !!ctxt->super.bitmaps ) {
|
||||
XP_Bitmap* bmp = ctxt->super.bitmaps[nSpecials].largeBM;
|
||||
if ( !!bmp ) {
|
||||
|
@ -389,7 +384,7 @@ linux_dictionary_destroy( DictionaryCtxt* dict )
|
|||
|
||||
XP_FREE( dict->mpool, ctxt->super.countsAndValues );
|
||||
XP_FREE( dict->mpool, ctxt->super.faces );
|
||||
XP_FREE( dict->mpool, ctxt->super.faceStarts );
|
||||
XP_FREE( dict->mpool, ctxt->super.faceIndices );
|
||||
XP_FREE( dict->mpool, ctxt->super.name );
|
||||
XP_FREE( dict->mpool, ctxt );
|
||||
} /* linux_dictionary_destroy */
|
||||
|
@ -398,7 +393,7 @@ static const XP_UCHAR*
|
|||
linux_dict_getShortName( const DictionaryCtxt* dict )
|
||||
{
|
||||
const XP_UCHAR* full = dict_getName( dict );
|
||||
const char* c = strrchr( full, '/' );
|
||||
const XP_UCHAR* c = strchr( full, '/' );
|
||||
if ( !!c ) {
|
||||
++c;
|
||||
} else {
|
||||
|
|
|
@ -57,24 +57,31 @@ static XP_Bool findAlternateDict( CEAppGlobals* globals, wchar_t* dictName );
|
|||
#define ALIGN_COUNT 2
|
||||
|
||||
DictionaryCtxt*
|
||||
ce_dictionary_make( CEAppGlobals* globals, XP_UCHAR* dictName )
|
||||
ce_dictionary_make( CEAppGlobals* globals, const char* dictName )
|
||||
{
|
||||
CEDictionaryCtxt* ctxt = (CEDictionaryCtxt*)NULL;
|
||||
HANDLE mappedFile = NULL;
|
||||
|
||||
wchar_t nameBuf[MAX_PATH+1];
|
||||
HANDLE hFile;
|
||||
XP_U8* ptr;
|
||||
XP_U8* ptr = NULL;
|
||||
XP_U32 dictLength;
|
||||
XP_UCHAR buf[CE_MAX_PATH_LEN+1]; /* in case we have to look */
|
||||
UINT codePages[] = { CP_ACP, CP_UTF8 };
|
||||
XP_U16 ii;
|
||||
|
||||
XP_ASSERT( !!dictName );
|
||||
|
||||
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, dictName, -1,
|
||||
nameBuf, VSIZE(nameBuf) );
|
||||
|
||||
/* Try both old-iso and UTF-8 to convert file name */
|
||||
for ( ii = 0; ii < VSIZE(codePages); ++ii ) {
|
||||
if ( 0 != MultiByteToWideChar( codePages[ii], 0, dictName, -1,
|
||||
nameBuf, VSIZE(nameBuf) ) ) {
|
||||
ptr = openMappedFile( MPPARM(globals->mpool) nameBuf, &mappedFile,
|
||||
&hFile, &dictLength );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !ptr ) {
|
||||
if ( findAlternateDict( globals, nameBuf ) ) {
|
||||
(void)WideCharToMultiByte( CP_ACP, 0, nameBuf, -1,
|
||||
|
@ -98,6 +105,7 @@ ce_dictionary_make( CEAppGlobals* globals, XP_UCHAR* dictName )
|
|||
|
||||
flags = n_ptr_tohs( &ptr );
|
||||
|
||||
#ifdef NODE_CAN_4
|
||||
if ( flags == 0x0002 ) {
|
||||
nodeSize = 3;
|
||||
} else if ( flags == 0x0003 ) {
|
||||
|
@ -111,7 +119,11 @@ ce_dictionary_make( CEAppGlobals* globals, XP_UCHAR* dictName )
|
|||
} else {
|
||||
break; /* we want to return NULL */
|
||||
}
|
||||
|
||||
#else
|
||||
if( flags != 0x0001 ) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if ( isUTF8 ) {
|
||||
numFaceBytes = (XP_U16)(*ptr++);
|
||||
}
|
||||
|
@ -128,6 +140,10 @@ ce_dictionary_make( CEAppGlobals* globals, XP_UCHAR* dictName )
|
|||
ctxt->super.destructor = ce_dict_destroy;
|
||||
ctxt->super.func_dict_getShortName = ce_dict_getShortName;
|
||||
|
||||
if ( !isUTF8 ) {
|
||||
numFaceBytes = numFaces * 2;
|
||||
}
|
||||
|
||||
ctxt->super.nFaces = (XP_U8)numFaces;
|
||||
ctxt->super.isUTF8 = isUTF8;
|
||||
|
||||
|
@ -135,14 +151,23 @@ ce_dictionary_make( CEAppGlobals* globals, XP_UCHAR* dictName )
|
|||
dict_splitFaces( &ctxt->super, ptr, numFaceBytes, numFaces );
|
||||
ptr += numFaceBytes;
|
||||
} else {
|
||||
XP_U8 buf[numFaces * 2];
|
||||
XP_U8 tmp[numFaces*4]; /* should be enough... */
|
||||
XP_U16 nBytes = 0;
|
||||
XP_U16 ii;
|
||||
XP_MEMCPY( buf, ptr, sizeof(buf) );
|
||||
ptr += sizeof(buf);
|
||||
/* Need to translate from iso-8859-n to utf8 */
|
||||
for ( ii = 0; ii < numFaces; ++ii ) {
|
||||
buf[ii] = buf[1+(ii*2)];
|
||||
XP_UCHAR ch = ptr[1];
|
||||
wchar_t wch;
|
||||
|
||||
ptr += 2;
|
||||
MultiByteToWideChar( CP_ACP, 0, &ch, 1, &wch, 1 );
|
||||
XP_UCHAR utfs[8];
|
||||
int len = WideCharToMultiByte( CP_UTF8, 0, &wch, 1,
|
||||
utfs, VSIZE(utfs), NULL, NULL );
|
||||
XP_MEMCPY( &tmp[nBytes], utfs, len );
|
||||
nBytes += len;
|
||||
}
|
||||
dict_splitFaces( &ctxt->super, buf, numFaces, numFaces );
|
||||
dict_splitFaces( &ctxt->super, tmp, nBytes, numFaces );
|
||||
}
|
||||
|
||||
ctxt->super.is_4_byte = (ctxt->super.nodeSize == 4);
|
||||
|
@ -211,24 +236,26 @@ ce_dictionary_make_empty( CEAppGlobals* XP_UNUSED_DBG(globals) )
|
|||
} /* ce_dictionary_make_empty */
|
||||
|
||||
void
|
||||
dict_splitFaces( DictionaryCtxt* dict, const XP_U8* inBuf,
|
||||
dict_splitFaces( DictionaryCtxt* dict, const XP_U8* utf8,
|
||||
XP_U16 nBytes, XP_U16 nFaces )
|
||||
{
|
||||
XP_UCHAR* faces = XP_MALLOC( dict->mpool, nBytes + nFaces );
|
||||
XP_UCHAR** starts = XP_MALLOC( dict->mpool, nFaces * sizeof(starts[0]));
|
||||
XP_U16* indices = XP_MALLOC( dict->mpool, nFaces * sizeof(indices[0]));
|
||||
XP_U16 ii;
|
||||
XP_UCHAR* next = faces;
|
||||
wchar_t widebuf[nFaces];
|
||||
UINT codePage = dict->isUTF8? CP_UTF8 : CP_ACP;
|
||||
|
||||
int nRead = MultiByteToWideChar( codePage, 0, (char*)inBuf, nBytes,
|
||||
wchar_t widebuf[nFaces];
|
||||
int nRead = MultiByteToWideChar( CP_UTF8, 0, (char*)utf8, nBytes,
|
||||
widebuf, VSIZE(widebuf) );
|
||||
if ( 0 == nRead ) {
|
||||
logLastError( "MultiByteToWideChar" );
|
||||
}
|
||||
XP_ASSERT( nRead == nFaces );
|
||||
|
||||
/* now split */
|
||||
for ( ii = 0; ii < nFaces; ++ii ) {
|
||||
starts[ii] = next;
|
||||
int nWritten = WideCharToMultiByte( codePage, 0, &widebuf[ii], 1,
|
||||
indices[ii] = next - faces;
|
||||
int nWritten = WideCharToMultiByte( CP_UTF8, 0, &widebuf[ii], 1,
|
||||
next, 100, NULL, NULL );
|
||||
next += nWritten;
|
||||
*next++ = 0;
|
||||
|
@ -237,8 +264,8 @@ dict_splitFaces( DictionaryCtxt* dict, const XP_U8* inBuf,
|
|||
XP_ASSERT( next == faces + nFaces + nBytes );
|
||||
XP_ASSERT( !dict->faces );
|
||||
dict->faces = faces;
|
||||
XP_ASSERT( !dict->faceStarts );
|
||||
dict->faceStarts = starts;
|
||||
XP_ASSERT( !dict->faceIndices );
|
||||
dict->faceIndices = indices;
|
||||
} /* dict_splitFaces */
|
||||
|
||||
static void
|
||||
|
@ -257,7 +284,7 @@ ceLoadSpecialData( CEDictionaryCtxt* ctxt, XP_U8** ptrp )
|
|||
|
||||
for ( ii = 0; ii < ctxt->super.nFaces; ++ii ) {
|
||||
|
||||
XP_UCHAR* facep = ctxt->super.faceStarts[(int)ii];
|
||||
XP_UCHAR* facep = &ctxt->super.faces[ctxt->super.faceIndices[(short)ii]];
|
||||
if ( IS_SPECIAL(*facep) ) {
|
||||
/* get the string */
|
||||
XP_U8 txtlen = *ptr++;
|
||||
|
@ -286,7 +313,8 @@ ceCountSpecials( CEDictionaryCtxt* ctxt )
|
|||
XP_U16 ii;
|
||||
|
||||
for ( ii = 0; ii < ctxt->super.nFaces; ++ii ) {
|
||||
if ( IS_SPECIAL( ctxt->super.faceStarts[ii][0] ) ) {
|
||||
XP_U16 index = ctxt->super.faceIndices[ii];
|
||||
if ( IS_SPECIAL( ctxt->super.faces[index] ) ) {
|
||||
++result;
|
||||
}
|
||||
}
|
||||
|
@ -452,7 +480,7 @@ ce_dict_destroy( DictionaryCtxt* dict )
|
|||
}
|
||||
|
||||
XP_FREE( ctxt->super.mpool, ctxt->super.faces );
|
||||
XP_FREE( ctxt->super.mpool, ctxt->super.faceStarts );
|
||||
XP_FREE( ctxt->super.mpool, ctxt->super.faceIndices );
|
||||
XP_FREE( ctxt->super.mpool, ctxt->super.countsAndValues );
|
||||
XP_FREE( ctxt->super.mpool, ctxt->super.name );
|
||||
|
||||
|
@ -580,7 +608,7 @@ checkIfDictAndLegal( MPFORMAL wchar_t* path, XP_U16 pathLen,
|
|||
{
|
||||
char narrowName[CE_MAX_PATH_LEN+1];
|
||||
int len = wcslen( pathBuf );
|
||||
len = WideCharToMultiByte( CP_ACP, 0, pathBuf, len + 1,
|
||||
len = WideCharToMultiByte( CP_UTF8, 0, pathBuf, len + 1,
|
||||
narrowName, len + 1, NULL, NULL );
|
||||
}
|
||||
#endif
|
||||
|
@ -592,8 +620,12 @@ checkIfDictAndLegal( MPFORMAL wchar_t* path, XP_U16 pathLen,
|
|||
|
||||
flags = n_ptr_tohs( &ptr );
|
||||
closeMappedFile( MPPARM(mpool) base, mappedFile );
|
||||
#ifdef NODE_CAN_4
|
||||
/* are the flags what we expect */
|
||||
result = flags >= 0x0002 && flags <= 0x0005;
|
||||
#else
|
||||
result = flags == 0x0001;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -787,23 +819,22 @@ bname( const XP_UCHAR* in )
|
|||
wchar_t*
|
||||
wbname( wchar_t* buf, XP_U16 buflen, const wchar_t* in )
|
||||
{
|
||||
wchar_t* result;
|
||||
|
||||
_snwprintf( buf, buflen, L"%s", in );
|
||||
result = buf + wcslen( buf ) - 1;
|
||||
|
||||
/* wipe out extension */
|
||||
while ( *result != L'.' ) {
|
||||
--result;
|
||||
XP_ASSERT( result > buf );
|
||||
}
|
||||
*result = 0;
|
||||
|
||||
while ( result >= buf && *result != L'\\' ) {
|
||||
--result;
|
||||
const wchar_t* slash = wcsrchr( in, L'\\' );
|
||||
if ( !!slash ) {
|
||||
++slash;
|
||||
} else {
|
||||
slash = in;
|
||||
}
|
||||
|
||||
return result + 1;
|
||||
const wchar_t* dot = wcsrchr( slash, L'.' );
|
||||
if ( !dot ) {
|
||||
dot = slash + wcslen( slash );
|
||||
}
|
||||
|
||||
_snwprintf( buf, buflen, L"%s", slash );
|
||||
XP_ASSERT( dot >= slash );
|
||||
buf[dot-slash] = 0;
|
||||
return buf;
|
||||
} /* wbname */
|
||||
|
||||
#endif /* ifndef STUBBED_DICT */
|
||||
|
|
|
@ -30,7 +30,7 @@ typedef struct CEBitmapInfo {
|
|||
XP_U16 nRows;
|
||||
} CEBitmapInfo;
|
||||
|
||||
DictionaryCtxt* ce_dictionary_make(CEAppGlobals* globals, XP_UCHAR* name);
|
||||
DictionaryCtxt* ce_dictionary_make(CEAppGlobals* globals, const char* name);
|
||||
DictionaryCtxt* ce_dictionary_make_empty( CEAppGlobals* globals );
|
||||
|
||||
/* Callback: return true if done; false to continue */
|
||||
|
|
Loading…
Add table
Reference in a new issue