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:
Max Kellermann 2009-07-15 16:57:37 +02:00
parent df7d7732c6
commit f7cc5b2efd
7 changed files with 68 additions and 61 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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 */;
}

View File

@ -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)

View File

@ -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);