@@ -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
0 commit comments