
#include <asn_application.h>
#include <asn_internal.h>
#include <xer_support.h>		/* XER/XML parsing support */
#include <assert.h>


/*
 * Decode the XER encoding of a given type.
 */
asn_dec_rval_t
xer_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
		void **struct_ptr, void *buffer, size_t size) {
	asn_codec_ctx_t s_codec_ctx;

	/*
	 * Satisfy the requirement that the codec context
	 * must be allocated on the stack.
	 */
	if(opt_codec_ctx && opt_codec_ctx->max_stack_size) {
		s_codec_ctx = *opt_codec_ctx;
		opt_codec_ctx = &s_codec_ctx;
	}

	/*
	 * Invoke type-specific decoder.
	 */
	return td->xer_decoder(opt_codec_ctx, td, struct_ptr, 0, buffer, size);
}



struct xer__cb_arg {
	pxml_chunk_type_e	chunk_type;
	size_t			chunk_size;
	void			*chunk_buf;
	int callback_not_invoked;
};

static int
xer__token_cb(pxml_chunk_type_e type, void *_chunk_data, size_t _chunk_size, void *key) {
	struct xer__cb_arg *arg = (struct xer__cb_arg *)key;
	arg->chunk_type = type;
	arg->chunk_size = _chunk_size;
	arg->chunk_buf = _chunk_data;
	arg->callback_not_invoked = 0;
	return -1;	/* Terminate the XML parsing */
}

/*
 * Fetch the next token from the XER/XML stream.
 */
ssize_t
xer_next_token(int *stateContext, void *buffer, size_t size,
		pxer_chunk_type_e *ch_type) {
	struct xer__cb_arg arg;
	ssize_t ret;

	arg.callback_not_invoked = 1;
	ret = pxml_parse(stateContext, buffer, size, xer__token_cb, &arg);
	if(ret < 0) return -1;
	if(arg.callback_not_invoked) {
		assert(ret == 0);	/* No data was consumed */
		return 0;		/* Try again with more data */
	} else {
		assert(arg.chunk_size);
		assert(arg.chunk_buf == buffer);
	}

	/*
	 * Translate the XML chunk types into more convenient ones.
	 */
	switch(arg.chunk_type) {
	case PXML_TEXT:
		*ch_type = PXER_TEXT;
		break;
	case PXML_TAG: return 0;	/* Want more */
	case PXML_TAG_END:
		*ch_type = PXER_TAG;
		break;
	case PXML_COMMENT:
	case PXML_COMMENT_END:
		*ch_type = PXER_COMMENT;
		break;
	}

	return arg.chunk_size;
}

#define	CSLASH	0x2f	/* '/' */
#define	LANGLE	0x3c	/* '<' */
#define	RANGLE	0x3e	/* '>' */

xer_check_tag_e
xer_check_tag(const void *buf_ptr, int size, const char *need_tag) {
	const char *buf = (const char *)buf_ptr;
	const char *end;
	xer_check_tag_e ct = XCT_OPENING;

	if(size < 2 || buf[0] != LANGLE || buf[size-1] != RANGLE) {
		return XCT_BROKEN;
	}

	/*
	 * Determine the tag class.
	 */
	if(buf[1] == CSLASH) {
		buf += 2;	/* advance past "</" */
		size -= 3;	/* strip "</" and ">" */
		ct = XCT_CLOSING;
		if(size > 0 && buf[size-1] == CSLASH)
			return XCT_BROKEN;	/* </abc/> */
	} else {
		buf++;		/* advance past "<" */
		size -= 2;	/* strip "<" and ">" */
		if(size > 0 && buf[size-1] == CSLASH) {
			ct = XCT_BOTH;
			size--;	/* One more, for "/" */
		}
	}

	/*
	 * Determine the tag name.
	 */
	for(end = buf + size; buf < end; buf++, need_tag++) {
		int b = *buf, n = *need_tag;
		if(b != n) {
			if(n == 0) {
				switch(b) {
				case 0x09: case 0x0a: case 0x0c: case 0x0d:
				case 0x20:
					/* "<abc def/>": whitespace is normal */
					return ct;
				}
			}
			return XCT_UNEXPECTED;
		}
		if(b == 0)
			return XCT_BROKEN;	/* Embedded 0 in buf?! */
	}
	if(*need_tag) return XCT_UNEXPECTED;

	return ct;
}


#undef	ADVANCE
#define	ADVANCE(num_bytes)	do {				\
		size_t num = (num_bytes);			\
		buf_ptr = ((char *)buf_ptr) + num;		\
		size -= num;					\
		consumed_myself += num;				\
	} while(0)

