summaryrefslogtreecommitdiff
path: root/tag.c
diff options
context:
space:
mode:
Diffstat (limited to 'tag.c')
-rw-r--r--tag.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/tag.c b/tag.c
new file mode 100644
index 0000000..ca56106
--- /dev/null
+++ b/tag.c
@@ -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;
+}