/*
 * libsyncml - A syncml protocol implementation
 * Copyright (C) 2005  Armin Bauer <armin.bauer@opensync.org>
 * Copyright (C) 2008  Michael Bell <michael.bell@opensync.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
 *
 */
 
#include "tests/support.h"

#ifdef ENABLE_WBXML
#include <libsyncml/parser/sml_wbxml_internals.h>
#endif

#include <libsyncml/sml_command_internals.h>
#include <libsyncml/sml_elements_internals.h>

static SmlParser *start_wbxml_parser(const char *data)
{
	setup_testbed(NULL);
	
	SmlError *error = NULL;
	SmlParser *parser = smlParserNew(SML_MIMETYPE_WBXML, 0, &error);
	sml_fail_unless(parser != NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	
#ifdef ENABLE_WBXML
	char *buffer = NULL;
	unsigned int size = 0;
	sml_fail_unless(smlWbxmlConvertTo(NULL, data, &buffer, &size, &error), NULL);

	if (!smlParserStart(parser, buffer, size, &error)) {
		sml_fail_unless(error != NULL, NULL);
		smlErrorDeref(&error); /* the error is not used */
		
		smlParserFree(parser);
		smlSafeCFree(&buffer);
		
		return NULL;
	}
	smlSafeCFree(&buffer);
#endif
	
	return parser;
}

START_TEST (wbxml_parser_syncml_empty)
{
	const char *data = "<SyncML></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser == NULL, NULL);
}
END_TEST

START_TEST (wbxml_parser_no_syncbody)
{
	const char *data = "<SyncML><SyncHdr></SyncHdr></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(!smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header == NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);
	
	sml_fail_unless(!smlParserEnd(parser, NULL, NULL, &error), NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);
	
	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_no_synchdr)
{
	const char *data = "<SyncML><SyncBody></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser == NULL, NULL);
}
END_TEST

START_TEST (wbxml_parser_synchdr_empty)
{
	const char *data = "<SyncML><SyncHdr></SyncHdr><SyncBody></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(!smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header == NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);

	/* The empty SyncHdr is followed by an empty SyncHdr.
	 * So the parser is at the correct position to finish successfully.
	 */	
	sml_fail_unless(smlParserEnd(parser, NULL, NULL, &error), NULL);
	sml_fail_unless(error == NULL, NULL);
	
	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_synchdr_verproto)
{
	const char *data = "<SyncML><SyncHdr><VerProto>SyncML/1.1</VerProto></SyncHdr><SyncBody></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(!smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header == NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);
	
	sml_fail_unless(!smlParserEnd(parser, NULL, NULL, &error), NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);
	
	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_synchdr_verdtd)
{
	const char *data = "<SyncML><SyncHdr><VerProto>SyncML/1.1</VerProto><VerDTD>1.1</VerDTD></SyncHdr><SyncBody></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(!smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header == NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);
	
	sml_fail_unless(!smlParserEnd(parser, NULL, NULL, &error), NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);
	
	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_synchdr_msgid)
{
	const char *data = "<SyncML><SyncHdr><VerProto>SyncML/1.1</VerProto><VerDTD>1.1</VerDTD><MsgID>1</MsgID></SyncHdr><SyncBody></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(!smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header == NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);
	
	sml_fail_unless(!smlParserEnd(parser, NULL, NULL, &error), NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);
	
	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_synchdr_sessionid)
{
	const char *data = "<SyncML><SyncHdr><VerProto>SyncML/1.1</VerProto><VerDTD>1.1</VerDTD><MsgID>1</MsgID><SessionID>1</SessionID></SyncHdr><SyncBody></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(!smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header == NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);
	
	sml_fail_unless(!smlParserEnd(parser, NULL, NULL, &error), NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);
	
	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_synchdr_target)
{
	const char *data = "<SyncML><SyncHdr><VerProto>SyncML/1.1</VerProto><VerDTD>1.1</VerDTD><MsgID>1</MsgID><SessionID>1</SessionID><Target><LocURI>test</LocURI></Target></SyncHdr><SyncBody></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(!smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header == NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);
	
	sml_fail_unless(!smlParserEnd(parser, NULL, NULL, &error), NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);
	
	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_synchdr_source)
{
	const char *data = "<SyncML><SyncHdr><VerProto>SyncML/1.1</VerProto><VerDTD>1.1</VerDTD><MsgID>1</MsgID><SessionID>1</SessionID><Target><LocURI>test</LocURI></Target><Source><LocURI>test</LocURI></Source></SyncHdr><SyncBody></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header != NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	sml_fail_unless(header->messageID == 1, NULL);
	sml_fail_unless(header->target != NULL, NULL);
	sml_fail_unless(header->source != NULL, NULL);
	sml_fail_unless(header->protocol == SML_PROTOCOL_SYNCML, NULL);
	sml_fail_unless(header->version == SML_VERSION_11, NULL);
	sml_fail_unless(!strcmp(header->sessionID, "1"), NULL);
	smlHeaderFree(header);

	SmlStatus *status = NULL;
	sml_fail_unless(smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	SmlCommand *cmd = NULL;
	sml_fail_unless(smlParserGetCommand(parser, &cmd, &error), NULL);
	sml_fail_unless(cmd == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	sml_fail_unless(smlParserEnd(parser, NULL, NULL, &error), NULL);
	sml_fail_unless(error == NULL, NULL);
	
	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_synchdr_source2)
{
	const char *data = "<SyncML><SyncHdr><VerProto>SyncML/1.1</VerProto><VerDTD>1.1</VerDTD><MsgID>1</MsgID><SessionID>asd</SessionID><Target><LocURI>test</LocURI></Target><Source><LocURI>test</LocURI></Source></SyncHdr><SyncBody></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header != NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	sml_fail_unless(header->messageID == 1, NULL);
	sml_fail_unless(header->target != NULL, NULL);
	sml_fail_unless(header->source != NULL, NULL);
	sml_fail_unless(header->protocol == SML_PROTOCOL_SYNCML, NULL);
	sml_fail_unless(header->version == SML_VERSION_11, NULL);
	sml_fail_unless(!strcmp(header->sessionID, "asd"), NULL);
	smlHeaderFree(header);
	
	SmlStatus *status = NULL;
	sml_fail_unless(smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	SmlCommand *cmd = NULL;
	sml_fail_unless(smlParserGetCommand(parser, &cmd, &error), NULL);
	sml_fail_unless(cmd == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	sml_fail_unless(smlParserEnd(parser, NULL, NULL, &error), NULL);
	sml_fail_unless(error == NULL, NULL);
	
	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_synchdr_additional)
{
	const char *data = "<SyncML><SyncHdr><VerProto>SyncML/1.1</VerProto><VerDTD>1.1</VerDTD><MsgID>1</MsgID><SessionID>1</SessionID><Target><LocURI>test</LocURI></Target><Source><LocURI>test</LocURI></Source><test></test></SyncHdr><SyncBody></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(!smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header == NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);
	
	sml_fail_unless(!smlParserEnd(parser, NULL, NULL, &error), NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);
	
	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_status_empty)
{
	const char *data = "<SyncML><SyncHdr><VerProto>SyncML/1.1</VerProto><VerDTD>1.1</VerDTD><MsgID>1</MsgID><SessionID>1</SessionID><Target><LocURI>test</LocURI></Target><Source><LocURI>test</LocURI></Source></SyncHdr><SyncBody><Status></Status></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header != NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	sml_fail_unless(header->messageID == 1, NULL);
	smlHeaderFree(header);
	
	SmlStatus *status = NULL;
	sml_fail_unless(!smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status == NULL, NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);
	
	SmlCommand *cmd = NULL;
	sml_fail_unless(smlParserGetCommand(parser, &cmd, &error), NULL);
	sml_fail_unless(cmd == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	sml_fail_unless(smlParserEnd(parser, NULL, NULL, &error), NULL);
	sml_fail_unless(error == NULL, NULL);
	
	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_status_cmdid)
{
	const char *data = "<SyncML><SyncHdr><VerProto>SyncML/1.1</VerProto><VerDTD>1.1</VerDTD><MsgID>1</MsgID><SessionID>1</SessionID><Target><LocURI>test</LocURI></Target><Source><LocURI>test</LocURI></Source></SyncHdr><SyncBody><Status><CmdID>1</CmdID></Status></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header != NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	sml_fail_unless(header->messageID == 1, NULL);
	smlHeaderFree(header);
	
	SmlStatus *status = NULL;
	sml_fail_unless(!smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status == NULL, NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);

	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_status_msgref)
{
	const char *data = "<SyncML><SyncHdr><VerProto>SyncML/1.1</VerProto><VerDTD>1.1</VerDTD><MsgID>1</MsgID><SessionID>1</SessionID><Target><LocURI>test</LocURI></Target><Source><LocURI>test</LocURI></Source></SyncHdr><SyncBody><Status><CmdID>1</CmdID><MsgRef>1</MsgRef></Status></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header != NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	sml_fail_unless(header->messageID == 1, NULL);
	smlHeaderFree(header);
	
	SmlStatus *status = NULL;
	sml_fail_unless(!smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status == NULL, NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);
	
	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_status_cmdref)
{
	const char *data = "<SyncML><SyncHdr><VerProto>SyncML/1.1</VerProto><VerDTD>1.1</VerDTD><MsgID>1</MsgID><SessionID>1</SessionID><Target><LocURI>test</LocURI></Target><Source><LocURI>test</LocURI></Source></SyncHdr><SyncBody><Status><CmdID>1</CmdID><MsgRef>1</MsgRef><CmdRef>1</CmdRef></Status></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header != NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	sml_fail_unless(header->messageID == 1, NULL);
	smlHeaderFree(header);
	
	SmlStatus *status = NULL;
	sml_fail_unless(!smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status == NULL, NULL);
	sml_fail_unless(error != NULL, NULL);
	smlErrorDeref(&error);
	
	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_status)
{
	const char *data = "<SyncML><SyncHdr><VerProto>SyncML/1.1</VerProto><VerDTD>1.1</VerDTD><MsgID>1</MsgID><SessionID>1</SessionID><Target><LocURI>test</LocURI></Target><Source><LocURI>test</LocURI></Source></SyncHdr><SyncBody><Status><CmdID>1</CmdID><MsgRef>1</MsgRef><CmdRef>0</CmdRef><Cmd>Sync</Cmd></Status></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header != NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	sml_fail_unless(header->messageID == 1, NULL);
	smlHeaderFree(header);
	
	SmlStatus *status = NULL;
	sml_fail_unless(smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status != NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	smlStatusUnref(status);
	
	sml_fail_unless(smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	SmlCommand *cmd = NULL;
	sml_fail_unless(smlParserGetCommand(parser, &cmd, &error), NULL);
	sml_fail_unless(cmd == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	sml_fail_unless(smlParserEnd(parser, NULL, NULL, &error), NULL);
	sml_fail_unless(error == NULL, NULL);
	
	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_status2)
{
	const char *data = "<SyncML><SyncHdr><VerProto>SyncML/1.1</VerProto><VerDTD>1.1</VerDTD><MsgID>1</MsgID><SessionID>1</SessionID><Target><LocURI>test</LocURI></Target><Source><LocURI>test</LocURI></Source></SyncHdr><SyncBody><Status><CmdID>1</CmdID><MsgRef>1</MsgRef><CmdRef>0</CmdRef><Cmd>Sync</Cmd></Status><Status><CmdID>1</CmdID><MsgRef>1</MsgRef><CmdRef>0</CmdRef><Cmd>Sync</Cmd></Status></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header != NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	sml_fail_unless(header->messageID == 1, NULL);
	smlHeaderFree(header);
	
	SmlStatus *status = NULL;
	sml_fail_unless(smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status != NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	smlStatusUnref(status);
	
	sml_fail_unless(smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status != NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	smlStatusUnref(status);
	
	sml_fail_unless(smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	SmlCommand *cmd = NULL;
	sml_fail_unless(smlParserGetCommand(parser, &cmd, &error), NULL);
	sml_fail_unless(cmd == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	SmlBool final = TRUE;
	SmlBool end = TRUE;
	sml_fail_unless(smlParserEnd(parser, &final, &end, &error), NULL);
	sml_fail_unless(error == NULL, NULL);
	sml_fail_unless(final == FALSE, NULL);
	sml_fail_unless(end == FALSE, NULL);
	
	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_final)
{
	const char *data = "<SyncML><SyncHdr><VerProto>SyncML/1.1</VerProto><VerDTD>1.1</VerDTD><MsgID>1</MsgID><SessionID>1</SessionID><Target><LocURI>test</LocURI></Target><Source><LocURI>test</LocURI></Source></SyncHdr><SyncBody><Status><CmdID>1</CmdID><MsgRef>1</MsgRef><CmdRef>0</CmdRef><Cmd>Sync</Cmd></Status><Status><CmdID>1</CmdID><MsgRef>1</MsgRef><CmdRef>0</CmdRef><Cmd>Sync</Cmd></Status><Final></Final></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header != NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	sml_fail_unless(header->messageID == 1, NULL);
	smlHeaderFree(header);
	
	SmlStatus *status = NULL;
	sml_fail_unless(smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status != NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	smlStatusUnref(status);
	
	sml_fail_unless(smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status != NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	smlStatusUnref(status);
	
	sml_fail_unless(smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	SmlCommand *cmd = NULL;
	sml_fail_unless(smlParserGetCommand(parser, &cmd, &error), NULL);
	sml_fail_unless(cmd == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	SmlBool final = FALSE;
	SmlBool end = FALSE;
	sml_fail_unless(smlParserEnd(parser, &final, &end, &error), NULL);
	sml_fail_unless(error == NULL, NULL);
	sml_fail_unless(final == TRUE, NULL);
	sml_fail_unless(end == TRUE, NULL);
	
	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_final2)
{
	const char *data = "<SyncML><SyncHdr><VerProto>SyncML/1.1</VerProto><VerDTD>1.1</VerDTD><MsgID>1</MsgID><SessionID>1</SessionID><Target><LocURI>test</LocURI></Target><Source><LocURI>test</LocURI></Source></SyncHdr><SyncBody><Status><CmdID>1</CmdID><MsgRef>1</MsgRef><CmdRef>0</CmdRef><Cmd>Sync</Cmd></Status><Status><CmdID>1</CmdID><MsgRef>1</MsgRef><CmdRef>0</CmdRef><Cmd>Sync</Cmd></Status><Final/></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header != NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	sml_fail_unless(header->messageID == 1, NULL);
	smlHeaderFree(header);
	
	SmlStatus *status = NULL;
	sml_fail_unless(smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status != NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	smlStatusUnref(status);
	
	sml_fail_unless(smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status != NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	smlStatusUnref(status);
	
	sml_fail_unless(smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	SmlCommand *cmd = NULL;
	sml_fail_unless(smlParserGetCommand(parser, &cmd, &error), NULL);
	sml_fail_unless(cmd == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	SmlBool final = FALSE;
	SmlBool end = FALSE;
	sml_fail_unless(smlParserEnd(parser, &final, &end, &error), NULL);
	sml_fail_unless(error == NULL, NULL);
	sml_fail_unless(final == TRUE, NULL);
	sml_fail_unless(end == TRUE, NULL);
	
	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_cmd)
{
	const char *data = "<SyncML><SyncHdr><VerProto>SyncML/1.1</VerProto><VerDTD>1.1</VerDTD><MsgID>1</MsgID><SessionID>1</SessionID><Target><LocURI>test</LocURI></Target><Source><LocURI>test</LocURI></Source></SyncHdr><SyncBody><Alert><CmdID>1</CmdID><Item><Target><LocURI>/test</LocURI></Target><Source><LocURI>/test</LocURI></Source><Meta><Anchor xmlns=\"syncml:metinf\"><Next>Next</Next><Last>last</Last></Anchor></Meta></Item><Data>200</Data></Alert></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header != NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	sml_fail_unless(header->messageID == 1, NULL);
	smlHeaderFree(header);
	
	SmlStatus *status = NULL;
	sml_fail_unless(smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	sml_fail_unless(smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	SmlCommand *cmd = NULL;
	sml_fail_unless(smlParserGetCommand(parser, &cmd, &error), NULL);
	sml_fail_unless(cmd != NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	sml_fail_unless(cmd->cmdID == 1, NULL);
	smlCommandUnref(cmd);
	
	sml_fail_unless(smlParserGetCommand(parser, &cmd, &error), NULL);
	sml_fail_unless(cmd == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	SmlBool final = TRUE;
	SmlBool end = TRUE;
	sml_fail_unless(smlParserEnd(parser, &final, &end, &error), NULL);
	sml_fail_unless(error == NULL, NULL);
	sml_fail_unless(final == FALSE, NULL);
	sml_fail_unless(end == FALSE, NULL);
	
	smlParserFree(parser);
}
END_TEST

START_TEST (wbxml_parser_cmd_final)
{
	const char *data = "<SyncML><SyncHdr><VerProto>SyncML/1.1</VerProto><VerDTD>1.1</VerDTD><MsgID>1</MsgID><SessionID>1</SessionID><Target><LocURI>test</LocURI></Target><Source><LocURI>test</LocURI></Source></SyncHdr><SyncBody><Alert><CmdID>1</CmdID><Item><Target><LocURI>/test</LocURI></Target><Source><LocURI>/test</LocURI></Source><Meta><Anchor xmlns=\"syncml:metinf\"><Next>Next</Next><Last>last</Last></Anchor></Meta></Item><Data>200</Data></Alert><Final></Final></SyncBody></SyncML>";
	SmlParser *parser = start_wbxml_parser(data);
	sml_fail_unless(parser != NULL, NULL);
	
	SmlError *error = NULL;
	SmlHeader *header = NULL;
	SmlCred *cred = NULL;
	
	sml_fail_unless(smlParserGetHeader(parser, &header, &cred, &error), NULL);
	sml_fail_unless(header != NULL, NULL);
	sml_fail_unless(cred == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	sml_fail_unless(header->messageID == 1, NULL);
	smlHeaderFree(header);
	
	SmlStatus *status = NULL;
	sml_fail_unless(smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	sml_fail_unless(smlParserGetStatus(parser, &status, &error), NULL);
	sml_fail_unless(status == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	SmlCommand *cmd = NULL;
	sml_fail_unless(smlParserGetCommand(parser, &cmd, &error), NULL);
	sml_fail_unless(cmd != NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	sml_fail_unless(cmd->cmdID == 1, NULL);
	smlCommandUnref(cmd);
	
	sml_fail_unless(smlParserGetCommand(parser, &cmd, &error), NULL);
	sml_fail_unless(cmd == NULL, NULL);
	sml_fail_unless(error == NULL, NULL);
	
	SmlBool final = FALSE;
	SmlBool end = TRUE;
	sml_fail_unless(smlParserEnd(parser, &final, &end, &error), NULL);
	sml_fail_unless(error == NULL, NULL);
	sml_fail_unless(final == TRUE, NULL);
	sml_fail_unless(end == FALSE, NULL);
	
	smlParserFree(parser);
}
END_TEST

@SML_TESTCASE_CODE@

