简体   繁体   English

GStreamer GError to boost::system::error_code?

[英]GStreamer GError to boost::system::error_code?

Looking for a clever way to transform a gstreamer/glib GError:寻找一种巧妙的方法来转换 gstreamer/glib GError:

 struct GError { GQuark domain; gint code; gchar* message; };

to a boost::system::error_code.到 boost::system::error_code。 Typically, you could create a category and register an enum to boost.通常,您可以创建一个类别并注册一个枚举来提升。 GStreamer uses enum but the code is returned as an int. GStreamer 使用枚举,但代码以 int 形式返回。 GQuark is a category. GQuark 是一个类别。

This is mainly to standardize error handling across an application.这主要是为了标准化跨应用程序的错误处理。

GQuark is a category. GQuark 是一个类别。

I think you mean that figuratively.我想你的意思是比喻性的。

Quarks are associations between strings and integer identifiers.夸克是字符串和 integer 标识符之间的关联。 Given either the string or the Quark identifier it is possible to retrieve the other.给定字符串或 Quark 标识符,可以检索另一个。

That's like interned strings, aka atoms.这就像实习字符串,又名原子。 So GQuark actually represents a string, then, that you want to treat as a category.所以GQuark实际上代表了一个字符串,然后,您希望将其视为一个类别。 Well then.好吧。

Categories are static类别为 static

Well.出色地。 Usually.通常。 At the very least categories are singleton with global object identity.至少类别是具有全局 object 标识的 singleton。 So, assuming that you know statically what domains to expect, you could create categories for those.因此,假设您静态地知道期望的域,您可以为这些域创建类别。

Map them to the text representation of the domain makes for the most stable mappings. Map 它们对域的文本表示使得最稳定的映射。

A single category单一类别

To get started, here's a single category:首先,这里有一个类别:

using boost::system::error_code;
using boost::system::error_condition;

enum class MyCoreError {
    failed,          // a general error which doesn't fit in any other category.  Make sure you add a custom message to the error call.
    too_lazy,        // do not use this except as a placeholder for deciding where to go while developing code.
    not_implemented, // use this when you do not want to implement this functionality yet.
    state_change,    // used for state change errors.
    pad,             // used for pad-related errors.
    thread,          // used for thread-related errors.
    negotiation,     // used for negotiation-related errors.
    event,           // used for event-related errors.
    seek,            // used for seek-related errors.
    caps,            // used for caps-related errors.
    tag,             // used for negotiation-related errors.
    missing_plugin,  // used if a plugin is missing.
    clock,           // used for clock related errors.
    disabled,        // used if functionality has been disabled at compile time.
    num_errors,      // the number of core error types.
};

namespace boost::system { template<> struct is_error_code_enum<MyCoreError> : std::true_type {}; }

namespace detail {
    class my_core_category : public boost::system::error_category {
      public:
        const char* name() const noexcept override { 
            return g_quark_to_string(GST_CORE_ERROR);
        }
        std::string message(int ev) const override {
          switch (static_cast<MyCoreError>(ev)) {
            case MyCoreError::failed: return "a general error which doesn't fit in any other category.  Make sure you add a custom message to the error call.";
            case MyCoreError::too_lazy: return "do not use this except as a placeholder for deciding where to go while developing code.";
            case MyCoreError::not_implemented: return "use this when you do not want to implement this functionality yet.";
            case MyCoreError::state_change: return "used for state change errors.";
            case MyCoreError::pad: return "used for pad-related errors.";
            case MyCoreError::thread: return "used for thread-related errors.";
            case MyCoreError::negotiation: return "used for negotiation-related errors.";
            case MyCoreError::event: return "used for event-related errors.";
            case MyCoreError::seek: return "used for seek-related errors.";
            case MyCoreError::caps: return "used for caps-related errors.";
            case MyCoreError::tag: return "used for negotiation-related errors.";
            case MyCoreError::missing_plugin: return "used if a plugin is missing.";
            case MyCoreError::clock: return "used for clock related errors.";
            case MyCoreError::disabled: return "used if functionality has been disabled at compile time.";
            case MyCoreError::num_errors: return "the number of core error types.";
            default: return "unknown core error";
          }
        }
        error_condition default_error_condition(int ev) const noexcept override {
            return error_condition{ ev, *this };
        }
        bool equivalent(int ev, error_condition const& condition) const noexcept override {
            return condition.value() == ev && &condition.category() == this;
        }
        bool equivalent(error_code const& error, int ev) const noexcept override {
            return error.value() == ev && &error.category() == this;
        }
    };
}
error_code make_error_code(MyCoreError se)
{
    static detail::my_core_category const cat{};
    return error_code{static_cast<std::underlying_type<MyCoreError>::type>(se), cat};
}

Now you can just现在你可以

auto code = MyCoreError::missing_plugin;
throw boost::system::system_error(make_error_code(code));

and it will magically do the right thing.它会神奇地做正确的事。

General Error Translation:一般错误翻译:

For the general case translating from API error:对于从 API 错误翻译的一般情况:

boost::system::error_code make_error_code(GError const& err) {
    if (err.domain == GST_CORE_ERROR) {
        return make_error_code(MyCoreError(err.code));
    }
    if (err.domain == GST_LIBRARY_ERROR) {
        return make_error_code(MyLibraryError(err.code));
    }
    if (err.domain == GST_RESOURCE_ERROR) {
        return make_error_code(MyResourceError(err.code));
    }
    if (err.domain == GST_STREAM_ERROR) {
        return make_error_code(MyStreamError(err.code));
    }
    // decide on how to represent unknown errors? Just throw, or translate into
    // MyCoreError::failed?
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 什么是升压系统error_code number 2 - What is boost system error_code number 2 boost::system::error_code 和 boost::system::error_code::value() 有什么区别? - What is the difference between boost::system::error_code and boost::system::error_code::value()? 是否可以将 boost::system::error_code 转换为 std:error_code? - Is it possible to convert a boost::system::error_code to a std:error_code? boost :: system :: error_code产生错误158未知 - boost::system::error_code producing error 158 unknown 在C ++中使用'boost :: system :: error_code' - Using 'boost::system::error_code' in C++ C ++ operator()重载boost :: system :: error_code技巧 - C++ operator() overload boost::system::error_code trick C++ 升压系统::error_code 语言 - C++ boost system::error_code language boost :: asio :: yield_context可以设置std :: error_code而不是boost :: system :: error_code吗? - Can boost::asio::yield_context set a std::error_code instead of boost::system::error_code? boost :: system :: error_code :: message()使用boost :: asio socket抛出访问冲突异常 - boost::system::error_code::message() throwing access violation exception with boost::asio socket 摆脱TCP代理中的boost依赖关系。 等效的boost :: system :: error_code - Get rid of boost dependencies in TCP proxy. boost::system::error_code equivalent
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM