1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
|
/*
==============================================================================
Utility to turn a bunch of binary files into a .cpp file and .h file full of
data so they can be built directly into an executable.
Use this code at your own risk! It carries no warranty!
==============================================================================
*/
#include "../JuceLibraryCode/JuceHeader.h"
//==============================================================================
static int addFile (const File& file,
const String& classname,
OutputStream& headerStream,
OutputStream& cppStream)
{
MemoryBlock mb;
file.loadFileAsData (mb);
const String name (file.getFileName()
.replaceCharacter (' ', '_')
.replaceCharacter ('.', '_')
.retainCharacters ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789"));
std::cout << "Adding " << name << ": "
<< (int) mb.getSize() << " bytes" << std::endl;
headerStream << " extern const char* " << name << ";\r\n"
" const int " << name << "Size = "
<< (int) mb.getSize() << ";\r\n\r\n";
static int tempNum = 0;
cppStream << "static const unsigned char temp" << ++tempNum << "[] = {";
size_t i = 0;
const uint8* const data = (const uint8*) mb.getData();
while (i < mb.getSize() - 1)
{
if ((i % 40) != 39)
cppStream << (int) data[i] << ",";
else
cppStream << (int) data[i] << ",\r\n ";
++i;
}
cppStream << (int) data[i] << ",0,0};\r\n";
cppStream << "const char* " << classname << "::" << name
<< " = (const char*) temp" << tempNum << ";\r\n\r\n";
return mb.getSize();
}
static bool isHiddenFile (const File& f, const File& root)
{
return f.getFileName().endsWithIgnoreCase (".scc")
|| f.getFileName() == ".svn"
|| f.getFileName().startsWithChar ('.')
|| (f.getSize() == 0 && ! f.isDirectory())
|| (f.getParentDirectory() != root && isHiddenFile (f.getParentDirectory(), root));
}
//==============================================================================
int main (int argc, char* argv[])
{
std::cout << std::endl << " BinaryBuilder! Visit www.juce.com for more info." << std::endl;
if (argc < 4 || argc > 5)
{
std::cout << " Usage: BinaryBuilder sourcedirectory targetdirectory targetclassname [optional wildcard pattern]\n\n"
" BinaryBuilder will find all files in the source directory, and encode them\n"
" into two files called (targetclassname).cpp and (targetclassname).h, which it\n"
" will write into the target directory supplied.\n\n"
" Any files in sub-directories of the source directory will be put into the\n"
" resultant class, but #ifdef'ed out using the name of the sub-directory (hard to\n"
" explain, but obvious when you try it...)\n";
return 0;
}
const File sourceDirectory (File::getCurrentWorkingDirectory()
.getChildFile (String (argv[1]).unquoted()));
if (! sourceDirectory.isDirectory())
{
std::cout << "Source directory doesn't exist: "
<< sourceDirectory.getFullPathName()
<< std::endl << std::endl;
return 0;
}
const File destDirectory (File::getCurrentWorkingDirectory()
.getChildFile (String (argv[2]).unquoted()));
if (! destDirectory.isDirectory())
{
std::cout << "Destination directory doesn't exist: "
<< destDirectory.getFullPathName() << std::endl << std::endl;
return 0;
}
String className (argv[3]);
className = className.trim();
const File headerFile (destDirectory.getChildFile (className).withFileExtension (".h"));
const File cppFile (destDirectory.getChildFile (className).withFileExtension (".cpp"));
std::cout << "Creating " << headerFile.getFullPathName()
<< " and " << cppFile.getFullPathName()
<< " from files in " << sourceDirectory.getFullPathName()
<< "..." << std::endl << std::endl;
Array<File> files;
sourceDirectory.findChildFiles (files, File::findFiles, true,
(argc > 4) ? argv[4] : "*");
if (files.size() == 0)
{
std::cout << "Didn't find any source files in: "
<< sourceDirectory.getFullPathName() << std::endl << std::endl;
return 0;
}
headerFile.deleteFile();
cppFile.deleteFile();
ScopedPointer<OutputStream> header (headerFile.createOutputStream());
if (header == nullptr)
{
std::cout << "Couldn't open "
<< headerFile.getFullPathName() << " for writing" << std::endl << std::endl;
return 0;
}
ScopedPointer<OutputStream> cpp (cppFile.createOutputStream());
if (cpp == nullptr)
{
std::cout << "Couldn't open "
<< cppFile.getFullPathName() << " for writing" << std::endl << std::endl;
return 0;
}
*header << "/* (Auto-generated binary data file). */\r\n\r\n"
"#ifndef BINARY_" << className.toUpperCase() << "_H\r\n"
"#define BINARY_" << className.toUpperCase() << "_H\r\n\r\n"
"namespace " << className << "\r\n"
"{\r\n";
*cpp << "/* (Auto-generated binary data file). */\r\n\r\n"
"#include \"" << className << ".h\"\r\n\r\n";
int totalBytes = 0;
for (int i = 0; i < files.size(); ++i)
{
const File file (files[i]);
// (avoid source control files and hidden files..)
if (! isHiddenFile (file, sourceDirectory))
{
if (file.getParentDirectory() != sourceDirectory)
{
*header << " #ifdef " << file.getParentDirectory().getFileName().toUpperCase() << "\r\n";
*cpp << "#ifdef " << file.getParentDirectory().getFileName().toUpperCase() << "\r\n";
totalBytes += addFile (file, className, *header, *cpp);
*header << " #endif\r\n";
*cpp << "#endif\r\n";
}
else
{
totalBytes += addFile (file, className, *header, *cpp);
}
}
}
*header << "}\r\n\r\n"
"#endif\r\n";
header = nullptr;
cpp = nullptr;
std::cout << std::endl << " Total size of binary data: " << totalBytes << " bytes" << std::endl;
return 0;
}
|