1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2008 litl, LLC
#ifndef GI_GERROR_H_
#define GI_GERROR_H_
#include <config.h>
#include <girepository/girepository.h>
#include <glib-object.h>
#include <glib.h>
#include <js/PropertySpec.h>
#include <js/TypeDecls.h>
#include "gi/cwrapper.h"
#include "gi/info.h"
#include "gi/wrapperutils.h"
#include "gjs/auto.h" // for Gjs::AutoPointer operators
#include "gjs/gerror-result.h"
#include "gjs/macros.h"
#include "util/log.h"
class ErrorPrototype;
class ErrorInstance;
namespace JS {
class CallArgs;
}
/* To conserve memory, we have two different kinds of private data for GError
* JS wrappers: ErrorInstance, and ErrorPrototype. Both inherit from ErrorBase
* for their common functionality. For more information, see the notes in
* wrapperutils.h.
*
* ErrorPrototype, unlike the other GIWrapperPrototype subclasses, represents a
* single error domain instead of a single GType. All Errors have a GType of
* G_TYPE_ERROR.
*
* Note that in some situations GError structs can show up as BoxedInstance
* instead of ErrorInstance. We have some special cases in this code to deal
* with that.
*/
class ErrorBase
: public GIWrapperBase<ErrorBase, ErrorPrototype, ErrorInstance> {
friend class CWrapperPointerOps<ErrorBase>;
friend class GIWrapperBase<ErrorBase, ErrorPrototype, ErrorInstance>;
protected:
explicit ErrorBase(ErrorPrototype* proto = nullptr)
: GIWrapperBase(proto) {}
static constexpr GjsDebugTopic DEBUG_TOPIC = GJS_DEBUG_GERROR;
static constexpr const char* DEBUG_TAG = "gerror";
static const struct JSClassOps class_ops;
public:
// public in order to implement Error.isError()
static const struct JSClass klass;
protected:
static JSPropertySpec proto_properties[];
static JSFunctionSpec static_methods[];
// Accessors
public:
[[nodiscard]] GQuark domain(void) const;
// Property getters
protected:
GJS_JSAPI_RETURN_CONVENTION
static bool get_domain(JSContext* cx, unsigned argc, JS::Value* vp);
GJS_JSAPI_RETURN_CONVENTION
static bool get_message(JSContext* cx, unsigned argc, JS::Value* vp);
GJS_JSAPI_RETURN_CONVENTION
static bool get_code(JSContext* cx, unsigned argc, JS::Value* vp);
// JS methods
GJS_JSAPI_RETURN_CONVENTION
static bool value_of(JSContext* cx, unsigned argc, JS::Value* vp);
public:
GJS_JSAPI_RETURN_CONVENTION
static bool to_string(JSContext* cx, unsigned argc, JS::Value* vp);
// Helper methods
GJS_JSAPI_RETURN_CONVENTION
static GError* to_c_ptr(JSContext* cx, JS::HandleObject obj);
GJS_JSAPI_RETURN_CONVENTION
static bool transfer_to_gi_argument(JSContext* cx, JS::HandleObject obj,
GIArgument* arg,
GIDirection transfer_direction,
GITransfer transfer_ownership);
GJS_JSAPI_RETURN_CONVENTION
static bool typecheck(JSContext* cx, JS::HandleObject obj);
[[nodiscard]] static bool typecheck(JSContext* cx, JS::HandleObject obj,
GjsTypecheckNoThrow);
};
class ErrorPrototype
: public GIWrapperPrototype<ErrorBase, ErrorPrototype, ErrorInstance,
GI::AutoEnumInfo, GI::EnumInfo> {
friend class GIWrapperPrototype<ErrorBase, ErrorPrototype, ErrorInstance,
GI::AutoEnumInfo, GI::EnumInfo>;
friend class GIWrapperBase<ErrorBase, ErrorPrototype, ErrorInstance>;
GQuark m_domain;
explicit ErrorPrototype(const GI::EnumInfo, GType);
~ErrorPrototype(void);
GJS_JSAPI_RETURN_CONVENTION
bool get_parent_proto(JSContext* cx, JS::MutableHandleObject proto) const;
public:
[[nodiscard]] GQuark domain(void) const { return m_domain; }
GJS_JSAPI_RETURN_CONVENTION
static bool define_class(JSContext* cx, JS::HandleObject in_object,
const GI::EnumInfo);
};
class ErrorInstance : public GIWrapperInstance<ErrorBase, ErrorPrototype,
ErrorInstance, GError> {
friend class GIWrapperInstance<ErrorBase, ErrorPrototype, ErrorInstance,
GError>;
friend class GIWrapperBase<ErrorBase, ErrorPrototype, ErrorInstance>;
explicit ErrorInstance(ErrorPrototype* prototype, JS::HandleObject obj);
~ErrorInstance(void);
public:
void copy_gerror(GError* other) { m_ptr = g_error_copy(other); }
GJS_JSAPI_RETURN_CONVENTION
static GError* copy_ptr(JSContext*, GType, void* ptr) {
return g_error_copy(static_cast<GError*>(ptr));
}
// Accessors
[[nodiscard]] const char* message(void) const { return m_ptr->message; }
[[nodiscard]] int code(void) const { return m_ptr->code; }
// JS constructor
private:
GJS_JSAPI_RETURN_CONVENTION
bool constructor_impl(JSContext* cx, JS::HandleObject obj,
const JS::CallArgs& args);
// Public API
public:
GJS_JSAPI_RETURN_CONVENTION
static JSObject* object_for_c_ptr(JSContext* cx, GError* gerror);
};
GJS_JSAPI_RETURN_CONVENTION
GError* gjs_gerror_make_from_thrown_value(JSContext* cx);
GJS_JSAPI_RETURN_CONVENTION
bool gjs_define_error_properties(JSContext* cx, JS::HandleObject obj);
bool gjs_throw_gerror(JSContext* cx, Gjs::AutoError const&);
#endif // GI_GERROR_H_
|