diff --git a/dictdfiles.cc b/dictdfiles.cc
index 4423524f..e47ff70d 100644
--- a/dictdfiles.cc
+++ b/dictdfiles.cc
@@ -264,18 +264,24 @@ sptr< Dictionary::DataRequest > DictdDictionary::getArticle( wstring const & wor
uint32_t articleOffset = decodeBase64( string( tab1 + 1, tab2 - tab1 - 1 ) );
uint32_t articleSize = decodeBase64( tab2 + 1 );
+ string articleText;
char * articleBody = dict_data_read_( dz, articleOffset, articleSize, 0, 0 );
if ( !articleBody )
- throw exCantReadFile( getDictionaryFilenames()[ 1 ] );
-
+ {
+// throw exCantReadFile( getDictionaryFilenames()[ 1 ] );
+ articleText = string( "
DICTZIP error: " )
+ + dict_error_str( dz ) + "
";
+ }
+ else
+ {
//sprintf( buf, "Offset: %u, Size: %u\n", articleOffset, articleSize );
- string articleText = string( "" ) +
- Html::preformat( articleBody ) + "
";
-
- free( articleBody );
+ articleText = string( "" ) +
+ Html::preformat( articleBody ) + "
";
+ free( articleBody );
+ }
// Ok. Now, does it go to main articles, or to alternate ones? We list
// main ones first, and alternates after.
diff --git a/dictzip.c b/dictzip.c
index 1c3eeff7..3b808a71 100644
--- a/dictzip.c
+++ b/dictzip.c
@@ -173,7 +173,7 @@ static void err_fatal( const char *routine, const char *format, ... )
fflush( stderr );
fflush( stdout );
- exit ( 1 );
+// exit ( 1 );
}
/* \doc |err_fatal_errno| flushes "stdout", prints a fatal error report on
@@ -212,7 +212,7 @@ static void err_fatal_errno( const char *routine, const char *format, ... )
fflush( stderr );
fflush( stdout );
- exit( 1 );
+// exit( 1 );
}
/* \doc |err_internal| flushes "stdout", prints the fatal error message,
@@ -246,7 +246,7 @@ static void err_internal( const char *routine, const char *format, ... )
fprintf( stderr, "Aborting...\n" );
fflush( stderr );
fflush( stdout );
- abort();
+// abort();
}
#ifndef __func__
@@ -273,8 +273,11 @@ static int dict_read_header( const char *filename,
unsigned long offset;
if (!(str = gd_fopen( filename, "rb" )))
+ {
err_fatal_errno( __func__,
"Cannot open data file \"%s\" for read\n", filename );
+ return 1;
+ }
header->filename = NULL;//str_find( filename );
header->headerLength = GZ_XLEN - 1;
@@ -326,9 +329,13 @@ static int dict_read_header( const char *filename,
header->version |= getc( str ) << 8;
if (header->version != 1)
+ {
err_internal( __func__,
"dzip header version %d not supported\n",
header->version );
+ fclose( str );
+ return 1;
+ }
header->chunkLength = getc( str ) << 0;
header->chunkLength |= getc( str ) << 8;
@@ -360,6 +367,8 @@ static int dict_read_header( const char *filename,
err_fatal (
__func__,
"too long FNAME field in dzip file \"%s\"\n", filename);
+ fclose( str );
+ return 1;
}
}
@@ -379,6 +388,8 @@ static int dict_read_header( const char *filename,
err_fatal (
__func__,
"too long COMMENT field in dzip file \"%s\"\n", filename);
+ fclose( str );
+ return 1;
}
}
@@ -396,9 +407,13 @@ static int dict_read_header( const char *filename,
}
if (ftell( str ) != header->headerLength + 1)
+ {
err_internal( __func__,
"File position (%lu) != header length + 1 (%d)\n",
ftell( str ), header->headerLength + 1 );
+ fclose( str );
+ return 1;
+ }
fseek( str, -8, SEEK_END );
header->crc = getc( str ) << 0;
@@ -543,6 +558,11 @@ char *dict_data_read_ (
end = start + size;
buffer = xmalloc( size + 1 );
+ if( !buffer )
+ {
+ strcpy( h->errorString, "Cannot allocate memory" );
+ return 0;
+ }
if ( !size )
{
@@ -557,11 +577,16 @@ char *dict_data_read_ (
assert( h != NULL);
switch (h->type) {
case DICT_GZIP:
+/*
err_fatal( __func__,
"Cannot seek on pure gzip format files.\n"
"Use plain text (for performance)"
" or dzip format (for space savings).\n" );
break;
+*/
+ strcpy( h->errorString, "Cannot seek on pure gzip format files" );
+ xfree( buffer );
+ return 0;
case DICT_TEXT:
{
#ifdef __WIN32
@@ -575,6 +600,7 @@ char *dict_data_read_ (
fread( buffer, size, 1, h->fd ) != 1 )
#endif
{
+ strcpy( h->errorString, "Cannot read file" );
xfree( buffer );
return 0;
}
@@ -592,9 +618,16 @@ char *dict_data_read_ (
h->zStream.next_out = NULL;
h->zStream.avail_out = 0;
if (inflateInit2( &h->zStream, -15 ) != Z_OK)
+/*
err_internal( __func__,
"Cannot initialize inflation engine: %s\n",
h->zStream.msg );
+*/
+ {
+ sprintf( h->errorString, "Cannot initialize inflation engine: %s", h->zStream.msg );
+ xfree( buffer );
+ return 0;
+ }
++h->initialized;
}
firstChunk = start / h->chunkLength;
@@ -643,9 +676,15 @@ char *dict_data_read_ (
inBuffer = h->cache[target].inBuffer;
if (h->chunks[i] >= OUT_BUFFER_SIZE ) {
+/*
err_internal( __func__,
"h->chunks[%d] = %d >= %ld (OUT_BUFFER_SIZE)\n",
i, h->chunks[i], OUT_BUFFER_SIZE );
+*/
+ sprintf( h->errorString, "h->chunks[%d] = %d >= %ld (OUT_BUFFER_SIZE)\n",
+ i, h->chunks[i], OUT_BUFFER_SIZE );
+ xfree( buffer );
+ return 0;
}
#ifdef __WIN32
@@ -670,11 +709,24 @@ char *dict_data_read_ (
h->zStream.next_out = (Bytef *)inBuffer;
h->zStream.avail_out = h->chunkLength;
if (inflate( &h->zStream, Z_PARTIAL_FLUSH ) != Z_OK)
- err_fatal( __func__, "inflate: %s\n", h->zStream.msg );
+ {
+// err_fatal( __func__, "inflate: %s\n", h->zStream.msg );
+ sprintf( h->errorString, "inflate: %s\n", h->zStream.msg );
+ xfree( buffer );
+ return 0;
+ }
if (h->zStream.avail_in)
+/*
err_internal( __func__,
"inflate did not flush (%d pending, %d avail)\n",
h->zStream.avail_in, h->zStream.avail_out );
+*/
+ {
+ sprintf( h->errorString, "inflate did not flush (%d pending, %d avail)\n",
+ h->zStream.avail_in, h->zStream.avail_out );
+ xfree( buffer );
+ return 0;
+ }
count = h->chunkLength - h->zStream.avail_out;
dict_data_filter( inBuffer, &count, h->chunkLength, postFilter );
@@ -689,9 +741,17 @@ char *dict_data_read_ (
pt += lastOffset - firstOffset;
} else {
if (count != h->chunkLength )
+/*
err_internal( __func__,
"Length = %d instead of %d\n",
count, h->chunkLength );
+*/
+ {
+ sprintf( h->errorString, "Length = %d instead of %d\n",
+ count, h->chunkLength );
+ xfree( buffer );
+ return 0;
+ }
memcpy( pt, inBuffer + firstOffset,
h->chunkLength - firstOffset );
pt += h->chunkLength - firstOffset;
@@ -708,9 +768,16 @@ char *dict_data_read_ (
*pt = '\0';
break;
case DICT_UNKNOWN:
- err_fatal( __func__, "Cannot read unknown file type\n" );
- break;
+// err_fatal( __func__, "Cannot read unknown file type\n" );
+ strcpy( h->errorString, "Cannot read unknown file type" );
+ xfree( buffer );
+ return 0;
}
return buffer;
}
+
+char *dict_error_str( dictData *data )
+{
+ return data->errorString;
+}
diff --git a/dictzip.h b/dictzip.h
index ab045df3..2d3cf4b0 100644
--- a/dictzip.h
+++ b/dictzip.h
@@ -80,6 +80,7 @@ typedef struct dictData {
unsigned long compressedLength;
int stamp;
dictCache cache[DICT_CACHE_SIZE];
+ char errorString[512];
} dictData;
@@ -96,6 +97,8 @@ extern char *dict_data_read_ (
const char *preFilter,
const char *postFilter );
+extern char *dict_error_str( dictData *data );
+
extern int mmap_mode;
#ifdef __cplusplus
diff --git a/dsl.cc b/dsl.cc
index d1d7c0e0..b8353c7c 100644
--- a/dsl.cc
+++ b/dsl.cc
@@ -503,20 +503,25 @@ void DslDictionary::loadArticle( uint32_t address,
}
if ( !articleBody )
- throw exCantReadFile( getDictionaryFilenames()[ 0 ] );
-
- try
{
- articleData =
- DslIconv::toWstring(
- DslIconv::getEncodingNameFor( DslEncoding( idxHeader.dslEncoding ) ),
- articleBody, articleSize );
- free( articleBody );
+// throw exCantReadFile( getDictionaryFilenames()[ 0 ] );
+ articleData = GD_NATIVE_TO_WS( L"\n\r\t" ) + gd::toWString( QString( "DICTZIP error: " ) + dict_error_str( dz ) );
}
- catch( ... )
+ else
{
- free( articleBody );
- throw;
+ try
+ {
+ articleData =
+ DslIconv::toWstring(
+ DslIconv::getEncodingNameFor( DslEncoding( idxHeader.dslEncoding ) ),
+ articleBody, articleSize );
+ free( articleBody );
+ }
+ catch( ... )
+ {
+ free( articleBody );
+ throw;
+ }
}
}
diff --git a/stardict.cc b/stardict.cc
index 02fbe469..5c6d4855 100644
--- a/stardict.cc
+++ b/stardict.cc
@@ -341,7 +341,11 @@ void StardictDictionary::loadArticle( uint32_t address,
}
if ( !articleBody )
- throw exCantReadFile( getDictionaryFilenames()[ 2 ] );
+ {
+// throw exCantReadFile( getDictionaryFilenames()[ 2 ] );
+ articleText = string( "DICTZIP error: " ) + dict_error_str( dz ) + "
";
+ return;
+ }
articleText.clear();
diff --git a/xdxf.cc b/xdxf.cc
index 4cd1b23e..37818cdc 100644
--- a/xdxf.cc
+++ b/xdxf.cc
@@ -545,7 +545,11 @@ void XdxfDictionary::loadArticle( uint32_t address,
}
if ( !articleBody )
- throw exCantReadFile( getDictionaryFilenames()[ 0 ] );
+ {
+// throw exCantReadFile( getDictionaryFilenames()[ 0 ] );
+ articleText = string( "DICTZIP error: " ) + dict_error_str( dz ) + "
";
+ return;
+ }
articleText = Xdxf2Html::convert( string( articleBody ), Xdxf2Html::XDXF, idxHeader.hasAbrv ? &abrv : NULL, this );