~ubuntu-branches/ubuntu/wily/easytag/wily

« back to all changes in this revision

Viewing changes to src/charset.c

  • Committer: Package Import Robot
  • Author(s): Alessio Treglia
  • Date: 2013-10-11 17:07:47 UTC
  • mto: (8.1.4 sid)
  • mto: This revision was merged to the branch mainline in revision 14.
  • Revision ID: package-import@ubuntu.com-20131011170747-uqvgtx7uyd046j7z
Tags: upstream-2.1.8
Import upstream version 2.1.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Main part of code, written by:
3
3
 *
4
 
 * Copyright (C) 1999-2001  H�vard Kv�len <havardk@xmms.org>
 
4
 * Copyright (C) 1999-2001  Håvard Kvålen <havardk@xmms.org>
5
5
 *
6
6
 * This program is free software; you can redistribute it and/or
7
7
 * modify it under the terms of the GNU General Public License
35
35
#include "setting.h"
36
36
#include "log.h"
37
37
 
38
 
#ifdef WIN32
39
 
    #include "win32/win32dep.h"
40
 
#endif
 
38
#ifdef G_OS_WIN32
 
39
#include "win32/win32dep.h"
 
40
#endif /* G_OS_WIN32 */
41
41
 
42
42
 
43
43
/****************
45
45
 ****************/
46
46
 
47
47
#define CHARSET_TRANS_ARRAY_LEN ( sizeof(charset_trans_array) / sizeof((charset_trans_array)[0]) )
48
 
