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