Blame json_visit.c

Packit Service def718
/*
Packit Service def718
 * Copyright (c) 2016 Eric Haszlakiewicz
Packit Service def718
 *
Packit Service def718
 * This is free software; you can redistribute it and/or modify
Packit Service def718
 * it under the terms of the MIT license. See COPYING for details.
Packit Service def718
 */
Packit Service def718
Packit Service def718
#include <stdio.h>
Packit Service def718
Packit Service def718
#include "config.h"
Packit Service def718
#include "json_inttypes.h"
Packit Service def718
#include "json_object.h"
Packit Service def718
#include "json_visit.h"
Packit Service def718
#include "linkhash.h"
Packit Service def718
Packit Service def718
static int _json_c_visit(json_object *jso, json_object *parent_jso,
Packit Service def718
                         const char *jso_key, size_t *jso_index,
Packit Service def718
                         json_c_visit_userfunc *userfunc, void *userarg);
Packit Service def718
Packit Service def718
int json_c_visit(json_object *jso, int future_flags,
Packit Service def718
                 json_c_visit_userfunc *userfunc, void *userarg)
Packit Service def718
{
Packit Service def718
	int ret = _json_c_visit(jso, NULL, NULL, NULL, userfunc, userarg);
Packit Service def718
	switch(ret)
Packit Service def718
	{
Packit Service def718
	case JSON_C_VISIT_RETURN_CONTINUE:
Packit Service def718
	case JSON_C_VISIT_RETURN_SKIP:
Packit Service def718
	case JSON_C_VISIT_RETURN_POP:
Packit Service def718
	case JSON_C_VISIT_RETURN_STOP:
Packit Service def718
		return 0;
Packit Service def718
	default:
Packit Service def718
		return JSON_C_VISIT_RETURN_ERROR;
Packit Service def718
	}
Packit Service def718
}
Packit Service def718
static int _json_c_visit(json_object *jso, json_object *parent_jso,
Packit Service def718
                         const char *jso_key, size_t *jso_index,
Packit Service def718
                         json_c_visit_userfunc *userfunc, void *userarg)
