| From e6cf7fb1960f544357925fed03e6c738e678f89b Mon Sep 17 00:00:00 2001 |
| From: Vaibhav Rustagi <vaibhavrustagi@google.com> |
| Date: Tue, 21 Sep 2021 09:57:31 -0700 |
| Subject: [PATCH] libbrillo: remove glib usage |
| |
| We're ugprading glib to latest 2.68 which causes an API |
| breakage and considering it is not used anymore in favor |
| of libchrome, we drop glib support instead of fixing it. |
| |
| ChromeOS Reference: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/3103795/ |
| |
| Change-Id: I357b04beb1a4042e3d369189c56e4ddcb536ec08 |
| --- |
| BUILD.gn | 42 -- |
| brillo/glib/README.md | 5 - |
| brillo/glib/abstract_dbus_service.cc | 33 -- |
| brillo/glib/abstract_dbus_service.h | 50 -- |
| brillo/glib/dbus.cc | 331 ------------ |
| brillo/glib/dbus.h | 450 ----------------- |
| brillo/glib/object.h | 469 ------------------ |
| brillo/glib/object_test.cc | 132 ----- |
| 8 files changed, 1512 deletions(-) |
| delete mode 100644 brillo/glib/README.md |
| delete mode 100644 brillo/glib/abstract_dbus_service.cc |
| delete mode 100644 brillo/glib/abstract_dbus_service.h |
| delete mode 100644 brillo/glib/dbus.cc |
| delete mode 100644 brillo/glib/dbus.h |
| delete mode 100644 brillo/glib/object.h |
| delete mode 100644 brillo/glib/object_test.cc |
| |
| diff --git a/BUILD.gn b/BUILD.gn |
| index 7b2073b451..b263e02074 100644 |
| --- a/BUILD.gn |
| +++ b/BUILD.gn |
| @@ -9,7 +9,6 @@ import("//common-mk/proto_library.gni") |
| group("all") { |
| deps = [ |
| ":libbrillo", |
| - ":libbrillo-glib", |
| ":libbrillo-test", |
| ":libinstallattributes", |
| ":libpolicy", |
| @@ -392,45 +391,6 @@ shared_library("libpolicy") { |
| ] |
| } |
| |
| -libbrillo_glib_pkg_deps = [ |
| - "glib-2.0", |
| - "gobject-2.0", |
| -] |
| -if (use.dbus) { |
| - libbrillo_glib_pkg_deps += [ |
| - "dbus-1", |
| - "dbus-glib-1", |
| - ] |
| -} |
| - |
| -generate_pkg_config("libbrillo-glib_pc") { |
| - name = "libbrillo-glib" |
| - output_name = "libbrillo-glib" |
| - description = "brillo glib wrapper library" |
| - version = libbase_ver |
| - requires_private = libbrillo_glib_pkg_deps |
| - libs = [ "-lbrillo-glib" ] |
| -} |
| - |
| -shared_library("libbrillo-glib") { |
| - configs += [ ":target_defaults" ] |
| - cflags = [ |
| - # glib uses the deprecated "register" attribute in some header files. |
| - "-Wno-deprecated-register", |
| - ] |
| - deps = [ |
| - ":libbrillo", |
| - ":libbrillo-glib_pc", |
| - ] |
| - all_dependent_pkg_deps = libbrillo_glib_pkg_deps |
| - if (use.dbus) { |
| - sources = [ |
| - "brillo/glib/abstract_dbus_service.cc", |
| - "brillo/glib/dbus.cc", |
| - ] |
| - } |
| -} |
| - |
| if (use.test) { |
| static_library("libbrillo_static") { |
| configs += [ ":target_defaults" ] |
| @@ -469,7 +429,6 @@ if (use.test) { |
| "brillo/files/file_util_test.cc", |
| "brillo/files/safe_fd_test.cc", |
| "brillo/flag_helper_test.cc", |
| - "brillo/glib/object_test.cc", |
| "brillo/http/http_connection_curl_test.cc", |
| "brillo/http/http_form_data_test.cc", |
| "brillo/http/http_request_test.cc", |
| @@ -537,7 +496,6 @@ if (use.test) { |
| cflags = [ "-Wno-format-zero-length" ] |
| pkg_deps = [ "libchrome-test" ] |
| deps = [ |
| - ":libbrillo-glib", |
| ":libbrillo-test", |
| ":libbrillo_static", |
| ":libbrillo_tests_proto", |
| diff --git a/brillo/glib/README.md b/brillo/glib/README.md |
| deleted file mode 100644 |
| index ef9ec9ee85..0000000000 |
| --- a/brillo/glib/README.md |
| +++ /dev/null |
| @@ -1,5 +0,0 @@ |
| -# libbrillo GLib support |
| - |
| -GLib is deprecated in Chrome OS. Use [libchrome] instead. |
| - |
| -[libchrome]: ../../../libchrome |
| diff --git a/brillo/glib/abstract_dbus_service.cc b/brillo/glib/abstract_dbus_service.cc |
| deleted file mode 100644 |
| index 4f3869715e..0000000000 |
| --- a/brillo/glib/abstract_dbus_service.cc |
| +++ /dev/null |
| @@ -1,33 +0,0 @@ |
| -// Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| -// Use of this source code is governed by a BSD-style license that can be |
| -// found in the LICENSE file. |
| - |
| -#include <base/logging.h> |
| - |
| -#include "brillo/glib/abstract_dbus_service.h" |
| - |
| -namespace brillo { |
| -namespace dbus { |
| - |
| -bool AbstractDbusService::Register(const brillo::dbus::BusConnection& conn) { |
| - return RegisterExclusiveService(conn, service_interface(), service_name(), |
| - service_path(), service_object()); |
| -} |
| - |
| -bool AbstractDbusService::Run() { |
| - if (!main_loop()) { |
| - LOG(ERROR) << "No run loop. Call Initialize before use."; |
| - return false; |
| - } |
| - ::g_main_loop_run(main_loop()); |
| - DLOG(INFO) << "Run() completed"; |
| - return true; |
| -} |
| - |
| -bool AbstractDbusService::Shutdown() { |
| - ::g_main_loop_quit(main_loop()); |
| - return true; |
| -} |
| - |
| -} // namespace dbus |
| -} // namespace brillo |
| diff --git a/brillo/glib/abstract_dbus_service.h b/brillo/glib/abstract_dbus_service.h |
| deleted file mode 100644 |
| index 32725c71bf..0000000000 |
| --- a/brillo/glib/abstract_dbus_service.h |
| +++ /dev/null |
| @@ -1,50 +0,0 @@ |
| -// Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| -// Use of this source code is governed by a BSD-style license that can be |
| -// found in the LICENSE file. |
| - |
| -#ifndef LIBBRILLO_BRILLO_GLIB_ABSTRACT_DBUS_SERVICE_H_ |
| -#define LIBBRILLO_BRILLO_GLIB_ABSTRACT_DBUS_SERVICE_H_ |
| - |
| -// IMPORTANT: Do not use this in new code. Instead, use |
| -// <brillo/daemons/dbus_daemon.h>. See https://goo.gl/EH3MmR for more details. |
| - |
| -#include <brillo/brillo_export.h> |
| -#include <brillo/glib/dbus.h> |
| - |
| -namespace brillo { |
| - |
| -namespace dbus { |
| -class BRILLO_EXPORT AbstractDbusService { |
| - public: |
| - virtual ~AbstractDbusService() {} |
| - |
| - // Setup the wrapped GObject and the GMainLoop |
| - virtual bool Initialize() = 0; |
| - virtual bool Reset() = 0; |
| - |
| - // Registers the GObject as a service with the system DBus |
| - // TODO(wad) make this testable by making BusConn and Proxy |
| - // subclassing friendly. |
| - virtual bool Register(const brillo::dbus::BusConnection& conn); |
| - |
| - // Starts the run loop |
| - virtual bool Run(); |
| - |
| - // Stops the run loop |
| - virtual bool Shutdown(); |
| - |
| - // Used internally during registration to set the |
| - // proper service information. |
| - virtual const char* service_name() const = 0; |
| - virtual const char* service_path() const = 0; |
| - virtual const char* service_interface() const = 0; |
| - virtual GObject* service_object() const = 0; |
| - |
| - protected: |
| - virtual GMainLoop* main_loop() = 0; |
| -}; |
| - |
| -} // namespace dbus |
| -} // namespace brillo |
| - |
| -#endif // LIBBRILLO_BRILLO_GLIB_ABSTRACT_DBUS_SERVICE_H_ |
| diff --git a/brillo/glib/dbus.cc b/brillo/glib/dbus.cc |
| deleted file mode 100644 |
| index 7525adfdfa..0000000000 |
| --- a/brillo/glib/dbus.cc |
| +++ /dev/null |
| @@ -1,331 +0,0 @@ |
| -// Copyright (c) 2009 The Chromium OS Authors. All rights reserved. |
| -// Use of this source code is governed by a BSD-style license that can be |
| -// found in the LICENSE file. |
| - |
| -#include "brillo/glib/dbus.h" |
| - |
| -#include <base/check.h> |
| -#include <dbus/dbus.h> |
| -#include <dbus/dbus-glib-bindings.h> |
| -#include <dbus/dbus-glib-lowlevel.h> |
| - |
| -#include <base/logging.h> |
| -#include <base/strings/stringprintf.h> |
| - |
| -namespace brillo { |
| -namespace dbus { |
| - |
| -bool CallPtrArray(const Proxy& proxy, |
| - const char* method, |
| - glib::ScopedPtrArray<const char*>* result) { |
| - glib::ScopedError error; |
| - |
| - ::GType g_type_array = |
| - ::dbus_g_type_get_collection("GPtrArray", DBUS_TYPE_G_OBJECT_PATH); |
| - |
| - if (!::dbus_g_proxy_call(proxy.gproxy(), method, &Resetter(&error).lvalue(), |
| - G_TYPE_INVALID, g_type_array, |
| - &Resetter(result).lvalue(), G_TYPE_INVALID)) { |
| - LOG(WARNING) << "CallPtrArray failed: " |
| - << (error->message ? error->message : "Unknown Error."); |
| - return false; |
| - } |
| - |
| - return true; |
| -} |
| - |
| -BusConnection GetSystemBusConnection() { |
| - glib::ScopedError error; |
| - ::DBusGConnection* result = |
| - ::dbus_g_bus_get(DBUS_BUS_SYSTEM, &Resetter(&error).lvalue()); |
| - if (!result) { |
| - LOG(ERROR) << "dbus_g_bus_get(DBUS_BUS_SYSTEM) failed: " |
| - << ((error.get() && error->message) ? error->message |
| - : "Unknown Error"); |
| - return BusConnection(nullptr); |
| - } |
| - // Set to not exit when system bus is disconnected. |
| - // This fixes the problem where when the dbus daemon is stopped, exit is |
| - // called which kills Chrome. |
| - ::dbus_connection_set_exit_on_disconnect( |
| - ::dbus_g_connection_get_connection(result), FALSE); |
| - return BusConnection(result); |
| -} |
| - |
| -BusConnection GetPrivateBusConnection(const char* address) { |
| - // Since dbus-glib does not have an API like dbus_g_connection_open_private(), |
| - // we have to implement our own. |
| - |
| - // We have to call _dbus_g_value_types_init() to register standard marshalers |
| - // just like as dbus_g_bus_get() and dbus_g_connection_open() do, but the |
| - // function is not exported. So we call GetPrivateBusConnection() which calls |
| - // dbus_g_bus_get() here instead. Note that if we don't call |
| - // _dbus_g_value_types_init(), we might get "WARNING **: No demarshaller |
| - // registered for type xxxxx" error and might not be able to handle incoming |
| - // signals nor method calls. |
| - { |
| - BusConnection system_bus_connection = GetSystemBusConnection(); |
| - if (!system_bus_connection.HasConnection()) { |
| - return system_bus_connection; // returns NULL connection. |
| - } |
| - } |
| - |
| - ::DBusError error; |
| - ::dbus_error_init(&error); |
| - |
| - ::DBusGConnection* result = nullptr; |
| - ::DBusConnection* raw_connection = |
| - ::dbus_connection_open_private(address, &error); |
| - if (!raw_connection) { |
| - LOG(WARNING) << "dbus_connection_open_private failed: " << address; |
| - return BusConnection(nullptr); |
| - } |
| - |
| - if (!::dbus_bus_register(raw_connection, &error)) { |
| - LOG(ERROR) << "dbus_bus_register failed: " |
| - << (error.message ? error.message : "Unknown Error."); |
| - ::dbus_error_free(&error); |
| - // TODO(yusukes): We don't call dbus_connection_close() nor g_object_unref() |
| - // here for now since these calls might interfere with IBusBus connections |
| - // in libcros and Chrome. See the comment in ~InputMethodStatusConnection() |
| - // function in platform/cros/chromeos_input_method.cc for details. |
| - return BusConnection(nullptr); |
| - } |
| - |
| - ::dbus_connection_setup_with_g_main(raw_connection, |
| - nullptr /* default context */); |
| - |
| - // A reference count of |raw_connection| is transferred to |result|. You don't |
| - // have to (and should not) unref the |raw_connection|. |
| - result = ::dbus_connection_get_g_connection(raw_connection); |
| - CHECK(result); |
| - |
| - ::dbus_connection_set_exit_on_disconnect( |
| - ::dbus_g_connection_get_connection(result), FALSE); |
| - |
| - return BusConnection(result); |
| -} |
| - |
| -bool RetrieveProperties(const Proxy& proxy, |
| - const char* interface, |
| - glib::ScopedHashTable* result) { |
| - glib::ScopedError error; |
| - |
| - if (!::dbus_g_proxy_call( |
| - proxy.gproxy(), "GetAll", &Resetter(&error).lvalue(), G_TYPE_STRING, |
| - interface, G_TYPE_INVALID, |
| - ::dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), |
| - &Resetter(result).lvalue(), G_TYPE_INVALID)) { |
| - LOG(WARNING) << "RetrieveProperties failed: " |
| - << (error->message ? error->message : "Unknown Error."); |
| - return false; |
| - } |
| - return true; |
| -} |
| - |
| -Proxy::Proxy() : object_(nullptr) {} |
| - |
| -// Set |connect_to_name_owner| true if you'd like to use |
| -// dbus_g_proxy_new_for_name_owner() rather than dbus_g_proxy_new_for_name(). |
| -Proxy::Proxy(const BusConnection& connection, |
| - const char* name, |
| - const char* path, |
| - const char* interface, |
| - bool connect_to_name_owner) |
| - : object_(GetGProxy( |
| - connection, name, path, interface, connect_to_name_owner)) {} |
| - |
| -// Equivalent to Proxy(connection, name, path, interface, false). |
| -Proxy::Proxy(const BusConnection& connection, |
| - const char* name, |
| - const char* path, |
| - const char* interface) |
| - : object_(GetGProxy(connection, name, path, interface, false)) {} |
| - |
| -// Creates a peer proxy using dbus_g_proxy_new_for_peer. |
| -Proxy::Proxy(const BusConnection& connection, |
| - const char* path, |
| - const char* interface) |
| - : object_(GetGPeerProxy(connection, path, interface)) {} |
| - |
| -Proxy::Proxy(const Proxy& x) : object_(x.object_) { |
| - if (object_) |
| - ::g_object_ref(object_); |
| -} |
| - |
| -Proxy::~Proxy() { |
| - if (object_) |
| - ::g_object_unref(object_); |
| -} |
| - |
| -/* static */ |
| -Proxy::value_type Proxy::GetGProxy(const BusConnection& connection, |
| - const char* name, |
| - const char* path, |
| - const char* interface, |
| - bool connect_to_name_owner) { |
| - value_type result = nullptr; |
| - if (connect_to_name_owner) { |
| - glib::ScopedError error; |
| - result = ::dbus_g_proxy_new_for_name_owner( |
| - connection.object_, name, path, interface, &Resetter(&error).lvalue()); |
| - if (!result) { |
| - DLOG(ERROR) << "Failed to construct proxy: " |
| - << (error->message ? error->message : "Unknown Error") << ": " |
| - << path; |
| - } |
| - } else { |
| - result = |
| - ::dbus_g_proxy_new_for_name(connection.object_, name, path, interface); |
| - if (!result) { |
| - LOG(ERROR) << "Failed to construct proxy: " << path; |
| - } |
| - } |
| - return result; |
| -} |
| - |
| -/* static */ |
| -Proxy::value_type Proxy::GetGPeerProxy(const BusConnection& connection, |
| - const char* path, |
| - const char* interface) { |
| - value_type result = |
| - ::dbus_g_proxy_new_for_peer(connection.object_, path, interface); |
| - if (!result) |
| - LOG(ERROR) << "Failed to construct peer proxy: " << path; |
| - |
| - return result; |
| -} |
| - |
| -bool RegisterExclusiveService(const BusConnection& connection, |
| - const char* interface_name, |
| - const char* service_name, |
| - const char* service_path, |
| - GObject* object) { |
| - CHECK(object); |
| - CHECK(interface_name); |
| - CHECK(service_name); |
| - // Create a proxy to DBus itself so that we can request to become a |
| - // service name owner and then register an object at the related service path. |
| - Proxy proxy = brillo::dbus::Proxy(connection, DBUS_SERVICE_DBUS, |
| - DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); |
| - // Exclusivity is determined by replacing any existing |
| - // service, not queuing, and ensuring we are the primary |
| - // owner after the name is ours. |
| - glib::ScopedError err; |
| - guint result = 0; |
| - // TODO(wad) determine if we are moving away from using generated functions |
| - if (!org_freedesktop_DBus_request_name(proxy.gproxy(), service_name, 0, |
| - &result, &Resetter(&err).lvalue())) { |
| - LOG(ERROR) << "Unable to request service name: " |
| - << (err->message ? err->message : "Unknown Error."); |
| - return false; |
| - } |
| - |
| - // Handle the error codes, releasing the name if exclusivity conditions |
| - // are not met. |
| - bool needs_release = false; |
| - if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { |
| - LOG(ERROR) << "Failed to become the primary owner. Releasing . . ."; |
| - needs_release = true; |
| - } |
| - if (result == DBUS_REQUEST_NAME_REPLY_EXISTS) { |
| - LOG(ERROR) << "Service name exists: " << service_name; |
| - return false; |
| - } else if (result == DBUS_REQUEST_NAME_REPLY_IN_QUEUE) { |
| - LOG(ERROR) << "Service name request enqueued despite our flags. Releasing"; |
| - needs_release = true; |
| - } |
| - LOG_IF(WARNING, result == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER) |
| - << "Service name already owned by this process"; |
| - if (needs_release) { |
| - if (!org_freedesktop_DBus_release_name(proxy.gproxy(), service_name, |
| - &result, &Resetter(&err).lvalue())) { |
| - LOG(ERROR) << "Unabled to release service name: " |
| - << (err->message ? err->message : "Unknown Error."); |
| - } |
| - DLOG(INFO) << "ReleaseName returned code " << result; |
| - return false; |
| - } |
| - |
| - // Determine a path from the service name and register the object. |
| - dbus_g_connection_register_g_object(connection.g_connection(), service_path, |
| - object); |
| - return true; |
| -} |
| - |
| -void CallMethodWithNoArguments(const char* service_name, |
| - const char* path, |
| - const char* interface_name, |
| - const char* method_name) { |
| - Proxy proxy(dbus::GetSystemBusConnection(), service_name, path, |
| - interface_name); |
| - ::dbus_g_proxy_call_no_reply(proxy.gproxy(), method_name, G_TYPE_INVALID); |
| -} |
| - |
| -void SignalWatcher::StartMonitoring(const std::string& interface, |
| - const std::string& signal) { |
| - DCHECK(interface_.empty()) << "StartMonitoring() must be called only once"; |
| - interface_ = interface; |
| - signal_ = signal; |
| - |
| - // Snoop on D-Bus messages so we can get notified about signals. |
| - DBusConnection* dbus_conn = |
| - dbus_g_connection_get_connection(GetSystemBusConnection().g_connection()); |
| - DCHECK(dbus_conn); |
| - |
| - DBusError error; |
| - dbus_error_init(&error); |
| - dbus_bus_add_match(dbus_conn, GetDBusMatchString().c_str(), &error); |
| - if (dbus_error_is_set(&error)) { |
| - LOG(DFATAL) << "Got error while adding D-Bus match rule: " << error.name |
| - << " (" << error.message << ")"; |
| - } |
| - |
| - if (!dbus_connection_add_filter(dbus_conn, &SignalWatcher::FilterDBusMessage, |
| - this, // user_data |
| - nullptr)) { // free_data_function |
| - LOG(DFATAL) << "Unable to add D-Bus filter"; |
| - } |
| -} |
| - |
| -SignalWatcher::~SignalWatcher() { |
| - if (interface_.empty()) |
| - return; |
| - |
| - DBusConnection* dbus_conn = dbus_g_connection_get_connection( |
| - dbus::GetSystemBusConnection().g_connection()); |
| - DCHECK(dbus_conn); |
| - |
| - dbus_connection_remove_filter(dbus_conn, &SignalWatcher::FilterDBusMessage, |
| - this); |
| - |
| - DBusError error; |
| - dbus_error_init(&error); |
| - dbus_bus_remove_match(dbus_conn, GetDBusMatchString().c_str(), &error); |
| - if (dbus_error_is_set(&error)) { |
| - LOG(DFATAL) << "Got error while removing D-Bus match rule: " << error.name |
| - << " (" << error.message << ")"; |
| - } |
| -} |
| - |
| -std::string SignalWatcher::GetDBusMatchString() const { |
| - return base::StringPrintf("type='signal', interface='%s', member='%s'", |
| - interface_.c_str(), signal_.c_str()); |
| -} |
| - |
| -/* static */ |
| -DBusHandlerResult SignalWatcher::FilterDBusMessage(DBusConnection* dbus_conn, |
| - DBusMessage* message, |
| - void* data) { |
| - SignalWatcher* self = static_cast<SignalWatcher*>(data); |
| - if (dbus_message_is_signal(message, self->interface_.c_str(), |
| - self->signal_.c_str())) { |
| - self->OnSignal(message); |
| - return DBUS_HANDLER_RESULT_HANDLED; |
| - } else { |
| - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; |
| - } |
| -} |
| - |
| -} // namespace dbus |
| -} // namespace brillo |
| diff --git a/brillo/glib/dbus.h b/brillo/glib/dbus.h |
| deleted file mode 100644 |
| index 299d65159e..0000000000 |
| --- a/brillo/glib/dbus.h |
| +++ /dev/null |
| @@ -1,450 +0,0 @@ |
| -// Copyright (c) 2009 The Chromium OS Authors. All rights reserved. |
| -// Use of this source code is governed by a BSD-style license that can be |
| -// found in the LICENSE file. |
| - |
| -#ifndef LIBBRILLO_BRILLO_GLIB_DBUS_H_ |
| -#define LIBBRILLO_BRILLO_GLIB_DBUS_H_ |
| - |
| -// IMPORTANT: Do not use this in new code. Instead, use libchrome's D-Bus |
| -// bindings. See https://goo.gl/EH3MmR for more details. |
| - |
| -#include <base/check.h> |
| -#include <dbus/dbus-glib.h> |
| -#include <glib-object.h> |
| - |
| -#include <algorithm> |
| -#include <string> |
| -#include <utility> |
| - |
| -#include "base/logging.h" |
| -#include <brillo/brillo_export.h> |
| -#include <brillo/glib/object.h> |
| - |
| -struct DBusMessage; |
| -struct DBusConnection; |
| - |
| -namespace brillo { |
| - |
| -namespace dbus { |
| - |
| -// \brief BusConnection manages the ref-count for a ::DBusGConnection*. |
| -// |
| -// A BusConnection has reference semantics bound to a particular communication |
| -// bus. |
| -// |
| -// \models Copyable, Assignable |
| -// \related GetSystemBusConnection() |
| - |
| -class BRILLO_EXPORT BusConnection { |
| - public: |
| - typedef ::DBusGConnection* value_type; |
| - |
| - BusConnection(const BusConnection& x) : object_(x.object_) { |
| - if (object_) |
| - ::dbus_g_connection_ref(object_); |
| - } |
| - |
| - ~BusConnection() { |
| - if (object_) |
| - ::dbus_g_connection_unref(object_); |
| - } |
| - |
| - BusConnection& operator=(BusConnection x) { |
| - swap(*this, x); |
| - return *this; |
| - } |
| - |
| - const value_type& g_connection() const { |
| - DCHECK(object_) << "referencing an empty connection"; |
| - return object_; |
| - } |
| - |
| - operator bool() const { return object_; } |
| - |
| - bool HasConnection() const { return object_; } |
| - |
| - private: |
| - friend void swap(BusConnection& x, BusConnection& y); |
| - |
| - friend class Proxy; |
| - friend BusConnection GetSystemBusConnection(); |
| - friend BusConnection GetPrivateBusConnection(const char* address); |
| - |
| - // Constructor takes ownership |
| - BRILLO_PRIVATE explicit BusConnection(::DBusGConnection* x) : object_(x) {} |
| - |
| - value_type object_; |
| -}; |
| - |
| -inline void swap(BusConnection& x, BusConnection& y) { |
| - std::swap(x.object_, y.object_); |
| -} |
| - |
| -// \brief Proxy manages the ref-count for a ::DBusGProxy*. |
| -// |
| -// Proxy has reference semantics and represents a connection to on object on |
| -// the bus. A proxy object is constructed with a connection to a bus, a name |
| -// to an entity on the bus, a path to an object owned by the entity, and an |
| -// interface protocol name used to communicate with the object. |
| - |
| -class BRILLO_EXPORT Proxy { |
| - public: |
| - typedef ::DBusGProxy* value_type; |
| - |
| - Proxy(); |
| - |
| - // Set |connect_to_name_owner| true if you'd like to use |
| - // dbus_g_proxy_new_for_name_owner() rather than dbus_g_proxy_new_for_name(). |
| - Proxy(const BusConnection& connection, |
| - const char* name, |
| - const char* path, |
| - const char* interface, |
| - bool connect_to_name_owner); |
| - |
| - // Equivalent to Proxy(connection, name, path, interface, false). |
| - Proxy(const BusConnection& connection, |
| - const char* name, |
| - const char* path, |
| - const char* interface); |
| - |
| - // Creates a peer proxy using dbus_g_proxy_new_for_peer. |
| - Proxy(const BusConnection& connection, |
| - const char* path, |
| - const char* interface); |
| - |
| - Proxy(const Proxy& x); |
| - |
| - ~Proxy(); |
| - |
| - Proxy& operator=(Proxy x) { |
| - swap(*this, x); |
| - return *this; |
| - } |
| - |
| - const char* path() const { |
| - DCHECK(object_) << "referencing an empty proxy"; |
| - return ::dbus_g_proxy_get_path(object_); |
| - } |
| - |
| - // gproxy() returns a reference to the underlying ::DBusGProxy*. As this |
| - // library evolves, the gproxy() will be moved to be private. |
| - |
| - const value_type& gproxy() const { |
| - DCHECK(object_) << "referencing an empty proxy"; |
| - return object_; |
| - } |
| - |
| - operator bool() const { return object_; } |
| - |
| - private: |
| - BRILLO_PRIVATE static value_type GetGProxy(const BusConnection& connection, |
| - const char* name, |
| - const char* path, |
| - const char* interface, |
| - bool connect_to_name_owner); |
| - |
| - BRILLO_PRIVATE static value_type GetGPeerProxy( |
| - const BusConnection& connection, const char* path, const char* interface); |
| - |
| - BRILLO_PRIVATE operator int() const; // for safe bool cast |
| - friend void swap(Proxy& x, Proxy& y); |
| - |
| - value_type object_; |
| -}; |
| - |
| -inline void swap(Proxy& x, Proxy& y) { |
| - std::swap(x.object_, y.object_); |
| -} |
| - |
| -// \brief RegisterExclusiveService configures a GObject to run as a service on |
| -// a supplied ::BusConnection. |
| -// |
| -// RegisterExclusiveService encapsulates the process of configuring the |
| -// supplied \param object at \param service_path on the \param connection. |
| -// Exclusivity is ensured by replacing any existing services at that named |
| -// location and confirming that the connection is the primary owner. |
| -// |
| -// Type information for the \param object must be installed with |
| -// dbus_g_object_type_install_info prior to use. |
| - |
| -BRILLO_EXPORT bool RegisterExclusiveService(const BusConnection& connection, |
| - const char* interface_name, |
| - const char* service_name, |
| - const char* service_path, |
| - GObject* object); |
| - |
| -template <typename F> // F is a function signature |
| -class MonitorConnection; |
| - |
| -template <typename A1> |
| -class MonitorConnection<void(A1)> { |
| - public: |
| - MonitorConnection(const Proxy& proxy, |
| - const char* name, |
| - void (*monitor)(void*, A1), |
| - void* object) |
| - : proxy_(proxy), name_(name), monitor_(monitor), object_(object) {} |
| - |
| - static void Run(::DBusGProxy*, A1 x, MonitorConnection* self) { |
| - self->monitor_(self->object_, x); |
| - } |
| - const Proxy& proxy() const { return proxy_; } |
| - const std::string& name() const { return name_; } |
| - |
| - private: |
| - Proxy proxy_; |
| - std::string name_; |
| - void (*monitor_)(void*, A1); |
| - void* object_; |
| -}; |
| - |
| -template <typename A1, typename A2> |
| -class MonitorConnection<void(A1, A2)> { |
| - public: |
| - MonitorConnection(const Proxy& proxy, |
| - const char* name, |
| - void (*monitor)(void*, A1, A2), |
| - void* object) |
| - : proxy_(proxy), name_(name), monitor_(monitor), object_(object) {} |
| - |
| - static void Run(::DBusGProxy*, A1 x, A2 y, MonitorConnection* self) { |
| - self->monitor_(self->object_, x, y); |
| - } |
| - const Proxy& proxy() const { return proxy_; } |
| - const std::string& name() const { return name_; } |
| - |
| - private: |
| - Proxy proxy_; |
| - std::string name_; |
| - void (*monitor_)(void*, A1, A2); |
| - void* object_; |
| -}; |
| - |
| -template <typename A1, typename A2, typename A3> |
| -class MonitorConnection<void(A1, A2, A3)> { |
| - public: |
| - MonitorConnection(const Proxy& proxy, |
| - const char* name, |
| - void (*monitor)(void*, A1, A2, A3), |
| - void* object) |
| - : proxy_(proxy), name_(name), monitor_(monitor), object_(object) {} |
| - |
| - static void Run(::DBusGProxy*, A1 x, A2 y, A3 z, MonitorConnection* self) { |
| - self->monitor_(self->object_, x, y, z); |
| - } |
| - const Proxy& proxy() const { return proxy_; } |
| - const std::string& name() const { return name_; } |
| - |
| - private: |
| - Proxy proxy_; |
| - std::string name_; |
| - void (*monitor_)(void*, A1, A2, A3); |
| - void* object_; |
| -}; |
| - |
| -template <typename A1, typename A2, typename A3, typename A4> |
| -class MonitorConnection<void(A1, A2, A3, A4)> { |
| - public: |
| - MonitorConnection(const Proxy& proxy, |
| - const char* name, |
| - void (*monitor)(void*, A1, A2, A3, A4), |
| - void* object) |
| - : proxy_(proxy), name_(name), monitor_(monitor), object_(object) {} |
| - |
| - static void Run( |
| - ::DBusGProxy*, A1 x, A2 y, A3 z, A4 w, MonitorConnection* self) { |
| - self->monitor_(self->object_, x, y, z, w); |
| - } |
| - const Proxy& proxy() const { return proxy_; } |
| - const std::string& name() const { return name_; } |
| - |
| - private: |
| - Proxy proxy_; |
| - std::string name_; |
| - void (*monitor_)(void*, A1, A2, A3, A4); |
| - void* object_; |
| -}; |
| - |
| -template <typename A1> |
| -MonitorConnection<void(A1)>* Monitor(const Proxy& proxy, |
| - const char* name, |
| - void (*monitor)(void*, A1), |
| - void* object) { |
| - typedef MonitorConnection<void(A1)> ConnectionType; |
| - |
| - ConnectionType* result = new ConnectionType(proxy, name, monitor, object); |
| - |
| - ::dbus_g_proxy_add_signal(proxy.gproxy(), name, glib::type_to_gtypeid<A1>(), |
| - G_TYPE_INVALID); |
| - ::dbus_g_proxy_connect_signal( |
| - proxy.gproxy(), name, G_CALLBACK(&ConnectionType::Run), result, nullptr); |
| - return result; |
| -} |
| - |
| -template <typename A1, typename A2> |
| -MonitorConnection<void(A1, A2)>* Monitor(const Proxy& proxy, |
| - const char* name, |
| - void (*monitor)(void*, A1, A2), |
| - void* object) { |
| - typedef MonitorConnection<void(A1, A2)> ConnectionType; |
| - |
| - ConnectionType* result = new ConnectionType(proxy, name, monitor, object); |
| - |
| - ::dbus_g_proxy_add_signal(proxy.gproxy(), name, glib::type_to_gtypeid<A1>(), |
| - glib::type_to_gtypeid<A2>(), G_TYPE_INVALID); |
| - ::dbus_g_proxy_connect_signal( |
| - proxy.gproxy(), name, G_CALLBACK(&ConnectionType::Run), result, nullptr); |
| - return result; |
| -} |
| - |
| -template <typename A1, typename A2, typename A3> |
| -MonitorConnection<void(A1, A2, A3)>* Monitor(const Proxy& proxy, |
| - const char* name, |
| - void (*monitor)(void*, A1, A2, A3), |
| - void* object) { |
| - typedef MonitorConnection<void(A1, A2, A3)> ConnectionType; |
| - |
| - ConnectionType* result = new ConnectionType(proxy, name, monitor, object); |
| - |
| - ::dbus_g_proxy_add_signal(proxy.gproxy(), name, glib::type_to_gtypeid<A1>(), |
| - glib::type_to_gtypeid<A2>(), |
| - glib::type_to_gtypeid<A3>(), G_TYPE_INVALID); |
| - ::dbus_g_proxy_connect_signal( |
| - proxy.gproxy(), name, G_CALLBACK(&ConnectionType::Run), result, nullptr); |
| - return result; |
| -} |
| - |
| -template <typename A1, typename A2, typename A3, typename A4> |
| -MonitorConnection<void(A1, A2, A3, A4)>* Monitor( |
| - const Proxy& proxy, |
| - const char* name, |
| - void (*monitor)(void*, A1, A2, A3, A4), |
| - void* object) { |
| - typedef MonitorConnection<void(A1, A2, A3, A4)> ConnectionType; |
| - |
| - ConnectionType* result = new ConnectionType(proxy, name, monitor, object); |
| - |
| - ::dbus_g_proxy_add_signal(proxy.gproxy(), name, glib::type_to_gtypeid<A1>(), |
| - glib::type_to_gtypeid<A2>(), |
| - glib::type_to_gtypeid<A3>(), |
| - glib::type_to_gtypeid<A4>(), G_TYPE_INVALID); |
| - ::dbus_g_proxy_connect_signal( |
| - proxy.gproxy(), name, G_CALLBACK(&ConnectionType::Run), result, nullptr); |
| - return result; |
| -} |
| - |
| -template <typename F> |
| -void Disconnect(MonitorConnection<F>* connection) { |
| - typedef MonitorConnection<F> ConnectionType; |
| - |
| - ::dbus_g_proxy_disconnect_signal( |
| - connection->proxy().gproxy(), connection->name().c_str(), |
| - G_CALLBACK(&ConnectionType::Run), connection); |
| - delete connection; |
| -} |
| - |
| -// \brief call_PtrArray() invokes a method on a proxy returning a |
| -// glib::PtrArray. |
| -// |
| -// CallPtrArray is the first instance of what is likely to be a general |
| -// way to make method calls to a proxy. It will likely be replaced with |
| -// something like Call(proxy, method, arg1, arg2, ..., ResultType*) in the |
| -// future. However, I don't yet have enough cases to generalize from. |
| - |
| -BRILLO_EXPORT bool CallPtrArray(const Proxy& proxy, |
| - const char* method, |
| - glib::ScopedPtrArray<const char*>* result); |
| - |
| -// \brief RetrieveProperty() retrieves a property of an object associated with a |
| -// proxy. |
| -// |
| -// Given a proxy to an object supporting the org.freedesktop.DBus.Properties |
| -// interface, the RetrieveProperty() call will retrieve a property of the |
| -// specified interface on the object storing it in \param result and returning |
| -// \true. If the dbus call fails or the object returned is not of type \param T, |
| -// then \false is returned and \param result is unchanged. |
| -// |
| -// \example |
| -// Proxy proxy(GetSystemBusConnection(), |
| -// "org.freedesktop.DeviceKit.Power", // A named entity on the bus |
| -// battery_name, // Path to a battery on the bus |
| -// "org.freedesktop.DBus.Properties") // Properties interface |
| -// |
| -// double x; |
| -// if (RetrieveProperty(proxy, |
| -// "org.freedesktop.DeviceKit.Power.Device", |
| -// "percentage") |
| -// std::cout << "Battery charge is " << x << "% of capacity."; |
| -// \end_example |
| - |
| -template <typename T> |
| -inline bool RetrieveProperty(const Proxy& proxy, |
| - const char* interface, |
| - const char* property, |
| - T* result) { |
| - glib::ScopedError error; |
| - glib::Value value; |
| - |
| - if (!::dbus_g_proxy_call(proxy.gproxy(), "Get", &Resetter(&error).lvalue(), |
| - G_TYPE_STRING, interface, G_TYPE_STRING, property, |
| - G_TYPE_INVALID, G_TYPE_VALUE, &value, |
| - G_TYPE_INVALID)) { |
| - LOG(ERROR) << "Getting property failed: " |
| - << (error->message ? error->message : "Unknown Error."); |
| - return false; |
| - } |
| - return glib::Retrieve(value, result); |
| -} |
| - |
| -// \brief RetrieveProperties returns a HashTable of all properties for the |
| -// specified interface. |
| - |
| -BRILLO_EXPORT bool RetrieveProperties(const Proxy& proxy, |
| - const char* interface, |
| - glib::ScopedHashTable* result); |
| - |
| -// \brief Returns a connection to the system bus. |
| - |
| -BRILLO_EXPORT BusConnection GetSystemBusConnection(); |
| - |
| -// \brief Returns a private connection to a bus at |address|. |
| - |
| -BRILLO_EXPORT BusConnection GetPrivateBusConnection(const char* address); |
| - |
| -// \brief Calls a method |method_name| with no arguments per the given |path| |
| -// and |interface_name|. Ignores return value. |
| - |
| -BRILLO_EXPORT void CallMethodWithNoArguments(const char* service_name, |
| - const char* path, |
| - const char* interface_name, |
| - const char* method_name); |
| - |
| -// \brief Low-level signal monitor base class. |
| -// |
| -// Used when there is no definite named signal sender (that Proxy |
| -// could be used for). |
| - |
| -class BRILLO_EXPORT SignalWatcher { |
| - public: |
| - SignalWatcher() {} |
| - ~SignalWatcher(); |
| - void StartMonitoring(const std::string& interface, const std::string& signal); |
| - |
| - private: |
| - // Callback invoked on the given signal arrival. |
| - virtual void OnSignal(DBusMessage* message) = 0; |
| - |
| - // Returns a string matching the D-Bus messages that we want to listen for. |
| - BRILLO_PRIVATE std::string GetDBusMatchString() const; |
| - |
| - // A D-Bus message filter to receive signals. |
| - BRILLO_PRIVATE static DBusHandlerResult FilterDBusMessage( |
| - DBusConnection* dbus_conn, DBusMessage* message, void* data); |
| - std::string interface_; |
| - std::string signal_; |
| -}; |
| - |
| -} // namespace dbus |
| -} // namespace brillo |
| - |
| -#endif // LIBBRILLO_BRILLO_GLIB_DBUS_H_ |
| diff --git a/brillo/glib/object.h b/brillo/glib/object.h |
| deleted file mode 100644 |
| index 87e5601648..0000000000 |
| --- a/brillo/glib/object.h |
| +++ /dev/null |
| @@ -1,469 +0,0 @@ |
| -// Copyright (c) 2009 The Chromium OS Authors. All rights reserved. |
| -// Use of this source code is governed by a BSD-style license that can be |
| -// found in the LICENSE file. |
| - |
| -#ifndef LIBBRILLO_BRILLO_GLIB_OBJECT_H_ |
| -#define LIBBRILLO_BRILLO_GLIB_OBJECT_H_ |
| - |
| -#include <glib-object.h> |
| -#include <stdint.h> |
| - |
| -#include <algorithm> |
| -#include <cstddef> |
| -#include <memory> |
| -#include <string> |
| -#include <utility> |
| - |
| -#include <base/check.h> |
| -#include <base/logging.h> |
| -#include <base/macros.h> |
| - |
| -namespace brillo { |
| - |
| -namespace details { // NOLINT |
| - |
| -// \brief ResetHelper is a private class for use with Resetter(). |
| -// |
| -// ResetHelper passes ownership of a pointer to a scoped pointer type with reset |
| -// on destruction. |
| - |
| -template <typename T> // T models ScopedPtr |
| -class ResetHelper { |
| - public: |
| - typedef typename T::element_type element_type; |
| - |
| - explicit ResetHelper(T* x) : ptr_(nullptr), scoped_(x) {} |
| - ~ResetHelper() { scoped_->reset(ptr_); } |
| - element_type*& lvalue() { return ptr_; } |
| - |
| - private: |
| - element_type* ptr_; |
| - T* scoped_; |
| -}; |
| - |
| -} // namespace details |
| - |
| -// \brief Resetter() is a utility function for passing pointers to |
| -// scoped pointers. |
| -// |
| -// The Resetter() function return a temporary object containing an lvalue of |
| -// \code T::element_type which can be assigned to. When the temporary object |
| -// destructs, the associated scoped pointer is reset with the lvalue. It is of |
| -// general use when a pointer is returned as an out-argument. |
| -// |
| -// \example |
| -// void function(int** x) { |
| -// *x = new int(10); |
| -// } |
| -// ... |
| -// std::unique_ptr<int> x; |
| -// function(Resetter(x).lvalue()); |
| -// |
| -// \end_example |
| - |
| -template <typename T> // T models ScopedPtr |
| -details::ResetHelper<T> Resetter(T* x) { |
| - return details::ResetHelper<T>(x); |
| -} |
| - |
| -namespace glib { |
| - |
| -// \brief type_to_gtypeid is a type function mapping from a canonical type to |
| -// the GType typeid for the associated GType (see type_to_gtype). |
| - |
| -template <typename T> |
| -::GType type_to_gtypeid(); |
| - |
| -template <> |
| -inline ::GType type_to_gtypeid<const char*>() { |
| - return G_TYPE_STRING; |
| -} |
| -template <> |
| -inline ::GType type_to_gtypeid<char*>() { |
| - return G_TYPE_STRING; |
| -} |
| -template <> |
| -inline ::GType type_to_gtypeid< ::uint8_t>() { |
| - return G_TYPE_UCHAR; |
| -} |
| -template <> |
| -inline ::GType type_to_gtypeid<double>() { |
| - return G_TYPE_DOUBLE; |
| -} |
| -template <> |
| -inline ::GType type_to_gtypeid<bool>() { |
| - return G_TYPE_BOOLEAN; |
| -} |
| -class Value; |
| -template <> |
| -inline ::GType type_to_gtypeid<const Value*>() { |
| - return G_TYPE_VALUE; |
| -} |
| - |
| -template <> |
| -inline ::GType type_to_gtypeid< ::uint32_t>() { |
| - // REVISIT (seanparent) : There currently isn't any G_TYPE_UINT32, this code |
| - // assumes sizeof(guint) == sizeof(guint32). Need a static_assert to assert |
| - // that. |
| - return G_TYPE_UINT; |
| -} |
| - |
| -template <> |
| -inline ::GType type_to_gtypeid< ::int64_t>() { |
| - return G_TYPE_INT64; |
| -} |
| - |
| -template <> |
| -inline ::GType type_to_gtypeid< ::int32_t>() { |
| - return G_TYPE_INT; |
| -} |
| - |
| -// \brief Value (and Retrieve) support using std::string as well as const char* |
| -// by promoting from const char* to the string. promote_from provides a mapping |
| -// for this promotion (and possibly others in the future). |
| - |
| -template <typename T> |
| -struct promotes_from { |
| - typedef T type; |
| -}; |
| -template <> |
| -struct promotes_from<std::string> { |
| - typedef const char* type; |
| -}; |
| - |
| -// \brief RawCast converts from a GValue to a value of a canonical type. |
| -// |
| -// RawCast is a low level function. Generally, use Cast() instead. |
| -// |
| -// \precondition \param x contains a value of type \param T. |
| - |
| -template <typename T> |
| -inline T RawCast(const ::GValue& x) { |
| - // Use static_assert() to issue a meaningful compile-time error. |
| - // To prevent this from happening for all references to RawCast, use sizeof(T) |
| - // to make static_assert depend on type T and therefore prevent binding it |
| - // unconditionally until the actual RawCast<T> instantiation happens. |
| - static_assert(sizeof(T) == 0, "Using RawCast on unsupported type"); |
| - return T(); |
| -} |
| - |
| -template <> |
| -inline const char* RawCast<const char*>(const ::GValue& x) { |
| - return static_cast<const char*>(::g_value_get_string(&x)); |
| -} |
| -template <> |
| -inline double RawCast<double>(const ::GValue& x) { |
| - return static_cast<double>(::g_value_get_double(&x)); |
| -} |
| -template <> |
| -inline bool RawCast<bool>(const ::GValue& x) { |
| - return static_cast<bool>(::g_value_get_boolean(&x)); |
| -} |
| -template <> |
| -inline ::uint32_t RawCast< ::uint32_t>(const ::GValue& x) { |
| - return static_cast< ::uint32_t>(::g_value_get_uint(&x)); |
| -} |
| -template <> |
| -inline ::uint8_t RawCast< ::uint8_t>(const ::GValue& x) { |
| - return static_cast< ::uint8_t>(::g_value_get_uchar(&x)); |
| -} |
| -template <> |
| -inline ::int64_t RawCast< ::int64_t>(const ::GValue& x) { |
| - return static_cast< ::int64_t>(::g_value_get_int64(&x)); |
| -} |
| -template <> |
| -inline ::int32_t RawCast< ::int32_t>(const ::GValue& x) { |
| - return static_cast< ::int32_t>(::g_value_get_int(&x)); |
| -} |
| - |
| -inline void RawSet(GValue* x, const std::string& v) { |
| - ::g_value_set_string(x, v.c_str()); |
| -} |
| -inline void RawSet(GValue* x, const char* v) { |
| - ::g_value_set_string(x, v); |
| -} |
| -inline void RawSet(GValue* x, double v) { |
| - ::g_value_set_double(x, v); |
| -} |
| -inline void RawSet(GValue* x, bool v) { |
| - ::g_value_set_boolean(x, v); |
| -} |
| -inline void RawSet(GValue* x, ::uint32_t v) { |
| - ::g_value_set_uint(x, v); |
| -} |
| -inline void RawSet(GValue* x, ::uint8_t v) { |
| - ::g_value_set_uchar(x, v); |
| -} |
| -inline void RawSet(GValue* x, ::int64_t v) { |
| - ::g_value_set_int64(x, v); |
| -} |
| -inline void RawSet(GValue* x, ::int32_t v) { |
| - ::g_value_set_int(x, v); |
| -} |
| - |
| -// \brief Value is a data type for managing GValues. |
| -// |
| -// A Value is a polymorphic container holding at most a single value. |
| -// |
| -// The Value wrapper ensures proper initialization, copies, and assignment of |
| -// GValues. |
| -// |
| -// \note GValues are equationally incomplete and so can't support proper |
| -// equality. The semantics of copy are verified with equality of retrieved |
| -// values. |
| - |
| -class Value : public ::GValue { |
| - public: |
| - Value() : GValue() {} |
| - explicit Value(const ::GValue& x) : GValue() { |
| - *this = *static_cast<const Value*>(&x); |
| - } |
| - template <typename T> |
| - explicit Value(T x) : GValue() { |
| - ::g_value_init(this, type_to_gtypeid<typename promotes_from<T>::type>()); |
| - RawSet(this, x); |
| - } |
| - Value(const Value& x) : GValue() { |
| - if (x.empty()) |
| - return; |
| - ::g_value_init(this, G_VALUE_TYPE(&x)); |
| - ::g_value_copy(&x, this); |
| - } |
| - ~Value() { clear(); } |
| - Value& operator=(const Value& x) { |
| - if (this == &x) |
| - return *this; |
| - clear(); |
| - if (x.empty()) |
| - return *this; |
| - ::g_value_init(this, G_VALUE_TYPE(&x)); |
| - ::g_value_copy(&x, this); |
| - return *this; |
| - } |
| - template <typename T> |
| - Value& operator=(const T& x) { |
| - clear(); |
| - ::g_value_init(this, type_to_gtypeid<typename promotes_from<T>::type>()); |
| - RawSet(this, x); |
| - return *this; |
| - } |
| - |
| - // Lower-case names to follow STL container conventions. |
| - |
| - void clear() { |
| - if (!empty()) |
| - ::g_value_unset(this); |
| - } |
| - |
| - bool empty() const { return G_VALUE_TYPE(this) == G_TYPE_INVALID; } |
| -}; |
| - |
| -template <> |
| -inline const Value* RawCast<const Value*>(const ::GValue& x) { |
| - return static_cast<const Value*>(&x); |
| -} |
| - |
| -// \brief Retrieve gets a value from a GValue. |
| -// |
| -// \postcondition If \param x contains a value of type \param T, then the |
| -// value is copied to \param result and \true is returned. Otherwise, \param |
| -// result is unchanged and \false is returned. |
| -// |
| -// \precondition \param result is not \nullptr. |
| - |
| -template <typename T> |
| -bool Retrieve(const ::GValue& x, T* result) { |
| - if (!G_VALUE_HOLDS(&x, type_to_gtypeid<typename promotes_from<T>::type>())) { |
| - LOG(WARNING) << "GValue retrieve failed. Expected: " |
| - << g_type_name( |
| - type_to_gtypeid<typename promotes_from<T>::type>()) |
| - << ", Found: " << g_type_name(G_VALUE_TYPE(&x)); |
| - return false; |
| - } |
| - |
| - *result = RawCast<typename promotes_from<T>::type>(x); |
| - return true; |
| -} |
| - |
| -inline bool Retrieve(const ::GValue& x, Value* result) { |
| - *result = Value(x); |
| - return true; |
| -} |
| - |
| -// \brief ScopedError holds a ::GError* and deletes it on destruction. |
| - |
| -struct FreeError { |
| - void operator()(::GError* x) const { |
| - if (x) |
| - ::g_error_free(x); |
| - } |
| -}; |
| - |
| -typedef std::unique_ptr< ::GError, FreeError> ScopedError; |
| - |
| -// \brief ScopedArray holds a ::GArray* and deletes both the container and the |
| -// segment containing the elements on destruction. |
| - |
| -struct FreeArray { |
| - void operator()(::GArray* x) const { |
| - if (x) |
| - ::g_array_free(x, TRUE); |
| - } |
| -}; |
| - |
| -typedef std::unique_ptr< ::GArray, FreeArray> ScopedArray; |
| - |
| -// \brief ScopedPtrArray adapts ::GPtrArray* to conform to the standard |
| -// container requirements. |
| -// |
| -// \note ScopedPtrArray is only partially implemented and is being fleshed out |
| -// as needed. |
| -// |
| -// \models Random Access Container, Back Insertion Sequence, ScopedPtrArray is |
| -// not copyable and equationally incomplete. |
| - |
| -template <typename T> // T models pointer |
| -class ScopedPtrArray { |
| - public: |
| - typedef ::GPtrArray element_type; |
| - |
| - typedef T value_type; |
| - typedef const value_type& const_reference; |
| - typedef value_type* iterator; |
| - typedef const value_type* const_iterator; |
| - |
| - ScopedPtrArray() : object_(0) {} |
| - |
| - explicit ScopedPtrArray(::GPtrArray* x) : object_(x) {} |
| - ScopedPtrArray(const ScopedPtrArray&) = delete; |
| - ScopedPtrArray& operator=(const ScopedPtrArray&) = delete; |
| - |
| - ~ScopedPtrArray() { clear(); } |
| - |
| - iterator begin() { return iterator(object_ ? object_->pdata : nullptr); } |
| - iterator end() { return begin() + size(); } |
| - const_iterator begin() const { |
| - return const_iterator(object_ ? object_->pdata : nullptr); |
| - } |
| - const_iterator end() const { return begin() + size(); } |
| - |
| - // \precondition x is a pointer to an object allocated with g_new(). |
| - |
| - void push_back(T x) { |
| - if (!object_) |
| - object_ = ::g_ptr_array_sized_new(1); |
| - ::g_ptr_array_add(object_, ::gpointer(x)); |
| - } |
| - |
| - T& operator[](std::size_t n) { |
| - DCHECK(!(size() < n)) << "ScopedPtrArray index out-of-bound."; |
| - return *(begin() + n); |
| - } |
| - |
| - std::size_t size() const { return object_ ? object_->len : 0; } |
| - |
| - void clear() { |
| - if (object_) { |
| - std::for_each(begin(), end(), FreeHelper()); |
| - ::g_ptr_array_free(object_, true); |
| - object_ = nullptr; |
| - } |
| - } |
| - |
| - void reset(::GPtrArray* p = nullptr) { |
| - if (p != object_) { |
| - clear(); |
| - object_ = p; |
| - } |
| - } |
| - |
| - private: |
| - struct FreeHelper { |
| - void operator()(T x) const { ::g_free(::gpointer(x)); } |
| - }; |
| - |
| - template <typename U> |
| - friend void swap(ScopedPtrArray<U>& x, ScopedPtrArray<U>& y); |
| - |
| - ::GPtrArray* object_; |
| -}; |
| - |
| -template <typename U> |
| -inline void swap(ScopedPtrArray<U>& x, ScopedPtrArray<U>& y) { |
| - std::swap(x.object_, y.object_); |
| -} |
| - |
| -// \brief ScopedHashTable manages the lifetime of a ::GHashTable* with an |
| -// interface compatibitle with a scoped ptr. |
| -// |
| -// The ScopedHashTable is also the start of an adaptor to model a standard |
| -// Container. The standard for an associative container would have an iterator |
| -// returning a key value pair. However, that isn't possible with |
| -// ::GHashTable because there is no interface returning a reference to the |
| -// key value pair, only to retrieve the keys and values and individual elements. |
| -// |
| -// So the standard interface of find() wouldn't work. I considered implementing |
| -// operator[] and count() - operator []. So retrieving a value would look like: |
| -// |
| -// if (table.count(key)) |
| -// success = Retrieve(table[key], &value); |
| -// |
| -// But that requires hashing the key twice. |
| -// For now I implemented a Retrieve member function to follow the pattern |
| -// developed elsewhere in the code. |
| -// |
| -// bool success = Retrieve(key, &x); |
| -// |
| -// This is also a template to retrieve the corect type from the stored GValue |
| -// type. |
| -// |
| -// I may revisit this and use scoped_ptr_malloc and a non-member function |
| -// Retrieve() in the future. The Retrieve pattern is becoming common enough |
| -// that I want to give some thought as to how to generalize it further. |
| - |
| -class ScopedHashTable { |
| - public: |
| - typedef ::GHashTable element_type; |
| - |
| - ScopedHashTable() : object_(nullptr) {} |
| - |
| - explicit ScopedHashTable(::GHashTable* p) : object_(p) {} |
| - |
| - ~ScopedHashTable() { clear(); } |
| - |
| - template <typename T> |
| - bool Retrieve(const char* key, T* result) const { |
| - DCHECK(object_) << "Retrieve on empty ScopedHashTable."; |
| - if (!object_) |
| - return false; |
| - |
| - ::gpointer ptr = ::g_hash_table_lookup(object_, key); |
| - if (!ptr) |
| - return false; |
| - return glib::Retrieve(*static_cast< ::GValue*>(ptr), result); |
| - } |
| - |
| - void clear() { |
| - if (object_) { |
| - ::g_hash_table_unref(object_); |
| - object_ = nullptr; |
| - } |
| - } |
| - |
| - GHashTable* get() { return object_; } |
| - |
| - void reset(::GHashTable* p = nullptr) { |
| - if (p != object_) { |
| - clear(); |
| - object_ = p; |
| - } |
| - } |
| - |
| - private: |
| - ::GHashTable* object_; |
| -}; |
| - |
| -} // namespace glib |
| -} // namespace brillo |
| - |
| -#endif // LIBBRILLO_BRILLO_GLIB_OBJECT_H_ |
| diff --git a/brillo/glib/object_test.cc b/brillo/glib/object_test.cc |
| deleted file mode 100644 |
| index 9381866b9f..0000000000 |
| --- a/brillo/glib/object_test.cc |
| +++ /dev/null |
| @@ -1,132 +0,0 @@ |
| -// Copyright (c) 2009 The Chromium OS Authors. All rights reserved. |
| -// Use of this source code is governed by a BSD-style license that can be |
| -// found in the LICENSE file. |
| - |
| -#include "brillo/glib/object.h" |
| - |
| -#include <gtest/gtest.h> |
| - |
| -#include <algorithm> |
| -#include <cstring> |
| -#include <iterator> |
| -#include <string> |
| - |
| -using brillo::Resetter; |
| -using brillo::glib::Retrieve; |
| -using brillo::glib::ScopedError; |
| -using brillo::glib::ScopedPtrArray; |
| -using brillo::glib::Value; |
| - |
| -namespace { // NOLINT |
| - |
| -template <typename T> |
| -void SetRetrieveTest(const T& x) { |
| - Value tmp(x); |
| - T result; |
| - EXPECT_TRUE(Retrieve(tmp, &result)); |
| - EXPECT_EQ(result, x); |
| -} |
| - |
| -void ModifyValue(Value* x) { |
| - *x = 1.0 / 1231415926.0; // An unlikely value |
| -} |
| - |
| -template <typename T, typename O> |
| -void MutableRegularTestValue(const T& x, O modify) { |
| - Value tmp(x); |
| - Value y = tmp; // copy-construction |
| - T result; |
| - EXPECT_TRUE(Retrieve(y, &result)); |
| - EXPECT_EQ(result, x); |
| - modify(&y); |
| - LOG(INFO) << "Warning Expected."; |
| - EXPECT_TRUE(!(Retrieve(y, &result) && result == x)); |
| - y = tmp; // assignment |
| - EXPECT_TRUE(Retrieve(y, &result)); |
| - EXPECT_EQ(result, x); |
| - modify(&y); |
| - LOG(INFO) << "Warning Expected."; |
| - EXPECT_TRUE(!(Retrieve(y, &result) && result == x)); |
| -} |
| - |
| -void OutArgument(int** x) { |
| - *x = new int(10); // NOLINT |
| -} |
| - |
| -} // namespace |
| - |
| -TEST(ResetterTest, All) { |
| - std::unique_ptr<int> x; |
| - OutArgument(&Resetter(&x).lvalue()); |
| - EXPECT_EQ(*x, 10); |
| -} |
| - |
| -TEST(RetrieveTest, Types) { |
| - SetRetrieveTest(std::string("Hello!")); |
| - SetRetrieveTest(static_cast<uint32_t>(10)); |
| - SetRetrieveTest(10.5); |
| - SetRetrieveTest(true); |
| -} |
| - |
| -TEST(ValueTest, All) { |
| - Value x; // default construction |
| - Value y = x; // copy with default value |
| - x = y; // assignment with default value |
| - Value z(1.5); |
| - x = z; // assignment to default value |
| - MutableRegularTestValue(std::string("Hello!"), &ModifyValue); |
| -} |
| - |
| -TEST(ScopedErrorTest, All) { |
| - ScopedError a; // default construction |
| - ScopedError b(::g_error_new(::g_quark_from_static_string("error"), -1, |
| - "")); // constructor |
| - ::GError* c = ::g_error_new(::g_quark_from_static_string("error"), -1, ""); |
| - ::GError* d = ::g_error_new(::g_quark_from_static_string("error"), -1, ""); |
| - a.reset(c); // reset form 1 |
| - (void)d; |
| -} |
| - |
| -TEST(ScopedPtrArrayTest, Construction) { |
| - const char item[] = "a string"; |
| - char* a = static_cast<char*>(::g_malloc(sizeof(item))); |
| - std::strcpy(a, &item[0]); // NOLINT |
| - |
| - ::GPtrArray* array = ::g_ptr_array_new(); |
| - ::g_ptr_array_add(array, ::gpointer(a)); |
| - |
| - ScopedPtrArray<const char*> x(array); |
| - EXPECT_EQ(x.size(), 1); |
| - EXPECT_EQ(x[0], a); // indexing |
| -} |
| - |
| -TEST(ScopedPtrArrayTest, Reset) { |
| - const char item[] = "a string"; |
| - char* a = static_cast<char*>(::g_malloc(sizeof(item))); |
| - std::strcpy(a, &item[0]); // NOLINT |
| - |
| - ScopedPtrArray<const char*> x; // default construction |
| - x.push_back(a); |
| - EXPECT_EQ(x.size(), 1); |
| - x.reset(); |
| - EXPECT_EQ(x.size(), 0); |
| - |
| - char* b = static_cast<char*>(::g_malloc(sizeof(item))); |
| - std::strcpy(b, &item[0]); // NOLINT |
| - |
| - ::GPtrArray* array = ::g_ptr_array_new(); |
| - ::g_ptr_array_add(array, ::gpointer(b)); |
| - |
| - x.reset(array); |
| - EXPECT_EQ(x.size(), 1); |
| -} |
| - |
| -TEST(ScopedPtrArrayTest, Iteration) { |
| - char* a[] = {static_cast<char*>(::g_malloc(1)), |
| - static_cast<char*>(::g_malloc(1)), |
| - static_cast<char*>(::g_malloc(1))}; |
| - |
| - ScopedPtrArray<const char*> x; |
| - std::copy(&a[0], &a[3], std::back_inserter(x)); |
| - EXPECT_TRUE(std::equal(x.begin(), x.end(), &a[0])); |
| -} |
| -- |
| 2.33.0.464.g1972c5931b-goog |
| |