#include <cassert>
#include <iostream>
-#include <cstdlib> // strtod
#include <QDir>
#include <QFile>
#include <libtransmission/bencode.h>
#include <libtransmission/json.h>
#include <libtransmission/utils.h>
+#include <stdlib.h>
#include "prefs.h"
#include "types.h"
+#include "utils.h"
/***
****
***/
Prefs :: Prefs( const char * configDir ):
- myConfigDir( configDir )
+ myConfigDir( QString::fromUtf8( configDir ) )
{
assert( sizeof(myItems) / sizeof(myItems[0]) == PREFS_COUNT );
for( int i=0; i<PREFS_COUNT; ++i )
break;
case QVariant::String:
if( tr_bencGetStr( b, &str ) )
- myValues[i].setValue( QString::fromUtf8(str) );
+ myValues[i].setValue( QString::fromUtf8( str ) );
break;
case QVariant::Bool:
if( tr_bencGetBool( b, &boolVal ) )
tr_bencDictAddStr( &top, key, val.value<FilterMode>().name().toUtf8().constData() );
break;
case QVariant::String:
- tr_bencDictAddStr( &top, key, val.toString().toUtf8().constData() );
+ { const char * s = val.toByteArray().constData();
+ if ( Utils::isValidUtf8( s ) )
+ tr_bencDictAddStr( &top, key, s );
+ else
+ tr_bencDictAddStr( &top, key, val.toString().toUtf8().constData() );
+ }
break;
case QVariant::Bool:
tr_bencDictAddBool( &top, key, val.toBool() );
tr_bencDictAddBool( d, keyStr(INHIBIT_HIBERNATION), false );
tr_bencDictAddInt ( d, keyStr(BLOCKLIST_DATE), 0 );
tr_bencDictAddBool( d, keyStr(BLOCKLIST_UPDATES_ENABLED), true );
- tr_bencDictAddStr ( d, keyStr(OPEN_DIALOG_FOLDER), QDir::home().absolutePath().toLatin1() );
+ tr_bencDictAddStr ( d, keyStr(OPEN_DIALOG_FOLDER), QDir::home().absolutePath().toUtf8() );
tr_bencDictAddInt ( d, keyStr(SHOW_TRACKER_SCRAPES), false );
tr_bencDictAddBool( d, keyStr(TOOLBAR), true );
tr_bencDictAddBool( d, keyStr(FILTERBAR), true );
Prefs :: getString( int key ) const
{
assert( myItems[key].type == QVariant::String );
- return myValues[key].toString( );
+ QByteArray b = myValues[key].toByteArray();
+ if ( Utils::isValidUtf8( b.constData() ) )
+ myValues[key].setValue( QString::fromUtf8( b.constData() ) );
+ return myValues[key].toString();
}
int
case QVariant::Bool: tr_bencDictAddBool ( args, key, value.toBool() ); break;
case QVariant::Int: tr_bencDictAddInt ( args, key, value.toInt() ); break;
case QVariant::Double: tr_bencDictAddReal ( args, key, value.toDouble() ); break;
- case QVariant::String: tr_bencDictAddStr ( args, key, value.toString().toUtf8() ); break;
+ case QVariant::String: tr_bencDictAddStr ( args, key, value.toString().toUtf8().constData() ); break;
default: assert( "unknown type" );
}
exec( &top );
myBlocklistSize( -1 ),
myPrefs( prefs ),
mySession( 0 ),
- myConfigDir( configDir ),
+ myConfigDir( QString::fromUtf8( configDir ) ),
myNAM( 0 )
{
myStats.ratio = TR_RATIO_NA;
return fallback;
}
+
+bool
+Utils :: isValidUtf8 ( const char *s )
+{
+ int n; // number of bytes in a UTF-8 sequence
+
+ for ( const char *c = s; *c; c += n )
+ {
+ if ( (*c & 0x80) == 0x00 ) n = 1; // ASCII
+ else if ((*c & 0xc0) == 0x80) return false; // not valid
+ else if ((*c & 0xe0) == 0xc0) n = 2;
+ else if ((*c & 0xf0) == 0xe0) n = 3;
+ else if ((*c & 0xf8) == 0xf0) n = 4;
+ else if ((*c & 0xfc) == 0xf8) n = 5;
+ else if ((*c & 0xfe) == 0xfc) n = 6;
+ else return false;
+ for ( int m = 1; m < n; m++ )
+ if ( (c[m] & 0xc0) != 0x80 )
+ return false;
+ }
+ return true;
+}