From 29030b54c98b0aee65fbc10ebf7ba36bed98c02c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 10 Aug 2013 18:02:44 +0200 Subject: util/Error: new error passing library Replaces GLib's GError. --- src/db/ProxyDatabasePlugin.cxx | 106 ++++++++++++++++------------------ src/db/SimpleDatabasePlugin.cxx | 123 +++++++++++++++++----------------------- src/db/SimpleDatabasePlugin.hxx | 20 +++---- 3 files changed, 113 insertions(+), 136 deletions(-) (limited to 'src/db') diff --git a/src/db/ProxyDatabasePlugin.cxx b/src/db/ProxyDatabasePlugin.cxx index 81aad0a4c..e0af53cee 100644 --- a/src/db/ProxyDatabasePlugin.cxx +++ b/src/db/ProxyDatabasePlugin.cxx @@ -28,6 +28,8 @@ #include "gcc.h" #include "conf.h" #include "Tag.hxx" +#include "util/Error.hxx" +#include "util/Domain.hxx" #undef MPD_DIRECTORY_H #undef MPD_SONG_H @@ -46,39 +48,34 @@ class ProxyDatabase : public Database { public: static Database *Create(const config_param ¶m, - GError **error_r); + Error &error); - virtual bool Open(GError **error_r) override; + virtual bool Open(Error &error) override; virtual void Close() override; virtual Song *GetSong(const char *uri_utf8, - GError **error_r) const override; + Error &error) const override; virtual void ReturnSong(Song *song) const; virtual bool Visit(const DatabaseSelection &selection, VisitDirectory visit_directory, VisitSong visit_song, VisitPlaylist visit_playlist, - GError **error_r) const override; + Error &error) const override; virtual bool VisitUniqueTags(const DatabaseSelection &selection, enum tag_type tag_type, VisitString visit_string, - GError **error_r) const override; + Error &error) const override; virtual bool GetStats(const DatabaseSelection &selection, DatabaseStats &stats, - GError **error_r) const override; + Error &error) const override; protected: - bool Configure(const config_param ¶m, GError **error_r); + bool Configure(const config_param ¶m, Error &error); }; -gcc_pure -static inline GQuark -libmpdclient_quark(void) -{ - return g_quark_from_static_string("libmpdclient"); -} +static constexpr Domain libmpdclient_domain("libmpdclient"); static constexpr struct { enum tag_type d; @@ -116,23 +113,23 @@ Convert(enum tag_type tag_type) } static bool -CheckError(struct mpd_connection *connection, GError **error_r) +CheckError(struct mpd_connection *connection, Error &error) { - const auto error = mpd_connection_get_error(connection); - if (error == MPD_ERROR_SUCCESS) + const auto code = mpd_connection_get_error(connection); + if (code == MPD_ERROR_SUCCESS) return true; - g_set_error_literal(error_r, libmpdclient_quark(), (int)error, - mpd_connection_get_error_message(connection)); + error.Set(libmpdclient_domain, (int)code, + mpd_connection_get_error_message(connection)); mpd_connection_clear_error(connection); return false; } Database * -ProxyDatabase::Create(const config_param ¶m, GError **error_r) +ProxyDatabase::Create(const config_param ¶m, Error &error) { ProxyDatabase *db = new ProxyDatabase(); - if (!db->Configure(param, error_r)) { + if (!db->Configure(param, error)) { delete db; db = NULL; } @@ -141,7 +138,7 @@ ProxyDatabase::Create(const config_param ¶m, GError **error_r) } bool -ProxyDatabase::Configure(const config_param ¶m, GError **) +ProxyDatabase::Configure(const config_param ¶m, gcc_unused Error &error) { host = param.GetBlockValue("host", ""); port = param.GetBlockValue("port", 0u); @@ -150,17 +147,16 @@ ProxyDatabase::Configure(const config_param ¶m, GError **) } bool -ProxyDatabase::Open(GError **error_r) +ProxyDatabase::Open(Error &error) { connection = mpd_connection_new(host.empty() ? NULL : host.c_str(), port, 0); if (connection == NULL) { - g_set_error_literal(error_r, libmpdclient_quark(), - (int)MPD_ERROR_OOM, "Out of memory"); + error.Set(libmpdclient_domain, (int)MPD_ERROR_OOM, "Out of memory"); return false; } - if (!CheckError(connection, error_r)) { + if (!CheckError(connection, error)) { mpd_connection_free(connection); return false; } @@ -183,13 +179,13 @@ static Song * Convert(const struct mpd_song *song); Song * -ProxyDatabase::GetSong(const char *uri, GError **error_r) const +ProxyDatabase::GetSong(const char *uri, Error &error) const { // TODO: implement // TODO: auto-reconnect if (!mpd_send_list_meta(connection, uri)) { - CheckError(connection, error_r); + CheckError(connection, error); return nullptr; } @@ -202,13 +198,12 @@ ProxyDatabase::GetSong(const char *uri, GError **error_r) const if (song2 != nullptr) song2->Free(); - CheckError(connection, error_r); + CheckError(connection, error); return nullptr; } if (song2 == nullptr) - g_set_error(error_r, db_quark(), DB_NOT_FOUND, - "No such song: %s", uri); + error.Format(db_domain, DB_NOT_FOUND, "No such song: %s", uri); return song2; } @@ -226,19 +221,19 @@ ProxyDatabase::ReturnSong(Song *song) const static bool Visit(struct mpd_connection *connection, const char *uri, bool recursive, VisitDirectory visit_directory, VisitSong visit_song, - VisitPlaylist visit_playlist, GError **error_r); + VisitPlaylist visit_playlist, Error &error); static bool Visit(struct mpd_connection *connection, bool recursive, const struct mpd_directory *directory, VisitDirectory visit_directory, VisitSong visit_song, - VisitPlaylist visit_playlist, GError **error_r) + VisitPlaylist visit_playlist, Error &error) { const char *path = mpd_directory_get_path(directory); if (visit_directory) { Directory *d = Directory::NewGeneric(path, &detached_root); - bool success = visit_directory(*d, error_r); + bool success = visit_directory(*d, error); d->Free(); if (!success) return false; @@ -246,7 +241,7 @@ Visit(struct mpd_connection *connection, if (recursive && !Visit(connection, path, recursive, - visit_directory, visit_song, visit_playlist, error_r)) + visit_directory, visit_song, visit_playlist, error)) return false; return true; @@ -290,13 +285,13 @@ Convert(const struct mpd_song *song) static bool Visit(const struct mpd_song *song, - VisitSong visit_song, GError **error_r) + VisitSong visit_song, Error &error) { if (!visit_song) return true; Song *s = Convert(song); - bool success = visit_song(*s, error_r); + bool success = visit_song(*s, error); s->Free(); return success; @@ -304,7 +299,7 @@ Visit(const struct mpd_song *song, static bool Visit(const struct mpd_playlist *playlist, - VisitPlaylist visit_playlist, GError **error_r) + VisitPlaylist visit_playlist, Error &error) { if (!visit_playlist) return true; @@ -312,7 +307,7 @@ Visit(const struct mpd_playlist *playlist, PlaylistInfo p(mpd_playlist_get_path(playlist), mpd_playlist_get_last_modified(playlist)); - return visit_playlist(p, detached_root, error_r); + return visit_playlist(p, detached_root, error); } class ProxyEntity { @@ -356,13 +351,13 @@ ReceiveEntities(struct mpd_connection *connection) static bool Visit(struct mpd_connection *connection, const char *uri, bool recursive, VisitDirectory visit_directory, VisitSong visit_song, - VisitPlaylist visit_playlist, GError **error_r) + VisitPlaylist visit_playlist, Error &error) { if (!mpd_send_list_meta(connection, uri)) - return CheckError(connection, error_r); + return CheckError(connection, error); std::list entities(ReceiveEntities(connection)); - if (!CheckError(connection, error_r)) + if (!CheckError(connection, error)) return false; for (const auto &entity : entities) { @@ -374,25 +369,25 @@ Visit(struct mpd_connection *connection, const char *uri, if (!Visit(connection, recursive, mpd_entity_get_directory(entity), visit_directory, visit_song, visit_playlist, - error_r)) + error)) return false; break; case MPD_ENTITY_TYPE_SONG: if (!Visit(mpd_entity_get_song(entity), visit_song, - error_r)) + error)) return false; break; case MPD_ENTITY_TYPE_PLAYLIST: if (!Visit(mpd_entity_get_playlist(entity), - visit_playlist, error_r)) + visit_playlist, error)) return false; break; } } - return CheckError(connection, error_r); + return CheckError(connection, error); } bool @@ -400,55 +395,54 @@ ProxyDatabase::Visit(const DatabaseSelection &selection, VisitDirectory visit_directory, VisitSong visit_song, VisitPlaylist visit_playlist, - GError **error_r) const + Error &error) const { // TODO: match // TODO: auto-reconnect return ::Visit(connection, selection.uri, selection.recursive, visit_directory, visit_song, visit_playlist, - error_r); + error); } bool ProxyDatabase::VisitUniqueTags(const DatabaseSelection &selection, enum tag_type tag_type, VisitString visit_string, - GError **error_r) const + Error &error) const { enum mpd_tag_type tag_type2 = Convert(tag_type); if (tag_type2 == MPD_TAG_COUNT) { - g_set_error_literal(error_r, libmpdclient_quark(), 0, - "Unsupported tag"); + error.Set(libmpdclient_domain, "Unsupported tag"); return false; } if (!mpd_search_db_tags(connection, tag_type2)) - return CheckError(connection, error_r); + return CheckError(connection, error); // TODO: match (void)selection; if (!mpd_search_commit(connection)) - return CheckError(connection, error_r); + return CheckError(connection, error); bool result = true; struct mpd_pair *pair; while (result && (pair = mpd_recv_pair_tag(connection, tag_type2)) != nullptr) { - result = visit_string(pair->value, error_r); + result = visit_string(pair->value, error); mpd_return_pair(connection, pair); } return mpd_response_finish(connection) && - CheckError(connection, error_r) && + CheckError(connection, error) && result; } bool ProxyDatabase::GetStats(const DatabaseSelection &selection, - DatabaseStats &stats, GError **error_r) const + DatabaseStats &stats, Error &error) const { // TODO: match (void)selection; @@ -456,7 +450,7 @@ ProxyDatabase::GetStats(const DatabaseSelection &selection, struct mpd_stats *stats2 = mpd_run_stats(connection); if (stats2 == nullptr) - return CheckError(connection, error_r); + return CheckError(connection, error); stats.song_count = mpd_stats_get_number_of_songs(stats2); stats.total_duration = mpd_stats_get_db_play_time(stats2); diff --git a/src/db/SimpleDatabasePlugin.cxx b/src/db/SimpleDatabasePlugin.cxx index 21eb8752d..56bdc2cb7 100644 --- a/src/db/SimpleDatabasePlugin.cxx +++ b/src/db/SimpleDatabasePlugin.cxx @@ -29,22 +29,19 @@ #include "TextFile.hxx" #include "conf.h" #include "fs/FileSystem.hxx" +#include "util/Error.hxx" +#include "util/Domain.hxx" #include #include -gcc_const -static inline GQuark -simple_db_quark(void) -{ - return g_quark_from_static_string("simple_db"); -} +static constexpr Domain simple_db_domain("simple_db"); Database * -SimpleDatabase::Create(const config_param ¶m, GError **error_r) +SimpleDatabase::Create(const config_param ¶m, Error &error) { SimpleDatabase *db = new SimpleDatabase(); - if (!db->Configure(param, error_r)) { + if (!db->Configure(param, error)) { delete db; db = NULL; } @@ -53,17 +50,13 @@ SimpleDatabase::Create(const config_param ¶m, GError **error_r) } bool -SimpleDatabase::Configure(const config_param ¶m, GError **error_r) +SimpleDatabase::Configure(const config_param ¶m, Error &error) { - GError *error = NULL; - - path = param.GetBlockPath("path", &error); + path = param.GetBlockPath("path", error); if (path.IsNull()) { - if (error != NULL) - g_propagate_error(error_r, error); - else - g_set_error(error_r, simple_db_quark(), 0, - "No \"path\" parameter specified"); + if (!error.IsDefined()) + error.Set(simple_db_domain, + "No \"path\" parameter specified"); return false; } @@ -73,7 +66,7 @@ SimpleDatabase::Configure(const config_param ¶m, GError **error_r) } bool -SimpleDatabase::Check(GError **error_r) const +SimpleDatabase::Check(Error &error) const { assert(!path.IsNull()); assert(!path.empty()); @@ -88,28 +81,26 @@ SimpleDatabase::Check(GError **error_r) const /* Check that the parent part of the path is a directory */ struct stat st; if (!StatFile(dirPath, st)) { - g_set_error(error_r, simple_db_quark(), errno, - "Couldn't stat parent directory of db file " - "\"%s\": %s", - path_utf8.c_str(), g_strerror(errno)); + error.FormatErrno("Couldn't stat parent directory of db file " + "\"%s\"", + path_utf8.c_str()); return false; } if (!S_ISDIR(st.st_mode)) { - g_set_error(error_r, simple_db_quark(), 0, - "Couldn't create db file \"%s\" because the " - "parent path is not a directory", - path_utf8.c_str()); + error.Format(simple_db_domain, + "Couldn't create db file \"%s\" because the " + "parent path is not a directory", + path_utf8.c_str()); return false; } /* Check if we can write to the directory */ if (!CheckAccess(dirPath, X_OK | W_OK)) { - int error = errno; + const int e = errno; const std::string dirPath_utf8 = dirPath.ToUTF8(); - g_set_error(error_r, simple_db_quark(), error, - "Can't create db file in \"%s\": %s", - dirPath_utf8.c_str(), g_strerror(error)); + error.FormatErrno(e, "Can't create db file in \"%s\"", + dirPath_utf8.c_str()); return false; } @@ -119,24 +110,22 @@ SimpleDatabase::Check(GError **error_r) const /* Path exists, now check if it's a regular file */ struct stat st; if (!StatFile(path, st)) { - g_set_error(error_r, simple_db_quark(), errno, - "Couldn't stat db file \"%s\": %s", - path_utf8.c_str(), g_strerror(errno)); + error.FormatErrno("Couldn't stat db file \"%s\"", + path_utf8.c_str()); return false; } if (!S_ISREG(st.st_mode)) { - g_set_error(error_r, simple_db_quark(), 0, - "db file \"%s\" is not a regular file", - path_utf8.c_str()); + error.Format(simple_db_domain, + "db file \"%s\" is not a regular file", + path_utf8.c_str()); return false; } /* And check that we can write to it */ if (!CheckAccess(path, R_OK | W_OK)) { - g_set_error(error_r, simple_db_quark(), errno, - "Can't open db file \"%s\" for reading/writing: %s", - path_utf8.c_str(), g_strerror(errno)); + error.FormatErrno("Can't open db file \"%s\" for reading/writing", + path_utf8.c_str()); return false; } @@ -144,20 +133,19 @@ SimpleDatabase::Check(GError **error_r) const } bool -SimpleDatabase::Load(GError **error_r) +SimpleDatabase::Load(Error &error) { assert(!path.empty()); assert(root != NULL); TextFile file(path); if (file.HasFailed()) { - g_set_error(error_r, simple_db_quark(), errno, - "Failed to open database file \"%s\": %s", - path_utf8.c_str(), g_strerror(errno)); + error.FormatErrno("Failed to open database file \"%s\"", + path_utf8.c_str()); return false; } - if (!db_load_internal(file, root, error_r)) + if (!db_load_internal(file, root, error)) return false; struct stat st; @@ -168,7 +156,7 @@ SimpleDatabase::Load(GError **error_r) } bool -SimpleDatabase::Open(GError **error_r) +SimpleDatabase::Open(Error &error) { root = Directory::NewRoot(); mtime = 0; @@ -177,14 +165,13 @@ SimpleDatabase::Open(GError **error_r) borrowed_song_count = 0; #endif - GError *error = NULL; - if (!Load(&error)) { + if (!Load(error)) { root->Free(); - g_warning("Failed to load database: %s", error->message); - g_error_free(error); + g_warning("Failed to load database: %s", error.GetMessage()); + error.Clear(); - if (!Check(error_r)) + if (!Check(error)) return false; root = Directory::NewRoot(); @@ -203,7 +190,7 @@ SimpleDatabase::Close() } Song * -SimpleDatabase::GetSong(const char *uri, GError **error_r) const +SimpleDatabase::GetSong(const char *uri, Error &error) const { assert(root != NULL); @@ -211,8 +198,8 @@ SimpleDatabase::GetSong(const char *uri, GError **error_r) const Song *song = root->LookupSong(uri); db_unlock(); if (song == NULL) - g_set_error(error_r, db_quark(), DB_NOT_FOUND, - "No such song: %s", uri); + error.Format(db_domain, DB_NOT_FOUND, + "No such song: %s", uri); #ifndef NDEBUG else ++const_cast(borrowed_song_count); @@ -248,7 +235,7 @@ SimpleDatabase::Visit(const DatabaseSelection &selection, VisitDirectory visit_directory, VisitSong visit_song, VisitPlaylist visit_playlist, - GError **error_r) const + Error &error) const { ScopeDatabaseLock protect; @@ -258,42 +245,41 @@ SimpleDatabase::Visit(const DatabaseSelection &selection, Song *song = root->LookupSong(selection.uri); if (song != nullptr) return !selection.Match(*song) || - visit_song(*song, error_r); + visit_song(*song, error); } - g_set_error(error_r, db_quark(), DB_NOT_FOUND, - "No such directory"); + error.Set(db_domain, DB_NOT_FOUND, "No such directory"); return false; } if (selection.recursive && visit_directory && - !visit_directory(*directory, error_r)) + !visit_directory(*directory, error)) return false; return directory->Walk(selection.recursive, selection.filter, visit_directory, visit_song, visit_playlist, - error_r); + error); } bool SimpleDatabase::VisitUniqueTags(const DatabaseSelection &selection, enum tag_type tag_type, VisitString visit_string, - GError **error_r) const + Error &error) const { return ::VisitUniqueTags(*this, selection, tag_type, visit_string, - error_r); + error); } bool SimpleDatabase::GetStats(const DatabaseSelection &selection, - DatabaseStats &stats, GError **error_r) const + DatabaseStats &stats, Error &error) const { - return ::GetStats(*this, selection, stats, error_r); + return ::GetStats(*this, selection, stats, error); } bool -SimpleDatabase::Save(GError **error_r) +SimpleDatabase::Save(Error &error) { db_lock(); @@ -309,18 +295,15 @@ SimpleDatabase::Save(GError **error_r) FILE *fp = FOpen(path, FOpenMode::WriteText); if (!fp) { - g_set_error(error_r, simple_db_quark(), errno, - "unable to write to db file \"%s\": %s", - path_utf8.c_str(), g_strerror(errno)); + error.FormatErrno("unable to write to db file \"%s\"", + path_utf8.c_str()); return false; } db_save_internal(fp, root); if (ferror(fp)) { - g_set_error(error_r, simple_db_quark(), errno, - "Failed to write to database file: %s", - g_strerror(errno)); + error.SetErrno("Failed to write to database file"); fclose(fp); return false; } diff --git a/src/db/SimpleDatabasePlugin.hxx b/src/db/SimpleDatabasePlugin.hxx index 7250ea063..5de52cdeb 100644 --- a/src/db/SimpleDatabasePlugin.hxx +++ b/src/db/SimpleDatabasePlugin.hxx @@ -53,7 +53,7 @@ public: return root; } - bool Save(GError **error_r); + bool Save(Error &error); gcc_pure time_t GetLastModified() const { @@ -61,37 +61,37 @@ public: } static Database *Create(const config_param ¶m, - GError **error_r); + Error &error); - virtual bool Open(GError **error_r) override; + virtual bool Open(Error &error) override; virtual void Close() override; virtual Song *GetSong(const char *uri_utf8, - GError **error_r) const override; + Error &error) const override; virtual void ReturnSong(Song *song) const; virtual bool Visit(const DatabaseSelection &selection, VisitDirectory visit_directory, VisitSong visit_song, VisitPlaylist visit_playlist, - GError **error_r) const override; + Error &error) const override; virtual bool VisitUniqueTags(const DatabaseSelection &selection, enum tag_type tag_type, VisitString visit_string, - GError **error_r) const override; + Error &error) const override; virtual bool GetStats(const DatabaseSelection &selection, DatabaseStats &stats, - GError **error_r) const override; + Error &error) const override; protected: - bool Configure(const config_param ¶m, GError **error_r); + bool Configure(const config_param ¶m, Error &error); gcc_pure - bool Check(GError **error_r) const; + bool Check(Error &error) const; - bool Load(GError **error_r); + bool Load(Error &error); gcc_pure const Directory *LookupDirectory(const char *uri) const; -- cgit v1.2.3