#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
/*--* AXIS2/C Headers *--*/
#include <axiom.h>
#include <axiom_util.h>

#define	MAX_COUNTER			99999

/* Function Prototypes */
static axis2_char_t *retrive_stream_from_om_ex( const axutil_env_t * env, axiom_node_t *node, char *pBuff, int nBuffLen );
static axiom_node_t *build_om_from_stream( const axutil_env_t * env, axis2_char_t *szData );

int main( int argc, char **argv )
{
	long counter = 0;
	const axutil_env_t 	* env			 	= NULL;
	axiom_node_t       	*om       		= NULL;
	char               	*pBuff        	= "<Header><h:guid xmlns:h=\"http://localhost/namespce/header/\">00000000-0000-0000-0000-000000000001</h:guid></Header>";
	char						*pOut				= NULL;

	/* Create Environment */
	env = axutil_env_create_all( "libxml_issue2.log", AXIS2_LOG_LEVEL_CRITICAL );
	if( !env )
	{
		printf( "Error: axutil_env_create_all\n");
		return  1;
	}
	om = build_om_from_stream( env, pBuff );
	if( !om )
	{
		printf( "Error: build_om_from_stream\n");
		return 2;
	}
   printf( "Enter any key to start the loop...\n" );
	getch();
	do
	{
		pOut = retrive_stream_from_om_ex( env, om, NULL, 0 );
		printf( "." );
		//printf( "\n%s\n", pOut );
		free( pOut );
	} while( counter++ < MAX_COUNTER );
	printf( "\nCounter:%d\n", counter );
	printf( "Enter any key to terminate...\n" );
	getch();

	
	axiom_node_free_tree(om, env);
	/* Free Environment */
	if( env )
	{
		axutil_env_free((axutil_env_t *) env);
		env = NULL;
	}

	return 0;
}

static axis2_char_t *retrive_stream_from_om_ex( const axutil_env_t * env, axiom_node_t *node, char *pBuff, int nBuffLen )
{
	axiom_xml_writer_t *w = NULL;
	axiom_output_t *on = NULL;
	axis2_char_t *rtn_str = pBuff;
	int          rtn_len = nBuffLen;

	do
	{
		char *pWork = NULL;

		w = axiom_xml_writer_create_for_memory( env, NULL, AXIS2_TRUE, 0, AXIS2_XML_PARSER_TYPE_BUFFER);
		if( !w )
			break;
		on = axiom_output_create( env, w );
		if( !on )
			break;

		if( axiom_node_serialize_sub_tree(node, env, on) !=AXIS2_SUCCESS )
		//if( axiom_node_serialize(node, env, on) !=AXIS2_SUCCESS )
			break;

		pWork = axiom_xml_writer_get_xml(w, env);
		if( !rtn_str || !rtn_len )
		{
			rtn_len = strlen( pWork );
			rtn_str = calloc( 1, rtn_len + 1 );
		}
		memcpy( rtn_str, pWork, rtn_len );

	}while( 0 );

	axiom_output_free( on, env);
	//axiom_xml_writer_free( w, env);	

	return rtn_str;
}
/*
 *Function Name:build_om_from_stream
 *
 *Parameters:
 *
 *Description: Returns OM created from an XML stream
 *
 *Returns:
 *
 */

static axiom_node_t *build_om_from_stream( const axutil_env_t * env, axis2_char_t *szData )
{
	axiom_xml_reader_t *r = NULL;
	axiom_stax_builder_t *sb = NULL;
	axiom_document_t *doc = NULL;
	axiom_node_t *rtn_node = NULL;

	do
	{
		if( !szData )
			break;

		r = axiom_xml_reader_create_for_memory(env, szData, strlen (szData), NULL, AXIS2_XML_PARSER_TYPE_BUFFER);
		if( !r )
			break;

		sb = axiom_stax_builder_create(env, r);
		if( !sb )
			break;

		doc = axiom_stax_builder_get_document(sb, env);
		if( doc )
			rtn_node =  axiom_document_build_all(doc, env);

	}while( 0 );

	axiom_stax_builder_free_self( sb, env);
	sb = NULL;
	//axiom_xml_reader_free( r, env);

	return rtn_node;
}

