diff --git a/src/mixer/Volume.cxx b/src/mixer/Volume.cxx
index 8b4928953..35def63e9 100644
--- a/src/mixer/Volume.cxx
+++ b/src/mixer/Volume.cxx
@@ -98,10 +98,10 @@ read_sw_volume_state(const char *line, MultipleOutputs &outputs)
 	char *end = nullptr;
 	long int sv;
 
-	if (!StringStartsWith(line, SW_VOLUME_STATE))
+	line = StringAfterPrefix(line, SW_VOLUME_STATE);
+	if (line == nullptr)
 		return false;
 
-	line += sizeof(SW_VOLUME_STATE) - 1;
 	sv = strtol(line, &end, 10);
 	if (*end == 0 && sv >= 0 && sv <= 100)
 		software_volume_change(outputs, sv);
diff --git a/src/output/OutputState.cxx b/src/output/OutputState.cxx
index e866eb507..421e2fa91 100644
--- a/src/output/OutputState.cxx
+++ b/src/output/OutputState.cxx
@@ -56,11 +56,10 @@ audio_output_state_read(const char *line, MultipleOutputs &outputs)
 	char *endptr;
 	const char *name;
 
-	if (!StringStartsWith(line, AUDIO_DEVICE_STATE))
+	line = StringAfterPrefix(line, AUDIO_DEVICE_STATE);
+	if (line == nullptr)
 		return false;
 
-	line += sizeof(AUDIO_DEVICE_STATE) - 1;
-
 	value = strtol(line, &endptr, 10);
 	if (*endptr != ':' || (value != 0 && value != 1))
 		return false;
diff --git a/src/queue/PlaylistState.cxx b/src/queue/PlaylistState.cxx
index 99d1b26cd..a1939e13a 100644
--- a/src/queue/PlaylistState.cxx
+++ b/src/queue/PlaylistState.cxx
@@ -33,6 +33,7 @@
 #include "config/ConfigGlobal.hxx"
 #include "config/ConfigOption.hxx"
 #include "util/CharUtil.hxx"
+#include "util/StringAPI.hxx"
 #include "util/StringCompare.hxx"
 #include "Log.hxx"
 
