[英]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.好吧。
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 它们对域的文本表示使得最稳定的映射。
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.它会神奇地做正确的事。
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.