From 0ff70adc3ec2e39867591cf4c7d0e86a2426c6d4 Mon Sep 17 00:00:00 2001 From: Jakub Izydorczyk Date: Fri, 6 Mar 2015 14:53:54 +0100 Subject: [PATCH] Remove Manifest::Type from parser Remove Manifest::Type, as this parser was supposed to be only for config.xml from *.wgt applications. Change-Id: Ie465f45c40d2c59492e3f9503132af8e47a4ccd0 --- ...widget_manifest_parser_manifest_handler_unittest.cc | 18 +++++------------- .../widget_manifest_parser_manifest_util_unittest.cc | 10 ++++------ src/widget-manifest-parser/application_data.cc | 9 ++++----- src/widget-manifest-parser/application_data.h | 1 - .../application_manifest_constants.cc | 10 +++++----- .../application_manifest_constants.h | 8 ++++---- src/widget-manifest-parser/manifest.cc | 8 +++----- src/widget-manifest-parser/manifest.h | 12 +----------- src/widget-manifest-parser/manifest_handler.cc | 17 +++++------------ src/widget-manifest-parser/manifest_handler.h | 16 +++------------- .../manifest_handlers/category_handler.cc | 5 +++-- .../manifest_handlers/ime_handler.cc | 6 +++++- .../manifest_handlers/metadata_handler.cc | 3 ++- .../manifest_handlers/permissions_handler.cc | 4 ---- .../manifest_handlers/permissions_handler.h | 1 - .../manifest_handlers/tizen_application_handler.cc | 5 ----- .../manifest_handlers/tizen_application_handler.h | 1 - .../manifest_handlers/widget_handler.cc | 4 ---- .../manifest_handlers/widget_handler.h | 1 - src/widget-manifest-parser/manifest_util.cc | 5 ++--- src/widget-manifest-parser/manifest_util.h | 4 ++-- src/widget-manifest-parser/widget_manifest_parser.cc | 2 +- 22 files changed, 49 insertions(+), 101 deletions(-) diff --git a/src/unit_tests/widget_manifest_parser_manifest_handler_unittest.cc b/src/unit_tests/widget_manifest_parser_manifest_handler_unittest.cc index 129159e..6f15215 100644 --- a/src/unit_tests/widget_manifest_parser_manifest_handler_unittest.cc +++ b/src/unit_tests/widget_manifest_parser_manifest_handler_unittest.cc @@ -30,17 +30,13 @@ class ScopedTestingManifestHandlerRegistry { public: ScopedTestingManifestHandlerRegistry( const std::vector& handlers) - : registry_( - new ManifestHandlerRegistry(handlers)), - prev_registry_( - ManifestHandlerRegistry::GetInstance(Manifest::TYPE_MANIFEST)) { - ManifestHandlerRegistry::SetInstanceForTesting( - registry_, Manifest::TYPE_MANIFEST); + : registry_(new ManifestHandlerRegistry(handlers)), + prev_registry_(ManifestHandlerRegistry::GetInstance()) { + ManifestHandlerRegistry::SetInstanceForTesting(registry_); } ~ScopedTestingManifestHandlerRegistry() { - ManifestHandlerRegistry::SetInstanceForTesting( - prev_registry_, Manifest::TYPE_MANIFEST); + ManifestHandlerRegistry::SetInstanceForTesting(prev_registry_); } ManifestHandlerRegistry* registry_; @@ -140,10 +136,6 @@ class ManifestHandlerTest : public testing::Test { ParsingWatcher* watcher) : TestManifestHandler(name, keys, prereqs, watcher) { } - - bool AlwaysParseForType(Manifest::Type type) const override { - return true; - } }; class TestManifestValidator : public ManifestHandler { @@ -168,7 +160,7 @@ class ManifestHandlerTest : public testing::Test { return return_value_; } - bool AlwaysValidateForType(Manifest::Type type) const override { + bool AlwaysValidateForType() const override { return always_validate_; } diff --git a/src/unit_tests/widget_manifest_parser_manifest_util_unittest.cc b/src/unit_tests/widget_manifest_parser_manifest_util_unittest.cc index b6b8a37..ab62cd5 100644 --- a/src/unit_tests/widget_manifest_parser_manifest_util_unittest.cc +++ b/src/unit_tests/widget_manifest_parser_manifest_util_unittest.cc @@ -32,9 +32,8 @@ TEST_F(ManifestUtilTest, LoadApplicationWithValidPath) { install_dir /= "good_manifest.xml"; std::string error; - std::unique_ptr manifest(LoadManifest(install_dir.string(), - Manifest::Type::TYPE_WIDGET, - &error)); + std::unique_ptr manifest( + widget_manifest_parser::LoadManifest(install_dir.string(), &error)); ASSERT_TRUE(error.empty()); std::shared_ptr app_data = @@ -53,9 +52,8 @@ TEST_F(ManifestUtilTest, install_dir /= "test_samples"; install_dir /= "bad_manifest.xml"; std::string error; - std::unique_ptr manifest(LoadManifest(install_dir.string(), - Manifest::Type::TYPE_WIDGET, - &error)); + std::unique_ptr manifest( + widget_manifest_parser::LoadManifest(install_dir.string(), &error)); ASSERT_TRUE(!error.empty()); ASSERT_FALSE(error.empty()); ASSERT_STREQ("Manifest file is missing or unreadable.", error.c_str()); diff --git a/src/widget-manifest-parser/application_data.cc b/src/widget-manifest-parser/application_data.cc index 347d727..37efbf3 100644 --- a/src/widget-manifest-parser/application_data.cc +++ b/src/widget-manifest-parser/application_data.cc @@ -61,7 +61,7 @@ std::shared_ptr ApplicationData::Create( return nullptr; ManifestHandlerRegistry* registry = - ManifestHandlerRegistry::GetInstance(app_data->manifest_type()); + ManifestHandlerRegistry::GetInstance(); if (!registry->ValidateAppManifest(app_data, error_message)) return nullptr; @@ -133,7 +133,7 @@ bool ApplicationData::Init(const std::string& explicit_id, std::string* error) { assert(error); ManifestHandlerRegistry* registry = - ManifestHandlerRegistry::GetInstance(manifest_type()); + ManifestHandlerRegistry::GetInstance(); if (!registry->ParseAppManifest(shared_from_this(), error)) return false; @@ -167,10 +167,9 @@ bool ApplicationData::LoadID(const std::string& explicit_id, bool ApplicationData::LoadName(std::string* error) { assert(error); std::string localized_name; - std::string name_key(GetNameKey(manifest_type())); + std::string name_key(GetNameKey()); - if (!manifest_->GetString(name_key, &localized_name) && - manifest_type() == Manifest::TYPE_MANIFEST) { + if (!manifest_->GetString(name_key, &localized_name)) { *error = errors::kInvalidName; return false; } diff --git a/src/widget-manifest-parser/application_data.h b/src/widget-manifest-parser/application_data.h index 07d24fa..565850a 100644 --- a/src/widget-manifest-parser/application_data.h +++ b/src/widget-manifest-parser/application_data.h @@ -85,7 +85,6 @@ class ApplicationData : public std::enable_shared_from_this { const bf::path& path() const { return path_; } const std::string& URL() const { return application_url_; } SourceType source_type() const { return source_type_; } - Manifest::Type manifest_type() const { return manifest_->type(); } const std::string& ID() const { return application_id_; } std::string GetPackageID() const; const std::string Version() const { return version_; } diff --git a/src/widget-manifest-parser/application_manifest_constants.cc b/src/widget-manifest-parser/application_manifest_constants.cc index c6a09fd..b50cea2 100644 --- a/src/widget-manifest-parser/application_manifest_constants.cc +++ b/src/widget-manifest-parser/application_manifest_constants.cc @@ -164,23 +164,23 @@ const char kManifestUnreadable[] = namespace widget_manifest_parser { -const char* GetNameKey(Manifest::Type /*manifest_type*/) { +const char* GetNameKey() { return application_widget_keys::kNameKey; } -const char* GetVersionKey(Manifest::Type /*manifest_type*/) { +const char* GetVersionKey() { return application_widget_keys::kVersionKey; } -const char* GetCSPKey(Manifest::Type /*manifest_type*/) { +const char* GetCSPKey() { return application_widget_keys::kCSPKey; } -const char* GetTizenAppIdKey(Manifest::Type /*manifest_type*/) { +const char* GetTizenAppIdKey() { return application_widget_keys::kTizenAppIdKey; } -const char* GetIcon128Key(Manifest::Type /*manifest_type*/) { +const char* GetIcon128Key() { return application_widget_keys::kIcon128Key; } diff --git a/src/widget-manifest-parser/application_manifest_constants.h b/src/widget-manifest-parser/application_manifest_constants.h index 2e1d4d6..2bc89b5 100644 --- a/src/widget-manifest-parser/application_manifest_constants.h +++ b/src/widget-manifest-parser/application_manifest_constants.h @@ -143,10 +143,10 @@ extern const char kManifestUnreadable[]; } // namespace application_manifest_errors namespace widget_manifest_parser { -const char* GetNameKey(Manifest::Type type); -const char* GetCSPKey(Manifest::Type type); -const char* GetTizenAppIdKey(Manifest::Type type); -const char* GetIcon128Key(Manifest::Type type); +const char* GetNameKey(); +const char* GetCSPKey(); +const char* GetTizenAppIdKey(); +const char* GetIcon128Key(); } // namespace widget_manifest_parser } // namespace common_installer diff --git a/src/widget-manifest-parser/manifest.cc b/src/widget-manifest-parser/manifest.cc index e401a5f..4d02208 100644 --- a/src/widget-manifest-parser/manifest.cc +++ b/src/widget-manifest-parser/manifest.cc @@ -59,10 +59,9 @@ std::unique_ptr ExpandUserAgentLocalesList( } // namespace -Manifest::Manifest(std::unique_ptr value, Type type) +Manifest::Manifest(std::unique_ptr value) : data_(std::move(value)), - i18n_data_(new utils::DictionaryValue), - type_(type) { + i18n_data_(new utils::DictionaryValue) { if (data_->HasKey(widget_keys::kWidgetKey) && data_->Get(widget_keys::kWidgetKey, nullptr)) @@ -141,8 +140,7 @@ bool Manifest::GetList( Manifest* Manifest::DeepCopy() const { Manifest* manifest = new Manifest( - std::unique_ptr(data_->DeepCopy()), - type()); + std::unique_ptr(data_->DeepCopy())); return manifest; } diff --git a/src/widget-manifest-parser/manifest.h b/src/widget-manifest-parser/manifest.h index 8df5553..7ee1fe4 100644 --- a/src/widget-manifest-parser/manifest.h +++ b/src/widget-manifest-parser/manifest.h @@ -23,13 +23,8 @@ namespace widget_manifest_parser { // properties of the manifest using ManifestFeatureProvider. class Manifest { public: - enum Type { - TYPE_MANIFEST, // Corresponds to w3c.github.io/manifest - TYPE_WIDGET // Corresponds to http://www.w3.org/TR/widgets - }; - explicit Manifest( - std::unique_ptr value, Type type = TYPE_MANIFEST); + std::unique_ptr value); ~Manifest(); // Returns false and |error| will be non-empty if the manifest is malformed. @@ -37,9 +32,6 @@ class Manifest { // be specified by the application type. bool ValidateManifest(std::string* error) const; - // Returns the manifest type. - Type type() const { return type_; } - // These access the wrapped manifest value, returning false when the property // does not exist or if the manifest type can't access it. bool HasKey(const std::string& key) const; @@ -102,8 +94,6 @@ class Manifest { std::string default_locale_; std::unique_ptr > user_agent_locales_; - Type type_; - DISALLOW_COPY_AND_ASSIGN(Manifest); }; diff --git a/src/widget-manifest-parser/manifest_handler.cc b/src/widget-manifest-parser/manifest_handler.cc index 8ab636e..b551261 100644 --- a/src/widget-manifest-parser/manifest_handler.cc +++ b/src/widget-manifest-parser/manifest_handler.cc @@ -63,11 +63,7 @@ bool ManifestHandler::Validate( return true; } -bool ManifestHandler::AlwaysParseForType(Manifest::Type /*type*/) const { - return false; -} - -bool ManifestHandler::AlwaysValidateForType(Manifest::Type /*type*/) const { +bool ManifestHandler::AlwaysValidateForType() const { return false; } @@ -91,7 +87,7 @@ ManifestHandlerRegistry::~ManifestHandlerRegistry() { } ManifestHandlerRegistry* -ManifestHandlerRegistry::GetInstance(Manifest::Type /*type*/) { +ManifestHandlerRegistry::GetInstance() { return GetInstanceForWGT(); } @@ -131,10 +127,7 @@ bool ManifestHandlerRegistry::ParseAppManifest( for (ManifestHandlerMap::iterator iter = handlers_.begin(); iter != handlers_.end(); ++iter) { ManifestHandler* handler = iter->second; - if (application->GetManifest()->HasPath(iter->first) || - handler->AlwaysParseForType(application->manifest_type())) { - handlers_by_order[order_map_[handler]] = handler; - } + handlers_by_order[order_map_[handler]] = handler; } for (std::map::iterator iter = handlers_by_order.begin(); @@ -153,7 +146,7 @@ bool ManifestHandlerRegistry::ValidateAppManifest( iter != handlers_.end(); ++iter) { ManifestHandler* handler = iter->second; if ((application->GetManifest()->HasPath(iter->first) || - handler->AlwaysValidateForType(application->manifest_type())) && + handler->AlwaysValidateForType()) && !handler->Validate(application, error)) return false; } @@ -166,7 +159,7 @@ bool ManifestHandlerRegistry::ValidateAppManifest( // static void ManifestHandlerRegistry::SetInstanceForTesting( - ManifestHandlerRegistry* registry, Manifest::Type /*type*/) { + ManifestHandlerRegistry* registry) { widget_registry_ = registry; return; } diff --git a/src/widget-manifest-parser/manifest_handler.h b/src/widget-manifest-parser/manifest_handler.h index b0b4ac6..9e74870 100644 --- a/src/widget-manifest-parser/manifest_handler.h +++ b/src/widget-manifest-parser/manifest_handler.h @@ -31,15 +31,8 @@ class ManifestHandler { virtual bool Validate(std::shared_ptr application, std::string* error) const; - // If false (the default), only parse the manifest if a registered - // key is present in the manifest. If true, always attempt to parse - // the manifest for this application type, even if no registered keys - // are present. This allows specifying a default parsed value for - // application that don't declare our key in the manifest. - virtual bool AlwaysParseForType(Manifest::Type type) const; - // Same as AlwaysParseForType, but for Validate instead of Parse. - virtual bool AlwaysValidateForType(Manifest::Type type) const; + virtual bool AlwaysValidateForType() const; // The list of keys that, if present, should be parsed before calling our // Parse (typically, because our Parse needs to read those keys). @@ -54,7 +47,7 @@ class ManifestHandlerRegistry final { public: ~ManifestHandlerRegistry(); - static ManifestHandlerRegistry* GetInstance(Manifest::Type type); + static ManifestHandlerRegistry* GetInstance(); bool ParseAppManifest( std::shared_ptr application, std::string* error); @@ -73,11 +66,9 @@ class ManifestHandlerRegistry final { void ReorderHandlersGivenDependencies(); // Sets a new global registry, for testing purposes. - static void SetInstanceForTesting(ManifestHandlerRegistry* registry, - Manifest::Type type); + static void SetInstanceForTesting(ManifestHandlerRegistry* registry); static ManifestHandlerRegistry* GetInstanceForWGT(); - static ManifestHandlerRegistry* GetInstanceForXPK(); typedef std::map ManifestHandlerMap; typedef std::map ManifestHandlerOrderMap; @@ -87,7 +78,6 @@ class ManifestHandlerRegistry final { // Handlers are executed in order; lowest order first. ManifestHandlerOrderMap order_map_; - static ManifestHandlerRegistry* xpk_registry_; static ManifestHandlerRegistry* widget_registry_; }; diff --git a/src/widget-manifest-parser/manifest_handlers/category_handler.cc b/src/widget-manifest-parser/manifest_handlers/category_handler.cc index 25a65c0..4be306e 100644 --- a/src/widget-manifest-parser/manifest_handlers/category_handler.cc +++ b/src/widget-manifest-parser/manifest_handlers/category_handler.cc @@ -5,6 +5,7 @@ #include "widget-manifest-parser/manifest_handlers/category_handler.h" +#include "utils/logging.h" #include "utils/values.h" #include "widget-manifest-parser/application_manifest_constants.h" @@ -63,8 +64,8 @@ bool CategoryHandler::Parse(std::shared_ptr application, if (!ParseCategoryEntryAndStore(*dict, aplist.get())) return false; } else { - *error = kErrMsgCategory; - return false; + LOG(INFO) << "Category element is not defined."; + return true; } application->SetManifestData(keys::kTizenCategoryKey, aplist); diff --git a/src/widget-manifest-parser/manifest_handlers/ime_handler.cc b/src/widget-manifest-parser/manifest_handlers/ime_handler.cc index f15cb61..7810fc7 100644 --- a/src/widget-manifest-parser/manifest_handlers/ime_handler.cc +++ b/src/widget-manifest-parser/manifest_handlers/ime_handler.cc @@ -9,6 +9,7 @@ #include #include +#include "utils/logging.h" #include "utils/values.h" #include "widget-manifest-parser/application_manifest_constants.h" @@ -134,9 +135,12 @@ bool ImeHandler::Parse(std::shared_ptr application, const utils::DictionaryValue* dict; value->GetAsDictionary(&dict); result = ParseImeEntryAndStore(*dict, ime_info.get(), error); - } else { + } else if (value->GetType() == utils::Value::TYPE_LIST) { *error = kErrMsgParsingIme; return false; + } else { + LOG(INFO) << "IME element is not defined."; + return true; } application->SetManifestData(keys::kTizenImeKey, ime_info); diff --git a/src/widget-manifest-parser/manifest_handlers/metadata_handler.cc b/src/widget-manifest-parser/manifest_handlers/metadata_handler.cc index 066bc18..8106d5f 100644 --- a/src/widget-manifest-parser/manifest_handlers/metadata_handler.cc +++ b/src/widget-manifest-parser/manifest_handlers/metadata_handler.cc @@ -9,6 +9,7 @@ #include #include +#include "utils/logging.h" #include "utils/values.h" #include "widget-manifest-parser/application_manifest_constants.h" @@ -69,7 +70,7 @@ bool MetaDataHandler::Parse(std::shared_ptr application, utils::Value* metadata_value = NULL; if (!manifest->Get(keys::kTizenMetaDataKey, &metadata_value)) { - *error = "Failed to get value of tizen metaData"; + LOG(INFO) << "Failed to get value of tizen metaData"; } MetaDataPair metadata_item; diff --git a/src/widget-manifest-parser/manifest_handlers/permissions_handler.cc b/src/widget-manifest-parser/manifest_handlers/permissions_handler.cc index b30c309..aaefe74 100644 --- a/src/widget-manifest-parser/manifest_handlers/permissions_handler.cc +++ b/src/widget-manifest-parser/manifest_handlers/permissions_handler.cc @@ -83,10 +83,6 @@ bool PermissionsHandler::Parse( return true; } -bool PermissionsHandler::AlwaysParseForType(Manifest::Type type) const { - return type == Manifest::TYPE_WIDGET; -} - std::vector PermissionsHandler::Keys() const { return std::vector(1, keys::kTizenPermissionsKey); } diff --git a/src/widget-manifest-parser/manifest_handlers/permissions_handler.h b/src/widget-manifest-parser/manifest_handlers/permissions_handler.h index 7507f39..674c5bd 100644 --- a/src/widget-manifest-parser/manifest_handlers/permissions_handler.h +++ b/src/widget-manifest-parser/manifest_handlers/permissions_handler.h @@ -40,7 +40,6 @@ class PermissionsHandler: public ManifestHandler { bool Parse(std::shared_ptr application, std::string* error) override; - bool AlwaysParseForType(Manifest::Type type) const override; std::vector Keys() const override; private: diff --git a/src/widget-manifest-parser/manifest_handlers/tizen_application_handler.cc b/src/widget-manifest-parser/manifest_handlers/tizen_application_handler.cc index 96e4463..82164c3 100644 --- a/src/widget-manifest-parser/manifest_handlers/tizen_application_handler.cc +++ b/src/widget-manifest-parser/manifest_handlers/tizen_application_handler.cc @@ -129,10 +129,5 @@ std::vector TizenApplicationHandler::Keys() const { return std::vector(1, keys::kTizenApplicationKey); } -bool TizenApplicationHandler::AlwaysParseForType( - Manifest::Type /*type*/) const { - return true; -} - } // namespace widget_manifest_parser } // namespace common_installer diff --git a/src/widget-manifest-parser/manifest_handlers/tizen_application_handler.h b/src/widget-manifest-parser/manifest_handlers/tizen_application_handler.h index 32f8e02..f89b5ab 100644 --- a/src/widget-manifest-parser/manifest_handlers/tizen_application_handler.h +++ b/src/widget-manifest-parser/manifest_handlers/tizen_application_handler.h @@ -58,7 +58,6 @@ class TizenApplicationHandler : public ManifestHandler { std::string* error) override; bool Validate(std::shared_ptr application, std::string* error) const override; - bool AlwaysParseForType(Manifest::Type type) const override; std::vector Keys() const override; private: diff --git a/src/widget-manifest-parser/manifest_handlers/widget_handler.cc b/src/widget-manifest-parser/manifest_handlers/widget_handler.cc index 4d46dad..ebedd23 100644 --- a/src/widget-manifest-parser/manifest_handlers/widget_handler.cc +++ b/src/widget-manifest-parser/manifest_handlers/widget_handler.cc @@ -181,10 +181,6 @@ bool WidgetHandler::Validate( return true; } -bool WidgetHandler::AlwaysParseForType(Manifest::Type /*type*/) const { - return true; -} - std::vector WidgetHandler::Keys() const { return std::vector(1, keys::kWidgetKey); } diff --git a/src/widget-manifest-parser/manifest_handlers/widget_handler.h b/src/widget-manifest-parser/manifest_handlers/widget_handler.h index 556b5df..337b178 100644 --- a/src/widget-manifest-parser/manifest_handlers/widget_handler.h +++ b/src/widget-manifest-parser/manifest_handlers/widget_handler.h @@ -46,7 +46,6 @@ class WidgetHandler : public ManifestHandler { bool Parse(std::shared_ptr application, std::string* error) override; - bool AlwaysParseForType(Manifest::Type type) const override; std::vector Keys() const override; bool Validate(std::shared_ptr application, diff --git a/src/widget-manifest-parser/manifest_util.cc b/src/widget-manifest-parser/manifest_util.cc index 8bf8713..b2b5eb7 100644 --- a/src/widget-manifest-parser/manifest_util.cc +++ b/src/widget-manifest-parser/manifest_util.cc @@ -316,7 +316,7 @@ std::unique_ptr LoadXMLNode( } // namespace std::unique_ptr LoadManifest(const std::string& manifest_path, - Manifest::Type /*type*/, std::string* error) { + std::string* error) { xmlDoc * doc = nullptr; xmlNode* root_node = nullptr; doc = xmlReadFile(manifest_path.c_str(), nullptr, 0); @@ -330,8 +330,7 @@ std::unique_ptr LoadManifest(const std::string& manifest_path, if (dv) result->Set(reinterpret_cast(root_node->name), dv.release()); - return std::unique_ptr( - new Manifest(std::move(result), Manifest::TYPE_WIDGET)); + return std::unique_ptr(new Manifest(std::move(result))); } bf::path ApplicationURLToRelativeFilePath(const std::string& url) { diff --git a/src/widget-manifest-parser/manifest_util.h b/src/widget-manifest-parser/manifest_util.h index 5c83dc4..754fa42 100644 --- a/src/widget-manifest-parser/manifest_util.h +++ b/src/widget-manifest-parser/manifest_util.h @@ -18,10 +18,10 @@ namespace common_installer { namespace widget_manifest_parser { -// Loads an application manifest from the specified directory. Returns NULL +// Loads an application manifest from the specified directory. Returns nullptr // on failure, with a description of the error in |error|. std::unique_ptr LoadManifest( - const std::string& file_path, Manifest::Type type, std::string* error); + const std::string& file_path, std::string* error); } // namespace widget_manifest_parser } // namespace common_installer diff --git a/src/widget-manifest-parser/widget_manifest_parser.cc b/src/widget-manifest-parser/widget_manifest_parser.cc index cfc8ed5..9eff341 100644 --- a/src/widget-manifest-parser/widget_manifest_parser.cc +++ b/src/widget-manifest-parser/widget_manifest_parser.cc @@ -286,7 +286,7 @@ bool WidgetManifestParser::ParseManifest(const bf::path& manifest_path) { } manifest_ = parser::LoadManifest( - manifest_path.string(), parser::Manifest::TYPE_WIDGET, &error_); + manifest_path.string(), &error_); if (!manifest_) return false; valid_ = error_.empty(); -- 2.7.4