aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWarren Dukes <warren.dukes@gmail.com>2004-11-10 01:09:03 +0000
committerWarren Dukes <warren.dukes@gmail.com>2004-11-10 01:09:03 +0000
commit92a75471505391edd2f8f9af23188b4f7b17bbcb (patch)
tree7cf738d5c40637942fe09c6a2edd98e34314ad5b
parent598db0d296a8c16e181b488040a324f9ae20cc33 (diff)
downloadmpd-92a75471505391edd2f8f9af23188b4f7b17bbcb.tar.gz
mpd-92a75471505391edd2f8f9af23188b4f7b17bbcb.tar.xz
mpd-92a75471505391edd2f8f9af23188b4f7b17bbcb.zip
begining of metadata rewrite:
now we support genre and date metadata, along with multiple metadata entries for each type git-svn-id: https://svn.musicpd.org/mpd/branches/r2562-metadata-handling-rewrite@2567 09075e82-0dd4-0310-85a5-a0d7c8717e4f
-rw-r--r--src/audioOutputs/audioOutput_shout.c16
-rw-r--r--src/directory.c20
-rw-r--r--src/song.c3
-rw-r--r--src/tag.c141
-rw-r--r--src/tag.h11
5 files changed, 127 insertions, 64 deletions
diff --git a/src/audioOutputs/audioOutput_shout.c b/src/audioOutputs/audioOutput_shout.c
index 7f21a73f4..661acd07d 100644
--- a/src/audioOutputs/audioOutput_shout.c
+++ b/src/audioOutputs/audioOutput_shout.c
@@ -375,22 +375,20 @@ static void myShout_closeDevice(AudioOutput * audioOutput) {
static void copyTagToVorbisComment(ShoutData * sd) {
if(sd->tag) {
- MpdTagItem * item = sd->tag->tagItems;
-
- while(item && item->type!=TAG_ITEM_END) {
- switch(item->type) {
+ int i;
+
+ for(i = 0; i < sd->tag->numOfItems; i++) {
+ switch(sd->tag->items[i].type) {
case TAG_ITEM_ARTIST:
- addTag("ARTIST", item->value);
+ addTag("ARTIST", sd->tag->items[i].value);
break;
case TAG_ITEM_ALBUM:
- addTag("ALBUM", item->value);
+ addTag("ALBUM", sd->tag->items[i].value);
break;
case TAG_ITEM_TITLE:
- addTag("TITLE", item->value);
+ addTag("TITLE", sd->tag->items[i].value);
break;
}
-
- item++;
}
}
}
diff --git a/src/directory.c b/src/directory.c
index 0fa5e85f6..5ac94c534 100644
--- a/src/directory.c
+++ b/src/directory.c
@@ -1189,17 +1189,15 @@ int printSongInDirectory(FILE * fp, Song * song, void * data) {
}
static inline int strstrSearchTag(Song * song, int type, char * str) {
- MpdTagItem * item;
+ int i;
char * dup;
if(!song->tag) return 0;
- for(item = song->tag->tagItems; item && item->type!=TAG_ITEM_END;
- item++)
- {
- if(item->type != type) continue;
+ for(i = 0; i < song->tag->numOfItems; i++) {
+ if(song->tag->items[i].type != type) continue;
- dup = strDupToUpper(item->value);
+ dup = strDupToUpper(song->tag->items[i].value);
if(strstr(dup, str)) return 1;
free(dup);
}
@@ -1263,16 +1261,14 @@ int searchForSongsIn(FILE * fp, char * name, char * item, char * string) {
}
static inline int tagItemFoundAndMatches(Song * song, int type, char * str) {
- MpdTagItem * item;
+ int i;
if(!song->tag) return 0;
- for(item = song->tag->tagItems; item && item->type != TAG_ITEM_END;
- item++)
- {
- if(item->type != type) continue;
+ for(i = 0; i < song->tag->numOfItems; i++) {
+ if(song->tag->items[i].type != type) continue;
- if( 0 == strcmp(str, item->value)) return 1;
+ if(0 == strcmp(str, song->tag->items[i].value)) return 1;
}
return 0;
diff --git a/src/song.c b/src/song.c
index 3d8ef4769..85a49ecbb 100644
--- a/src/song.c
+++ b/src/song.c
@@ -187,6 +187,7 @@ static int matchesAnMpdTagItemKey(char * buffer, int * itemType) {
if( 0 == strncmp(mpdTagItemKeys[i], buffer,
strlen(mpdTagItemKeys[i])))
{
+ *itemType = i;
return 1;
}
}
@@ -225,7 +226,7 @@ void readSongInfoIntoList(FILE * fp, SongList * list) {
else if(matchesAnMpdTagItemKey(buffer, &itemType)) {
if(!song->tag) song->tag = newMpdTag();
addItemToMpdTag(song->tag, itemType,
- &(buffer[strlen(mpdTagItemKeys[itemType])]));
+ &(buffer[strlen(mpdTagItemKeys[itemType])+2]));
}
else if(0==strncmp(SONG_TIME,buffer,strlen(SONG_TIME))) {
if(!song->tag) song->tag = newMpdTag();
diff --git a/src/tag.c b/src/tag.c
index 8b365f85f..7a8dcada4 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -40,7 +40,7 @@
#include <FLAC/metadata.h>
#endif
-char * mpdTagItemsKeys[TAG_NUM_OF_ITEM_TYPES] =
+char * mpdTagItemKeys[TAG_NUM_OF_ITEM_TYPES] =
{
"Artist",
"Album",
@@ -52,14 +52,14 @@ char * mpdTagItemsKeys[TAG_NUM_OF_ITEM_TYPES] =
};
void printMpdTag(FILE * fp, MpdTag * tag) {
- MpdTagItem * item;
-
- for(item = tag->tagItems; item && item->type!=TAG_ITEM_END; item++) {
- myfprintf(fp, "%s: %s\n", mpdTagItemKeys[item->type],
- item->value);
- }
+ int i;
if(tag->time>=0) myfprintf(fp,"Time: %i\n",tag->time);
+
+ for(i = 0; i < tag->numOfItems; i++) {
+ myfprintf(fp, "%s: %s\n", mpdTagItemKeys[tag->items[i].type],
+ tag->items[i].value);
+ }
}
#define fixUtf8(str) { \
@@ -73,12 +73,11 @@ void printMpdTag(FILE * fp, MpdTag * tag) {
}
void validateUtf8Tag(MpdTag * tag) {
- MpdTagItem * item = tag->tagItems;
+ int i;
- while(item && item->type != TAG_ITEM_END) {
- fixUtf8(item->value);
- stripReturnChar(item->value);
- item++;
+ for(i = 0; i < tag->numOfItems; i++) {
+ fixUtf8(tag->items[i].value);
+ stripReturnChar(tag->items[i].value);
}
}
@@ -93,14 +92,13 @@ MpdTag * getID3Info(struct id3_tag * tag, char * id, int type, MpdTag * mpdTag)
int i;
frame = id3_tag_findframe(tag, id, 0);
- if(!frame) return NULL;
+ if(!frame) return mpdTag;
field = &frame->fields[1];
nstrings = id3_field_getnstrings(field);
- if(nstrings<1) return NULL;
for(i = 0; i < nstrings; i++) {
- ucs4 = id3_field_getstrings(field,0);
+ ucs4 = id3_field_getstrings(field, i);
assert(ucs4);
if(type == TAG_ITEM_GENRE) {
@@ -110,8 +108,10 @@ MpdTag * getID3Info(struct id3_tag * tag, char * id, int type, MpdTag * mpdTag)
utf8 = id3_ucs4_utf8duplicate(ucs4);
if(!utf8) continue;
- if( NULL == mpdTag ) mpdTag == newMpdTag();
- addItemToMpdTag(mpdTag, type, utf8);
+ if(strlen(utf8)) {
+ if( NULL == mpdTag ) mpdTag = newMpdTag();
+ addItemToMpdTag(mpdTag, type, utf8);
+ }
free(utf8);
}
@@ -163,20 +163,55 @@ MpdTag * id3Dup(char * file) {
MpdTag * newMpdTag() {
MpdTag * ret = malloc(sizeof(MpdTag));
- ret->tagItems = NULL;
+ ret->items = NULL;
ret->time = -1;
+ ret->numOfItems = 0;
return ret;
}
+static void deleteItem(MpdTag * tag, int index) {
+ tag->numOfItems--;
+
+ if(tag->numOfItems-index > 0) {
+ memmove(tag->items+index, tag->items+index+1,
+ tag->numOfItems-index);
+ }
+
+ if(tag->numOfItems > 0) {
+ tag->items = realloc(tag->items,
+ tag->numOfItems*sizeof(MpdTagItem));
+ }
+ else {
+ free(tag->items);
+ tag->items = NULL;
+ }
+}
+
+void clearItemsFromMpdTag(MpdTag * tag, int type) {
+ int i = 0;
+
+ for(i = 0; i < tag->numOfItems; i++) {
+ if(tag->items[i].type == type) {
+ deleteItem(tag, i);
+ /* decrement since when just deleted this node */
+ i--;
+ }
+ }
+}
+
void clearMpdTag(MpdTag * tag) {
- MpdTagItem * item;
+ int i;
- for(item = tag->tagItems; item && item->type != TAG_ITEM_END; item++) {
- free(item->value);
+ for(i = 0; i < tag->numOfItems; i++) {
+ free(tag->items[i].value);
}
- if(tag->tagItems) free(tag->tagItems);
- tag->tagItems = NULL;
+ if(tag->items) free(tag->items);
+ tag->items = NULL;
+
+ tag->numOfItems = 0;
+
+ tag->time = -1;
}
void freeMpdTag(MpdTag * tag) {
@@ -186,40 +221,70 @@ void freeMpdTag(MpdTag * tag) {
MpdTag * mpdTagDup(MpdTag * tag) {
MpdTag * ret = NULL;
- MpdTagItem * item;
+ int i;
if(!tag) return NULL;
ret = newMpdTag();
ret->time = tag->time;
- for(item = tag->tagItems; item && item->type != TAG_ITEM_END; item++) {
- addItemToMpdTag(ret, item->type, item->value);
+ for(i = 0; i < tag->numOfItems; i++) {
+ addItemToMpdTag(ret, tag->items[i].type, tag->items[i].value);
}
return ret;
}
int mpdTagsAreEqual(MpdTag * tag1, MpdTag * tag2) {
- MpdTagItem * item1;
- MpdTagItem * item2;
+ int i;
if(tag1 == NULL && tag2 == NULL) return 1;
else if(!tag1 || !tag2) return 0;
if(tag1->time != tag2->time) return 0;
- for(item1 = tag1->tagItems, item2 = tag2->tagItems;
- item1 && item1->type != TAG_ITEM_END;
- item1++, item2++)
- {
- if(!item2) return 0;
- if(item1->type != item2->type) return 0;
- if(0 == strcmp(item1->value, item2->value)) return 0;
- }
+ if(tag1->numOfItems != tag2->numOfItems) return 0;
- if(item2 && !item1) return 0;
- if(item2->type != item1->type) return 0;
+ for(i = 0; i < tag1->numOfItems; i++) {
+ if(tag1->items[i].type != tag2->items[i].type) return 0;
+ if(strcmp(tag1->items[i].value, tag2->items[i].value)) {
+ return 0;
+ }
+ }
return 1;
}
+
+inline static void appendToTagItems(MpdTag * tag, int type, char * value,
+ int len)
+{
+ int i = tag->numOfItems;
+
+ tag->numOfItems++;
+ tag->items = realloc(tag->items, tag->numOfItems*sizeof(MpdTagItem));
+
+ tag->items[i].type = type;
+ tag->items[i].value = malloc(len+1);
+ strncpy(tag->items[i].value, value, len);
+ tag->items[i].value[len] = '\0';
+}
+
+void addItemToMpdTagWithLen(MpdTag * tag, int itemType, char * value, int len) {
+ appendToTagItems(tag, itemType, value, len);
+}
+
+char * getNextItemFromMpdTag(MpdTag * tag, int itemType, int * last) {
+ int i = 0;
+
+ if(last && *last >=0) i = *last+1;
+
+ for(i = 0; i < tag->numOfItems; i++) {
+ if(itemType == tag->items[i].type) {
+ if(last) *last = i;
+ return tag->items[i].value;
+ }
+ i++;
+ }
+
+ return NULL;
+}
diff --git a/src/tag.h b/src/tag.h
index 7905e92a8..557b979b5 100644
--- a/src/tag.h
+++ b/src/tag.h
@@ -23,6 +23,8 @@
#include "mpd_types.h"
+#include <string.h>
+
#include <stdio.h>
#ifdef HAVE_ID3TAG
#ifdef USE_MPD_ID3TAG
@@ -32,7 +34,6 @@
#endif
#endif
-#define TAG_ITEM_END -1
#define TAG_ITEM_ARTIST 0
#define TAG_ITEM_ALBUM 1
#define TAG_ITEM_TITLE 2
@@ -52,7 +53,8 @@ typedef struct _MpdTagItem {
typedef struct _MpdTag {
int time;
- MpdTagItem * tagItems;
+ MpdTagItem * items;
+ mpd_uint8 numOfItems;
} MpdTag;
#ifdef HAVE_ID3TAG
@@ -69,10 +71,11 @@ void clearMpdTag(MpdTag * tag);
void freeMpdTag(MpdTag * tag);
-void addItemToMpdTag(MpdTag * tag, int itemType, char * value);
-
void addItemToMpdTagWithLen(MpdTag * tag, int itemType, char * value, int len);
+#define addItemToMpdTag(tag, itemType, value) \
+ addItemToMpdTagWithLen(tag, itemType, value, strlen(value))
+
void printMpdTag(FILE * fp, MpdTag * tag);
MpdTag * mpdTagDup(MpdTag * tag);