Skip to content

Commit bcfbe55

Browse files
committed
Implemented C code generation support for ArrayGenerator, SegmentGenerator, StringGenerator and Win32ResourceGenerator. #53
1 parent 2253490 commit bcfbe55

File tree

9 files changed

+536
-6
lines changed

9 files changed

+536
-6
lines changed

src/bin2cpp/ArrayGenerator.cpp

Lines changed: 154 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ namespace bin2cpp
131131
delete[] buffer;
132132
buffer = NULL;
133133

134-
//write cpp file footer
134+
//write cpp source file footer
135135
fprintf(cpp, " return (const char *)buffer;\n");
136136
fprintf(cpp, " }\n");
137137
fprintf(cpp, "%s", getSaveMethodTemplate().c_str());
@@ -192,4 +192,157 @@ namespace bin2cpp
192192
return true;
193193
}
194194

195+
bool ArrayGenerator::createCSourceFile(const char* file_path)
196+
{
197+
//check if input file exists
198+
FILE* input = fopen(mContext.inputFilePath.c_str(), "rb");
199+
if ( !input )
200+
return false;
201+
202+
//Uppercase function identifier
203+
std::string functionIdentifier = ra::strings::Lowercase(mContext.functionIdentifier);
204+
205+
//Build header and cpp file path
206+
std::string headerPath = getHeaderFilePath(file_path);
207+
std::string sourcePath = file_path;
208+
209+
//create c source file
210+
FILE* fout = fopen(sourcePath.c_str(), "w");
211+
if ( !fout )
212+
{
213+
fclose(input);
214+
return false;
215+
}
216+
217+
//determine file properties
218+
uint32_t fileSize = ra::filesystem::GetFileSize(input);
219+
std::string filename = ra::filesystem::GetFilename(mContext.inputFilePath.c_str());
220+
//long lastSegmentSize = fileSize%chunk_size;
221+
//size_t numSegments = fileSize/chunk_size + (lastSegmentSize == 0 ? 0 : 1);
222+
223+
//Build class name
224+
std::string className = getClassName();
225+
226+
//Build function
227+
std::string getterFunctionName = getGetterFunctionName();
228+
229+
//Build FileManager class template
230+
std::string manager = mContext.managerHeaderFilename;
231+
232+
//write c file heading
233+
fprintf(fout, "%s", getHeaderTemplate().c_str());
234+
fprintf(fout, "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n");
235+
fprintf(fout, "#define _CRT_SECURE_NO_WARNINGS\n");
236+
fprintf(fout, "#endif\n");
237+
fprintf(fout, "#include \"%s\"\n", mContext.headerFilename.c_str());
238+
fprintf(fout, "#include <stdlib.h> // for malloc\n");
239+
fprintf(fout, "#include <string.h> // for memset\n");
240+
fprintf(fout, "#include <stdio.h> // for fopen\n");
241+
242+
fprintf(fout, "static %s %s_file = { 0 };\n", mContext.baseClass.c_str(), functionIdentifier.c_str());
243+
fprintf(fout, "static bool %s_initialized = false;\n", functionIdentifier.c_str());
244+
fprintf(fout, "\n");
245+
246+
fprintf(fout, "bool %s_load()\n", functionIdentifier.c_str());
247+
fprintf(fout, "{\n");
248+
fprintf(fout, " if ( %s_file.buffer )\n", functionIdentifier.c_str());
249+
fprintf(fout, " return true;\n");
250+
fprintf(fout, " static const unsigned char static_buffer[] = {\n");
251+
252+
//create buffer for each chunks from input buffer
253+
int numLinePrinted = 0;
254+
unsigned char* buffer = new unsigned char[getContext().chunkSize];
255+
while ( !feof(input) )
256+
{
257+
//read a chunk of the file
258+
size_t readSize = fread(buffer, 1, getContext().chunkSize, input);
259+
260+
bool isLastChunk = !(readSize == getContext().chunkSize);
261+
262+
if ( readSize > 0 )
263+
{
264+
if ( numLinePrinted > 0 )
265+
{
266+
//end previous line
267+
fprintf(fout, ",\n");
268+
}
269+
270+
//output
271+
fprintf(fout, " %s", ra::code::cpp::ToCppCharactersArray(buffer, readSize).c_str());
272+
numLinePrinted++;
273+
}
274+
275+
//end the array. all the file content is printed
276+
if ( isLastChunk )
277+
{
278+
fprintf(fout, "\n");
279+
fprintf(fout, " };\n");
280+
}
281+
}
282+
delete[] buffer;
283+
buffer = NULL;
284+
285+
//write c source file footer
286+
fprintf(fout, "\n");
287+
fprintf(fout, " %s_file.buffer = static_buffer;\n", functionIdentifier.c_str());
288+
fprintf(fout, " return true;\n");
289+
fprintf(fout, "}\n");
290+
291+
fprintf(fout, "\n");
292+
293+
fprintf(fout, "void %s_free()\n", functionIdentifier.c_str());
294+
fprintf(fout, "{\n");
295+
fprintf(fout, " %s_file.buffer = NULL;\n", functionIdentifier.c_str());
296+
fprintf(fout, "}\n");
297+
fprintf(fout, "\n");
298+
fprintf(fout, "bool %s_save(const char* path)\n", functionIdentifier.c_str());
299+
fprintf(fout, "{\n");
300+
fprintf(fout, " if ( !%s_file.buffer )\n", functionIdentifier.c_str());
301+
fprintf(fout, " return false;\n");
302+
fprintf(fout, " FILE* f = fopen(path, \"wb\");\n");
303+
fprintf(fout, " if ( !f )\n");
304+
fprintf(fout, " return false;\n");
305+
fprintf(fout, " size_t write_size = fwrite(%s_file.buffer, 1, %s_file.size, f);\n", functionIdentifier.c_str(), functionIdentifier.c_str());
306+
fprintf(fout, " fclose(f);\n");
307+
fprintf(fout, " if ( write_size != %s_file.size )\n", functionIdentifier.c_str());
308+
fprintf(fout, " return false;\n");
309+
fprintf(fout, " return true;\n");
310+
fprintf(fout, "}\n");
311+
fprintf(fout, "\n");
312+
fprintf(fout, "inline void %s_init()\n", functionIdentifier.c_str());
313+
fprintf(fout, "{\n");
314+
fprintf(fout, " // remember we already initialized\n");
315+
fprintf(fout, " if ( %s_initialized )\n", functionIdentifier.c_str());
316+
fprintf(fout, " return;\n");
317+
fprintf(fout, " %s_initialized = true;\n", functionIdentifier.c_str());
318+
fprintf(fout, "\n");
319+
fprintf(fout, " // initialize\n");
320+
fprintf(fout, " %s* file = &%s_file;\n", mContext.baseClass.c_str(), functionIdentifier.c_str());
321+
fprintf(fout, " file->size = %uULL;\n", fileSize);
322+
fprintf(fout, " file->file_name = \"%s\";\n", getFileClassFileName().c_str());
323+
fprintf(fout, " file->file_path = \"%s\";\n", getFileClassFilePath().c_str());
324+
fprintf(fout, " file->buffer = NULL;\n");
325+
fprintf(fout, " file->load = %s_load;\n", functionIdentifier.c_str());
326+
fprintf(fout, " file->unload = %s_free;\n", functionIdentifier.c_str());
327+
fprintf(fout, " file->save = %s_save;\n", functionIdentifier.c_str());
328+
fprintf(fout, "}\n");
329+
fprintf(fout, "\n");
330+
fprintf(fout, "%s* %s(void)\n", mContext.baseClass.c_str(), getGetterFunctionName().c_str());
331+
fprintf(fout, "{\n");
332+
fprintf(fout, " %s_init();\n", functionIdentifier.c_str());
333+
fprintf(fout, " return &%s_file;\n", functionIdentifier.c_str());
334+
fprintf(fout, "}\n");
335+
336+
if ( mContext.registerFiles )
337+
{
338+
std::string fileManagerTemplate = getFileManagerRegistrationTemplate();
339+
fprintf(fout, "%s", fileManagerTemplate.c_str());
340+
}
341+
342+
fclose(input);
343+
fclose(fout);
344+
345+
return true;
346+
}
347+
195348
}; //bin2cpp

