On Wed, May 22, 2013 at 04:04:38PM +0200, Arne Goedeke wrote: > Maybe its helpful to be able to pass a string there, aswell. That way > one could encode all objects without encode_json() as 'undefined' > cheaply.
indeed, i added that. since this is my first venture into CMODs i am attaching the patch here for review. (i also need to check or update my commit access, so i'd appreciate if someone else could apply this patch if it is ok) greetings, martin.
>From 85d912d46d709921084359060015687f7cada6df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20B=C3=A4hr?= <[email protected]> Date: Thu, 23 May 2013 12:54:42 +0800 Subject: [PATCH 1/1] add a callback argument to JSON.encode() --- src/post_modules/JSON/json.cmod | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/post_modules/JSON/json.cmod b/src/post_modules/JSON/json.cmod index 4673237..acfdddc 100644 --- a/src/post_modules/JSON/json.cmod +++ b/src/post_modules/JSON/json.cmod @@ -138,6 +138,7 @@ struct encode_context { struct string_builder buf; int flags; int indent; + struct svalue *callback; }; static void json_encode_recur (struct encode_context *ctx, struct svalue *val); @@ -335,14 +336,31 @@ static void json_encode_recur (struct encode_context *ctx, struct svalue *v al) struct object *o = val->u.object; if (o->prog) { int fun = find_identifier ("encode_json", o->prog); - if (fun >= 0) { - int args = 1; + int args = 0; + if (fun < 0 && ctx->callback && TYPEOF(*ctx->callback) != PIKE_T_STRING) { + push_svalue(val); + args++; + } + if (fun >= 0 || (ctx->callback && TYPEOF(*ctx->callback) != PIKE_T_STRING)) { push_int (ctx->flags); + args++; if (ctx->indent >= 0) { - push_int (ctx->indent); + push_int(ctx->indent); args++; } - apply_low (o, fun, args); + + if (fun >= 0) { + apply_low (o, fun, args); + } + else if (ctx->callback) { + apply_svalue(ctx->callback, args); + } + } + else if (ctx->callback && TYPEOF(*ctx->callback) == PIKE_T_STRING) { + push_svalue(ctx->callback); + } + + if (fun >= 0 || ctx->callback) { if (TYPEOF(Pike_sp[-1]) != PIKE_T_STRING) Pike_error ("Expected string from %O->encode_json(), got %s.\n", val, get_name_of_type (TYPEOF(Pike_sp[-1]))); @@ -402,7 +420,7 @@ static void json_encode_recur (struct encode_context *ctx, struct svalue *val ) */ /*! @decl string encode (int|float|string|array|mapping|object val, @ - *! void|int flags) + *! void|int flags, void|function|object|program|string callback) *! *! Encodes a value to a JSON string. *! @@ -411,12 +429,20 @@ static void json_encode_recur (struct encode_context *ctx, struct svalue *v al) *! special numbers NaN and infinity), strings, arrays, mappings *! with string indices, and the special object values @[null], *! @[true] and @[false] defined in this module (or really any - *! object that implements an @expr{encode_json@} callback). + *! object that implements an @expr{encode_json@} callback or + *! is handled by the supplied callback argument). *! *! @param flags *! Flag bit field to control formatting. See @[ASCII_ONLY], *! @[HUMAN_READABLE] and @[PIKE_CANONICAL] for further details. *! + *! @param callback + *! A function that will be called for types that can not be encoded + *! otherwise. It will be called with the value to be encoded as the first + *! argument, and optionally with flags and indent arguments. If a string is + *! supplied, it will be used to replace the value verbatim. + *! The callback must return a string or throw an error. + *! *! @note *! 8-bit and wider characters in input strings are neither escaped *! nor utf-8 encoded by default. @[string_to_utf8] can be used safely @@ -428,13 +454,14 @@ static void json_encode_recur (struct encode_context *ctx, struct svalue *v al) *! @[escape_string] */ PIKEFUN string encode (int|float|string|array|mapping|object val, - void|int flags) + void|int flags, void|function|object|program|string callback) optflags OPT_TRY_OPTIMIZE; { struct encode_context ctx; ONERROR uwp; ctx.flags = (flags ? flags->u.integer : 0); ctx.indent = (ctx.flags & HUMAN_READABLE ? 0 : -1); + ctx.callback = callback; init_string_builder (&ctx.buf, 0); SET_ONERROR (uwp, free_string_builder, &ctx.buf); json_encode_recur (&ctx, val); -- 1.8.0.1
