/*
* 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;
}