/* * bin2res.cpp - generate embedded resources from binary data (based on qembed) * * Copyright (c) 2005-2008 Tobias Doerffel * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This program 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 * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program (see COPYING); if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * */ #include #include #include #include static void embedData( const char * _input, int _size, std::ostream & _output ); static std::string convertFileNameToCIdentifier( const std::string & _s ); struct embed { unsigned int size; std::string name; std::string cname; } ; typedef std::vector stringlist; const int MAX_FILE_SIZE = 256*256*256; // = 16 MB int main( int argc, char * * argv ) { if( argc < 2 ) { std::cerr << "Usage:" << std::endl << "\t" << argv[0] << " files" << std::endl; return( 1 ); } std::cout << "// Generated by bin2res" << std::endl; std::vector embedded_data; std::cout << "#ifndef _EMBEDDED_RESOURCES_H" << std::endl; std::cout << "#define _EMBEDDED_RESOURCES_H" << std::endl; stringlist files; for( int i = 1; i < argc; ++i ) { files.push_back( std::string( argv[i] ) ); } for( stringlist::iterator it = files.begin(); it != files.end(); ++it ) { std::ifstream f( it->c_str(), std::ios::binary ); if( f.fail() ) { std::cerr << "Cannot open file " << *it << ", ignoring it" << std::endl; continue; } f.seekg( 0, std::ios::end ); int fsize = f.tellg(); f.seekg( 0 ); if( fsize == 0 || fsize > MAX_FILE_SIZE ) { std::cerr << "File " << *it << " has zero size or is " "too large to be processed with bin2res." << std::endl; } char * data = new char[fsize]; f.read( data, fsize ); embed * e = new embed; e->size = fsize; if( it->rfind( '/' ) != std::string::npos ) { e->name = std::string( it->c_str() + it->rfind( '/' ) + 1 ); } else { e->name = *it; } e->cname = convertFileNameToCIdentifier( e->name ); embedded_data.push_back( e ); std::string s; std::cout << "static const unsigned char " << e->cname << "_data[] = {"; embedData( data, fsize, std::cout ); std::cout << std::endl << "};" << std::endl << std::endl; delete[] data; } if( embedded_data.size() > 0 ) { std::cout << "static const unsigned char dummy_data[] =" "{ 0x00 };" << std::endl << std::endl; embed * dummy = new embed; dummy->size = 1; dummy->name = "dummy"; dummy->cname = convertFileNameToCIdentifier( std::string( "dummy" ) ); embedded_data.push_back( dummy ); std::cout << "#include " << std::endl << std::endl; std::cout << "#include \"embed.h\"" << std::endl << std::endl; std::cout << "static embed::descriptor embed_vec[] = {" << std::endl; /* << "{" << std::endl << " int size;" << std::endl << " const unsigned char * data;" << std::endl << " const char * name;" << std::endl << "} embed_vec[] = {" << std::endl;*/ while( embedded_data.size() > 0 ) { embed * e = embedded_data[0]; std::cout << " { " << e->size << ", " << e->cname << "_data, " << "\"" << e->name << "\" }," << std::endl; delete e; embedded_data.erase( embedded_data.begin() ); } std::cout << " { 0, 0, 0 }" << std::endl << "};" << std::endl << std::endl << "static const embed::descriptor & " "findEmbeddedData( const char * _name )" << std::endl << "{" << std::endl << " for( int i = 0; embed_vec[i].data; " "i++ )" << std::endl << " {" << std::endl << " if( strcmp( embed_vec[i].name, " "_name ) == 0 )" << std::endl << " {" << std::endl << " return( " "embed_vec[i] );" << std::endl << " }" << std::endl << " }" << std::endl /* << " printf( \"warning: embedded resource " "%s not found!\\n\", _name );" << std::endl*/ << " return( findEmbeddedData( " "\"dummy\" ) );" << std::endl << "}" << std::endl << std::endl; } std::cout << "#endif" << std::endl; return( 0 ); } std::string convertFileNameToCIdentifier( const std::string & _s ) { std::string r = _s; int len = r.length(); if ( len > 0 && !isalpha( (char)r[0] ) ) { r[0] = '_'; } for ( int i = 1; i < len; i++ ) { if ( !isalnum( (char)r[i] ) ) { r[i] = '_'; } } return( r ); } void embedData( const char * _input, int _nbytes, std::ostream & _output ) { static const char hexdigits[] = "0123456789abcdef"; std::string s; for( int i = 0; i < _nbytes; i++ ) { if( ( i%14 ) == 0 ) { s += "\n "; _output << s; s = ""; } unsigned int v = _input[i]; s += "0x"; s += hexdigits[(v >> 4) & 15]; s += hexdigits[v & 15]; if( i < _nbytes-1 ) { s += ','; } } if ( s.length() ) { _output << s; } }