簡體   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