Mercurial > audlegacy
diff Plugins/Input/mpg123/id3_frame_content.c @ 227:539a0fa7f030 trunk
[svn] Unicode support fixes, based on an XMMS patch written by Ilya Konstantinov. <ikonst@users.sourceforge.net>:
- Fixes UTF16 to UTF8 down-conversion.
- Fixes length management of UTF8 entities.
- Doesn't break ASCII support.
- Corrects several issues with the original implementation.
author | nenolod |
---|---|
date | Fri, 25 Nov 2005 20:23:40 -0800 |
parents | fa848bd484d8 |
children | 08973a746a3e |
line wrap: on
line diff
--- a/Plugins/Input/mpg123/id3_frame_content.c Fri Nov 25 19:54:46 2005 -0800 +++ b/Plugins/Input/mpg123/id3_frame_content.c Fri Nov 25 20:23:40 2005 -0800 @@ -28,6 +28,7 @@ #include <glib.h> #include <glib/gi18n.h> +#include <string.h> #include "xmms-id3.h" @@ -44,95 +45,95 @@ char * id3_get_content(struct id3_frame *frame) { - char *text, *text_beg, *ptr; - char buffer[256]; - int spc = sizeof(buffer) - 1; + gchar *text, *text_it; + + /* Type check */ + if (frame->fr_desc->fd_id != ID3_TCON) + return NULL; - /* Type check */ - if (frame->fr_desc->fd_id != ID3_TCON) - return NULL; + /* Check if frame is compressed */ + if (id3_decompress_frame(frame) == -1) + return NULL; + + ID3_FRAME_DEFINE_CURSOR(frame); - /* Check if frame is compressed */ - if (id3_decompress_frame(frame) == -1) + guint8 encoding; + ID3_FRAME_READ_OR_RETVAL(encoding, NULL); + + text = text_it = id3_string_decode(encoding, cursor, length); + + if (text == NULL) return NULL; - if (*(guint8 *) frame->fr_data == ID3_ENCODING_ISO_8859_1) - text_beg = text = g_strdup((char *) frame->fr_data + 1); - else - text_beg = text = id3_utf16_to_ascii((char *) frame->fr_data + 1); + /* + * Expand ID3v1 genre numbers. + */ + while ((text_it = strstr(text_it, "(")) != NULL) + { + gchar* replace = NULL; + gchar* ref_start = text_it + 1; - /* - * If content is just plain text, return it. - */ - if (text[0] != '(') { - return text; - } + if (*ref_start == ')') + { + /* False alarm */ + ++text_it; + continue; + } + + gsize ref_size = strstr(ref_start, ")") - ref_start; - /* - * Expand ID3v1 genre numbers. - */ - ptr = buffer; - while (text[0] == '(' && text[1] != '(' && spc > 0) { - const char *genre; - int num = 0; - - if (text[1] == 'R' && text[2] == 'X') { - text += 4; - genre = _(" (Remix)"); - if (ptr == buffer) - genre++; - - } - else if (text[1] == 'C' && text[2] == 'R') { - text += 4; - genre = _(" (Cover)"); - if (ptr == buffer) - genre++; + if (strncmp(ref_start, "RX", ref_size) == 0) + { + replace = _("Remix"); + } + else if (strncmp(ref_start, "CR", ref_size) == 0) + { + replace = _("Cover"); + } + else + { + /* Maybe an ID3v1 genre? */ + int genre_number; + gchar* genre_number_str = g_strndup(ref_start, ref_size); + if (sscanf(genre_number_str, "%d", &genre_number) > 0) + { + /* Boundary check */ + if (genre_number >= sizeof(mpg123_id3_genres) / sizeof(char *)) + continue; - } - else { - /* Get ID3v1 genre number */ - text++; - while (*text != ')') { - num *= 10; - num += *text++ - '0'; - } - text++; + replace = gettext(mpg123_id3_genres[genre_number]); + } + } - /* Boundary check */ - if (num >= sizeof(mpg123_id3_genres) / sizeof(char *)) - continue; - - genre = gettext(mpg123_id3_genres[num]); - - if (ptr != buffer && spc-- > 0) - *ptr++ = '/'; - } + if (replace != NULL) + { + /* Amazingly hairy code to replace a part of the original genre string + with 'replace'. */ + gchar* copy = g_malloc(strlen(text) - ref_size + strlen(replace) + 1); + gsize pos = 0; + gsize copy_size; - /* Expand string into buffer */ - while (*genre != '\0' && spc > 0) { - *ptr++ = *genre++; - spc--; - } - } + /* Copy the part before the replaced part */ + copy_size = ref_start - text; + memcpy(copy + pos, text, copy_size); + pos += copy_size; + /* Copy the replacement instead of the original reference */ + copy_size = strlen(replace); + memcpy(copy + pos, replace, copy_size); + pos += copy_size; + /* Copy the rest, including the null */ + memcpy(copy + pos, ref_start + ref_size, strlen(ref_start + ref_size)+1); - /* - * Add plaintext refinement. - */ - if (*text == '(') - text++; - if (*text != '\0' && ptr != buffer && spc-- > 0) - *ptr++ = ' '; - while (*text != '\0' && spc > 0) { - *ptr++ = *text++; - spc--; - } - *ptr = '\0'; + /* Put into original variables */ + gsize offset = text_it - text; + g_free(text); + text = copy; + text_it = text + offset; + } - g_free(text_beg); + ++text_it; + } - /* - * Return the expanded content string. - */ - return g_strdup(buffer); + return text; + }