/*
 *  call-seq:
 *     term_enum.to_json() -> string
 *
 *  Returns a JSON representation of the term enum. You can speed this up by
 *  having the method return arrays instead of objects, simply by passing an
 *  argument to the to_json method. For example;
 *
 *    term_enum.to_json() #=> 
 *    # [
 *    #   {"term":"apple","frequency":12},
 *    #   {"term":"banana","frequency":2},
 *    #   {"term":"cantaloupe","frequency":12}
 *    # ]
 *
 *    term_enum.to_json(:fast) #=> 
 *    # [
 *    #   ["apple",12],
 *    #   ["banana",2],
 *    #   ["cantaloupe",12]
 *    # ]
 */
static VALUE
frt_te_to_json(int argc, VALUE *argv, VALUE self)
{
    TermEnum *te = (TermEnum *)DATA_PTR(self);
    VALUE rjson;
    char *json, *jp;
    char *term;
    int capa = 65536;
    jp = json = ALLOC_N(char, capa);
    *(jp++) = '[';

    if (argc > 0) {
        while (NULL != (term = te->next(te))) {
            /* enough room for for term after converting " to '"' and frequency
             * plus some extra for good measure */
            *(jp++) = '[';
            if (te->curr_term_len * 3 + (jp - json) + 100 > capa) {
                capa <<= 1;
                REALLOC_N(json, char, capa);
            }
            jp = json_concat_string(jp, term);
            *(jp++) = ',';
            sprintf(jp, "%d", te->curr_ti.doc_freq);
            jp += strlen(jp);
            *(jp++) = ']';
            *(jp++) = ',';
        }
    }
    else {
        while (NULL != (term = te->next(te))) {
            /* enough room for for term after converting " to '"' and frequency
             * plus some extra for good measure */
            if (te->curr_term_len * 3 + (jp - json) + 100 > capa) {
                capa <<= 1;
                REALLOC_N(json, char, capa);
            }
            *(jp++) = '{';
            memcpy(jp, "\"term\":", 7);
            jp += 7;
            jp = json_concat_string(jp, term);
            *(jp++) = ',';
            memcpy(jp, "\"frequency\":", 12);
            jp += 12;
            sprintf(jp, "%d", te->curr_ti.doc_freq);
            jp += strlen(jp);
            *(jp++) = '}';
            *(jp++) = ',';
        }
    }
    if (*(jp-1) == ',') jp--;
    *(jp++) = ']';
    *jp = '\0';

    rjson = rb_str_new2(json);
    free(json);
    return rjson;
}