Packit Service def718
{
Packit Service def718
	int userret = userfunc(jso, 0, parent_jso, jso_key, jso_index, userarg);
Packit Service def718
	switch(userret)
Packit Service def718
	{
Packit Service def718
	case JSON_C_VISIT_RETURN_CONTINUE:
Packit Service def718
		break;
Packit Service def718
	case JSON_C_VISIT_RETURN_SKIP:
Packit Service def718
	case JSON_C_VISIT_RETURN_POP:
Packit Service def718
	case JSON_C_VISIT_RETURN_STOP:
Packit Service def718
	case JSON_C_VISIT_RETURN_ERROR:
Packit Service def718
		return userret;
Packit Service def718
	default:
Packit Service def718
		fprintf(stderr, "ERROR: invalid return value from json_c_visit userfunc: %d\n", userret);
Packit Service def718
		return JSON_C_VISIT_RETURN_ERROR;
Packit Service def718
	}
Packit Service def718
Packit Service def718
	switch(json_object_get_type(jso))
Packit Service def718
	{
Packit Service def718
	case json_type_null:
Packit Service def718
	case json_type_boolean:
Packit Service def718
	case json_type_double:
Packit Service def718
	case json_type_int:
Packit Service def718
	case json_type_string:
Packit Service def718
		// we already called userfunc above, move on to the next object
Packit Service def718
		return JSON_C_VISIT_RETURN_CONTINUE;
Packit Service def718
Packit Service def718
	case json_type_object:
Packit Service def718
	{
Packit Service def718
		json_object_object_foreach(jso, key, child)
Packit Service def718
		{
Packit Service def718
			userret = _json_c_visit(child, jso, key, NULL, userfunc, userarg);
Packit Service def718
			if (userret == JSON_C_VISIT_RETURN_POP)
Packit Service def718
				break;
Packit Service def718
			if (userret == JSON_C_VISIT_RETURN_STOP ||
Packit Service def718
				userret == JSON_C_VISIT_RETURN_ERROR)
Packit Service def718
				return userret;
Packit Service def718
			if (userret != JSON_C_VISIT_RETURN_CONTINUE &&
Packit Service def718
				userret != JSON_C_VISIT_RETURN_SKIP)
Packit Service def718
			{
Packit Service def718
				fprintf(stderr, "INTERNAL ERROR: _json_c_visit returned %d\n", userret);
Packit Service def718
				return JSON_C_VISIT_RETURN_ERROR;
Packit Service def718
			}
Packit Service def718
		}
Packit Service def718
		break;
Packit Service def718
	}
Packit Service def718
	case json_type_array:
Packit Service def718
	{
Packit Service def718
		size_t array_len = json_object_array_length(jso);
Packit Service def718
		size_t ii;
Packit Service def718
		for (ii = 0; ii < array_len; ii++)
Packit Service def718
		{
Packit Service def718
			json_object *child = json_object_array_get_idx(jso, ii);
Packit Service def718
			userret = _json_c_visit(child, jso, NULL, &ii, userfunc, userarg);
Packit Service def718
			if (userret == JSON_C_VISIT_RETURN_POP)
Packit Service def718
				break;
Packit Service def718
			if (userret == JSON_C_VISIT_RETURN_STOP ||
Packit Service def718
				userret == JSON_C_VISIT_RETURN_ERROR)
Packit Service def718
				return userret;
Packit Service def718
			if (userret != JSON_C_VISIT_RETURN_CONTINUE &&
Packit Service def718
				userret != JSON_C_VISIT_RETURN_SKIP)
Packit Service def718
			{
Packit Service def718
				fprintf(stderr, "INTERNAL ERROR: _json_c_visit returned %d\n", userret);
Packit Service def718
				return JSON_C_VISIT_RETURN_ERROR;
Packit Service def718
			}
Packit Service def718
		}
Packit Service def718
		break;
Packit Service def718
	}
Packit Service def718
	default:
Packit Service def718
		fprintf(stderr, "INTERNAL ERROR: _json_c_visit found object of unknown type: %d\n", json_object_get_type(jso));
Packit Service def718
		return JSON_C_VISIT_RETURN_ERROR;
Packit Service def718
	}
Packit Service def718
Packit Service def718
	// Call userfunc for the second type on container types, after all
Packit Service def718
	//  members of the container have been visited.
Packit Service def718
	// Non-container types will have already returned before this point.
Packit Service def718
Packit Service def718
	userret = userfunc(jso, JSON_C_VISIT_SECOND, parent_jso, jso_key, jso_index, userarg);
Packit Service def718
	switch(userret)
Packit Service def718
	{
Packit Service def718
	case JSON_C_VISIT_RETURN_SKIP:
Packit Service def718
	case JSON_C_VISIT_RETURN_POP:
Packit Service def718
		// These are not really sensible during JSON_C_VISIT_SECOND, 
Packit Service def718
		// but map them to JSON_C_VISIT_CONTINUE anyway.
Packit Service def718
		// FALLTHROUGH
Packit Service def718
	case JSON_C_VISIT_RETURN_CONTINUE:
Packit Service def718
		return JSON_C_VISIT_RETURN_CONTINUE;
Packit Service def718
	case JSON_C_VISIT_RETURN_STOP:
Packit Service def718
	case JSON_C_VISIT_RETURN_ERROR:
Packit Service def718
		return userret;
Packit Service def718
	default:
Packit Service def718
		fprintf(stderr, "ERROR: invalid return value from json_c_visit userfunc: %d\n", userret);
Packit Service def718
		return JSON_C_VISIT_RETURN_ERROR;
Packit Service def718
	}
Packit Service def718
	// NOTREACHED
Packit Service def718
}
Packit Service def718