1 /***************************************************************************
2 * Copyright (C) 2008-2014 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
23 #include <boost/format.hpp>
24 #include <boost/functional/hash.hpp>
25 #include <boost/lexical_cast.hpp>
30 #include "utility/type_conversions.h"
31 #include "utility/wide_string.h"
36 size_t calc_hash(const char *s
, size_t seed
= 0)
38 for (; *s
!= '\0'; ++s
)
39 boost::hash_combine(seed
, *s
);
47 std::string
Song::TagsSeparator
= " | ";
49 std::string
Song::get(mpd_tag_type type
, unsigned idx
) const
52 const char *tag
= mpd_song_get_tag(m_song
.get(), type
, idx
);
58 Song::Song(mpd_song
*s
)
61 m_song
= std::shared_ptr
<mpd_song
>(s
, mpd_song_free
);
62 m_hash
= calc_hash(mpd_song_get_uri(s
));
65 std::string
Song::getURI(unsigned idx
) const
71 return mpd_song_get_uri(m_song
.get());
74 std::string
Song::getName(unsigned idx
) const
77 mpd_song
*s
= m_song
.get();
78 const char *res
= mpd_song_get_tag(s
, MPD_TAG_NAME
, idx
);
83 const char *uri
= mpd_song_get_uri(s
);
84 const char *name
= strrchr(uri
, '/');
91 std::string
Song::getDirectory(unsigned idx
) const
94 if (idx
> 0 || isStream())
96 const char *uri
= mpd_song_get_uri(m_song
.get());
97 const char *name
= strrchr(uri
, '/');
99 return std::string(uri
, name
-uri
);
104 std::string
Song::getArtist(unsigned idx
) const
107 return get(MPD_TAG_ARTIST
, idx
);
110 std::string
Song::getTitle(unsigned idx
) const
113 return get(MPD_TAG_TITLE
, idx
);
116 std::string
Song::getAlbum(unsigned idx
) const
119 return get(MPD_TAG_ALBUM
, idx
);
122 std::string
Song::getAlbumArtist(unsigned idx
) const
125 return get(MPD_TAG_ALBUM_ARTIST
, idx
);
128 std::string
Song::getTrack(unsigned idx
) const
131 std::string track
= get(MPD_TAG_TRACK
, idx
);
132 if ((track
.length() == 1 && track
[0] != '0')
133 || (track
.length() > 3 && track
[1] == '/'))
138 std::string
Song::getTrackNumber(unsigned idx
) const
141 std::string track
= getTrack(idx
);
142 size_t slash
= track
.find('/');
143 if (slash
!= std::string::npos
)
148 std::string
Song::getDate(unsigned idx
) const
151 return get(MPD_TAG_DATE
, idx
);
154 std::string
Song::getGenre(unsigned idx
) const
157 return get(MPD_TAG_GENRE
, idx
);
160 std::string
Song::getComposer(unsigned idx
) const
163 return get(MPD_TAG_COMPOSER
, idx
);
166 std::string
Song::getPerformer(unsigned idx
) const
169 return get(MPD_TAG_PERFORMER
, idx
);
172 std::string
Song::getDisc(unsigned idx
) const
175 return get(MPD_TAG_DISC
, idx
);
178 std::string
Song::getComment(unsigned idx
) const
181 return get(MPD_TAG_COMMENT
, idx
);
184 std::string
Song::getLength(unsigned idx
) const
189 unsigned len
= getDuration();
191 return ShowTime(len
);
196 std::string
Song::getPriority(unsigned idx
) const
201 return boost::lexical_cast
<std::string
>(getPrio());
204 std::string
MPD::Song::getTags(GetFunction f
) const
209 for (std::string tag
; !(tag
= (this->*f
)(idx
)).empty(); ++idx
)
212 result
+= TagsSeparator
;
218 unsigned Song::getDuration() const
221 return mpd_song_get_duration(m_song
.get());
224 unsigned Song::getPosition() const
227 return mpd_song_get_pos(m_song
.get());
230 unsigned Song::getID() const
233 return mpd_song_get_id(m_song
.get());
236 unsigned Song::getPrio() const
239 return mpd_song_get_prio(m_song
.get());
242 time_t Song::getMTime() const
245 return mpd_song_get_last_modified(m_song
.get());
248 bool Song::isFromDatabase() const
251 const char *uri
= mpd_song_get_uri(m_song
.get());
252 return uri
[0] != '/' || !strrchr(uri
, '/');
255 bool Song::isStream() const
258 return !strncmp(mpd_song_get_uri(m_song
.get()), "http://", 7);
261 bool Song::empty() const
263 return m_song
.get() == 0;
266 std::string
Song::ShowTime(unsigned length
)
268 int hours
= length
/3600;
269 length
-= hours
*3600;
270 int minutes
= length
/60;
271 length
-= minutes
*60;
272 int seconds
= length
;
276 result
= (boost::format("%d:%02d:%02d") % hours
% minutes
% seconds
).str();
278 result
= (boost::format("%d:%02d") % minutes
% seconds
).str();