diff options
Diffstat (limited to 'tag.c')
-rw-r--r-- | tag.c | 72 |
1 files changed, 72 insertions, 0 deletions
@@ -0,0 +1,72 @@ +#include "tag.h" + +#include <id3tag.h> + +static void tag_add(struct tag *tag, enum tag_type type, const gchar *value) { + struct tag_field *field = g_new0(struct tag_field, 1); + if(field == 0) { + g_error("tag_add: g_new0 returned NULL"); + } + + field->type = type; + field->string = g_strdup(value); + tag->fields = g_slist_prepend(tag->fields, field); +} + +static void tag_add_string(struct tag *tag, struct id3_tag *id3tag, + enum tag_type type, const gchar *id) { + struct id3_frame *frame = id3_tag_findframe(id3tag, id, 0); + + if(frame == NULL) { + return; + } + + if(frame->nfields != 2) { + g_debug("unexpected nfields value"); + return; + } + + const union id3_field *field = id3_frame_field(frame, 1); + guint nstrings = id3_field_getnstrings(field); + + for(guint i = 0; i < nstrings; i++) { + const id3_ucs4_t *ucs4 = id3_field_getstrings(field, i); + + if(ucs4 == NULL) { + g_warning("ucs4 is NULL"); + continue; + } + + id3_utf8_t *utf8 = id3_ucs4_utf8duplicate(ucs4); + tag_add(tag, type, (gchar*)utf8); + g_free(utf8); + } +} + +/* TODO: support other tag formats beside ID3 */ +struct tag *tag_read(const gchar *path) { + struct id3_file *file = id3_file_open(path, ID3_FILE_MODE_READONLY); + + if(file == NULL) { + g_warning("file is NULL"); + return NULL; + } + + struct id3_tag *id3tag = id3_file_tag(file); + + if(id3tag == NULL) { + g_debug("tag is NULL"); + return NULL; + } + + struct tag *tag = g_new0(struct tag, 1); + + /* TODO: add more interesting data */ + tag_add_string(tag, id3tag, TAG_TYPE_ARTIST, ID3_FRAME_ARTIST); + tag_add_string(tag, id3tag, TAG_TYPE_ALBUM, ID3_FRAME_ALBUM); + tag_add_string(tag, id3tag, TAG_TYPE_TITLE, ID3_FRAME_TITLE); + + id3_file_close(file); + + return tag; +} |