Return-Path: X-Original-To: apmail-couchdb-commits-archive@www.apache.org Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id D0A3B184BE for ; Mon, 13 Jul 2015 18:45:01 +0000 (UTC) Received: (qmail 84335 invoked by uid 500); 13 Jul 2015 18:45:01 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 84230 invoked by uid 500); 13 Jul 2015 18:45:01 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 84111 invoked by uid 99); 13 Jul 2015 18:45:01 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 13 Jul 2015 18:45:01 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id DF51FE0941; Mon, 13 Jul 2015 18:45:00 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: kxepal@apache.org To: commits@couchdb.apache.org Date: Mon, 13 Jul 2015 18:45:05 -0000 Message-Id: <11d0b770149542b2ba738456c2d9486b@git.apache.org> In-Reply-To: <9be4c77905ae4fe0a4f2a108e023e74d@git.apache.org> References: <9be4c77905ae4fe0a4f2a108e023e74d@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [06/43] jiffy commit: updated refs/heads/upstream to 446e284 Use a resource for the encoder structure This is ground work to allow Jiffy to yield back to the scheduler. Creating an encoder resource will allow for the necessary state to be carried across NIF function invocations. Project: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/commit/5ccff57a Tree: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/tree/5ccff57a Diff: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/diff/5ccff57a Branch: refs/heads/upstream Commit: 5ccff57adec8493d72005cc9b92756f69c4e33d4 Parents: 79d24e9 Author: Paul J. Davis Authored: Thu Jun 12 16:58:19 2014 -0500 Committer: Paul J. Davis Committed: Fri Jun 13 16:56:35 2014 -0500 ---------------------------------------------------------------------- c_src/encoder.c | 113 +++++++++++++++++++++++++++++++++++---------------- c_src/jiffy.c | 12 +++++- c_src/jiffy.h | 5 ++- src/jiffy.erl | 9 ++-- 4 files changed, 100 insertions(+), 39 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/5ccff57a/c_src/encoder.c ---------------------------------------------------------------------- diff --git a/c_src/encoder.c b/c_src/encoder.c index c23b309..1b916b6 100644 --- a/c_src/encoder.c +++ b/c_src/encoder.c @@ -36,6 +36,7 @@ typedef struct { int iolen; ERL_NIF_TERM iolist; + ErlNifBinary bin; ErlNifBinary* curr; @@ -60,39 +61,24 @@ static char* shifts[NUM_SHIFTS] = { }; -int -enc_init(Encoder* e, ErlNifEnv* env, ERL_NIF_TERM opts, ErlNifBinary* bin) +Encoder* +enc_new(ErlNifEnv* env) { - ERL_NIF_TERM val; + jiffy_st* st = (jiffy_st*) enif_priv_data(env); + Encoder* e = enif_alloc_resource(st->res_enc, sizeof(Encoder)); - e->env = env; - e->atoms = enif_priv_data(env); + e->atoms = st; e->uescape = 0; e->pretty = 0; e->shiftcnt = 0; e->count = 0; - if(!enif_is_list(env, opts)) { - return 0; - } - - while(enif_get_list_cell(env, opts, &val, &opts)) { - if(enif_compare(val, e->atoms->atom_uescape) == 0) { - e->uescape = 1; - } else if(enif_compare(val, e->atoms->atom_pretty) == 0) { - e->pretty = 1; - } else if(enif_compare(val, e->atoms->atom_force_utf8) == 0) { - // Ignore, handled in Erlang - } else { - return 0; - } - } - e->iolen = 0; - e->iolist = enif_make_list(env, 0); - e->curr = bin; + e->curr = &(e->bin); if(!enif_alloc_binary(BIN_INC_SIZE, e->curr)) { - return 0; + e->curr = NULL; + enif_release_resource(e); + return NULL; } memset(e->curr->data, 0, e->curr->size); @@ -101,12 +87,21 @@ enc_init(Encoder* e, ErlNifEnv* env, ERL_NIF_TERM opts, ErlNifBinary* bin) e->u = (unsigned char*) e->curr->data; e->i = 0; + return e; +} + +int +enc_init(Encoder* e, ErlNifEnv* env) +{ + e->env = env; return 1; } void -enc_destroy(Encoder* e) +enc_destroy(ErlNifEnv* env, void* obj) { + Encoder* e = (Encoder*) obj; + if(e->curr != NULL) { enif_release_binary(e->curr); } @@ -494,13 +489,57 @@ enc_comma(Encoder* e) } ERL_NIF_TERM -encode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +encode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { - Encoder enc; - Encoder* e = &enc; + jiffy_st* st = (jiffy_st*) enif_priv_data(env); + Encoder* e; - ErlNifBinary bin; - ERL_NIF_TERM ret; + ERL_NIF_TERM opts; + ERL_NIF_TERM val; + ERL_NIF_TERM tmp_argv[3]; + + if(argc != 2) { + return enif_make_badarg(env); + } + + e = enc_new(env); + if(e == NULL) { + return make_error(st, env, "internal_error"); + } + + tmp_argv[0] = enif_make_resource(env, e); + tmp_argv[1] = enif_make_list(env, 1, argv[0]); + tmp_argv[2] = enif_make_list(env, 0); + + enif_release_resource(e); + + opts = argv[1]; + if(!enif_is_list(env, opts)) { + return enif_make_badarg(env); + } + + while(enif_get_list_cell(env, opts, &val, &opts)) { + if(enif_compare(val, e->atoms->atom_uescape) == 0) { + e->uescape = 1; + } else if(enif_compare(val, e->atoms->atom_pretty) == 0) { + e->pretty = 1; + } else if(enif_compare(val, e->atoms->atom_force_utf8) == 0) { + // Ignore, handled in Erlang + } else { + return enif_make_badarg(env); + } + } + + return encode_iter(env, 3, tmp_argv); +} + +ERL_NIF_TERM +encode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + Encoder* e; + jiffy_st* st = (jiffy_st*) enif_priv_data(env); + + ERL_NIF_TERM ret = 0; ERL_NIF_TERM stack; ERL_NIF_TERM curr; @@ -510,15 +549,22 @@ encode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) ErlNifSInt64 lval; double dval; - if(argc != 2) { + if(argc != 3) { + return enif_make_badarg(env); + } else if(!enif_get_resource(env, argv[0], st->res_enc, (void**) &e)) { + return enif_make_badarg(env); + } else if(!enif_is_list(env, argv[1])) { + return enif_make_badarg(env); + } else if(!enif_is_list(env, argv[2])) { return enif_make_badarg(env); } - if(!enc_init(e, env, argv[1], &bin)) { + if(!enc_init(e, env)) { return enif_make_badarg(env); } - stack = enif_make_list(env, 1, argv[0]); + stack = argv[1]; + e->iolist = argv[2]; while(!enif_is_empty_list(env, stack)) { if(!enif_get_list_cell(env, stack, &curr, &stack)) { @@ -704,6 +750,5 @@ encode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) } done: - enc_destroy(e); return ret; } http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/5ccff57a/c_src/jiffy.c ---------------------------------------------------------------------- diff --git a/c_src/jiffy.c b/c_src/jiffy.c index e0c1f20..0d84dcf 100644 --- a/c_src/jiffy.c +++ b/c_src/jiffy.c @@ -37,6 +37,15 @@ load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info) NULL ); + st->res_enc = enif_open_resource_type( + env, + NULL, + "encoder", + enc_destroy, + ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER, + NULL + ); + *priv = (void*) st; return 0; @@ -65,7 +74,8 @@ static ErlNifFunc funcs[] = { {"nif_decode_init", 1, decode_init}, {"nif_decode_iter", 4, decode_iter}, - {"nif_encode", 2, encode} + {"nif_encode_init", 2, encode_init}, + {"nif_encode_iter", 3, encode_iter} }; ERL_NIF_INIT(jiffy, funcs, &load, &reload, &upgrade, &unload); http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/5ccff57a/c_src/jiffy.h ---------------------------------------------------------------------- diff --git a/c_src/jiffy.h b/c_src/jiffy.h index bfd5940..97863be 100644 --- a/c_src/jiffy.h +++ b/c_src/jiffy.h @@ -24,6 +24,7 @@ typedef struct { ERL_NIF_TERM ref_array; ErlNifResourceType* res_dec; + ErlNifResourceType* res_enc; } jiffy_st; ERL_NIF_TERM make_atom(ErlNifEnv* env, const char* name); @@ -32,9 +33,11 @@ ERL_NIF_TERM make_error(jiffy_st* st, ErlNifEnv* env, const char* error); ERL_NIF_TERM decode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); ERL_NIF_TERM decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); -ERL_NIF_TERM encode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM encode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +ERL_NIF_TERM encode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); void dec_destroy(ErlNifEnv* env, void* obj); +void enc_destroy(ErlNifEnv* env, void* obj); int int_from_hex(const unsigned char* p); int int_to_hex(int val, char* p); http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/5ccff57a/src/jiffy.erl ---------------------------------------------------------------------- diff --git a/src/jiffy.erl b/src/jiffy.erl index c9e65e4..cc756ba 100644 --- a/src/jiffy.erl +++ b/src/jiffy.erl @@ -26,7 +26,7 @@ encode(Data) -> encode(Data, Options) -> ForceUTF8 = lists:member(force_utf8, Options), - case nif_encode(Data, Options) of + case nif_encode_init(Data, Options) of {error, invalid_string} when ForceUTF8 == true -> FixedData = jiffy_utf8:fix(Data), encode(FixedData, Options -- [force_utf8]); @@ -106,6 +106,9 @@ nif_decode_init(_Data) -> nif_decode_iter(_Data, _Decoder, _, _) -> ?NOT_LOADED. -nif_encode(_Data, _Options) -> - ?NOT_LOADED. +nif_encode_init(_Data, _Options) -> + ?NOT_LOADED, + nif_encode_iter(x, y, z). +nif_encode_iter(_Encoder, _Stack, _IoList) -> + ?NOT_LOADED. \ No newline at end of file