#undef	RETURN
#define	RETURN(_code)	do {					\
		rval.code = _code;				\
		rval.consumed = consumed_myself;		\
		return rval;					\
	} while(0)

#define	XER_GOT_BODY(chunk_buf, chunk_size)	do {		\
		ssize_t converted_size = body_receiver		\
			(struct_ptr, chunk_buf, chunk_size,	\
				(size_t)chunk_size < size);	\
		if(converted_size == -1) RETURN(RC_FAIL);	\
		chunk_size = converted_size;			\
	} while(0)
#define	XER_GOT_EMPTY()	do {					\
		ssize_t chunk_size = 0;				\
		XER_GOT_BODY(0, chunk_size);			\
	} while(0)

/*
 * Generalized function for decoding the primitive values.
 */
asn_dec_rval_t
xer_decode_general(asn_codec_ctx_t *opt_codec_ctx,
	asn_struct_ctx_t *ctx,	/* Type decoder context */
	void *struct_ptr,	/* The structure must be already allocated */
	const char *xml_tag,	/* Expected XML tag */
	void *buf_ptr, size_t size,
	int (*opt_unexpected_tag_decoder)
		(void *struct_ptr, void *chunk_buf, size_t chunk_size),
	ssize_t (*body_receiver)
		(void *struct_ptr, void *chunk_buf, size_t chunk_size,
			int have_more)
	) {

	asn_dec_rval_t rval;
	ssize_t consumed_myself = 0;
	pxer_chunk_type_e ch_type;	/* XER chunk type */
	int xer_state;			/* XER low level parsing context */

	(void)opt_codec_ctx;

	/*
	 * Phases of XER/XML processing:
	 * Phase 0: Check that the opening tag matches our expectations.
	 * Phase 1: Processing body and reacting on closing tag.
	 */
	if(ctx->phase > 1) RETURN(RC_FAIL);
	for(xer_state = ctx->step;;) {
		ssize_t ch_size;	/* Chunk size */
		xer_check_tag_e tcv;	/* Tag check value */

		/*
		 * Get the next part of the XML stream.
		 */
		ch_size = xer_next_token(&xer_state, buf_ptr, size, &ch_type);
		switch(ch_size) {
		case -1: RETURN(RC_FAIL);
		case 0:
			ctx->step = xer_state;
			RETURN(RC_WMORE);
		default:
			switch(ch_type) {
			case PXER_COMMENT:		/* Got XML comment */
				ADVANCE(ch_size);	/* Skip silently */
				continue;
			case PXER_TEXT:
				if(ctx->phase == 0) {
					/* Unexpected data */
					/* TODO: ignore whitespace? */
					RETURN(RC_FAIL);
				}
				XER_GOT_BODY(buf_ptr, ch_size);
				ADVANCE(ch_size);
				continue;
			case PXER_TAG:
				break;	/* Check the rest down there */
			}
		}

		assert(ch_type == PXER_TAG && size);

		tcv = xer_check_tag(buf_ptr, ch_size, xml_tag);
		if(ctx->phase == 0) {
			/*
			 * Expecting the opening tag
			 * for the type being processed.
			 */
			switch(tcv) {
			case XCT_BOTH:
				/* Finished decoding of an empty element */
				XER_GOT_EMPTY();
				ADVANCE(ch_size);
				ctx->phase = 2;	/* Phase out */
				RETURN(RC_OK);
			case XCT_OPENING:
				ADVANCE(ch_size);
				ctx->phase = 1;	/* Processing body phase */
				continue;
			default:
				break;		/* Unexpected tag */
			}
		} else {
			/*
			 * Waiting for the closing XML tag.
			 */
			switch(tcv) {
			case XCT_CLOSING:
				ADVANCE(ch_size);
				ctx->phase = 2;	/* Phase out */
				RETURN(RC_OK);
			case XCT_UNEXPECTED:
				/*
				 * Certain tags in the body may be expected.
				 */
				if(opt_unexpected_tag_decoder
				&& opt_unexpected_tag_decoder(struct_ptr,
						buf_ptr, ch_size) == 0) {
					/* Tag's processed fine */
					ADVANCE(ch_size);
					continue;
				}
				/* Fall through */
			default:
				break;
			}
			ASN_DEBUG("Unexpected XML tag");
		}
		break;	/* Dark and mysterious things have just happened */
	}

	RETURN(RC_FAIL);
}

