2 ==============================================================================
4 Utility to turn a bunch of binary files into a .cpp file and .h file full of
5 data so they can be built directly into an executable.
7 Use this code at your own risk! It carries no warranty!
9 ==============================================================================
12 #include "../JuceLibraryCode/JuceHeader.h"
15 //==============================================================================
16 static int addFile (const File
& file
,
17 const String
& classname
,
18 OutputStream
& headerStream
,
19 OutputStream
& cppStream
)
22 file
.loadFileAsData (mb
);
24 const String
name (file
.getFileName().toLowerCase()
25 .replaceCharacter (' ', '_')
26 .replaceCharacter ('.', '_')
27 .retainCharacters ("abcdefghijklmnopqrstuvwxyz_0123456789"));
29 std::cout
<< "Adding " << name
<< ": "
30 << (int) mb
.getSize() << " bytes" << std::endl
;
32 headerStream
<< " extern const char* " << name
<< ";\r\n"
33 " const int " << name
<< "Size = "
34 << (int) mb
.getSize() << ";\r\n\r\n";
36 static int tempNum
= 0;
38 cppStream
<< "static const unsigned char temp" << ++tempNum
<< "[] = {";
41 const uint8
* const data
= (const uint8
*) mb
.getData();
43 while (i
< mb
.getSize() - 1)
46 cppStream
<< (int) data
[i
] << ",";
48 cppStream
<< (int) data
[i
] << ",\r\n ";
53 cppStream
<< (int) data
[i
] << ",0,0};\r\n";
55 cppStream
<< "const char* " << classname
<< "::" << name
56 << " = (const char*) temp" << tempNum
<< ";\r\n\r\n";
61 static bool isHiddenFile (const File
& f
, const File
& root
)
63 return f
.getFileName().endsWithIgnoreCase (".scc")
64 || f
.getFileName() == ".svn"
65 || f
.getFileName().startsWithChar ('.')
66 || (f
.getSize() == 0 && ! f
.isDirectory())
67 || (f
.getParentDirectory() != root
&& isHiddenFile (f
.getParentDirectory(), root
));
71 //==============================================================================
72 int main (int argc
, char* argv
[])
74 std::cout
<< "\n BinaryBuilder! Copyright 2007 by Julian Storer - www.rawmaterialsoftware.com\n\n";
76 if (argc
< 4 || argc
> 5)
78 std::cout
<< " Usage: BinaryBuilder sourcedirectory targetdirectory targetclassname [optional wildcard pattern]\n\n"
79 " BinaryBuilder will find all files in the source directory, and encode them\n"
80 " into two files called (targetclassname).cpp and (targetclassname).h, which it\n"
81 " will write into the target directory supplied.\n\n"
82 " Any files in sub-directories of the source directory will be put into the\n"
83 " resultant class, but #ifdef'ed out using the name of the sub-directory (hard to\n"
84 " explain, but obvious when you try it...)\n";
89 const File
sourceDirectory (File::getCurrentWorkingDirectory()
90 .getChildFile (String (argv
[1]).unquoted()));
92 if (! sourceDirectory
.isDirectory())
94 std::cout
<< "Source directory doesn't exist: "
95 << sourceDirectory
.getFullPathName()
96 << std::endl
<< std::endl
;
101 const File
destDirectory (File::getCurrentWorkingDirectory()
102 .getChildFile (String (argv
[2]).unquoted()));
104 if (! destDirectory
.isDirectory())
106 std::cout
<< "Destination directory doesn't exist: "
107 << destDirectory
.getFullPathName() << std::endl
<< std::endl
;
112 String
className (argv
[3]);
113 className
= className
.trim();
115 const File
headerFile (destDirectory
.getChildFile (className
).withFileExtension (".h"));
116 const File
cppFile (destDirectory
.getChildFile (className
).withFileExtension (".cpp"));
118 std::cout
<< "Creating " << headerFile
.getFullPathName()
119 << " and " << cppFile
.getFullPathName()
120 << " from files in " << sourceDirectory
.getFullPathName()
121 << "..." << std::endl
<< std::endl
;
124 sourceDirectory
.findChildFiles (files
, File::findFiles
, true,
125 (argc
> 4) ? argv
[4] : "*");
127 if (files
.size() == 0)
129 std::cout
<< "Didn't find any source files in: "
130 << sourceDirectory
.getFullPathName() << std::endl
<< std::endl
;
134 headerFile
.deleteFile();
135 cppFile
.deleteFile();
137 ScopedPointer
<OutputStream
> header (headerFile
.createOutputStream());
141 std::cout
<< "Couldn't open "
142 << headerFile
.getFullPathName() << " for writing" << std::endl
<< std::endl
;
146 ScopedPointer
<OutputStream
> cpp (cppFile
.createOutputStream());
150 std::cout
<< "Couldn't open "
151 << cppFile
.getFullPathName() << " for writing" << std::endl
<< std::endl
;
155 *header
<< "/* (Auto-generated binary data file). */\r\n\r\n"
156 "#ifndef BINARY_" << className
.toUpperCase() << "_H\r\n"
157 "#define BINARY_" << className
.toUpperCase() << "_H\r\n\r\n"
158 "namespace " << className
<< "\r\n"
161 *cpp
<< "/* (Auto-generated binary data file). */\r\n\r\n"
162 "#include \"" << className
<< ".h\"\r\n\r\n";
166 for (int i
= 0; i
< files
.size(); ++i
)
168 const File
file (files
[i
]);
170 // (avoid source control files and hidden files..)
171 if (! isHiddenFile (file
, sourceDirectory
))
173 if (file
.getParentDirectory() != sourceDirectory
)
175 *header
<< " #ifdef " << file
.getParentDirectory().getFileName().toUpperCase() << "\r\n";
176 *cpp
<< "#ifdef " << file
.getParentDirectory().getFileName().toUpperCase() << "\r\n";
178 totalBytes
+= addFile (file
, className
, *header
, *cpp
);
180 *header
<< " #endif\r\n";
181 *cpp
<< "#endif\r\n";
185 totalBytes
+= addFile (file
, className
, *header
, *cpp
);
190 *header
<< "};\r\n\r\n"
196 std::cout
<< std::endl
<< " Total size of binary data: " << totalBytes
<< " bytes" << std::endl
;