bin2res.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. * bin2res.cpp - generate embedded resources from binary data (based on qembed)
  3. *
  4. * Copyright (c) 2005-2008 Tobias Doerffel <tobydox/at/users.sourceforge.net>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public
  17. * License along with this program (see COPYING); if not, write to the
  18. * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  19. * Boston, MA 02110-1301 USA.
  20. *
  21. */
  22. #include <string>
  23. #include <vector>
  24. #include <iostream>
  25. #include <fstream>
  26. static void embedData( const char * _input, int _size, std::ostream & _output );
  27. static std::string convertFileNameToCIdentifier( const std::string & _s );
  28. struct embed
  29. {
  30. unsigned int size;
  31. std::string name;
  32. std::string cname;
  33. } ;
  34. typedef std::vector<std::string> stringlist;
  35. const int MAX_FILE_SIZE = 256*256*256; // = 16 MB
  36. int main( int argc, char * * argv )
  37. {
  38. if( argc < 2 )
  39. {
  40. std::cerr << "Usage:" << std::endl << "\t" << argv[0] <<
  41. " files" << std::endl;
  42. return( 1 );
  43. }
  44. std::cout << "// Generated by bin2res" << std::endl;
  45. std::vector<embed *> embedded_data;
  46. std::cout << "#ifndef _EMBEDDED_RESOURCES_H" << std::endl;
  47. std::cout << "#define _EMBEDDED_RESOURCES_H" << std::endl;
  48. stringlist files;
  49. for( int i = 1; i < argc; ++i )
  50. {
  51. files.push_back( std::string( argv[i] ) );
  52. }
  53. for( stringlist::iterator it = files.begin(); it != files.end(); ++it )
  54. {
  55. std::ifstream f( it->c_str(), std::ios::binary );
  56. if( f.fail() )
  57. {
  58. std::cerr << "Cannot open file " << *it <<
  59. ", ignoring it" << std::endl;
  60. continue;
  61. }
  62. f.seekg( 0, std::ios::end );
  63. int fsize = f.tellg();
  64. f.seekg( 0 );
  65. if( fsize == 0 || fsize > MAX_FILE_SIZE )
  66. {
  67. std::cerr << "File " << *it << " has zero size or is "
  68. "too large to be processed with bin2res." <<
  69. std::endl;
  70. }
  71. char * data = new char[fsize];
  72. f.read( data, fsize );
  73. embed * e = new embed;
  74. e->size = fsize;
  75. if( it->rfind( '/' ) != std::string::npos )
  76. {
  77. e->name = std::string( it->c_str() +
  78. it->rfind( '/' ) + 1 );
  79. }
  80. else
  81. {
  82. e->name = *it;
  83. }
  84. e->cname = convertFileNameToCIdentifier( e->name );
  85. embedded_data.push_back( e );
  86. std::string s;
  87. std::cout << "static const unsigned char " << e->cname <<
  88. "_data[] = {";
  89. embedData( data, fsize, std::cout );
  90. std::cout << std::endl << "};" << std::endl << std::endl;
  91. delete[] data;
  92. }
  93. if( embedded_data.size() > 0 )
  94. {
  95. std::cout << "static const unsigned char dummy_data[] ="
  96. "{ 0x00 };" << std::endl << std::endl;
  97. embed * dummy = new embed;
  98. dummy->size = 1;
  99. dummy->name = "dummy";
  100. dummy->cname = convertFileNameToCIdentifier(
  101. std::string( "dummy" ) );
  102. embedded_data.push_back( dummy );
  103. std::cout << "#include <string.h>" << std::endl << std::endl;
  104. std::cout << "#include \"embed.h\"" << std::endl << std::endl;
  105. std::cout << "static embed::descriptor embed_vec[] = {" << std::endl;
  106. /* << "{" << std::endl
  107. << " int size;" << std::endl
  108. << " const unsigned char * data;" <<
  109. std::endl
  110. << " const char * name;" << std::endl
  111. << "} embed_vec[] = {" << std::endl;*/
  112. while( embedded_data.size() > 0 )
  113. {
  114. embed * e = embedded_data[0];
  115. std::cout << " { " << e->size << ", " << e->cname <<
  116. "_data, " << "\"" << e->name <<
  117. "\" }," << std::endl;
  118. delete e;
  119. embedded_data.erase( embedded_data.begin() );
  120. }
  121. std::cout << " { 0, 0, 0 }" << std::endl << "};" << std::endl
  122. << std::endl
  123. << "static const embed::descriptor & "
  124. "findEmbeddedData( const char * _name )"
  125. << std::endl << "{" << std::endl
  126. << " for( int i = 0; embed_vec[i].data; "
  127. "i++ )" << std::endl
  128. << " {" << std::endl
  129. << " if( strcmp( embed_vec[i].name, "
  130. "_name ) == 0 )" << std::endl
  131. << " {" << std::endl
  132. << " return( "
  133. "embed_vec[i] );" << std::endl
  134. << " }" << std::endl
  135. << " }" << std::endl
  136. /* << " printf( \"warning: embedded resource "
  137. "%s not found!\\n\", _name );"
  138. << std::endl*/
  139. << " return( findEmbeddedData( "
  140. "\"dummy\" ) );" << std::endl
  141. << "}" << std::endl << std::endl;
  142. }
  143. std::cout << "#endif" << std::endl;
  144. return( 0 );
  145. }
  146. std::string convertFileNameToCIdentifier( const std::string & _s )
  147. {
  148. std::string r = _s;
  149. int len = r.length();
  150. if ( len > 0 && !isalpha( (char)r[0] ) )
  151. {
  152. r[0] = '_';
  153. }
  154. for ( int i = 1; i < len; i++ )
  155. {
  156. if ( !isalnum( (char)r[i] ) )
  157. {
  158. r[i] = '_';
  159. }
  160. }
  161. return( r );
  162. }
  163. void embedData( const char * _input, int _nbytes, std::ostream & _output )
  164. {
  165. static const char hexdigits[] = "0123456789abcdef";
  166. std::string s;
  167. for( int i = 0; i < _nbytes; i++ )
  168. {
  169. if( ( i%14 ) == 0 )
  170. {
  171. s += "\n ";
  172. _output << s;
  173. s = "";
  174. }
  175. unsigned int v = _input[i];
  176. s += "0x";
  177. s += hexdigits[(v >> 4) & 15];
  178. s += hexdigits[v & 15];
  179. if( i < _nbytes-1 )
  180. {
  181. s += ',';
  182. }
  183. }
  184. if ( s.length() )
  185. {
  186. _output << s;
  187. }
  188. }