/*
 * SparseBoolVector.cpp
 *
 *  Created on: 15. 5. 2017
 *	  Author: Jan Travnicek
 */

#include "SparseBoolVector.hpp"
#include <primitive/xml/Unsigned.h>
#include <primitive/xml/UnsignedLong.h>

namespace core {

common::SparseBoolVector xmlApi < common::SparseBoolVector >::parse ( ext::deque < sax::Token >::iterator & input ) {
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, xmlTagName ( ) );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "Size" );
	size_t size = core::xmlApi < size_t >::parse ( input );
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "Size" );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "Data" );
	ext::list < common::SparseBoolVector::element > data;
	while ( sax::FromXMLParserHelper::isTokenType ( input, sax::Token::TokenType::START_ELEMENT ) ) {
		sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::START_ELEMENT, "Block" );

		unsigned run = core::xmlApi < unsigned >::parse ( input );
		unsigned word = core::xmlApi < unsigned >::parse ( input );

		data.push_back ( common::SparseBoolVector::element { run, word } );

		sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "Block" );
	}
	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, "Data" );

	sax::FromXMLParserHelper::popToken ( input, sax::Token::TokenType::END_ELEMENT, xmlTagName ( ) );

	return common::SparseBoolVector ( std::move ( data ), size );
}

void xmlApi < common::SparseBoolVector >::compose ( ext::deque < sax::Token > & output, const common::SparseBoolVector & input ) {
	output.emplace_back ( xmlTagName ( ), sax::Token::TokenType::START_ELEMENT );
	output.emplace_back ( "Size", sax::Token::TokenType::START_ELEMENT );
	core::xmlApi < size_t >::compose ( output, input.size ( ) );
	output.emplace_back ( "Size", sax::Token::TokenType::END_ELEMENT );
	output.emplace_back ( "Data", sax::Token::TokenType::START_ELEMENT );
	for ( const common::SparseBoolVector::element & elem : input.data ( ) ) {
		output.emplace_back ( "Block", sax::Token::TokenType::START_ELEMENT );
		core::xmlApi < unsigned >::compose ( output, elem.run );
		core::xmlApi < unsigned >::compose ( output, elem.word );
		output.emplace_back ( "Block", sax::Token::TokenType::END_ELEMENT );
	}
	output.emplace_back ( "Data", sax::Token::TokenType::END_ELEMENT );
	output.emplace_back ( xmlTagName ( ), sax::Token::TokenType::END_ELEMENT );
}

} /* namespace core */
