core/tags/track: Convert std::string to gchar *

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2015-11-12 09:38:35 -05:00
parent 9e3e3e514c
commit b5caf6faed
6 changed files with 119 additions and 77 deletions

View File

@ -82,7 +82,7 @@ static void scan_path(void *);
*/ */
static void tag_track(struct library *library, const std::string &filepath) static void tag_track(struct library *library, const std::string &filepath)
{ {
struct track *track = track_add(library, filepath); struct track *track = track_add(library, filepath.c_str());
if (track) if (track)
library_q.add(track); library_q.add(track);
} }
@ -127,16 +127,19 @@ static void validate_library(void *data)
struct library *library = (struct library *)data; struct library *library = (struct library *)data;
struct db_entry *dbe, *next; struct db_entry *dbe, *next;
struct track *track; struct track *track;
gchar *path;
db_for_each(dbe, next, track_db_get()) { db_for_each(dbe, next, track_db_get()) {
track = TRACK(dbe); track = TRACK(dbe);
if (track->tr_library != library) if (track->tr_library != library)
continue; continue;
if (g_file_test(track_path(track).c_str(), G_FILE_TEST_EXISTS) == false) { path = track_path(track);
if (g_file_test(path, G_FILE_TEST_EXISTS) == false) {
library_q.del(track); library_q.del(track);
track_remove(track); track_remove(track);
} }
g_free(path);
} }
} }

View File

