1 /***************************************************************************
2     copyright            : (C) 2003 by Scott Wheeler
3     email                : wheeler@kde.org
4  ***************************************************************************/
5 
6 /***************************************************************************
7  *   This library is free software; you can redistribute it and/or modify  *
8  *   it  under the terms of the GNU Lesser General Public License version  *
9  *   2.1 as published by the Free Software Foundation.                     *
10  *                                                                         *
11  *   This library is distributed in the hope that it will be useful, but   *
12  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
14  *   Lesser General Public License for more details.                       *
15  *                                                                         *
16  *   You should have received a copy of the GNU Lesser General Public      *
17  *   License along with this library; if not, write to the Free Software   *
18  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
19  *   USA                                                                   *
20  ***************************************************************************/
21 
22 #ifdef HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25 
26 #include <stdlib.h>
27 #include <fileref.h>
28 #include <tfile.h>
29 #include <asffile.h>
30 #include <vorbisfile.h>
31 #include <mpegfile.h>
32 #include <flacfile.h>
33 #include <oggflacfile.h>
34 #include <mpcfile.h>
35 #include <wavpackfile.h>
36 #include <speexfile.h>
37 #include <trueaudiofile.h>
38 #include <mp4file.h>
39 #include <tag.h>
40 #include <string.h>
41 #include <id3v2framefactory.h>
42 
43 #include "tag_c.h"
44 
45 using namespace TagLib;
46 
47 namespace
48 {
49   List<char *> strings;
50   bool unicodeStrings = true;
51   bool stringManagementEnabled = true;
52 
stringToCharArray(const String & s)53   char *stringToCharArray(const String &s)
54   {
55     const std::string str = s.to8Bit(unicodeStrings);
56 
57 #ifdef HAVE_ISO_STRDUP
58 
59     return ::_strdup(str.c_str());
60 
61 #else
62 
63     return ::strdup(str.c_str());
64 
65 #endif
66   }
67 
charArrayToString(const char * s)68   String charArrayToString(const char *s)
69   {
70     return String(s, unicodeStrings ? String::UTF8 : String::Latin1);
71   }
72 }
73 
taglib_set_strings_unicode(BOOL unicode)74 void taglib_set_strings_unicode(BOOL unicode)
75 {
76   unicodeStrings = (unicode != 0);
77 }
78 
taglib_set_string_management_enabled(BOOL management)79 void taglib_set_string_management_enabled(BOOL management)
80 {
81   stringManagementEnabled = (management != 0);
82 }
83 
taglib_free(void * pointer)84 void taglib_free(void* pointer)
85 {
86   free(pointer);
87 }
88 
89 ////////////////////////////////////////////////////////////////////////////////
90 // TagLib::File wrapper
91 ////////////////////////////////////////////////////////////////////////////////
92 
taglib_file_new(const char * filename)93 TagLib_File *taglib_file_new(const char *filename)
94 {
95   return reinterpret_cast<TagLib_File *>(FileRef::create(filename));
96 }
97 
taglib_file_new_type(const char * filename,TagLib_File_Type type)98 TagLib_File *taglib_file_new_type(const char *filename, TagLib_File_Type type)
99 {
100   switch(type) {
101   case TagLib_File_MPEG:
102     return reinterpret_cast<TagLib_File *>(new MPEG::File(filename));
103   case TagLib_File_OggVorbis:
104     return reinterpret_cast<TagLib_File *>(new Ogg::Vorbis::File(filename));
105   case TagLib_File_FLAC:
106     return reinterpret_cast<TagLib_File *>(new FLAC::File(filename));
107   case TagLib_File_MPC:
108     return reinterpret_cast<TagLib_File *>(new MPC::File(filename));
109   case TagLib_File_OggFlac:
110     return reinterpret_cast<TagLib_File *>(new Ogg::FLAC::File(filename));
111   case TagLib_File_WavPack:
112     return reinterpret_cast<TagLib_File *>(new WavPack::File(filename));
113   case TagLib_File_Speex:
114     return reinterpret_cast<TagLib_File *>(new Ogg::Speex::File(filename));
115   case TagLib_File_TrueAudio:
116     return reinterpret_cast<TagLib_File *>(new TrueAudio::File(filename));
117   case TagLib_File_MP4:
118     return reinterpret_cast<TagLib_File *>(new MP4::File(filename));
119   case TagLib_File_ASF:
120     return reinterpret_cast<TagLib_File *>(new ASF::File(filename));
121   default:
122     return 0;
123   }
124 }
125 
taglib_file_free(TagLib_File * file)126 void taglib_file_free(TagLib_File *file)
127 {
128   delete reinterpret_cast<File *>(file);
129 }
130 
taglib_file_is_valid(const TagLib_File * file)131 BOOL taglib_file_is_valid(const TagLib_File *file)
132 {
133   return reinterpret_cast<const File *>(file)->isValid();
134 }
135 
taglib_file_tag(const TagLib_File * file)136 TagLib_Tag *taglib_file_tag(const TagLib_File *file)
137 {
138   const File *f = reinterpret_cast<const File *>(file);
139   return reinterpret_cast<TagLib_Tag *>(f->tag());
140 }
141 
taglib_file_audioproperties(const TagLib_File * file)142 const TagLib_AudioProperties *taglib_file_audioproperties(const TagLib_File *file)
143 {
144   const File *f = reinterpret_cast<const File *>(file);
145   return reinterpret_cast<const TagLib_AudioProperties *>(f->audioProperties());
146 }
147 
taglib_file_save(TagLib_File * file)148 BOOL taglib_file_save(TagLib_File *file)
149 {
150   return reinterpret_cast<File *>(file)->save();
151 }
152 
153 ////////////////////////////////////////////////////////////////////////////////
154 // TagLib::Tag wrapper
155 ////////////////////////////////////////////////////////////////////////////////
156 
taglib_tag_title(const TagLib_Tag * tag)157 char *taglib_tag_title(const TagLib_Tag *tag)
158 {
159   const Tag *t = reinterpret_cast<const Tag *>(tag);
160   char *s = stringToCharArray(t->title());
161   if(stringManagementEnabled)
162     strings.append(s);
163   return s;
164 }
165 
taglib_tag_artist(const TagLib_Tag * tag)166 char *taglib_tag_artist(const TagLib_Tag *tag)
167 {
168   const Tag *t = reinterpret_cast<const Tag *>(tag);
169   char *s = stringToCharArray(t->artist());
170   if(stringManagementEnabled)
171     strings.append(s);
172   return s;
173 }
174 
taglib_tag_album(const TagLib_Tag * tag)175 char *taglib_tag_album(const TagLib_Tag *tag)
176 {
177   const Tag *t = reinterpret_cast<const Tag *>(tag);
178   char *s = stringToCharArray(t->album());
179   if(stringManagementEnabled)
180     strings.append(s);
181   return s;
182 }
183 
taglib_tag_comment(const TagLib_Tag * tag)184 char *taglib_tag_comment(const TagLib_Tag *tag)
185 {
186   const Tag *t = reinterpret_cast<const Tag *>(tag);
187   char *s = stringToCharArray(t->comment());
188   if(stringManagementEnabled)
189     strings.append(s);
190   return s;
191 }
192 
taglib_tag_genre(const TagLib_Tag * tag)193 char *taglib_tag_genre(const TagLib_Tag *tag)
194 {
195   const Tag *t = reinterpret_cast<const Tag *>(tag);
196   char *s = stringToCharArray(t->genre());
197   if(stringManagementEnabled)
198     strings.append(s);
199   return s;
200 }
201 
taglib_tag_year(const TagLib_Tag * tag)202 unsigned int taglib_tag_year(const TagLib_Tag *tag)
203 {
204   const Tag *t = reinterpret_cast<const Tag *>(tag);
205   return t->year();
206 }
207 
taglib_tag_track(const TagLib_Tag * tag)208 unsigned int taglib_tag_track(const TagLib_Tag *tag)
209 {
210   const Tag *t = reinterpret_cast<const Tag *>(tag);
211   return t->track();
212 }
213 
taglib_tag_set_title(TagLib_Tag * tag,const char * title)214 void taglib_tag_set_title(TagLib_Tag *tag, const char *title)
215 {
216   Tag *t = reinterpret_cast<Tag *>(tag);
217   t->setTitle(charArrayToString(title));
218 }
219 
taglib_tag_set_artist(TagLib_Tag * tag,const char * artist)220 void taglib_tag_set_artist(TagLib_Tag *tag, const char *artist)
221 {
222   Tag *t = reinterpret_cast<Tag *>(tag);
223   t->setArtist(charArrayToString(artist));
224 }
225 
taglib_tag_set_album(TagLib_Tag * tag,const char * album)226 void taglib_tag_set_album(TagLib_Tag *tag, const char *album)
227 {
228   Tag *t = reinterpret_cast<Tag *>(tag);
229   t->setAlbum(charArrayToString(album));
230 }
231 
taglib_tag_set_comment(TagLib_Tag * tag,const char * comment)232 void taglib_tag_set_comment(TagLib_Tag *tag, const char *comment)
233 {
234   Tag *t = reinterpret_cast<Tag *>(tag);
235   t->setComment(charArrayToString(comment));
236 }
237 
taglib_tag_set_genre(TagLib_Tag * tag,const char * genre)238 void taglib_tag_set_genre(TagLib_Tag *tag, const char *genre)
239 {
240   Tag *t = reinterpret_cast<Tag *>(tag);
241   t->setGenre(charArrayToString(genre));
242 }
243 
taglib_tag_set_year(TagLib_Tag * tag,unsigned int year)244 void taglib_tag_set_year(TagLib_Tag *tag, unsigned int year)
245 {
246   Tag *t = reinterpret_cast<Tag *>(tag);
247   t->setYear(year);
248 }
249 
taglib_tag_set_track(TagLib_Tag * tag,unsigned int track)250 void taglib_tag_set_track(TagLib_Tag *tag, unsigned int track)
251 {
252   Tag *t = reinterpret_cast<Tag *>(tag);
253   t->setTrack(track);
254 }
255 
taglib_tag_free_strings()256 void taglib_tag_free_strings()
257 {
258   if(!stringManagementEnabled)
259     return;
260 
261   for(List<char *>::ConstIterator it = strings.begin(); it != strings.end(); ++it)
262     free(*it);
263   strings.clear();
264 }
265 
266 ////////////////////////////////////////////////////////////////////////////////
267 // TagLib::AudioProperties wrapper
268 ////////////////////////////////////////////////////////////////////////////////
269 
taglib_audioproperties_length(const TagLib_AudioProperties * audioProperties)270 int taglib_audioproperties_length(const TagLib_AudioProperties *audioProperties)
271 {
272   const AudioProperties *p = reinterpret_cast<const AudioProperties *>(audioProperties);
273   return p->length();
274 }
275 
taglib_audioproperties_bitrate(const TagLib_AudioProperties * audioProperties)276 int taglib_audioproperties_bitrate(const TagLib_AudioProperties *audioProperties)
277 {
278   const AudioProperties *p = reinterpret_cast<const AudioProperties *>(audioProperties);
279   return p->bitrate();
280 }
281 
taglib_audioproperties_samplerate(const TagLib_AudioProperties * audioProperties)282 int taglib_audioproperties_samplerate(const TagLib_AudioProperties *audioProperties)
283 {
284   const AudioProperties *p = reinterpret_cast<const AudioProperties *>(audioProperties);
285   return p->sampleRate();
286 }
287 
taglib_audioproperties_channels(const TagLib_AudioProperties * audioProperties)288 int taglib_audioproperties_channels(const TagLib_AudioProperties *audioProperties)
289 {
290   const AudioProperties *p = reinterpret_cast<const AudioProperties *>(audioProperties);
291   return p->channels();
292 }
293 
taglib_id3v2_set_default_text_encoding(TagLib_ID3v2_Encoding encoding)294 void taglib_id3v2_set_default_text_encoding(TagLib_ID3v2_Encoding encoding)
295 {
296   String::Type type = String::Latin1;
297 
298   switch(encoding)
299   {
300   case TagLib_ID3v2_Latin1:
301     type = String::Latin1;
302     break;
303   case TagLib_ID3v2_UTF16:
304     type = String::UTF16;
305     break;
306   case TagLib_ID3v2_UTF16BE:
307     type = String::UTF16BE;
308     break;
309   case TagLib_ID3v2_UTF8:
310     type = String::UTF8;
311     break;
312   }
313 
314   ID3v2::FrameFactory::instance()->setDefaultTextEncoding(type);
315 }
316