mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-06 20:45:54 +01:00
Refactor ce_dictionary_make so that it returns NULL rather than an
broken dict when the file's missing or corrupt.
This commit is contained in:
parent
acd3bdf24b
commit
8fb0b4685a
2 changed files with 116 additions and 97 deletions
|
@ -51,120 +51,138 @@ ce_dictionary_make( CEAppGlobals* globals, XP_UCHAR* dictName )
|
||||||
CEDictionaryCtxt* ctxt = (CEDictionaryCtxt*)NULL;
|
CEDictionaryCtxt* ctxt = (CEDictionaryCtxt*)NULL;
|
||||||
HANDLE mappedFile = NULL;
|
HANDLE mappedFile = NULL;
|
||||||
|
|
||||||
ctxt = (CEDictionaryCtxt*)XP_MALLOC(globals->mpool, sizeof(*ctxt));
|
wchar_t nameBuf[MAX_PATH+1];
|
||||||
XP_MEMSET( ctxt, 0, sizeof(*ctxt) );
|
HANDLE hFile;
|
||||||
|
XP_U8* ptr;
|
||||||
|
HANDLE mappedFile;
|
||||||
|
|
||||||
dict_super_init( (DictionaryCtxt*)ctxt );
|
XP_ASSERT( !!dictName );
|
||||||
MPASSIGN( ctxt->super.mpool, globals->mpool );
|
XP_DEBUGF( "looking for dict %s", dictName );
|
||||||
|
|
||||||
if ( !!dictName ) {
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, dictName, -1,
|
||||||
wchar_t nameBuf[MAX_PATH+1];
|
nameBuf, sizeof(nameBuf)/sizeof(nameBuf[0]) );
|
||||||
HANDLE hFile;
|
|
||||||
XP_U8* ptr;
|
ptr = openMappedFile( nameBuf, &mappedFile, &hFile );
|
||||||
|
|
||||||
|
while( !!ptr ) { /* lets us break.... */
|
||||||
|
XP_U32 offset;
|
||||||
|
XP_U16 numFaces;
|
||||||
|
XP_U16 i;
|
||||||
|
XP_U16 flags;
|
||||||
|
XP_U32 dictLength;
|
||||||
|
void* mappedBase = (void*)ptr;
|
||||||
|
XP_U8 nodeSize;
|
||||||
|
|
||||||
|
flags = n_ptr_tohs( &ptr );
|
||||||
|
XP_DEBUGF( "ce_dictionary_make: flags=0x%x", flags );
|
||||||
|
|
||||||
|
#ifdef NODE_CAN_4
|
||||||
|
if ( flags == 0x0002 ) {
|
||||||
|
nodeSize = 3;
|
||||||
|
} else if ( flags == 0x0003 ) {
|
||||||
|
nodeSize = 4;
|
||||||
|
} else {
|
||||||
|
break; /* we want to return NULL */
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if( flags != 0x0001 ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
ctxt = (CEDictionaryCtxt*)ce_dictionary_make_empty( globals );
|
||||||
|
|
||||||
|
ctxt->super.nodeSize = nodeSize;
|
||||||
|
|
||||||
ctxt->super.destructor = ce_dict_destroy;
|
ctxt->super.destructor = ce_dict_destroy;
|
||||||
ctxt->super.func_dict_getShortName = ce_dict_getShortName;
|
ctxt->super.func_dict_getShortName = ce_dict_getShortName;
|
||||||
|
|
||||||
XP_DEBUGF( "looking for dict %s", dictName );
|
ctxt->mappedBase = mappedBase;
|
||||||
|
XP_DEBUGF( "ptr starting at 0x%lx", ptr );
|
||||||
|
|
||||||
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, dictName, -1,
|
numFaces = (XP_U16)(*ptr++);
|
||||||
nameBuf, sizeof(nameBuf)/sizeof(nameBuf[0]) );
|
ctxt->super.nFaces = (XP_U8)numFaces;
|
||||||
|
XP_DEBUGF( "read %d faces from dict", (short)numFaces );
|
||||||
ptr = openMappedFile( nameBuf, &ctxt->mappedFile, &hFile );
|
ctxt->super.faces16 =
|
||||||
|
XP_MALLOC( globals->mpool,
|
||||||
if ( !!ptr ) {
|
numFaces * sizeof(ctxt->super.faces16[0]) );
|
||||||
XP_U32 offset;
|
|
||||||
XP_U16 numFaces;
|
|
||||||
XP_U16 i;
|
|
||||||
XP_U16 flags;
|
|
||||||
XP_U32 dictLength;
|
|
||||||
|
|
||||||
ctxt->mappedBase = (void*)ptr;
|
|
||||||
XP_DEBUGF( "ptr starting at 0x%lx", ptr );
|
|
||||||
|
|
||||||
flags = n_ptr_tohs( &ptr );
|
|
||||||
XP_DEBUGF( "ce_dictionary_make: flags=0x%x", flags );
|
|
||||||
|
|
||||||
numFaces = (XP_U16)(*ptr++);
|
|
||||||
ctxt->super.nFaces = (XP_U8)numFaces;
|
|
||||||
XP_DEBUGF( "read %d faces from dict", (short)numFaces );
|
|
||||||
ctxt->super.faces16 =
|
|
||||||
XP_MALLOC( globals->mpool,
|
|
||||||
numFaces * sizeof(ctxt->super.faces16[0]) );
|
|
||||||
|
|
||||||
#ifdef NODE_CAN_4
|
#ifdef NODE_CAN_4
|
||||||
if ( flags == 0x0002 ) {
|
ctxt->super.is_4_byte = (ctxt->super.nodeSize == 4);
|
||||||
ctxt->super.nodeSize = 3;
|
|
||||||
} else if ( flags == 0x0003 ) {
|
|
||||||
ctxt->super.nodeSize = 4;
|
|
||||||
} else {
|
|
||||||
XP_ASSERT( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
ctxt->super.is_4_byte = ctxt->super.nodeSize == 4;
|
for ( i = 0; i < numFaces; ++i ) {
|
||||||
|
ctxt->super.faces16[i] = n_ptr_tohs(&ptr);
|
||||||
for ( i = 0; i < numFaces; ++i ) {
|
|
||||||
ctxt->super.faces16[i] = n_ptr_tohs(&ptr);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
XP_ASSERT( flags == 0x0001 );
|
|
||||||
for ( i = 0; i < numFaces; ++i ) {
|
|
||||||
ctxt->super.faces16[i] = (XP_CHAR16)*ptr++;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ctxt->super.countsAndValues =
|
|
||||||
(XP_U8*)XP_MALLOC(globals->mpool, numFaces*2);
|
|
||||||
|
|
||||||
ptr += 2; /* skip xloc header */
|
|
||||||
XP_DEBUGF( "pre values: ptr now 0x%lx", ptr );
|
|
||||||
for ( i = 0; i < numFaces*2; i += 2 ) {
|
|
||||||
ctxt->super.countsAndValues[i] = *ptr++;
|
|
||||||
ctxt->super.countsAndValues[i+1] = *ptr++;
|
|
||||||
}
|
|
||||||
XP_DEBUGF( "post values: ptr now 0x%lx", ptr );
|
|
||||||
|
|
||||||
ceLoadSpecialData( ctxt, &ptr );
|
|
||||||
|
|
||||||
dictLength = GetFileSize( hFile, NULL );
|
|
||||||
dictLength -= ptr - (XP_U8*)ctxt->mappedBase;
|
|
||||||
if ( dictLength > sizeof(XP_U32) ) {
|
|
||||||
offset = n_ptr_tohl( &ptr );
|
|
||||||
dictLength -= sizeof(offset);
|
|
||||||
#ifdef NODE_CAN_4
|
|
||||||
XP_ASSERT( dictLength % ctxt->super.nodeSize == 0 );
|
|
||||||
# ifdef DEBUG
|
|
||||||
ctxt->super.numEdges = dictLength / ctxt->super.nodeSize;
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
XP_ASSERT( dictLength % 3 == 0 );
|
|
||||||
# ifdef DEBUG
|
|
||||||
ctxt->super.numEdges = dictLength / 3;
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( dictLength > 0 ) {
|
|
||||||
XP_DEBUGF( "setting topEdge; offset = %ld", offset );
|
|
||||||
ctxt->super.base = (array_edge*)ptr;
|
|
||||||
#ifdef NODE_CAN_4
|
|
||||||
ctxt->super.topEdge = ctxt->super.base
|
|
||||||
+ (offset * ctxt->super.nodeSize);
|
|
||||||
#else
|
|
||||||
ctxt->super.topEdge = ctxt->super.base + (offset * 3);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
ctxt->super.topEdge = (array_edge*)NULL;
|
|
||||||
ctxt->super.base = (array_edge*)NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
for ( i = 0; i < numFaces; ++i ) {
|
||||||
|
ctxt->super.faces16[i] = (XP_CHAR16)*ptr++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ctxt->super.countsAndValues =
|
||||||
|
(XP_U8*)XP_MALLOC(globals->mpool, numFaces*2);
|
||||||
|
|
||||||
|
ptr += 2; /* skip xloc header */
|
||||||
|
XP_DEBUGF( "pre values: ptr now 0x%lx", ptr );
|
||||||
|
for ( i = 0; i < numFaces*2; i += 2 ) {
|
||||||
|
ctxt->super.countsAndValues[i] = *ptr++;
|
||||||
|
ctxt->super.countsAndValues[i+1] = *ptr++;
|
||||||
|
}
|
||||||
|
XP_DEBUGF( "post values: ptr now 0x%lx", ptr );
|
||||||
|
|
||||||
|
ceLoadSpecialData( ctxt, &ptr );
|
||||||
|
|
||||||
|
dictLength = GetFileSize( hFile, NULL );
|
||||||
|
dictLength -= ptr - (XP_U8*)ctxt->mappedBase;
|
||||||
|
if ( dictLength > sizeof(XP_U32) ) {
|
||||||
|
offset = n_ptr_tohl( &ptr );
|
||||||
|
dictLength -= sizeof(offset);
|
||||||
|
#ifdef NODE_CAN_4
|
||||||
|
XP_ASSERT( dictLength % ctxt->super.nodeSize == 0 );
|
||||||
|
# ifdef DEBUG
|
||||||
|
ctxt->super.numEdges = dictLength / ctxt->super.nodeSize;
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
XP_ASSERT( dictLength % 3 == 0 );
|
||||||
|
# ifdef DEBUG
|
||||||
|
ctxt->super.numEdges = dictLength / 3;
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( dictLength > 0 ) {
|
||||||
|
XP_DEBUGF( "setting topEdge; offset = %ld", offset );
|
||||||
|
ctxt->super.base = (array_edge*)ptr;
|
||||||
|
#ifdef NODE_CAN_4
|
||||||
|
ctxt->super.topEdge = ctxt->super.base
|
||||||
|
+ (offset * ctxt->super.nodeSize);
|
||||||
|
#else
|
||||||
|
ctxt->super.topEdge = ctxt->super.base + (offset * 3);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
ctxt->super.topEdge = (array_edge*)NULL;
|
||||||
|
ctxt->super.base = (array_edge*)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
setBlankTile( (DictionaryCtxt*)ctxt );
|
setBlankTile( (DictionaryCtxt*)ctxt );
|
||||||
|
|
||||||
ctxt->super.name = copyString(MPPARM(globals->mpool) dictName);
|
ctxt->super.name = copyString(MPPARM(globals->mpool) dictName);
|
||||||
|
break; /* exit phony while loop */
|
||||||
}
|
}
|
||||||
return (DictionaryCtxt*)ctxt;
|
return (DictionaryCtxt*)ctxt;
|
||||||
} /* ce_dictionary_make */
|
} /* ce_dictionary_make */
|
||||||
|
|
||||||
|
DictionaryCtxt*
|
||||||
|
ce_dictionary_make_empty( CEAppGlobals* globals )
|
||||||
|
{
|
||||||
|
CEDictionaryCtxt* ctxt = (CEDictionaryCtxt*)XP_MALLOC(globals->mpool,
|
||||||
|
sizeof(*ctxt));
|
||||||
|
XP_MEMSET( ctxt, 0, sizeof(*ctxt) );
|
||||||
|
|
||||||
|
dict_super_init( (DictionaryCtxt*)ctxt );
|
||||||
|
MPASSIGN( ctxt->super.mpool, globals->mpool );
|
||||||
|
return (DictionaryCtxt*)ctxt;
|
||||||
|
} /* ce_dictionary_make_empty */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ceLoadSpecialData( CEDictionaryCtxt* ctxt, XP_U8** ptrp )
|
ceLoadSpecialData( CEDictionaryCtxt* ctxt, XP_U8** ptrp )
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,6 +29,7 @@ typedef struct CEBitmapInfo {
|
||||||
} CEBitmapInfo;
|
} CEBitmapInfo;
|
||||||
|
|
||||||
DictionaryCtxt* ce_dictionary_make(CEAppGlobals* globals, XP_UCHAR* name);
|
DictionaryCtxt* ce_dictionary_make(CEAppGlobals* globals, XP_UCHAR* name);
|
||||||
|
DictionaryCtxt* ce_dictionary_make_empty( globals );
|
||||||
|
|
||||||
XP_Bool ce_pickDictFile( CEAppGlobals* globals, XP_UCHAR* buf, XP_U16 len );
|
XP_Bool ce_pickDictFile( CEAppGlobals* globals, XP_UCHAR* buf, XP_U16 len );
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue