diff options
| author | Colin Walters <walters@verbum.org> | 2012-11-05 08:18:01 -0500 |
|---|---|---|
| committer | Colin Walters <walters@verbum.org> | 2012-11-05 08:21:13 -0500 |
| commit | ef49ab9d8d98edfc7edc0c1b470b8c2fc91109a6 (patch) | |
| tree | fb5ba55a62d02672edca68f01ebe7f2f352f7cd7 | |
| parent | c61483400bbd72866bddfca02bd465b073d9d426 (diff) | |
| download | gjs-wip/gjson.tar.gz | |
wipwip/gjson
| -rw-r--r-- | Makefile-modules.am | 7 | ||||
| -rw-r--r-- | modules/gjson.c | 117 | ||||
| -rw-r--r-- | modules/gjson.h | 42 | ||||
| -rw-r--r-- | test/js/testGJSON.js | 73 |
4 files changed, 238 insertions, 1 deletions
diff --git a/Makefile-modules.am b/Makefile-modules.am index 47e7a510..326bc1d7 100644 --- a/Makefile-modules.am +++ b/Makefile-modules.am @@ -18,7 +18,7 @@ dist_gjsjs_DATA += \ modules/promise.js \ modules/format.js -gjsnative_LTLIBRARIES += console.la debugger.la langNative.la mainloop.la gettextNative.la dbusNative.la cairoNative.la system.la formatNative.la +gjsnative_LTLIBRARIES += console.la debugger.la gjson.la langNative.la mainloop.la gettextNative.la dbusNative.la cairoNative.la system.la formatNative.la JS_NATIVE_MODULE_CFLAGS = \ $(AM_CFLAGS) \ @@ -106,6 +106,11 @@ system_la_SOURCES = \ modules/system.h \ modules/system.c +gjson_la_SOURCES = modules/gjson.c modules/gjson.h +gjson_la_CFLAGS = $(JS_NATIVE_MODULE_CFLAGS) +gjson_la_LIBADD = $(JS_NATIVE_MODULE_LIBADD) +gjson_la_LDFLAGS = $(JS_NATIVE_MODULE_LDFLAGS) + console_la_CFLAGS = \ $(JS_NATIVE_MODULE_CFLAGS) console_la_LIBADD = \ diff --git a/modules/gjson.c b/modules/gjson.c new file mode 100644 index 00000000..634fbbe0 --- /dev/null +++ b/modules/gjson.c @@ -0,0 +1,117 @@ +/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ +/* vim: set ts=8 sw=4 et tw=78: + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "config.h" + +#include <stdlib.h> +#include <string.h> + +#include <jsapi.h> +#include <gio/gio.h> +#include <gjs/gjs-module.h> +#include <gi/object.h> +#include <gjs/compat.h> + +#include "gjson.h" + +JSBool +gjs_gjson_load(JSContext *context, + uintN argc, + jsval *vp) +{ + JSBool ret = JS_FALSE; + GError *local_error = NULL; + GError **error = &local_error; + jsval *argv = JS_ARGV(cx, vp); + JSObject *stream_obj = NULL; + GInputStream *stream = NULL; + guchar buf[4096]; + gssize bytes_read; + JSONParser *parser = NULL; + jsval rv = JSVAL_NULL; + + if (!gjs_parse_args(context, "gjson_load", "o", argc, argv, + "stream", &stream_obj)) + goto out; + + if (!gjs_typecheck_object (context, stream_obj, G_TYPE_INPUT_STREAM, TRUE)) + goto out; + stream = (GInputStream*)gjs_g_object_from_object (context, stream_obj); + + parser = JS_BeginJSONParse(context, &rv); + + while ((bytes_read = g_input_stream_read (stream, buf, sizeof (buf), + NULL, error)) > 0) { + if (!JS_ConsumeJSONText(context, parser, (jschar*)buf, (uint32)bytes_read)) + goto out; + } + if (bytes_read < 0) + goto out; + + /* Swap parser to NULL so we don't clean up */ + { + JSONParser *tmp = parser; + parser = NULL; + if (!JS_FinishJSONParse(context, tmp, JSVAL_NULL)) + goto out; + } + + ret = JS_TRUE; + out: + /* Clean up parser if necessary */ + if (parser) + JS_FinishJSONParse(context, parser, JSVAL_NULL); + return ret; +} + +JSBool +gjs_define_gjson_stuff(JSContext *context, + JSObject *module_obj) +{ + if (!JS_DefineFunction(context, module_obj, + "load", + (JSNative) gjs_gjson_load, + 1, GJS_MODULE_PROP_FLAGS)) + return JS_FALSE; + + return JS_TRUE; +} + +GJS_REGISTER_NATIVE_MODULE("gjson", gjs_define_gjson_stuff); diff --git a/modules/gjson.h b/modules/gjson.h new file mode 100644 index 00000000..ebdb7741 --- /dev/null +++ b/modules/gjson.h @@ -0,0 +1,42 @@ +/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ +/* + * Copyright (c) 2012 Colin Walters <walters@verbum.org> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef __GJS_JSON_H__ +#define __GJS_JSON_H__ + +#include <config.h> +#include <glib.h> + +#include <jsapi.h> + +G_BEGIN_DECLS + +JSBool gjs_define_gjson_stuff (JSContext *context, + JSObject *in_object); +JSBool gjs_gjson_load (JSContext *context, + uintN argc, + jsval *vp); + +G_END_DECLS + +#endif /* __GJS_CONSOLE_H__ */ diff --git a/test/js/testGJSON.js b/test/js/testGJSON.js new file mode 100644 index 00000000..864d136f --- /dev/null +++ b/test/js/testGJSON.js @@ -0,0 +1,73 @@ +// application/javascript;version=1.8 +const GJSON = imports.gjson; +const Gio = imports.gi.Gio; + +function testLoad() { + var jsonData = "{'hello': 'world', 'v': 42, 'x': 3.14159}"; + var mem = Gio.MemoryInputStream.new_from_bytes(GLib.Bytes.new(jsonData, ); + +} + +function testIdle() { + var trackIdles = { + runTwiceCount : 0, + runOnceCount : 0, + neverRunsCount : 0, + quitAfterManyRunsCount : 0 + }; + Mainloop.idle_add(function() { + trackIdles.runTwiceCount += 1; + if (trackIdles.runTwiceCount == 2) + return false; + else + return true; + }); + Mainloop.idle_add(function() { + trackIdles.runOnceCount += 1; + return false; + }); + var neverRunsId = + Mainloop.idle_add(function() { + trackIdles.neverRunsCount += 1; + return false; + }); + Mainloop.idle_add(function() { + trackIdles.quitAfterManyRunsCount += 1; + if (trackIdles.quitAfterManyRunsCount > 10) { + Mainloop.quit('foobar'); + return false; + } else { + return true; + } + }); + + Mainloop.source_remove(neverRunsId); + + Mainloop.run('foobar'); + + assertEquals("one-shot ran once", 1, trackIdles.runOnceCount); + assertEquals("two-shot ran twice", 2, trackIdles.runTwiceCount); + assertEquals("removed never ran", 0, trackIdles.neverRunsCount); + assertEquals("quit after many ran 11", 11, trackIdles.quitAfterManyRunsCount); + + // check re-entrancy of removing closures while they + // are being invoked + + trackIdles.removeId = Mainloop.idle_add(function() { + Mainloop.source_remove(trackIdles.removeId); + Mainloop.quit('foobar'); + return false; + }); + Mainloop.run('foobar'); + + // Add an idle before exit, then never run main loop again. + // This is to test that we remove idle callbacks when the associated + // JSContext is blown away. The leak check in gjs-unit will + // fail if the idle function is not garbage collected. + Mainloop.idle_add(function() { + fail("This should never have been called"); + return true; + }); +} + +gjstestRun(); |