src/bin2cpp/ArrayGenerator.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ namespace bin2cpp
4141
virtual ~ArrayGenerator();
4242
virtual const char * getName() const;
4343
virtual bool createCppSourceFile(const char * cpp_file_path);
44+
virtual bool createCSourceFile(const char * cpp_file_path);
4445
virtual bool printFileContent();
4546
};
4647

src/bin2cpp/BaseGenerator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ namespace bin2cpp
433433
fprintf(header, " size_t size;\n");
434434
fprintf(header, " const char* file_name;\n");
435435
fprintf(header, " const char* file_path;\n");
436-
fprintf(header, " unsigned char* buffer;\n");
436+
fprintf(header, " const unsigned char* buffer;\n");
437437
fprintf(header, " bin2c_load_func load;\n");
438438
fprintf(header, " bin2c_free_func unload;\n");
439439
fprintf(header, " bin2c_save_func save;\n");

src/bin2cpp/SegmentGenerator.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ namespace bin2cpp
140140
delete[] buffer;
141141
buffer = NULL;
142142

143-
//write cpp file footer
143+
//write cpp source file footer
144144
fprintf(cpp, " }\n");
145145
fprintf(cpp, "%s", getSaveMethodTemplate().c_str());
146146
fprintf(cpp, " private:\n");
@@ -253,6 +253,7 @@ namespace bin2cpp
253253
delete[] buffer;
254254
buffer = NULL;
255255

