/* nanojson - very small JSON event parser with push API - semantic level

   This nanolib is written by Tibor 'Igor2' Palinkas in 2023 and 2024 and
   is licensed under the Creative Common CC0 (or is placed in the Public Domain
   where it is permitted by the law). */
#include <stdlib.h>
#include "semantic.h"

njson_sem_ev_t njson_sem_push(njson_sem_ctx_t *ctx, int chr)
{
	njson_ev_t ev = njson_push(&ctx->njs, chr);

	if (ctx->reset_name) {
		free(ctx->name);
		ctx->name = NULL;
		ctx->reset_name = 0;
	}

	switch(ev) {
		case NJSON_EV_OBJECT_BEGIN: ctx->reset_name = 1; return NJSON_SEM_EV_OBJECT_BEGIN;
		case NJSON_EV_OBJECT_END:   return NJSON_SEM_EV_OBJECT_END;
		case NJSON_EV_ARRAY_BEGIN:  ctx->reset_name = 1; return NJSON_SEM_EV_ARRAY_BEGIN;
		case NJSON_EV_ARRAY_END:    return NJSON_SEM_EV_ARRAY_END;

		case NJSON_EV_NAME:
			if (ctx->name != NULL)
				free(ctx->name);
			ctx->name = ctx->njs.str.arr;
			ctx->njs.str.arr = NULL;
			ctx->njs.str.used = ctx->njs.str.alloced = 0;
			return NJSON_SEM_EV_more;


		case NJSON_EV_STRING:
			ctx->reset_name = 1;
			ctx->type = NJSON_SEM_TYPE_STRING;
			ctx->value.string = (char *)ctx->njs.value.string; /* it's dynamic alloced in the parser */
			return NJSON_SEM_EV_ATOMIC;

		case NJSON_EV_NUMBER:
			ctx->reset_name = 1;
			ctx->type = NJSON_SEM_TYPE_NUMBER;
			ctx->value.number = ctx->njs.value.number;
			return NJSON_SEM_EV_ATOMIC;

		case NJSON_EV_TRUE:
			ctx->reset_name = 1;
			ctx->value.string = NULL; ctx->value.number = 0;
			ctx->type = NJSON_SEM_TYPE_TRUE;
			return NJSON_SEM_EV_ATOMIC;

		case NJSON_EV_FALSE:
			ctx->reset_name = 1;
			ctx->value.string = NULL; ctx->value.number = 0;
			ctx->type = NJSON_SEM_TYPE_FALSE;
			return NJSON_SEM_EV_ATOMIC;

		case NJSON_EV_NULL:
			ctx->reset_name = 1;
			ctx->value.string = NULL; ctx->value.number = 0;
			ctx->type = NJSON_SEM_TYPE_NULL;
			return NJSON_SEM_EV_ATOMIC;

		case NJSON_EV_error: return NJSON_SEM_EV_error;
		case NJSON_EV_eof: return NJSON_SEM_EV_eof;
		case NJSON_EV_more: return NJSON_SEM_EV_more;
	}

	/* shouldn't get here */
	return NJSON_SEM_EV_error;
}


void njson_sem_uninit(njson_sem_ctx_t *ctx)
{
	free(ctx->name);
	ctx->name = NULL;
	njson_uninit(&ctx->njs);
}

