Skip to content

Commit 2253490

Browse files
committed
Created a valid implementation of IGenerator::createCHeaderFile() in BAseGenrator and a valid implementation of IGenerator::createCSourceFile() in SegmentGenerator.
1 parent b2c1416 commit 2253490

File tree

4 files changed

+286
-4
lines changed

4 files changed

+286
-4
lines changed

src/bin2cpp/BaseGenerator.cpp

Lines changed: 125 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,29 +61,68 @@ namespace bin2cpp
6161

6262
std::string BaseGenerator::getGetterFunctionName()
6363
{
64+
65+
std::string getter;
66+
switch ( mContext.code )
67+
{
68+
default:
69+
case CODE_GENERATION_CPP:
70+
{
6471
//Uppercase function identifier
6572
std::string functionIdentifier = ra::strings::CapitalizeFirstCharacter(mContext.functionIdentifier);
6673

67-
std::string getter;
6874
getter.append("get");
6975
getter.append(functionIdentifier);
7076
getter.append("File");
77+
}
78+
break;
79+
case CODE_GENERATION_C:
80+
{
81+
//Uppercase function identifier
82+
std::string functionIdentifier = ra::strings::Lowercase(mContext.functionIdentifier);
83+
84+
getter.append("bin2c_get_file_");
85+
getter.append(functionIdentifier);
86+
}
87+
break;
88+
};
89+
7190
return getter;
7291
}
7392

7493
std::string BaseGenerator::getHeaderFilePath(const char * cpp_file_path)
7594
{
7695
//Build header file path
7796
std::string headerPath = cpp_file_path;
97+
switch ( mContext.code )
98+
{
99+
default:
100+
case CODE_GENERATION_CPP:
78101
ra::strings::Replace(headerPath, ".cpp", ".h");
102+
break;
103+
case CODE_GENERATION_C:
104+
ra::strings::Replace(headerPath, ".c", ".h");
105+
break;
106+
};
107+
79108
return headerPath;
80109
}
81110

82111
std::string BaseGenerator::getCppFilePath(const char * header_file_path)
83112
{
84113
//Build header file path
85114
std::string cppPath = header_file_path;
115+
switch ( mContext.code )
116+
{
117+
default:
118+
case CODE_GENERATION_CPP:
86119
ra::strings::Replace(cppPath, ".cpp", ".h");
120+
break;
121+
case CODE_GENERATION_C:
122+
ra::strings::Replace(cppPath, ".c", ".h");
123+
break;
124+
};
125+
87126
return cppPath;
88127
}
89128

@@ -225,6 +264,50 @@ namespace bin2cpp
225264
return output;
226265
}
227266

