bin2c.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * Copyright 2011-2017 Branimir Karadzic. All rights reserved.
  3. * License: https://github.com/bkaradzic/bx#license-bsd-2-clause
  4. */
  5. #include <string>
  6. #include <vector>
  7. #include <bx/commandline.h>
  8. #include <bx/crtimpl.h>
  9. #include <bx/string.h>
  10. class Bin2cWriter : public bx::WriterI
  11. {
  12. public:
  13. Bin2cWriter(bx::WriterI* _writer, const char* _name)
  14. : m_writer(_writer)
  15. , m_name(_name)
  16. {
  17. }
  18. virtual ~Bin2cWriter()
  19. {
  20. }
  21. virtual int32_t write(const void* _data, int32_t _size, bx::Error* /*_err*/ = NULL) BX_OVERRIDE
  22. {
  23. const char* data = (const char*)_data;
  24. m_buffer.insert(m_buffer.end(), data, data+_size);
  25. return _size;
  26. }
  27. void finish()
  28. {
  29. #define HEX_DUMP_WIDTH 16
  30. #define HEX_DUMP_SPACE_WIDTH 96
  31. #define HEX_DUMP_FORMAT "%-" BX_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "." BX_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "s"
  32. const uint8_t* data = &m_buffer[0];
  33. uint32_t size = (uint32_t)m_buffer.size();
  34. bx::writePrintf(m_writer, "static const uint8_t %s[%d] =\n{\n", m_name.c_str(), size);
  35. if (NULL != data)
  36. {
  37. char hex[HEX_DUMP_SPACE_WIDTH+1];
  38. char ascii[HEX_DUMP_WIDTH+1];
  39. uint32_t hexPos = 0;
  40. uint32_t asciiPos = 0;
  41. for (uint32_t ii = 0; ii < size; ++ii)
  42. {
  43. bx::snprintf(&hex[hexPos], sizeof(hex)-hexPos, "0x%02x, ", data[asciiPos]);
  44. hexPos += 6;
  45. ascii[asciiPos] = isprint(data[asciiPos]) && data[asciiPos] != '\\' ? data[asciiPos] : '.';
  46. asciiPos++;
  47. if (HEX_DUMP_WIDTH == asciiPos)
  48. {
  49. ascii[asciiPos] = '\0';
  50. bx::writePrintf(m_writer, "\t" HEX_DUMP_FORMAT "// %s\n", hex, ascii);
  51. data += asciiPos;
  52. hexPos = 0;
  53. asciiPos = 0;
  54. }
  55. }
  56. if (0 != asciiPos)
  57. {
  58. ascii[asciiPos] = '\0';
  59. bx::writePrintf(m_writer, "\t" HEX_DUMP_FORMAT "// %s\n", hex, ascii);
  60. }
  61. }
  62. bx::writePrintf(m_writer, "};\n");
  63. #undef HEX_DUMP_WIDTH
  64. #undef HEX_DUMP_SPACE_WIDTH
  65. #undef HEX_DUMP_FORMAT
  66. m_buffer.clear();
  67. }
  68. bx::WriterI* m_writer;
  69. std::string m_filePath;
  70. std::string m_name;
  71. typedef std::vector<uint8_t> Buffer;
  72. Buffer m_buffer;
  73. };
  74. void help(const char* _error = NULL)
  75. {
  76. if (NULL != _error)
  77. {
  78. fprintf(stderr, "Error:\n%s\n\n", _error);
  79. }
  80. fprintf(stderr
  81. , "bin2c, binary to C\n"
  82. "Copyright 2011-2017 Branimir Karadzic. All rights reserved.\n"
  83. "License: https://github.com/bkaradzic/bx#license-bsd-2-clause\n\n"
  84. );
  85. fprintf(stderr
  86. , "Usage: bin2c -f <in> -o <out> -n <name>\n"
  87. "\n"
  88. "Options:\n"
  89. " -f <file path> Input file path.\n"
  90. " -o <file path> Output file path.\n"
  91. " -n <name> Array name.\n"
  92. "\n"
  93. "For additional information, see https://github.com/bkaradzic/bx\n"
  94. );
  95. }
  96. int main(int _argc, const char* _argv[])
  97. {
  98. bx::CommandLine cmdLine(_argc, _argv);
  99. if (cmdLine.hasArg('h', "help") )
  100. {
  101. help();
  102. return EXIT_FAILURE;
  103. }
  104. const char* filePath = cmdLine.findOption('f');
  105. if (NULL == filePath)
  106. {
  107. help("Input file name must be specified.");
  108. return EXIT_FAILURE;
  109. }
  110. const char* outFilePath = cmdLine.findOption('o');
  111. if (NULL == outFilePath)
  112. {
  113. help("Output file name must be specified.");
  114. return EXIT_FAILURE;
  115. }
  116. const char* name = cmdLine.findOption('n');
  117. if (NULL == name)
  118. {
  119. name = "data";
  120. }
  121. void* data = NULL;
  122. size_t size = 0;
  123. bx::CrtFileReader fr;
  124. if (bx::open(&fr, filePath) )
  125. {
  126. size = (size_t)bx::getSize(&fr);
  127. data = malloc(size);
  128. bx::read(&fr, data, size);
  129. bx::CrtFileWriter fw;
  130. if (bx::open(&fw, outFilePath) )
  131. {
  132. Bin2cWriter writer(&fw, name);
  133. bx::write(&writer, data, size);
  134. writer.finish();
  135. bx::close(&fw);
  136. }
  137. free(data);
  138. }
  139. return 0;
  140. }