const CharsetInfo charset_trans_array[] = {
 
48
static const CharsetInfo charset_trans_array[] = {
49
49
    {N_("Arabic (IBM-864)"),                  "IBM864"        },
50
50
    {N_("Arabic (ISO-8859-6)"),               "ISO-8859-6"    },
51
51
    {N_("Arabic (Windows-1256)"),             "windows-1256"  },
185
185
 
186
186
    /* "C" is plain ascii */
187
187
    insert_locales (encodings, "ASCII", "C", NULL);
188
 
#if WIN32
 
188
#ifdef G_OS_WIN32
189
189
    insert_locales (encodings, "windows-1256", "ar", NULL); // 2006.12.31 - For testing with Arabic
190
 
#else
 
190
#else /* !G_OS_WIN32 */
191
191
    insert_locales (encodings, "ISO-8859-6", "ar", NULL);
192
 
#endif
 
192
#endif /* !G_OS_WIN32 */
193
193
    insert_locales (encodings, "ARMSCII-8", "by", NULL);
194
194
    insert_locales (encodings, "BIG5", "zh_TW", NULL);
195
195
    insert_locales (encodings, "CP1251", "be", "bg", NULL);
203
203
    /*insert_locales (encodings, "GEORGIAN-ACADEMY", NULL);*/
204
204
    insert_locales (encodings, "GEORGIAN-PS", "ka", NULL);
205
205
    insert_locales (encodings, "ISO-8859-1", "br", "ca", "da", "de", "en", "es", "eu", "fi", "fr", "gl", "it", "nl", "wa", "nb", "nn", "pt", "pt", "sv", NULL);
206
 
#if WIN32
 
206
#ifdef G_OS_WIN32
207
207
    insert_locales (encodings, "windows-1250", "cs", "hr", "hu", "pl", "ro", "sk", "sl", "sq", "sr", NULL);
208
 
#else
 
208
#else /* !G_OS_WIN32 */
209
209
    insert_locales (encodings, "ISO-8859-2", "cs", "hr", "hu", "pl", "ro", "sk", "sl", "sq", "sr", NULL);
210
 
#endif
 
210
#endif /* !G_OS_WIN32 */
211
211
    insert_locales (encodings, "ISO-8859-3", "eo", NULL);
212
212
    insert_locales (encodings, "ISO-8859-5", "mk", "sp", NULL);
213
 
#if WIN32
 
213
#ifdef G_OS_WIN32
214
214
    insert_locales (encodings, "windows-1253", "el", NULL);
215
 
#else
 
215
#else /* !G_OS_WIN32 */
216
216
    insert_locales (encodings, "ISO-8859-7", "el", NULL);
217
 
#endif
218
 
#if WIN32
 
217
#endif /* !G_OS_WIN32 */
 
218
#ifdef G_OS_WIN32
219
219
    insert_locales (encodings, "windows-1254", "tr", NULL);
220
 
#else
 
220
#else /* !G_OS_WIN32 */
221
221
    insert_locales (encodings, "ISO-8859-9", "tr", NULL);
222
 
#endif
 
222
#endif /* !G_OS_WIN32 */
223
223
    insert_locales (encodings, "ISO-8859-13", "lt", "lv", "mi", NULL);
224
224
    insert_locales (encodings, "ISO-8859-14", "ga", "cy", NULL);
225
225
    insert_locales (encodings, "ISO-8859-15", "et", NULL);
226
 
#if WIN32
 
226
#ifdef G_OS_WIN32
227
227
    insert_locales (encodings, "windows-1251", "ru", NULL);
228
 
#else
 
228
#else /* !G_OS_WIN32 */
229
229
    insert_locales (encodings, "KOI8-R", "ru", NULL);
230
 
#endif
 
230
#endif /* !G_OS_WIN32 */
231
231
    insert_locales (encodings, "KOI8-U", "uk", NULL);
232
232
    if (check_locale ("TCVN-5712")) {
233
233
        insert_locales (encodings, "TCVN-5712", "vi", NULL);
235
235
        insert_locales (encodings, "TCVN", "vi", NULL);
236
236
    }
237
237
    insert_locales (encodings, "TIS-620", "th", NULL);
238
 
#if WIN32
 
238
#ifdef G_OS_WIN32
239
239
    insert_locales (encodings, "windows-1255", "he", NULL);
240
 
#endif
 
240
#endif /* G_OS_WIN32 */
241
241
    /*insert_locales (encodings, "VISCII", NULL);*/
242
242
}
243
243
 
354
354
 */
355
355
const gchar *get_locale (void)
356
356
{
357
 
    gchar *loc;
 
357
    const gchar *loc;
358
358
    
359
359
    if ((loc = g_getenv("LC_ALL")) && *loc)
360
360
        return loc;
381
381
{
382
382
    return convert_string_1(string, -1, from_codeset, to_codeset, display_error);
383
383
}
 
384
 
384
385
/* Length must be passed, as the string might be Unicode, in which case we can't
385
386
 * count zeroes (see strlen call below). */
386
 
gchar *convert_string_1 (const gchar *string, gssize length, const gchar *from_codeset,
 
387
gchar *
 
388
convert_string_1 (const gchar *string, gssize length, const gchar *from_codeset,
387
389
                         const gchar *to_codeset, const gboolean display_error)
388
390
{
389
391
    gchar *output;
390
392
    GError *error = NULL;
391
393
    gsize bytes_written;
392
394
 
393
 
    if (!string)
394
 
        return NULL;
 
395
    g_return_val_if_fail (string != NULL, NULL);
395
396
 
396
397
    output = g_convert(string, length, to_codeset, from_codeset, NULL, &bytes_written, &error);
397
398
    //output = g_convert_with_fallback(string, length, to_codeset, from_codeset, "?", NULL, &bytes_written, &error);
420
421
        //    g_convert returns null-terminated string only with one \0 at the
421
422
        // end. It can cause some garbage at the end of a string for UTF-16.
422
423
        // The second \0 should be set manually.
423
 
        output = g_realloc(output, bytes_written + 2);
424
 
        if (output != NULL)
 
424
        gchar *new_output;
 
425
        new_output = g_realloc (output, bytes_written + 2);
 
426
        if (new_output != NULL)
 
427
        {
 
428
            output = new_output;
425
429
            output[bytes_written] = output[bytes_written + 1] = 0;
 
430
        }
426
431
    }
427
432
 
428
433
    //g_print("from %s => len: %d, string: '%s'\n     (%x %x %x %x %x %x %x %x)\n",from_codeset,length,string,string[0],string[1],string[2],string[3],string[4],string[5],string[6],string[7]);
467
472
    return output;
468
473
}
469
474
 
470
 
gchar *convert_from_utf8 (const char *string)
471
 
{
472
 
    gchar *output;
473
 
    GError *error = NULL;
474
 
 
475
 
    if (!string)
476
 
        return NULL;
477
 
 
478
 
    output = g_locale_from_utf8(string, -1, NULL, NULL, &error);
479
 
 
480
 
    if (output == NULL)
481
 
    {
482
 
        const gchar *usercharset;
483
 
        gchar *escaped_str = g_strescape(string, NULL);
484
 
        g_get_charset(&usercharset);
485
 
        Log_Print(LOG_ERROR,"convert_from_utf8(): Failed conversion to charset '%s'. "
486
 
                  "String '%s'. Errcode %d (%s).",
487
 
                  usercharset, escaped_str, error->code, error->message);
488
 
        g_free(escaped_str);
489
 
 
490
 
        if (g_utf8_validate(string, -1, NULL))
491
 
            Log_Print(LOG_ERROR,"convert_from_utf8(): String was valid UTF-8.");
492
 
        else
493
 
            Log_Print(LOG_ERROR,"convert_from_utf8(): String was INVALID UTF-8.");
494
 
 
495
 
        g_error_free(error);
496
 
        return g_strdup(string);
497
 
    }
498
 
 
499
 
    return output;
500
 
}
501
 
 
502
 
 
503
 
 
504
475
/*
505
476
 * Convert a string from the filename system encoding to UTF-8.
506
477
 *  - conversion OK : returns the UTF-8 string (new allocated)
507
478
 *  - conversion KO : tries others encodings else returns an 'escaped' string
508
479
 */
509
 
gchar *filename_to_display (const gchar *string)
 
480
gchar *
 
481
filename_to_display (const gchar *string)
510
482
{
511
483
    gchar *ret = NULL;
512
484
    GError *error = NULL;
513
485
 
514
 
    if (!string)
515
 
        return NULL;
 
486
    g_return_val_if_fail (string != NULL, NULL);
516
487
 
517
488
    if (g_utf8_validate(string, -1, NULL))
518
489
    {
549
520
        }
550
521
    }
551
522
 
552
 
#ifdef WIN32
553
 
    ET_Win32_Path_Remove_Trailing_Slash(ret);
554
 
    ET_Win32_Path_Replace_Slashes(ret);
555
 
#endif
 
523
#ifdef G_OS_WIN32
 
524
    ET_Win32_Path_Remove_Trailing_Slash (ret);
 
525
    ET_Win32_Path_Replace_Slashes (ret);
 
526
#endif /* G_OS_WIN32 */
556
527
 
557
528
    return ret;
558
529
}
569
540
    const gchar *char_encoding = NULL;
570
541
    //const gchar *filename_encoding = NULL;
571
542
 
572
 
    if (!string) return NULL;
 
543
    g_return_val_if_fail (string != NULL, NULL);
573
544
 
574
545
    // Get system encoding from LANG if found (ex : fr_FR.UTF-8 => UTF-8)
575
546
    if (get_locale())
647
618
        ret = escaped_str;
648
619
    }