267+
std::string BaseGenerator::getFileClassFileName()
268+
{
269+
std::string output;
270+
271+
std::string inputFileName = ra::filesystem::GetFilename(mContext.inputFilePath.c_str());
272+
273+
//return default implementation
274+
output += inputFileName;
275+
return output;
276+
}
277+
278+
std::string BaseGenerator::getFileClassFilePath()
279+
{
280+
std::string output;
281+
282+
//convert mReportedFilePath string to c++
283+
std::string path = mContext.reportedFilePath;
284+
#ifdef _WIN32
285+
//escape backslash characters for c++
286+
static const std::string BACKSLASH = "\\";
287+
static const std::string BACKSLASH_ESCAPED = "\\\\";
288+
ra::strings::Replace(path, BACKSLASH, BACKSLASH_ESCAPED);
289+
#endif
290+
291+
//is there a reported path specified ?
292+
const char * reported_path = mContext.reportedFilePath.c_str();
293+
if (reported_path != NULL && reported_path[0] != '\0')
294+
{
295+
output += path;
296+
return output;
297+
}
298+
else
299+
{
300+
//if reported path is not specified ?
301+
//report the same as getFileName()
302+
output = getFileClassFileName();
303+
return output;
304+
}
305+
306+
//return default implementation
307+
output += path;
308+
return output;
309+
}
310+
228311
bool BaseGenerator::createCppHeaderFile(const char * header_file_path)
229312
{
230313
FILE * header = fopen(header_file_path, "w");
@@ -322,8 +405,47 @@ namespace bin2cpp
322405

323406
bool BaseGenerator::createCHeaderFile(const char* file_path)
324407
{
325-
// not supported yet
326-
return false;
408+
FILE* header = fopen(file_path, "w");
409+
if ( !header )
410+
return false;
411+
412+
//define macro guard matching the filename
413+
std::string macroGuard = getCppIncludeGuardMacroName(file_path);
414+
415+
std::string classMacroGuardPrefix = getClassMacroGuardPrefix();
416+
std::string fileHeader = getHeaderTemplate();
417+
418+
fprintf(header, "%s", fileHeader.c_str());
419+
fprintf(header, "#ifndef %s\n", macroGuard.c_str());
420+
fprintf(header, "#define %s\n", macroGuard.c_str());
421+
fprintf(header, "\n");
422+
fprintf(header, "#include <stddef.h>\n");
423+
fprintf(header, "#include <stdbool.h>\n");
424+
fprintf(header, "\n");
425+
fprintf(header, "#ifndef %s_EMBEDDEDFILE_STRUCT\n", classMacroGuardPrefix.c_str());
426+
fprintf(header, "#define %s_EMBEDDEDFILE_STRUCT\n", classMacroGuardPrefix.c_str());
427+
fprintf(header, "typedef struct %s %s;\n", mContext.baseClass.c_str(), mContext.baseClass.c_str());
428+
fprintf(header, "typedef bool(*bin2c_load_func)();\n");
429+
fprintf(header, "typedef void(*bin2c_free_func)();\n");
430+
fprintf(header, "typedef bool(*bin2c_save_func)(const char*);\n");
431+
fprintf(header, "typedef struct %s\n", mContext.baseClass.c_str());
432+
fprintf(header, "{\n");
433+
fprintf(header, " size_t size;\n");
434+
fprintf(header, " const char* file_name;\n");
435+
fprintf(header, " const char* file_path;\n");
436+
fprintf(header, " unsigned char* buffer;\n");
437+
fprintf(header, " bin2c_load_func load;\n");
438+
fprintf(header, " bin2c_free_func unload;\n");
439+
fprintf(header, " bin2c_save_func save;\n");
440+
fprintf(header, "} %s;\n", mContext.baseClass.c_str());
441+
fprintf(header, "#endif //%s_EMBEDDEDFILE_STRUCT\n", classMacroGuardPrefix.c_str());
442+
fprintf(header, "%s* %s();\n", mContext.baseClass.c_str(), getGetterFunctionName().c_str());
443+
fprintf(header, "\n");
444+
fprintf(header, "#endif //%s\n", macroGuard.c_str());
445+
446+
fclose(header);
447+
448+
return true;
327449
}
328450

329451
bool BaseGenerator::createCSourceFile(const char* file_path)

src/bin2cpp/BaseGenerator.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ namespace bin2cpp
6262
virtual std::string getClassMacroGuardPrefix();
6363
virtual std::string getImplOfGetFileName();
6464
virtual std::string getImplOfGetFilePath();
65+
virtual std::string getFileClassFileName();
66+
virtual std::string getFileClassFilePath();
6567

6668
//attributes
6769
Context mContext;

src/bin2cpp/SegmentGenerator.cpp

Lines changed: 158 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ namespace bin2cpp
6161
std::string headerPath = getHeaderFilePath(cpp_file_path);
6262
std::string cppPath = cpp_file_path;
6363

64-
//create cpp file
64+
//create cpp source file
6565
FILE * cpp = fopen(cppPath.c_str(), "w");
6666
if (!cpp)
6767
{
@@ -160,4 +160,161 @@ namespace bin2cpp
160160
return true;
161161
}
162162

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

src/bin2cpp/SegmentGenerator.h

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

4647
}; //bin2cpp

0 commit comments

Comments
 (0)