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 bool
readAudioDevicesState(FILE *fp) readAudioDevicesState(const char *line)
{ {
char buffer[1024]; long value;
char *endptr;
const char *name;
struct audio_output *ao;
while (fgets(buffer, sizeof(buffer), fp)) { if (!g_str_has_prefix(line, AUDIO_DEVICE_STATE))
char *c, *name; return false;
struct audio_output *ao;
g_strchomp(buffer); line += sizeof(AUDIO_DEVICE_STATE) - 1;
if (!g_str_has_prefix(buffer, AUDIO_DEVICE_STATE)) value = strtol(line, &endptr, 10);
continue; if (*endptr != ':' || (value != 0 && value != 1))
return false;
c = strchr(buffer, ':'); if (value != 0)
if (!c || !(++c)) /* state is "enabled": no-op */
goto errline; return true;
name = strchr(c, ':'); name = endptr + 1;
if (!name || !(++name)) ao = audio_output_find(name);
goto errline; if (ao == NULL) {
g_debug("Ignoring device state for '%s'", name);
ao = audio_output_find(name); return true;
if (ao != NULL && atoi(c) == 0)
ao->enabled = false;
continue;
errline:
/* nonfatal */
g_warning("invalid line in state_file: %s\n", buffer);
} }
ao->enabled = false;
return true;
} }

View File

@ -25,10 +25,11 @@
#ifndef OUTPUT_STATE_H #ifndef OUTPUT_STATE_H
#define OUTPUT_STATE_H #define OUTPUT_STATE_H
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
void bool
readAudioDevicesState(FILE *fp); readAudioDevicesState(const char *line);
void void
saveAudioDevicesState(FILE *fp); saveAudioDevicesState(FILE *fp);

View File

@ -115,8 +115,8 @@ playlist_state_load(FILE *fp, struct playlist *playlist, char *buffer)
queue_increment_version(&playlist->queue); queue_increment_version(&playlist->queue);
} }
void bool
playlist_state_restore(FILE *fp, struct playlist *playlist) playlist_state_restore(const char *line, FILE *fp, struct playlist *playlist)
{ {
int current = -1; int current = -1;
int seek_time = 0; int seek_time = 0;
@ -124,21 +124,20 @@ playlist_state_restore(FILE *fp, struct playlist *playlist)
char buffer[PLAYLIST_BUFFER_SIZE]; char buffer[PLAYLIST_BUFFER_SIZE];
bool random_mode = false; 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)) { while (fgets(buffer, sizeof(buffer), fp)) {
g_strchomp(buffer); g_strchomp(buffer);
if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_STATE)) { if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_TIME)) {
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)) {
seek_time = seek_time =
atoi(&(buffer[strlen(PLAYLIST_STATE_FILE_TIME)])); atoi(&(buffer[strlen(PLAYLIST_STATE_FILE_TIME)]));
} else if (g_str_has_prefix(buffer, PLAYLIST_STATE_FILE_REPEAT)) { } 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) if (state == PLAYER_STATE_PAUSE)
playerPause(); playerPause();
} }
return true;
} }

View File

@ -25,6 +25,7 @@
#ifndef PLAYLIST_STATE_H #ifndef PLAYLIST_STATE_H
#define PLAYLIST_STATE_H #define PLAYLIST_STATE_H
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
struct playlist; struct playlist;
@ -32,7 +33,7 @@ struct playlist;
void void
playlist_state_save(FILE *fp, const struct playlist *playlist); playlist_state_save(FILE *fp, const struct playlist *playlist);
void bool
playlist_state_restore(FILE *fp, struct playlist *playlist); playlist_state_restore(const char *line, FILE *fp, struct playlist *playlist);
#endif #endif

View File

@ -63,6 +63,8 @@ static void
state_file_read(void) state_file_read(void)
{ {
FILE *fp; FILE *fp;
char line[1024];
bool success;
assert(state_file_path != NULL); assert(state_file_path != NULL);
@ -75,11 +77,15 @@ state_file_read(void)
return; return;
} }
read_sw_volume_state(fp); while (fgets(line, sizeof(line), fp) != NULL) {
rewind(fp); g_strchomp(line);
readAudioDevicesState(fp);
rewind(fp); success = read_sw_volume_state(line) ||
playlist_state_restore(fp, &g_playlist); 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 */; while(fclose(fp) && errno == EINTR) /* nothing */;
} }

View File

@ -100,24 +100,22 @@ bool volume_level_change(unsigned volume)
return hardware_volume_change(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; char *end = NULL;
long int sv; long int sv;
while (fgets(buf, sizeof(buf), fp)) { if (!g_str_has_prefix(line, SW_VOLUME_STATE))
if (!g_str_has_prefix(buf, SW_VOLUME_STATE)) return false;
continue;
g_strchomp(buf); line += sizeof(SW_VOLUME_STATE) - 1;
sv = strtol(buf + strlen(SW_VOLUME_STATE), &end, 10); sv = strtol(line, &end, 10);
if (G_LIKELY(!*end) && sv >= 0 && sv <= 100) if (*end == 0 && sv >= 0 && sv <= 100)
software_volume_change(sv); software_volume_change(sv);
else else
g_warning("Can't parse software volume: %s\n", buf); g_warning("Can't parse software volume: %s\n", line);
return; return true;
}
} }
void save_sw_volume_state(FILE *fp) void save_sw_volume_state(FILE *fp)

View File

@ -31,7 +31,8 @@ int volume_level_get(void);
bool volume_level_change(unsigned volume); 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); void save_sw_volume_state(FILE *fp);