bin2c.cpp 4.0 KB

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