client/Response: new Client wrapper class for writing responses
This commit is contained in:
+13
-14
@@ -21,7 +21,8 @@
|
||||
#include "Count.hxx"
|
||||
#include "Selection.hxx"
|
||||
#include "Interface.hxx"
|
||||
#include "client/Client.hxx"
|
||||
#include "Partition.hxx"
|
||||
#include "client/Response.hxx"
|
||||
#include "LightSong.hxx"
|
||||
#include "tag/Tag.hxx"
|
||||
|
||||
@@ -40,26 +41,24 @@ class TagCountMap : public std::map<std::string, SearchStats> {
|
||||
};
|
||||
|
||||
static void
|
||||
PrintSearchStats(Client &client, const SearchStats &stats)
|
||||
PrintSearchStats(Response &r, const SearchStats &stats)
|
||||
{
|
||||
unsigned total_duration_s =
|
||||
std::chrono::duration_cast<std::chrono::seconds>(stats.total_duration).count();
|
||||
|
||||
client_printf(client,
|
||||
"songs: %u\n"
|
||||
"playtime: %u\n",
|
||||
stats.n_songs, total_duration_s);
|
||||
r.Format("songs: %u\n"
|
||||
"playtime: %u\n",
|
||||
stats.n_songs, total_duration_s);
|
||||
}
|
||||
|
||||
static void
|
||||
Print(Client &client, TagType group, const TagCountMap &m)
|
||||
Print(Response &r, TagType group, const TagCountMap &m)
|
||||
{
|
||||
assert(unsigned(group) < TAG_NUM_OF_ITEM_TYPES);
|
||||
|
||||
for (const auto &i : m) {
|
||||
client_printf(client, "%s: %s\n",
|
||||
tag_item_names[group], i.first.c_str());
|
||||
PrintSearchStats(client, i.second);
|
||||
r.Format("%s: %s\n", tag_item_names[group], i.first.c_str());
|
||||
PrintSearchStats(r, i.second);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,12 +108,12 @@ GroupCountVisitor(TagCountMap &map, TagType group, const LightSong &song)
|
||||
}
|
||||
|
||||
bool
|
||||
PrintSongCount(Client &client, const char *name,
|
||||
PrintSongCount(Response &r, const Partition &partition, const char *name,
|
||||
const SongFilter *filter,
|
||||
TagType group,
|
||||
Error &error)
|
||||
{
|
||||
const Database *db = client.GetDatabase(error);
|
||||
const Database *db = partition.GetDatabase(error);
|
||||
if (db == nullptr)
|
||||
return false;
|
||||
|
||||
@@ -131,7 +130,7 @@ PrintSongCount(Client &client, const char *name,
|
||||
if (!db->Visit(selection, f, error))
|
||||
return false;
|
||||
|
||||
PrintSearchStats(client, stats);
|
||||
PrintSearchStats(r, stats);
|
||||
} else {
|
||||
/* group by the specified tag: store counts in a
|
||||
std::map */
|
||||
@@ -144,7 +143,7 @@ PrintSongCount(Client &client, const char *name,
|
||||
if (!db->Visit(selection, f, error))
|
||||
return false;
|
||||
|
||||
Print(client, group, map);
|
||||
Print(r, group, map);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
+4
-3
@@ -25,13 +25,14 @@
|
||||
#include <stdint.h>
|
||||
|
||||
enum TagType : uint8_t;
|
||||
class Client;
|
||||
struct Partition;
|
||||
class Response;
|
||||
class SongFilter;
|
||||
class Error;
|
||||
|
||||
gcc_nonnull(2)
|
||||
gcc_nonnull(3)
|
||||
bool
|
||||
PrintSongCount(Client &client, const char *name,
|
||||
PrintSongCount(Response &r, const Partition &partition, const char *name,
|
||||
const SongFilter *filter,
|
||||
TagType group,
|
||||
Error &error);
|
||||
|
||||
+52
-45
@@ -24,6 +24,8 @@
|
||||
#include "SongPrint.hxx"
|
||||
#include "TimePrint.hxx"
|
||||
#include "client/Client.hxx"
|
||||
#include "client/Response.hxx"
|
||||
#include "Partition.hxx"
|
||||
#include "tag/Tag.hxx"
|
||||
#include "LightSong.hxx"
|
||||
#include "LightDirectory.hxx"
|
||||
@@ -42,116 +44,119 @@ ApplyBaseFlag(const char *uri, bool base)
|
||||
}
|
||||
|
||||
static void
|
||||
PrintDirectoryURI(Client &client, bool base, const LightDirectory &directory)
|
||||
PrintDirectoryURI(Response &r, bool base, const LightDirectory &directory)
|
||||
{
|
||||
client_printf(client, "directory: %s\n",
|
||||
ApplyBaseFlag(directory.GetPath(), base));
|
||||
r.Format("directory: %s\n",
|
||||
ApplyBaseFlag(directory.GetPath(), base));
|
||||
}
|
||||
|
||||
static bool
|
||||
PrintDirectoryBrief(Client &client, bool base, const LightDirectory &directory)
|
||||
PrintDirectoryBrief(Response &r, bool base, const LightDirectory &directory)
|
||||
{
|
||||
if (!directory.IsRoot())
|
||||
PrintDirectoryURI(client, base, directory);
|
||||
PrintDirectoryURI(r, base, directory);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
PrintDirectoryFull(Client &client, bool base, const LightDirectory &directory)
|
||||
PrintDirectoryFull(Response &r, bool base, const LightDirectory &directory)
|
||||
{
|
||||
if (!directory.IsRoot()) {
|
||||
PrintDirectoryURI(client, base, directory);
|
||||
PrintDirectoryURI(r, base, directory);
|
||||
|
||||
if (directory.mtime > 0)
|
||||
time_print(client, "Last-Modified", directory.mtime);
|
||||
time_print(r, "Last-Modified", directory.mtime);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
print_playlist_in_directory(Client &client, bool base,
|
||||
print_playlist_in_directory(Response &r, bool base,
|
||||
const char *directory,
|
||||
const char *name_utf8)
|
||||
{
|
||||
if (base || directory == nullptr)
|
||||
client_printf(client, "playlist: %s\n",
|
||||
ApplyBaseFlag(name_utf8, base));
|
||||
r.Format("playlist: %s\n",
|
||||
ApplyBaseFlag(name_utf8, base));
|
||||
else
|
||||
client_printf(client, "playlist: %s/%s\n",
|
||||
directory, name_utf8);
|
||||
r.Format("playlist: %s/%s\n",
|
||||
directory, name_utf8);
|
||||
}
|
||||
|
||||
static void
|
||||
print_playlist_in_directory(Client &client, bool base,
|
||||
print_playlist_in_directory(Response &r, bool base,
|
||||
const LightDirectory *directory,
|
||||
const char *name_utf8)
|
||||
{
|
||||
if (base || directory == nullptr || directory->IsRoot())
|
||||
client_printf(client, "playlist: %s\n", name_utf8);
|
||||
r.Format("playlist: %s\n", name_utf8);
|
||||
else
|
||||
client_printf(client, "playlist: %s/%s\n",
|
||||
directory->GetPath(), name_utf8);
|
||||
r.Format("playlist: %s/%s\n",
|
||||
directory->GetPath(), name_utf8);
|
||||
}
|
||||
|
||||
static bool
|
||||
PrintSongBrief(Client &client, bool base, const LightSong &song)
|
||||
PrintSongBrief(Response &r, Partition &partition,
|
||||
bool base, const LightSong &song)
|
||||
{
|
||||
song_print_uri(client, song, base);
|
||||
song_print_uri(r, partition, song, base);
|
||||
|
||||
if (song.tag->has_playlist)
|
||||
/* this song file has an embedded CUE sheet */
|
||||
print_playlist_in_directory(client, base,
|
||||
print_playlist_in_directory(r, base,
|
||||
song.directory, song.uri);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
PrintSongFull(Client &client, bool base, const LightSong &song)
|
||||
PrintSongFull(Response &r, Partition &partition,
|
||||
bool base, const LightSong &song)
|
||||
{
|
||||
song_print_info(client, song, base);
|
||||
song_print_info(r, partition, song, base);
|
||||
|
||||
if (song.tag->has_playlist)
|
||||
/* this song file has an embedded CUE sheet */
|
||||
print_playlist_in_directory(client, base,
|
||||
print_playlist_in_directory(r, base,
|
||||
song.directory, song.uri);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
PrintPlaylistBrief(Client &client, bool base,
|
||||
PrintPlaylistBrief(Response &r, bool base,
|
||||
const PlaylistInfo &playlist,
|
||||
const LightDirectory &directory)
|
||||
{
|
||||
print_playlist_in_directory(client, base,
|
||||
print_playlist_in_directory(r, base,
|
||||
&directory, playlist.name.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
PrintPlaylistFull(Client &client, bool base,
|
||||
PrintPlaylistFull(Response &r, bool base,
|
||||
const PlaylistInfo &playlist,
|
||||
const LightDirectory &directory)
|
||||
{
|
||||
print_playlist_in_directory(client, base,
|
||||
print_playlist_in_directory(r, base,
|
||||
&directory, playlist.name.c_str());
|
||||
|
||||
if (playlist.mtime > 0)
|
||||
time_print(client, "Last-Modified", playlist.mtime);
|
||||
time_print(r, "Last-Modified", playlist.mtime);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
db_selection_print(Client &client, const DatabaseSelection &selection,
|
||||
db_selection_print(Response &r, Partition &partition,
|
||||
const DatabaseSelection &selection,
|
||||
bool full, bool base,
|
||||
unsigned window_start, unsigned window_end,
|
||||
Error &error)
|
||||
{
|
||||
const Database *db = client.GetDatabase(error);
|
||||
const Database *db = partition.GetDatabase(error);
|
||||
if (db == nullptr)
|
||||
return false;
|
||||
|
||||
@@ -160,13 +165,13 @@ db_selection_print(Client &client, const DatabaseSelection &selection,
|
||||
using namespace std::placeholders;
|
||||
const auto d = selection.filter == nullptr
|
||||
? std::bind(full ? PrintDirectoryFull : PrintDirectoryBrief,
|
||||
std::ref(client), base, _1)
|
||||
std::ref(r), base, _1)
|
||||
: VisitDirectory();
|
||||
VisitSong s = std::bind(full ? PrintSongFull : PrintSongBrief,
|
||||
std::ref(client), base, _1);
|
||||
std::ref(r), std::ref(partition), base, _1);
|
||||
const auto p = selection.filter == nullptr
|
||||
? std::bind(full ? PrintPlaylistFull : PrintPlaylistBrief,
|
||||
std::ref(client), base, _1, _2)
|
||||
std::ref(r), base, _1, _2)
|
||||
: VisitPlaylist();
|
||||
|
||||
if (window_start > 0 ||
|
||||
@@ -182,45 +187,47 @@ db_selection_print(Client &client, const DatabaseSelection &selection,
|
||||
}
|
||||
|
||||
bool
|
||||
db_selection_print(Client &client, const DatabaseSelection &selection,
|
||||
db_selection_print(Response &r, Partition &partition,
|
||||
const DatabaseSelection &selection,
|
||||
bool full, bool base,
|
||||
Error &error)
|
||||
{
|
||||
return db_selection_print(client, selection, full, base,
|
||||
return db_selection_print(r, partition, selection, full, base,
|
||||
0, std::numeric_limits<int>::max(),
|
||||
error);
|
||||
}
|
||||
|
||||
static bool
|
||||
PrintSongURIVisitor(Client &client, const LightSong &song)
|
||||
PrintSongURIVisitor(Response &r, Partition &partition, const LightSong &song)
|
||||
{
|
||||
song_print_uri(client, song);
|
||||
song_print_uri(r, partition, song);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
PrintUniqueTag(Client &client, TagType tag_type,
|
||||
PrintUniqueTag(Response &r, TagType tag_type,
|
||||
const Tag &tag)
|
||||
{
|
||||
const char *value = tag.GetValue(tag_type);
|
||||
assert(value != nullptr);
|
||||
client_printf(client, "%s: %s\n", tag_item_names[tag_type], value);
|
||||
r.Format("%s: %s\n", tag_item_names[tag_type], value);
|
||||
|
||||
for (const auto &item : tag)
|
||||
if (item.type != tag_type)
|
||||
client_printf(client, "%s: %s\n",
|
||||
tag_item_names[item.type], item.value);
|
||||
r.Format("%s: %s\n",
|
||||
tag_item_names[item.type], item.value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PrintUniqueTags(Client &client, unsigned type, uint32_t group_mask,
|
||||
PrintUniqueTags(Response &r, Partition &partition,
|
||||
unsigned type, uint32_t group_mask,
|
||||
const SongFilter *filter,
|
||||
Error &error)
|
||||
{
|
||||
const Database *db = client.GetDatabase(error);
|
||||
const Database *db = partition.GetDatabase(error);
|
||||
if (db == nullptr)
|
||||
return false;
|
||||
|
||||
@@ -229,13 +236,13 @@ PrintUniqueTags(Client &client, unsigned type, uint32_t group_mask,
|
||||
if (type == LOCATE_TAG_FILE_TYPE) {
|
||||
using namespace std::placeholders;
|
||||
const auto f = std::bind(PrintSongURIVisitor,
|
||||
std::ref(client), _1);
|
||||
std::ref(r), std::ref(partition), _1);
|
||||
return db->Visit(selection, f, error);
|
||||
} else {
|
||||
assert(type < TAG_NUM_OF_ITEM_TYPES);
|
||||
|
||||
using namespace std::placeholders;
|
||||
const auto f = std::bind(PrintUniqueTag, std::ref(client),
|
||||
const auto f = std::bind(PrintUniqueTag, std::ref(r),
|
||||
(TagType)type, _1);
|
||||
return db->VisitUniqueTags(selection, (TagType)type,
|
||||
group_mask,
|
||||
|
||||
@@ -26,7 +26,9 @@
|
||||
|
||||
class SongFilter;
|
||||
struct DatabaseSelection;
|
||||
struct Partition;
|
||||
class Client;
|
||||
class Response;
|
||||
class Error;
|
||||
|
||||
/**
|
||||
@@ -34,17 +36,20 @@ class Error;
|
||||
* @param base print only base name of songs/directories?
|
||||
*/
|
||||
bool
|
||||
db_selection_print(Client &client, const DatabaseSelection &selection,
|
||||
db_selection_print(Response &r, Partition &partition,
|
||||
const DatabaseSelection &selection,
|
||||
bool full, bool base, Error &error);
|
||||
|
||||
bool
|
||||
db_selection_print(Client &client, const DatabaseSelection &selection,
|
||||
db_selection_print(Response &r, Partition &partition,
|
||||
const DatabaseSelection &selection,
|
||||
bool full, bool base,
|
||||
unsigned window_start, unsigned window_end,
|
||||
Error &error);
|
||||
|
||||
bool
|
||||
PrintUniqueTags(Client &client, unsigned type, uint32_t group_mask,
|
||||
PrintUniqueTags(Response &r, Partition &partition,
|
||||
unsigned type, uint32_t group_mask,
|
||||
const SongFilter *filter,
|
||||
Error &error);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user