QueueSave.cxx 3.14 KB
Newer Older
1
/*
Max Kellermann's avatar
Max Kellermann committed
2
 * Copyright (C) 2003-2014 The Music Player Daemon Project
3 4 5 6 7 8 9 10 11 12 13
 * http://www.musicpd.org
 *
 * 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.
14 15 16 17
 *
 * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 19
 */

20
#include "config.h"
21
#include "QueueSave.hxx"
22 23
#include "Queue.hxx"
#include "PlaylistError.hxx"
24
#include "DetachedSong.hxx"
25
#include "SongSave.hxx"
26 27
#include "SongLoader.hxx"
#include "playlist/PlaylistSong.hxx"
28 29
#include "fs/io/TextFile.hxx"
#include "fs/io/BufferedOutputStream.hxx"
30
#include "util/StringUtil.hxx"
31
#include "util/Error.hxx"
32
#include "fs/Traits.hxx"
33
#include "Log.hxx"
34 35 36

#include <stdlib.h>

37 38
#define PRIO_LABEL "Prio: "

39
static void
40 41
queue_save_database_song(BufferedOutputStream &os,
			 int idx, const DetachedSong &song)
42
{
43
	os.Format("%i:%s\n", idx, song.GetURI());
44 45
}

46
static void
47
queue_save_full_song(BufferedOutputStream &os, const DetachedSong &song)
48
{
49
	song_save(os, song);
50 51 52
}

static void
53
queue_save_song(BufferedOutputStream &os, int idx, const DetachedSong &song)
54
{
55
	if (song.IsInDatabase() &&
56
	    song.GetStartTime().IsZero() && song.GetEndTime().IsZero())
57 58
		/* use the brief format (just the URI) for "full"
		   database songs */
59
		queue_save_database_song(os, idx, song);
60
	else
61 62
		/* use the long format (URI, range, tags) for the
		   rest, so all metadata survives a MPD restart */
63
		queue_save_full_song(os, song);
64 65
}

66
void
67
queue_save(BufferedOutputStream &os, const Queue &queue)
68
{
69 70
	for (unsigned i = 0; i < queue.GetLength(); i++) {
		uint8_t prio = queue.GetPriorityAtPosition(i);
71
		if (prio != 0)
72
			os.Format(PRIO_LABEL "%u\n", prio);
73

74
		queue_save_song(os, i, queue.Get(i));
75
	}
76 77
}

78
void
79 80
queue_load_song(TextFile &file, const SongLoader &loader,
		const char *line, Queue &queue)
81
{
82
	if (queue.IsFull())
83
		return;
84

85
	uint8_t priority = 0;
86
	if (StringStartsWith(line, PRIO_LABEL)) {
87
		priority = strtoul(line + sizeof(PRIO_LABEL) - 1, nullptr, 10);
88

89
		line = file.ReadLine();
90
		if (line == nullptr)
91 92 93
			return;
	}

94
	DetachedSong *song;
95

96
	if (StringStartsWith(line, SONG_BEGIN)) {
97
		const char *uri = line + sizeof(SONG_BEGIN) - 1;
98

99
		Error error;
100
		song = song_load(file, uri, error);
101
		if (song == nullptr) {
102
			LogError(error);
103 104 105 106 107 108
			return;
		}
	} else {
		char *endptr;
		long ret = strtol(line, &endptr, 10);
		if (ret < 0 || *endptr != ':' || endptr[1] == 0) {
109 110
			LogError(playlist_domain,
				 "Malformed playlist line in state file");
111 112
			return;
		}
113

114
		const char *uri = endptr + 1;
115

116 117 118 119 120 121
		song = new DetachedSong(uri);
	}

	if (!playlist_check_translate_song(*song, nullptr, loader)) {
		delete song;
		return;
122
	}
123

124 125
	queue.Append(std::move(*song), priority);
	delete song;
126
}