FEX: Make fex crap properly convert filenames from 7z archives to utf8 under Linux
This commit is contained in:
parent
a59c64a292
commit
750a57a4a7
|
@ -201,6 +201,74 @@ void Zip7_Extractor::close_v()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This method was taken from ogre-7z (thanks), and is thus LGPL
|
||||||
|
bool Zip7_Extractor::utf16ToUtf8( unsigned char* dest, size_t* destLen, const short* src, size_t srcLen )
|
||||||
|
{
|
||||||
|
static const unsigned char sUtf8Limits[5] = { 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||||
|
|
||||||
|
size_t destPos = 0, srcPos = 0;
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
unsigned int numAdds;
|
||||||
|
unsigned long value;
|
||||||
|
if( srcPos == srcLen )
|
||||||
|
{
|
||||||
|
*destLen = destPos;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = src[srcPos++];
|
||||||
|
if( value < 0x80 )
|
||||||
|
{
|
||||||
|
if( dest )
|
||||||
|
{
|
||||||
|
dest[destPos] = (char)value;
|
||||||
|
}
|
||||||
|
destPos++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( value >= 0xD800 && value < 0xE000 )
|
||||||
|
{
|
||||||
|
unsigned long c2;
|
||||||
|
if( value >= 0xDC00 || srcPos == srcLen )
|
||||||
|
break;
|
||||||
|
|
||||||
|
c2 = src[srcPos++];
|
||||||
|
if( c2 < 0xDC00 || c2 >= 0xE000 )
|
||||||
|
break;
|
||||||
|
|
||||||
|
value = (((value - 0xD800) << 10) | (c2 - 0xDC00)) + 0x10000;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( numAdds = 1; numAdds < 5; numAdds++ )
|
||||||
|
{
|
||||||
|
if( value < (((UInt32)1) << (numAdds * 5 + 6)) )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( dest )
|
||||||
|
{
|
||||||
|
dest[destPos] = (char)(sUtf8Limits[numAdds - 1] + (value >> (6 * numAdds)));
|
||||||
|
}
|
||||||
|
|
||||||
|
destPos++;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
numAdds--;
|
||||||
|
if( dest )
|
||||||
|
{
|
||||||
|
dest[destPos] = (char)(0x80 + ((value >> (6 * numAdds)) & 0x3F));
|
||||||
|
}
|
||||||
|
destPos++;
|
||||||
|
}
|
||||||
|
while( numAdds != 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
*destLen = destPos;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
blargg_err_t Zip7_Extractor::next_v()
|
blargg_err_t Zip7_Extractor::next_v()
|
||||||
{
|
{
|
||||||
while ( ++index < (int) impl->db.db.NumFiles )
|
while ( ++index < (int) impl->db.db.NumFiles )
|
||||||
|
@ -226,7 +294,7 @@ blargg_err_t Zip7_Extractor::next_v()
|
||||||
localtime_r( &_time, &tm );
|
localtime_r( &_time, &tm );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
date = ( tm.tm_sec >> 1 ) & 0x1F |
|
date = (( tm.tm_sec >> 1 ) & 0x1F) |
|
||||||
(( tm.tm_min & 0x3F ) << 5 ) |
|
(( tm.tm_min & 0x3F ) << 5 ) |
|
||||||
(( tm.tm_hour & 0x1F ) << 11 ) |
|
(( tm.tm_hour & 0x1F ) << 11 ) |
|
||||||
(( tm.tm_mday & 0x1F ) << 16 ) |
|
(( tm.tm_mday & 0x1F ) << 16 ) |
|
||||||
|
@ -235,14 +303,15 @@ blargg_err_t Zip7_Extractor::next_v()
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t name_length = SzArEx_GetFileNameUtf16( &impl->db, index, 0 );
|
size_t name_length = SzArEx_GetFileNameUtf16( &impl->db, index, 0 );
|
||||||
|
size_t utf8_length = 0;
|
||||||
name16.resize( name_length );
|
name16.resize( name_length );
|
||||||
SzArEx_GetFileNameUtf16( &impl->db, index, ( UInt16 * ) name16.begin() );
|
SzArEx_GetFileNameUtf16( &impl->db, index, ( UInt16 * ) name16.begin() );
|
||||||
char * temp = blargg_to_utf8( name16.begin() );
|
unsigned char temp[1024];
|
||||||
if ( !temp ) temp = "";
|
utf16ToUtf8( temp, &utf8_length, (const short*)name16.begin(), name_length - 1 );
|
||||||
size_t utf8_length = strlen( temp );
|
temp[utf8_length] = '\0';
|
||||||
|
|
||||||
name8.resize( utf8_length + 1 );
|
name8.resize( utf8_length + 1 );
|
||||||
memcpy( name8.begin(), temp, utf8_length + 1 );
|
memcpy( name8.begin(), temp, utf8_length + 1 );
|
||||||
free( temp );
|
|
||||||
set_name( name8.begin(), name16.begin() );
|
set_name( name8.begin(), name16.begin() );
|
||||||
set_info( item.Size, 0, (item.CrcDefined ? item.Crc : 0) );
|
set_info( item.Size, 0, (item.CrcDefined ? item.Crc : 0) );
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -24,6 +24,8 @@ protected:
|
||||||
|
|
||||||
virtual blargg_err_t data_v( void const** out );
|
virtual blargg_err_t data_v( void const** out );
|
||||||
|
|
||||||
|
bool utf16ToUtf8( unsigned char* dest, size_t* destLen, const short* src, size_t srcLen );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Zip7_Extractor_Impl* impl;
|
Zip7_Extractor_Impl* impl;
|
||||||
int index;
|
int index;
|
||||||
|
|
Loading…
Reference in New Issue