649
620
 
650
 
#ifdef WIN32
651
 
    //ET_Win32_Path_Replace_Backslashes(ret);
652
 
#endif
 
621
#ifdef G_OS_WIN32
 
622
    //ET_Win32_Path_Replace_Backslashes (ret);
 
623
#endif /* G_OS_WIN32 */
653
624
 
654
625
    return ret; // We need to catch errors (e.g. temp=NULL) in the real code
655
626
}
663
634
 * Examples :
664
635
 *   - some Ogg Vorbis tags contain ISO-8859-1 characters instead of UTF-8).
665
636
 *   - some Flac tags may be probably encoded to ISO-8859-15 (by using for example
666
 
 *     "metaflac --no-utf8-convert ...") so we convert it from ISO-8859-1 to UTF-8.
 
637
 *     "metaflac --no-utf8-convert …") so we convert it from ISO-8859-1 to UTF-8.
667
638
 *
668
639
 * If not valid UTF-8, we try some conversion to try to get the correct string
669
640
 *  - conversion OK : returns the UTF-8 string (new allocated)
723
694
 
724
695
    for (i=0; i<CHARSET_TRANS_ARRAY_LEN; i++)
725
696
    {
726
 
        gtk_combo_box_append_text(combo, _(charset_trans_array[i].charset_title));
 
697
        gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _(charset_trans_array[i].charset_title));
727
698
 
728
699
        if (select_charset && strcmp(charset_trans_array[i].charset_name, select_charset) == 0)
729
700
            gtk_combo_box_set_active(combo, i);
734
705
/*
735
706
 * Return charset_name from charset_title
736
707
 */
737
 
gchar *Charset_Get_Name_From_Title (const gchar *charset_title)
738
 
{
739
 
    guint i;
740
 
 
741
 
    if (charset_title)
742
 
        for (i=0; i<CHARSET_TRANS_ARRAY_LEN; i++)
743
 
            if ( strcasecmp(_(charset_title),_(charset_trans_array[i].charset_title)) == 0 )
744
 
                return charset_trans_array[i].charset_name;
745
 
    return "";
746
 
}
747
 
 
748
 
 
749
 
/*
750
 
 * Return charset_title from charset_name
751
 
 */
