Skip to content
Snippets Groups Projects
stringApi.cpp 4.15 KiB
Newer Older
  • Learn to ignore specific revisions
  • #include "stringApi.hpp"
    
    namespace core {
    
    
    ext::map < core::type_details, std::unique_ptr < stringApi < object::Object >::GroupWriter > > & stringApi < object::Object >::composeFunctions ( ) {
    	static ext::map < core::type_details, std::unique_ptr < GroupWriter > > res;
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    ext::list < std::pair < std::function < bool ( ext::istream & ) >, std::unique_ptr < stringApi < object::Object >::GroupReader > > > & stringApi < object::Object >::parseFunctions ( ) {
    	static ext::list < std::pair < std::function < bool ( ext::istream & ) >, std::unique_ptr < GroupReader > > > res;
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    void stringApi < object::Object >::unregisterStringReader ( ext::list < std::pair < std::function < bool ( ext::istream & ) >, std::unique_ptr < GroupReader > > >::const_iterator iter ) {
    
    	auto & entry = parseFunctions ( );
    	if ( ! ext::range_contains_iterator ( entry.begin ( ), entry.end ( ), iter ) )
    		throw std::invalid_argument ( "Entry not found." );
    
    	entry.erase ( iter );
    }
    
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    ext::list < std::pair < std::function < bool ( ext::istream & ) >, std::unique_ptr < stringApi < object::Object >::GroupReader > > >::const_iterator stringApi < object::Object >::registerStringReader ( std::function < bool ( ext::istream & ) > first, std::unique_ptr < GroupReader > entry ) {
    
    	auto & entries = parseFunctions ( );
    	return entries.insert ( entries.end ( ), std::make_pair ( std::move ( first ), std::move ( entry ) ) );
    }
    
    
    void stringApi < object::Object >::unregisterStringWriter ( const core::type_details & type ) {
    
    	if ( ! composeFunctions ( ).erase ( type ) ) {
    		std::string groupName = ext::to_string < object::Object > ( );
    
    
    		throw::exception::CommonException ( "Parse callback of " + ext::to_string ( type ) + " not registered in group " + groupName + "." );
    
    void stringApi < object::Object >::registerStringWriter ( core::type_details type, std::unique_ptr < GroupWriter > entry ) {
    	auto res = composeFunctions ( ).insert ( std::make_pair ( std::move ( type ), std::move ( entry ) ) );
    	if ( ! res.second ) {
    
    		std::string groupName = ext::to_string < object::Object > ( );
    
    
    		throw::exception::CommonException ( "Parse callback of " + ext::to_string ( res.first->first ) + " already registered in group " + groupName + "." );
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    object::Object stringApi < object::Object >::parse ( ext::istream & input ) {
    
    	while ( ext::isspace ( input.peek ( ) ) )
    		input.get ( );
    
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    	auto lambda = [ & ] ( const std::pair < std::function < bool ( ext::istream & ) >, std::unique_ptr < GroupReader > > & entry ) {
    
    		return entry.first ( input );
    	};
    
    
    	std::streamoff pos = input.tellg();
    
    
    	auto callback = find_if ( parseFunctions ( ).begin ( ), parseFunctions ( ).end ( ), lambda );
    	if ( callback == parseFunctions ( ).end ( ) )
    		throw exception::CommonException ( "Parse callback not registered." );
    
    	if ( pos != input.tellg ( ) )
    		throw exception::CommonException ( "First function of registered callback moved the stream (before = " + ext::to_string ( pos ) + ", after = " + ext::to_string ( input.tellg ( ) ) + ")." );
    
    	object::Object res = callback->second->parse ( input );
    
    	input.clear();
    
    	while ( input >> std::string ( "'" ) )
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    bool stringApi < object::Object >::first ( ext::istream & input ) {
    	auto lambda = [ & ] ( const std::pair < std::function < bool ( ext::istream & ) >, std::unique_ptr < GroupReader > > & entry ) {
    
    		return entry.first ( input );
    	};
    
    	return std::any_of ( parseFunctions ( ).begin ( ), parseFunctions ( ).end ( ), lambda );
    }
    
    
    Jan Trávníček's avatar
    Jan Trávníček committed
    void stringApi < object::Object >::compose ( ext::ostream & output, const object::Object & data ) {
    
    	std::unique_ptr < core::type_details_base > type = data.getType ( );
    	auto callback = std::find_if ( composeFunctions ( ).begin ( ), composeFunctions ( ).end ( ), [ & ] ( const std::pair < const core::type_details, std::unique_ptr < GroupWriter > > & entry ) { return entry.first.compatible_with ( * type ); } );
    
    	if ( callback == composeFunctions ( ).end ( ) ) throw exception::CommonException ( "Compose callback for " + ext::to_string ( type ) + " tag not registered." );
    
    
    	callback->second->compose ( output, data );
    	for ( unsigned i = 0; i < data.getId ( ); ++ i )
    		output << "'";
    }