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