From 4b17aca7476dacfbd3b3220ff8013724f5eed0c9 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 1 Nov 2009 17:51:29 +0100 Subject: song_save: load one song at a time Changed songvec_load() to song_load(). Added start and end markers for each song. Removed the "key" line, it's redundant. --- src/database.c | 2 +- src/directory_save.c | 20 ++++++++++---- src/song.h | 3 --- src/song_save.c | 73 ++++++++-------------------------------------------- src/song_save.h | 12 +++++---- 5 files changed, 34 insertions(+), 76 deletions(-) diff --git a/src/database.c b/src/database.c index 8e927bfc4..4ecc58f2d 100644 --- a/src/database.c +++ b/src/database.c @@ -46,7 +46,7 @@ #define DIRECTORY_FS_CHARSET "fs_charset: " enum { - DB_FORMAT = 0, + DB_FORMAT = 1, }; static char *database_path; diff --git a/src/directory_save.c b/src/directory_save.c index e6d3649d0..a22d28ffb 100644 --- a/src/directory_save.c +++ b/src/directory_save.c @@ -144,7 +144,6 @@ directory_load(FILE *fp, struct directory *directory, GString *buffer, GError **error) { const char *line; - bool success; while ((line = read_text_line(fp, buffer)) != NULL && !g_str_has_prefix(line, DIRECTORY_END)) { @@ -157,11 +156,22 @@ directory_load(FILE *fp, struct directory *directory, return false; dirvec_add(&directory->children, subdir); - } else if (strcmp(line, SONG_BEGIN) == 0) { - success = songvec_load(fp, &directory->songs, - directory, buffer, error); - if (!success) + } 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); diff --git a/src/song.h b/src/song.h index bfa33e23d..c8e80b0d1 100644 --- a/src/song.h +++ b/src/song.h @@ -24,9 +24,6 @@ #include #include -#define SONG_BEGIN "songList begin" -#define SONG_END "songList end" - #define SONG_FILE "file: " #define SONG_TIME "Time: " diff --git a/src/song_save.c b/src/song_save.c index d931849e5..731d59e86 100644 --- a/src/song_save.c +++ b/src/song_save.c @@ -31,8 +31,8 @@ #undef G_LOG_DOMAIN #define G_LOG_DOMAIN "song" -#define SONG_KEY "key: " #define SONG_MTIME "mtime: " +#define SONG_END "song_end" static GQuark song_save_quark(void) @@ -40,61 +40,25 @@ song_save_quark(void) return g_quark_from_static_string("song_save"); } -static void -song_save_uri(FILE *fp, struct song *song) -{ - if (song->parent != NULL && song->parent->path != NULL) - fprintf(fp, SONG_FILE "%s/%s\n", - directory_get_path(song->parent), song->uri); - else - fprintf(fp, SONG_FILE "%s\n", song->uri); -} - static int song_save(struct song *song, void *data) { FILE *fp = data; - fprintf(fp, SONG_KEY "%s\n", song->uri); - - song_save_uri(fp, song); + fprintf(fp, SONG_BEGIN "%s\n", song->uri); if (song->tag != NULL) tag_save(fp, song->tag); fprintf(fp, SONG_MTIME "%li\n", (long)song->mtime); + fprintf(fp, SONG_END "\n"); return 0; } void songvec_save(FILE *fp, struct songvec *sv) { - fprintf(fp, "%s\n", SONG_BEGIN); songvec_for_each(sv, song_save, fp); - fprintf(fp, "%s\n", SONG_END); -} - -static void -commit_song(struct songvec *sv, struct song *newsong) -{ - struct song *existing = songvec_find(sv, newsong->uri); - - if (!existing) { - songvec_add(sv, newsong); - if (newsong->tag) - tag_end_add(newsong->tag); - } else { /* prevent dupes, just update the existing song info */ - if (existing->mtime != newsong->mtime) { - if (existing->tag != NULL) - tag_free(existing->tag); - if (newsong->tag) - tag_end_add(newsong->tag); - existing->tag = newsong->tag; - existing->mtime = newsong->mtime; - newsong->tag = NULL; - } - song_free(newsong); - } } static char * @@ -115,33 +79,18 @@ parse_tag_value(char *buffer, enum tag_type *type_r) return NULL; } -bool -songvec_load(FILE *fp, struct songvec *sv, struct directory *parent, - GString *buffer, GError **error_r) +struct song * +song_load(FILE *fp, struct directory *parent, const char *uri, + GString *buffer, GError **error_r) { + struct song *song = song_file_new(uri, parent); char *line; - struct song *song = NULL; enum tag_type type; const char *value; while ((line = read_text_line(fp, buffer)) != NULL && strcmp(line, SONG_END) != 0) { - if (0 == strncmp(SONG_KEY, line, strlen(SONG_KEY))) { - if (song) - commit_song(sv, song); - - song = song_file_new(line + strlen(SONG_KEY), - parent); - } else if (*line == 0) { - /* ignore empty lines (starting with '\0') */ - } else if (song == NULL) { - g_set_error(error_r, song_save_quark(), 0, - "Problems reading song info"); - return false; - } else if (0 == strncmp(SONG_FILE, line, strlen(SONG_FILE))) { - /* we don't need this info anymore */ - } else if ((value = parse_tag_value(line, - &type)) != NULL) { + if ((value = parse_tag_value(line, &type)) != NULL) { if (!song->tag) { song->tag = tag_new(); tag_begin_add(song->tag); @@ -164,8 +113,8 @@ songvec_load(FILE *fp, struct songvec *sv, struct directory *parent, } } - if (song) - commit_song(sv, song); + if (song->tag != NULL) + tag_end_add(song->tag); - return true; + return song; } diff --git a/src/song_save.h b/src/song_save.h index cd62c986d..70ddb249e 100644 --- a/src/song_save.h +++ b/src/song_save.h @@ -25,21 +25,23 @@ #include #include +#define SONG_BEGIN "song_begin: " + struct songvec; struct directory; void songvec_save(FILE *fp, struct songvec *sv); /** - * Loads songs from the input file and add the to the specified - * directory. + * Loads a song from the input file. Reading stops after the + * "song_end" line. * * @param error_r location to store the error occuring, or NULL to * ignore errors * @return true on success, false on error */ -bool -songvec_load(FILE *file, struct songvec *sv, struct directory *parent, - GString *buffer, GError **error_r); +struct song * +song_load(FILE *fp, struct directory *parent, const char *uri, + GString *buffer, GError **error_r); #endif -- cgit v1.2.3