[gjs/esm/static-imports: 39/52] WIP - implement parseURI in C++
- From: Evan Welsh <ewlsh src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/esm/static-imports: 39/52] WIP - implement parseURI in C++
- Date: Fri, 29 Jan 2021 02:14:04 +0000 (UTC)
commit a301dc8a6a66104028ca1831e19c627a3f515553
Author: Philip Chimento <philip chimento gmail com>
Date: Fri Dec 11 18:10:58 2020 -0800
WIP - implement parseURI in C++
Question: Does the function have to throw ImportError? see e.g.
ModuleLoader.resolveRelativePath()
gjs/global.cpp | 1 +
gjs/internal.cpp | 82 +++++++++++++++++++++++++++++++++++++++++++++++++
gjs/internal.h | 5 +++
lib/.eslintrc.yml | 2 +-
lib/bootstrap/module.js | 28 -----------------
lib/modules/esm.js | 4 ++-
6 files changed, 92 insertions(+), 30 deletions(-)
---
diff --git a/gjs/global.cpp b/gjs/global.cpp
index 699a7de5..9e2e1b5a 100644
--- a/gjs/global.cpp
+++ b/gjs/global.cpp
@@ -272,6 +272,7 @@ class GjsInternalGlobal : GjsBaseGlobal {
0),
JS_FN("getRegistry", gjs_internal_global_get_registry, 1, 0),
JS_FN("importSync", gjs_internal_global_import_sync, 1, 0),
+ JS_FN("parseURI", gjs_internal_parse_uri, 1, 0),
JS_FN("setModuleLoadHook", gjs_internal_global_set_module_hook, 3, 0),
JS_FN("setModuleMetaHook", gjs_internal_global_set_module_meta_hook, 2,
0),
diff --git a/gjs/internal.cpp b/gjs/internal.cpp
index 72ea2120..a62d5bfb 100644
--- a/gjs/internal.cpp
+++ b/gjs/internal.cpp
@@ -391,3 +391,85 @@ bool gjs_internal_global_get_registry(JSContext* cx, unsigned argc,
args.rval().setObject(*registry);
return true;
}
+
+bool gjs_internal_parse_uri(JSContext* cx, unsigned argc, JS::Value* vp) {
+ using AutoHashTable =
+ GjsAutoPointer<GHashTable, GHashTable, g_hash_table_destroy>;
+ using AutoURI = GjsAutoPointer<GUri, GUri, g_uri_unref>;
+
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+
+ g_assert(args.length() == 1 && "parseUri() takes one string argument");
+ g_assert(args[0].isString() && "parseUri() takes one string argument");
+
+ JS::RootedString string_arg(cx, args[0].toString());
+ JS::UniqueChars uri = JS_EncodeStringToUTF8(cx, string_arg);
+ if (!uri)
+ return false;
+
+ GError* error = nullptr;
+ AutoURI parsed = g_uri_parse(uri.get(), G_URI_FLAGS_NONE, &error);
+ if (!parsed)
+ return gjs_throw_gerror_message(cx, error);
+
+ JS::RootedObject query_obj(cx, JS_NewPlainObject(cx));
+ if (!query_obj)
+ return false;
+
+ const char* raw_query = g_uri_get_query(parsed);
+ if (raw_query) {
+ AutoHashTable query =
+ g_uri_parse_params(raw_query, -1, "&", G_URI_PARAMS_NONE, &error);
+ if (!query)
+ return gjs_throw_gerror_message(cx, error);
+
+ GHashTableIter iter;
+ g_hash_table_iter_init(&iter, query);
+
+ void* key_ptr;
+ void* value_ptr;
+ while (g_hash_table_iter_next(&iter, &key_ptr, &value_ptr)) {
+ auto* key = static_cast<const char*>(key_ptr);
+ auto* value = static_cast<const char*>(value_ptr);
+
+ JS::ConstUTF8CharsZ value_chars{value, strlen(value)};
+ JS::RootedString value_str(cx,
+ JS_NewStringCopyUTF8Z(cx, value_chars));
+ if (!value_str || !JS_DefineProperty(cx, query_obj, key, value_str,
+ JSPROP_ENUMERATE))
+ return false;
+ }
+ }
+
+ JS::RootedObject return_obj(cx, JS_NewPlainObject(cx));
+ if (!return_obj)
+ return false;
+
+ // JS_NewStringCopyZ() used here and below because the URI components are
+ // %-encoded, meaning ASCII-only
+ JS::RootedString scheme(cx,
+ JS_NewStringCopyZ(cx, g_uri_get_scheme(parsed)));
+ if (!scheme)
+ return false;
+
+ JS::RootedString host(cx, JS_NewStringCopyZ(cx, g_uri_get_host(parsed)));
+ if (!host)
+ return false;
+
+ JS::RootedString path(cx, JS_NewStringCopyZ(cx, g_uri_get_path(parsed)));
+ if (!path)
+ return false;
+
+ if (!JS_DefineProperty(cx, return_obj, "uri", string_arg,
+ JSPROP_ENUMERATE) ||
+ !JS_DefineProperty(cx, return_obj, "scheme", scheme,
+ JSPROP_ENUMERATE) ||
+ !JS_DefineProperty(cx, return_obj, "host", host, JSPROP_ENUMERATE) ||
+ !JS_DefineProperty(cx, return_obj, "path", path, JSPROP_ENUMERATE) ||
+ !JS_DefineProperty(cx, return_obj, "query", query_obj,
+ JSPROP_ENUMERATE))
+ return false;
+
+ args.rval().setObject(*return_obj);
+ return true;
+}
diff --git a/gjs/internal.h b/gjs/internal.h
index bf550c8d..e6d1a4a3 100644
--- a/gjs/internal.h
+++ b/gjs/internal.h
@@ -9,6 +9,8 @@
#include <js/TypeDecls.h>
#include <jsapi.h>
+#include "gjs/macros.h"
+
bool gjs_load_internal_module(JSContext* cx, const char* identifier);
bool gjs_internal_compile_module(JSContext* cx, unsigned argc, JS::Value* vp);
@@ -34,4 +36,7 @@ bool gjs_internal_set_module_private(JSContext* cx, unsigned argc,
bool gjs_internal_global_set_module_resolve_hook(JSContext* cx, unsigned argc,
JS::Value* vp);
+GJS_JSAPI_RETURN_CONVENTION
+bool gjs_internal_parse_uri(JSContext* cx, unsigned argc, JS::Value* vp);
+
#endif // GJS_INTERNAL_H_
diff --git a/lib/.eslintrc.yml b/lib/.eslintrc.yml
index fb5dfe5e..53cfdf5c 100644
--- a/lib/.eslintrc.yml
+++ b/lib/.eslintrc.yml
@@ -15,12 +15,12 @@ globals:
logError: off
print: off
printerr: off
- GLib: readonly
Gio: readonly
ByteUtils: readonly
moduleGlobalThis: readonly
compileModule: readonly
compileInternalModule: readonly
+ parseURI: readonly
setModuleResolveHook: readonly
setModuleMetaHook: readonly
setModuleLoadHook: readonly
diff --git a/lib/bootstrap/module.js b/lib/bootstrap/module.js
index 7323be1c..6b5c5f09 100644
--- a/lib/bootstrap/module.js
+++ b/lib/bootstrap/module.js
@@ -1,8 +1,6 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2020 Evan Welsh <contact evanwelsh com>
-// NOTE: Gio, GLib, and GObject have no overrides.
-
/** @typedef {{ uri: string; scheme: string; host: string; path: string; query: Query }} Uri */
/** @typedef {{ load(uri: Uri): [string, boolean]; }} SchemeHandler */
@@ -106,32 +104,6 @@ function resolveRelativeResourceOrFile(uri, relativePath) {
throw new ImportError('File does not have a valid parent!');
}
-/**
- * Parses a string into a Uri object
- *
- * @param {string} uri the URI to parse as a string
- * @returns {Uri}
- */
-export function parseURI(uri) {
- try {
- const parsed = GLib.Uri.parse(uri, GLib.UriFlags.NONE);
-
- const raw_query = parsed.get_query();
- const query = raw_query ? GLib.Uri.parse_params(raw_query, -1, '&', GLib.UriParamsFlags.NONE) : {};
-
- return {
- uri,
- scheme: parsed.get_scheme(),
- host: parsed.get_host(),
- path: parsed.get_path(),
- query,
-
- };
- } catch (error) {
- throw new ImportError(`Attempted to import invalid URI: ${uri}`);
- }
-}
-
/**
* Handles resolving and loading URIs.
*
diff --git a/lib/modules/esm.js b/lib/modules/esm.js
index 27fc48ec..443ff273 100644
--- a/lib/modules/esm.js
+++ b/lib/modules/esm.js
@@ -1,7 +1,9 @@
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2020 Evan Welsh <contact evanwelsh com>
-import {ESModule, ImportError, loadResourceOrFile, ModuleLoader, parseURI} from '../bootstrap/module.js';
+/* global debug, finishDynamicModuleImport, initAndEval, setModuleDynamicImportHook, parseURI */
+
+import {ESModule, ImportError, loadResourceOrFile, ModuleLoader} from '../bootstrap/module.js';
import {generateModule} from './gi.js';
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]