1.1 --- a/decoder.c Wed Feb 04 19:34:25 2009 +0800
1.2 +++ b/decoder.c Thu Feb 12 20:47:23 2009 +0800
1.3 @@ -1,7 +1,7 @@
1.4 /*
1.5 * MP3/MPlayer plugin to VDR (C++)
1.6 *
1.7 - * (C) 2001-2007 Stefan Huelswitt <s.huelswitt@gmx.de>
1.8 + * (C) 2001-2009 Stefan Huelswitt <s.huelswitt@gmx.de>
1.9 *
1.10 * This code is free software; you can redistribute it and/or
1.11 * modify it under the terms of the GNU General Public License
1.12 @@ -53,6 +53,35 @@
1.13 return h;
1.14 }
1.15
1.16 +// --- cStrConv ----------------------------------------------------------------
1.17 +
1.18 +class cStrConv : private cMutex {
1.19 +private:
1.20 + cCharSetConv toSys;
1.21 +public:
1.22 + cStrConv(void):toSys("UTF-8",cCharSetConv::SystemCharacterTable()) {}
1.23 + char *ToSys(char *from);
1.24 + };
1.25 +
1.26 +static cStrConv *strconv;
1.27 +
1.28 +char *cStrConv::ToSys(char *from)
1.29 +{
1.30 + if(from) {
1.31 + Lock();
1.32 + const char *r=toSys.Convert(from);
1.33 + Unlock();
1.34 + if(r!=from) {
1.35 + char *n=strdup(r);
1.36 + if(n) {
1.37 + free(from);
1.38 + return n;
1.39 + }
1.40 + }
1.41 + }
1.42 + return from;
1.43 +}
1.44 +
1.45 // --- cSongInfo ---------------------------------------------------------------
1.46
1.47 cSongInfo::cSongInfo(void)
1.48 @@ -75,12 +104,18 @@
1.49 free(Album); Album=0;
1.50 Year=-1;
1.51 Level=Peak=0.0;
1.52 - infoDone=false;
1.53 -}
1.54 -
1.55 -void cSongInfo::Set(cSongInfo *si)
1.56 -{
1.57 - Clear(); InfoDone();
1.58 + infoDone=false; utf8clean=true;
1.59 +}
1.60 +
1.61 +void cSongInfo::Set(cSongInfo *si, bool update)
1.62 +{
1.63 + if(!update || si->Utf8Clean()) {
1.64 + Clear();
1.65 + Title=si->Title ? strdup(si->Title):0;
1.66 + Artist=si->Artist ? strdup(si->Artist):0;
1.67 + Album=si->Album ? strdup(si->Album):0;
1.68 + utf8clean=si->utf8clean;
1.69 + }
1.70 Frames=si->Frames;
1.71 Total=si->Total;
1.72 SampleFreq=si->SampleFreq;
1.73 @@ -89,14 +124,12 @@
1.74 MaxBitrate=si->MaxBitrate;
1.75 ChMode=si->ChMode;
1.76 Year=si->Year;
1.77 - Title=si->Title ? strdup(si->Title):0;
1.78 - Artist=si->Artist ? strdup(si->Artist):0;
1.79 - Album=si->Album ? strdup(si->Album):0;
1.80 if(si->Level>0.0) { // preserve old level
1.81 Level=si->Level;
1.82 Peak=si->Peak;
1.83 }
1.84 DecoderID=si->DecoderID;
1.85 + InfoDone();
1.86 }
1.87
1.88 void cSongInfo::FakeTitle(const char *filename, const char *extention)
1.89 @@ -121,6 +154,16 @@
1.90 }
1.91 }
1.92
1.93 +void cSongInfo::ConvertToSys(void)
1.94 +{
1.95 + if(cCharSetConv::SystemCharacterTable()) {
1.96 + Title=strconv->ToSys(Title);
1.97 + Artist=strconv->ToSys(Artist);
1.98 + Album=strconv->ToSys(Album);
1.99 + utf8clean=false;
1.100 + }
1.101 +}
1.102 +
1.103 // --- cFileInfo ---------------------------------------------------------------
1.104
1.105 cFileInfo::cFileInfo(void)
1.106 @@ -349,8 +392,18 @@
1.107 return false;
1.108 }
1.109
1.110 +bool cCacheData::Check8bit(const char *str)
1.111 +{
1.112 + if(str) while(*str) if(*str++ & 0x80) return true;
1.113 + return false;
1.114 +}
1.115 +
1.116 bool cCacheData::Upgrade(void)
1.117 {
1.118 + if(version<8) {
1.119 + if(Check8bit(Title) || Check8bit(Artist) || Check8bit(Album))
1.120 + return false; // Trash entries not 7bit clean
1.121 + }
1.122 if(version<7) {
1.123 if(DecoderID==DEC_SND || (Title && startswith(Title,"track-")))
1.124 return false; // Trash older SND entries (incomplete)
1.125 @@ -372,10 +425,10 @@
1.126 return true;
1.127 }
1.128
1.129 -void cCacheData::Create(cFileInfo *fi, cSongInfo *si)
1.130 +void cCacheData::Create(cFileInfo *fi, cSongInfo *si, bool update)
1.131 {
1.132 cFileInfo::Set(fi);
1.133 - cSongInfo::Set(si);
1.134 + cSongInfo::Set(si,update);
1.135 hash=MakeHash(Filename);
1.136 Touch();
1.137 }
1.138 @@ -472,14 +525,14 @@
1.139 lock.Lock();
1.140 cCacheData *dat=Search(file);
1.141 if(dat) {
1.142 - dat->Create(file,info);
1.143 + dat->Create(file,info,true);
1.144 Modified();
1.145 dat->Unlock();
1.146 d(printf("cache: updating infos for %s\n",file->Filename))
1.147 }
1.148 else {
1.149 dat=new cCacheData;
1.150 - dat->Create(file,info);
1.151 + dat->Create(file,info,false);
1.152 AddEntry(dat);
1.153 d(printf("cache: caching infos for %s\n",file->Filename))
1.154 }
1.155 @@ -601,6 +654,8 @@
1.156
1.157 void cInfoCache::Load(void)
1.158 {
1.159 + if(!strconv) strconv=new cStrConv;
1.160 +
1.161 char *name=CacheFile();
1.162 if(access(name,F_OK)==0) {
1.163 isyslog("loading id3 cache from %s",name);