* gjs_uri_object: * @cx: the current JSContext * @uri: the URI to parse into a JS URI object * @rval: (out): handle to a JSValue where the URI object will be stored * * Parses @uri and creates a JS object with the various parsed parts available * as properties. See type `Uri` in modules/internal/environment.d.ts. * * Basically a JS wrapper for g_uri_parse() for use in the internal global s
| 318 | * Returns: false if an exception is pending, otherwise true |
| 319 | */ |
| 320 | static bool gjs_uri_object(JSContext* cx, const char* uri, |
| 321 | JS::MutableHandleValue rval) { |
| 322 | using AutoHashTable = |
| 323 | Gjs::AutoPointer<GHashTable, GHashTable, g_hash_table_destroy>; |
| 324 | using AutoURI = Gjs::AutoPointer<GUri, GUri, g_uri_unref>; |
| 325 | |
| 326 | Gjs::AutoError error; |
| 327 | AutoURI parsed = g_uri_parse(uri, G_URI_FLAGS_ENCODED, &error); |
| 328 | if (!parsed) { |
| 329 | Gjs::AutoMainRealm ar{cx}; |
| 330 | |
| 331 | gjs_throw_custom(cx, JSEXN_ERR, "ImportError", |
| 332 | "Attempted to import invalid URI: %s (%s)", uri, |
| 333 | error->message); |
| 334 | return false; |
| 335 | } |
| 336 | |
| 337 | JS::RootedObject query_obj(cx, JS_NewPlainObject(cx)); |
| 338 | if (!query_obj) |
| 339 | return false; |
| 340 | |
| 341 | const char* raw_query = g_uri_get_query(parsed); |
| 342 | if (raw_query) { |
| 343 | AutoHashTable query = |
| 344 | g_uri_parse_params(raw_query, -1, "&", G_URI_PARAMS_NONE, &error); |
| 345 | if (!query) { |
| 346 | Gjs::AutoMainRealm ar{cx}; |
| 347 | |
| 348 | gjs_throw_custom(cx, JSEXN_ERR, "ImportError", |
| 349 | "Attempted to import invalid URI: %s (%s)", uri, |
| 350 | error->message); |
| 351 | return false; |
| 352 | } |
| 353 | |
| 354 | GHashTableIter iter; |
| 355 | g_hash_table_iter_init(&iter, query); |
| 356 | |
| 357 | void* key_ptr; |
| 358 | void* value_ptr; |
| 359 | while (g_hash_table_iter_next(&iter, &key_ptr, &value_ptr)) { |
| 360 | const auto* key = static_cast<const char*>(key_ptr); |
| 361 | const auto* value = static_cast<const char*>(value_ptr); |
| 362 | |
| 363 | JS::ConstUTF8CharsZ value_chars{value, strlen(value)}; |
| 364 | JS::RootedString value_str(cx, |
| 365 | JS_NewStringCopyUTF8Z(cx, value_chars)); |
| 366 | if (!value_str || !JS_DefineProperty(cx, query_obj, key, value_str, |
| 367 | JSPROP_ENUMERATE)) |
| 368 | return false; |
| 369 | } |
| 370 | } |
| 371 | |
| 372 | JS::RootedObject return_obj(cx, JS_NewPlainObject(cx)); |
| 373 | if (!return_obj) |
| 374 | return false; |
| 375 | |
| 376 | JS::RootedValue v_uri{cx}; |
| 377 | Gjs::AutoChar uri_string{g_uri_to_string(parsed)}; |
no test coverage detected