aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/list.c32
-rw-r--r--src/list.h4
-rw-r--r--src/player.c1
-rw-r--r--src/song.c2
-rw-r--r--src/tag.c47
-rw-r--r--src/tag.h2
-rw-r--r--src/tagTracker.c50
-rw-r--r--src/tagTracker.h10
9 files changed, 106 insertions, 44 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 98a5412fe..8b1f3d1f6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -51,6 +51,7 @@ mpd_headers = \
song.h \
stats.h \
tag.h \
+ tagTracker.h \
utf8.h \
utils.h \
volume.h
@@ -93,6 +94,7 @@ mpd_SOURCES = \
song.c \
stats.c \
tag.c \
+ tagTracker.c \
utils.c \
volume.c \
utf8.c
diff --git a/src/list.c b/src/list.c
index c7d49397a..dad4093e6 100644
--- a/src/list.c
+++ b/src/list.c
@@ -104,7 +104,7 @@ int insertInListBeforeNode(List * list, ListNode * beforeNode, char * key,
return 1;
}
-int insertInList(List * list,char * key,void * data) {
+ListNode * insertInList(List * list,char * key,void * data) {
ListNode * node;
assert(list!=NULL);
@@ -137,7 +137,7 @@ int insertInList(List * list,char * key,void * data) {
list->numberOfNodes++;
- return 1;
+ return node;
}
int insertInListWithoutKey(List * list, void * data) {
@@ -173,7 +173,7 @@ int insertInListWithoutKey(List * list, void * data) {
return 1;
}
-int findInList(List * list,char * key,void ** data) {
+ListNode * findNodeInList(List * list, char * key) {
static long high;
static long low;
static long cur;
@@ -191,10 +191,7 @@ int findInList(List * list,char * key,void ** data) {
cur = (high+low)/2;
tmpNode = list->nodesArray[cur];
cmp = strcmp(tmpNode->key,key);
- if(cmp==0) {
- if(data) *data = tmpNode->data;
- return 1;
- }
+ if(cmp==0) return tmpNode;
else if(cmp>0) high = cur;
else {
if(low==cur) break;
@@ -205,10 +202,7 @@ int findInList(List * list,char * key,void ** data) {
cur = high;
if(cur>=0) {
tmpNode = list->nodesArray[cur];
- if(strcmp(tmpNode->key,key)==0) {
- (*data) = tmpNode->data;
- return 1;
- }
+ if(strcmp(tmpNode->key,key)==0) return tmpNode;
}
}
else {
@@ -218,10 +212,18 @@ int findInList(List * list,char * key,void ** data) {
tmpNode = tmpNode->nextNode;
}
- if(tmpNode!=NULL) {
- (*data) = tmpNode->data;
- return 1;
- }
+ if(tmpNode!=NULL) return tmpNode;
+ }
+
+ return NULL;
+}
+
+int findInList(List * list, char * key, void ** data) {
+ ListNode * node = findNodeInList(list, key);
+
+ if(node) {
+ if(data) *data = node->data;
+ return 1;
}
return 0;
diff --git a/src/list.h b/src/list.h
index 4653237f0..86f4a239a 100644
--- a/src/list.h
+++ b/src/list.h
@@ -67,7 +67,7 @@ List * makeList(ListFreeDataFunc * freeDataFunc);
* _data_ -> data to be inserted in list
* returns 1 if successful, 0 otherwise
*/
-int insertInList(List * list,char * key,void * data);
+ListNode * insertInList(List * list,char * key,void * data);
int insertInListBeforeNode(List * list, ListNode * beforeNode, char * key,
void * data);
@@ -93,6 +93,8 @@ void deleteNodeFromList(List * list,ListNode * node);
*/
int findInList(List * list, char * key, void ** data);
+ListNode * findNodeInList(List * list, char * key);
+
/* frees memory malloc'd for list and its nodes
* _list_ -> List to be free'd
*/
diff --git a/src/player.c b/src/player.c
index 8f217b091..5b8298970 100644
--- a/src/player.c
+++ b/src/player.c
@@ -478,7 +478,6 @@ Song * playerCurrentDecodeSong() {
song = newNullSong();
song->utf8url = strdup(pc->currentUrl);
song->tag = metadataChunkToMpdTagDup(prev);
- validateUtf8Tag(song->tag);
ret = song;
resetPlayerMetadata();
}
diff --git a/src/song.c b/src/song.c
index 85a49ecbb..462a434cc 100644
--- a/src/song.c
+++ b/src/song.c
@@ -59,7 +59,6 @@ Song * newSong(char * utf8url, SONG_TYPE type) {
if((plugin = isMusic(utf8url,&(song->mtime)))) {
song->tag = plugin->tagDupFunc(
rmp2amp(utf8ToFsCharset(utf8url)));
- if(song->tag) validateUtf8Tag(song->tag);
}
if(!song->tag || song->tag->time<0) {
freeSong(song);
@@ -267,7 +266,6 @@ int updateSongInfo(Song * song) {
if((plugin = isMusic(utf8url,&(song->mtime)))) {
song->tag = plugin->tagDupFunc(
rmp2amp(utf8ToFsCharset(utf8url)));
- if(song->tag) validateUtf8Tag(song->tag);
}
if(!song->tag || song->tag->time<0) return -1;
}
diff --git a/src/tag.c b/src/tag.c
index 7a8dcada4..b076859f0 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -25,6 +25,7 @@
#include "inputStream.h"
#include "conf.h"
#include "charConv.h"
+#include "tagTracker.h"
#include <sys/stat.h>
#include <stdlib.h>
@@ -62,25 +63,6 @@ void printMpdTag(FILE * fp, MpdTag * tag) {
}
}
-#define fixUtf8(str) { \
- if(str && !validUtf8String(str)) { \
- char * temp; \
- DEBUG("not valid utf8 in tag: %s\n",str); \
- temp = latin1StrToUtf8Dup(str); \
- free(str); \
- str = temp; \
- } \
-}
-
-void validateUtf8Tag(MpdTag * tag) {
- int i;
-
- for(i = 0; i < tag->numOfItems; i++) {
- fixUtf8(tag->items[i].value);
- stripReturnChar(tag->items[i].value);
- }
-}
-
#ifdef HAVE_ID3TAG
MpdTag * getID3Info(struct id3_tag * tag, char * id, int type, MpdTag * mpdTag)
{
@@ -172,6 +154,8 @@ MpdTag * newMpdTag() {
static void deleteItem(MpdTag * tag, int index) {
tag->numOfItems--;
+ removeTagItemString(tag->items[index].type, tag->items[index].value);
+
if(tag->numOfItems-index > 0) {
memmove(tag->items+index, tag->items+index+1,
tag->numOfItems-index);
@@ -203,7 +187,7 @@ void clearMpdTag(MpdTag * tag) {
int i;
for(i = 0; i < tag->numOfItems; i++) {
- free(tag->items[i].value);
+ removeTagItemString(tag->items[i].type, tag->items[i].value);
}
if(tag->items) free(tag->items);
@@ -255,18 +239,35 @@ int mpdTagsAreEqual(MpdTag * tag1, MpdTag * tag2) {
return 1;
}
+#define fixUtf8(str) { \
+ if(str && !validUtf8String(str)) { \
+ char * temp; \
+ DEBUG("not valid utf8 in tag: %s\n",str); \
+ temp = latin1StrToUtf8Dup(str); \
+ free(str); \
+ str = temp; \
+ } \
+}
+
inline static void appendToTagItems(MpdTag * tag, int type, char * value,
int len)
{
int i = tag->numOfItems;
+ char * temp;
+ temp = malloc(len+1);
+ strncpy(temp, value, len);
+ temp[len] = '\0';
+
+ fixUtf8(temp);
+
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';
+ tag->items[i].value = getTagItemString(type, value);
+
+ free(temp);
}
void addItemToMpdTagWithLen(MpdTag * tag, int itemType, char * value, int len) {
diff --git a/src/tag.h b/src/tag.h
index 557b979b5..856142bd5 100644
--- a/src/tag.h
+++ b/src/tag.h
@@ -80,8 +80,6 @@ void printMpdTag(FILE * fp, MpdTag * tag);
MpdTag * mpdTagDup(MpdTag * tag);
-void validateUtf8Tag(MpdTag * tag);
-
int mpdTagsAreEqual(MpdTag * tag1, MpdTag * tag2);
/* *last shoudl be initialzed to -1 before calling this function */
diff --git a/src/tagTracker.c b/src/tagTracker.c
new file mode 100644
index 000000000..fec96550a
--- /dev/null
+++ b/src/tagTracker.c
@@ -0,0 +1,50 @@
+#include "tagTracker.h"
+
+#include "list.h"
+
+static List * tagLists[TAG_NUM_OF_ITEM_TYPES] =
+{
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+char * getTagItemString(int type, char * string) {
+ ListNode * node;
+
+ if(tagLists[type] == NULL) {
+ tagLists[type] = makeList(NULL);
+ }
+
+ if((node = findNodeInList(tagLists[type], string))) {
+ (*((int *)node->data))++;
+ }
+ else {
+ int * intPtr = malloc(sizeof(int));
+ *intPtr = 1;
+ node = insertInList(tagLists[type], string, intPtr);
+ }
+
+ return node->key;
+}
+
+void removeTagItemString(int type, char * string) {
+ ListNode * node;
+
+ if(tagLists[type] == NULL) return;
+
+ if((node = findNodeInList(tagLists[type], string))) {
+ int * countPtr = node->data;
+ *countPtr--;
+ if(*countPtr <= 0) deleteNodeFromList(tagLists[type], node);
+ }
+
+ if(tagLists[type]->numberOfNodes == 0) {
+ freeList(tagLists[type]);
+ tagLists[type] = NULL;
+ }
+}
diff --git a/src/tagTracker.h b/src/tagTracker.h
new file mode 100644
index 000000000..c30185e2b
--- /dev/null
+++ b/src/tagTracker.h
@@ -0,0 +1,10 @@
+#ifndef TAG_TRACKER_H
+#define TAG_TRACKER_H
+
+#include "tag.h"
+
+char * getTagItemString(int type, char * string);
+
+void removeTagItemString(int type, char * string);
+
+#endif