Changeset f9756bd


Ignore:
Timestamp:
2008-03-30T21:26:16Z (16 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
ddba0ae
Parents:
5ecf96b
Message:

Changed charset handling: irc_t keeps two iconv structures, which are just
used for every line sent and received, so now there's no need to use
g_iconv_open() every time a message comes in/out. Also, fixed a small
memory leak that was there for a long time but somehow never caught my
attention.

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • irc.c

    r5ecf96b rf9756bd  
    4242}
    4343
     44static char *set_eval_charset( set_t *set, char *value )
     45{
     46        irc_t *irc = set->data;
     47        GIConv ic, oc;
     48
     49        if( g_strcasecmp( value, "none" ) == 0 )
     50                value = g_strdup( "utf-8" );
     51
     52        if( ( ic = g_iconv_open( "utf-8", value ) ) == (GIConv) -1 )
     53        {
     54                return NULL;
     55        }
     56        if( ( oc = g_iconv_open( value, "utf-8" ) ) == (GIConv) -1 )
     57        {
     58                g_iconv_close( ic );
     59                return NULL;
     60        }
     61       
     62        if( irc->iconv != (GIConv) -1 )
     63                g_iconv_close( irc->iconv );
     64        if( irc->oconv != (GIConv) -1 )
     65                g_iconv_close( irc->oconv );
     66       
     67        irc->iconv = ic;
     68        irc->oconv = oc;
     69
     70        return value;
     71}
     72
    4473irc_t *irc_new( int fd )
    4574{
     
    6493        irc->mynick = g_strdup( ROOT_NICK );
    6594        irc->channel = g_strdup( ROOT_CHAN );
     95       
     96        irc->iconv = (GIConv) -1;
     97        irc->oconv = (GIConv) -1;
    6698       
    6799        if( global.conf->hostname )
     
    127159        conf_loaddefaults( irc );
    128160       
     161        /* Evaluator sets the iconv/oconv structures. */
     162        set_eval_charset( set_find( &irc->set, "charset" ), set_getstr( &irc->set, "charset" ) );
     163       
    129164        return( irc );
    130165}
     
    265300        g_hash_table_destroy(irc->watches);
    266301       
     302        if( irc->iconv != (GIConv) -1 )
     303                g_iconv_close( irc->iconv );
     304        if( irc->oconv != (GIConv) -1 )
     305                g_iconv_close( irc->oconv );
     306       
     307        g_free( irc->last_target );
     308       
    267309        g_free(irc);
    268310       
     
    286328void irc_process( irc_t *irc )
    287329{
    288         char **lines, *temp, **cmd, *cs;
     330        char **lines, *temp, **cmd;
    289331        int i;
    290332
     
    295337                for( i = 0; *lines[i] != '\0'; i ++ )
    296338                {
    297                         char conv[IRC_MAX_LINE+1];
     339                        char *conv = NULL;
    298340                       
    299341                        /* [WvG] If the last line isn't empty, it's an incomplete line and we
     
    308350                        }
    309351                       
    310                         if( ( cs = set_getstr( &irc->set, "charset" ) ) && g_strcasecmp( cs, "none" ) != 0 )
    311                         {
    312                                 conv[IRC_MAX_LINE] = 0;
    313                                 if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) == -1 )
     352                        if( irc->iconv != (GIConv) -1 )
     353                        {
     354                                gsize bytes_read, bytes_written;
     355                               
     356                                conv = g_convert_with_iconv( lines[i], -1, irc->iconv,
     357                                                             &bytes_read, &bytes_written, NULL );
     358                               
     359                                if( conv == NULL || bytes_read != strlen( lines[i] ) )
    314360                                {
    315361                                        /* GLib can do strange things if things are not in the expected charset,
     
    323369                                                                  "expect by changing the charset setting. See "
    324370                                                                  "`help set charset' for more information. Your "
    325                                                                   "message was ignored.", cs );
    326                                                 *conv = 0;
     371                                                                  "message was ignored.",
     372                                                                  set_getstr( &irc->set, "charset" ) );
     373                                               
     374                                                g_free( conv );
     375                                                conv = NULL;
    327376                                        }
    328377                                        else
     
    331380                                                           "Warning: invalid characters received at login time." );
    332381                                               
    333                                                 strncpy( conv, lines[i], IRC_MAX_LINE );
     382                                                conv = g_strdup( lines[i] );
    334383                                                for( temp = conv; *temp; temp ++ )
    335384                                                        if( *temp & 0x80 )
     
    340389                        }
    341390                       
    342                         if( ( cmd = irc_parse_line( lines[i] ) ) == NULL )
    343                                 continue;
    344                         irc_exec( irc, cmd );
     391                        if( lines[i] )
     392                        {
     393                                if( ( cmd = irc_parse_line( lines[i] ) ) == NULL )
     394                                        continue;
     395                                irc_exec( irc, cmd );
     396                                g_free( cmd );
     397                        }
    345398                       
    346                         g_free( cmd );
     399                        g_free( conv );
    347400                       
    348401                        /* Shouldn't really happen, but just in case... */
     
    536589
    537590        return;
    538 
    539591}
    540592
     
    542594{
    543595        int size;
    544         char line[IRC_MAX_LINE+1], *cs;
     596        char line[IRC_MAX_LINE+1];
    545597               
    546598        /* Don't try to write anything new anymore when shutting down. */
     
    548600                return;
    549601       
    550         line[IRC_MAX_LINE] = 0;
     602        memset( line, 0, sizeof( line ) );
    551603        g_vsnprintf( line, IRC_MAX_LINE - 2, format, params );
    552        
    553604        strip_newlines( line );
    554         if( ( cs = set_getstr( &irc->set, "charset" ) ) &&
    555             g_strcasecmp( cs, "none" ) != 0 && g_strcasecmp( cs, "utf-8" ) != 0 )
    556         {
    557                 char conv[IRC_MAX_LINE+1];
    558                
    559                 conv[IRC_MAX_LINE] = 0;
    560                 if( do_iconv( "UTF-8", cs, line, conv, 0, IRC_MAX_LINE - 2 ) != -1 )
    561                         strcpy( line, conv );
    562         }
    563         strcat( line, "\r\n" );
     605       
     606        if( irc->oconv != (GIConv) -1 )
     607        {
     608                gsize bytes_read, bytes_written;
     609                char *conv;
     610               
     611                conv = g_convert_with_iconv( line, -1, irc->oconv,
     612                                             &bytes_read, &bytes_written, NULL );
     613
     614                if( bytes_read == strlen( line ) )
     615                        strncpy( line, conv, IRC_MAX_LINE - 2 );
     616               
     617                g_free( conv );
     618        }
     619        g_strlcat( line, "\r\n", IRC_MAX_LINE + 1 );
    564620       
    565621        if( irc->sendbuffer != NULL )
  • irc.h

    r5ecf96b rf9756bd  
    6161        char *sendbuffer;
    6262        char *readbuffer;
     63        GIConv iconv, oconv;
    6364
    6465        int sentbytes;
  • irc_commands.c

    r5ecf96b rf9756bd  
    278278                        if( cmd[1] != irc->last_target )
    279279                        {
    280                                 if( irc->last_target )
    281                                         g_free( irc->last_target );
     280                                g_free( irc->last_target );
    282281                                irc->last_target = g_strdup( cmd[1] );
    283282                        }
  • set.c

    r5ecf96b rf9756bd  
    230230        return value;
    231231}
    232 
    233 char *set_eval_charset( set_t *set, char *value )
    234 {
    235         GIConv cd;
    236 
    237         if( g_strcasecmp( value, "none" ) == 0 )
    238                 return value;
    239 
    240         cd = g_iconv_open( "UTF-8", value );
    241         if( cd == (GIConv) -1 )
    242                 return NULL;
    243 
    244         g_iconv_close( cd );
    245         return value;
    246 }
  • set.h

    r5ecf96b rf9756bd  
    9797char *set_eval_to_char( set_t *set, char *value );
    9898char *set_eval_ops( set_t *set, char *value );
    99 char *set_eval_charset( set_t *set, char *value );
    10099
    101100#endif /* __SET_H__ */
Note: See TracChangeset for help on using the changeset viewer.