@ -13,13 +13,36 @@ extern "C" {
static struct database track_db; static struct database track_db;
static gchar *__track_key(struct library *library, const std::string &path) static gchar *__track_key(struct library *library, gchar *path)
{ {
if (!library) gchar *res;
return g_strdup("");
return g_strdup_printf("%u/%s", library->li_dbe.dbe_index, path.c_str()); if (library)
res = g_strdup_printf("%u/%s", library->li_dbe.dbe_index, path);
else
res = g_strdup("");
g_free(path);
return res;
} }
static gchar *__track_path(struct track *track)
{
gchar *path;
sscanf(track->tr_path, "%*u/%m[^\n]", &path);
return path;
}
static struct track *__track_alloc()
{
struct track *track = new struct track;
dbe_init(&track->tr_dbe, track);
return track;
}
struct db_entry *track_alloc(const gchar *key) struct db_entry *track_alloc(const gchar *key)
{ {
const TagLib_AudioProperties *audio; const TagLib_AudioProperties *audio;
@ -28,7 +51,7 @@ struct db_entry *track_alloc(const gchar *key)
unsigned int lib_id; unsigned int lib_id;
TagLib_File *file; TagLib_File *file;
TagLib_Tag *tag; TagLib_Tag *tag;
char *fullpath, *path, *lower; char *fullpath, *path;
sscanf(key, "%u/%m[^\n]", &lib_id, &path); sscanf(key, "%u/%m[^\n]", &lib_id, &path);
library = library_get(lib_id); library = library_get(lib_id);
@ -39,8 +62,7 @@ struct db_entry *track_alloc(const gchar *key)
goto out; goto out;
} }
track = new struct track; track = __track_alloc();
dbe_init(&track->tr_dbe, track);
tag = taglib_file_tag(file); tag = taglib_file_tag(file);
audio = taglib_file_audioproperties(file); audio = taglib_file_audioproperties(file);
@ -54,17 +76,15 @@ struct db_entry *track_alloc(const gchar *key)
track->tr_track = taglib_tag_track(tag); track->tr_track = taglib_tag_track(tag);
date_set(&track->tr_date, 0, 0, 0); date_set(&track->tr_date, 0, 0, 0);
track->tr_path = path; track->tr_path = g_strdup(key);
track->tr_title = taglib_tag_title(tag); track->tr_title = g_strdup(taglib_tag_title(tag));
lower = string_lowercase(track->tr_title.c_str()); track->tr_lower = string_lowercase(track->tr_title);
track->tr_lower = lower;
taglib_tag_free_strings(); taglib_tag_free_strings();
taglib_file_free(file); taglib_file_free(file);
g_free(lower);
out: out:
g_free(fullpath);
g_free(path); g_free(path);
g_free(fullpath);
return track ? &track->tr_dbe : NULL; return track ? &track->tr_dbe : NULL;
} }
@ -72,6 +92,9 @@ static void track_free(struct db_entry *dbe)
{ {
struct track *track = TRACK(dbe); struct track *track = TRACK(dbe);
g_free(track->tr_title);
g_free(track->tr_lower);
if (track->tr_library) if (track->tr_library)
track->tr_library->li_size--; track->tr_library->li_size--;
delete track; delete track;
@ -81,7 +104,7 @@ static void track_setup(struct db_entry *dbe)
{ {
struct track *track = TRACK(dbe); struct track *track = TRACK(dbe);
filter_add(track->tr_lower.c_str(), dbe->dbe_index); filter_add(track->tr_lower, dbe->dbe_index);
filter_add(track->tr_artist->ar_lower, dbe->dbe_index); filter_add(track->tr_artist->ar_lower, dbe->dbe_index);
filter_add(track->tr_album->al_lower, dbe->dbe_index); filter_add(track->tr_album->al_lower, dbe->dbe_index);
track->tr_library->li_size++; track->tr_library->li_size++;
@ -89,41 +112,35 @@ static void track_setup(struct db_entry *dbe)
static gchar *track_key(struct db_entry *dbe) static gchar *track_key(struct db_entry *dbe)
{ {
return __track_key(TRACK(dbe)->tr_library, TRACK(dbe)->tr_path); return TRACK(dbe)->tr_path;
} }
static struct db_entry *track_read(struct file *file) static struct db_entry *track_read(struct file *file)
{ {
unsigned int library_id, artist_id, album_id, genre_id; unsigned int library_id, artist_id, album_id, genre_id;
struct track *track = new struct track; struct track *track = __track_alloc();
gchar *path, *name, *lower;
dbe_init(&track->tr_dbe, track);
file_readf(file, "%u %u %u %u %u", &library_id, &artist_id, &album_id, file_readf(file, "%u %u %u %u %u", &library_id, &artist_id, &album_id,
&genre_id, &track->tr_track); &genre_id, &track->tr_track);
date_read(file, &track->tr_date); date_read(file, &track->tr_date);
file_readf(file, "%u %u", &track->tr_count, &track->tr_length); file_readf(file, "%u %u", &track->tr_count, &track->tr_length);
name = file_readl(file);
path = file_readl(file);
lower = string_lowercase(name);
track->tr_title = name;
track->tr_path = path;
track->tr_lower = lower;
g_free(name);
g_free(path);
g_free(lower);
track->tr_library = library_get(library_id);
track->tr_artist = artist_get(artist_id);
track->tr_album = album_get(album_id); track->tr_album = album_get(album_id);
track->tr_artist = artist_get(artist_id);
track->tr_genre = genre_get(genre_id); track->tr_genre = genre_get(genre_id);
track->tr_library = library_get(library_id);
track->tr_title = file_readl(file);
track->tr_lower = string_lowercase(track->tr_title);
track->tr_path = __track_key(track->tr_library, file_readl(file));
return &track->tr_dbe; return &track->tr_dbe;
} }
static void track_write(struct file *file, struct db_entry *dbe) static void track_write(struct file *file, struct db_entry *dbe)
{ {
struct track *track = TRACK(dbe); struct track *track = TRACK(dbe);
gchar *path = __track_path(track);
file_writef(file, "%u %u %u %u %u ", track->tr_library->li_dbe.dbe_index, file_writef(file, "%u %u %u %u %u ", track->tr_library->li_dbe.dbe_index,
track->tr_artist->ar_dbe.dbe_index, track->tr_artist->ar_dbe.dbe_index,
track->tr_album->al_dbe.dbe_index, track->tr_album->al_dbe.dbe_index,
@ -132,8 +149,10 @@ static void track_write(struct file *file, struct db_entry *dbe)
date_write(file, &track->tr_date); date_write(file, &track->tr_date);
file_writef(file, " %u %u %s\n%s\n", track->tr_count, file_writef(file, " %u %u %s\n%s\n", track->tr_count,
track->tr_length, track->tr_length,
track->tr_title.c_str(), track->tr_title,
track->tr_path.c_str()); path);
g_free(path);
} }
@ -168,10 +187,10 @@ const struct database *track_db_get()
return &track_db; return &track_db;
} }
struct track *track_add(struct library *library, const std::string &filepath) struct track *track_add(struct library *library, const gchar *filepath)
{ {
std::string path = filepath.substr(strlen(library->li_path) + 1); unsigned int offset = strlen(library->li_path) + 1;
gchar *key = __track_key(library, path); gchar *key = __track_key(library, g_strdup(filepath + offset));
struct track *track = NULL; struct track *track = NULL;
if (!db_get(&track_db, key)) if (!db_get(&track_db, key))
@ -204,19 +223,20 @@ struct track *track_get(const unsigned int index)
int track_compare(struct track *lhs, struct track *rhs) int track_compare(struct track *lhs, struct track *rhs)
{ {
return string_compare(lhs->tr_lower.c_str(), rhs->tr_lower.c_str()); return string_compare(lhs->tr_lower, rhs->tr_lower);
} }
const std::string track_path(struct track *track) gchar *track_path(struct track *track)
{ {
std::string ret = ""; gchar *path, *res;
if (track->tr_library) { if (track->tr_library) {
gchar *g_ret = library_file(track->tr_library, track->tr_path.c_str()); path = __track_path(track);
ret = g_ret; res = library_file(track->tr_library, path);
g_free(g_ret); g_free(path);
return res;
} }
return ret; return g_strdup("");
} }
void track_played(struct track *track) void track_played(struct track *track)
@ -226,17 +246,11 @@ void track_played(struct track *track)
track_db_commit(); track_db_commit();
} }
const std::string track_last_play(struct track *track) gchar *track_last_play(struct track *track)
{ {
std::string res = "Never"; if (track->tr_count > 0)
char *buf; return date_string(&track->tr_date);
return g_strdup("Never");
if (track->tr_count > 0) {
buf = date_string(&track->tr_date);
res = buf;
g_free(buf);
}
return res;
} }
#ifdef CONFIG_TESTING #ifdef CONFIG_TESTING

View File

@ -59,8 +59,9 @@ class GSTDriver : public AudioDriver
public: public:
void load(struct track *track) void load(struct track *track)
{ {
gchar *uri = gst_filename_to_uri(track_path(track).c_str(), NULL); gchar *path = track_path(track);
gchar *len = string_sec2str(track->tr_length); gchar *uri = gst_filename_to_uri(path, NULL);
gchar *len = string_sec2str(track->tr_length);
gchar *str; gchar *str;
gst_change_state(GST_STATE_NULL); gst_change_state(GST_STATE_NULL);
@ -78,6 +79,7 @@ public:
set_markup(o_title, "xx-large", track->tr_title); set_markup(o_title, "xx-large", track->tr_title);
o_duration->set_text(len); o_duration->set_text(len);
g_free(path);
g_free(len); g_free(len);
plist :: track_loaded(track); plist :: track_loaded(track);
@ -145,11 +147,15 @@ static void parse_gst_error(GstMessage *error)
{ {
GError *err; GError *err;
struct track *track = audio :: current_track(); struct track *track = audio :: current_track();
gchar *path;
gst_message_parse_error(error, &err, NULL); gst_message_parse_error(error, &err, NULL);
if (track) if (track) {
g_print("Error playing file: %s\n", track_path(track).c_str()); path = track_path(track);
g_print("Error playing file: %s\n", path);
g_free(path);
}
g_print("Error: %s\n", err->message); g_print("Error: %s\n", err->message);
g_error_free(err); g_error_free(err);
} }

View File

@ -111,7 +111,8 @@ void QueueModel::get_value_vfunc(const Gtk::TreeIter &iter, int column,
case 0: case 0:
return set_val(track->tr_track, value); return set_val(track->tr_track, value);
case 1: case 1:
return set_val(track->tr_title, value); field = track->tr_title;
return set_val(field, value);
case 2: case 2:
str = string_sec2str(track->tr_length); str = string_sec2str(track->tr_length);
set_val(Glib::ustring(str), value); set_val(Glib::ustring(str), value);
@ -131,9 +132,15 @@ void QueueModel::get_value_vfunc(const Gtk::TreeIter &iter, int column,
case 7: case 7:
return set_val(track->tr_count, value); return set_val(track->tr_count, value);
case 8: case 8:
return set_val(track_last_play(track), value); str = track_last_play(track);
set_val(Glib::Markup::escape_text(str), value);
g_free(str);
return;
case 9: case 9:
return set_val(Glib::Markup::escape_text(track_path(track)), value); str = track_path(track);
set_val(Glib::Markup::escape_text(str), value);
g_free(str);
return;
} }
} }

View File

@ -31,9 +31,9 @@ struct track {
unsigned int tr_track; /* This track's track number. */ unsigned int tr_track; /* This track's track number. */
struct date tr_date; /* This track's last-played date. */ struct date tr_date; /* This track's last-played date. */
std::string tr_path; /* This track's path, relative to the library. */ gchar *tr_path; /* This track's path, relative to the library. */
std::string tr_title; /* This track's title. */ gchar *tr_title; /* This track's title. */
std::string tr_lower; /* This track's title (lowercased). */ gchar *tr_lower; /* This track's title (lowercased). */
struct db_entry tr_dbe; struct db_entry tr_dbe;
}; };
@ -54,7 +54,7 @@ void track_db_commit();
const struct database *track_db_get(); const struct database *track_db_get();
/* Called to add a track tag to the database. */ /* Called to add a track tag to the database. */
struct track *track_add(struct library *, const std::string &); struct track *track_add(struct library *, const gchar *);
/* Called to remove a specific track tag. */ /* Called to remove a specific track tag. */
void track_remove(struct track *); void track_remove(struct track *);
@ -68,14 +68,20 @@ struct track *track_get(const unsigned int);
/* Called to compare two track tags */ /* Called to compare two track tags */
int track_compare(struct track *, struct track *); int track_compare(struct track *, struct track *);
/* Called to find the full path of the track tag. */ /*
const std::string track_path(struct track *); * Called to find the full path of the track tag.
* This function returns a new string that MUST be freed with g_free().
*/
gchar *track_path(struct track *);
/* Called to mark a track tag as played. */ /* Called to mark a track tag as played. */
void track_played(struct track *); void track_played(struct track *);
/* Called to find the date that this track was last played. */ /*
const std::string track_last_play(struct track *); * Called to find the date that this track was last played.
* This function returns a new string that MUST be freed with g_free().
*/
gchar *track_last_play(struct track *);
#ifdef CONFIG_TESTING #ifdef CONFIG_TESTING
const struct db_ops *test_track_ops(); const struct db_ops *test_track_ops();

View File

@ -34,11 +34,11 @@ static void test_verify_track(struct track *track)
test_equal(track->tr_title, "Title Theme"); test_equal(track->tr_title, "Title Theme");
test_equal(track->tr_lower, "title theme"); test_equal(track->tr_lower, "title theme");
test_str_equal(track_ops->dbe_key(&track->tr_dbe), test_equal(track_ops->dbe_key(&track->tr_dbe),
"0/Hyrule Symphony/01 - Title Theme.ogg"); "0/Hyrule Symphony/01 - Title Theme.ogg");
test_equal(track_path(track), test_str_equal(track_path(track),
"tests/Music/Hyrule Symphony/01 - Title Theme.ogg"); "tests/Music/Hyrule Symphony/01 - Title Theme.ogg");
test_equal(track_last_play(track), "Never"); test_str_equal(track_last_play(track), "Never");
test_equal(track->tr_track, 1); test_equal(track->tr_track, 1);
test_equal(track->tr_length, 243); test_equal(track->tr_length, 243);
@ -52,11 +52,11 @@ static void test_verify_notrack(struct track *track)
test_equal(track->tr_title, ""); test_equal(track->tr_title, "");
test_equal(track->tr_lower, ""); test_equal(track->tr_lower, "");
test_str_equal(track_ops->dbe_key(&track->tr_dbe), test_equal(track_ops->dbe_key(&track->tr_dbe),
"0/Hyrule Symphony/00 - No Track.ogg"); "0/Hyrule Symphony/00 - No Track.ogg");
test_equal(track_path(track), test_str_equal(track_path(track),
"tests/Music/Hyrule Symphony/00 - No Track.ogg"); "tests/Music/Hyrule Symphony/00 - No Track.ogg");
test_equal(track_last_play(track), "Never"); test_str_equal(track_last_play(track), "Never");
test_equal(track->tr_track, 0); test_equal(track->tr_track, 0);
test_equal(track->tr_length, 0); test_equal(track->tr_length, 0);
@ -92,6 +92,7 @@ static void test_track()
track_ops->dbe_write(&f, &track->tr_dbe); track_ops->dbe_write(&f, &track->tr_dbe);
file_close(&f); file_close(&f);
g_free(track->tr_path);
track_ops->dbe_free(&track->tr_dbe); track_ops->dbe_free(&track->tr_dbe);
test_equal(library->li_size, 0); test_equal(library->li_size, 0);
@ -101,6 +102,8 @@ static void test_track()
track_ops->dbe_setup(&track->tr_dbe); track_ops->dbe_setup(&track->tr_dbe);
test_verify_notrack(track); test_verify_notrack(track);
test_equal(library->li_size, 1); test_equal(library->li_size, 1);
g_free(track->tr_path);
track_ops->dbe_free(&track->tr_dbe); track_ops->dbe_free(&track->tr_dbe);
track = TRACK(track_ops->dbe_read(&f)); track = TRACK(track_ops->dbe_read(&f));
@ -112,8 +115,9 @@ static void test_track()
track_played(track); track_played(track);
test_equal(track->tr_count, 1); test_equal(track->tr_count, 1);
test_equal(track_last_play(track), date); test_str_equal(track_last_play(track), date);
g_free(track->tr_path);
track_ops->dbe_free(&track->tr_dbe); track_ops->dbe_free(&track->tr_dbe);
g_free(date); g_free(date);
} }
@ -150,13 +154,15 @@ static void test_track_compare()
test_equal(track_compare(kokiri, title), -1); test_equal(track_compare(kokiri, title), -1);
test_equal(track_compare(title, kokiri), 1); test_equal(track_compare(title, kokiri), 1);
g_free(title->tr_path);
g_free(kokiri->tr_path);
track_ops->dbe_free(&title->tr_dbe); track_ops->dbe_free(&title->tr_dbe);
track_ops->dbe_free(&kokiri->tr_dbe); track_ops->dbe_free(&kokiri->tr_dbe);
} }
static void test_track_db() static void test_track_db()
{ {
std::string path = "tests/Music/Hyrule Symphony/01 - Title Theme.ogg"; const gchar *path = "tests/Music/Hyrule Symphony/01 - Title Theme.ogg";
struct library *library = library_find("tests/Music"); struct library *library = library_find("tests/Music");
const struct db_ops *track_ops = test_track_ops(); const struct db_ops *track_ops = test_track_ops();
struct database track_db; struct database track_db;