[英]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.