Files
ncmpcpp/src/utility/comparators.cpp
2014-11-02 22:14:29 +01:00

111 lines
3.7 KiB
C++

/***************************************************************************
* Copyright (C) 2008-2014 by Andrzej Rybczak *
* electricityispower@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include <locale>
#include "comparators.h"
#include "utility/string.h"
namespace {//
bool hasTheWord(const std::string &s)
{
return s.length() >= 4
&& (s[0] == 't' || s[0] == 'T')
&& (s[1] == 'h' || s[1] == 'H')
&& (s[2] == 'e' || s[2] == 'E')
&& (s[3] == ' ');
}
}
int LocaleStringComparison::compare(const char *a, size_t a_len, const char *b, size_t b_len) const
{
size_t ac_off = 0, bc_off = 0;
if (m_ignore_the)
{
if (hasTheWord(a))
ac_off += 4;
if (hasTheWord(b))
bc_off += 4;
}
return std::use_facet<std::collate<char>>(m_locale).compare(
a+ac_off, a+a_len, b+bc_off, b+b_len
);
}
bool LocaleBasedItemSorting::operator()(const MPD::Item &a, const MPD::Item &b) const
{
bool result = false;
if (a.type() == b.type())
{
switch (m_sort_mode)
{
case SortMode::Name:
switch (a.type())
{
case MPD::Item::Type::Directory:
result = m_cmp(a.directory().path(), b.directory().path());
break;
case MPD::Item::Type::Playlist:
result = m_cmp(a.playlist().path(), b.playlist().path());
break;
case MPD::Item::Type::Song:
result = m_cmp(a.song(), b.song());
break;
}
break;
case SortMode::CustomFormat:
switch (a.type())
{
case MPD::Item::Type::Directory:
result = m_cmp(a.directory().path(), b.directory().path());
break;
case MPD::Item::Type::Playlist:
result = m_cmp(a.playlist().path(), b.playlist().path());
break;
case MPD::Item::Type::Song:
result = m_cmp(a.song().toString(Config.browser_sort_format, Config.tags_separator),
b.song().toString(Config.browser_sort_format, Config.tags_separator));
break;
}
break;
case SortMode::ModificationTime:
switch (a.type())
{
case MPD::Item::Type::Directory:
result = a.directory().lastModified() > b.directory().lastModified();
break;
case MPD::Item::Type::Playlist:
result = a.playlist().lastModified() > b.playlist().lastModified();
break;
case MPD::Item::Type::Song:
result = a.song().getMTime() > b.song().getMTime();
break;
}
break;
case SortMode::NoOp:
throw std::logic_error("can't sort with NoOp sorting mode");
}
}
else
result = a.type() < b.type();
return result;
}