bin2c.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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. bx::WriterI* stdOut = bx::getStdOut();
  77. if (NULL != _error)
  78. {
  79. bx::writePrintf(stdOut, "Error:\n%s\n\n", _error);
  80. }
  81. bx::writePrintf(stdOut
  82. , "bin2c, binary to C\n"
  83. "Copyright 2011-2017 Branimir Karadzic. All rights reserved.\n"
  84. "License: https://github.com/bkaradzic/bx#license-bsd-2-clause\n\n"
  85. );
  86. bx::writePrintf(stdOut
  87. , "Usage: bin2c -f <in> -o <out> -n <name>\n"
  88. "\n"
  89. "Options:\n"
  90. " -f <file path> Input file path.\n"
  91. " -o <file path> Output file path.\n"
  92. " -n <name> Array name.\n"
  93. "\n"
  94. "For additional information, see https://github.com/bkaradzic/bx\n"
  95. );
  96. }
  97. int main(int _argc, const char* _argv[])
  98. {
  99. bx::CommandLine cmdLine(_argc, _argv);
  100. if (cmdLine.hasArg('h', "help") )
  101. {
  102. help();
  103. return bx::kExitFailure;
  104. }
  105. const char* filePath = cmdLine.findOption('f');
  106. if (NULL == filePath)
  107. {
  108. help("Input file name must be specified.");
  109. return bx::kExitFailure;
  110. }
  111. const char* outFilePath = cmdLine.findOption('o');
  112. if (NULL == outFilePath)
  113. {
  114. help("Output file name must be specified.");
  115. return bx::kExitFailure;
  116. }
  117. const char* name = cmdLine.findOption('n');
  118. if (NULL == name)
  119. {
  120. name = "data";
  121. }
  122. void* data = NULL;
  123. uint32_t size = 0;
  124. bx::FileReader fr;
  125. if (bx::open(&fr, filePath) )
  126. {
  127. size = uint32_t(bx::getSize(&fr) );
  128. bx::DefaultAllocator allocator;
  129. data = BX_ALLOC(&allocator, size);
  130. bx::read(&fr, data, size);
  131. bx::FileWriter fw;
  132. if (bx::open(&fw, outFilePath) )
  133. {
  134. Bin2cWriter writer(&fw, name);
  135. bx::write(&writer, data, size);
  136. writer.finish();
  137. bx::close(&fw);
  138. }
  139. BX_FREE(&allocator, data);
  140. }
  141. return 0;
  142. }