/*
 * Copyright (c) 2003, 2004 X/IO Labs, xiolabs.com.
 * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
 * Redistribution and modifications are permitted subject to BSD license.
 */
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>

#include <xer_support.h>

/* Parser states */
typedef enum {
	ST_TEXT,
	ST_TAG_START,
	ST_TAG_BODY,
	ST_TAG_QUOTE_WAIT,
	ST_TAG_QUOTED_STRING,
	ST_TAG_UNQUOTED_STRING,
	ST_COMMENT_WAIT_DASH1,	// "<!--"[1]
	ST_COMMENT_WAIT_DASH2,	// "<!--"[2]
	ST_COMMENT,
	ST_COMMENT_CLO_DASH2,	// "-->"[0]
	ST_COMMENT_CLO_RT	// "-->"[1]
} pstate_e;

static pxml_chunk_type_e final_chunk_type[] = {
	PXML_TEXT,
	PXML_TAG_END,
	PXML_COMMENT_END,
	PXML_TAG_END,
	PXML_COMMENT_END,
};


static int
_charclass[256] = {
	0,0,0,0,0,0,0,0, 0,1,1,0,1,1,0,0,
	0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
	1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
	2,2,2,2,2,2,2,2, 2,2,0,0,0,0,0,0,	/* 01234567 89       */
	0,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,	/*  ABCDEFG HIJKLMNO */
	3,3,3,3,3,3,3,3, 3,3,3,0,0,0,0,0,	/* PQRSTUVW XYZ      */
	0,3,3,3,3,3,3,3, 3,3,3,3,3,3,3,3,	/*  abcdefg hijklmno */
	3,3,3,3,3,3,3,3, 3,3,3,0,0,0,0,0	/* pqrstuvw xyz      */
};
#define WHITESPACE(c)	(_charclass[(unsigned char)(c)] == 1)
#define ALNUM(c)	(_charclass[(unsigned char)(c)] >= 2)
#define ALPHA(c)	(_charclass[(unsigned char)(c)] == 3)

/* Aliases for characters, ASCII/UTF-8 */
#define	EXCLAM	0x21	/* '!' */
#define	CQUOTE	0x22	/* '"' */
#define	CDASH	0x2d	/* '-' */
#define	CSLASH	0x2f	/* '/' */
#define	LANGLE	0x3c	/* '<' */
#define	CEQUAL	0x3d	/* '=' */
#define	RANGLE	0x3e	/* '>' */

/* Invoke token callback */
#define	TOKEN_CB_CALL(type, _ns, _current_too, _final) do {	\
		int _ret;					\
		pstate_e ns  = _ns;				\
		ssize_t _sz = (p - chunk_start) + _current_too;	\
		if (!_sz) {					\
			/* Shortcut */				\
			state = _ns;				\
			break;					\
		}						\
		_ret = cb(type, chunk_start, _sz, key);		\
		if(_ret < _sz) {				\
			if(_current_too && _ret == -1)		\
				state = ns;			\
			goto finish;				\
		}						\
		chunk_start = p + _current_too;			\
		state = ns;					\
	} while(0)

#define TOKEN_CB(_type, _ns, _current_too)			\
	TOKEN_CB_CALL(_type, _ns, _current_too, 0)

#define TOKEN_CB_FINAL(_type, _ns, _current_too)		\
	TOKEN_CB_CALL(final_chunk_type[_type], _ns, _current_too, 1)

/*
 * Parser itself
 */
