예제 #1
0
static void
dict2json(heim_object_t key, heim_object_t value, void *ctx)
{
    struct twojson *j = ctx;
    indent(j);
    base2json(key, j);
    j->out(j->ctx, " = ");
    base2json(value, j);
    j->out(j->ctx, ",\n");
}
예제 #2
0
static void
array2json(heim_object_t value, void *ctx)
{
    struct twojson *j = ctx;
    indent(j);
    base2json(value, j);
    j->out(j->ctx, ",\n");
    j->indent--;
}
예제 #3
0
static int
heim_base2json(heim_object_t obj, void *ctx,
	       void (*out)(void *, const char *))
{
    struct twojson j;

    j.indent = 0;
    j.ctx = ctx;
    j.out = out;

    return base2json(obj, &j);
}
예제 #4
0
파일: json.c 프로젝트: kaduk/heimdal
static void
dict2json(heim_object_t key, heim_object_t value, void *ctx)
{
    struct twojson *j = ctx;
    if (j->ret)
	return;
    if (j->first) {
	j->first = 0;
    } else {
	j->out(j->ctx, NULL); /* eat previous '\n' if possible */
	j->out(j->ctx, ",\n");
    }
    j->ret = base2json(key, j);
    if (j->ret)
	return;
    j->out(j->ctx, " : \n");
    j->indent++;
    j->ret = base2json(value, j);
    if (j->ret)
	return;
    j->indent--;
}
예제 #5
0
파일: json.c 프로젝트: kaduk/heimdal
static void
array2json(heim_object_t value, void *ctx, int *stop)
{
    struct twojson *j = ctx;
    if (j->ret)
	return;
    if (j->first) {
	j->first = 0;
    } else {
	j->out(j->ctx, NULL); /* eat previous '\n' if possible */
	j->out(j->ctx, ",\n");
    }
    j->ret = base2json(value, j);
}
예제 #6
0
파일: json.c 프로젝트: kaduk/heimdal
static int
heim_base2json(heim_object_t obj, void *ctx, heim_json_flags_t flags,
	       void (*out)(void *, const char *))
{
    struct twojson j;

    if (flags & HEIM_JSON_F_STRICT_STRINGS)
	return ENOTSUP; /* Sorry, not yet! */

    heim_base_once_f(&heim_json_once, NULL, json_init_once);

    j.indent = 0;
    j.ctx = ctx;
    j.out = out;
    j.flags = flags;
    j.ret = 0;
    j.first = 1;

    return base2json(obj, &j);
}
예제 #7
0
파일: json.c 프로젝트: kaduk/heimdal
static int
base2json(heim_object_t obj, struct twojson *j)
{
    heim_tid_t type;
    int first = 0;

    if (obj == NULL) {
	if (j->flags & HEIM_JSON_F_CNULL2JSNULL) {
	    obj = heim_null_create();
	} else if (j->flags & HEIM_JSON_F_NO_C_NULL) {
	    return EINVAL;
	} else {
	    indent(j);
	    j->out(j->ctx, "<NULL>\n"); /* This is NOT valid JSON! */
	    return 0;
	}
    }

    type = heim_get_tid(obj);
    switch (type) {
    case HEIM_TID_ARRAY:
	indent(j);
	j->out(j->ctx, "[\n");
	j->indent++;
	first = j->first;
	j->first = 1;
	heim_array_iterate_f(obj, j, array2json);
	j->indent--;
	if (!j->first)
	    j->out(j->ctx, "\n");
	indent(j);
	j->out(j->ctx, "]\n");
	j->first = first;
	break;

    case HEIM_TID_DICT:
	indent(j);
	j->out(j->ctx, "{\n");
	j->indent++;
	first = j->first;
	j->first = 1;
	heim_dict_iterate_f(obj, j, dict2json);
	j->indent--;
	if (!j->first)
	    j->out(j->ctx, "\n");
	indent(j);
	j->out(j->ctx, "}\n");
	j->first = first;
	break;

    case HEIM_TID_STRING:
	indent(j);
	j->out(j->ctx, "\"");
	j->out(j->ctx, heim_string_get_utf8(obj));
	j->out(j->ctx, "\"");
	break;

    case HEIM_TID_DATA: {
	heim_dict_t d;
	heim_string_t v;
	const heim_octet_string *data;
	char *b64 = NULL;
	int ret;

	if (j->flags & HEIM_JSON_F_NO_DATA)
	    return EINVAL; /* JSON doesn't do binary */

	data = heim_data_get_data(obj);
	ret = base64_encode(data->data, data->length, &b64);
	if (ret < 0 || b64 == NULL)
	    return ENOMEM;

	if (j->flags & HEIM_JSON_F_NO_DATA_DICT) {
	    indent(j);
	    j->out(j->ctx, "\"");
	    j->out(j->ctx, b64); /* base64-encode; hope there's no aliasing */
	    j->out(j->ctx, "\"");
	    free(b64);
	} else {
	    /*
	     * JSON has no way to represent binary data, therefore the
	     * following is a Heimdal-specific convention.
	     *
	     * We encode binary data as a dict with a single very magic
	     * key with a base64-encoded value.  The magic key includes
	     * a uuid, so we're not likely to alias accidentally.
	     */
	    d = heim_dict_create(2);
	    if (d == NULL) {
		free(b64);
		return ENOMEM;
	    }
	    v = heim_string_ref_create(b64, free);
	    if (v == NULL) {
		free(b64);
		heim_release(d);
		return ENOMEM;
	    }
	    ret = heim_dict_set_value(d, heim_tid_data_uuid_key, v);
	    heim_release(v);
	    if (ret) {
		heim_release(d);
		return ENOMEM;
	    }
	    ret = base2json(d, j);
	    heim_release(d);
	    if (ret)
		return ret;
	}
	break;
    }

    case HEIM_TID_NUMBER: {
	char num[32];
	indent(j);
	snprintf(num, sizeof (num), "%d", heim_number_get_int(obj));
	j->out(j->ctx, num);
	break;
    }
    case HEIM_TID_NULL:
	indent(j);
	j->out(j->ctx, "null");
	break;
    case HEIM_TID_BOOL:
	indent(j);
	j->out(j->ctx, heim_bool_val(obj) ? "true" : "false");
	break;
    default:
	return 1;
    }
    return 0;
}