@@ -132,11 +133,10 @@ playlist_state_restore(const char *line, TextFile &file,
 	SongTime seek_time = SongTime::zero();
 	bool random_mode = false;
 
-	if (!StringStartsWith(line, PLAYLIST_STATE_FILE_STATE))
+	line = StringAfterPrefix(line, PLAYLIST_STATE_FILE_STATE);
+	if (line == nullptr)
 		return false;
 
-	line += sizeof(PLAYLIST_STATE_FILE_STATE) - 1;
-
 	PlayerState state;
 	if (strcmp(line, PLAYLIST_STATE_FILE_STATE_PLAY) == 0)
 		state = PlayerState::PLAY;
@@ -146,39 +146,28 @@ playlist_state_restore(const char *line, TextFile &file,
 		state = PlayerState::STOP;
 
 	while ((line = file.ReadLine()) != nullptr) {
-		if (StringStartsWith(line, PLAYLIST_STATE_FILE_TIME)) {
-			double seconds = atof(line + strlen(PLAYLIST_STATE_FILE_TIME));
-			seek_time = SongTime::FromS(seconds);
-		} else if (StringStartsWith(line, PLAYLIST_STATE_FILE_REPEAT)) {
-			playlist.SetRepeat(pc,
-					   strcmp(&(line[strlen(PLAYLIST_STATE_FILE_REPEAT)]),
-						  "1") == 0);
-		} else if (StringStartsWith(line, PLAYLIST_STATE_FILE_SINGLE)) {
-			playlist.SetSingle(pc,
-					   strcmp(&(line[strlen(PLAYLIST_STATE_FILE_SINGLE)]),
-						  "1") == 0);
-		} else if (StringStartsWith(line, PLAYLIST_STATE_FILE_CONSUME)) {
-			playlist.SetConsume(strcmp(&(line[strlen(PLAYLIST_STATE_FILE_CONSUME)]),
-						   "1") == 0);
-		} else if (StringStartsWith(line, PLAYLIST_STATE_FILE_CROSSFADE)) {
-			pc.SetCrossFade(atoi(line + strlen(PLAYLIST_STATE_FILE_CROSSFADE)));
-		} else if (StringStartsWith(line, PLAYLIST_STATE_FILE_MIXRAMPDB)) {
-			pc.SetMixRampDb(atof(line + strlen(PLAYLIST_STATE_FILE_MIXRAMPDB)));
-		} else if (StringStartsWith(line, PLAYLIST_STATE_FILE_MIXRAMPDELAY)) {
-			const char *p = line + strlen(PLAYLIST_STATE_FILE_MIXRAMPDELAY);
-
+		const char *p;
+		if ((p = StringAfterPrefix(line, PLAYLIST_STATE_FILE_TIME))) {
+			seek_time = SongTime::FromS(atof(p));
+		} else if ((p = StringAfterPrefix(line, PLAYLIST_STATE_FILE_REPEAT))) {
+			playlist.SetRepeat(pc, StringIsEqual(p, "1"));
+		} else if ((p = StringAfterPrefix(line, PLAYLIST_STATE_FILE_SINGLE))) {
+			playlist.SetSingle(pc, StringIsEqual(p, "1"));
+		} else if ((p = StringAfterPrefix(line, PLAYLIST_STATE_FILE_CONSUME))) {
+			playlist.SetConsume(StringIsEqual(p, "1"));
+		} else if ((p = StringAfterPrefix(line, PLAYLIST_STATE_FILE_CROSSFADE))) {
+			pc.SetCrossFade(atoi(p));
+		} else if ((p = StringAfterPrefix(line, PLAYLIST_STATE_FILE_MIXRAMPDB))) {
+			pc.SetMixRampDb(atof(p));
+		} else if ((p = StringAfterPrefix(line, PLAYLIST_STATE_FILE_MIXRAMPDELAY))) {
 			/* this check discards "nan" which was used
 			   prior to MPD 0.18 */
 			if (IsDigitASCII(*p))
 				pc.SetMixRampDelay(atof(p));
-		} else if (StringStartsWith(line, PLAYLIST_STATE_FILE_RANDOM)) {
-			random_mode =
-				strcmp(line + strlen(PLAYLIST_STATE_FILE_RANDOM),
-				       "1") == 0;
-		} else if (StringStartsWith(line, PLAYLIST_STATE_FILE_CURRENT)) {
-			current = atoi(&(line
-					 [strlen
-					  (PLAYLIST_STATE_FILE_CURRENT)]));
+		} else if ((p = StringAfterPrefix(line, PLAYLIST_STATE_FILE_RANDOM))) {
+			random_mode = StringIsEqual(p, "1");
+		} else if ((p = StringAfterPrefix(line, PLAYLIST_STATE_FILE_CURRENT))) {
+			current = atoi(p);
 		} else if (StringStartsWith(line,
 					    PLAYLIST_STATE_FILE_PLAYLIST_BEGIN)) {
 			playlist_state_load(file, song_loader, playlist);
diff --git a/src/queue/QueueSave.cxx b/src/queue/QueueSave.cxx
index cb8611cf8..3b9589450 100644
--- a/src/queue/QueueSave.cxx
+++ b/src/queue/QueueSave.cxx
@@ -83,8 +83,9 @@ queue_load_song(TextFile &file, const SongLoader &loader,
 		return;
 
 	uint8_t priority = 0;
-	if (StringStartsWith(line, PRIO_LABEL)) {
-		priority = strtoul(line + sizeof(PRIO_LABEL) - 1, nullptr, 10);
+	const char *p;
+	if ((p = StringAfterPrefix(line, PRIO_LABEL))) {
+		priority = strtoul(p, nullptr, 10);
 
 		line = file.ReadLine();
 		if (line == nullptr)
@@ -93,8 +94,8 @@ queue_load_song(TextFile &file, const SongLoader &loader,
 
 	DetachedSong *song;
 
-	if (StringStartsWith(line, SONG_BEGIN)) {
-		const char *uri = line + sizeof(SONG_BEGIN) - 1;
+	if ((p = StringAfterPrefix(line, PRIO_LABEL))) {
+		const char *uri = p;
 
 		Error error;
 		song = song_load(file, uri, error);