ssize_t pxml_parse(int *stateContext, void *xmlbuf, size_t size, pxml_callback_f *cb, void *key) {
	pstate_e state = (pstate_e)*stateContext;
	char *chunk_start = (char *)xmlbuf;
	char *p = chunk_start;
	char *end = p + size;

	for(; p < end; p++) {
	  int C = *(unsigned char *)p;
	  switch(state) {
	  case ST_TEXT:
		/*
		 * Initial state: we're in the middle of some text,
		 * or just have started.
		 */
		if (C == LANGLE) 
			/* We're now in the tag, probably */
			TOKEN_CB(PXML_TEXT, ST_TAG_START, 0);
		break;
	  case ST_TAG_START:
		if (ALPHA(C) || (C == CSLASH))
			state = ST_TAG_BODY;
		else if (C == EXCLAM)
			state = ST_COMMENT_WAIT_DASH1;
		else 
			/*
			 * Not characters and not whitespace.
			 * Must be something like "3 < 4".
			 */
			TOKEN_CB(PXML_TEXT, ST_TEXT, 1);/* Flush as data */
		break;
	  case ST_TAG_BODY:
		switch(C) {
		case RANGLE:
			/* End of the tag */
			TOKEN_CB_FINAL(PXML_TAG, ST_TEXT, 1);
			break;
		case LANGLE:
			/*
			 * The previous tag wasn't completed, but still
			 * recognized as valid. (Mozilla-compatible)
			 */
			TOKEN_CB_FINAL(PXML_TAG, ST_TAG_START, 0);	
			break;
		case CEQUAL:
			state = ST_TAG_QUOTE_WAIT;
			break;
		}
		break;
	  case ST_TAG_QUOTE_WAIT:
		/*
		 * State after the equal sign ("=") in the tag.
		 */
		switch(C) {
		case CQUOTE:
			state = ST_TAG_QUOTED_STRING;
			break;
		case RANGLE:
			/* End of the tag */
			TOKEN_CB_FINAL(PXML_TAG, ST_TEXT, 1);
			break;
		default:
			if(!WHITESPACE(C))
				/* Unquoted string value */
				state = ST_TAG_UNQUOTED_STRING;
		}
		break;
	  case ST_TAG_QUOTED_STRING:
		/*
		 * Tag attribute's string value in quotes.
		 */
		if(C == CQUOTE) {
			/* Return back to the tag state */
			state = ST_TAG_BODY;
		}
		break;
	  case ST_TAG_UNQUOTED_STRING:
		if(C == RANGLE) {
			/* End of the tag */
			TOKEN_CB_FINAL(PXML_TAG, ST_TEXT, 1);
		} else if(WHITESPACE(C)) {
			/* Return back to the tag state */
			state = ST_TAG_BODY;
		}
		break;
	  case ST_COMMENT_WAIT_DASH1:
		if(C == CDASH) {
			state = ST_COMMENT_WAIT_DASH2;
		} else {
			/* Some ordinary tag. */
			state = ST_TAG_BODY;
		}
		break;
	  case ST_COMMENT_WAIT_DASH2:
		if(C == CDASH) {
			/* Seen "<--" */
			state = ST_COMMENT;
		} else {
			/* Some ordinary tag */
			state = ST_TAG_BODY;
		}
		break;
	  case ST_COMMENT:
		if(C == CDASH) {
			state = ST_COMMENT_CLO_DASH2;
		}
		break;
	  case ST_COMMENT_CLO_DASH2:
		if(C == CDASH) {
			state = ST_COMMENT_CLO_RT;
		} else {
			/* This is not an end of a comment */
			state = ST_COMMENT;
		}
		break;
	  case ST_COMMENT_CLO_RT:
		if(C == RANGLE) {
			TOKEN_CB_FINAL(PXML_COMMENT, ST_TEXT, 1);
		} else {
			state = ST_COMMENT;
		}
		break;
	  } /* switch(*ptr) */
	} /* for() */

	/*
	 * Flush the partially processed chunk, state permitting.
	 */
	if(p - chunk_start) {
		switch (state) {
		case ST_COMMENT:
			TOKEN_CB(PXML_COMMENT, state, 0);
			break;
		case ST_TEXT:
			TOKEN_CB(PXML_TEXT, state, 0);
			break;
		default: break;	/* a no-op */
		}
	}

finish:
	*stateContext = (int)state;
	return chunk_start - (char *)xmlbuf;
}

