繁体   English   中英

GStreamer GError to boost::system::error_code?

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

寻找一种巧妙的方法来转换 gstreamer/glib GError:

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

到 boost::system::error_code。 通常,您可以创建一个类别并注册一个枚举来提升。 GStreamer 使用枚举,但代码以 int 形式返回。 GQuark 是一个类别。

这主要是为了标准化跨应用程序的错误处理。

GQuark 是一个类别。

我想你的意思是比喻性的。

夸克是字符串和 integer 标识符之间的关联。 给定字符串或 Quark 标识符,可以检索另一个。

这就像实习字符串,又名原子。 所以GQuark实际上代表了一个字符串,然后,您希望将其视为一个类别。 好吧。

类别为 static

出色地。 通常。 至少类别是具有全局 object 标识的 singleton。 因此,假设您静态地知道期望的域,您可以为这些域创建类别。

Map 它们对域的文本表示使得最稳定的映射。

单一类别

首先,这里有一个类别:

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};
}

现在你可以

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

它会神奇地做正确的事。

一般错误翻译:

对于从 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM