[英]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
实际上代表了一个字符串,然后,您希望将其视为一个类别。 好吧。
出色地。 通常。 至少类别是具有全局 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.