/* autogenerated file */
#include "json_common.h"

bool reformat_integer (void *ctx, long long int num) {
    yajl_gen g = (yajl_gen) ctx;
    GEN_AND_RETURN (yajl_gen_integer (g,num));
}

bool reformat_double (void *ctx, double num) {
    yajl_gen g = (yajl_gen) ctx;
    GEN_AND_RETURN (yajl_gen_double (g,num));
}

bool reformat_number (void *ctx, const char *str, size_t len) {
    yajl_gen g = (yajl_gen) ctx;
    GEN_AND_RETURN (yajl_gen_number (g, str, len));
}

bool reformat_string (void *ctx, const unsigned char *str, size_t len) {
    yajl_gen g = (yajl_gen) ctx;
    GEN_AND_RETURN (yajl_gen_string (g, str, len));
}

bool reformat_null (void *ctx) {
    yajl_gen g = (yajl_gen) ctx;
    GEN_AND_RETURN (yajl_gen_null (g));
}

bool reformat_boolean (void *ctx, int boolean) {
    yajl_gen g = (yajl_gen) ctx;
    GEN_AND_RETURN (yajl_gen_bool (g, boolean));
}

bool reformat_map_key (void *ctx, const unsigned char *str, size_t len) {
    yajl_gen g = (yajl_gen) ctx;
    GEN_AND_RETURN (yajl_gen_string (g, str, len));
}

bool reformat_start_map (void *ctx) {
    yajl_gen g = (yajl_gen) ctx;
    GEN_AND_RETURN (yajl_gen_map_open (g));
}

bool reformat_end_map (void *ctx) {
    yajl_gen g = (yajl_gen) ctx;
    GEN_AND_RETURN (yajl_gen_map_close (g));
}

bool reformat_start_array (void *ctx) {
    yajl_gen g = (yajl_gen) ctx;
    GEN_AND_RETURN (yajl_gen_array_open (g));
}

bool reformat_end_array (void *ctx) {
    yajl_gen g = (yajl_gen) ctx;
    GEN_AND_RETURN (yajl_gen_array_close (g));
}

bool gen_map_string_string (void *ctx, string_cells *cells) {
    bool stat = true;
    yajl_gen g = (yajl_gen) ctx;
    size_t i = 0;
    if (!cells)
        return false;

    stat = reformat_start_map (g);
    if (!stat)
        return false;

    for (i = 0; i < cells->len; i++) {
        stat = reformat_map_key (g, (unsigned char *) cells->keys[i], strlen (cells->keys[i]));
        if (!stat)
            return false;
        stat = reformat_string (g, (unsigned char *) cells->values[i], strlen (cells->values[i]));
        if (!stat)
            return false;
    }

    stat = reformat_end_map (g);
    if (!stat)
        return false;
    return true;
}

bool json_gen_init (yajl_gen *g) {
    *g = yajl_gen_alloc (NULL);
    if (NULL == *g)
        return false;

    yajl_gen_config (*g, yajl_gen_beautify, 1);
    yajl_gen_config (*g, yajl_gen_validate_utf8, 1);
    return true;
}

yajl_val get_val (yajl_val tree, const char *name, yajl_type type) {
    const char *path[] = { name, NULL };
    return yajl_tree_get (tree, path, type);
}

void free_cells (string_cells *cells) {
    if (cells) {
        size_t i;
        for (i = 0; i < cells->len; i++) {
            free (cells->keys[i]);
            cells->keys[i] = NULL;
            free (cells->values[i]);
            cells->values[i] = NULL;
        }
        free (cells->keys);
        cells->keys = NULL;
        free (cells->values);
        cells->values = NULL;
        free (cells);
    }
}

void *safe_malloc (size_t size) {
    void *ret = malloc (size);
    if (ret == NULL)
        abort ();
    memset (ret, 0, size);
    return ret;
}

string_cells *read_map_string_string (yajl_val src) {
    string_cells *ret = NULL;
    if (src && YAJL_GET_OBJECT (src)) {
        size_t i;
        ret = safe_malloc (sizeof (string_cells));
        ret->len = YAJL_GET_OBJECT (src)->len;
        ret->keys = safe_malloc ((YAJL_GET_OBJECT (src)->len + 1) * sizeof (char *));
        ret->values = safe_malloc ((YAJL_GET_OBJECT (src)->len + 1) * sizeof (char *));
        for (i = 0; i < YAJL_GET_OBJECT (src)->len; i++) {
            const char *srckey = YAJL_GET_OBJECT (src)->keys[i];
            yajl_val srcval = YAJL_GET_OBJECT (src)->values[i];
            ret->keys[i] = strdup (srckey ? srckey : "");
            if (ret->keys[i] == NULL)
                abort ();
            if (srcval) {
                char *str = YAJL_GET_STRING (srcval);
                ret->values[i] = strdup (str ? str : "");
                if (ret->values[i] == NULL)
                    abort ();
            } else {
                ret->values[i] = NULL;
            }
        }
    }
    return ret;
}
