Beispiel #1
0
inline static VALUE mArray_json_transfrom(VALUE self, VALUE Vstate, VALUE Vdepth) {
    long i, len = RARRAY_LEN(self);
    VALUE shift, result;
    long depth = NIL_P(Vdepth) ? 0 : FIX2LONG(Vdepth);
    VALUE delim = rb_str_new2(",");
    GET_STATE(Vstate);

    if (state->check_circular) {
        VALUE self_id = rb_obj_id(self);
        rb_hash_aset(state->seen, self_id, Qtrue);
        result = rb_str_buf_new(len);
        if (RSTRING_LEN(state->array_nl)) rb_str_append(delim, state->array_nl);
        shift = rb_str_times(state->indent, LONG2FIX(depth + 1));

        rb_str_buf_cat2(result, "[");
        rb_str_buf_append(result, state->array_nl);
        for (i = 0;  i < len; i++) {
            VALUE element = RARRAY_PTR(self)[i];
            if (RTEST(rb_hash_aref(state->seen, rb_obj_id(element)))) {
                rb_raise(eCircularDatastructure,
                        "circular data structures not supported!");
            }
            OBJ_INFECT(result, element);
            if (i > 0) rb_str_buf_append(result, delim);
            rb_str_buf_append(result, shift);
            rb_str_buf_append(result, rb_funcall(element, i_to_json, 2, Vstate, LONG2FIX(depth + 1)));
        }
        if (RSTRING_LEN(state->array_nl)) {
            rb_str_buf_append(result, state->array_nl);
            rb_str_buf_append(result, rb_str_times(state->indent, LONG2FIX(depth)));
        }
        rb_str_buf_cat2(result, "]");
        rb_hash_delete(state->seen, self_id);
    } else {
        result = rb_str_buf_new(len);
        if (RSTRING_LEN(state->array_nl)) rb_str_append(delim, state->array_nl);
        shift = rb_str_times(state->indent, LONG2FIX(depth + 1));

        rb_str_buf_cat2(result, "[");
        rb_str_buf_append(result, state->array_nl);
        for (i = 0;  i < len; i++) {
            VALUE element = RARRAY_PTR(self)[i];
            OBJ_INFECT(result, element);
            if (i > 0) rb_str_buf_append(result, delim);
            rb_str_buf_append(result, shift);
            rb_str_buf_append(result, rb_funcall(element, i_to_json, 2, Vstate, LONG2FIX(depth + 1)));
        }
        rb_str_buf_append(result, state->array_nl);
        if (RSTRING_LEN(state->array_nl)) {
            rb_str_buf_append(result, rb_str_times(state->indent, LONG2FIX(depth)));
        }
        rb_str_buf_cat2(result, "]");
    }
    return result;
}
Beispiel #2
0
static int hash_to_json_state_i(VALUE key, VALUE value, VALUE Vstate)
{
    VALUE json, buf, Vdepth;
    GET_STATE(Vstate);
    buf = state->memo;
    Vdepth = state->depth;

    if (key == Qundef) return ST_CONTINUE;
    if (state->flag) {
        state->flag = 0;
        rb_str_buf_cat2(buf, ",");
        if (RSTRING_LEN(state->object_nl)) rb_str_buf_append(buf, state->object_nl);
    }
    if (RSTRING_LEN(state->object_nl)) {
        rb_str_buf_append(buf, rb_str_times(state->indent, Vdepth));
    }
    json = rb_funcall(rb_funcall(key, i_to_s, 0), i_to_json, 2, Vstate, Vdepth);
    Check_Type(json, T_STRING);
    rb_str_buf_append(buf, json);
    OBJ_INFECT(buf, json);
    if (RSTRING_LEN(state->space_before)) {
        rb_str_buf_append(buf, state->space_before);
    }
    rb_str_buf_cat2(buf, ":");
    if (RSTRING_LEN(state->space)) rb_str_buf_append(buf, state->space);
    json = rb_funcall(value, i_to_json, 2, Vstate, Vdepth);
    Check_Type(json, T_STRING);
    state->flag = 1;
    rb_str_buf_append(buf, json);
    OBJ_INFECT(buf, json);
    state->depth = Vdepth;
    state->memo = buf;
    return ST_CONTINUE;
}
Beispiel #3
0
inline static VALUE mHash_json_transfrom(VALUE self, VALUE Vstate, VALUE Vdepth) {
    long depth, len = RHASH_SIZE(self);
    VALUE result;
    GET_STATE(Vstate);

    depth = 1 + FIX2LONG(Vdepth);
    result = rb_str_buf_new(len);
    state->memo = result;
    state->depth = LONG2FIX(depth);
    state->flag = 0;
    rb_str_buf_cat2(result, "{");
    if (RSTRING_LEN(state->object_nl)) rb_str_buf_append(result, state->object_nl);
    rb_hash_foreach(self, hash_to_json_state_i, Vstate);
    if (RSTRING_LEN(state->object_nl)) rb_str_buf_append(result, state->object_nl);
    if (RSTRING_LEN(state->object_nl)) {
        rb_str_buf_append(result, rb_str_times(state->indent, Vdepth));
    }
    rb_str_buf_cat2(result, "}");
    return result;
}