aboutsummaryrefslogtreecommitdiff
path: root/src/tools/bin2cpp.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/tools/bin2cpp.cpp414
1 files changed, 207 insertions, 207 deletions
diff --git a/src/tools/bin2cpp.cpp b/src/tools/bin2cpp.cpp
index 0b822f0..4214b34 100644
--- a/src/tools/bin2cpp.cpp
+++ b/src/tools/bin2cpp.cpp
@@ -16,244 +16,244 @@ using namespace Bu;
16class Options : public OptParser 16class Options : public OptParser
17{ 17{
18public: 18public:
19 Options( int argc, char *argv[] ) : 19 Options( int argc, char *argv[] ) :
20 sClass("Datafiles") 20 sClass("Datafiles")
21 { 21 {
22 addHelpBanner("bin2cpp - convert files into executable-embeddable C++ code.\n"); 22 addHelpBanner("bin2cpp - convert files into executable-embeddable C++ code.\n");
23 addHelpBanner("Each file in the input is loaded, filtered according to your options, and written as stack allocated, static variables in a generated class. You can then access the files as though they were on disk through that class."); 23 addHelpBanner("Each file in the input is loaded, filtered according to your options, and written as stack allocated, static variables in a generated class. You can then access the files as though they were on disk through that class.");
24 addHelpBanner("\nUsage: bin2cpp [options] [input1] [input2] [...] [inputN]"); 24 addHelpBanner("\nUsage: bin2cpp [options] [input1] [input2] [...] [inputN]");
25 addHelpBanner( " Or: bin2cpp -s <taf spec file>\n"); 25 addHelpBanner( " Or: bin2cpp -s <taf spec file>\n");
26 addOption( sClass, 'c', "Class name [default=\"Datafiles\"]"); 26 addOption( sClass, 'c', "Class name [default=\"Datafiles\"]");
27 addOption( sOutBase, 'o', "Output base filename [defaults to classname]"); 27 addOption( sOutBase, 'o', "Output base filename [defaults to classname]");
28 addOption( sOutDir, 'd', "Output directory [defaults to current dir]"); 28 addOption( sOutDir, 'd', "Output directory [defaults to current dir]");
29 addOption( slot(this, &Options::addFilter), 'f', "Add filter: deflate, bzip2, lzma, base64, hex"); 29 addOption( slot(this, &Options::addFilter), 'f', "Add filter: deflate, bzip2, lzma, base64, hex");
30 addOption( sSpecFile, 's', "Use the specified spec file instead of providing options on the command line. If you use this option all others are ignored."); 30 addOption( sSpecFile, 's', "Use the specified spec file instead of providing options on the command line. If you use this option all others are ignored.");
31 setNonOption( slot(this, &Options::addInput) ); 31 setNonOption( slot(this, &Options::addInput) );
32 addHelpOption(); 32 addHelpOption();
33 33
34 parse( argc, argv ); 34 parse( argc, argv );
35 35
36 if( !sOutBase.isSet() ) 36 if( !sOutBase.isSet() )
37 sOutBase = sClass.toLower(); 37 sOutBase = sClass.toLower();
38 if( sOutDir.isSet() ) 38 if( sOutDir.isSet() )
39 sOutDir += "/"; 39 sOutDir += "/";
40 } 40 }
41 41
42 virtual ~Options() 42 virtual ~Options()
43 { 43 {
44 } 44 }
45 45
46 int addFilter( Bu::StrArray aArgs ) 46 int addFilter( Bu::StrArray aArgs )
47 { 47 {
48 slFilter.append( aArgs[1] ); 48 slFilter.append( aArgs[1] );
49 return 1; 49 return 1;
50 } 50 }
51 51
52 int addInput( Bu::StrArray aArgs ) 52 int addInput( Bu::StrArray aArgs )
53 { 53 {
54 slInput.append( aArgs[0] ); 54 slInput.append( aArgs[0] );
55 return 0; 55 return 0;
56 } 56 }
57 57
58 Bu::String sClass; 58 Bu::String sClass;
59 Bu::String sOutBase; 59 Bu::String sOutBase;
60 Bu::String sOutDir; 60 Bu::String sOutDir;
61 Bu::StringList slInput; 61 Bu::StringList slInput;
62 Bu::StringList slFilter; 62 Bu::StringList slFilter;
63 Bu::String sSpecFile; 63 Bu::String sSpecFile;
64}; 64};
65 65
66int main( int argc, char *argv[] ) 66int main( int argc, char *argv[] )
67{ 67{
68 Options opt( argc, argv ); 68 Options opt( argc, argv );
69 69
70 if( !opt.sSpecFile.isEmpty() ) 70 if( !opt.sSpecFile.isEmpty() )
71 { 71 {
72 Bu::File fTaf( opt.sSpecFile, Bu::File::Read ); 72 Bu::File fTaf( opt.sSpecFile, Bu::File::Read );
73 Bu::TafReader rTaf( fTaf ); 73 Bu::TafReader rTaf( fTaf );
74 Bu::TafGroup *pRoot = rTaf.readGroup(); 74 Bu::TafGroup *pRoot = rTaf.readGroup();
75 75
76 if( pRoot == NULL || pRoot->getName() != "bin2cpp" ) 76 if( pRoot == NULL || pRoot->getName() != "bin2cpp" )
77 { 77 {
78 sio << "Specfied spec file does not appear to be a bin2cpp taf " 78 sio << "Specfied spec file does not appear to be a bin2cpp taf "
79 "specifications file." << sio.nl; 79 "specifications file." << sio.nl;
80 return 5; 80 return 5;
81 } 81 }
82 82
83 opt.sOutBase = opt.sClass = pRoot->getProperty("class"); 83 opt.sOutBase = opt.sClass = pRoot->getProperty("class");
84 if( pRoot->hasProperty("output") ) 84 if( pRoot->hasProperty("output") )
85 opt.sOutBase = pRoot->getProperty("output"); 85 opt.sOutBase = pRoot->getProperty("output");
86 opt.sOutDir = pRoot->getProperty("dir", ".") + "/"; 86 opt.sOutDir = pRoot->getProperty("dir", ".") + "/";
87 87
88 delete pRoot; 88 delete pRoot;
89 } 89 }
90 90
91 File fHdrOut( opt.sOutDir + opt.sOutBase + ".h", File::WriteNew ); 91 File fHdrOut( opt.sOutDir + opt.sOutBase + ".h", File::WriteNew );
92 File fSrcOut( opt.sOutDir + opt.sOutBase + ".cpp", File::WriteNew ); 92 File fSrcOut( opt.sOutDir + opt.sOutBase + ".cpp", File::WriteNew );
93 93
94 Bu::Hash<char, bool> hFilters; 94 Bu::Hash<char, bool> hFilters;
95 95
96 Formatter fHdr( fHdrOut ); 96 Formatter fHdr( fHdrOut );
97 Formatter fSrc( fSrcOut ); 97 Formatter fSrc( fSrcOut );
98 fHdr << "#ifndef BIN2CPP_" << opt.sClass.toUpper() << "_H" << fHdr.nl 98 fHdr << "#ifndef BIN2CPP_" << opt.sClass.toUpper() << "_H" << fHdr.nl
99 << "#define BIN2CPP_" << opt.sClass.toUpper() << "_H" << fHdr.nl << fHdr.nl 99 << "#define BIN2CPP_" << opt.sClass.toUpper() << "_H" << fHdr.nl << fHdr.nl
100 << "#include <bu/string.h>" << fHdr.nl 100 << "#include <bu/string.h>" << fHdr.nl
101 << "#include <bu/streamstack.h>" << fHdr.nl 101 << "#include <bu/streamstack.h>" << fHdr.nl
102 << fHdr.nl 102 << fHdr.nl
103 << "class " << opt.sClass << fHdr.nl 103 << "class " << opt.sClass << fHdr.nl
104 << "{" << fHdr.nl 104 << "{" << fHdr.nl
105 << "public:" << fHdr.nl 105 << "public:" << fHdr.nl
106 << "\tclass File { public: int iSize; const char *data; const char *flt; };" << fHdr.nl << fHdr.nl 106 << "\tclass File { public: int iSize; const char *data; const char *flt; };" << fHdr.nl << fHdr.nl
107 << "\tstatic const File &getFile( const Bu::String &sName );" << fHdr.nl 107 << "\tstatic const File &getFile( const Bu::String &sName );" << fHdr.nl
108 << "\tstatic Bu::StreamStack *open( const Bu::String &sName );" << fHdr.nl 108 << "\tstatic Bu::StreamStack *open( const Bu::String &sName );" << fHdr.nl
109 << "\tstatic Bu::StreamStack *openRaw( const Bu::String &sName );" << fHdr.nl 109 << "\tstatic Bu::StreamStack *openRaw( const Bu::String &sName );" << fHdr.nl
110 << "\tstatic Bu::String getString( const Bu::String &sName );" << fHdr.nl 110 << "\tstatic Bu::String getString( const Bu::String &sName );" << fHdr.nl
111 << "\tstatic Bu::String getStringRaw( const Bu::String &sName );" << fHdr.nl 111 << "\tstatic Bu::String getStringRaw( const Bu::String &sName );" << fHdr.nl
112 << fHdr.nl; 112 << fHdr.nl;
113 fHdr << "public:" << fHdr.nl 113 fHdr << "public:" << fHdr.nl
114 << "\tstatic const File aFile[];" << fHdr.nl 114 << "\tstatic const File aFile[];" << fHdr.nl
115 << "};" << fHdr.nl << fHdr.nl; 115 << "};" << fHdr.nl << fHdr.nl;
116 fHdr << "#endif"; 116 fHdr << "#endif";
117 117
118 fSrc << "#include \"" << opt.sOutBase << ".h\"" << fSrc.nl 118 fSrc << "#include \"" << opt.sOutBase << ".h\"" << fSrc.nl
119 << "#include <bu/deflate.h>" << fSrc.nl 119 << "#include <bu/deflate.h>" << fSrc.nl
120 << "#include <bu/bzip2.h>" << fSrc.nl 120 << "#include <bu/bzip2.h>" << fSrc.nl
121 << "#include <bu/base64.h>" << fSrc.nl 121 << "#include <bu/base64.h>" << fSrc.nl
122 << "#include <bu/lzma.h>" << fSrc.nl 122 << "#include <bu/lzma.h>" << fSrc.nl
123 << "#include <bu/hex.h>" << fSrc.nl 123 << "#include <bu/hex.h>" << fSrc.nl
124 << "#include <bu/strfilter.h>" << fSrc.nl 124 << "#include <bu/strfilter.h>" << fSrc.nl
125 << "#include <bu/staticmembuf.h>" << fSrc.nl << fSrc.nl 125 << "#include <bu/staticmembuf.h>" << fSrc.nl << fSrc.nl
126 << "const " << opt.sClass << "::File " << opt.sClass << "::aFile[] = {" << fSrc.nl; 126 << "const " << opt.sClass << "::File " << opt.sClass << "::aFile[] = {" << fSrc.nl;
127 127
128 for( Bu::StringList::iterator i = opt.slInput.begin(); i; i++ ) 128 for( Bu::StringList::iterator i = opt.slInput.begin(); i; i++ )
129 { 129 {
130 File fIn( *i, File::Read ); 130 File fIn( *i, File::Read );
131 Bu::String sDat; 131 Bu::String sDat;
132 char buf[1024]; 132 char buf[1024];
133 while( !fIn.isEos() ) 133 while( !fIn.isEos() )
134 { 134 {
135 sDat.append( buf, fIn.read( buf, 1024 ) ); 135 sDat.append( buf, fIn.read( buf, 1024 ) );
136 } 136 }
137 137
138 Bu::String sFltDesc; 138 Bu::String sFltDesc;
139 for( Bu::StringList::iterator f = opt.slFilter.begin(); f; f++ ) 139 for( Bu::StringList::iterator f = opt.slFilter.begin(); f; f++ )
140 { 140 {
141 if( *f == "deflate" ) 141 if( *f == "deflate" )
142 { 142 {
143 sDat = encodeStr<Deflate>( sDat ); 143 sDat = encodeStr<Deflate>( sDat );
144 sFltDesc.prepend("d"); 144 sFltDesc.prepend("d");
145 hFilters.insert('d', true ); 145 hFilters.insert('d', true );
146 } 146 }
147 else if( *f == "bzip2" ) 147 else if( *f == "bzip2" )
148 { 148 {
149 sDat = encodeStr<BZip2>( sDat ); 149 sDat = encodeStr<BZip2>( sDat );
150 sFltDesc.prepend("b"); 150 sFltDesc.prepend("b");
151 hFilters.insert('b', true ); 151 hFilters.insert('b', true );
152 } 152 }
153 else if( *f == "lzma" ) 153 else if( *f == "lzma" )
154 { 154 {
155 sDat = encodeStr<Lzma>( sDat ); 155 sDat = encodeStr<Lzma>( sDat );
156 sFltDesc.prepend("l"); 156 sFltDesc.prepend("l");
157 hFilters.insert('l', true ); 157 hFilters.insert('l', true );
158 } 158 }
159 else if( *f == "base64" ) 159 else if( *f == "base64" )
160 { 160 {
161 sDat = encodeStr<Base64>( sDat ); 161 sDat = encodeStr<Base64>( sDat );
162 sFltDesc.prepend("6"); 162 sFltDesc.prepend("6");
163 hFilters.insert('6', true ); 163 hFilters.insert('6', true );
164 } 164 }
165 else if( *f == "hex" ) 165 else if( *f == "hex" )
166 { 166 {
167 sDat = encodeStr<Hex>( sDat ); 167 sDat = encodeStr<Hex>( sDat );
168 sFltDesc.prepend("h"); 168 sFltDesc.prepend("h");
169 hFilters.insert('h', true ); 169 hFilters.insert('h', true );
170 } 170 }
171 else 171 else
172 { 172 {
173 sio << "No known filter named " << *f << sio.nl; 173 sio << "No known filter named " << *f << sio.nl;
174 return 1; 174 return 1;
175 } 175 }
176 } 176 }
177 177
178 fSrc << " {" << sDat.getSize() << ", \""; 178 fSrc << " {" << sDat.getSize() << ", \"";
179 179
180 for( Bu::String::iterator j = sDat.begin(); j; j++ ) 180 for( Bu::String::iterator j = sDat.begin(); j; j++ )
181 { 181 {
182 fSrc << "\\x" << Fmt::hex() << (unsigned char)*j; 182 fSrc << "\\x" << Fmt::hex() << (unsigned char)*j;
183 } 183 }
184 fSrc << "\", \"" << sFltDesc << "\"}," << fSrc.nl; 184 fSrc << "\", \"" << sFltDesc << "\"}," << fSrc.nl;
185 } 185 }
186 fSrc << "};" << fSrc.nl << fSrc.nl; 186 fSrc << "};" << fSrc.nl << fSrc.nl;
187 187
188 fSrc << "const " << opt.sClass << "::File &" << opt.sClass << "::getFile( const Bu::String &sName )" 188 fSrc << "const " << opt.sClass << "::File &" << opt.sClass << "::getFile( const Bu::String &sName )"
189 << fSrc.nl 189 << fSrc.nl
190 << "{" << fSrc.nl 190 << "{" << fSrc.nl
191 << "\tswitch( Bu::__calcHashCode( sName ) )" << fSrc.nl 191 << "\tswitch( Bu::__calcHashCode( sName ) )" << fSrc.nl
192 << "\t{" << fSrc.nl; 192 << "\t{" << fSrc.nl;
193 193
194 int idx = 0; 194 int idx = 0;
195 for( Bu::StringList::iterator i = opt.slInput.begin(); i; i++ ) 195 for( Bu::StringList::iterator i = opt.slInput.begin(); i; i++ )
196 { 196 {
197 fSrc << "\t\tcase " << Bu::__calcHashCode( *i ) << "UL:" << fSrc.nl 197 fSrc << "\t\tcase " << Bu::__calcHashCode( *i ) << "UL:" << fSrc.nl
198 << "\t\t\treturn aFile[" << idx << "];" << fSrc.nl; 198 << "\t\t\treturn aFile[" << idx << "];" << fSrc.nl;
199 idx++; 199 idx++;
200 } 200 }
201 fSrc << "\t}" << fSrc.nl 201 fSrc << "\t}" << fSrc.nl
202 << "\tthrow Bu::ExceptionBase(\"No file matching \\\"%s\\\" found.\", sName.getStr() );" << fSrc.nl 202 << "\tthrow Bu::ExceptionBase(\"No file matching \\\"%s\\\" found.\", sName.getStr() );" << fSrc.nl
203 << "}" << fSrc.nl << fSrc.nl; 203 << "}" << fSrc.nl << fSrc.nl;
204 204
205 fSrc << "Bu::StreamStack *" << opt.sClass << "::open( const Bu::String &sName )" << fSrc.nl 205 fSrc << "Bu::StreamStack *" << opt.sClass << "::open( const Bu::String &sName )" << fSrc.nl
206 << "{" << fSrc.nl 206 << "{" << fSrc.nl
207 << "\tconst File &f = getFile( sName );" << fSrc.nl 207 << "\tconst File &f = getFile( sName );" << fSrc.nl
208 << "\tBu::StreamStack *s = new Bu::StreamStack( new Bu::StaticMemBuf( f.data, f.iSize ) );" << fSrc.nl; 208 << "\tBu::StreamStack *s = new Bu::StreamStack( new Bu::StaticMemBuf( f.data, f.iSize ) );" << fSrc.nl;
209 209
210 if( !hFilters.isEmpty() ) 210 if( !hFilters.isEmpty() )
211 { 211 {
212 fSrc << "\tfor( const char *t = f.flt; *t; t++ )" << fSrc.nl 212 fSrc << "\tfor( const char *t = f.flt; *t; t++ )" << fSrc.nl
213 << "\t{" << fSrc.nl 213 << "\t{" << fSrc.nl
214 << "\t\tswitch( *t )" << fSrc.nl 214 << "\t\tswitch( *t )" << fSrc.nl
215 << "\t\t{" << fSrc.nl; 215 << "\t\t{" << fSrc.nl;
216 if( hFilters.has('d') ) 216 if( hFilters.has('d') )
217 fSrc << "\t\t\tcase 'd': s->pushFilter<Bu::Deflate>(); break;" << fSrc.nl; 217 fSrc << "\t\t\tcase 'd': s->pushFilter<Bu::Deflate>(); break;" << fSrc.nl;
218 if( hFilters.has('b') ) 218 if( hFilters.has('b') )
219 fSrc << "\t\t\tcase 'b': s->pushFilter<Bu::BZip2>(); break;" << fSrc.nl; 219 fSrc << "\t\t\tcase 'b': s->pushFilter<Bu::BZip2>(); break;" << fSrc.nl;
220 if( hFilters.has('l') ) 220 if( hFilters.has('l') )
221 fSrc << "\t\t\tcase 'l': s->pushFilter<Bu::Lzma>(); break;" << fSrc.nl; 221 fSrc << "\t\t\tcase 'l': s->pushFilter<Bu::Lzma>(); break;" << fSrc.nl;
222 if( hFilters.has('6') ) 222 if( hFilters.has('6') )
223 fSrc << "\t\t\tcase '6': s->pushFilter<Bu::Base64>(); break;" << fSrc.nl; 223 fSrc << "\t\t\tcase '6': s->pushFilter<Bu::Base64>(); break;" << fSrc.nl;
224 if( hFilters.has('h') ) 224 if( hFilters.has('h') )
225 fSrc << "\t\t\tcase 'h': s->pushFilter<Bu::Hex>(); break;" << fSrc.nl; 225 fSrc << "\t\t\tcase 'h': s->pushFilter<Bu::Hex>(); break;" << fSrc.nl;
226 fSrc << "\t\t}" << fSrc.nl 226 fSrc << "\t\t}" << fSrc.nl
227 << "\t}" << fSrc.nl; 227 << "\t}" << fSrc.nl;
228 } 228 }
229 fSrc << "\treturn s;" << fSrc.nl 229 fSrc << "\treturn s;" << fSrc.nl
230 << "}" << fSrc.nl << fSrc.nl; 230 << "}" << fSrc.nl << fSrc.nl;
231 231
232 fSrc << "Bu::StreamStack *" << opt.sClass << "::openRaw( const Bu::String &sName )" << fSrc.nl 232 fSrc << "Bu::StreamStack *" << opt.sClass << "::openRaw( const Bu::String &sName )" << fSrc.nl
233 << "{" << fSrc.nl 233 << "{" << fSrc.nl
234 << "\tconst File &f = getFile( sName );" << fSrc.nl 234 << "\tconst File &f = getFile( sName );" << fSrc.nl
235 << "\treturn new Bu::StreamStack( new Bu::StaticMemBuf( f.data, f.iSize ) );" << fSrc.nl 235 << "\treturn new Bu::StreamStack( new Bu::StaticMemBuf( f.data, f.iSize ) );" << fSrc.nl
236 << "}" << fSrc.nl << fSrc.nl; 236 << "}" << fSrc.nl << fSrc.nl;
237 237
238 fSrc << "Bu::String " << opt.sClass << "::getString( const Bu::String &sName )" << fSrc.nl 238 fSrc << "Bu::String " << opt.sClass << "::getString( const Bu::String &sName )" << fSrc.nl
239 << "{" << fSrc.nl 239 << "{" << fSrc.nl
240 << "\tBu::StreamStack *ss = open( sName );" << fSrc.nl 240 << "\tBu::StreamStack *ss = open( sName );" << fSrc.nl
241 << "\tBu::String s;" << fSrc.nl 241 << "\tBu::String s;" << fSrc.nl
242 << "\tchar buf[1024];" << fSrc.nl 242 << "\tchar buf[1024];" << fSrc.nl
243 << "\twhile( !ss->isEos() )" << fSrc.nl 243 << "\twhile( !ss->isEos() )" << fSrc.nl
244 << "\t{" << fSrc.nl 244 << "\t{" << fSrc.nl
245 << "\t\ts.append( buf, ss->read( buf, 1024 ) );" << fSrc.nl 245 << "\t\ts.append( buf, ss->read( buf, 1024 ) );" << fSrc.nl
246 << "\t}" << fSrc.nl 246 << "\t}" << fSrc.nl
247 << "\tdelete ss;" << fSrc.nl 247 << "\tdelete ss;" << fSrc.nl
248 << "\treturn s;" << fSrc.nl 248 << "\treturn s;" << fSrc.nl
249 << "}" << fSrc.nl << fSrc.nl; 249 << "}" << fSrc.nl << fSrc.nl;
250 250
251 fSrc << "Bu::String " << opt.sClass << "::getStringRaw( const Bu::String &sName )" << fSrc.nl 251 fSrc << "Bu::String " << opt.sClass << "::getStringRaw( const Bu::String &sName )" << fSrc.nl
252 << "{" << fSrc.nl 252 << "{" << fSrc.nl
253 << "\tconst File &f = getFile( sName );" << fSrc.nl 253 << "\tconst File &f = getFile( sName );" << fSrc.nl
254 << "\treturn Bu::String( f.data, f.iSize );" << fSrc.nl 254 << "\treturn Bu::String( f.data, f.iSize );" << fSrc.nl
255 << "}" << fSrc.nl << fSrc.nl; 255 << "}" << fSrc.nl << fSrc.nl;
256 256
257 return 0; 257 return 0;
258} 258}
259 259