752
 
gchar *Charset_Get_Title_From_Name (gchar *charset_name)
753
 
{
754
 
    guint i;
755
 
 
756
 
    if (charset_name)
757
 
        for (i=0; i<CHARSET_TRANS_ARRAY_LEN; i++)
758
 
            if ( strcasecmp(charset_name,charset_trans_array[i].charset_name) == 0 )
759
 
                return _(charset_trans_array[i].charset_title);
760
 
    return "";
761
 
}
762
 
 
763
 
 
764
 
 
765
 
/*
766
 
 * Test if the conversion is supported between two character sets ('from' and 'to)
767
 
 * (function called in the preferences window).
768
 
 * Note : for UTF-16 (2 byte for each character) we make a special test...
769
 
 */
770
 
gboolean test_conversion_charset (const gchar *from, const gchar *to)
771
 
{
772
 
    gchar *temp;
773
 
 
774
 
    if (!from || !to)
775
 
        return FALSE;
776
 
 
777
 
    // Do a quick test conversion and examine error output
778
 
    if ( strcmp(from,"UTF-16BE") == 0 )
779
 
    {
780
 
        temp = convert_string_1("F\0O\0O\0\0\0", 6, from, to, FALSE);
781
 
    }else if ( strcmp(from,"UTF-16LE") == 0 )
782
 
    {
783
 
        temp = convert_string_1("\0F\0O\0O\0\0", 6, from, to, FALSE);
784
 
    }else
785
 
    {
786
 
        temp = convert_string("FOO", from, to, FALSE);
787
 
    }
788
 
 
789
 
    if (!temp)
790
 
    {
791
 
        /*// Error in conversion
792
 
        if (error && error->code == G_CONVERT_ERROR_NO_CONVERSION)
793
 
        {
794
 
            Log_Print(LOG_ERROR,"Conversion error from '%s' to '%s' (G_CONVERT_ERROR_NO_CONVERSION)",from,to);
795
 
        } else if (error && error->code == G_CONVERT_ERROR_ILLEGAL_SEQUENCE)
796
 
        {
797
 
            Log_Print(LOG_ERROR,"Conversion error from '%s' to '%s' (G_CONVERT_ERROR_ILLEGAL_SEQUENCE)",from,to);
798
 
        } else if (error && error->code == G_CONVERT_ERROR_FAILED)
799
 
        {
800
 
            Log_Print(LOG_ERROR,"Conversion error from '%s' to '%s' (G_CONVERT_ERROR_FAILED)",from,to);
801
 
        } else if (error && error->code == G_CONVERT_ERROR_PARTIAL_INPUT)
802
 
        {
803
 
            Log_Print(LOG_ERROR,"Conversion error from '%s' to '%s' (G_CONVERT_ERROR_PARTIAL_INPUT)",from,to);
804
 
        } else if (error && error->code == G_CONVERT_ERROR_BAD_URI)
805
 
        {
806
 
            Log_Print(LOG_ERROR,"Conversion error from '%s' to '%s' (G_CONVERT_ERROR_BAD_URI)",from,to);
807
 
        } else if (error && error->code == G_CONVERT_ERROR_NOT_ABSOLUTE_PATH)
808
 
        {
809
 
            Log_Print(LOG_ERROR,"Conversion error from '%s' to '%s' (G_CONVERT_ERROR_NOT_ABSOLUTE_PATH)",from,to);
810
 
        } else
811
 
        {
812
 
            Log_Print(LOG_ERROR,"Conversion error from '%s' to '%s' (unknown : %d)",from,to,error->code);
 
708
gchar *
 
709
Charset_Get_Name_From_Title (const gchar *charset_title)
 
710
{
 
711
    guint i;
 
712
 
 
713
    g_return_val_if_fail (charset_title != NULL, NULL);
 
714
 
 
715
    for (i = 0; i < CHARSET_TRANS_ARRAY_LEN; i++)
 
716
    {
 
717
        if (strcasecmp (_(charset_title),
 
718
                        _(charset_trans_array[i].charset_title)) == 0)
 
719
        {
 
720
            return charset_trans_array[i].charset_name;
813
721
        }
 
722
    }
814
723
 
815
 
        if (error)
816
 
            g_error_free(error);*/
817
 
        return FALSE;
818
 
    } else
819
 
    {
820
 
        /*// No error
821
 
        if (error)
822
 
            g_error_free(error);*/
823
 
        g_free(temp);
824
 
        return TRUE;
825
 
    }
 
724
    return NULL;
826
725
}