256+
//write c source file footer
256257
fprintf(fout, "\n");
257258
fprintf(fout, " %s_file.buffer = local_buffer;\n", functionIdentifier.c_str());
258259
fprintf(fout, " return true;\n");

src/bin2cpp/StringGenerator.cpp

Lines changed: 167 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ namespace bin2cpp
143143
delete[] buffer;
144144
buffer = NULL;
145145

146-
//write cpp file footer
146+
//write cpp source file footer
147147
fprintf(cpp, " return buffer;\n");
148148
fprintf(cpp, " }\n");
149149
fprintf(cpp, "%s", getSaveMethodTemplate().c_str());
@@ -162,4 +162,170 @@ namespace bin2cpp
162162
return true;
163163
}
164164

165+
bool StringGenerator::createCSourceFile(const char* file_path)
166+
{
167+
//check if input file exists
168+
FILE* input = fopen(mContext.inputFilePath.c_str(), "rb");
169+
if ( !input )
170+
return false;
171+
172+
//Uppercase function identifier
173+
std::string functionIdentifier = ra::strings::Lowercase(mContext.functionIdentifier);
174+
175+
//Build header and cpp file path
176+
std::string headerPath = getHeaderFilePath(file_path);
177+
std::string sourcePath = file_path;
178+
179+
//create c source file
180+
FILE* fout = fopen(sourcePath.c_str(), "w");
181+
if ( !fout )
182+
{
183+
fclose(input);
184+
return false;
185+
}
186+
187+
//determine file properties
188+
uint32_t fileSize = ra::filesystem::GetFileSize(input);
189+
std::string filename = ra::filesystem::GetFilename(mContext.inputFilePath.c_str());
190+
//long lastSegmentSize = fileSize%chunk_size;
191+
//size_t numSegments = fileSize/chunk_size + (lastSegmentSize == 0 ? 0 : 1);
192+
193+
//Build class name
194+
std::string className = getClassName();
195+
196+
//Build function
197+
std::string getterFunctionName = getGetterFunctionName();
198+
199+
//Build FileManager class template
200+
std::string manager = mContext.managerHeaderFilename;
201+
202+
//write c file heading
203+
fprintf(fout, "%s", getHeaderTemplate().c_str());
204+
fprintf(fout, "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n");
205+
fprintf(fout, "#define _CRT_SECURE_NO_WARNINGS\n");
206+
fprintf(fout, "#endif\n");
207+
fprintf(fout, "#include \"%s\"\n", mContext.headerFilename.c_str());
208+
fprintf(fout, "#include <stdlib.h> // for malloc\n");
209+
fprintf(fout, "#include <string.h> // for memset\n");
210+
fprintf(fout, "#include <stdio.h> // for fopen\n");
211+
212+
fprintf(fout, "static %s %s_file = { 0 };\n", mContext.baseClass.c_str(), functionIdentifier.c_str());
213+
fprintf(fout, "static bool %s_initialized = false;\n", functionIdentifier.c_str());
214+
fprintf(fout, "\n");
215+
216+
fprintf(fout, "bool %s_load()\n", functionIdentifier.c_str());
217+
fprintf(fout, "{\n");
218+
fprintf(fout, " if ( %s_file.buffer )\n", functionIdentifier.c_str());
219+
fprintf(fout, " return true;\n");
220+
fprintf(fout, "\n");
221+
fprintf(fout, " static const char * static_buffer = ""\n");
222+
223+
//create buffer for each chunks from input buffer
224+
int numLinePrinted = 0;
225+
unsigned char* buffer = new unsigned char[getContext().chunkSize];
226+
while ( !feof(input) )
227+
{
228+
//read a chunk of the file
229+
size_t readSize = fread(buffer, 1, getContext().chunkSize, input);
230+
231+
bool isLastChunk = !(readSize == getContext().chunkSize);
232+
233+
if ( readSize > 0 )
234+
{
235+
if ( numLinePrinted > 0 )
236+
{
237+
//end previous line
238+
fprintf(fout, "\n");
239+
}
240+
241+
//convert to cpp string
242+
std::string cppEncoder;
243+
switch ( getContext().cppEncoder )
244+
{
245+
case CPP_ENCODER_HEX:
246+
cppEncoder = ra::code::cpp::ToHexString(buffer, readSize);
247+
break;
248+
case CPP_ENCODER_OCT:
249+
default:
250+
cppEncoder = ra::code::cpp::ToOctString(buffer, readSize, false);
251+
break;
252+
};
253+
254+
//output
255+
fprintf(fout, " \"%s\"", cppEncoder.c_str());
256+
numLinePrinted++;
257+
}
258+
259+
//end the string if last chunk printed
260+
if ( isLastChunk )
261+
{
262+
fprintf(fout, ";\n");
263+
}
264+
}
265+
delete[] buffer;
266+
buffer = NULL;
267+
268+
//write c source file footer
269+
fprintf(fout, "\n");
270+
fprintf(fout, " %s_file.buffer = static_buffer;\n", functionIdentifier.c_str());
271+
fprintf(fout, " return true;\n");
272+
fprintf(fout, "}\n");
273+
274+
fprintf(fout, "\n");
275+
276+
fprintf(fout, "void %s_free()\n", functionIdentifier.c_str());
277+
fprintf(fout, "{\n");
278+
fprintf(fout, " %s_file.buffer = NULL;\n", functionIdentifier.c_str());
279+
fprintf(fout, "}\n");
280+
fprintf(fout, "\n");
281+
fprintf(fout, "bool %s_save(const char* path)\n", functionIdentifier.c_str());
282+
fprintf(fout, "{\n");
283+
fprintf(fout, " if ( !%s_file.buffer )\n", functionIdentifier.c_str());
284+
fprintf(fout, " return false;\n");
285+
fprintf(fout, " FILE* f = fopen(path, \"wb\");\n");
286+
fprintf(fout, " if ( !f )\n");
287+
fprintf(fout, " return false;\n");
288+
fprintf(fout, " size_t write_size = fwrite(%s_file.buffer, 1, %s_file.size, f);\n", functionIdentifier.c_str(), functionIdentifier.c_str());
289+
fprintf(fout, " fclose(f);\n");
290+
fprintf(fout, " if ( write_size != %s_file.size )\n", functionIdentifier.c_str());
291+
fprintf(fout, " return false;\n");
292+
fprintf(fout, " return true;\n");
293+
fprintf(fout, "}\n");
294+
fprintf(fout, "\n");
295+
fprintf(fout, "inline void %s_init()\n", functionIdentifier.c_str());
296+
fprintf(fout, "{\n");
297+
fprintf(fout, " // remember we already initialized\n");
298+
fprintf(fout, " if ( %s_initialized )\n", functionIdentifier.c_str());
299+
fprintf(fout, " return;\n");
300+
fprintf(fout, " %s_initialized = true;\n", functionIdentifier.c_str());
301+
fprintf(fout, "\n");
302+
fprintf(fout, " // initialize\n");
303+
fprintf(fout, " %s* file = &%s_file;\n", mContext.baseClass.c_str(), functionIdentifier.c_str());
304+
fprintf(fout, " file->size = %uULL;\n", fileSize);
305+
fprintf(fout, " file->file_name = \"%s\";\n", getFileClassFileName().c_str());
306+
fprintf(fout, " file->file_path = \"%s\";\n", getFileClassFilePath().c_str());
307+
fprintf(fout, " file->buffer = NULL;\n");
308+
fprintf(fout, " file->load = %s_load;\n", functionIdentifier.c_str());
309+
fprintf(fout, " file->unload = %s_free;\n", functionIdentifier.c_str());
310+
fprintf(fout, " file->save = %s_save;\n", functionIdentifier.c_str());
311+
fprintf(fout, "}\n");
312+
fprintf(fout, "\n");
313+
fprintf(fout, "%s* %s(void)\n", mContext.baseClass.c_str(), getGetterFunctionName().c_str());
314+
fprintf(fout, "{\n");
315+
fprintf(fout, " %s_init();\n", functionIdentifier.c_str());
316+
fprintf(fout, " return &%s_file;\n", functionIdentifier.c_str());
317+
fprintf(fout, "}\n");
318+
319+
if ( mContext.registerFiles )
320+
{
321+
std::string fileManagerTemplate = getFileManagerRegistrationTemplate();
322+
fprintf(fout, "%s", fileManagerTemplate.c_str());
323+
}
324+
325+
fclose(input);
326+
fclose(fout);
327+
328+
return true;
329+
}
330+
165331
}; //bin2cpp

src/bin2cpp/StringGenerator.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ namespace bin2cpp
4040
virtual ~StringGenerator();
4141
virtual const char * getName() const;
4242
virtual bool createCppSourceFile(const char * cpp_file_path);
43+
virtual bool createCSourceFile(const char* file_path);
4344
};
4445

4546
}; //bin2cpp

0 commit comments

Comments
 (0)