bin2c.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * Copyright 2011-2018 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/file.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) 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_name;
  70. typedef std::vector<uint8_t> Buffer;
  71. Buffer m_buffer;
  72. };
  73. void help(const char* _error = NULL)
  74. {
  75. bx::WriterI* stdOut = bx::getStdOut();
  76. if (NULL != _error)
  77. {
  78. bx::writePrintf(stdOut, "Error:\n%s\n\n", _error);
  79. }
  80. bx::writePrintf(stdOut
  81. , "bin2c, binary to C\n"
  82. "Copyright 2011-2018 Branimir Karadzic. All rights reserved.\n"
  83. "License: https://github.com/bkaradzic/bx#license-bsd-2-clause\n\n"
  84. );
  85. bx::writePrintf(stdOut
  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 bx::kExitFailure;
  103. }
  104. const char* filePath = cmdLine.findOption('f');
  105. if (NULL == filePath)
  106. {
  107. help("Input file name must be specified.");
  108. return bx::kExitFailure;
  109. }
  110. const char* outFilePath = cmdLine.findOption('o');
  111. if (NULL == outFilePath)
  112. {
  113. help("Output file name must be specified.");
  114. return bx::kExitFailure;
  115. }
  116. const char* name = cmdLine.findOption('n');
  117. if (NULL == name)
  118. {
  119. name = "data";
  120. }
  121. void* data = NULL;
  122. uint32_t size = 0;
  123. bx::FileReader fr;
  124. if (bx::open(&fr, filePath) )
  125. {
  126. size = uint32_t(bx::getSize(&fr) );
  127. bx::DefaultAllocator allocator;
  128. data = BX_ALLOC(&allocator, size);
  129. bx::read(&fr, data, size);
  130. bx::FileWriter fw;
  131. if (bx::open(&fw, outFilePath) )
  132. {
  133. Bin2cWriter writer(&fw, name);
  134. bx::write(&writer, data, size);
  135. writer.finish();
  136. bx::close(&fw);
  137. }
  138. BX_FREE(&allocator, data);
  139. }
  140. return 0;
  141. }