changeset 540:fd2ba28ac54b

Js: add dukx_(get|push)_object
author David Demelier <markand@malikania.fr>
date Wed, 08 Jun 2016 22:12:58 +0200
parents 1ac766cd87e8
children 218545c3c560
files modules/js/duktape.hpp modules/js/test/main.cpp
diffstat 2 files changed, 117 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/modules/js/duktape.hpp	Wed Jun 08 22:01:04 2016 +0200
+++ b/modules/js/duktape.hpp	Wed Jun 08 22:12:58 2016 +0200
@@ -31,6 +31,7 @@
 #include <string>
 #include <unordered_map>
 #include <utility>
+#include <vector>
 
 #include <duktape.h>
 
@@ -334,7 +335,7 @@
  * \param pop if true, also remove the exception from the stack
  * \return the information
  */
-inline Exception duk_exception(duk_context *ctx, int index, bool pop = true)
+inline Exception dukx_exception(duk_context *ctx, int index, bool pop = true)
 {
 	Exception ex;
 
@@ -368,7 +369,7 @@
  * \param func the function to call for each properties
  */
 template <typename Func>
-void duk_enumerate(duk_context *ctx, int index, duk_uint_t flags, duk_bool_t getvalue, Func &&func)
+void dukx_enumerate(duk_context *ctx, int index, duk_uint_t flags, duk_bool_t getvalue, Func &&func)
 {
 	duk_enum(ctx, index, flags);
 
@@ -387,7 +388,7 @@
  * \param ex the exception
  */
 template <typename Exception>
-void duk_raise(duk_context *ctx, const Exception &ex)
+void dukx_throw(duk_context *ctx, const Exception &ex)
 {
 	ex.raise(ctx);
 }
@@ -399,7 +400,7 @@
  * \param index the index
  * \return the string
  */
-inline std::string duk_get_stdstring(duk_context *ctx, int index)
+inline std::string dukx_get_std_string(duk_context *ctx, int index)
 {
 	duk_size_t size;
 	const char *text = duk_get_lstring(ctx, index, &size);
@@ -414,7 +415,7 @@
  * \param index the index
  * \return the string
  */
-inline std::string duk_require_stdstring(duk_context *ctx, int index)
+inline std::string dukx_require_std_string(duk_context *ctx, int index)
 {
 	duk_size_t size;
 	const char *text = duk_require_lstring(ctx, index, &size);
@@ -428,9 +429,96 @@
  * \param ctx the context
  * \param str the string
  */
-inline void duk_push_stdstring(duk_context *ctx, const std::string &str)
+inline void dukx_push_std_string(duk_context *ctx, const std::string &str)
 {
 	duk_push_lstring(ctx, str.data(), str.length());
 }
 
+/**
+ * Get an array.
+ *
+ * \param ctx the context
+ * \param index the array index
+ * \param get the conversion function (e.g. duk_get_int)
+ */
+template <typename Getter>
+auto dukx_get_array(duk_context *ctx, duk_idx_t index, Getter &&get)
+{
+	using T = decltype(get(ctx, 0));
+
+	std::vector<T> result;
+	std::size_t length = duk_get_length(ctx, index);
+
+	for (std::size_t i = 0; i < length; ++i) {
+		duk_get_prop_index(ctx, -1, i);
+		result.push_back(get(ctx, -1));
+		duk_pop(ctx);
+	}
+
+	return result;
+}
+
+/**
+ * Push an array.
+ *
+ * \param ctx the context
+ * \param values the values
+ * \param push the function to push values
+ */
+template <typename T, typename Pusher>
+void dukx_push_array(duk_context *ctx, const std::vector<T> &values, Pusher &&push)
+{
+	duk_push_array(ctx);
+
+	int i = 0;
+	for (auto x : values) {
+		push(ctx, x);
+		duk_put_prop_index(ctx, -2, i++);
+	}
+}
+
+/**
+ * Get an object.
+ *
+ * \param ctx the context
+ * \param index the object index
+ * \param get the conversion function (e.g. duk_get_int)
+ */
+template <typename Getter>
+auto dukx_get_object(duk_context *ctx, duk_idx_t index, Getter &&get)
+{
+	using T = decltype(get(ctx, 0));
+
+	std::unordered_map<std::string, T> result;
+
+	duk_enum(ctx, index, 0);
+
+	while (duk_next(ctx, -1, true)) {
+		result.emplace(dukx_get_std_string(ctx, -2), get(ctx, -1));
+		duk_pop_2(ctx);
+	}
+
+	duk_pop(ctx);
+
+	return result;
+}
+
+/**
+ * Push an object.
+ *
+ * \param ctx the context
+ * \param values the values
+ * \param push the function to push values
+ */
+template <typename T, typename Pusher>
+void dukx_push_object(duk_context *ctx, const std::unordered_map<std::string, T> &values, Pusher &&push)
+{
+	duk_push_object(ctx);
+
+	for (const auto &pair : values) {
+		push(ctx, pair.second);
+		duk_put_prop_string(ctx, -2, pair.first.c_str());
+	}
+}
+
 #endif // !DUKTAPE_HPP
--- a/modules/js/test/main.cpp	Wed Jun 08 22:01:04 2016 +0200
+++ b/modules/js/test/main.cpp	Wed Jun 08 22:12:58 2016 +0200
@@ -20,6 +20,29 @@
 
 #include <duktape.hpp>
 
+TEST(Push, array)
+{
+	UniqueContext ctx;
+
+	std::vector<int> v{1, 2, 3};
+
+	dukx_push_array(ctx, v, duk_push_int);
+	ASSERT_EQ(v, dukx_get_array(ctx, -1, duk_get_int));
+}
+
+TEST(Push, object)
+{
+	UniqueContext ctx;
+
+	std::unordered_map<std::string, std::string> o{
+		{ "file", "foo.txt" },
+		{ "password", "test" }
+	};
+
+	dukx_push_object(ctx, o, dukx_push_std_string);
+	ASSERT_EQ(o, dukx_get_object(ctx, -1, dukx_get_std_string));
+}
+
 #if 0
 
 TEST(Basics, enumerate)