state_file: don't rewind the stream while reading the state file
Parse the state file line by line, let each subsystem probe a line. Only the playlist_state code gets the FILE pointer to read the following lines.
This commit is contained in:
parent
df7d7732c6
commit
f7cc5b2efd
|
@ -49,35 +49,34 @@ saveAudioDevicesState(FILE *fp)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
readAudioDevicesState(FILE *fp)
|
||||
bool
|
||||
readAudioDevicesState(const char *line)
|
||||
{
|
||||
char buffer[1024];
|
||||
long value;
|
||||
char *endptr;
|
||||
const char *name;
|
||||
struct audio_output *ao;
|
||||
|
||||
while (fgets(buffer, sizeof(buffer), fp)) {
|
||||
char *c, *name;
|
||||
struct audio_output *ao;
|
||||
if (!g_str_has_prefix(line, AUDIO_DEVICE_STATE))
|
||||
return false;
|
||||
|
||||
g_strchomp(buffer);
|
||||
line += sizeof(AUDIO_DEVICE_STATE) - 1;
|
||||
|
||||
if (!g_str_has_prefix(buffer, AUDIO_DEVICE_STATE))
|
||||
continue;
|
||||
value = strtol(line, &endptr, 10);
|
||||
if (*endptr != ':' || (value != 0 && value != 1))
|
||||
return false;
|
||||
|
||||
c = strchr(buffer, ':');
|
||||
if (!c || !(++c))
|
||||
goto errline;
|
||||
if (value != 0)
|
||||
/* state is "enabled": no-op */
|
||||
return true;
|
||||
|
||||
name = strchr(c, ':');
|
||||
if (!name || !(++name))
|
||||
goto errline;
|
||||
|
||||
ao = audio_output_find(name);
|
||||
if (ao != NULL && atoi(c) == 0)
|
||||
ao->enabled = false;
|
||||
|
||||
continue;
|
||||
errline:
|
||||
/* nonfatal */
|
||||
g_warning("invalid line in state_file: %s\n", buffer);
|
||||
name = endptr + 1;
|
||||
ao = audio_output_find(name);
|
||||
if (ao == NULL) {
|
||||
g_debug("Ignoring device state for '%s'", name);
|
||||
return true;
|
||||
}
|
||||
|
||||
ao->enabled = false;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -25,10 +25,11 @@
|
|||
#ifndef OUTPUT_STATE_H
|
||||
#define OUTPUT_STATE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void
|
||||
readAudioDevicesState(FILE *fp);
|
||||
bool
|
||||
readAudioDevicesState(const char *line);
|
||||
|
||||
void
|
||||
saveAudioDevicesState(FILE *fp);
|
||||
|
|
|
@ -115,8 +115,8 @@ playlist_state_load(FILE *fp, struct playlist *playlist, char *buffer)
|
|||
queue_increment_version(&playlist->queue);
|
||||
}
|
||||
|
||||
void
|
||||
playlist_state_restore(FILE *fp, struct playlist *playlist)
|
||||
bool
|
||||
playlist_state_restore(const char *line, FILE *fp, struct playlist *playlist)
|
||||
{
|
||||
int current = -1;
|
||||
int seek_time = 0;
|
||||
|
@ -124,21 +124,20 @@ playlist_state_restore(FILE *fp, struct playlist *playlist)
|
|||
char buffer[PLAYLIST_BUFFER_SIZE];
|
||||
bool random_mode = false;
|
||||
|
||||
if (!g_str_has_prefix(line, PLAYLIST_STATE_FILE_STATE))
|
||||
return false;
|
||||
|
||||
line += sizeof(PLAYLIST_STATE_FILE_STATE) - 1;
|
||||
|
||||
if (strcmp(line, PLAYLIST_STATE_FILE_STATE_PLAY) == 0)
|
||||
state = PLAYER_STATE_PLAY;
|
||||
else if (strcmp(line, PLAYLIST_STATE_FILE_STATE_PAUSE) == 0)
|
||||
state = PLAYER_STATE_PAUSE;
|
||||
|
||||
while (fgets(buffer, sizeof(buffer), fp)) {
|
||||
g_strchomp(buffer);
|
||||
|
||||
if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_STATE)) {
|
||||
if (strcmp(&(buffer[strlen(PLAYLIST_STATE_FILE_STATE)]),
|
||||
PLAYLIST_STATE_FILE_STATE_PLAY) == 0) {
|
||||
state = PLAYER_STATE_PLAY;
|
||||
} else
|
||||
if (strcmp
|
||||
(&(buffer[strlen(PLAYLIST_STATE_FILE_STATE)]),
|
||||
PLAYLIST_STATE_FILE_STATE_PAUSE)
|
||||
== 0) {
|
||||
state = PLAYER_STATE_PAUSE;
|
||||
}
|
||||
} else if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_TIME)) {
|
||||
if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_TIME)) {
|
||||
seek_time =
|
||||
atoi(&(buffer[strlen(PLAYLIST_STATE_FILE_TIME)]));
|
||||
} else if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_REPEAT)) {
|
||||
|
@ -198,4 +197,6 @@ playlist_state_restore(FILE *fp, struct playlist *playlist)
|
|||
if (state == PLAYER_STATE_PAUSE)
|
||||
playerPause();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#ifndef PLAYLIST_STATE_H
|
||||
#define PLAYLIST_STATE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct playlist;
|
||||
|
@ -32,7 +33,7 @@ struct playlist;
|
|||
void
|
||||
playlist_state_save(FILE *fp, const struct playlist *playlist);
|
||||
|
||||
void
|
||||
playlist_state_restore(FILE *fp, struct playlist *playlist);
|
||||
bool
|
||||
playlist_state_restore(const char *line, FILE *fp, struct playlist *playlist);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -63,6 +63,8 @@ static void
|
|||
state_file_read(void)
|
||||
{
|
||||
FILE *fp;
|
||||
char line[1024];
|
||||
bool success;
|
||||
|
||||
assert(state_file_path != NULL);
|
||||
|
||||
|
@ -75,11 +77,15 @@ state_file_read(void)
|
|||
return;
|
||||
}
|
||||
|
||||
read_sw_volume_state(fp);
|
||||
rewind(fp);
|
||||
readAudioDevicesState(fp);
|
||||
rewind(fp);
|
||||
playlist_state_restore(fp, &g_playlist);
|
||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
||||
g_strchomp(line);
|
||||
|
||||
success = read_sw_volume_state(line) ||
|
||||
readAudioDevicesState(line) ||
|
||||
playlist_state_restore(line, fp, &g_playlist);
|
||||
if (!success)
|
||||
g_warning("Unrecognized line in state file: %s", line);
|
||||
}
|
||||
|
||||
while(fclose(fp) && errno == EINTR) /* nothing */;
|
||||
}
|
||||
|
|
24
src/volume.c
24
src/volume.c
|
@ -100,24 +100,22 @@ bool volume_level_change(unsigned volume)
|
|||
return hardware_volume_change(volume);
|
||||
}
|
||||
|
||||
void read_sw_volume_state(FILE *fp)
|
||||
bool
|
||||
read_sw_volume_state(const char *line)
|
||||
{
|
||||
char buf[sizeof(SW_VOLUME_STATE) + sizeof("100") - 1];
|
||||
char *end = NULL;
|
||||
long int sv;
|
||||
|
||||
while (fgets(buf, sizeof(buf), fp)) {
|
||||
if (!g_str_has_prefix(buf, SW_VOLUME_STATE))
|
||||
continue;
|
||||
if (!g_str_has_prefix(line, SW_VOLUME_STATE))
|
||||
return false;
|
||||
|
||||
g_strchomp(buf);
|
||||
sv = strtol(buf + strlen(SW_VOLUME_STATE), &end, 10);
|
||||
if (G_LIKELY(!*end) && sv >= 0 && sv <= 100)
|
||||
software_volume_change(sv);
|
||||
else
|
||||
g_warning("Can't parse software volume: %s\n", buf);
|
||||
return;
|
||||
}
|
||||
line += sizeof(SW_VOLUME_STATE) - 1;
|
||||
sv = strtol(line, &end, 10);
|
||||
if (*end == 0 && sv >= 0 && sv <= 100)
|
||||
software_volume_change(sv);
|
||||
else
|
||||
g_warning("Can't parse software volume: %s\n", line);
|
||||
return true;
|
||||
}
|
||||
|
||||
void save_sw_volume_state(FILE *fp)
|
||||
|
|
|
@ -31,7 +31,8 @@ int volume_level_get(void);
|
|||
|
||||
bool volume_level_change(unsigned volume);
|
||||
|
||||
void read_sw_volume_state(FILE *fp);
|
||||
bool
|
||||
read_sw_volume_state(const char *line);
|
||||
|
||||
void save_sw_volume_state(FILE *fp);
|
||||
|
||||
|
|
Loading…
Reference in New Issue