diff options
author | Derrell Lipman <derrell@samba.org> | 2006-09-26 02:26:36 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 14:20:20 -0500 |
commit | e44df751a17aa5b77c151228b3b0f5af91d4bd12 (patch) | |
tree | c602fae78eb7945ba2d86cf79f0d0f2b971964e6 | |
parent | 26ece8f69772a0991a7299cdef8403a9ad1ad48a (diff) | |
download | samba-e44df751a17aa5b77c151228b3b0f5af91d4bd12.tar.gz samba-e44df751a17aa5b77c151228b3b0f5af91d4bd12.tar.bz2 samba-e44df751a17aa5b77c151228b3b0f5af91d4bd12.zip |
r18911: add a JSON encoder
(This used to be commit 774e87974951a03663a1efd15dfde3d012bcf526)
-rw-r--r-- | jsonrpc/json.esp | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/jsonrpc/json.esp b/jsonrpc/json.esp new file mode 100644 index 0000000000..d06a173f0f --- /dev/null +++ b/jsonrpc/json.esp @@ -0,0 +1,213 @@ +<% + +/* + * Copyright: + * (C) 2006 by Derrell Lipman + * All rights reserved + * + * License: + * LGPL 2.1: http://creativecommons.org/licenses/LGPL/2.1/ + */ + +/* + * This module provides a JSON encoder. + */ + + +/* escape a string as required by json */ +function _escape(s) +{ + var i; + var arr = new Array(); + + for (i = 0; i < strlen(s); i++) + { + var c = substr(s, i, 1); + if (c == '\x00') + { + arr[i] = '\\u0000'; + } + if (Json._internal.convert[c] != undefined) + { + arr[i] = Json._internal.convert[c]; + } + else + { + arr[i] = c; + } + } + + return join("", arr); +} + +/* encode an arbitrary object. called recursively, for object and array */ +function _encode(o) +{ + var type = nativeTypeOf(o); + + if (type == "undefined") + { + return "null"; /* you really shouldn't count on this! */ + } + else if (type == "null") + { + return "null"; + } + else if (type == "boolean") + { + if (o) + { + return "true"; + } + else + { + return "false"; + } + } + else if (type == "c_function" || + type == "js_function" || + type == "string_c_function") + { + /* no output */ + } + else if (type == "float" || + type == "integer" || + type == "integer64" || + type == "pointer") + { + return (o + 0); + } + else if (type == "object") + { + var buf; + + /* Is this an array or an ordinary object? */ + if (o["length"] != undefined) + { + var i; + + /* Assume it's an array if there's a length field */ + buf = "["; + for (i = 0; i < o.length; i++) + { + /* + * NOTE: We don't support sparse arrays nor associative + * arrays. Should we later want to do either, we're supposed + * to send it as an object rather than as an array. + */ + if (i > 0) + { + buf = buf + ","; + } + buf = buf + this.encode(o[i]); + } + buf = buf + "]"; + } + else + { + /* No length field, so it must be an ordinary object */ + var key; + var first = true; + + buf = "{"; + for (key in o) + { + if (! first) + { + buf = buf + ","; + } + buf = buf + '"' + key + '":' + this.encode(o[key]); + first = false; + } + buf = buf + "}"; + } + + return buf; + } + else if (type == "string") + { + return '"' + this._internal.escape(o) + '"'; + } +} + +/* Allocate the public Json access object */ +Json = new Object(); + +/* Json.encode(): encode an arbitrary object */ +Json.encode = _encode; +_encode = null; + +/* Internal stuff, not for external access */ +Json._internal = new Object(); + +Json._internal.escape = _escape; +_escape = null; + +Json._internal.convert = new Object(); +Json._internal.convert['\b'] = '\\b'; +Json._internal.convert['\t'] = '\\t'; +Json._internal.convert['\n'] = '\\n'; +Json._internal.convert['\f'] = '\\f'; +Json._internal.convert['\r'] = '\\r'; +Json._internal.convert['"'] = '\\"'; +Json._internal.convert['\\'] = '\\\\'; +Json._internal.convert['\x01'] = '\\u0001'; +Json._internal.convert['\x02'] = '\\u0002'; +Json._internal.convert['\x03'] = '\\u0003'; +Json._internal.convert['\x04'] = '\\u0004'; +Json._internal.convert['\x05'] = '\\u0005'; +Json._internal.convert['\x06'] = '\\u0006'; +Json._internal.convert['\x07'] = '\\u0007'; +Json._internal.convert['\x08'] = '\\u0008'; +Json._internal.convert['\x09'] = '\\u0009'; +Json._internal.convert['\x0a'] = '\\u000a'; +Json._internal.convert['\x0b'] = '\\u000b'; +Json._internal.convert['\x0c'] = '\\u000c'; +Json._internal.convert['\x0d'] = '\\u000d'; +Json._internal.convert['\x0e'] = '\\u000e'; +Json._internal.convert['\x0f'] = '\\u000f'; +Json._internal.convert['\x10'] = '\\u0010'; +Json._internal.convert['\x11'] = '\\u0011'; +Json._internal.convert['\x12'] = '\\u0012'; +Json._internal.convert['\x13'] = '\\u0013'; +Json._internal.convert['\x14'] = '\\u0014'; +Json._internal.convert['\x15'] = '\\u0015'; +Json._internal.convert['\x16'] = '\\u0016'; +Json._internal.convert['\x17'] = '\\u0017'; +Json._internal.convert['\x18'] = '\\u0018'; +Json._internal.convert['\x19'] = '\\u0019'; +Json._internal.convert['\x1a'] = '\\u001a'; +Json._internal.convert['\x1b'] = '\\u001b'; +Json._internal.convert['\x1c'] = '\\u001c'; +Json._internal.convert['\x1d'] = '\\u001d'; +Json._internal.convert['\x1e'] = '\\u001e'; +Json._internal.convert['\x1f'] = '\\u001f'; +/* + * At some point, we probably want to add \x80-\xff as well, and it's then + * probably more efficient to generate these strings dynamically. (Even now + * it may be, but this was the the way I started, and so it remains.) + */ + + +/* Test it */ +libinclude("base.js"); +function testIt() +{ + var test = new Object(); + test.int = 23; + test.str = "hello world"; + test.float = 223.1; + test.bool = true; + test.array = new Array(); + test.array[0] = "hello"; + test.array[1] = "world"; + test.obj = new Object(); + test.obj.int = 1000; + test.obj.array = new Array(); + test.obj.array[0] = 42; + test.obj.array[1] = 223; + printf("%s\n", Json.encode(test)); +} +//testIt(); + +%> |