static struct directory * directory_load_subdir(FILE *fp, struct directory *parent, const char *name, GString *buffer, GError **error_r) { struct directory *directory; const char *line; bool success; if (directory_get_child(parent, name) != NULL) { g_set_error(error_r, directory_quark(), 0, "Duplicate subdirectory '%s'", name); return NULL; } if (directory_is_root(parent)) { directory = directory_new(name, parent); } else { char *path = g_strconcat(directory_get_path(parent), "/", name, NULL); directory = directory_new(path, parent); g_free(path); } line = read_text_line(fp, buffer); if (line == NULL) { g_set_error(error_r, directory_quark(), 0, "Unexpected end of file"); directory_free(directory); return NULL; } if (g_str_has_prefix(line, DIRECTORY_MTIME)) { directory->mtime = g_ascii_strtoull(line + sizeof(DIRECTORY_MTIME) - 1, NULL, 10); line = read_text_line(fp, buffer); if (line == NULL) { g_set_error(error_r, directory_quark(), 0, "Unexpected end of file"); directory_free(directory); return NULL; } } if (!g_str_has_prefix(line, DIRECTORY_BEGIN)) { g_set_error(error_r, directory_quark(), 0, "Malformed line: %s", line); directory_free(directory); return NULL; } success = directory_load(fp, directory, buffer, error_r); if (!success) { directory_free(directory); return NULL; } return directory; }
GPtrArray * spl_load(const char *utf8path, GError **error_r) { FILE *file; GPtrArray *list; char *path_fs; if (spl_map(error_r) == NULL) return NULL; path_fs = spl_map_to_fs(utf8path, error_r); if (path_fs == NULL) return NULL; file = fopen(path_fs, "r"); g_free(path_fs); if (file == NULL) { playlist_errno(error_r); return NULL; } list = g_ptr_array_new(); GString *buffer = g_string_sized_new(1024); char *s; while ((s = read_text_line(file, buffer)) != NULL) { if (*s == 0 || *s == PLAYLIST_COMMENT) continue; if (g_path_is_absolute(s)) { char *t = fs_charset_to_utf8(s); if (t == NULL) continue; s = g_strconcat("file://", t, NULL); g_free(t); } else if (!uri_has_scheme(s)) { char *path_utf8; path_utf8 = map_fs_to_utf8(s); if (path_utf8 == NULL) continue; s = path_utf8; } else { s = fs_charset_to_utf8(s); if (s == NULL) continue; } g_ptr_array_add(list, s); if (list->len >= playlist_max_length) break; } fclose(file); return list; }
static WORD LEX_readln(LEX_class *LEX) { WORD i, j, done; done = 0; do { if (!read_text_line(LEX->handle, MAX_IN_LEN, LEX->buf)) return (-1); if (LEX->buf[0] == '') switch (LEX->buf[1]) { case '<': set_verbosity(verbose() + 1); break; case '>': set_verbosity(verbose() - 1); break; } else done = 1; } while (!done); if (!(LEX->flags & LEX_LININFO)) return (0); j = strlen(LEX->buf); if (LEX->file_list != NULL) for (i = 0; i < j; i++) if (LEX->buf[i] == ' ') { LEX->buf[i] = 0; if (DICT_lookup(LEX->file_list, LEX->buf) == NULL) DICT_enter(LEX->file_list, LEX->buf, 0); LEX->buf[i] = ' '; break; } for (i = 2; i < j; i++) if ((LEX->buf[i - 2] == ':') && (LEX->buf[i - 1] == ' ')) break; if (i == j) return (-1); LEX->buf[i - 2] = 0; LEX->state[0].new_line = 1; LEX->state[1].new_line = 1; report(E_NEWLINE, NULL, NULL); return (i); }
static void playlist_state_load(FILE *fp, GString *buffer, struct playlist *playlist) { const char *line = read_text_line(fp, buffer); if (line == NULL) { g_warning("No playlist in state file"); return; } while (!g_str_has_prefix(line, PLAYLIST_STATE_FILE_PLAYLIST_END)) { queue_load_song(fp, buffer, line, &playlist->queue); line = read_text_line(fp, buffer); if (line == NULL) { g_warning("'" PLAYLIST_STATE_FILE_PLAYLIST_END "' not found in state file"); break; } } queue_increment_version(&playlist->queue); }
bool directory_load(FILE *fp, struct directory *directory, GString *buffer, GError **error) { const char *line; while ((line = read_text_line(fp, buffer)) != NULL && !g_str_has_prefix(line, DIRECTORY_END)) { if (g_str_has_prefix(line, DIRECTORY_DIR)) { struct directory *subdir = directory_load_subdir(fp, directory, line + sizeof(DIRECTORY_DIR) - 1, buffer, error); if (subdir == NULL) return false; dirvec_add(&directory->children, subdir); } else if (g_str_has_prefix(line, SONG_BEGIN)) { const char *name = line + sizeof(SONG_BEGIN) - 1; struct song *song; if (songvec_find(&directory->songs, name) != NULL) { g_set_error(error, directory_quark(), 0, "Duplicate song '%s'", name); return NULL; } song = song_load(fp, directory, name, buffer, error); if (song == NULL) return false; songvec_add(&directory->songs, song); } else { g_set_error(error, directory_quark(), 0, "Malformed line: %s", line); return false; } } return true; }
static void state_file_read(struct player_control *pc) { FILE *fp; bool success; assert(state_file_path != NULL); g_debug("Loading state file %s", state_file_path); fp = fopen(state_file_path, "r"); if (G_UNLIKELY(!fp)) { g_warning("failed to open %s: %s", state_file_path, strerror(errno)); return; } GString *buffer = g_string_sized_new(1024); const char *line; while ((line = read_text_line(fp, buffer)) != NULL) { success = read_sw_volume_state(line) || audio_output_state_read(line) || playlist_state_restore(line, fp, buffer, &g_playlist, pc); if (!success) g_warning("Unrecognized line in state file: %s", line); } fclose(fp); prev_volume_version = sw_volume_state_get_hash(); prev_output_version = audio_output_state_get_version(); prev_playlist_version = playlist_state_get_hash(&g_playlist, pc); g_string_free(buffer, true); }
struct song * song_load(FILE *fp, struct directory *parent, const char *uri, GString *buffer, GError **error_r) { struct song *song = parent != NULL ? song_file_new(uri, parent) : song_remote_new(uri); char *line, *colon; enum tag_type type; const char *value; while ((line = read_text_line(fp, buffer)) != NULL && strcmp(line, SONG_END) != 0) { colon = strchr(line, ':'); if (colon == NULL || colon == line) { if (song->tag != NULL) tag_end_add(song->tag); song_free(song); g_set_error(error_r, song_save_quark(), 0, "unknown line in db: %s", line); return NULL; } *colon++ = 0; value = g_strchug(colon); if ((type = tag_name_parse(line)) != TAG_NUM_OF_ITEM_TYPES) { if (!song->tag) { song->tag = tag_new(); tag_begin_add(song->tag); } tag_add_item(song->tag, type, value); } else if (strcmp(line, "Time") == 0) { if (!song->tag) { song->tag = tag_new(); tag_begin_add(song->tag); } song->tag->time = atoi(value); } else if (strcmp(line, SONG_MTIME) == 0) { song->mtime = atoi(value); } else if (strcmp(line, "Range") == 0) { char *endptr; song->start_ms = strtoul(value, &endptr, 10); if (*endptr == '-') song->end_ms = strtoul(endptr + 1, NULL, 10); } else { if (song->tag != NULL) tag_end_add(song->tag); song_free(song); g_set_error(error_r, song_save_quark(), 0, "unknown line in db: %s", line); return NULL; } } if (song->tag != NULL) tag_end_add(song->tag); return song; }
bool playlist_state_restore(const char *line, FILE *fp, GString *buffer, struct playlist *playlist) { int current = -1; int seek_time = 0; int state = PLAYER_STATE_STOP; 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 ((line = read_text_line(fp, buffer)) != NULL) { if (g_str_has_prefix(line, PLAYLIST_STATE_FILE_TIME)) { seek_time = atoi(&(line[strlen(PLAYLIST_STATE_FILE_TIME)])); } else if (g_str_has_prefix(line, PLAYLIST_STATE_FILE_REPEAT)) { if (strcmp (&(line[strlen(PLAYLIST_STATE_FILE_REPEAT)]), "1") == 0) { playlist_set_repeat(playlist, true); } else playlist_set_repeat(playlist, false); } else if (g_str_has_prefix(line, PLAYLIST_STATE_FILE_SINGLE)) { if (strcmp (&(line[strlen(PLAYLIST_STATE_FILE_SINGLE)]), "1") == 0) { playlist_set_single(playlist, true); } else playlist_set_single(playlist, false); } else if (g_str_has_prefix(line, PLAYLIST_STATE_FILE_CONSUME)) { if (strcmp (&(line[strlen(PLAYLIST_STATE_FILE_CONSUME)]), "1") == 0) { playlist_set_consume(playlist, true); } else playlist_set_consume(playlist, false); } else if (g_str_has_prefix(line, PLAYLIST_STATE_FILE_CROSSFADE)) { pc_set_cross_fade(atoi(line + strlen(PLAYLIST_STATE_FILE_CROSSFADE))); } else if (g_str_has_prefix(line, PLAYLIST_STATE_FILE_MIXRAMPDB)) { pc_set_mixramp_db(atof(line + strlen(PLAYLIST_STATE_FILE_MIXRAMPDB))); } else if (g_str_has_prefix(line, PLAYLIST_STATE_FILE_MIXRAMPDELAY)) { pc_set_mixramp_delay(atof(line + strlen(PLAYLIST_STATE_FILE_MIXRAMPDELAY))); } else if (g_str_has_prefix(line, PLAYLIST_STATE_FILE_RANDOM)) { random_mode = strcmp(line + strlen(PLAYLIST_STATE_FILE_RANDOM), "1") == 0; } else if (g_str_has_prefix(line, PLAYLIST_STATE_FILE_CURRENT)) { current = atoi(&(line [strlen (PLAYLIST_STATE_FILE_CURRENT)])); } else if (g_str_has_prefix(line, PLAYLIST_STATE_FILE_PLAYLIST_BEGIN)) { playlist_state_load(fp, buffer, playlist); } } playlist_set_random(playlist, random_mode); if (!queue_is_empty(&playlist->queue)) { if (!queue_valid_position(&playlist->queue, current)) current = 0; /* enable all devices for the first time; this must be called here, after the audio output states were restored, before playback begins */ if (state != PLAYER_STATE_STOP) pc_update_audio(); if (state == PLAYER_STATE_STOP /* && config_option */) playlist->current = current; else if (seek_time == 0) playlist_play(playlist, current); else playlist_seek_song(playlist, current, seek_time); if (state == PLAYER_STATE_PAUSE) pc_pause(); } return true; }