1 /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ 2 /* 3 * Copyright (c) 2008 litl, LLC 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a copy 6 * of this software and associated documentation files (the "Software"), to 7 * deal in the Software without restriction, including without limitation the 8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9 * sell copies of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24 #ifndef GI_GERROR_H_ 25 #define GI_GERROR_H_ 26 27 #include <config.h> 28 29 #include <girepository.h> 30 #include <glib-object.h> 31 #include <glib.h> 32 33 #include <js/PropertySpec.h> 34 #include <js/TypeDecls.h> 35 36 #include "gi/wrapperutils.h" 37 #include "cjs/macros.h" 38 #include "util/log.h" 39 40 class ErrorPrototype; 41 class ErrorInstance; 42 namespace JS { 43 class CallArgs; 44 } 45 46 /* To conserve memory, we have two different kinds of private data for GError 47 * JS wrappers: ErrorInstance, and ErrorPrototype. Both inherit from ErrorBase 48 * for their common functionality. For more information, see the notes in 49 * wrapperutils.h. 50 * 51 * ErrorPrototype, unlike the other GIWrapperPrototype subclasses, represents a 52 * single error domain instead of a single GType. All Errors have a GType of 53 * G_TYPE_ERROR. 54 * 55 * Note that in some situations GError structs can show up as BoxedInstance 56 * instead of ErrorInstance. We have some special cases in this code to deal 57 * with that. 58 */ 59 60 class ErrorBase 61 : public GIWrapperBase<ErrorBase, ErrorPrototype, ErrorInstance> { 62 friend class GIWrapperBase<ErrorBase, ErrorPrototype, ErrorInstance>; 63 64 protected: 65 explicit ErrorBase(ErrorPrototype* proto = nullptr) GIWrapperBase(proto)66 : GIWrapperBase(proto) {} ~ErrorBase(void)67 ~ErrorBase(void) {} 68 69 static const GjsDebugTopic debug_topic = GJS_DEBUG_GERROR; 70 static constexpr const char* debug_tag = "gerror"; 71 72 static const struct JSClassOps class_ops; 73 static const struct JSClass klass; 74 static JSPropertySpec proto_properties[]; 75 static JSFunctionSpec static_methods[]; 76 77 // Accessors 78 79 public: 80 [[nodiscard]] GQuark domain(void) const; 81 82 // Property getters 83 84 protected: 85 GJS_JSAPI_RETURN_CONVENTION 86 static bool get_domain(JSContext* cx, unsigned argc, JS::Value* vp); 87 GJS_JSAPI_RETURN_CONVENTION 88 static bool get_message(JSContext* cx, unsigned argc, JS::Value* vp); 89 GJS_JSAPI_RETURN_CONVENTION 90 static bool get_code(JSContext* cx, unsigned argc, JS::Value* vp); 91 92 // JS methods 93 94 GJS_JSAPI_RETURN_CONVENTION 95 static bool value_of(JSContext* cx, unsigned argc, JS::Value* vp); 96 97 public: 98 GJS_JSAPI_RETURN_CONVENTION 99 static bool to_string(JSContext* cx, unsigned argc, JS::Value* vp); 100 101 // Helper methods 102 103 GJS_JSAPI_RETURN_CONVENTION 104 static GError* to_c_ptr(JSContext* cx, JS::HandleObject obj); 105 106 GJS_JSAPI_RETURN_CONVENTION 107 static bool transfer_to_gi_argument(JSContext* cx, JS::HandleObject obj, 108 GIArgument* arg, 109 GIDirection transfer_direction, 110 GITransfer transfer_ownership); 111 112 GJS_JSAPI_RETURN_CONVENTION 113 static bool typecheck(JSContext* cx, JS::HandleObject obj); 114 [[nodiscard]] static bool typecheck(JSContext* cx, JS::HandleObject obj, 115 GjsTypecheckNoThrow); 116 }; 117 118 class ErrorPrototype : public GIWrapperPrototype<ErrorBase, ErrorPrototype, 119 ErrorInstance, GIEnumInfo> { 120 friend class GIWrapperPrototype<ErrorBase, ErrorPrototype, ErrorInstance, 121 GIEnumInfo>; 122 friend class GIWrapperBase<ErrorBase, ErrorPrototype, ErrorInstance>; 123 124 GQuark m_domain; 125 126 static constexpr InfoType::Tag info_type_tag = InfoType::Enum; 127 128 explicit ErrorPrototype(GIEnumInfo* info, GType gtype); 129 ~ErrorPrototype(void); 130 131 GJS_JSAPI_RETURN_CONVENTION 132 bool get_parent_proto(JSContext* cx, JS::MutableHandleObject proto) const; 133 134 public: domain(void)135 [[nodiscard]] GQuark domain(void) const { return m_domain; } 136 137 GJS_JSAPI_RETURN_CONVENTION 138 static bool define_class(JSContext* cx, JS::HandleObject in_object, 139 GIEnumInfo* info); 140 }; 141 142 class ErrorInstance : public GIWrapperInstance<ErrorBase, ErrorPrototype, 143 ErrorInstance, GError> { 144 friend class GIWrapperInstance<ErrorBase, ErrorPrototype, ErrorInstance, 145 GError>; 146 friend class GIWrapperBase<ErrorBase, ErrorPrototype, ErrorInstance>; 147 148 explicit ErrorInstance(JSContext* cx, JS::HandleObject obj); 149 ~ErrorInstance(void); 150 151 public: copy_gerror(GError * other)152 void copy_gerror(GError* other) { m_ptr = g_error_copy(other); } 153 GJS_JSAPI_RETURN_CONVENTION copy_ptr(JSContext *,GType,void * ptr)154 static GError* copy_ptr(JSContext*, GType, void* ptr) { 155 return g_error_copy(static_cast<GError*>(ptr)); 156 } 157 158 // Accessors 159 message(void)160 [[nodiscard]] const char* message(void) const { return m_ptr->message; } code(void)161 [[nodiscard]] int code(void) const { return m_ptr->code; } 162 163 // JS constructor 164 165 private: 166 GJS_JSAPI_RETURN_CONVENTION 167 bool constructor_impl(JSContext* cx, JS::HandleObject obj, 168 const JS::CallArgs& args); 169 170 // Public API 171 172 public: 173 GJS_JSAPI_RETURN_CONVENTION 174 static JSObject* object_for_c_ptr(JSContext* cx, GError* gerror); 175 }; 176 177 GJS_JSAPI_RETURN_CONVENTION 178 GError *gjs_gerror_make_from_error(JSContext *cx, 179 JS::HandleObject obj); 180 181 GJS_JSAPI_RETURN_CONVENTION 182 bool gjs_define_error_properties(JSContext* cx, JS::HandleObject obj); 183 184 bool gjs_throw_gerror(JSContext* cx, GError* error); 185 186 #endif // GI_GERROR_H_ 187