From 8b1d3b864a3687700989c142abf78a30ae2f45fe Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Thu, 22 May 2025 21:30:52 -0400 Subject: [PATCH 01/26] Implemented ITemplateVariableLookup and TemplateProcessor classes for processing code generation from templates. --- src/bin2cpp/CMakeLists.txt | 3 + src/bin2cpp/ITemplateVariableLookup.h | 50 +++++++ src/bin2cpp/TemplateProcessor.cpp | 133 ++++++++++++++++++ src/bin2cpp/TemplateProcessor.h | 65 +++++++++ test/bin2cpp_unittest/CMakeLists.txt | 8 ++ .../TestTemplateProcessor.cpp | 115 +++++++++++++++ test/bin2cpp_unittest/TestTemplateProcessor.h | 37 +++++ 7 files changed, 411 insertions(+) create mode 100644 src/bin2cpp/ITemplateVariableLookup.h create mode 100644 src/bin2cpp/TemplateProcessor.cpp create mode 100644 src/bin2cpp/TemplateProcessor.h create mode 100644 test/bin2cpp_unittest/TestTemplateProcessor.cpp create mode 100644 test/bin2cpp_unittest/TestTemplateProcessor.h diff --git a/src/bin2cpp/CMakeLists.txt b/src/bin2cpp/CMakeLists.txt index 326f03b..c21f1b5 100644 --- a/src/bin2cpp/CMakeLists.txt +++ b/src/bin2cpp/CMakeLists.txt @@ -22,6 +22,7 @@ add_executable(bin2cpp enums.h IGenerator.h INameProvider.h + ITemplateVariableLookup.h LegacyNameProvider.cpp LegacyNameProvider.h main.cpp @@ -31,6 +32,8 @@ add_executable(bin2cpp SegmentGenerator.h StringGenerator.cpp StringGenerator.h + TemplateProcessor.cpp + TemplateProcessor.h types.h wildcard.cpp wildcard.h diff --git a/src/bin2cpp/ITemplateVariableLookup.h b/src/bin2cpp/ITemplateVariableLookup.h new file mode 100644 index 0000000..760e9ba --- /dev/null +++ b/src/bin2cpp/ITemplateVariableLookup.h @@ -0,0 +1,50 @@ +/********************************************************************************** + * MIT License + * + * Copyright (c) 2018 Antoine Beauchamp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *********************************************************************************/ + +#ifndef ITEMPLATE_VARIABLE_LOOKUP_H +#define ITEMPLATE_VARIABLE_LOOKUP_H + +#include + +namespace bin2cpp +{ + + class ITemplateVariableLookup + { + public: + virtual ~ITemplateVariableLookup() + {} + + /// + ///Look up the value for a given template variable name. + /// + ///The name of the template variable. + ///Returns the value of the template variable. Returns an empty string if unknown. + virtual std::string lookupTemplateVariable(const std::string& name) = 0; + + }; + +}; //bin2cpp + +#endif //ITEMPLATE_VARIABLE_LOOKUP_H diff --git a/src/bin2cpp/TemplateProcessor.cpp b/src/bin2cpp/TemplateProcessor.cpp new file mode 100644 index 0000000..57053f8 --- /dev/null +++ b/src/bin2cpp/TemplateProcessor.cpp @@ -0,0 +1,133 @@ +/********************************************************************************** + * MIT License + * + * Copyright (c) 2018 Antoine Beauchamp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *********************************************************************************/ + +#include "TemplateProcessor.h" +#include +#include + +namespace bin2cpp +{ + TemplateProcessor::TemplateProcessor() + { + reset(); + } + + TemplateProcessor::~TemplateProcessor() + { + } + + void TemplateProcessor::reset() + { + mTemplateText = NULL; + mVariableLookup = NULL; + } + + void TemplateProcessor::setTemplateText(const std::string* value) + { + mTemplateText = value; + } + + const std::string* TemplateProcessor::getTemplateText() const + { + return mTemplateText; + } + + void TemplateProcessor::setTemplateVariableLookup(ITemplateVariableLookup* lookup) + { + mVariableLookup = lookup; + } + + ITemplateVariableLookup* TemplateProcessor::getTemplateVariableLookup() const + { + return mVariableLookup; + } + + void TemplateProcessor::writeString(std::string& output) + { + std::ostringstream output_stream; + std::set recursion_history; + processTemplate(output_stream, *mTemplateText, recursion_history); + output = output_stream.str(); + } + + bool TemplateProcessor::writeFile(const std::string& file_path) + { + std::ofstream output_file(file_path); + if ( !output_file.is_open() ) return false; + + std::set recursion_history; + processTemplate(output_file, *mTemplateText, recursion_history); + return true; + } + + //------------------------------- + //protected methods + //------------------------------- + + void TemplateProcessor::processTemplate(std::ostream& output_stream, const std::string& value, std::set& recursion_history) + { + size_t pos = 0; + while ( pos < value.size() ) + { + if ( value[pos] == '$' && pos + 1 < value.size() && value[pos + 1] == '{' ) + { + size_t end_pos = value.find('}', pos); + if ( end_pos != std::string::npos ) + { + std::string variable_name = value.substr(pos + 2, end_pos - pos - 2); + + // Detect actual circular dependency within same recursion path + if ( recursion_history.find(variable_name) != recursion_history.end() ) + { + pos = end_pos + 1; + continue; + } + + // Do the variable expansion + std::string expanded_value = mVariableLookup ? mVariableLookup->lookupTemplateVariable(variable_name) : ""; + + // Add variable to recursion history before expanding + recursion_history.insert(variable_name); + + // Recursively process expanded value with updated recursion tracking + processTemplate(output_stream, expanded_value, recursion_history); + + // Remove variable from recursion history after recursion returns + recursion_history.erase(variable_name); + + pos = end_pos + 1; + } + else + { + output_stream.put(value[pos++]); + } + } + else + { + output_stream.put(value[pos++]); + } + } + } + +}; //bin2cpp \ No newline at end of file diff --git a/src/bin2cpp/TemplateProcessor.h b/src/bin2cpp/TemplateProcessor.h new file mode 100644 index 0000000..24d88ba --- /dev/null +++ b/src/bin2cpp/TemplateProcessor.h @@ -0,0 +1,65 @@ +/********************************************************************************** + * MIT License + * + * Copyright (c) 2018 Antoine Beauchamp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *********************************************************************************/ + +#ifndef TEMPLATEPROCESSOR_H +#define TEMPLATEPROCESSOR_H + +#include +#include +#include "ITemplateVariableLookup.h" + +namespace bin2cpp +{ + + /// + ///A class for processing a template containing template markers variables + ///and replace those to their actual values. + /// + class TemplateProcessor + { + public: + TemplateProcessor(); + virtual ~TemplateProcessor(); + virtual void reset(); + + void setTemplateText(const std::string* value); + const std::string* getTemplateText() const; + + void setTemplateVariableLookup(ITemplateVariableLookup* lookup); + ITemplateVariableLookup* getTemplateVariableLookup() const; + + virtual void writeString(std::string& output); + virtual bool writeFile(const std::string& file_path); + + protected: + virtual void processTemplate(std::ostream& output_stream, const std::string& value, std::set& recursion_history); + + //attributes + const std::string* mTemplateText; + ITemplateVariableLookup* mVariableLookup; + }; + +}; //bin2cpp + +#endif //TEMPLATEPROCESSOR_H diff --git a/test/bin2cpp_unittest/CMakeLists.txt b/test/bin2cpp_unittest/CMakeLists.txt index ac6c4ba..c682746 100644 --- a/test/bin2cpp_unittest/CMakeLists.txt +++ b/test/bin2cpp_unittest/CMakeLists.txt @@ -285,6 +285,9 @@ source_group("External Files" FILES ${CMAKE_SOURCE_DIR}/src/bin2cpp/common.h ${CMAKE_SOURCE_DIR}/src/bin2cpp/wildcard.cpp ${CMAKE_SOURCE_DIR}/src/bin2cpp/wildcard.h + ${CMAKE_SOURCE_DIR}/src/bin2cpp/ITemplateVariableLookup.h + ${CMAKE_SOURCE_DIR}/src/bin2cpp/TemplateProcessor.cpp + ${CMAKE_SOURCE_DIR}/src/bin2cpp/TemplateProcessor.h ) # Ensure source files are properly recognized as generated @@ -297,6 +300,9 @@ add_executable(bin2cpp_unittest ${CMAKE_SOURCE_DIR}/src/bin2cpp/common.h ${CMAKE_SOURCE_DIR}/src/bin2cpp/wildcard.cpp ${CMAKE_SOURCE_DIR}/src/bin2cpp/wildcard.h + ${CMAKE_SOURCE_DIR}/src/bin2cpp/ITemplateVariableLookup.h + ${CMAKE_SOURCE_DIR}/src/bin2cpp/TemplateProcessor.cpp + ${CMAKE_SOURCE_DIR}/src/bin2cpp/TemplateProcessor.h application.cpp application.h CMakeLists.txt @@ -310,6 +316,8 @@ add_executable(bin2cpp_unittest TestCommon.h TestExtraction.cpp TestExtraction.h + TestTemplateProcessor.cpp + TestTemplateProcessor.h TestWildcard.cpp TestWildcard.h ${GENERATED_TEST_FILES} diff --git a/test/bin2cpp_unittest/TestTemplateProcessor.cpp b/test/bin2cpp_unittest/TestTemplateProcessor.cpp new file mode 100644 index 0000000..4bd56fb --- /dev/null +++ b/test/bin2cpp_unittest/TestTemplateProcessor.cpp @@ -0,0 +1,115 @@ +/********************************************************************************** + * MIT License + * + * Copyright (c) 2018 Antoine Beauchamp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *********************************************************************************/ + +#include "TestTemplateProcessor.h" + +#include "TemplateProcessor.h" + +#include "rapidassist/testing.h" +#include "rapidassist/filesystem.h" +#include "rapidassist/testing.h" +#include "rapidassist/user.h" + + // Sample variable lookup implementation +class SampleVariableLookup : public bin2cpp::ITemplateVariableLookup +{ +public: + std::string lookupTemplateVariable(const std::string& name) override + { + if ( name == "first-name" ) return "Luke"; + if ( name == "last-name" ) return "Skywalker"; + if ( name == "full-name" ) return "${first-name} ${last-name}"; + if ( name == "age" ) return "53"; + if ( name == "job" ) return "Jedi Knight"; + if ( name == "children" ) return "2"; + if ( name == "foo" ) return "foo is ${bar}"; + if ( name == "bar" ) return "bar is ${baz}"; + if ( name == "baz" ) return "baz is ${foo}"; + return ""; + } +}; + +void TestTemplateProcessor::SetUp() +{ +} + +void TestTemplateProcessor::TearDown() +{ +} + +TEST_F(TestTemplateProcessor, testBaseSingleVariable) +{ + bin2cpp::TemplateProcessor processor; + SampleVariableLookup lookup; + processor.setTemplateVariableLookup(&lookup); + + const std::string actual_input = "I am ${age} years old."; + const std::string expected_output = "I am 53 years old."; + processor.setTemplateText(&actual_input); + std::string actual_output; + processor.writeString(actual_output); + ASSERT_EQ(actual_output, expected_output); +} + +TEST_F(TestTemplateProcessor, testRecursive) +{ + bin2cpp::TemplateProcessor processor; + SampleVariableLookup lookup; + processor.setTemplateVariableLookup(&lookup); + + const std::string actual_input = "My name is ${full-name}. I work as a ${job} now. I have ${children} children."; + const std::string expected_output = "My name is Luke Skywalker. I work as a Jedi Knight now. I have 2 children."; + processor.setTemplateText(&actual_input); + std::string actual_output; + processor.writeString(actual_output); + ASSERT_EQ(actual_output, expected_output); +} + +TEST_F(TestTemplateProcessor, testMultipleTwinMarkers) +{ + bin2cpp::TemplateProcessor processor; + SampleVariableLookup lookup; + processor.setTemplateVariableLookup(&lookup); + + const std::string actual_input = "My name is ${first-name} but everyone calls me Lucky-${first-name}."; + const std::string expected_output = "My name is Luke but everyone calls me Lucky-Luke."; + processor.setTemplateText(&actual_input); + std::string actual_output; + processor.writeString(actual_output); + ASSERT_EQ(actual_output, expected_output); +} + +TEST_F(TestTemplateProcessor, testCircularReference) +{ + bin2cpp::TemplateProcessor processor; + SampleVariableLookup lookup; + processor.setTemplateVariableLookup(&lookup); + + const std::string actual_input = "${foo}"; + const std::string expected_output = "foo is bar is baz is "; + processor.setTemplateText(&actual_input); + std::string actual_output; + processor.writeString(actual_output); + ASSERT_EQ(actual_output, expected_output); +} diff --git a/test/bin2cpp_unittest/TestTemplateProcessor.h b/test/bin2cpp_unittest/TestTemplateProcessor.h new file mode 100644 index 0000000..a74fb27 --- /dev/null +++ b/test/bin2cpp_unittest/TestTemplateProcessor.h @@ -0,0 +1,37 @@ +/********************************************************************************** + * MIT License + * + * Copyright (c) 2018 Antoine Beauchamp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + *********************************************************************************/ + +#ifndef TESTTEMPLATEPROCESSOR_H +#define TESTTEMPLATEPROCESSOR_H + +#include + +class TestTemplateProcessor : public ::testing::Test +{ +public: + virtual void SetUp(); + virtual void TearDown(); +}; + +#endif //TESTTEMPLATEPROCESSOR_H From 4bbd685e9aad6f2bdf571bdbdb796d80879ca4df Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Thu, 22 May 2025 21:39:07 -0400 Subject: [PATCH 02/26] Small improvements --- src/bin2cpp/TemplateProcessor.cpp | 12 ++++++++++-- src/bin2cpp/TemplateProcessor.h | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/bin2cpp/TemplateProcessor.cpp b/src/bin2cpp/TemplateProcessor.cpp index 57053f8..e63ed0a 100644 --- a/src/bin2cpp/TemplateProcessor.cpp +++ b/src/bin2cpp/TemplateProcessor.cpp @@ -63,6 +63,12 @@ namespace bin2cpp return mVariableLookup; } + void TemplateProcessor::writeStream(std::ostream& stream) + { + std::set recursion_history; + processTemplate(stream, *mTemplateText, recursion_history); + } + void TemplateProcessor::writeString(std::string& output) { std::ostringstream output_stream; @@ -120,12 +126,14 @@ namespace bin2cpp } else { - output_stream.put(value[pos++]); + output_stream.put(value[pos]); + pos++; } } else { - output_stream.put(value[pos++]); + output_stream.put(value[pos]); + pos++; } } } diff --git a/src/bin2cpp/TemplateProcessor.h b/src/bin2cpp/TemplateProcessor.h index 24d88ba..4ea8165 100644 --- a/src/bin2cpp/TemplateProcessor.h +++ b/src/bin2cpp/TemplateProcessor.h @@ -49,6 +49,7 @@ namespace bin2cpp void setTemplateVariableLookup(ITemplateVariableLookup* lookup); ITemplateVariableLookup* getTemplateVariableLookup() const; + virtual void TemplateProcessor::writeStream(std::ostream& stream); virtual void writeString(std::string& output); virtual bool writeFile(const std::string& file_path); From 6b02ac3c442e1b329075f48316b64030bd252eec Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Fri, 23 May 2025 16:22:11 -0400 Subject: [PATCH 03/26] Made optimization to TemplateProcessor --- src/bin2cpp/TemplateProcessor.cpp | 10 ++++-- src/bin2cpp/TemplateProcessor.h | 3 +- .../TestTemplateProcessor.cpp | 32 +++++++++++++++++-- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/bin2cpp/TemplateProcessor.cpp b/src/bin2cpp/TemplateProcessor.cpp index e63ed0a..96d9dee 100644 --- a/src/bin2cpp/TemplateProcessor.cpp +++ b/src/bin2cpp/TemplateProcessor.cpp @@ -33,6 +33,12 @@ namespace bin2cpp reset(); } + TemplateProcessor::TemplateProcessor(const std::string* value) + { + reset(); + setTemplateText(value); + } + TemplateProcessor::~TemplateProcessor() { } @@ -63,10 +69,10 @@ namespace bin2cpp return mVariableLookup; } - void TemplateProcessor::writeStream(std::ostream& stream) + void TemplateProcessor::writeStream(std::ostream& output_stream) { std::set recursion_history; - processTemplate(stream, *mTemplateText, recursion_history); + processTemplate(output_stream, *mTemplateText, recursion_history); } void TemplateProcessor::writeString(std::string& output) diff --git a/src/bin2cpp/TemplateProcessor.h b/src/bin2cpp/TemplateProcessor.h index 4ea8165..32e1d5d 100644 --- a/src/bin2cpp/TemplateProcessor.h +++ b/src/bin2cpp/TemplateProcessor.h @@ -40,6 +40,7 @@ namespace bin2cpp { public: TemplateProcessor(); + TemplateProcessor(const std::string* value); virtual ~TemplateProcessor(); virtual void reset(); @@ -49,7 +50,7 @@ namespace bin2cpp void setTemplateVariableLookup(ITemplateVariableLookup* lookup); ITemplateVariableLookup* getTemplateVariableLookup() const; - virtual void TemplateProcessor::writeStream(std::ostream& stream); + virtual void writeStream(std::ostream& output_stream); virtual void writeString(std::string& output); virtual bool writeFile(const std::string& file_path); diff --git a/test/bin2cpp_unittest/TestTemplateProcessor.cpp b/test/bin2cpp_unittest/TestTemplateProcessor.cpp index 4bd56fb..d7368de 100644 --- a/test/bin2cpp_unittest/TestTemplateProcessor.cpp +++ b/test/bin2cpp_unittest/TestTemplateProcessor.cpp @@ -72,14 +72,42 @@ TEST_F(TestTemplateProcessor, testBaseSingleVariable) ASSERT_EQ(actual_output, expected_output); } +TEST_F(TestTemplateProcessor, testUnknownVariable) +{ + bin2cpp::TemplateProcessor processor; + SampleVariableLookup lookup; + processor.setTemplateVariableLookup(&lookup); + + const std::string actual_input = "My ${father} tried to kill me."; + const std::string expected_output = "My tried to kill me."; + processor.setTemplateText(&actual_input); + std::string actual_output; + processor.writeString(actual_output); + ASSERT_EQ(actual_output, expected_output); +} + +TEST_F(TestTemplateProcessor, testCaseSensitive) +{ + bin2cpp::TemplateProcessor processor; + SampleVariableLookup lookup; + processor.setTemplateVariableLookup(&lookup); + + const std::string actual_input = "The variable '${children}' should expand to a value but '${Children}' should be empty."; + const std::string expected_output = "The variable '2' should expand to a value but '' should be empty."; + processor.setTemplateText(&actual_input); + std::string actual_output; + processor.writeString(actual_output); + ASSERT_EQ(actual_output, expected_output); +} + TEST_F(TestTemplateProcessor, testRecursive) { bin2cpp::TemplateProcessor processor; SampleVariableLookup lookup; processor.setTemplateVariableLookup(&lookup); - const std::string actual_input = "My name is ${full-name}. I work as a ${job} now. I have ${children} children."; - const std::string expected_output = "My name is Luke Skywalker. I work as a Jedi Knight now. I have 2 children."; + const std::string actual_input = "My name is ${full-name}. I work as a ${job} now."; + const std::string expected_output = "My name is Luke Skywalker. I work as a Jedi Knight now."; processor.setTemplateText(&actual_input); std::string actual_output; processor.writeString(actual_output); From 59a4d9900ea99366872e1908c77d4ad62b71c313 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Fri, 23 May 2025 16:28:50 -0400 Subject: [PATCH 04/26] Modified IGenerator to implement ITemplateVariableLookup. Modified BaseGenerator to implement lookupTemplateVariable() and uses C/C++ header files template to generate output header files with the help of the TemplateProcessor. --- src/bin2cpp/BaseGenerator.cpp | 248 +++++++++++++++++++++++----------- src/bin2cpp/BaseGenerator.h | 7 + src/bin2cpp/IGenerator.h | 5 +- 3 files changed, 178 insertions(+), 82 deletions(-) diff --git a/src/bin2cpp/BaseGenerator.cpp b/src/bin2cpp/BaseGenerator.cpp index 980fefa..7fb0366 100755 --- a/src/bin2cpp/BaseGenerator.cpp +++ b/src/bin2cpp/BaseGenerator.cpp @@ -23,6 +23,7 @@ *********************************************************************************/ #include "BaseGenerator.h" +#include "TemplateProcessor.h" #include #include #include @@ -55,6 +56,50 @@ namespace bin2cpp return mContext; } + std::string BaseGenerator::lookupTemplateVariable(const std::string& name) + { + if ( name == "bin2cpp_output_file_macro_guard" ) return getCppIncludeGuardMacroName(mContext.headerFilename); + if ( name == "bin2cpp_embedded_file_class_macro_guard" ) return getClassMacroGuardPrefix(); + if ( name == "bin2cpp_output_file_header" ) return getHeaderTemplate(); + if ( name == "bin2cpp_baseclass" ) return mContext.baseClass; + if ( name == "bin2cpp_classname" ) return getClassName(); + if ( name == "bin2cpp_function_identifier" ) return mContext.functionIdentifier; + if ( name == "bin2cpp_function_identifier_lowercase" ) return ra::strings::Lowercase(mContext.functionIdentifier); + if ( name == "bin2cpp_classname" ) return getClassName(); + if ( name == "bin2cpp_namespace" ) return mContext.codeNamespace; + if ( name == "bin2cpp_cpp_getter_function_name" ) return getGetterFunctionName(); + if ( name == "bin2cpp_insert_input_file_as_code" ) return getInputFileDataAsCode(); + if ( name == "bin2cpp_cpp_header_include_path" ) return getCppHeaderIncludePath(); + if ( name == "bin2cpp_cpp_get_file_name_impl" ) return getImplOfGetFileName(); + if ( name == "bin2cpp_cpp_get_file_path_impl" ) return getImplOfGetFilePath(); + if ( name == "bin2cpp_get_file_obj_file_name" ) return getFileClassFileName(); + if ( name == "bin2cpp_get_file_obj_file_path" ) return getFileClassFilePath(); + if ( name == "bin2cpp_cpp_get_save_method_impl" ) return getSaveMethodTemplate(); + if ( name == "bin2cpp_cpp_get_file_manager_registration_impl" && mContext.registerFiles ) return getCppFileManagerRegistrationImplementationTemplate(); + if ( name == "bin2cpp_c_file_manager_registration_predeclaration" && mContext.registerFiles ) return getCFileManagerRegistrationPredeclarationTemplate(); + if ( name == "bin2cpp_c_file_manager_registration_implementation" && mContext.registerFiles ) return getCFileManagerRegistrationImplementationTemplate(); + + //if ( name == "bin2cpp_c_registration_post_init_impl" && mContext.registerFiles ) + //{ + // std::string output; + // output += " \n"; + // output += " // register when loaded if static initialisation does not work\n"; + // output += " ${bin2cpp_classname}_filemanager_register_file(file);\n"; + // return output; + //} + + if ( name == "bin2cpp_input_file_size" ) + { + //determine file properties + uint32_t file_size = ra::filesystem::GetFileSize(mContext.inputFilePath.c_str()); + std::string file_size_str = ra::strings::ToString(file_size); + return file_size_str; + } + + // Unknown name + return ""; + } + //------------------------------- //protected methods //------------------------------- @@ -179,6 +224,7 @@ namespace bin2cpp output << " typedef const " << mContext.baseClass << " & (*t_func)();\n"; output << " extern bool RegisterFile(t_func iFunctionPointer);\n"; output << " static bool k" << className << "Registered = " << mContext.codeNamespace << "::RegisterFile(&" << getGetterFunctionName() << ");\n"; + output << " \n"; return output; } @@ -344,47 +390,95 @@ namespace bin2cpp return output; } - bool BaseGenerator::createCppHeaderFile(const char * header_file_path) + std::string BaseGenerator::getCppHeaderIncludePath() { - FILE * header = fopen(header_file_path, "w"); - if (!header) - return false; + return mContext.headerFilename; + } + + std::string BaseGenerator::getInputFileDataAsCode() + { + std::string output; - //define macro guard matching the filename - std::string macroGuard = getCppIncludeGuardMacroName(header_file_path); - - std::string classMacroGuardPrefix = getClassMacroGuardPrefix(); - std::string fileHeader = getHeaderTemplate(); - - fprintf(header, "%s", fileHeader.c_str()); - fprintf(header, "#ifndef %s\n", macroGuard.c_str()); - fprintf(header, "#define %s\n", macroGuard.c_str()); - fprintf(header, "\n"); - fprintf(header, "#include \n"); - fprintf(header, "\n"); - fprintf(header, "namespace %s\n", mContext.codeNamespace.c_str()); - fprintf(header, "{\n"); - fprintf(header, " #ifndef %s_EMBEDDEDFILE_CLASS\n", classMacroGuardPrefix.c_str()); - fprintf(header, " #define %s_EMBEDDEDFILE_CLASS\n", classMacroGuardPrefix.c_str()); - fprintf(header, " class %s\n", mContext.baseClass.c_str()); - fprintf(header, " {\n"); - fprintf(header, " public:\n"); - fprintf(header, " virtual size_t getSize() const = 0;\n"); - fprintf(header, " /* DEPRECATED */ virtual inline const char * getFilename() const { return getFileName(); }\n"); - fprintf(header, " virtual const char * getFileName() const = 0;\n"); - fprintf(header, " virtual const char * getFilePath() const = 0;\n"); - fprintf(header, " virtual const char * getBuffer() const = 0;\n"); - fprintf(header, " virtual bool save(const char * filename) const = 0;\n"); - fprintf(header, " };\n"); - fprintf(header, " #endif //%s_EMBEDDEDFILE_CLASS\n", classMacroGuardPrefix.c_str()); - fprintf(header, " const %s & %s();\n", mContext.baseClass.c_str(), getGetterFunctionName().c_str()); - fprintf(header, "}; //%s\n", mContext.codeNamespace.c_str()); - fprintf(header, "\n"); - fprintf(header, "#endif //%s\n", macroGuard.c_str()); - - fclose(header); + //check if input file exists + FILE* fin = fopen(mContext.inputFilePath.c_str(), "rb"); + if ( !fin ) + return ""; - return true; + uint64_t fileSize = ra::filesystem::GetFileSize64(mContext.inputFilePath.c_str()); + size_t chunkCount = fileSize / mContext.chunkSize; + if ( fileSize % mContext.chunkSize > 0 ) + chunkCount++; + + //create buffer for each chunks from input buffer + int numLinePrinted = 0; + size_t chunkIndex = 0; + unsigned char* buffer = new unsigned char[mContext.chunkSize]; + while ( !feof(fin) ) + { + //read a chunk of the file + size_t readSize = fread(buffer, 1, mContext.chunkSize, fin); + + bool isLastChunk = (chunkIndex == (chunkCount - 1)); + + if ( readSize > 0 ) + { + //output + std::string encoded_chunk = getInputFileChunkAsCode(buffer, readSize, chunkIndex, chunkCount, isLastChunk); + output += encoded_chunk; + + numLinePrinted++; + chunkIndex++; + } + + } + delete[] buffer; + buffer = NULL; + + fclose(fin); + + return output; + } + + std::string BaseGenerator::getInputFileChunkAsCode(const unsigned char* buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk) + { + return ""; + } + + bool BaseGenerator::createCppHeaderFile(const char * header_file_path) + { + const std::string text = "" + "${bin2cpp_output_file_header}" + "#ifndef ${bin2cpp_output_file_macro_guard}\n" + "#define ${bin2cpp_output_file_macro_guard}\n" + "\n" + "#include \n" + "\n" + "namespace ${bin2cpp_namespace}\n" + "{\n" + " #ifndef ${bin2cpp_embedded_file_class_macro_guard}_EMBEDDEDFILE_CLASS\n" + " #define ${bin2cpp_embedded_file_class_macro_guard}_EMBEDDEDFILE_CLASS\n" + " class ${bin2cpp_baseclass}\n" + " {\n" + " public:\n" + " virtual size_t getSize() const = 0;\n" + " /* DEPRECATED */ virtual inline const char * getFilename() const { return getFileName(); }\n" + " virtual const char * getFileName() const = 0;\n" + " virtual const char * getFilePath() const = 0;\n" + " virtual const char * getBuffer() const = 0;\n" + " virtual bool save(const char * filename) const = 0;\n" + " };\n" + " #endif //${bin2cpp_embedded_file_class_macro_guard}_EMBEDDEDFILE_CLASS\n" + " const ${bin2cpp_baseclass} & ${bin2cpp_cpp_getter_function_name}();\n" + "}; //${bin2cpp_namespace}\n" + "\n" + "#endif //${bin2cpp_output_file_macro_guard}\n" + ; + + TemplateProcessor processor(&text); + processor.setTemplateVariableLookup(this); + bool write_success = processor.writeFile(header_file_path); + + return write_success; } bool BaseGenerator::printFileContent() @@ -441,48 +535,42 @@ namespace bin2cpp bool BaseGenerator::createCHeaderFile(const char* file_path) { - FILE* header = fopen(file_path, "w"); - if ( !header ) - return false; - - //define macro guard matching the filename - std::string macroGuard = getCppIncludeGuardMacroName(file_path); - - std::string classMacroGuardPrefix = getClassMacroGuardPrefix(); - std::string fileHeader = getHeaderTemplate(); - - fprintf(header, "%s", fileHeader.c_str()); - fprintf(header, "#ifndef %s\n", macroGuard.c_str()); - fprintf(header, "#define %s\n", macroGuard.c_str()); - fprintf(header, "\n"); - fprintf(header, "#include \n"); - fprintf(header, "#include \n"); - fprintf(header, "\n"); - fprintf(header, "#ifndef %s_EMBEDDEDFILE_STRUCT\n", classMacroGuardPrefix.c_str()); - fprintf(header, "#define %s_EMBEDDEDFILE_STRUCT\n", classMacroGuardPrefix.c_str()); - fprintf(header, "typedef struct %s %s;\n", mContext.baseClass.c_str(), mContext.baseClass.c_str()); - fprintf(header, "typedef bool(*%s_load_func)();\n", mContext.codeNamespace.c_str()); - fprintf(header, "typedef void(*%s_free_func)();\n", mContext.codeNamespace.c_str()); - fprintf(header, "typedef bool(*%s_save_func)(const char*);\n", mContext.codeNamespace.c_str()); - fprintf(header, "typedef struct %s\n", mContext.baseClass.c_str()); - fprintf(header, "{\n"); - fprintf(header, " size_t size;\n"); - fprintf(header, " const char* file_name;\n"); - fprintf(header, " const char* file_path;\n"); - fprintf(header, " const unsigned char* buffer;\n"); - fprintf(header, " %s_load_func load;\n", mContext.codeNamespace.c_str()); - fprintf(header, " %s_free_func unload;\n", mContext.codeNamespace.c_str()); - fprintf(header, " %s_save_func save;\n", mContext.codeNamespace.c_str()); - fprintf(header, "} %s;\n", mContext.baseClass.c_str()); - fprintf(header, "typedef %s* %sPtr;\n", mContext.baseClass.c_str(), mContext.baseClass.c_str()); - fprintf(header, "#endif //%s_EMBEDDEDFILE_STRUCT\n", classMacroGuardPrefix.c_str()); - fprintf(header, "%s* %s(void);\n", mContext.baseClass.c_str(), getGetterFunctionName().c_str()); - fprintf(header, "\n"); - fprintf(header, "#endif //%s\n", macroGuard.c_str()); - - fclose(header); - - return true; + const std::string text = "" + "${bin2cpp_output_file_header}" + "#ifndef ${bin2cpp_output_file_macro_guard}\n" + "#define ${bin2cpp_output_file_macro_guard}\n" + "\n" + "#include \n" + "#include \n" + "\n" + "#ifndef ${bin2cpp_embedded_file_class_macro_guard}_EMBEDDEDFILE_STRUCT\n" + "#define ${bin2cpp_embedded_file_class_macro_guard}_EMBEDDEDFILE_STRUCT\n" + "typedef struct ${bin2cpp_baseclass} ${bin2cpp_baseclass};\n" + "typedef bool(*${bin2cpp_namespace}_load_func)();\n" + "typedef void(*${bin2cpp_namespace}_free_func)();\n" + "typedef bool(*${bin2cpp_namespace}_save_func)(const char*);\n" + "typedef struct ${bin2cpp_baseclass}\n" + "{\n" + " size_t size;\n" + " const char* file_name;\n" + " const char* file_path;\n" + " const unsigned char* buffer;\n" + " ${bin2cpp_namespace}_load_func load;\n" + " ${bin2cpp_namespace}_free_func unload;\n" + " ${bin2cpp_namespace}_save_func save;\n" + "} ${bin2cpp_baseclass};\n" + "typedef ${bin2cpp_baseclass}* ${bin2cpp_baseclass}Ptr;\n" + "#endif //${bin2cpp_embedded_file_class_macro_guard}_EMBEDDEDFILE_STRUCT\n" + "${bin2cpp_baseclass}* ${bin2cpp_cpp_getter_function_name}(void);\n" + "\n" + "#endif //${bin2cpp_output_file_macro_guard}\n" + ; + + TemplateProcessor processor(&text); + processor.setTemplateVariableLookup(this); + bool write_success = processor.writeFile(file_path); + + return write_success; } bool BaseGenerator::createCSourceFile(const char* file_path) diff --git a/src/bin2cpp/BaseGenerator.h b/src/bin2cpp/BaseGenerator.h index 31473df..7ccaab2 100644 --- a/src/bin2cpp/BaseGenerator.h +++ b/src/bin2cpp/BaseGenerator.h @@ -26,6 +26,7 @@ #define BASEGENERATOR_H #include "IGenerator.h" +#include namespace bin2cpp { @@ -43,6 +44,9 @@ namespace bin2cpp virtual void setContext(const Context& c); virtual const Context & getContext() const; + //ITemplateVariableLookup methods + virtual std::string lookupTemplateVariable(const std::string& name); + //same header file for all generators virtual bool createCppHeaderFile(const char * header_file_path); virtual bool printFileContent(); @@ -66,6 +70,9 @@ namespace bin2cpp virtual std::string getImplOfGetFilePath(); virtual std::string getFileClassFileName(); virtual std::string getFileClassFilePath(); + virtual std::string getCppHeaderIncludePath(); + virtual std::string getInputFileDataAsCode(); + virtual std::string getInputFileChunkAsCode(const unsigned char * buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk); //attributes Context mContext; diff --git a/src/bin2cpp/IGenerator.h b/src/bin2cpp/IGenerator.h index 5b459cb..da7ca54 100644 --- a/src/bin2cpp/IGenerator.h +++ b/src/bin2cpp/IGenerator.h @@ -27,11 +27,12 @@ #include #include "Context.h" - +#include "ITemplateVariableLookup.h" + namespace bin2cpp { - class IGenerator + class IGenerator : public virtual ITemplateVariableLookup { public: From 6f638d0874740c477d36d21e19ec265e29706847 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Fri, 23 May 2025 16:29:43 -0400 Subject: [PATCH 05/26] Modified ArrayGenerator to uses file templates to generate output C/C++ source files with the help of the TemplateProcessor. --- src/bin2cpp/ArrayGenerator.cpp | 454 ++++++++++++--------------------- src/bin2cpp/ArrayGenerator.h | 1 + 2 files changed, 170 insertions(+), 285 deletions(-) diff --git a/src/bin2cpp/ArrayGenerator.cpp b/src/bin2cpp/ArrayGenerator.cpp index b43bfa2..b428cd1 100644 --- a/src/bin2cpp/ArrayGenerator.cpp +++ b/src/bin2cpp/ArrayGenerator.cpp @@ -23,6 +23,7 @@ *********************************************************************************/ #include "ArrayGenerator.h" +#include "TemplateProcessor.h" #include #include #include @@ -47,147 +48,54 @@ namespace bin2cpp return "array"; } - bool ArrayGenerator::createCppSourceFile(const char * cpp_file_path) + bool ArrayGenerator::createCppSourceFile(const char * file_path) { //check if input file exists - FILE * input = fopen(mContext.inputFilePath.c_str(), "rb"); - if (!input) + if ( !ra::filesystem::FileExists(mContext.inputFilePath.c_str()) ) return false; - //Uppercase function identifier - std::string functionIdentifier = ra::strings::CapitalizeFirstCharacter(getContext().functionIdentifier); - - //Build header and cpp file path - std::string headerPath = getHeaderFilePath(cpp_file_path); - std::string cppPath = cpp_file_path; - - //create cpp file - FILE * cpp = fopen(cppPath.c_str(), "w"); - if (!cpp) - { - fclose(input); - return false; - } - - //determine file properties - uint32_t fileSize = ra::filesystem::GetFileSize(input); - std::string filename = ra::filesystem::GetFilename(mContext.inputFilePath.c_str()); - - //Build class name - std::string className = getClassName(); - - //Build function - std::string getterFunctionName = getGetterFunctionName(); - - //write cpp file heading - fprintf(cpp, "%s", getHeaderTemplate().c_str()); - fprintf(cpp, "#include \"%s\"\n", mContext.headerFilename.c_str() ); - fprintf(cpp, "#include \n"); - fprintf(cpp, "#include //for ofstream\n"); - fprintf(cpp, "namespace %s\n", getContext().codeNamespace.c_str()); - fprintf(cpp, "{\n"); - fprintf(cpp, " class %s : public virtual %s::%s\n", className.c_str(), getContext().codeNamespace.c_str(), getContext().baseClass.c_str()); - fprintf(cpp, " {\n"); - fprintf(cpp, " public:\n"); - fprintf(cpp, " %s() {}\n", className.c_str()); - fprintf(cpp, " virtual ~%s() {}\n", className.c_str()); - fprintf(cpp, " virtual size_t getSize() const { return %u; }\n", fileSize); - fprintf(cpp, " virtual const char * getFileName() const { %s }\n", getImplOfGetFileName().c_str()); - fprintf(cpp, " virtual const char * getFilePath() const { %s }\n", getImplOfGetFilePath().c_str()); - fprintf(cpp, " virtual const char * getBuffer() const\n"); - fprintf(cpp, " {\n"); - fprintf(cpp, " static const unsigned char buffer[] = {\n"); - - //create buffer for each chunks from input buffer - int numLinePrinted = 0; - unsigned char * buffer = new unsigned char[getContext().chunkSize]; - while(!feof(input)) - { - //read a chunk of the file - size_t readSize = fread(buffer, 1, getContext().chunkSize, input); - - bool isLastChunk = !(readSize == getContext().chunkSize); - - if (readSize > 0) - { - if (numLinePrinted > 0) - { - //end previous line - fprintf(cpp, ",\n"); - } - - //output - fprintf(cpp, " %s", ra::code::cpp::ToCppCharactersArray(buffer, readSize).c_str()); - numLinePrinted++; - } - - //end the array. all the file content is printed - if (isLastChunk) - { - fprintf(cpp, "\n"); - fprintf(cpp, " };\n"); - } - } - delete[] buffer; - buffer = NULL; - - //write cpp source file footer - fprintf(cpp, " return (const char *)buffer;\n"); - fprintf(cpp, " }\n"); - fprintf(cpp, "%s", getSaveMethodTemplate().c_str()); - fprintf(cpp, " };\n"); - fprintf(cpp, " const %s & %s() { static %s _instance; return _instance; }\n", getContext().baseClass.c_str(), getterFunctionName.c_str(), className.c_str()); - if (mContext.registerFiles) - { - std::string fileManagerTemplate = getCppFileManagerRegistrationImplementationTemplate(); - fprintf(cpp, "%s", fileManagerTemplate.c_str()); - } - fprintf(cpp, "}; //%s\n", getContext().codeNamespace.c_str()); - - fclose(input); - fclose(cpp); - - return true; + const std::string text = "" + "${bin2cpp_output_file_header}" + "#include \"${bin2cpp_cpp_header_include_path}\"\n" + "#include \n" + "#include //for ofstream\n" + "namespace ${bin2cpp_namespace}\n" + "{\n" + " class ${bin2cpp_classname} : public virtual ${bin2cpp_namespace}::${bin2cpp_baseclass}\n" + " {\n" + " public:\n" + " ${bin2cpp_classname}() {}\n" + " virtual ~${bin2cpp_classname}() {}\n" + " virtual size_t getSize() const { return ${bin2cpp_input_file_size}; }\n" + " virtual const char * getFileName() const { ${bin2cpp_cpp_get_file_name_impl} }\n" + " virtual const char * getFilePath() const { ${bin2cpp_cpp_get_file_path_impl} }\n" + " virtual const char * getBuffer() const\n" + " {\n" + " static const unsigned char buffer[] = {\n${bin2cpp_insert_input_file_as_code}" + " };\n" + " return (const char *)buffer;\n" + " }\n" + "${bin2cpp_cpp_get_save_method_impl}" + " };\n" + " const ${bin2cpp_baseclass} & ${bin2cpp_cpp_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" + "${bin2cpp_cpp_get_file_manager_registration_impl}" + "}; //${bin2cpp_namespace}\n"; + + TemplateProcessor processor(&text); + processor.setTemplateVariableLookup(this); + bool write_success = processor.writeFile(file_path); + + return write_success; } bool ArrayGenerator::printFileContent() { //check if input file exists - FILE * input = fopen(mContext.inputFilePath.c_str(), "rb"); - if (!input) + if (!ra::filesystem::FileExists(mContext.inputFilePath.c_str()) ) return false; - //determine file properties - uint32_t fileSize = ra::filesystem::GetFileSize(input); - - //create buffer for each chunks from input buffer - int numLinePrinted = 0; - unsigned char * buffer = new unsigned char[getContext().chunkSize]; - while(!feof(input)) - { - //read a chunk of the file - size_t readSize = fread(buffer, 1, getContext().chunkSize, input); - - bool isLastChunk = !(readSize == getContext().chunkSize); - - if (readSize > 0) - { - if (numLinePrinted > 0) - { - //end previous line - printf("\n"); - } - - //output - std::string text = ra::code::cpp::ToCppCharactersArray(buffer, readSize); - printf("\"%s\"", text.c_str()); - numLinePrinted++; - } - } - delete[] buffer; - buffer = NULL; - - fclose(input); + std::string output = getInputFileDataAsCode(); + printf("\"%s\"", output.c_str()); return true; } @@ -195,163 +103,139 @@ namespace bin2cpp bool ArrayGenerator::createCSourceFile(const char* file_path) { //check if input file exists - FILE* input = fopen(mContext.inputFilePath.c_str(), "rb"); - if ( !input ) - return false; - - //Lowercase function identifier - std::string functionIdentifier = ra::strings::Lowercase(mContext.functionIdentifier); - - //Build header and cpp file path - std::string headerPath = getHeaderFilePath(file_path); - std::string sourcePath = file_path; - - //create c source file - FILE* fout = fopen(sourcePath.c_str(), "w"); - if ( !fout ) - { - fclose(input); + if ( !ra::filesystem::FileExists(mContext.inputFilePath.c_str()) ) return false; - } - - //determine file properties - uint32_t fileSize = ra::filesystem::GetFileSize(input); - std::string filename = ra::filesystem::GetFilename(mContext.inputFilePath.c_str()); - //long lastSegmentSize = fileSize%chunk_size; - //size_t numSegments = fileSize/chunk_size + (lastSegmentSize == 0 ? 0 : 1); - - //Build class name - std::string className = getClassName(); - - //Build function - std::string getterFunctionName = getGetterFunctionName(); - - //Build FileManager class template - std::string manager = mContext.managerHeaderFilename; - - //write c file heading - fprintf(fout, "%s", getHeaderTemplate().c_str()); - fprintf(fout, "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n"); - fprintf(fout, "#define _CRT_SECURE_NO_WARNINGS\n"); - fprintf(fout, "#endif\n"); - fprintf(fout, "#include \"%s\"\n", mContext.headerFilename.c_str()); - fprintf(fout, "#include // for malloc\n"); - fprintf(fout, "#include // for memset\n"); - fprintf(fout, "#include // for fopen\n"); - - fprintf(fout, "static %s %s_file = { 0 };\n", mContext.baseClass.c_str(), functionIdentifier.c_str()); - fprintf(fout, "static bool %s_initialized = false;\n", functionIdentifier.c_str()); - fprintf(fout, "\n"); - - // File registration predeclaration code - fprintf(fout, "%s", getCFileManagerRegistrationPredeclarationTemplate().c_str()); - - fprintf(fout, "bool %s_load()\n", functionIdentifier.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " if ( %s_file.buffer )\n", functionIdentifier.c_str()); - fprintf(fout, " return true;\n"); - fprintf(fout, " static const unsigned char static_buffer[] = {\n"); - - //create buffer for each chunks from input buffer - int numLinePrinted = 0; - unsigned char* buffer = new unsigned char[getContext().chunkSize]; - while ( !feof(input) ) - { - //read a chunk of the file - size_t readSize = fread(buffer, 1, getContext().chunkSize, input); - - bool isLastChunk = !(readSize == getContext().chunkSize); - - if ( readSize > 0 ) - { - if ( numLinePrinted > 0 ) - { - //end previous line - fprintf(fout, ",\n"); - } - - //output - fprintf(fout, " %s", ra::code::cpp::ToCppCharactersArray(buffer, readSize).c_str()); - numLinePrinted++; - } - - //end the array. all the file content is printed - if ( isLastChunk ) - { - fprintf(fout, "\n"); - fprintf(fout, " };\n"); - } - } - delete[] buffer; - buffer = NULL; - - //write c source file footer - fprintf(fout, "\n"); - fprintf(fout, " %s_file.buffer = static_buffer;\n", functionIdentifier.c_str()); - fprintf(fout, " return true;\n"); - fprintf(fout, "}\n"); - - fprintf(fout, "\n"); - - fprintf(fout, "void %s_free()\n", functionIdentifier.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " %s_file.buffer = NULL;\n", functionIdentifier.c_str()); - fprintf(fout, "}\n"); - fprintf(fout, "\n"); - fprintf(fout, "bool %s_save(const char* path)\n", functionIdentifier.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " if ( !%s_file.buffer )\n", functionIdentifier.c_str()); - fprintf(fout, " return false;\n"); - fprintf(fout, " FILE* f = fopen(path, \"wb\");\n"); - fprintf(fout, " if ( !f )\n"); - fprintf(fout, " return false;\n"); - fprintf(fout, " size_t write_size = fwrite(%s_file.buffer, 1, %s_file.size, f);\n", functionIdentifier.c_str(), functionIdentifier.c_str()); - fprintf(fout, " fclose(f);\n"); - fprintf(fout, " if ( write_size != %s_file.size )\n", functionIdentifier.c_str()); - fprintf(fout, " return false;\n"); - fprintf(fout, " return true;\n"); - fprintf(fout, "}\n"); - fprintf(fout, "\n"); - fprintf(fout, "static inline void %s_init()\n", functionIdentifier.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " // remember we already initialized\n"); - fprintf(fout, " if ( %s_initialized )\n", functionIdentifier.c_str()); - fprintf(fout, " return;\n"); - fprintf(fout, " %s_initialized = true;\n", functionIdentifier.c_str()); - fprintf(fout, "\n"); - fprintf(fout, " // initialize\n"); - fprintf(fout, " %s* file = &%s_file;\n", mContext.baseClass.c_str(), functionIdentifier.c_str()); - fprintf(fout, " file->size = %uULL;\n", fileSize); - fprintf(fout, " file->file_name = \"%s\";\n", getFileClassFileName().c_str()); - fprintf(fout, " file->file_path = \"%s\";\n", getFileClassFilePath().c_str()); - fprintf(fout, " file->buffer = NULL;\n"); - fprintf(fout, " file->load = %s_load;\n", functionIdentifier.c_str()); - fprintf(fout, " file->unload = %s_free;\n", functionIdentifier.c_str()); - fprintf(fout, " file->save = %s_save;\n", functionIdentifier.c_str()); - fprintf(fout, "\n"); - fprintf(fout, " // load file by default on init as in c++ implementation"); - fprintf(fout, " file->load();\n"); - if ( mContext.registerFiles ) - { - fprintf(fout, " \n"); - fprintf(fout, " // register when loaded if static initialisation does not work\n"); - fprintf(fout, " %s_filemanager_register_file(file);\n", mContext.codeNamespace.c_str()); - } - fprintf(fout, "}\n"); - fprintf(fout, "\n"); - fprintf(fout, "%s* %s(void)\n", mContext.baseClass.c_str(), getGetterFunctionName().c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " %s_init();\n", functionIdentifier.c_str()); - fprintf(fout, " return &%s_file;\n", functionIdentifier.c_str()); - fprintf(fout, "}\n"); - - // File registration implementation code - fprintf(fout, "%s", getCFileManagerRegistrationImplementationTemplate().c_str()); - - fclose(input); - fclose(fout); + + const std::string text = "" + "${bin2cpp_output_file_header}" + "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" + "#define _CRT_SECURE_NO_WARNINGS\n" + "#endif\n" + "#include \"${bin2cpp_cpp_header_include_path}\"\n" + "#include // for malloc\n" + "#include // for memset\n" + "#include // for fopen\n" + "static ${bin2cpp_baseclass} ${bin2cpp_function_identifier_lowercase}_file = { 0 };\n" + "static bool ${bin2cpp_function_identifier_lowercase}_initialized = false;\n" + "\n" + "${bin2cpp_c_file_manager_registration_predeclaration}" + "bool ${bin2cpp_function_identifier_lowercase}_load()\n" + "{\n" + " if ( ${bin2cpp_function_identifier_lowercase}_file.buffer )\n" + " return true;\n" + " static const unsigned char static_buffer[] = {\n${bin2cpp_insert_input_file_as_code}" + " };\n" + "\n" + " ${bin2cpp_function_identifier_lowercase}_file.buffer = static_buffer;\n" + " return true;\n" + "}\n" + "\n" + "void ${bin2cpp_function_identifier_lowercase}_free()\n" + "{\n" + " ${bin2cpp_function_identifier_lowercase}_file.buffer = NULL;\n" + "}\n" + "\n" + "bool ${bin2cpp_function_identifier_lowercase}_save(const char* path)\n" + "{\n" + " if ( !${bin2cpp_function_identifier_lowercase}_file.buffer )\n" + " return false;\n" + " FILE* f = fopen(path, \"wb\");\n" + " if ( !f )\n" + " return false;\n" + " size_t write_size = fwrite(${bin2cpp_function_identifier_lowercase}_file.buffer, 1, ${bin2cpp_function_identifier_lowercase}_file.size, f);\n" + " fclose(f);\n" + " if ( write_size != ${bin2cpp_function_identifier_lowercase}_file.size )\n" + " return false;\n" + " return true;\n" + "}\n" + "\n" + "static inline void ${bin2cpp_function_identifier_lowercase}_init()\n" + "{\n" + " // remember we already initialized\n" + " if ( ${bin2cpp_function_identifier_lowercase}_initialized )\n" + " return;\n" + " ${bin2cpp_function_identifier_lowercase}_initialized = true;\n" + "\n" + " // initialize\n" + " ${bin2cpp_baseclass}* file = &${bin2cpp_function_identifier_lowercase}_file;\n" + " file->size = ${bin2cpp_input_file_size}ULL;\n" + " file->file_name = \"${bin2cpp_get_file_obj_file_name}\";\n" + " file->file_path = \"${bin2cpp_get_file_obj_file_path}\";\n" + " file->buffer = NULL;\n" + " file->load = ${bin2cpp_function_identifier_lowercase}_load;\n" + " file->unload = ${bin2cpp_function_identifier_lowercase}_free;\n" + " file->save = ${bin2cpp_function_identifier_lowercase}_save;\n" + "\n" + " // load file by default on init as in c++ implementation" + " file->load();\n" + "${bin2cpp_c_registration_post_init_impl}" + "}\n" + "\n" + "${bin2cpp_baseclass}* ${bin2cpp_cpp_getter_function_name}(void)\n" + "{\n" + " ${bin2cpp_function_identifier_lowercase}_init();\n" + " return &${bin2cpp_function_identifier_lowercase}_file;\n" + "}\n" + "${bin2cpp_c_file_manager_registration_implementation}" + ; + + TemplateProcessor processor(&text); + processor.setTemplateVariableLookup(this); + bool write_success = processor.writeFile(file_path); + + return write_success; + } - return true; + std::string ArrayGenerator::getInputFileChunkAsCode(const unsigned char * buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk) + { + size_t indentation = 0; + + if ( mContext.plainOutput ) + indentation = 0; + else if ( mContext.code == CodeGenerationEnum::CODE_GENERATION_CPP ) + indentation = 8; + else if ( mContext.code == CodeGenerationEnum::CODE_GENERATION_C ) + indentation = 4; + + std::string output; + if ( indentation ) + output += std::string(indentation, ' '); + if ( mContext.plainOutput ) + output += "\""; + output += ra::code::cpp::ToCppCharactersArray(buffer, buffer_size); + if ( mContext.plainOutput ) + output += "\""; + if ( !is_last_chunk ) + output += ","; + output += "\n"; + return output; + + //if ( !mContext.plainOutput ) + //{ + // // C/C++ code generation + // static const size_t INDENTATION_SIZE = 8; + // std::string output; + // output += std::string(INDENTATION_SIZE, ' '); + // output += ra::code::cpp::ToCppCharactersArray(buffer, buffer_size); + // if ( !is_last_chunk ) + // output += ","; + // output += "\n"; + // return output; + //} + + //if ( mContext.plainOutput ) + //{ + // // C/C++ declaration + // std::string output; + // if ( index > 0 ) + // output += "\""; + // output += ra::code::cpp::ToCppCharactersArray(buffer, buffer_size); + // if ( !is_last_chunk ) + // output += "\"\n"; + // return output; + //} + + return ""; } }; //bin2cpp \ No newline at end of file diff --git a/src/bin2cpp/ArrayGenerator.h b/src/bin2cpp/ArrayGenerator.h index 46ec570..68d6e3f 100644 --- a/src/bin2cpp/ArrayGenerator.h +++ b/src/bin2cpp/ArrayGenerator.h @@ -43,6 +43,7 @@ namespace bin2cpp virtual bool createCppSourceFile(const char * cpp_file_path); virtual bool createCSourceFile(const char * cpp_file_path); virtual bool printFileContent(); + virtual std::string getInputFileChunkAsCode(const unsigned char * buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk); }; }; //bin2cpp From f8613cc0b3b4c559bc7f1b5dcd7148d097ebd4a4 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Fri, 23 May 2025 16:30:00 -0400 Subject: [PATCH 06/26] Added new command line samples. --- src/bin2cpp/bin2cpp.samples.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/bin2cpp/bin2cpp.samples.txt b/src/bin2cpp/bin2cpp.samples.txt index 1f9d63f..338158d 100644 --- a/src/bin2cpp/bin2cpp.samples.txt +++ b/src/bin2cpp/bin2cpp.samples.txt @@ -1,4 +1,6 @@ +########################################################################################## # C code examples: +########################################################################################## Test all generators --file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\test\bin2cpp_unittest\generated_files\testHtml100000 --headerfile=_testHtml100000_C.h --override --code=c --generator=array @@ -24,7 +26,25 @@ Test for baseclass: --file=..\..\test\bin2cpp_unittest\generated_files\testBaseClass_C\testBaseClass_C.bin --output=..\..\test\bin2cpp_unittest\generated_files\testBaseClass_C --headerfile=testBaseClass_C.h --identifier=testBaseClass_C --managerfile=filemanager.h --override --code=c --baseclass=Resource +########################################################################################## # CPP code examples: +########################################################################################## + +Test all generators +--file=..\..\test\bin2cpp_unittest\generated_files\testGeneratorArray10000\testGeneratorArray10000.bin --output=..\..\test\bin2cpp_unittest\generated_files\testGeneratorArray10000 --headerfile=_testGeneratorArray10000.h --identifier=testGeneratorArray10000 --chunksize=450 --override --generator=array +--file=..\..\test\bin2cpp_unittest\generated_files\testGeneratorSegment10000\testGeneratorSegment10000.bin --output=..\..\test\bin2cpp_unittest\generated_files\testGeneratorSegment10000 --headerfile=_testGeneratorSegment10000.h --identifier=testGeneratorSegment10000 --chunksize=450 --override --generator=segment +--file=..\..\test\bin2cpp_unittest\generated_files\testGeneratorString10000\testGeneratorString10000.bin --output=..\..\test\bin2cpp_unittest\generated_files\testGeneratorString10000 --headerfile=_testGeneratorString10000.h --identifier=testGeneratorString10000 --chunksize=450 --override --generator=string +--file=..\..\test\bin2cpp_unittest\generated_files\testGeneratorWin32\testGeneratorWin32.bin --output=..\..\test\bin2cpp_unittest\generated_files\testGeneratorWin32 --headerfile=_testGeneratorWin32.h --identifier=testGeneratorWin32 --chunksize=450 --override --generator=win32 + +Test plain output: +--plainoutput --chunksize=75 --file=..\..\test\bin2cpp_unittest\generated_files\testSequential1000\testSequential1000.bin --generator=array +--plainoutput --chunksize=75 --file=..\..\test\bin2cpp_unittest\generated_files\testSequential1000\testSequential1000.bin --generator=segment +--plainoutput --chunksize=75 --file=..\..\test\bin2cpp_unittest\generated_files\testSequential1000\testSequential1000.bin --generator=string + + + + + --dir=..\..\..\samples\demo_website\www --output=..\..\temp --managerfile=PagesFileManager.h --namespace=myblog --keepdirs --dir=..\..\..\samples\demo_website\www --output=..\..\temp --dirincludefilter="*\static\*.css:*.jpg" --dir=..\..\..\samples\demo_website\www --output=..\..\temp --dirincludefilter="*\static\*.css:*.jpg" --direxcludefilter="*\light-mode.css" From c8f5cd431005d9c1ca072e79feebb617002b69fb Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Fri, 23 May 2025 16:58:07 -0400 Subject: [PATCH 07/26] Code cleanup --- src/bin2cpp/ArrayGenerator.cpp | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/src/bin2cpp/ArrayGenerator.cpp b/src/bin2cpp/ArrayGenerator.cpp index b428cd1..bd384ef 100644 --- a/src/bin2cpp/ArrayGenerator.cpp +++ b/src/bin2cpp/ArrayGenerator.cpp @@ -209,33 +209,6 @@ namespace bin2cpp output += ","; output += "\n"; return output; - - //if ( !mContext.plainOutput ) - //{ - // // C/C++ code generation - // static const size_t INDENTATION_SIZE = 8; - // std::string output; - // output += std::string(INDENTATION_SIZE, ' '); - // output += ra::code::cpp::ToCppCharactersArray(buffer, buffer_size); - // if ( !is_last_chunk ) - // output += ","; - // output += "\n"; - // return output; - //} - - //if ( mContext.plainOutput ) - //{ - // // C/C++ declaration - // std::string output; - // if ( index > 0 ) - // output += "\""; - // output += ra::code::cpp::ToCppCharactersArray(buffer, buffer_size); - // if ( !is_last_chunk ) - // output += "\"\n"; - // return output; - //} - - return ""; } }; //bin2cpp \ No newline at end of file From ec2880ff74de16933efb7bdb73d9c7fcf1c1092e Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Fri, 23 May 2025 17:18:53 -0400 Subject: [PATCH 08/26] Fixed small bugs in ArrayGenerator implementation. Refactored function names in BaseGenerator. --- src/bin2cpp/ArrayGenerator.cpp | 4 ++-- src/bin2cpp/BaseGenerator.cpp | 31 +++++++++++++------------- src/bin2cpp/BaseGenerator.h | 4 ++-- src/bin2cpp/SegmentGenerator.cpp | 4 ++-- src/bin2cpp/StringGenerator.cpp | 4 ++-- src/bin2cpp/Win32ResourceGenerator.cpp | 4 ++-- src/bin2cpp/bin2cpp.samples.txt | 10 ++++++++- 7 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/bin2cpp/ArrayGenerator.cpp b/src/bin2cpp/ArrayGenerator.cpp index bd384ef..e56418f 100644 --- a/src/bin2cpp/ArrayGenerator.cpp +++ b/src/bin2cpp/ArrayGenerator.cpp @@ -166,9 +166,9 @@ namespace bin2cpp " file->unload = ${bin2cpp_function_identifier_lowercase}_free;\n" " file->save = ${bin2cpp_function_identifier_lowercase}_save;\n" "\n" - " // load file by default on init as in c++ implementation" + " // load file by default on init as in c++ implementation\n" " file->load();\n" - "${bin2cpp_c_registration_post_init_impl}" + "${bin2cpp_c_file_manager_registration_post_init_impl}" "}\n" "\n" "${bin2cpp_baseclass}* ${bin2cpp_cpp_getter_function_name}(void)\n" diff --git a/src/bin2cpp/BaseGenerator.cpp b/src/bin2cpp/BaseGenerator.cpp index 7fb0366..3846b1c 100755 --- a/src/bin2cpp/BaseGenerator.cpp +++ b/src/bin2cpp/BaseGenerator.cpp @@ -76,17 +76,17 @@ namespace bin2cpp if ( name == "bin2cpp_get_file_obj_file_path" ) return getFileClassFilePath(); if ( name == "bin2cpp_cpp_get_save_method_impl" ) return getSaveMethodTemplate(); if ( name == "bin2cpp_cpp_get_file_manager_registration_impl" && mContext.registerFiles ) return getCppFileManagerRegistrationImplementationTemplate(); - if ( name == "bin2cpp_c_file_manager_registration_predeclaration" && mContext.registerFiles ) return getCFileManagerRegistrationPredeclarationTemplate(); - if ( name == "bin2cpp_c_file_manager_registration_implementation" && mContext.registerFiles ) return getCFileManagerRegistrationImplementationTemplate(); - - //if ( name == "bin2cpp_c_registration_post_init_impl" && mContext.registerFiles ) - //{ - // std::string output; - // output += " \n"; - // output += " // register when loaded if static initialisation does not work\n"; - // output += " ${bin2cpp_classname}_filemanager_register_file(file);\n"; - // return output; - //} + if ( name == "bin2cpp_c_file_manager_registration_predeclaration" && mContext.registerFiles ) return getCFileManagerRegistrationPredeclarationImplementation(); + if ( name == "bin2cpp_c_file_manager_registration_implementation" && mContext.registerFiles ) return getCFileManagerStaticFileRegistrationImplementation(); + + if ( name == "bin2cpp_c_file_manager_registration_post_init_impl" && mContext.registerFiles ) + { + std::string output; + output += " \n"; + output += " // register when loaded if static initialisation does not work\n"; + output += " ${bin2cpp_namespace}_filemanager_register_file(file);\n"; + return output; + } if ( name == "bin2cpp_input_file_size" ) { @@ -228,7 +228,7 @@ namespace bin2cpp return output; } - std::string BaseGenerator::getCFileManagerRegistrationPredeclarationTemplate() + std::string BaseGenerator::getCFileManagerRegistrationPredeclarationImplementation() { if ( !mContext.registerFiles ) return std::string(); @@ -239,7 +239,7 @@ namespace bin2cpp return output; } - std::string BaseGenerator::getCFileManagerRegistrationImplementationTemplate() + std::string BaseGenerator::getCFileManagerStaticFileRegistrationImplementation() { if ( !mContext.registerFiles ) return std::string(); @@ -248,17 +248,18 @@ namespace bin2cpp std::string functionIdentifier = ra::strings::Lowercase(mContext.functionIdentifier); std::string output; + output << "\n"; output << "#if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) // GCC 4.0+ required, Clang supports it by default\n"; output << "__attribute__((constructor))\n"; output << "#endif\n"; - output << "void " << mContext.codeNamespace << "_register_file_static_init_" << functionIdentifier << "(void)\n"; + output << "void " << mContext.codeNamespace << "_" << functionIdentifier << "_register_file_static_init(void)\n"; output << "{\n"; output << " " << mContext.baseClass << "* this_file = " << mContext.codeNamespace << "_get_file_" << functionIdentifier << "();\n"; output << " " << mContext.codeNamespace << "_filemanager_register_file(this_file);\n"; output << "}\n"; output << "#if _MSC_VER >= 1920 // Visual Studio 2019 or later\n"; output << "#pragma section(\".CRT$XCU\", read)\n"; - output << "__declspec(allocate(\".CRT$XCU\")) void (*init_ptr_" << functionIdentifier << ")(void) = " << mContext.codeNamespace << "_register_file_static_init_" << functionIdentifier << ";\n"; + output << "__declspec(allocate(\".CRT$XCU\")) void (*init_ptr_" << mContext.codeNamespace << "_" << functionIdentifier << ")(void) = " << mContext.codeNamespace << "_" << functionIdentifier << "_register_file_static_init" << ";\n"; output << "#endif\n"; return output; } diff --git a/src/bin2cpp/BaseGenerator.h b/src/bin2cpp/BaseGenerator.h index 7ccaab2..d82e2ef 100644 --- a/src/bin2cpp/BaseGenerator.h +++ b/src/bin2cpp/BaseGenerator.h @@ -62,8 +62,8 @@ namespace bin2cpp virtual std::string getHeaderTemplate(bool include_source_file); virtual std::string getSaveMethodTemplate(); virtual std::string getCppFileManagerRegistrationImplementationTemplate(); - virtual std::string getCFileManagerRegistrationPredeclarationTemplate(); - virtual std::string getCFileManagerRegistrationImplementationTemplate(); + virtual std::string getCFileManagerRegistrationPredeclarationImplementation(); + virtual std::string getCFileManagerStaticFileRegistrationImplementation(); virtual std::string getClassName(); virtual std::string getClassMacroGuardPrefix(); virtual std::string getImplOfGetFileName(); diff --git a/src/bin2cpp/SegmentGenerator.cpp b/src/bin2cpp/SegmentGenerator.cpp index 071365d..fbc0fec 100755 --- a/src/bin2cpp/SegmentGenerator.cpp +++ b/src/bin2cpp/SegmentGenerator.cpp @@ -212,7 +212,7 @@ namespace bin2cpp fprintf(fout, "\n"); // File registration predeclaration code - fprintf(fout, "%s", getCFileManagerRegistrationPredeclarationTemplate().c_str()); + fprintf(fout, "%s", getCFileManagerRegistrationPredeclarationImplementation().c_str()); fprintf(fout, "bool %s_load()\n", functionIdentifier.c_str()); fprintf(fout, "{\n"); @@ -319,7 +319,7 @@ namespace bin2cpp fprintf(fout, "}\n"); // File registration implementation code - fprintf(fout, "%s", getCFileManagerRegistrationImplementationTemplate().c_str()); + fprintf(fout, "%s", getCFileManagerStaticFileRegistrationImplementation().c_str()); fclose(input); fclose(fout); diff --git a/src/bin2cpp/StringGenerator.cpp b/src/bin2cpp/StringGenerator.cpp index b3fe3af..8ef08b0 100755 --- a/src/bin2cpp/StringGenerator.cpp +++ b/src/bin2cpp/StringGenerator.cpp @@ -214,7 +214,7 @@ namespace bin2cpp fprintf(fout, "\n"); // File registration predeclaration code - fprintf(fout, "%s", getCFileManagerRegistrationPredeclarationTemplate().c_str()); + fprintf(fout, "%s", getCFileManagerRegistrationPredeclarationImplementation().c_str()); fprintf(fout, "bool %s_load()\n", functionIdentifier.c_str()); fprintf(fout, "{\n"); @@ -331,7 +331,7 @@ namespace bin2cpp fprintf(fout, "}\n"); // File registration implementation code - fprintf(fout, "%s", getCFileManagerRegistrationImplementationTemplate().c_str()); + fprintf(fout, "%s", getCFileManagerStaticFileRegistrationImplementation().c_str()); fclose(input); fclose(fout); diff --git a/src/bin2cpp/Win32ResourceGenerator.cpp b/src/bin2cpp/Win32ResourceGenerator.cpp index 574a8f5..7552125 100755 --- a/src/bin2cpp/Win32ResourceGenerator.cpp +++ b/src/bin2cpp/Win32ResourceGenerator.cpp @@ -265,7 +265,7 @@ namespace bin2cpp fprintf(fout, "\n"); // File registration predeclaration code - fprintf(fout, "%s", getCFileManagerRegistrationPredeclarationTemplate().c_str()); + fprintf(fout, "%s", getCFileManagerRegistrationPredeclarationImplementation().c_str()); fprintf(fout, "bool %s_load()\n", functionIdentifier.c_str()); fprintf(fout, "{\n"); @@ -375,7 +375,7 @@ namespace bin2cpp fprintf(fout, "}\n"); // File registration implementation code - fprintf(fout, "%s", getCFileManagerRegistrationImplementationTemplate().c_str()); + fprintf(fout, "%s", getCFileManagerStaticFileRegistrationImplementation().c_str()); fclose(input); fclose(fout); diff --git a/src/bin2cpp/bin2cpp.samples.txt b/src/bin2cpp/bin2cpp.samples.txt index 338158d..1fcaa88 100644 --- a/src/bin2cpp/bin2cpp.samples.txt +++ b/src/bin2cpp/bin2cpp.samples.txt @@ -2,12 +2,18 @@ # C code examples: ########################################################################################## -Test all generators +Test all generators: --file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\test\bin2cpp_unittest\generated_files\testHtml100000 --headerfile=_testHtml100000_C.h --override --code=c --generator=array --file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\test\bin2cpp_unittest\generated_files\testHtml100000 --headerfile=_testHtml100000_C.h --override --code=c --generator=segment --file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\test\bin2cpp_unittest\generated_files\testHtml100000 --headerfile=_testHtml100000_C.h --override --code=c --generator=string --file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\test\bin2cpp_unittest\generated_files\testHtml100000 --headerfile=_testHtml100000_C.h --override --code=c --generator=win32 +Test as much features as possible with all generators: +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_tim_testHtml100000.h --identifier=LibFooFOO --chunksize=75 --baseclass=ben --namespace=ray --managerfile=c_tim_filemanager.h --registerfile --override --code=c --generator=array +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_jim_testHtml100000.h --identifier=LibBarBAR --chunksize=75 --baseclass=tom --namespace=eva --managerfile=c_jim_filemanager.h --registerfile --override --code=c --generator=segment +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_lou_testHtml100000.h --identifier=LibBazBAZ --chunksize=75 --baseclass=sam --namespace=joe --managerfile=c_lou_filemanager.h --registerfile --override --code=c --generator=string +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_sue_testHtml100000.h --identifier=LibBobBOB --chunksize=75 --baseclass=leo --namespace=jon --managerfile=c_sue_filemanager.h --registerfile --override --code=c --generator=win32 + Test for: * Segment C generator * filemanager @@ -15,6 +21,8 @@ Test for: --file=..\..\test\bin2cpp_unittest\generated_files\testFileManager_C\testFileManager_C.1.bin --output=..\..\test\bin2cpp_unittest\generated_files\testFileManager_C --headerfile=_testFileManager_C.1.h --identifier=testFileManager1_c --managerfile=filemanager.h --override --code=c --file=..\..\test\bin2cpp_unittest\generated_files\testFileManager_C\testFileManager_C.2.bin --output=..\..\test\bin2cpp_unittest\generated_files\testFileManager_C --headerfile=_testFileManager_C.2.h --identifier=testFileManager2_c --registerfile --override --code=c + + Test directories: --dir=..\..\..\samples\demo_website\www --output=..\..\temp --code=c --dir=..\..\..\samples\demo_website\www --output=..\..\temp --code=c --managerfile=www-file-manager.h From 2bb2255b3a6ca2dddd68d79ca69c5fec5f86a8ed Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sat, 24 May 2025 07:37:04 -0400 Subject: [PATCH 09/26] Modified ManagerGenerator to use TemplateProcessor. --- src/bin2cpp/BaseGenerator.cpp | 37 +- src/bin2cpp/BaseGenerator.h | 1 + src/bin2cpp/ManagerGenerator.cpp | 767 +++++++++++++++---------------- src/bin2cpp/ManagerGenerator.h | 4 +- src/bin2cpp/bin2cpp.samples.txt | 6 + src/bin2cpp/main.cpp | 4 + 6 files changed, 409 insertions(+), 410 deletions(-) diff --git a/src/bin2cpp/BaseGenerator.cpp b/src/bin2cpp/BaseGenerator.cpp index 3846b1c..3ed80bf 100755 --- a/src/bin2cpp/BaseGenerator.cpp +++ b/src/bin2cpp/BaseGenerator.cpp @@ -59,14 +59,22 @@ namespace bin2cpp std::string BaseGenerator::lookupTemplateVariable(const std::string& name) { if ( name == "bin2cpp_output_file_macro_guard" ) return getCppIncludeGuardMacroName(mContext.headerFilename); - if ( name == "bin2cpp_embedded_file_class_macro_guard" ) return getClassMacroGuardPrefix(); + if ( name == "bin2cpp_embedded_file_class_macro_guard_prefix" ) return getClassMacroGuardPrefix(); if ( name == "bin2cpp_output_file_header" ) return getHeaderTemplate(); + if ( name == "bin2cpp_filemanager_file_header" ) return getHeaderTemplate(false); + if ( name == "bin2cpp_file_manager_header_file_name" ) return mContext.managerHeaderFilename; + if ( name == "bin2cpp_file_manager_macro_guard_prefix" ) return getFileManagerMacroGuardPrefix(); if ( name == "bin2cpp_baseclass" ) return mContext.baseClass; if ( name == "bin2cpp_classname" ) return getClassName(); + if ( name == "bin2cpp_namespace" ) return mContext.codeNamespace; + if ( name == "bin2cpp_baseclass_uppercase" ) return ra::strings::Uppercase(mContext.baseClass); + if ( name == "bin2cpp_classname_uppercase" ) return ra::strings::Uppercase(getClassName()); + if ( name == "bin2cpp_namespace_uppercase" ) return ra::strings::Lowercase(mContext.codeNamespace); + if ( name == "bin2cpp_baseclass_lowercase" ) return ra::strings::Lowercase(mContext.baseClass); + if ( name == "bin2cpp_classname_lowercase" ) return ra::strings::Lowercase(getClassName()); + if ( name == "bin2cpp_namespace_lowercase" ) return ra::strings::Lowercase(mContext.codeNamespace); if ( name == "bin2cpp_function_identifier" ) return mContext.functionIdentifier; if ( name == "bin2cpp_function_identifier_lowercase" ) return ra::strings::Lowercase(mContext.functionIdentifier); - if ( name == "bin2cpp_classname" ) return getClassName(); - if ( name == "bin2cpp_namespace" ) return mContext.codeNamespace; if ( name == "bin2cpp_cpp_getter_function_name" ) return getGetterFunctionName(); if ( name == "bin2cpp_insert_input_file_as_code" ) return getInputFileDataAsCode(); if ( name == "bin2cpp_cpp_header_include_path" ) return getCppHeaderIncludePath(); @@ -283,6 +291,17 @@ namespace bin2cpp return macroGuardPrefix; } + std::string BaseGenerator::getFileManagerMacroGuardPrefix() + { + //define macro guard a macro matching the filename + std::string output; + output += getCppIncludeGuardMacroName(mContext.codeNamespace.c_str()); //prefix the custom namespace for the file manager + if ( !output.empty() ) + output += "_"; + output += getCppIncludeGuardMacroName(mContext.managerHeaderFilename); + return output; + } + std::string BaseGenerator::getImplOfGetFileName() { std::string output; @@ -456,8 +475,8 @@ namespace bin2cpp "\n" "namespace ${bin2cpp_namespace}\n" "{\n" - " #ifndef ${bin2cpp_embedded_file_class_macro_guard}_EMBEDDEDFILE_CLASS\n" - " #define ${bin2cpp_embedded_file_class_macro_guard}_EMBEDDEDFILE_CLASS\n" + " #ifndef ${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_CLASS\n" + " #define ${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_CLASS\n" " class ${bin2cpp_baseclass}\n" " {\n" " public:\n" @@ -468,7 +487,7 @@ namespace bin2cpp " virtual const char * getBuffer() const = 0;\n" " virtual bool save(const char * filename) const = 0;\n" " };\n" - " #endif //${bin2cpp_embedded_file_class_macro_guard}_EMBEDDEDFILE_CLASS\n" + " #endif //${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_CLASS\n" " const ${bin2cpp_baseclass} & ${bin2cpp_cpp_getter_function_name}();\n" "}; //${bin2cpp_namespace}\n" "\n" @@ -544,8 +563,8 @@ namespace bin2cpp "#include \n" "#include \n" "\n" - "#ifndef ${bin2cpp_embedded_file_class_macro_guard}_EMBEDDEDFILE_STRUCT\n" - "#define ${bin2cpp_embedded_file_class_macro_guard}_EMBEDDEDFILE_STRUCT\n" + "#ifndef ${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_STRUCT\n" + "#define ${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_STRUCT\n" "typedef struct ${bin2cpp_baseclass} ${bin2cpp_baseclass};\n" "typedef bool(*${bin2cpp_namespace}_load_func)();\n" "typedef void(*${bin2cpp_namespace}_free_func)();\n" @@ -561,7 +580,7 @@ namespace bin2cpp " ${bin2cpp_namespace}_save_func save;\n" "} ${bin2cpp_baseclass};\n" "typedef ${bin2cpp_baseclass}* ${bin2cpp_baseclass}Ptr;\n" - "#endif //${bin2cpp_embedded_file_class_macro_guard}_EMBEDDEDFILE_STRUCT\n" + "#endif //${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_STRUCT\n" "${bin2cpp_baseclass}* ${bin2cpp_cpp_getter_function_name}(void);\n" "\n" "#endif //${bin2cpp_output_file_macro_guard}\n" diff --git a/src/bin2cpp/BaseGenerator.h b/src/bin2cpp/BaseGenerator.h index d82e2ef..966cf64 100644 --- a/src/bin2cpp/BaseGenerator.h +++ b/src/bin2cpp/BaseGenerator.h @@ -66,6 +66,7 @@ namespace bin2cpp virtual std::string getCFileManagerStaticFileRegistrationImplementation(); virtual std::string getClassName(); virtual std::string getClassMacroGuardPrefix(); + virtual std::string getFileManagerMacroGuardPrefix(); virtual std::string getImplOfGetFileName(); virtual std::string getImplOfGetFilePath(); virtual std::string getFileClassFileName(); diff --git a/src/bin2cpp/ManagerGenerator.cpp b/src/bin2cpp/ManagerGenerator.cpp index fa38a8f..681bfc9 100644 --- a/src/bin2cpp/ManagerGenerator.cpp +++ b/src/bin2cpp/ManagerGenerator.cpp @@ -23,6 +23,7 @@ *********************************************************************************/ #include "ManagerGenerator.h" +#include "TemplateProcessor.h" #include #include #include @@ -45,425 +46,393 @@ namespace bin2cpp return "manager"; } - bool ManagerGenerator::createCppHeaderFile(const char* header_file_path) + bool ManagerGenerator::createCppHeaderFile(const char* file_path) { - FILE* header = fopen(header_file_path, "w"); - if ( !header ) - return false; + const std::string text = "" + "${bin2cpp_filemanager_file_header}" + "#ifndef ${bin2cpp_file_manager_macro_guard_prefix}\n" + "#define ${bin2cpp_file_manager_macro_guard_prefix}\n" + "\n" + "#include \n" + "#include \n" + "\n" + "namespace ${bin2cpp_namespace}\n" + "{\n" + " #ifndef ${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_CLASS\n" + " #define ${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_CLASS\n" + " class ${bin2cpp_baseclass}\n" + " {\n" + " public:\n" + " virtual size_t getSize() const = 0;\n" + " /* DEPRECATED */ virtual inline const char * getFilename() const { return getFileName(); }\n" + " virtual const char * getFileName() const = 0;\n" + " virtual const char * getFilePath() const = 0;\n" + " virtual const char * getBuffer() const = 0;\n" + " virtual bool save(const char * filename) const = 0;\n" + " };\n" + " #endif //${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_CLASS\n" + "\n" + " #ifndef ${bin2cpp_embedded_file_class_macro_guard_prefix}_FILEMANAGER_CLASS\n" + " #define ${bin2cpp_embedded_file_class_macro_guard_prefix}_FILEMANAGER_CLASS\n" + " class FileManager\n" + " {\n" + " private:\n" + " FileManager();\n" + " ~FileManager();\n" + " public:\n" + " typedef const ${bin2cpp_baseclass} & (*t_func)();\n" + " static FileManager & getInstance();\n" + " void registerFile(t_func func);\n" + " size_t getFileCount() const;\n" + " const ${bin2cpp_baseclass} * getFile(const size_t & index) const;\n" + " bool saveFiles(const char * directory) const;\n" + " bool createParentDirectories(const char * file_path) const;\n" + " bool createDirectories(const char * path) const;\n" + " private:\n" + " std::vector functions_;\n" + " };\n" + " #endif //${bin2cpp_embedded_file_class_macro_guard_prefix}_FILEMANAGER_CLASS\n" + "}; //${bin2cpp_namespace}\n" + "\n" + "#endif //${bin2cpp_file_manager_macro_guard_prefix}\n" + ; - //define macro guard a macro matching the filename - std::string macroGuard; - macroGuard += getCppIncludeGuardMacroName(mContext.codeNamespace.c_str()); //prefix the custom namespace for the file manager - if ( !macroGuard.empty() ) - macroGuard += "_"; - macroGuard += getCppIncludeGuardMacroName(header_file_path); + TemplateProcessor processor(&text); + processor.setTemplateVariableLookup(this); + bool write_success = processor.writeFile(file_path); - std::string classMacroGuardPrefix = getClassMacroGuardPrefix(); - std::string fileHeader = getHeaderTemplate(false); - - fprintf(header, "%s", fileHeader.c_str()); - fprintf(header, "#ifndef %s\n", macroGuard.c_str()); - fprintf(header, "#define %s\n", macroGuard.c_str()); - fprintf(header, "\n"); - fprintf(header, "#include \n"); - fprintf(header, "#include \n"); - fprintf(header, "\n"); - fprintf(header, "namespace %s\n", mContext.codeNamespace.c_str()); - fprintf(header, "{\n"); - fprintf(header, " #ifndef %s_EMBEDDEDFILE_CLASS\n", classMacroGuardPrefix.c_str()); - fprintf(header, " #define %s_EMBEDDEDFILE_CLASS\n", classMacroGuardPrefix.c_str()); - fprintf(header, " class %s\n", mContext.baseClass.c_str()); - fprintf(header, " {\n"); - fprintf(header, " public:\n"); - fprintf(header, " virtual size_t getSize() const = 0;\n"); - fprintf(header, " /* DEPRECATED */ virtual inline const char * getFilename() const { return getFileName(); }\n"); - fprintf(header, " virtual const char * getFileName() const = 0;\n"); - fprintf(header, " virtual const char * getFilePath() const = 0;\n"); - fprintf(header, " virtual const char * getBuffer() const = 0;\n"); - fprintf(header, " virtual bool save(const char * filename) const = 0;\n"); - fprintf(header, " };\n"); - fprintf(header, " #endif //%s_EMBEDDEDFILE_CLASS\n", classMacroGuardPrefix.c_str()); - fprintf(header, "\n"); - fprintf(header, " #ifndef %s_FILEMANAGER_CLASS\n", classMacroGuardPrefix.c_str()); - fprintf(header, " #define %s_FILEMANAGER_CLASS\n", classMacroGuardPrefix.c_str()); - fprintf(header, " class FileManager\n"); - fprintf(header, " {\n"); - fprintf(header, " private:\n"); - fprintf(header, " FileManager();\n"); - fprintf(header, " ~FileManager();\n"); - fprintf(header, " public:\n"); - fprintf(header, " typedef const %s & (*t_func)();\n", mContext.baseClass.c_str()); - fprintf(header, " static FileManager & getInstance();\n"); - fprintf(header, " void registerFile(t_func func);\n"); - fprintf(header, " size_t getFileCount() const;\n"); - fprintf(header, " const %s * getFile(const size_t & index) const;\n", mContext.baseClass.c_str()); - fprintf(header, " bool saveFiles(const char * directory) const;\n"); - fprintf(header, " bool createParentDirectories(const char * file_path) const;\n"); - fprintf(header, " bool createDirectories(const char * path) const;\n"); - fprintf(header, " private:\n"); - fprintf(header, " std::vector functions_;\n"); - fprintf(header, " };\n"); - fprintf(header, " #endif //%s_FILEMANAGER_CLASS\n", classMacroGuardPrefix.c_str()); - fprintf(header, "}; //%s\n", mContext.codeNamespace.c_str()); - fprintf(header, "\n"); - fprintf(header, "#endif //%s\n", macroGuard.c_str()); - - fclose(header); - - return true; + return write_success; } - bool ManagerGenerator::createCppSourceFile(const char* cpp_file_path) + bool ManagerGenerator::createCppSourceFile(const char* file_path) { - FILE* cpp = fopen(cpp_file_path, "w"); - if ( !cpp ) - return false; - - //Build header and cpp file path - std::string headerPath = getHeaderFilePath(cpp_file_path); - std::string cppPath = cpp_file_path; - - std::string fileHeader = getHeaderTemplate(false); - - fprintf(cpp, "%s", fileHeader.c_str()); - fprintf(cpp, "#include \"%s\"\n", mContext.managerHeaderFilename.c_str()); - fprintf(cpp, "#include \n"); - fprintf(cpp, "#include // strlen\n"); - fprintf(cpp, "#include // stat\n"); - fprintf(cpp, "#include // errno, EEXIST\n"); - fprintf(cpp, "#if defined(_WIN32)\n"); - fprintf(cpp, "#include // _mkdir\n"); - fprintf(cpp, "#endif\n"); - fprintf(cpp, "\n"); - fprintf(cpp, "#if defined(_WIN32)\n"); - fprintf(cpp, "#define portable_stat _stat\n"); - fprintf(cpp, "#define portable_mkdir(path) _mkdir(path)\n"); - fprintf(cpp, "#define PATH_SEPARATOR_CHAR '\\\\'\n"); - fprintf(cpp, "#define PATH_SEPARATOR_STR \"\\\\\"\n"); - fprintf(cpp, "#else\n"); - fprintf(cpp, "#define portable_stat stat\n"); - fprintf(cpp, "#define portable_mkdir(path) mkdir(path, 0755)\n"); - fprintf(cpp, "#define PATH_SEPARATOR_CHAR '/'\n"); - fprintf(cpp, "#define PATH_SEPARATOR_STR \"/\"\n"); - fprintf(cpp, "#endif\n"); - fprintf(cpp, "\n"); - fprintf(cpp, "namespace %s\n", mContext.codeNamespace.c_str()); - fprintf(cpp, "{\n"); - fprintf(cpp, " bool RegisterFile(FileManager::t_func functionPointer)\n"); - fprintf(cpp, " {\n"); - fprintf(cpp, " if (functionPointer == NULL)\n"); - fprintf(cpp, " return false;\n"); - fprintf(cpp, " FileManager::getInstance().registerFile(functionPointer);\n"); - fprintf(cpp, " return true;\n"); - fprintf(cpp, " }\n"); - fprintf(cpp, " FileManager::FileManager() {}\n"); - fprintf(cpp, " FileManager::~FileManager() {}\n"); - fprintf(cpp, " FileManager & FileManager::getInstance() { static FileManager _mgr; return _mgr; }\n"); - fprintf(cpp, " void FileManager::registerFile(t_func func) { functions_.push_back(func); }\n"); - fprintf(cpp, " size_t FileManager::getFileCount() const { return functions_.size(); }\n"); - fprintf(cpp, " const File * FileManager::getFile(const size_t & index) const\n"); - fprintf(cpp, " {\n"); - fprintf(cpp, " if (index >= functions_.size())\n"); - fprintf(cpp, " return NULL;\n"); - fprintf(cpp, " t_func ressource_getter_function = functions_[index];\n"); - fprintf(cpp, " const %s::File & resource = ressource_getter_function();\n", mContext.codeNamespace.c_str()); - fprintf(cpp, " return &resource;\n"); - fprintf(cpp, " }\n"); - fprintf(cpp, " bool FileManager::saveFiles(const char * directory) const\n"); - fprintf(cpp, " {\n"); - fprintf(cpp, " if (directory == NULL)\n"); - fprintf(cpp, " return false;\n"); - fprintf(cpp, " size_t count = getFileCount();\n"); - fprintf(cpp, " for(size_t i=0; igetFilePath());\n"); - fprintf(cpp, " if (!createParentDirectories(path.c_str()))\n"); - fprintf(cpp, " return false;\n"); - fprintf(cpp, " bool saved = f->save(path.c_str());\n"); - fprintf(cpp, " if (!saved)\n"); - fprintf(cpp, " return false;\n"); - fprintf(cpp, " }\n"); - fprintf(cpp, " return true;\n"); - fprintf(cpp, " }\n"); - fprintf(cpp, " static inline bool isRootDirectory(const char * path)\n"); - fprintf(cpp, " {\n"); - fprintf(cpp, " if (path == NULL && path[0] == '\\0')\n"); - fprintf(cpp, " return false;\n"); - fprintf(cpp, " #if defined(_WIN32)\n"); - fprintf(cpp, " bool isDriveLetter = ((path[0] >= 'a' && path[0] <= 'z') || (path[0] >= 'A' && path[0] <= 'Z'));\n"); - fprintf(cpp, " if ((isDriveLetter && path[1] == ':' && path[2] == '\\0') || // test for C:\n"); - fprintf(cpp, " (isDriveLetter && path[1] == ':' && path[2] == PATH_SEPARATOR_CHAR && path[3] == '\\0')) // test for C:\\ \n"); - fprintf(cpp, " return true;\n"); - fprintf(cpp, " #else\n"); - fprintf(cpp, " if (path[0] == PATH_SEPARATOR_CHAR)\n"); - fprintf(cpp, " return true;\n"); - fprintf(cpp, " #endif\n"); - fprintf(cpp, " return false;\n"); - fprintf(cpp, " }\n"); - fprintf(cpp, " bool FileManager::createParentDirectories(const char * file_path) const\n"); - fprintf(cpp, " {\n"); - fprintf(cpp, " if (file_path == NULL)\n"); - fprintf(cpp, " return false;\n"); - fprintf(cpp, " std::string accumulator;\n"); - fprintf(cpp, " size_t length = strlen(file_path);\n"); - fprintf(cpp, " for(size_t i=0; i\n" + "#include // strlen\n" + "#include // stat\n" + "#include // errno, EEXIST\n" + "#if defined(_WIN32)\n" + "#include // _mkdir\n" + "#endif\n" + "\n" + "#if defined(_WIN32)\n" + "#define portable_stat _stat\n" + "#define portable_mkdir(path) _mkdir(path)\n" + "#define PATH_SEPARATOR_CHAR '\\\\'\n" + "#define PATH_SEPARATOR_STR \"\\\\\"\n" + "#else\n" + "#define portable_stat stat\n" + "#define portable_mkdir(path) mkdir(path, 0755)\n" + "#define PATH_SEPARATOR_CHAR '/'\n" + "#define PATH_SEPARATOR_STR \"/\"\n" + "#endif\n" + "\n" + "namespace ${bin2cpp_namespace}\n" + "{\n" + " bool RegisterFile(FileManager::t_func functionPointer)\n" + " {\n" + " if (functionPointer == NULL)\n" + " return false;\n" + " FileManager::getInstance().registerFile(functionPointer);\n" + " return true;\n" + " }\n" + " FileManager::FileManager() {}\n" + " FileManager::~FileManager() {}\n" + " FileManager & FileManager::getInstance() { static FileManager _mgr; return _mgr; }\n" + " void FileManager::registerFile(t_func func) { functions_.push_back(func); }\n" + " size_t FileManager::getFileCount() const { return functions_.size(); }\n" + " const File * FileManager::getFile(const size_t & index) const\n" + " {\n" + " if (index >= functions_.size())\n" + " return NULL;\n" + " t_func ressource_getter_function = functions_[index];\n" + " const ${bin2cpp_namespace}::File & resource = ressource_getter_function();\n" + " return &resource;\n" + " }\n" + " bool FileManager::saveFiles(const char * directory) const\n" + " {\n" + " if (directory == NULL)\n" + " return false;\n" + " size_t count = getFileCount();\n" + " for(size_t i=0; igetFilePath());\n" + " if (!createParentDirectories(path.c_str()))\n" + " return false;\n" + " bool saved = f->save(path.c_str());\n" + " if (!saved)\n" + " return false;\n" + " }\n" + " return true;\n" + " }\n" + " static inline bool isRootDirectory(const char * path)\n" + " {\n" + " if (path == NULL && path[0] == '\\0')\n" + " return false;\n" + " #if defined(_WIN32)\n" + " bool isDriveLetter = ((path[0] >= 'a' && path[0] <= 'z') || (path[0] >= 'A' && path[0] <= 'Z'));\n" + " if ((isDriveLetter && path[1] == ':' && path[2] == '\\0') || // test for C:\n" + " (isDriveLetter && path[1] == ':' && path[2] == PATH_SEPARATOR_CHAR && path[3] == '\\0')) // test for C:\\ \n" + " return true;\n" + " #else\n" + " if (path[0] == PATH_SEPARATOR_CHAR)\n" + " return true;\n" + " #endif\n" + " return false;\n" + " }\n" + " bool FileManager::createParentDirectories(const char * file_path) const\n" + " {\n" + " if (file_path == NULL)\n" + " return false;\n" + " std::string accumulator;\n" + " size_t length = strlen(file_path);\n" + " for(size_t i=0; i\n" + "#include \n" + "\n" + "#ifndef ${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_STRUCT\n" + "#define ${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_STRUCT\n" + "typedef struct ${bin2cpp_baseclass} ${bin2cpp_baseclass};\n" + "typedef bool(*${bin2cpp_namespace}_load_func)();\n" + "typedef void(*${bin2cpp_namespace}_free_func)();\n" + "typedef bool(*${bin2cpp_namespace}_save_func)(const char*);\n" + "typedef struct ${bin2cpp_baseclass}\n" + "{\n" + " size_t size;\n" + " const char* file_name;\n" + " const char* file_path;\n" + " const unsigned char* buffer;\n" + " ${bin2cpp_namespace}_load_func load;\n" + " ${bin2cpp_namespace}_free_func unload;\n" + " ${bin2cpp_namespace}_save_func save;\n" + "} ${bin2cpp_baseclass};\n" + "typedef ${bin2cpp_baseclass}* ${bin2cpp_baseclass}Ptr;\n" + "#endif //${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_STRUCT\n" + "\n" + "size_t ${bin2cpp_namespace}_filemanager_get_file_count();\n" + "bool ${bin2cpp_namespace}_filemanager_register_file(${bin2cpp_baseclass}* file);\n" + "const ${bin2cpp_baseclass}* ${bin2cpp_namespace}_filemanager_get_file(size_t index);\n" + "bool ${bin2cpp_namespace}_filemanager_save_files(const char* directory);\n" + "\n" + "#endif //${bin2cpp_file_manager_macro_guard_prefix}\n" + ; - //define macro guard a macro matching the filename - std::string macroGuard; - macroGuard += getCppIncludeGuardMacroName(mContext.codeNamespace.c_str()); //prefix the custom namespace for the file manager - if ( !macroGuard.empty() ) - macroGuard += "_"; - macroGuard += getCppIncludeGuardMacroName(file_path); + TemplateProcessor processor(&text); + processor.setTemplateVariableLookup(this); + bool write_success = processor.writeFile(file_path); - std::string classMacroGuardPrefix = getClassMacroGuardPrefix(); - std::string fileHeader = getHeaderTemplate(false); - - fprintf(fout, "%s", fileHeader.c_str()); - fprintf(fout, "#ifndef %s\n", macroGuard.c_str()); - fprintf(fout, "#define %s\n", macroGuard.c_str()); - fprintf(fout, "\n"); - fprintf(fout, "#include \n"); - fprintf(fout, "#include \n"); - fprintf(fout, "\n"); - fprintf(fout, "#ifndef %s_EMBEDDEDFILE_STRUCT\n", classMacroGuardPrefix.c_str()); - fprintf(fout, "#define %s_EMBEDDEDFILE_STRUCT\n", classMacroGuardPrefix.c_str()); - fprintf(fout, "typedef struct %s %s;\n", mContext.baseClass.c_str(), mContext.baseClass.c_str()); - fprintf(fout, "typedef bool(*%s_load_func)();\n", mContext.codeNamespace.c_str()); - fprintf(fout, "typedef void(*%s_free_func)();\n", mContext.codeNamespace.c_str()); - fprintf(fout, "typedef bool(*%s_save_func)(const char*);\n", mContext.codeNamespace.c_str()); - fprintf(fout, "typedef struct %s\n", mContext.baseClass.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " size_t size;\n"); - fprintf(fout, " const char* file_name;\n"); - fprintf(fout, " const char* file_path;\n"); - fprintf(fout, " const unsigned char* buffer;\n"); - fprintf(fout, " %s_load_func load;\n", mContext.codeNamespace.c_str()); - fprintf(fout, " %s_free_func unload;\n", mContext.codeNamespace.c_str()); - fprintf(fout, " %s_save_func save;\n", mContext.codeNamespace.c_str()); - fprintf(fout, "} %s;\n", mContext.baseClass.c_str()); - fprintf(fout, "typedef %s* %sPtr;\n", mContext.baseClass.c_str(), mContext.baseClass.c_str()); - fprintf(fout, "#endif //%s_EMBEDDEDFILE_STRUCT\n", classMacroGuardPrefix.c_str()); - fprintf(fout, "\n"); - fprintf(fout, "size_t %s_filemanager_get_file_count();\n", mContext.codeNamespace.c_str()); - fprintf(fout, "bool %s_filemanager_register_file(%s* file);\n", mContext.codeNamespace.c_str(), mContext.baseClass.c_str()); - fprintf(fout, "const %s* %s_filemanager_get_file(size_t index);\n", mContext.baseClass.c_str(), mContext.codeNamespace.c_str()); - fprintf(fout, "bool %s_filemanager_save_files(const char* directory);\n", mContext.codeNamespace.c_str()); - fprintf(fout, "\n"); - fprintf(fout, "#endif //%s\n", macroGuard.c_str()); - - fclose(fout); - - return true; + return write_success; } bool ManagerGenerator::createCSourceFile(const char* file_path) { - FILE* fout = fopen(file_path, "w"); - if ( !fout ) - return false; - - //Build header and cpp file path - std::string headerPath = getHeaderFilePath(file_path); - std::string sourcePath = file_path; - - std::string fileHeader = getHeaderTemplate(false); - - fprintf(fout, "%s", fileHeader.c_str()); - fprintf(fout, "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n"); - fprintf(fout, "#define _CRT_SECURE_NO_WARNINGS\n"); - fprintf(fout, "#endif\n"); - fprintf(fout, "\n"); - fprintf(fout, "#include \"%s\"\n", mContext.managerHeaderFilename.c_str()); - fprintf(fout, "#include // for malloc\n"); - fprintf(fout, "#include // for snprintf()\n"); - fprintf(fout, "#include // strlen\n"); - fprintf(fout, "#include // stat\n"); - fprintf(fout, "#include // errno, EEXIST\n"); - fprintf(fout, "#if defined(_WIN32)\n"); - fprintf(fout, "#include // _mkdir\n"); - fprintf(fout, "#endif\n"); - fprintf(fout, "#if defined(_WIN32)\n"); - fprintf(fout, "#define portable_stat _stat\n"); - fprintf(fout, "#define portable_mkdir(path) _mkdir(path)\n"); - fprintf(fout, "#define PATH_SEPARATOR_CHAR '\\\\'\n"); - fprintf(fout, "#define PATH_SEPARATOR_STR \"\\\\\"\n"); - fprintf(fout, "#else\n"); - fprintf(fout, "#define portable_stat stat\n"); - fprintf(fout, "#define portable_mkdir(path) mkdir(path, 0755)\n"); - fprintf(fout, "#define PATH_SEPARATOR_CHAR '/'\n"); - fprintf(fout, "#define PATH_SEPARATOR_STR \"/\"\n"); - fprintf(fout, "#endif\n"); - fprintf(fout, "\n"); - fprintf(fout, "#define BIN2C_MAX_PATH 32767\n"); - fprintf(fout, "\n"); - fprintf(fout, "static %s** registered_files = NULL;\n", mContext.baseClass.c_str()); - fprintf(fout, "static size_t registered_files_count = 0;\n"); - fprintf(fout, "\n"); - fprintf(fout, "size_t %s_filemanager_get_file_count()\n", mContext.codeNamespace.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " return registered_files_count;\n"); - fprintf(fout, "}\n"); - fprintf(fout, "\n"); - fprintf(fout, "bool %s_filemanager_register_file(%s* file)\n", mContext.codeNamespace.c_str(), mContext.baseClass.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " // check if already registered\n"); - fprintf(fout, " if ( registered_files_count && registered_files )\n"); - fprintf(fout, " {\n"); - fprintf(fout, " for ( size_t i = 0; i < registered_files_count; i++ )\n"); - fprintf(fout, " {\n"); - fprintf(fout, " const %s* existing_file = registered_files[i];\n", mContext.baseClass.c_str()); - fprintf(fout, " if ( existing_file == file )\n"); - fprintf(fout, " return true; // nothing to do\n"); - fprintf(fout, " }\n"); - fprintf(fout, " }\n"); - fprintf(fout, " \n"); - fprintf(fout, " // allocate ram\n"); - fprintf(fout, " size_t new_ram_size = sizeof(%s**) * (registered_files_count + 1);\n", mContext.baseClass.c_str()); - fprintf(fout, " %s** tmp = NULL;\n", mContext.baseClass.c_str()); - fprintf(fout, " if ( registered_files == NULL )\n"); - fprintf(fout, " tmp = (%s**)malloc(new_ram_size);\n", mContext.baseClass.c_str()); - fprintf(fout, " else\n"); - fprintf(fout, " tmp = (%s**)realloc(registered_files, new_ram_size);\n", mContext.baseClass.c_str()); - fprintf(fout, " if ( tmp == NULL )\n"); - fprintf(fout, " return false;\n"); - fprintf(fout, " \n"); - fprintf(fout, " registered_files = tmp;\n"); - fprintf(fout, " registered_files_count++;\n"); - fprintf(fout, " \n"); - fprintf(fout, " // insert\n"); - fprintf(fout, " registered_files[registered_files_count - 1] = file;\n"); - fprintf(fout, " \n"); - fprintf(fout, " return true;\n"); - fprintf(fout, "}\n"); - fprintf(fout, "\n"); - fprintf(fout, "const %s* %s_filemanager_get_file(size_t index)\n", mContext.baseClass.c_str(), mContext.codeNamespace.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " if ( index >= registered_files_count )\n"); - fprintf(fout, " return NULL;\n"); - fprintf(fout, " return registered_files[index];\n"); - fprintf(fout, "}\n"); - fprintf(fout, "\n"); - fprintf(fout, "static inline bool %s_filemanager_is_root_directory(const char* path)\n", mContext.codeNamespace.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " if ( path == NULL && path[0] == '\\0' )\n"); - fprintf(fout, " return false;\n"); - fprintf(fout, "#if defined(_WIN32)\n"); - fprintf(fout, " bool is_drive_letter = ((path[0] >= 'a' && path[0] <= 'z') || (path[0] >= 'A' && path[0] <= 'Z'));\n"); - fprintf(fout, " if ( (is_drive_letter && path[1] == ':' && path[2] == '\\0') || // test for C:\n"); - fprintf(fout, " (is_drive_letter && path[1] == ':' && path[2] == PATH_SEPARATOR_CHAR && path[3] == '\\0') ) // test for C:\\ \n"); - fprintf(fout, " return true;\n"); - fprintf(fout, "#else\n"); - fprintf(fout, " if ( path[0] == PATH_SEPARATOR_CHAR )\n"); - fprintf(fout, " return true;\n"); - fprintf(fout, "#endif\n"); - fprintf(fout, " return false;\n"); - fprintf(fout, "}\n"); - fprintf(fout, "\n"); - fprintf(fout, "bool %s_filemanager_create_parent_directories(const char* file_path)\n", mContext.codeNamespace.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " if ( file_path == NULL )\n"); - fprintf(fout, " return false;\n"); - fprintf(fout, " char* accumulator = (char*)malloc(BIN2C_MAX_PATH);\n"); - fprintf(fout, " if ( accumulator == NULL )\n"); - fprintf(fout, " return false;\n"); - fprintf(fout, " accumulator[0] = '\\0';\n"); - fprintf(fout, " size_t length = strlen(file_path);\n"); - fprintf(fout, " for ( size_t i = 0; i < length; i++ )\n"); - fprintf(fout, " {\n"); - fprintf(fout, " if ( file_path[i] == PATH_SEPARATOR_CHAR && !(accumulator[0] == '\\0') && !%s_filemanager_is_root_directory(accumulator) )\n", mContext.codeNamespace.c_str()); - fprintf(fout, " {\n"); - fprintf(fout, " int ret = portable_mkdir(accumulator);\n"); - fprintf(fout, " if ( ret != 0 && errno != EEXIST )\n"); - fprintf(fout, " {\n"); - fprintf(fout, " free(accumulator);\n"); - fprintf(fout, " return false;\n"); - fprintf(fout, " }\n"); - fprintf(fout, " }\n"); - fprintf(fout, " \n"); - fprintf(fout, " // append\n"); - fprintf(fout, " char tmp[] = { file_path[i], '\\0' };\n"); - fprintf(fout, " strcat(accumulator, tmp);\n"); - fprintf(fout, " }\n"); - fprintf(fout, " free(accumulator);\n"); - fprintf(fout, " return true;\n"); - fprintf(fout, "}\n"); - fprintf(fout, "\n"); - fprintf(fout, "bool %s_filemanager_save_files(const char * directory)\n", mContext.codeNamespace.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " if (directory == NULL)\n"); - fprintf(fout, " return false;\n"); - fprintf(fout, " char* path = (char*)malloc(BIN2C_MAX_PATH);\n"); - fprintf(fout, " if ( path == NULL )\n"); - fprintf(fout, " return false;\n"); - fprintf(fout, " path[0] = '\\0';\n"); - fprintf(fout, " for(size_t i=0; i< registered_files_count; i++)\n"); - fprintf(fout, " {\n"); - fprintf(fout, " const %s* f = %s_filemanager_get_file(i);\n", mContext.baseClass.c_str(), mContext.codeNamespace.c_str()); - fprintf(fout, " if ( !f )\n"); - fprintf(fout, " {\n"); - fprintf(fout, " free(path);\n"); - fprintf(fout, " return false;\n"); - fprintf(fout, " }\n"); - fprintf(fout, " \n"); - fprintf(fout, " snprintf(path, sizeof(path), \"%%s%%c%%s\", directory, PATH_SEPARATOR_CHAR, f->file_path);\n"); - fprintf(fout, " \n"); - fprintf(fout, " if (!%s_filemanager_create_parent_directories(path))\n", mContext.codeNamespace.c_str()); - fprintf(fout, " {\n"); - fprintf(fout, " free(path);\n"); - fprintf(fout, " return false;\n"); - fprintf(fout, " }\n"); - fprintf(fout, " bool saved = f->save(path);\n"); - fprintf(fout, " if (!saved)\n"); - fprintf(fout, " {\n"); - fprintf(fout, " free(path);\n"); - fprintf(fout, " return false;\n"); - fprintf(fout, " }\n"); - fprintf(fout, " }\n"); - fprintf(fout, " free(path);\n"); - fprintf(fout, " return true;\n"); - fprintf(fout, "}\n"); - fprintf(fout, "\n"); + const std::string text = "" + "${bin2cpp_filemanager_file_header}" + "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" + "#define _CRT_SECURE_NO_WARNINGS\n" + "#endif\n" + "\n" + "#include \"${bin2cpp_file_manager_header_file_name}\"\n" + "#include // for malloc\n" + "#include // for snprintf()\n" + "#include // strlen\n" + "#include // stat\n" + "#include // errno, EEXIST\n" + "#if defined(_WIN32)\n" + "#include // _mkdir\n" + "#endif\n" + "#if defined(_WIN32)\n" + "#define portable_stat _stat\n" + "#define portable_mkdir(path) _mkdir(path)\n" + "#define PATH_SEPARATOR_CHAR '\\\\'\n" + "#define PATH_SEPARATOR_STR \"\\\\\"\n" + "#else\n" + "#define portable_stat stat\n" + "#define portable_mkdir(path) mkdir(path, 0755)\n" + "#define PATH_SEPARATOR_CHAR '/'\n" + "#define PATH_SEPARATOR_STR \"/\"\n" + "#endif\n" + "\n" + "#define BIN2C_MAX_PATH 32767\n" + "\n" + "static ${bin2cpp_baseclass}** registered_files = NULL;\n" + "static size_t registered_files_count = 0;\n" + "\n" + "size_t ${bin2cpp_namespace}_filemanager_get_file_count()\n" + "{\n" + " return registered_files_count;\n" + "}\n" + "\n" + "bool ${bin2cpp_namespace}_filemanager_register_file(${bin2cpp_baseclass}* file)\n" + "{\n" + " // check if already registered\n" + " if ( registered_files_count && registered_files )\n" + " {\n" + " for ( size_t i = 0; i < registered_files_count; i++ )\n" + " {\n" + " const ${bin2cpp_baseclass}* existing_file = registered_files[i];\n" + " if ( existing_file == file )\n" + " return true; // nothing to do\n" + " }\n" + " }\n" + " \n" + " // allocate ram\n" + " size_t new_ram_size = sizeof(${bin2cpp_baseclass}**) * (registered_files_count + 1);\n" + " ${bin2cpp_baseclass}** tmp = NULL;\n" + " if ( registered_files == NULL )\n" + " tmp = (${bin2cpp_baseclass}**)malloc(new_ram_size);\n" + " else\n" + " tmp = (${bin2cpp_baseclass}**)realloc(registered_files, new_ram_size);\n" + " if ( tmp == NULL )\n" + " return false;\n" + " \n" + " registered_files = tmp;\n" + " registered_files_count++;\n" + " \n" + " // insert\n" + " registered_files[registered_files_count - 1] = file;\n" + " \n" + " return true;\n" + "}\n" + "\n" + "const ${bin2cpp_baseclass}* ${bin2cpp_namespace}_filemanager_get_file(size_t index)\n" + "{\n" + " if ( index >= registered_files_count )\n" + " return NULL;\n" + " return registered_files[index];\n" + "}\n" + "\n" + "static inline bool ${bin2cpp_namespace}_filemanager_is_root_directory(const char* path)\n" + "{\n" + " if ( path == NULL && path[0] == '\\0' )\n" + " return false;\n" + "#if defined(_WIN32)\n" + " bool is_drive_letter = ((path[0] >= 'a' && path[0] <= 'z') || (path[0] >= 'A' && path[0] <= 'Z'));\n" + " if ( (is_drive_letter && path[1] == ':' && path[2] == '\\0') || // test for C:\n" + " (is_drive_letter && path[1] == ':' && path[2] == PATH_SEPARATOR_CHAR && path[3] == '\\0') ) // test for C:\\ \n" + " return true;\n" + "#else\n" + " if ( path[0] == PATH_SEPARATOR_CHAR )\n" + " return true;\n" + "#endif\n" + " return false;\n" + "}\n" + "\n" + "bool ${bin2cpp_namespace}_filemanager_create_parent_directories(const char* file_path)\n" + "{\n" + " if ( file_path == NULL )\n" + " return false;\n" + " char* accumulator = (char*)malloc(BIN2C_MAX_PATH);\n" + " if ( accumulator == NULL )\n" + " return false;\n" + " accumulator[0] = '\\0';\n" + " size_t length = strlen(file_path);\n" + " for ( size_t i = 0; i < length; i++ )\n" + " {\n" + " if ( file_path[i] == PATH_SEPARATOR_CHAR && !(accumulator[0] == '\\0') && !${bin2cpp_namespace}_filemanager_is_root_directory(accumulator) )\n" + " {\n" + " int ret = portable_mkdir(accumulator);\n" + " if ( ret != 0 && errno != EEXIST )\n" + " {\n" + " free(accumulator);\n" + " return false;\n" + " }\n" + " }\n" + " \n" + " // append\n" + " char tmp[] = { file_path[i], '\\0' };\n" + " strcat(accumulator, tmp);\n" + " }\n" + " free(accumulator);\n" + " return true;\n" + "}\n" + "\n" + "bool ${bin2cpp_namespace}_filemanager_save_files(const char * directory)\n" + "{\n" + " if (directory == NULL)\n" + " return false;\n" + " char* path = (char*)malloc(BIN2C_MAX_PATH);\n" + " if ( path == NULL )\n" + " return false;\n" + " path[0] = '\\0';\n" + " for(size_t i=0; i< registered_files_count; i++)\n" + " {\n" + " const ${bin2cpp_baseclass}* f = ${bin2cpp_namespace}_filemanager_get_file(i);\n" + " if ( !f )\n" + " {\n" + " free(path);\n" + " return false;\n" + " }\n" + " \n" + " snprintf(path, sizeof(path), \"%s%c%s\", directory, PATH_SEPARATOR_CHAR, f->file_path);\n" + " \n" + " if (!${bin2cpp_namespace}_filemanager_create_parent_directories(path))\n" + " {\n" + " free(path);\n" + " return false;\n" + " }\n" + " bool saved = f->save(path);\n" + " if (!saved)\n" + " {\n" + " free(path);\n" + " return false;\n" + " }\n" + " }\n" + " free(path);\n" + " return true;\n" + "}\n" + "\n" + ; - fclose(fout); + TemplateProcessor processor(&text); + processor.setTemplateVariableLookup(this); + bool write_success = processor.writeFile(file_path); - return true; + return write_success; } bool ManagerGenerator::printFileContent() diff --git a/src/bin2cpp/ManagerGenerator.h b/src/bin2cpp/ManagerGenerator.h index a6d7981..7bad555 100644 --- a/src/bin2cpp/ManagerGenerator.h +++ b/src/bin2cpp/ManagerGenerator.h @@ -39,8 +39,8 @@ namespace bin2cpp ManagerGenerator(); virtual ~ManagerGenerator(); virtual const char * getName() const; - virtual bool createCppHeaderFile(const char* header_file_path); - virtual bool createCppSourceFile(const char * cpp_file_path); + virtual bool createCppHeaderFile(const char* file_path); + virtual bool createCppSourceFile(const char * file_path); virtual bool createCHeaderFile(const char* file_path); virtual bool createCSourceFile(const char* file_path); virtual bool printFileContent(); diff --git a/src/bin2cpp/bin2cpp.samples.txt b/src/bin2cpp/bin2cpp.samples.txt index 1fcaa88..1790bac 100644 --- a/src/bin2cpp/bin2cpp.samples.txt +++ b/src/bin2cpp/bin2cpp.samples.txt @@ -44,6 +44,12 @@ Test all generators --file=..\..\test\bin2cpp_unittest\generated_files\testGeneratorString10000\testGeneratorString10000.bin --output=..\..\test\bin2cpp_unittest\generated_files\testGeneratorString10000 --headerfile=_testGeneratorString10000.h --identifier=testGeneratorString10000 --chunksize=450 --override --generator=string --file=..\..\test\bin2cpp_unittest\generated_files\testGeneratorWin32\testGeneratorWin32.bin --output=..\..\test\bin2cpp_unittest\generated_files\testGeneratorWin32 --headerfile=_testGeneratorWin32.h --identifier=testGeneratorWin32 --chunksize=450 --override --generator=win32 +Test as much features as possible with all generators: +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_tim_testHtml100000.h --identifier=LibFooFOO --chunksize=75 --baseclass=ben --namespace=ray --managerfile=cpp_tim_filemanager.h --registerfile --override --code=cpp --generator=array +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_jim_testHtml100000.h --identifier=LibBarBAR --chunksize=75 --baseclass=tom --namespace=eva --managerfile=cpp_jim_filemanager.h --registerfile --override --code=cpp --generator=segment +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_lou_testHtml100000.h --identifier=LibBazBAZ --chunksize=75 --baseclass=sam --namespace=joe --managerfile=cpp_lou_filemanager.h --registerfile --override --code=cpp --generator=string +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_sue_testHtml100000.h --identifier=LibBobBOB --chunksize=75 --baseclass=leo --namespace=jon --managerfile=cpp_sue_filemanager.h --registerfile --override --code=cpp --generator=win32 + Test plain output: --plainoutput --chunksize=75 --file=..\..\test\bin2cpp_unittest\generated_files\testSequential1000\testSequential1000.bin --generator=array --plainoutput --chunksize=75 --file=..\..\test\bin2cpp_unittest\generated_files\testSequential1000\testSequential1000.bin --generator=segment diff --git a/src/bin2cpp/main.cpp b/src/bin2cpp/main.cpp index d5763f0..c70cdab 100755 --- a/src/bin2cpp/main.cpp +++ b/src/bin2cpp/main.cpp @@ -558,6 +558,9 @@ int main(int argc, char* argv[]) //should we also generate the FileManager class? if (c.hasManagerFile) { + //for the manager, header file name is the same as a normal output file header file name + c.headerFilename = c.managerHeaderFilename; + APP_ERROR_CODES error = processManagerFiles(c); if (error != APP_ERROR_SUCCESS) { @@ -837,6 +840,7 @@ APP_ERROR_CODES processManagerFiles(const Context & c) //configure the generator generator.setContext(c); + //process files bool headerResult = generateOutputFile(c, outputHeaderPath, &generator); if (!headerResult) From e440dd07bfc572a02f1a770c63929a21244f53f7 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sat, 24 May 2025 08:17:43 -0400 Subject: [PATCH 10/26] Modified SegmentGenerator to use TemplateProcessor. --- src/bin2cpp/ArrayGenerator.cpp | 7 +- src/bin2cpp/ArrayGenerator.h | 4 +- src/bin2cpp/SegmentGenerator.cpp | 430 +++++++++++++------------------ src/bin2cpp/SegmentGenerator.h | 3 +- 4 files changed, 179 insertions(+), 265 deletions(-) diff --git a/src/bin2cpp/ArrayGenerator.cpp b/src/bin2cpp/ArrayGenerator.cpp index e56418f..2556e77 100644 --- a/src/bin2cpp/ArrayGenerator.cpp +++ b/src/bin2cpp/ArrayGenerator.cpp @@ -71,7 +71,7 @@ namespace bin2cpp " virtual const char * getFilePath() const { ${bin2cpp_cpp_get_file_path_impl} }\n" " virtual const char * getBuffer() const\n" " {\n" - " static const unsigned char buffer[] = {\n${bin2cpp_insert_input_file_as_code}" + " static const unsigned char buffer[] = {\n${bin2cpp_insert_input_file_as_code}" // INPUT FILE AS CODE HERE " };\n" " return (const char *)buffer;\n" " }\n" @@ -123,7 +123,7 @@ namespace bin2cpp "{\n" " if ( ${bin2cpp_function_identifier_lowercase}_file.buffer )\n" " return true;\n" - " static const unsigned char static_buffer[] = {\n${bin2cpp_insert_input_file_as_code}" + " static const unsigned char static_buffer[] = {\n${bin2cpp_insert_input_file_as_code}" // INPUT FILE AS CODE HERE " };\n" "\n" " ${bin2cpp_function_identifier_lowercase}_file.buffer = static_buffer;\n" @@ -176,8 +176,7 @@ namespace bin2cpp " ${bin2cpp_function_identifier_lowercase}_init();\n" " return &${bin2cpp_function_identifier_lowercase}_file;\n" "}\n" - "${bin2cpp_c_file_manager_registration_implementation}" - ; + "${bin2cpp_c_file_manager_registration_implementation}"; TemplateProcessor processor(&text); processor.setTemplateVariableLookup(this); diff --git a/src/bin2cpp/ArrayGenerator.h b/src/bin2cpp/ArrayGenerator.h index 68d6e3f..2d7cb91 100644 --- a/src/bin2cpp/ArrayGenerator.h +++ b/src/bin2cpp/ArrayGenerator.h @@ -40,8 +40,8 @@ namespace bin2cpp ArrayGenerator(); virtual ~ArrayGenerator(); virtual const char * getName() const; - virtual bool createCppSourceFile(const char * cpp_file_path); - virtual bool createCSourceFile(const char * cpp_file_path); + virtual bool createCppSourceFile(const char * file_path); + virtual bool createCSourceFile(const char * file_path); virtual bool printFileContent(); virtual std::string getInputFileChunkAsCode(const unsigned char * buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk); }; diff --git a/src/bin2cpp/SegmentGenerator.cpp b/src/bin2cpp/SegmentGenerator.cpp index fbc0fec..40151a2 100755 --- a/src/bin2cpp/SegmentGenerator.cpp +++ b/src/bin2cpp/SegmentGenerator.cpp @@ -23,6 +23,7 @@ *********************************************************************************/ #include "SegmentGenerator.h" +#include "TemplateProcessor.h" #include #include #include @@ -47,284 +48,197 @@ namespace bin2cpp return "segment"; } - bool SegmentGenerator::createCppSourceFile(const char * cpp_file_path) + bool SegmentGenerator::createCppSourceFile(const char * file_path) { //check if input file exists - FILE * input = fopen(mContext.inputFilePath.c_str(), "rb"); - if (!input) + if ( !ra::filesystem::FileExists(mContext.inputFilePath.c_str()) ) return false; - //Uppercase function identifier - std::string functionIdentifier = ra::strings::CapitalizeFirstCharacter(getContext().functionIdentifier); - - //Build header and cpp file path - std::string headerPath = getHeaderFilePath(cpp_file_path); - std::string cppPath = cpp_file_path; - - //create cpp source file - FILE * cpp = fopen(cppPath.c_str(), "w"); - if (!cpp) - { - fclose(input); - return false; - } - - //determine file properties - uint32_t fileSize = ra::filesystem::GetFileSize(input); - std::string filename = ra::filesystem::GetFilename(mContext.inputFilePath.c_str()); - //long lastSegmentSize = fileSize%chunk_size; - //size_t numSegments = fileSize/chunk_size + (lastSegmentSize == 0 ? 0 : 1); - - //Build class name - std::string className = getClassName(); - - //Build function - std::string getterFunctionName = getGetterFunctionName(); - - //Build FileManager class template - std::string manager = mContext.managerHeaderFilename; - - //write cpp file heading - fprintf(cpp, "%s", getHeaderTemplate().c_str()); - fprintf(cpp, "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n"); - fprintf(cpp, "#define _CRT_SECURE_NO_WARNINGS\n"); - fprintf(cpp, "#endif\n"); - fprintf(cpp, "#include \"%s\"\n", mContext.headerFilename.c_str() ); - fprintf(cpp, "#include //for std::string\n"); - fprintf(cpp, "#include \n"); - fprintf(cpp, "#include //for ofstream\n"); - fprintf(cpp, "namespace %s\n", getContext().codeNamespace.c_str()); - fprintf(cpp, "{\n"); - fprintf(cpp, " class %s : public virtual %s::%s\n", className.c_str(), getContext().codeNamespace.c_str(), getContext().baseClass.c_str()); - fprintf(cpp, " {\n"); - fprintf(cpp, " public:\n"); - fprintf(cpp, " %s() { build(); }\n", className.c_str()); - fprintf(cpp, " virtual ~%s() {}\n", className.c_str()); - fprintf(cpp, " virtual size_t getSize() const { return %u; }\n", fileSize); - fprintf(cpp, " virtual const char * getFileName() const { %s }\n", getImplOfGetFileName().c_str()); - fprintf(cpp, " virtual const char * getFilePath() const { %s }\n", getImplOfGetFilePath().c_str()); - fprintf(cpp, " virtual const char * getBuffer() const { return mBuffer.c_str(); }\n"); - fprintf(cpp, " void build()\n"); - fprintf(cpp, " {\n"); - fprintf(cpp, " mBuffer.clear();\n"); - fprintf(cpp, " mBuffer.reserve(getSize()); //allocate all required memory at once to prevent reallocations\n"); - - //create buffer for each chunks from input buffer - unsigned char * buffer = new unsigned char[getContext().chunkSize]; - while(!feof(input)) - { - //read a chunk of the file - size_t readSize = fread(buffer, 1, getContext().chunkSize, input); - - //bool isLastChunk = !(readSize == chunk_size); - - if (readSize == 0) - continue; //nothing to output if nothing was read - - //convert to cpp string - std::string cppEncoder; - switch(getContext().cppEncoder) - { - case CPP_ENCODER_HEX: - cppEncoder = ra::code::cpp::ToHexString(buffer, readSize); - break; - case CPP_ENCODER_OCT: - default: - cppEncoder = ra::code::cpp::ToOctString(buffer, readSize, false); - break; - }; - - //output - fprintf(cpp, " mBuffer.append(\"%s\", %s);\n", cppEncoder.c_str(), ra::strings::ToString(readSize).c_str()); - } - delete[] buffer; - buffer = NULL; - - //write cpp source file footer - fprintf(cpp, " }\n"); - fprintf(cpp, "%s", getSaveMethodTemplate().c_str()); - fprintf(cpp, " private:\n"); - fprintf(cpp, " std::string mBuffer;\n"); - fprintf(cpp, " };\n"); - fprintf(cpp, " const %s & %s() { static %s _instance; return _instance; }\n", getContext().baseClass.c_str(), getterFunctionName.c_str(), className.c_str()); - if (mContext.registerFiles) - { - std::string fileManagerTemplate = getCppFileManagerRegistrationImplementationTemplate(); - fprintf(cpp, "%s", fileManagerTemplate.c_str()); - } - fprintf(cpp, "}; //%s\n", getContext().codeNamespace.c_str()); - - fclose(input); - fclose(cpp); - - return true; + const std::string text = "" + "${bin2cpp_output_file_header}" + "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" + "#define _CRT_SECURE_NO_WARNINGS\n" + "#endif\n" + "#include \"${bin2cpp_cpp_header_include_path}\"\n" + "#include //for std::string\n" + "#include \n" + "#include //for ofstream\n" + "namespace ${bin2cpp_namespace}\n" + "{\n" + " class ${bin2cpp_classname} : public virtual ${bin2cpp_namespace}::${bin2cpp_baseclass}\n" + " {\n" + " public:\n" + " ${bin2cpp_classname}() { build(); }\n" + " virtual ~${bin2cpp_classname}() {}\n" + " virtual size_t getSize() const { return ${bin2cpp_input_file_size}; }\n" + " virtual const char * getFileName() const { ${bin2cpp_cpp_get_file_name_impl} }\n" + " virtual const char * getFilePath() const { ${bin2cpp_cpp_get_file_path_impl} }\n" + " virtual const char * getBuffer() const { return mBuffer.c_str(); }\n" + " void build()\n" + " {\n" + " mBuffer.clear();\n" + " mBuffer.reserve(getSize()); //allocate all required memory at once to prevent reallocations\n${bin2cpp_insert_input_file_as_code}" // INPUT FILE AS CODE HERE + " }\n" + "${bin2cpp_cpp_get_save_method_impl}" + " private:\n" + " std::string mBuffer;\n" + " };\n" + " const ${bin2cpp_baseclass} & ${bin2cpp_cpp_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" + "${bin2cpp_cpp_get_file_manager_registration_impl}" + "}; //${bin2cpp_namespace}\n"; + + TemplateProcessor processor(&text); + processor.setTemplateVariableLookup(this); + bool write_success = processor.writeFile(file_path); + + return write_success; } bool SegmentGenerator::createCSourceFile(const char* file_path) { //check if input file exists - FILE* input = fopen(mContext.inputFilePath.c_str(), "rb"); - if ( !input ) + if ( !ra::filesystem::FileExists(mContext.inputFilePath.c_str()) ) return false; - //Lowercase function identifier - std::string functionIdentifier = ra::strings::Lowercase(mContext.functionIdentifier); - - //Build header and cpp file path - std::string headerPath = getHeaderFilePath(file_path); - std::string sourcePath = file_path; + const std::string text = "" + "${bin2cpp_output_file_header}" + "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" + "#define _CRT_SECURE_NO_WARNINGS\n" + "#endif\n" + "#include \"${bin2cpp_cpp_header_include_path}\"\n" + "#include // for malloc\n" + "#include // for memset\n" + "#include // for fopen\n" + "static ${bin2cpp_baseclass} ${bin2cpp_function_identifier_lowercase}_file = { 0 };\n" + "static bool ${bin2cpp_function_identifier_lowercase}_initialized = false;\n" + "\n" + "${bin2cpp_c_file_manager_registration_predeclaration}" + "bool ${bin2cpp_function_identifier_lowercase}_load()\n" + "{\n" + " if ( ${bin2cpp_function_identifier_lowercase}_file.buffer )\n" + " return true;\n" + "\n" + " unsigned char* local_buffer = (unsigned char*)malloc(${bin2cpp_function_identifier_lowercase}_file.size);\n" + " if ( local_buffer == NULL )\n" + " return false;\n" + "\n" + " unsigned char* next = local_buffer;\n${bin2cpp_insert_input_file_as_code}" // INPUT FILE AS CODE HERE + "\n" + " ${bin2cpp_function_identifier_lowercase}_file.buffer = local_buffer;\n" + " return true;\n" + "}\n" + "\n" + "void ${bin2cpp_function_identifier_lowercase}_free()\n" + "{\n" + " if ( ${bin2cpp_function_identifier_lowercase}_file.buffer )\n" + " free((unsigned char*)${bin2cpp_function_identifier_lowercase}_file.buffer);\n" + " ${bin2cpp_function_identifier_lowercase}_file.buffer = NULL;\n" + "}\n" + "\n" + "bool ${bin2cpp_function_identifier_lowercase}_save(const char* path)\n" + "{\n" + " if ( !${bin2cpp_function_identifier_lowercase}_file.buffer )\n" + " return false;\n" + " FILE* f = fopen(path, \"wb\");\n" + " if ( !f )\n" + " return false;\n" + " size_t write_size = fwrite(${bin2cpp_function_identifier_lowercase}_file.buffer, 1, ${bin2cpp_function_identifier_lowercase}_file.size, f);\n" + " fclose(f);\n" + " if ( write_size != ${bin2cpp_function_identifier_lowercase}_file.size )\n" + " return false;\n" + " return true;\n" + "}\n" + "\n" + "static inline void ${bin2cpp_function_identifier_lowercase}_init()\n" + "{\n" + " // remember we already initialized\n" + " if ( ${bin2cpp_function_identifier_lowercase}_initialized )\n" + " return;\n" + " ${bin2cpp_function_identifier_lowercase}_initialized = true;\n" + "\n" + " // initialize\n" + " ${bin2cpp_baseclass}* file = &${bin2cpp_function_identifier_lowercase}_file;\n" + " file->size = ${bin2cpp_input_file_size}ULL;\n" + " file->file_name = \"${bin2cpp_get_file_obj_file_name}\";\n" + " file->file_path = \"${bin2cpp_get_file_obj_file_path}\";\n" + " file->buffer = NULL;\n" + " file->load = ${bin2cpp_function_identifier_lowercase}_load;\n" + " file->unload = ${bin2cpp_function_identifier_lowercase}_free;\n" + " file->save = ${bin2cpp_function_identifier_lowercase}_save;\n" + "\n" + " // load file by default on init as in c++ implementation\n" + " file->load();\n" + "${bin2cpp_c_file_manager_registration_post_init_impl}" + "}\n" + "\n" + "${bin2cpp_baseclass}* ${bin2cpp_cpp_getter_function_name}(void)\n" + "{\n" + " ${bin2cpp_function_identifier_lowercase}_init();\n" + " return &${bin2cpp_function_identifier_lowercase}_file;\n" + "}\n" + "${bin2cpp_c_file_manager_registration_implementation}"; + + TemplateProcessor processor(&text); + processor.setTemplateVariableLookup(this); + bool write_success = processor.writeFile(file_path); + + return write_success; + } - //create c source file - FILE* fout = fopen(sourcePath.c_str(), "w"); - if ( !fout ) + std::string SegmentGenerator::getInputFileChunkAsCode(const unsigned char* buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk) + { + size_t indentation = 0; + + if ( mContext.plainOutput ) + indentation = 0; + else if ( mContext.code == CodeGenerationEnum::CODE_GENERATION_CPP ) + indentation = 6; + else if ( mContext.code == CodeGenerationEnum::CODE_GENERATION_C ) + indentation = 2; + + std::string output; + if ( indentation ) + output += std::string(indentation, ' '); + + //convert to cpp string + std::string code; + switch ( mContext.cppEncoder ) + { + case CPP_ENCODER_HEX: + code = ra::code::cpp::ToHexString(buffer, buffer_size); + break; + case CPP_ENCODER_OCT: + default: + code = ra::code::cpp::ToOctString(buffer, buffer_size, false); + break; + }; + + if ( mContext.plainOutput ) { - fclose(input); - return false; } - - //determine file properties - uint32_t fileSize = ra::filesystem::GetFileSize(input); - std::string filename = ra::filesystem::GetFilename(mContext.inputFilePath.c_str()); - //long lastSegmentSize = fileSize%chunk_size; - //size_t numSegments = fileSize/chunk_size + (lastSegmentSize == 0 ? 0 : 1); - - //Build class name - std::string className = getClassName(); - - //Build function - std::string getterFunctionName = getGetterFunctionName(); - - //Build FileManager class template - std::string manager = mContext.managerHeaderFilename; - - //write c file heading - fprintf(fout, "%s", getHeaderTemplate().c_str()); - fprintf(fout, "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n"); - fprintf(fout, "#define _CRT_SECURE_NO_WARNINGS\n"); - fprintf(fout, "#endif\n"); - fprintf(fout, "#include \"%s\"\n", mContext.headerFilename.c_str()); - fprintf(fout, "#include // for malloc\n"); - fprintf(fout, "#include // for memset\n"); - fprintf(fout, "#include // for fopen\n"); - - fprintf(fout, "static %s %s_file = { 0 };\n", mContext.baseClass.c_str(), functionIdentifier.c_str()); - fprintf(fout, "static bool %s_initialized = false;\n", functionIdentifier.c_str()); - fprintf(fout, "\n"); - - // File registration predeclaration code - fprintf(fout, "%s", getCFileManagerRegistrationPredeclarationImplementation().c_str()); - - fprintf(fout, "bool %s_load()\n", functionIdentifier.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " if ( %s_file.buffer )\n", functionIdentifier.c_str()); - fprintf(fout, " return true;\n"); - fprintf(fout, "\n"); - fprintf(fout, " unsigned char* local_buffer = (unsigned char*)malloc(%s_file.size);\n", functionIdentifier.c_str()); - fprintf(fout, " if ( local_buffer == NULL )\n"); - fprintf(fout, " return false;\n"); - fprintf(fout, "\n"); - fprintf(fout, " unsigned char* next = local_buffer;\n"); - - //create buffer for each chunks from input buffer - unsigned char* buffer = new unsigned char[getContext().chunkSize]; - while ( !feof(input) ) + else if ( mContext.code == CodeGenerationEnum::CODE_GENERATION_CPP ) { - //read a chunk of the file - size_t readSize = fread(buffer, 1, getContext().chunkSize, input); - - //bool isLastChunk = !(readSize == chunk_size); - - if ( readSize == 0 ) - continue; //nothing to output if nothing was read - - //convert to cpp string - std::string cppEncoder; - switch ( getContext().cppEncoder ) - { - case CPP_ENCODER_HEX: - cppEncoder = ra::code::cpp::ToHexString(buffer, readSize); - break; - case CPP_ENCODER_OCT: - default: - cppEncoder = ra::code::cpp::ToOctString(buffer, readSize, false); - break; - }; - - //output - fprintf(fout, " memcpy(next, \"%s\", %s); next += %s; \n", cppEncoder.c_str(), ra::strings::ToString(readSize).c_str(), ra::strings::ToString(readSize).c_str()); + output += "mBuffer.append(\""; + output += code; + output += "\", "; + output += ra::strings::ToString(buffer_size); + output += ");"; } - delete[] buffer; - buffer = NULL; - - //write c source file footer - fprintf(fout, "\n"); - fprintf(fout, " %s_file.buffer = local_buffer;\n", functionIdentifier.c_str()); - fprintf(fout, " return true;\n"); - fprintf(fout, "}\n"); - - fprintf(fout, "\n"); - - fprintf(fout, "void %s_free()\n", functionIdentifier.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " if ( %s_file.buffer )\n", functionIdentifier.c_str()); - fprintf(fout, " free((unsigned char*)%s_file.buffer);\n", functionIdentifier.c_str()); - fprintf(fout, " %s_file.buffer = NULL;\n", functionIdentifier.c_str()); - fprintf(fout, "}\n"); - fprintf(fout, "\n"); - fprintf(fout, "bool %s_save(const char* path)\n", functionIdentifier.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " if ( !%s_file.buffer )\n", functionIdentifier.c_str()); - fprintf(fout, " return false;\n"); - fprintf(fout, " FILE* f = fopen(path, \"wb\");\n"); - fprintf(fout, " if ( !f )\n"); - fprintf(fout, " return false;\n"); - fprintf(fout, " size_t write_size = fwrite(%s_file.buffer, 1, %s_file.size, f);\n", functionIdentifier.c_str(), functionIdentifier.c_str()); - fprintf(fout, " fclose(f);\n"); - fprintf(fout, " if ( write_size != %s_file.size )\n", functionIdentifier.c_str()); - fprintf(fout, " return false;\n"); - fprintf(fout, " return true;\n"); - fprintf(fout, "}\n"); - fprintf(fout, "\n"); - fprintf(fout, "static inline void %s_init()\n", functionIdentifier.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " // remember we already initialized\n"); - fprintf(fout, " if ( %s_initialized )\n", functionIdentifier.c_str()); - fprintf(fout, " return;\n"); - fprintf(fout, " %s_initialized = true;\n", functionIdentifier.c_str()); - fprintf(fout, "\n"); - fprintf(fout, " // initialize\n"); - fprintf(fout, " %s* file = &%s_file;\n", mContext.baseClass.c_str(), functionIdentifier.c_str()); - fprintf(fout, " file->size = %uULL;\n", fileSize); - fprintf(fout, " file->file_name = \"%s\";\n", getFileClassFileName().c_str()); - fprintf(fout, " file->file_path = \"%s\";\n", getFileClassFilePath().c_str()); - fprintf(fout, " file->buffer = NULL;\n"); - fprintf(fout, " file->load = %s_load;\n", functionIdentifier.c_str()); - fprintf(fout, " file->unload = %s_free;\n", functionIdentifier.c_str()); - fprintf(fout, " file->save = %s_save;\n", functionIdentifier.c_str()); - fprintf(fout, "\n"); - fprintf(fout, " // load file by default on init as in c++ implementation"); - fprintf(fout, " file->load();\n"); - if ( mContext.registerFiles ) + else if ( mContext.code == CodeGenerationEnum::CODE_GENERATION_C ) { - fprintf(fout, " \n"); - fprintf(fout, " // register when loaded if static initialisation does not work\n"); - fprintf(fout, " %s_filemanager_register_file(file);\n", mContext.codeNamespace.c_str()); + //fprintf(fout, " memcpy(next, \"%s\", %s); next += %s; \n", cppEncoder.c_str(), ra::strings::ToString(readSize).c_str(), ra::strings::ToString(readSize).c_str()); + output += "memcpy(next, \""; + output += code; + output += "\", "; + output += ra::strings::ToString(buffer_size); + output += "); next += "; + output += ra::strings::ToString(buffer_size); + output += ";"; } - fprintf(fout, "}\n"); - fprintf(fout, "\n"); - fprintf(fout, "%s* %s(void)\n", mContext.baseClass.c_str(), getGetterFunctionName().c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " %s_init();\n", functionIdentifier.c_str()); - fprintf(fout, " return &%s_file;\n", functionIdentifier.c_str()); - fprintf(fout, "}\n"); - - // File registration implementation code - fprintf(fout, "%s", getCFileManagerStaticFileRegistrationImplementation().c_str()); - fclose(input); - fclose(fout); + output += "\n"; - return true; + return output; } }; //bin2cpp \ No newline at end of file diff --git a/src/bin2cpp/SegmentGenerator.h b/src/bin2cpp/SegmentGenerator.h index 767eeaa..d85bab9 100644 --- a/src/bin2cpp/SegmentGenerator.h +++ b/src/bin2cpp/SegmentGenerator.h @@ -40,8 +40,9 @@ namespace bin2cpp SegmentGenerator(); virtual ~SegmentGenerator(); virtual const char * getName() const; - virtual bool createCppSourceFile(const char * cpp_file_path); + virtual bool createCppSourceFile(const char * file_path); virtual bool createCSourceFile(const char* file_path); + virtual std::string getInputFileChunkAsCode(const unsigned char* buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk); }; }; //bin2cpp From 19b57d7c90b2aeaf601e0eaace5f6b60d23aa473 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sat, 24 May 2025 09:31:10 -0400 Subject: [PATCH 11/26] Modified StringGenerator to use TemplateProcessor. --- src/bin2cpp/SegmentGenerator.cpp | 1 - src/bin2cpp/StringGenerator.cpp | 416 +++++++++++-------------------- src/bin2cpp/StringGenerator.h | 3 +- 3 files changed, 145 insertions(+), 275 deletions(-) diff --git a/src/bin2cpp/SegmentGenerator.cpp b/src/bin2cpp/SegmentGenerator.cpp index 40151a2..0e7c633 100755 --- a/src/bin2cpp/SegmentGenerator.cpp +++ b/src/bin2cpp/SegmentGenerator.cpp @@ -226,7 +226,6 @@ namespace bin2cpp } else if ( mContext.code == CodeGenerationEnum::CODE_GENERATION_C ) { - //fprintf(fout, " memcpy(next, \"%s\", %s); next += %s; \n", cppEncoder.c_str(), ra::strings::ToString(readSize).c_str(), ra::strings::ToString(readSize).c_str()); output += "memcpy(next, \""; output += code; output += "\", "; diff --git a/src/bin2cpp/StringGenerator.cpp b/src/bin2cpp/StringGenerator.cpp index 8ef08b0..20dea4c 100755 --- a/src/bin2cpp/StringGenerator.cpp +++ b/src/bin2cpp/StringGenerator.cpp @@ -23,6 +23,7 @@ *********************************************************************************/ #include "StringGenerator.h" +#include "TemplateProcessor.h" #include #include #include @@ -47,296 +48,165 @@ namespace bin2cpp return "string"; } - bool StringGenerator::createCppSourceFile(const char * cpp_file_path) + bool StringGenerator::createCppSourceFile(const char * file_path) { //check if input file exists - FILE * input = fopen(mContext.inputFilePath.c_str(), "rb"); - if (!input) + if ( !ra::filesystem::FileExists(mContext.inputFilePath.c_str()) ) return false; - //Uppercase function identifier - std::string functionIdentifier = ra::strings::CapitalizeFirstCharacter(getContext().functionIdentifier); - - //Build header and cpp file path - std::string headerPath = getHeaderFilePath(cpp_file_path); - std::string cppPath = cpp_file_path; - - //create cpp file - FILE * cpp = fopen(cppPath.c_str(), "w"); - if (!cpp) - { - fclose(input); - return false; - } - - //determine file properties - uint32_t fileSize = ra::filesystem::GetFileSize(input); - std::string filename = ra::filesystem::GetFilename(mContext.inputFilePath.c_str()); - - //Build class name - std::string className = getClassName(); - - //Build function - std::string getterFunctionName = getGetterFunctionName(); - - //write cpp file heading - fprintf(cpp, "%s", getHeaderTemplate().c_str()); - fprintf(cpp, "#include \"%s\"\n", mContext.headerFilename.c_str() ); - fprintf(cpp, "#include \n"); - fprintf(cpp, "#include //for ofstream\n"); - fprintf(cpp, "namespace %s\n", getContext().codeNamespace.c_str()); - fprintf(cpp, "{\n"); - fprintf(cpp, " class %s : public virtual %s::%s\n", className.c_str(), getContext().codeNamespace.c_str(), getContext().baseClass.c_str()); - fprintf(cpp, " {\n"); - fprintf(cpp, " public:\n"); - fprintf(cpp, " %s() {}\n", className.c_str()); - fprintf(cpp, " virtual ~%s() {}\n", className.c_str()); - fprintf(cpp, " virtual size_t getSize() const { return %u; }\n", fileSize); - fprintf(cpp, " virtual const char * getFileName() const { %s }\n", getImplOfGetFileName().c_str()); - fprintf(cpp, " virtual const char * getFilePath() const { %s }\n", getImplOfGetFilePath().c_str()); - fprintf(cpp, " virtual const char * getBuffer() const\n"); - fprintf(cpp, " {\n"); - fprintf(cpp, " const char * buffer = ""\n"); - - //create buffer for each chunks from input buffer - int numLinePrinted = 0; - unsigned char * buffer = new unsigned char[getContext().chunkSize]; - while(!feof(input)) - { - //read a chunk of the file - size_t readSize = fread(buffer, 1, getContext().chunkSize, input); - - bool isLastChunk = !(readSize == getContext().chunkSize); - - if (readSize > 0) - { - if (numLinePrinted > 0) - { - //end previous line - fprintf(cpp, "\n"); - } - - //convert to cpp string - std::string cppEncoder; - switch(getContext().cppEncoder) - { - case CPP_ENCODER_HEX: - cppEncoder = ra::code::cpp::ToHexString(buffer, readSize); - break; - case CPP_ENCODER_OCT: - default: - cppEncoder = ra::code::cpp::ToOctString(buffer, readSize, false); - break; - }; - - //output - fprintf(cpp, " \"%s\"", cppEncoder.c_str()); - numLinePrinted++; - } - - //end the string if last chunk printed - if (isLastChunk) - { - fprintf(cpp, ";\n"); - } - } - delete[] buffer; - buffer = NULL; - - //write cpp source file footer - fprintf(cpp, " return buffer;\n"); - fprintf(cpp, " }\n"); - fprintf(cpp, "%s", getSaveMethodTemplate().c_str()); - fprintf(cpp, " };\n"); - fprintf(cpp, " const %s & %s() { static %s _instance; return _instance; }\n", getContext().baseClass.c_str(), getterFunctionName.c_str(), className.c_str()); - if (mContext.registerFiles) - { - std::string fileManagerTemplate = getCppFileManagerRegistrationImplementationTemplate(); - fprintf(cpp, "%s", fileManagerTemplate.c_str()); - } - fprintf(cpp, "}; //%s\n", getContext().codeNamespace.c_str()); - - fclose(input); - fclose(cpp); - - return true; + const std::string text = "" + "${bin2cpp_output_file_header}" + "#include \"${bin2cpp_cpp_header_include_path}\"\n" + "#include \n" + "#include //for ofstream\n" + "namespace ${bin2cpp_namespace}\n" + "{\n" + " class ${bin2cpp_classname} : public virtual ${bin2cpp_namespace}::${bin2cpp_baseclass}\n" + " {\n" + " public:\n" + " ${bin2cpp_classname}() {}\n" + " virtual ~${bin2cpp_classname}() {}\n" + " virtual size_t getSize() const { return ${bin2cpp_input_file_size}; }\n" + " virtual const char * getFileName() const { ${bin2cpp_cpp_get_file_name_impl} }\n" + " virtual const char * getFilePath() const { ${bin2cpp_cpp_get_file_path_impl} }\n" + " virtual const char * getBuffer() const\n" + " {\n" + " const char * buffer = \n${bin2cpp_insert_input_file_as_code}" // INPUT FILE AS CODE HERE + " return buffer;\n" + " }\n" + "${bin2cpp_cpp_get_save_method_impl}" + " };\n" + " const ${bin2cpp_baseclass} & ${bin2cpp_cpp_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" + "${bin2cpp_cpp_get_file_manager_registration_impl}" + "}; //${bin2cpp_namespace}\n"; + + TemplateProcessor processor(&text); + processor.setTemplateVariableLookup(this); + bool write_success = processor.writeFile(file_path); + + return write_success; } bool StringGenerator::createCSourceFile(const char* file_path) { //check if input file exists - FILE* input = fopen(mContext.inputFilePath.c_str(), "rb"); - if ( !input ) + if ( !ra::filesystem::FileExists(mContext.inputFilePath.c_str()) ) return false; - //Uppercase function identifier - std::string functionIdentifier = ra::strings::Lowercase(mContext.functionIdentifier); - - //Build header and cpp file path - std::string headerPath = getHeaderFilePath(file_path); - std::string sourcePath = file_path; - - //create c source file - FILE* fout = fopen(sourcePath.c_str(), "w"); - if ( !fout ) - { - fclose(input); - return false; - } - - //determine file properties - uint32_t fileSize = ra::filesystem::GetFileSize(input); - std::string filename = ra::filesystem::GetFilename(mContext.inputFilePath.c_str()); - //long lastSegmentSize = fileSize%chunk_size; - //size_t numSegments = fileSize/chunk_size + (lastSegmentSize == 0 ? 0 : 1); - - //Build class name - std::string className = getClassName(); - - //Build function - std::string getterFunctionName = getGetterFunctionName(); - - //Build FileManager class template - std::string manager = mContext.managerHeaderFilename; - - //write c file heading - fprintf(fout, "%s", getHeaderTemplate().c_str()); - fprintf(fout, "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n"); - fprintf(fout, "#define _CRT_SECURE_NO_WARNINGS\n"); - fprintf(fout, "#endif\n"); - fprintf(fout, "#include \"%s\"\n", mContext.headerFilename.c_str()); - fprintf(fout, "#include // for malloc\n"); - fprintf(fout, "#include // for memset\n"); - fprintf(fout, "#include // for fopen\n"); - - fprintf(fout, "static %s %s_file = { 0 };\n", mContext.baseClass.c_str(), functionIdentifier.c_str()); - fprintf(fout, "static bool %s_initialized = false;\n", functionIdentifier.c_str()); - fprintf(fout, "\n"); - - // File registration predeclaration code - fprintf(fout, "%s", getCFileManagerRegistrationPredeclarationImplementation().c_str()); - - fprintf(fout, "bool %s_load()\n", functionIdentifier.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " if ( %s_file.buffer )\n", functionIdentifier.c_str()); - fprintf(fout, " return true;\n"); - fprintf(fout, "\n"); - fprintf(fout, " static const char * static_buffer = ""\n"); - - //create buffer for each chunks from input buffer - int numLinePrinted = 0; - unsigned char* buffer = new unsigned char[getContext().chunkSize]; - while ( !feof(input) ) - { - //read a chunk of the file - size_t readSize = fread(buffer, 1, getContext().chunkSize, input); - - bool isLastChunk = !(readSize == getContext().chunkSize); - - if ( readSize > 0 ) - { - if ( numLinePrinted > 0 ) - { - //end previous line - fprintf(fout, "\n"); - } - - //convert to cpp string - std::string cppEncoder; - switch ( getContext().cppEncoder ) - { - case CPP_ENCODER_HEX: - cppEncoder = ra::code::cpp::ToHexString(buffer, readSize); - break; - case CPP_ENCODER_OCT: - default: - cppEncoder = ra::code::cpp::ToOctString(buffer, readSize, false); - break; - }; - - //output - fprintf(fout, " \"%s\"", cppEncoder.c_str()); - numLinePrinted++; - } + const std::string text = "" + "${bin2cpp_output_file_header}" + "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" + "#define _CRT_SECURE_NO_WARNINGS\n" + "#endif\n" + "#include \"${bin2cpp_cpp_header_include_path}\"\n" + "#include // for malloc\n" + "#include // for memset\n" + "#include // for fopen\n" + "static ${bin2cpp_baseclass} ${bin2cpp_function_identifier_lowercase}_file = { 0 };\n" + "static bool ${bin2cpp_function_identifier_lowercase}_initialized = false;\n" + "\n" + "${bin2cpp_c_file_manager_registration_predeclaration}" + "bool ${bin2cpp_function_identifier_lowercase}_load()\n" + "{\n" + " if ( ${bin2cpp_function_identifier_lowercase}_file.buffer )\n" + " return true;\n" + "\n" + " static const char * static_buffer = \n${bin2cpp_insert_input_file_as_code}" // INPUT FILE AS CODE HERE + "\n" + " ${bin2cpp_function_identifier_lowercase}_file.buffer = static_buffer;\n" + " return true;\n" + "}\n" + "\n" + "void ${bin2cpp_function_identifier_lowercase}_free()\n" + "{\n" + " ${bin2cpp_function_identifier_lowercase}_file.buffer = NULL;\n" + "}\n" + "\n" + "bool ${bin2cpp_function_identifier_lowercase}_save(const char* path)\n" + "{\n" + " if ( !${bin2cpp_function_identifier_lowercase}_file.buffer )\n" + " return false;\n" + " FILE* f = fopen(path, \"wb\");\n" + " if ( !f )\n" + " return false;\n" + " size_t write_size = fwrite(${bin2cpp_function_identifier_lowercase}_file.buffer, 1, ${bin2cpp_function_identifier_lowercase}_file.size, f);\n" + " fclose(f);\n" + " if ( write_size != ${bin2cpp_function_identifier_lowercase}_file.size )\n" + " return false;\n" + " return true;\n" + "}\n" + "\n" + "static inline void ${bin2cpp_function_identifier_lowercase}_init()\n" + "{\n" + " // remember we already initialized\n" + " if ( ${bin2cpp_function_identifier_lowercase}_initialized )\n" + " return;\n" + " ${bin2cpp_function_identifier_lowercase}_initialized = true;\n" + "\n" + " // initialize\n" + " ${bin2cpp_baseclass}* file = &${bin2cpp_function_identifier_lowercase}_file;\n" + " file->size = ${bin2cpp_input_file_size}ULL;\n" + " file->file_name = \"${bin2cpp_get_file_obj_file_name}\";\n" + " file->file_path = \"${bin2cpp_get_file_obj_file_path}\";\n" + " file->buffer = NULL;\n" + " file->load = ${bin2cpp_function_identifier_lowercase}_load;\n" + " file->unload = ${bin2cpp_function_identifier_lowercase}_free;\n" + " file->save = ${bin2cpp_function_identifier_lowercase}_save;\n" + "\n" + " // load file by default on init as in c++ implementation\n" + " file->load();\n" + "${bin2cpp_c_file_manager_registration_post_init_impl}" + "}\n" + "\n" + "${bin2cpp_baseclass}* ${bin2cpp_cpp_getter_function_name}(void)\n" + "{\n" + " ${bin2cpp_function_identifier_lowercase}_init();\n" + " return &${bin2cpp_function_identifier_lowercase}_file;\n" + "}\n" + "${bin2cpp_c_file_manager_registration_implementation}"; + + TemplateProcessor processor(&text); + processor.setTemplateVariableLookup(this); + bool write_success = processor.writeFile(file_path); + + return write_success; + } - //end the string if last chunk printed - if ( isLastChunk ) - { - fprintf(fout, ";\n"); - } - } - delete[] buffer; - buffer = NULL; + std::string StringGenerator::getInputFileChunkAsCode(const unsigned char* buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk) + { + size_t indentation = 0; - //write c source file footer - fprintf(fout, "\n"); - fprintf(fout, " %s_file.buffer = static_buffer;\n", functionIdentifier.c_str()); - fprintf(fout, " return true;\n"); - fprintf(fout, "}\n"); + if ( mContext.plainOutput ) + indentation = 0; + else if ( mContext.code == CodeGenerationEnum::CODE_GENERATION_CPP ) + indentation = 8; + else if ( mContext.code == CodeGenerationEnum::CODE_GENERATION_C ) + indentation = 4; - fprintf(fout, "\n"); + std::string output; + if ( indentation ) + output += std::string(indentation, ' '); - fprintf(fout, "void %s_free()\n", functionIdentifier.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " %s_file.buffer = NULL;\n", functionIdentifier.c_str()); - fprintf(fout, "}\n"); - fprintf(fout, "\n"); - fprintf(fout, "bool %s_save(const char* path)\n", functionIdentifier.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " if ( !%s_file.buffer )\n", functionIdentifier.c_str()); - fprintf(fout, " return false;\n"); - fprintf(fout, " FILE* f = fopen(path, \"wb\");\n"); - fprintf(fout, " if ( !f )\n"); - fprintf(fout, " return false;\n"); - fprintf(fout, " size_t write_size = fwrite(%s_file.buffer, 1, %s_file.size, f);\n", functionIdentifier.c_str(), functionIdentifier.c_str()); - fprintf(fout, " fclose(f);\n"); - fprintf(fout, " if ( write_size != %s_file.size )\n", functionIdentifier.c_str()); - fprintf(fout, " return false;\n"); - fprintf(fout, " return true;\n"); - fprintf(fout, "}\n"); - fprintf(fout, "\n"); - fprintf(fout, "static inline void %s_init()\n", functionIdentifier.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " // remember we already initialized\n"); - fprintf(fout, " if ( %s_initialized )\n", functionIdentifier.c_str()); - fprintf(fout, " return;\n"); - fprintf(fout, " %s_initialized = true;\n", functionIdentifier.c_str()); - fprintf(fout, "\n"); - fprintf(fout, " // initialize\n"); - fprintf(fout, " %s* file = &%s_file;\n", mContext.baseClass.c_str(), functionIdentifier.c_str()); - fprintf(fout, " file->size = %uULL;\n", fileSize); - fprintf(fout, " file->file_name = \"%s\";\n", getFileClassFileName().c_str()); - fprintf(fout, " file->file_path = \"%s\";\n", getFileClassFilePath().c_str()); - fprintf(fout, " file->buffer = NULL;\n"); - fprintf(fout, " file->load = %s_load;\n", functionIdentifier.c_str()); - fprintf(fout, " file->unload = %s_free;\n", functionIdentifier.c_str()); - fprintf(fout, " file->save = %s_save;\n", functionIdentifier.c_str()); - fprintf(fout, "\n"); - fprintf(fout, " // load file by default on init as in c++ implementation"); - fprintf(fout, " file->load();\n"); + output += "\""; - if ( mContext.registerFiles ) + //convert to cpp string + switch ( mContext.cppEncoder ) { - fprintf(fout, " \n"); - fprintf(fout, " // register\n"); - fprintf(fout, " %s_filemanager_register_file(file);\n", mContext.codeNamespace.c_str()); - } - - fprintf(fout, "}\n"); - fprintf(fout, "\n"); - fprintf(fout, "%s* %s(void)\n", mContext.baseClass.c_str(), getGetterFunctionName().c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " %s_init();\n", functionIdentifier.c_str()); - fprintf(fout, " return &%s_file;\n", functionIdentifier.c_str()); - fprintf(fout, "}\n"); - - // File registration implementation code - fprintf(fout, "%s", getCFileManagerStaticFileRegistrationImplementation().c_str()); - - fclose(input); - fclose(fout); - - return true; + case CPP_ENCODER_HEX: + output += ra::code::cpp::ToHexString(buffer, buffer_size); + break; + case CPP_ENCODER_OCT: + default: + output += ra::code::cpp::ToOctString(buffer, buffer_size, false); + break; + }; + + output += "\""; + if ( is_last_chunk ) + output += ";"; + output += "\n"; + + return output; } }; //bin2cpp \ No newline at end of file diff --git a/src/bin2cpp/StringGenerator.h b/src/bin2cpp/StringGenerator.h index f3dda2f..b536ea3 100644 --- a/src/bin2cpp/StringGenerator.h +++ b/src/bin2cpp/StringGenerator.h @@ -39,8 +39,9 @@ namespace bin2cpp StringGenerator(); virtual ~StringGenerator(); virtual const char * getName() const; - virtual bool createCppSourceFile(const char * cpp_file_path); + virtual bool createCppSourceFile(const char * file_path); virtual bool createCSourceFile(const char* file_path); + virtual std::string getInputFileChunkAsCode(const unsigned char* buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk); }; }; //bin2cpp From c50f096cdbd73c128b5b1a7c2e30bb89d7312421 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sat, 24 May 2025 13:32:08 -0400 Subject: [PATCH 12/26] Modified Win32ResourceGenerator to use TemplateProcessor. --- src/bin2cpp/Win32ResourceGenerator.cpp | 571 +++++++++++-------------- src/bin2cpp/Win32ResourceGenerator.h | 12 +- 2 files changed, 260 insertions(+), 323 deletions(-) diff --git a/src/bin2cpp/Win32ResourceGenerator.cpp b/src/bin2cpp/Win32ResourceGenerator.cpp index 7552125..14b37b8 100755 --- a/src/bin2cpp/Win32ResourceGenerator.cpp +++ b/src/bin2cpp/Win32ResourceGenerator.cpp @@ -23,6 +23,7 @@ *********************************************************************************/ #include "Win32ResourceGenerator.h" +#include "TemplateProcessor.h" #include "common.h" #include "crc32.h" @@ -51,144 +52,114 @@ namespace bin2cpp return "win32"; } - bool Win32ResourceGenerator::createCppSourceFile(const char * cpp_file_path) + bool Win32ResourceGenerator::createCppSourceFile(const char * file_path) { - bool resourceFileSuccess = createResourceFile(cpp_file_path); + bool resourceFileSuccess = createResourceFile(file_path); if (!resourceFileSuccess) return false; //check if input file exists - FILE * input = fopen(mContext.inputFilePath.c_str(), "rb"); - if (!input) + if ( !ra::filesystem::FileExists(mContext.inputFilePath.c_str()) ) return false; - //Uppercase function identifier - std::string functionIdentifier = ra::strings::CapitalizeFirstCharacter(getContext().functionIdentifier); - - //Build header and cpp file path - std::string headerPath = getHeaderFilePath(cpp_file_path); - std::string cppPath = cpp_file_path; - - //create cpp file - FILE * cpp = fopen(cppPath.c_str(), "w"); - if (!cpp) - { - fclose(input); - return false; - } - - //determine file properties - //uint32_t fileSize = ra::filesystem::GetFileSize(input); - std::string filename = ra::filesystem::GetFilename(mContext.inputFilePath.c_str()); - - //Build class name - std::string className = getClassName(); - - //Build function - std::string getterFunctionName = getGetterFunctionName(); - - //write cpp file heading - fprintf(cpp, "%s", getHeaderTemplate().c_str()); - fprintf(cpp, "#include \"%s\"\n", mContext.headerFilename.c_str() ); - fprintf(cpp, "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n"); - fprintf(cpp, "#define _CRT_SECURE_NO_WARNINGS\n"); - fprintf(cpp, "#endif\n"); - fprintf(cpp, "\n"); - fprintf(cpp, "#include \n"); - fprintf(cpp, "#include \n"); - fprintf(cpp, "#include //for ofstream\n"); - fprintf(cpp, "\n"); - fprintf(cpp, "#ifndef WIN32_LEAN_AND_MEAN\n"); - fprintf(cpp, "#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers\n"); - fprintf(cpp, "#endif\n"); - fprintf(cpp, "#include \n"); - fprintf(cpp, "\n"); - fprintf(cpp, "#include //for EnumProcessModules()\n"); - fprintf(cpp, "#pragma comment( lib, \"psapi.lib\" )\n"); - fprintf(cpp, "\n"); - - fprintf(cpp, "namespace %s\n", getContext().codeNamespace.c_str()); - fprintf(cpp, "{\n"); - fprintf(cpp, " class %s : public virtual %s::%s\n", className.c_str(), getContext().codeNamespace.c_str(), getContext().baseClass.c_str()); - fprintf(cpp, " {\n"); - fprintf(cpp, " public:\n"); - fprintf(cpp, " %s() :\n", className.c_str()); - fprintf(cpp, " hProcess(NULL),\n"); - fprintf(cpp, " hModule(NULL),\n"); - fprintf(cpp, " hResourceInfoBlock(NULL),\n"); - fprintf(cpp, " hResHandle(NULL),\n"); - fprintf(cpp, " mBufferSize(0),\n"); - fprintf(cpp, " mBuffer(NULL)\n"); - fprintf(cpp, " {\n"); - fprintf(cpp, " loadResource();\n"); - fprintf(cpp, " }\n"); - fprintf(cpp, " virtual ~%s() { unloadResource(); }\n", className.c_str()); - fprintf(cpp, " virtual size_t getSize() const { return mBufferSize; }\n"); - fprintf(cpp, " virtual const char * getFileName() const { %s }\n", getImplOfGetFileName().c_str()); - fprintf(cpp, " virtual const char * getFilePath() const { %s }\n", getImplOfGetFilePath().c_str()); - fprintf(cpp, " virtual const char * getBuffer() const { return mBuffer; }\n"); - fprintf(cpp, " void loadResource()\n"); - fprintf(cpp, " {\n"); - fprintf(cpp, " //Get a handle to this process\n"); - fprintf(cpp, " hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId() );\n"); - fprintf(cpp, " if (hProcess)\n"); - fprintf(cpp, " {\n"); - fprintf(cpp, " //Find the main HMODULE of the process\n"); - fprintf(cpp, " DWORD cbNeeded;\n"); - fprintf(cpp, " if ( EnumProcessModules( hProcess, &hModule, sizeof(hModule), &cbNeeded) )\n"); - fprintf(cpp, " {\n"); - fprintf(cpp, " //Retrieve the resource\n"); - fprintf(cpp, " hResourceInfoBlock = FindResourceA(hModule, \"%s\", \"CUSTOM\");\n", getRandomIdentifier(mContext.inputFilePath.c_str()).c_str()); - fprintf(cpp, " if (hResourceInfoBlock)\n"); - fprintf(cpp, " {\n"); - fprintf(cpp, " hResHandle = LoadResource(hModule, hResourceInfoBlock);\n"); - fprintf(cpp, " if (hResHandle)\n"); - fprintf(cpp, " {\n"); - fprintf(cpp, " mBuffer = (const char *)LockResource(hResHandle);\n"); - fprintf(cpp, " mBufferSize = SizeofResource(hModule, hResourceInfoBlock);\n"); - fprintf(cpp, " }\n"); - fprintf(cpp, " }\n"); - fprintf(cpp, " }\n"); - fprintf(cpp, " }\n"); - fprintf(cpp, " }\n"); - fprintf(cpp, " virtual void unloadResource()\n"); - fprintf(cpp, " {\n"); - fprintf(cpp, " if (hResHandle)\n"); - fprintf(cpp, " {\n"); - fprintf(cpp, " FreeResource(hResHandle);\n"); - fprintf(cpp, " hResHandle = NULL;\n"); - fprintf(cpp, " mBuffer = NULL;\n"); - fprintf(cpp, " mBufferSize = 0;\n"); - fprintf(cpp, " }\n"); - fprintf(cpp, " hResourceInfoBlock = NULL;\n"); - fprintf(cpp, " hModule = NULL;\n"); - fprintf(cpp, " if (hProcess)\n"); - fprintf(cpp, " {\n"); - fprintf(cpp, " CloseHandle(hProcess);\n"); - fprintf(cpp, " hProcess = NULL;\n"); - fprintf(cpp, " }\n"); - fprintf(cpp, " }\n"); - fprintf(cpp, "%s", getSaveMethodTemplate().c_str()); - fprintf(cpp, " private:\n"); - fprintf(cpp, " HANDLE hProcess;\n"); - fprintf(cpp, " HMODULE hModule;\n"); - fprintf(cpp, " HRSRC hResourceInfoBlock;\n"); - fprintf(cpp, " HGLOBAL hResHandle;\n"); - fprintf(cpp, " DWORD mBufferSize;\n"); - fprintf(cpp, " const char * mBuffer;\n"); - fprintf(cpp, " };\n"); - fprintf(cpp, " const %s & %s() { static %s _instance; return _instance; }\n", getContext().baseClass.c_str(), getterFunctionName.c_str(), className.c_str()); - if (mContext.registerFiles) - { - std::string fileManagerTemplate = getCppFileManagerRegistrationImplementationTemplate(); - fprintf(cpp, "%s", fileManagerTemplate.c_str()); - } - fprintf(cpp, "}; //%s\n", getContext().codeNamespace.c_str()); - - fclose(input); - fclose(cpp); - - return true; + const std::string text = "" + "${bin2cpp_output_file_header}" + "#include \"${bin2cpp_cpp_header_include_path}\"\n" + "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" + "#define _CRT_SECURE_NO_WARNINGS\n" + "#endif\n" + "\n" + "#include \n" + "#include \n" + "#include //for ofstream\n" + "\n" + "#ifndef WIN32_LEAN_AND_MEAN\n" + "#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers\n" + "#endif\n" + "#include \n" + "\n" + "#include //for EnumProcessModules()\n" + "#pragma comment( lib, \"psapi.lib\" )\n" + "\n" + "namespace ${bin2cpp_namespace}\n" + "{\n" + " class ${bin2cpp_classname} : public virtual ${bin2cpp_namespace}::${bin2cpp_baseclass}\n" + " {\n" + " public:\n" + " ${bin2cpp_classname}() :\n" + " hProcess(NULL),\n" + " hModule(NULL),\n" + " hResourceInfoBlock(NULL),\n" + " hResHandle(NULL),\n" + " mBufferSize(0),\n" + " mBuffer(NULL)\n" + " {\n" + " loadResource();\n" + " }\n" + " virtual ~${bin2cpp_classname}() { unloadResource(); }\n" + " virtual size_t getSize() const { return mBufferSize; }\n" + " virtual const char * getFileName() const { ${bin2cpp_cpp_get_file_name_impl} }\n" + " virtual const char * getFilePath() const { ${bin2cpp_cpp_get_file_path_impl} }\n" + " virtual const char * getBuffer() const { return mBuffer; }\n" + " void loadResource()\n" + " {\n" + " //Get a handle to this process\n" + " hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId() );\n" + " if (hProcess)\n" + " {\n" + " //Find the main HMODULE of the process\n" + " DWORD cbNeeded;\n" + " if ( EnumProcessModules( hProcess, &hModule, sizeof(hModule), &cbNeeded) )\n" + " {\n" + " //Retrieve the resource\n" + " hResourceInfoBlock = FindResourceA(hModule, \"${bin2cpp_win32_resource_random_identifier}\", \"CUSTOM\");\n" + " if (hResourceInfoBlock)\n" + " {\n" + " hResHandle = LoadResource(hModule, hResourceInfoBlock);\n" + " if (hResHandle)\n" + " {\n" + " mBuffer = (const char *)LockResource(hResHandle);\n" + " mBufferSize = SizeofResource(hModule, hResourceInfoBlock);\n" + " }\n" + " }\n" + " }\n" + " }\n" + " }\n" + " virtual void unloadResource()\n" + " {\n" + " if (hResHandle)\n" + " {\n" + " FreeResource(hResHandle);\n" + " hResHandle = NULL;\n" + " mBuffer = NULL;\n" + " mBufferSize = 0;\n" + " }\n" + " hResourceInfoBlock = NULL;\n" + " hModule = NULL;\n" + " if (hProcess)\n" + " {\n" + " CloseHandle(hProcess);\n" + " hProcess = NULL;\n" + " }\n" + " }\n" + "${bin2cpp_cpp_get_save_method_impl}" + " private:\n" + " HANDLE hProcess;\n" + " HMODULE hModule;\n" + " HRSRC hResourceInfoBlock;\n" + " HGLOBAL hResHandle;\n" + " DWORD mBufferSize;\n" + " const char * mBuffer;\n" + " };\n" + " const ${bin2cpp_baseclass} & ${bin2cpp_cpp_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" + "${bin2cpp_cpp_get_file_manager_registration_impl}" + "}; //${bin2cpp_namespace}\n"; + + TemplateProcessor processor(&text); + processor.setTemplateVariableLookup(this); + bool write_success = processor.writeFile(file_path); + + return write_success; } bool Win32ResourceGenerator::createCSourceFile(const char* file_path) @@ -198,195 +169,148 @@ namespace bin2cpp return false; //check if input file exists - FILE* input = fopen(mContext.inputFilePath.c_str(), "rb"); - if ( !input ) + if ( !ra::filesystem::FileExists(mContext.inputFilePath.c_str()) ) return false; - //Uppercase function identifier - std::string functionIdentifier = ra::strings::Lowercase(mContext.functionIdentifier); - - //Build header and cpp file path - std::string headerPath = getHeaderFilePath(file_path); - std::string sourcePath = file_path; - - //create c source file - FILE* fout = fopen(sourcePath.c_str(), "w"); - if ( !fout ) - { - fclose(input); - return false; - } - - //determine file properties - uint32_t fileSize = ra::filesystem::GetFileSize(input); - std::string filename = ra::filesystem::GetFilename(mContext.inputFilePath.c_str()); - //long lastSegmentSize = fileSize%chunk_size; - //size_t numSegments = fileSize/chunk_size + (lastSegmentSize == 0 ? 0 : 1); - - //Build class name - std::string className = getClassName(); - - //Build function - std::string getterFunctionName = getGetterFunctionName(); - - //Build FileManager class template - std::string manager = mContext.managerHeaderFilename; - - //write c file heading - fprintf(fout, "%s", getHeaderTemplate().c_str()); - fprintf(fout, "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n"); - fprintf(fout, "#define _CRT_SECURE_NO_WARNINGS\n"); - fprintf(fout, "#endif\n"); - fprintf(fout, "\n"); - fprintf(fout, "#include \"%s\"\n", mContext.headerFilename.c_str()); - fprintf(fout, "#include // for malloc\n"); - fprintf(fout, "#include // for memset\n"); - fprintf(fout, "#include // for fopen\n"); - fprintf(fout, "\n"); - fprintf(fout, "#ifndef WIN32_LEAN_AND_MEAN\n"); - fprintf(fout, "#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers\n"); - fprintf(fout, "#endif\n"); - fprintf(fout, "#include \n"); - fprintf(fout, "\n"); - fprintf(fout, "#include //for EnumProcessModules()\n"); - fprintf(fout, "#pragma comment( lib, \"psapi.lib\" )\n"); - fprintf(fout, "\n"); - fprintf(fout, "static %s %s_file = { 0 };\n", mContext.baseClass.c_str(), functionIdentifier.c_str()); - fprintf(fout, "static bool %s_initialized = false;\n", functionIdentifier.c_str()); - fprintf(fout, "typedef struct %s\n", getLocalInfoStructName().c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " HANDLE hProcess;\n"); - fprintf(fout, " HMODULE hModule;\n"); - fprintf(fout, " HRSRC hResourceInfoBlock;\n"); - fprintf(fout, " HGLOBAL hResHandle;\n"); - fprintf(fout, " DWORD dwBufferSize;\n"); - fprintf(fout, "} %s;\n", getLocalInfoStructName().c_str()); - fprintf(fout, "static %s %s_info = { 0 };\n", getLocalInfoStructName().c_str(), functionIdentifier.c_str()); - fprintf(fout, "\n"); - - // File registration predeclaration code - fprintf(fout, "%s", getCFileManagerRegistrationPredeclarationImplementation().c_str()); - - fprintf(fout, "bool %s_load()\n", functionIdentifier.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " if ( %s_file.buffer )\n", functionIdentifier.c_str()); - fprintf(fout, " return true;\n"); - fprintf(fout, "\n"); - fprintf(fout, " %s* info = &%s_info;\n", getLocalInfoStructName().c_str(), functionIdentifier.c_str()); - - fprintf(fout, " //Get a handle to this process\n"); - fprintf(fout, " info->hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId() );\n"); - fprintf(fout, " if (info->hProcess)\n"); - fprintf(fout, " {\n"); - fprintf(fout, " //Find the main HMODULE of the process\n"); - fprintf(fout, " DWORD cbNeeded;\n"); - fprintf(fout, " if ( EnumProcessModules( info->hProcess, &info->hModule, sizeof(info->hModule), &cbNeeded) )\n"); - fprintf(fout, " {\n"); - fprintf(fout, " //Retrieve the resource\n"); - fprintf(fout, " info->hResourceInfoBlock = FindResourceA(info->hModule, \"%s\", \"CUSTOM\");\n", getRandomIdentifier(mContext.inputFilePath.c_str()).c_str()); - fprintf(fout, " if (info->hResourceInfoBlock)\n"); - fprintf(fout, " {\n"); - fprintf(fout, " info->hResHandle = LoadResource(info->hModule, info->hResourceInfoBlock);\n"); - fprintf(fout, " if (info->hResHandle)\n"); - fprintf(fout, " {\n"); - fprintf(fout, " %s_file.buffer = (const unsigned char *)LockResource(info->hResHandle);\n", functionIdentifier.c_str()); - fprintf(fout, " info->dwBufferSize = SizeofResource(info->hModule, info->hResourceInfoBlock);\n"); - fprintf(fout, " return true;\n"); - fprintf(fout, " }\n"); - fprintf(fout, " }\n"); - fprintf(fout, " }\n"); - fprintf(fout, " }\n"); - fprintf(fout, " \n"); - fprintf(fout, " return false;\n"); - fprintf(fout, "}\n"); - fprintf(fout, "\n"); - - fprintf(fout, "void %s_free()\n", functionIdentifier.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " if ( %s_file.buffer == NULL)\n", functionIdentifier.c_str()); - fprintf(fout, " return;\n"); - fprintf(fout, " %s* info = &%s_info;\n", getLocalInfoStructName().c_str(), functionIdentifier.c_str()); - fprintf(fout, " if (info->hResHandle)\n"); - fprintf(fout, " {\n"); - fprintf(fout, " FreeResource(info->hResHandle);\n"); - fprintf(fout, " info->hResHandle = NULL;\n"); - fprintf(fout, " %s_file.buffer = NULL;\n", functionIdentifier.c_str()); - fprintf(fout, " info->dwBufferSize = 0;\n"); - fprintf(fout, " }\n"); - fprintf(fout, " info->hResourceInfoBlock = NULL;\n"); - fprintf(fout, " info->hModule = NULL;\n"); - fprintf(fout, " if (info->hProcess)\n"); - fprintf(fout, " {\n"); - fprintf(fout, " CloseHandle(info->hProcess);\n"); - fprintf(fout, " info->hProcess = NULL;\n"); - fprintf(fout, " }\n"); - fprintf(fout, "}\n"); - fprintf(fout, "\n"); - - fprintf(fout, "bool %s_save(const char* path)\n", functionIdentifier.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " if ( !%s_file.buffer )\n", functionIdentifier.c_str()); - fprintf(fout, " return false;\n"); - fprintf(fout, " FILE* f = fopen(path, \"wb\");\n"); - fprintf(fout, " if ( !f )\n"); - fprintf(fout, " return false;\n"); - fprintf(fout, " size_t write_size = fwrite(%s_file.buffer, 1, %s_file.size, f);\n", functionIdentifier.c_str(), functionIdentifier.c_str()); - fprintf(fout, " fclose(f);\n"); - fprintf(fout, " if ( write_size != %s_file.size )\n", functionIdentifier.c_str()); - fprintf(fout, " return false;\n"); - fprintf(fout, " return true;\n"); - fprintf(fout, "}\n"); - fprintf(fout, "\n"); - - fprintf(fout, "static inline void %s_init()\n", functionIdentifier.c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " // remember we already initialized\n"); - fprintf(fout, " if ( %s_initialized )\n", functionIdentifier.c_str()); - fprintf(fout, " return;\n"); - fprintf(fout, " %s_initialized = true;\n", functionIdentifier.c_str()); - fprintf(fout, "\n"); - fprintf(fout, " // initialize\n"); - fprintf(fout, " %s* file = &%s_file;\n", mContext.baseClass.c_str(), functionIdentifier.c_str()); - fprintf(fout, " file->size = %uULL;\n", fileSize); - fprintf(fout, " file->file_name = \"%s\";\n", getFileClassFileName().c_str()); - fprintf(fout, " file->file_path = \"%s\";\n", getFileClassFilePath().c_str()); - fprintf(fout, " file->buffer = NULL;\n"); - fprintf(fout, " file->load = %s_load;\n", functionIdentifier.c_str()); - fprintf(fout, " file->unload = %s_free;\n", functionIdentifier.c_str()); - fprintf(fout, " file->save = %s_save;\n", functionIdentifier.c_str()); - fprintf(fout, "\n"); - fprintf(fout, " // load file by default on init as in c++ implementation"); - fprintf(fout, " file->load();\n"); - - if ( mContext.registerFiles ) - { - fprintf(fout, " \n"); - fprintf(fout, " // register\n"); - fprintf(fout, " %s_filemanager_register_file(file);\n", mContext.codeNamespace.c_str()); - } - - fprintf(fout, "}\n"); - fprintf(fout, "\n"); - - fprintf(fout, "%s* %s(void)\n", mContext.baseClass.c_str(), getGetterFunctionName().c_str()); - fprintf(fout, "{\n"); - fprintf(fout, " %s_init();\n", functionIdentifier.c_str()); - fprintf(fout, " return &%s_file;\n", functionIdentifier.c_str()); - fprintf(fout, "}\n"); - - // File registration implementation code - fprintf(fout, "%s", getCFileManagerStaticFileRegistrationImplementation().c_str()); - - fclose(input); - fclose(fout); - - return true; + const std::string text = "" + "${bin2cpp_output_file_header}" + "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" + "#define _CRT_SECURE_NO_WARNINGS\n" + "#endif\n" + "\n" + "#include \"${bin2cpp_cpp_header_include_path}\"\n" + "#include // for malloc\n" + "#include // for memset\n" + "#include // for fopen\n" + "\n" + "#ifndef WIN32_LEAN_AND_MEAN\n" + "#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers\n" + "#endif\n" + "#include \n" + "\n" + "#include //for EnumProcessModules()\n" + "#pragma comment( lib, \"psapi.lib\" )\n" + "\n" + "static ${bin2cpp_baseclass} ${bin2cpp_function_identifier_lowercase}_file = { 0 };\n" + "static bool ${bin2cpp_function_identifier_lowercase}_initialized = false;\n" + "typedef struct ${bin2cpp_win32_local_info_struct_name}\n" + "{\n" + " HANDLE hProcess;\n" + " HMODULE hModule;\n" + " HRSRC hResourceInfoBlock;\n" + " HGLOBAL hResHandle;\n" + " DWORD dwBufferSize;\n" + "} ${bin2cpp_win32_local_info_struct_name};\n" + "static ${bin2cpp_win32_local_info_struct_name} ${bin2cpp_function_identifier_lowercase}_info = { 0 };\n" + "\n" + "${bin2cpp_c_file_manager_registration_predeclaration}" + "bool ${bin2cpp_function_identifier_lowercase}_load()\n" + "{\n" + " if ( ${bin2cpp_function_identifier_lowercase}_file.buffer )\n" + " return true;\n" + "\n" + " ${bin2cpp_win32_local_info_struct_name}* info = &${bin2cpp_function_identifier_lowercase}_info;\n" + " //Get a handle to this process\n" + " info->hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, GetCurrentProcessId() );\n" + " if (info->hProcess)\n" + " {\n" + " //Find the main HMODULE of the process\n" + " DWORD cbNeeded;\n" + " if ( EnumProcessModules( info->hProcess, &info->hModule, sizeof(info->hModule), &cbNeeded) )\n" + " {\n" + " //Retrieve the resource\n" + " info->hResourceInfoBlock = FindResourceA(info->hModule, \"${bin2cpp_win32_resource_random_identifier}\", \"CUSTOM\");\n" + " if (info->hResourceInfoBlock)\n" + " {\n" + " info->hResHandle = LoadResource(info->hModule, info->hResourceInfoBlock);\n" + " if (info->hResHandle)\n" + " {\n" + " ${bin2cpp_function_identifier_lowercase}_file.buffer = (const unsigned char *)LockResource(info->hResHandle);\n" + " info->dwBufferSize = SizeofResource(info->hModule, info->hResourceInfoBlock);\n" + " return true;\n" + " }\n" + " }\n" + " }\n" + " }\n" + " \n" + " return false;\n" + "}\n" + "\n" + "void ${bin2cpp_function_identifier_lowercase}_free()\n" + "{\n" + " if ( ${bin2cpp_function_identifier_lowercase}_file.buffer == NULL)\n" + " return;\n" + " ${bin2cpp_win32_local_info_struct_name}* info = &${bin2cpp_function_identifier_lowercase}_info;\n" + " if (info->hResHandle)\n" + " {\n" + " FreeResource(info->hResHandle);\n" + " info->hResHandle = NULL;\n" + " ${bin2cpp_function_identifier_lowercase}_file.buffer = NULL;\n" + " info->dwBufferSize = 0;\n" + " }\n" + " info->hResourceInfoBlock = NULL;\n" + " info->hModule = NULL;\n" + " if (info->hProcess)\n" + " {\n" + " CloseHandle(info->hProcess);\n" + " info->hProcess = NULL;\n" + " }\n" + "}\n" + "\n" + "bool ${bin2cpp_function_identifier_lowercase}_save(const char* path)\n" + "{\n" + " if ( !${bin2cpp_function_identifier_lowercase}_file.buffer )\n" + " return false;\n" + " FILE* f = fopen(path, \"wb\");\n" + " if ( !f )\n" + " return false;\n" + " size_t write_size = fwrite(${bin2cpp_function_identifier_lowercase}_file.buffer, 1, ${bin2cpp_function_identifier_lowercase}_file.size, f);\n" + " fclose(f);\n" + " if ( write_size != ${bin2cpp_function_identifier_lowercase}_file.size )\n" + " return false;\n" + " return true;\n" + "}\n" + "\n" + "static inline void ${bin2cpp_function_identifier_lowercase}_init()\n" + "{\n" + " // remember we already initialized\n" + " if ( ${bin2cpp_function_identifier_lowercase}_initialized )\n" + " return;\n" + " ${bin2cpp_function_identifier_lowercase}_initialized = true;\n" + "\n" + " // initialize\n" + " ${bin2cpp_baseclass}* file = &${bin2cpp_function_identifier_lowercase}_file;\n" + " file->size = ${bin2cpp_input_file_size}ULL;\n" + " file->file_name = \"${bin2cpp_get_file_obj_file_name}\";\n" + " file->file_path = \"${bin2cpp_get_file_obj_file_path}\";\n" + " file->buffer = NULL;\n" + " file->load = ${bin2cpp_function_identifier_lowercase}_load;\n" + " file->unload = ${bin2cpp_function_identifier_lowercase}_free;\n" + " file->save = ${bin2cpp_function_identifier_lowercase}_save;\n" + "\n" + " // load file by default on init as in c++ implementation\n" + " file->load();\n" + "${bin2cpp_c_file_manager_registration_post_init_impl}" + "}\n" + "\n" + "${bin2cpp_baseclass}* ${bin2cpp_cpp_getter_function_name}(void)\n" + "{\n" + " ${bin2cpp_function_identifier_lowercase}_init();\n" + " return &${bin2cpp_function_identifier_lowercase}_file;\n" + "}\n" + "${bin2cpp_c_file_manager_registration_implementation}"; + + TemplateProcessor processor(&text); + processor.setTemplateVariableLookup(this); + bool write_success = processor.writeFile(file_path); + + return write_success; } - std::string Win32ResourceGenerator::getResourceFilePath(const char * cpp_file_path) + std::string Win32ResourceGenerator::getResourceFilePath(const char * file_path) { //Build header file path - std::string resourcePath = cpp_file_path; + std::string resourcePath = file_path; switch ( mContext.code ) { default: @@ -400,10 +324,10 @@ namespace bin2cpp return resourcePath; } - bool Win32ResourceGenerator::createResourceFile(const char * cpp_file_path) + bool Win32ResourceGenerator::createResourceFile(const char * file_path) { //Build resource file path - std::string resourceFilePath = getResourceFilePath(cpp_file_path); + std::string resourceFilePath = getResourceFilePath(file_path); //create resource file FILE * res = fopen(resourceFilePath.c_str(), "w"); @@ -424,14 +348,14 @@ namespace bin2cpp return true; } - std::string Win32ResourceGenerator::getRandomIdentifier(const char * cpp_file_path) + std::string Win32ResourceGenerator::getRandomIdentifier(const char * file_path) { - std::string include_guard = getCppIncludeGuardMacroName(cpp_file_path); + std::string include_guard = getCppIncludeGuardMacroName(file_path); //append a CRC32 checksum of the file path to allow storing multiple files with the same name in resources uint32_t checksum = 0; crc32Init(&checksum); - crc32Update(&checksum, (unsigned char *)cpp_file_path, (uint32_t)strlen(cpp_file_path)); + crc32Update(&checksum, (unsigned char *)file_path, (uint32_t)strlen(file_path)); crc32Finish(&checksum); std::string checksumString; @@ -452,6 +376,15 @@ namespace bin2cpp return false; // not supported } + std::string Win32ResourceGenerator::lookupTemplateVariable(const std::string& name) + { + if ( name == "bin2cpp_win32_resource_random_identifier" ) return getRandomIdentifier(mContext.inputFilePath.c_str()); + if ( name == "bin2cpp_win32_local_info_struct_name" ) return getLocalInfoStructName(); + + // Unknown name + return this->BaseGenerator::lookupTemplateVariable(name); + } + std::string Win32ResourceGenerator::getLocalInfoStructName() { std::string name = ra::strings::Lowercase(mContext.functionIdentifier); diff --git a/src/bin2cpp/Win32ResourceGenerator.h b/src/bin2cpp/Win32ResourceGenerator.h index a5e29ce..c157d6a 100644 --- a/src/bin2cpp/Win32ResourceGenerator.h +++ b/src/bin2cpp/Win32ResourceGenerator.h @@ -39,13 +39,17 @@ namespace bin2cpp Win32ResourceGenerator(); virtual ~Win32ResourceGenerator(); virtual const char * getName() const; - virtual bool createCppSourceFile(const char * cpp_file_path); + virtual bool createCppSourceFile(const char * file_path); virtual bool createCSourceFile(const char* file_path); virtual bool printFileContent(); + + //ITemplateVariableLookup methods + virtual std::string lookupTemplateVariable(const std::string& name); + protected: - virtual std::string getResourceFilePath(const char * cpp_file_path); - virtual bool createResourceFile(const char * cpp_file_path); - virtual std::string getRandomIdentifier(const char * cpp_file_path); + virtual std::string getResourceFilePath(const char * file_path); + virtual bool createResourceFile(const char * file_path); + virtual std::string getRandomIdentifier(const char * file_path); virtual std::string getLocalInfoStructName(); }; From a82f669435e27edd5bb6cb3876b7ed4a371ccfc8 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Thu, 29 May 2025 17:31:32 -0400 Subject: [PATCH 13/26] Updated README.md for #53 --- README.md | 19 ++++++------------- src/bin2cpp/bin2cpp.samples.txt | 22 ++++++++++++++-------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 8b44bb0..4bee374 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,9 @@ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Github Releases](https://img.shields.io/github/release/end2endzone/bin2cpp.svg)](https://github.com/end2endzone/bin2cpp/releases) -bin2cpp is a command line tool for embedding small files (like images, icons or raw data files) into a C++ executable. +bin2cpp is a command line tool for embedding small files (like images, icons or raw data files) into a C or C++ executable. -When executed, bin2cpp takes binary file as input and outputs c++ code (a function) that when called allows a c++ program to retrieve the content of the input binary file. +When executed, bin2cpp takes binary file as input and outputs C or C++ code (a function) that when called allows a program to retrieve the content of the input binary file. @@ -22,13 +22,6 @@ Build: | Ubuntu 20.04 | [![Build on Linux](https://github.com/end2endzone/bin2cpp/actions/workflows/build_linux.yml/badge.svg)](https://github.com/end2endzone/bin2cpp/actions/workflows/build_linux.yml) | [![Tests on Linux](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/end2endzone/58cf6c72c08e706335337d5ef9ca48e8/raw/bin2cpp.master.Linux.json)](https://github.com/end2endzone/bin2cpp/actions/workflows/build_linux.yml) | | macOS 10.15 | [![Build on macOS](https://github.com/end2endzone/bin2cpp/actions/workflows/build_macos.yml/badge.svg)](https://github.com/end2endzone/bin2cpp/actions/workflows/build_macos.yml) | [![Tests on macOS](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/end2endzone/58cf6c72c08e706335337d5ef9ca48e8/raw/bin2cpp.master.macOS.json)](https://github.com/end2endzone/bin2cpp/actions/workflows/build_macos.yml) | -Statistics: - -| AppVeyor | Travic CI | GitHub | -| ---------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -| [![Statistics](https://buildstats.info/appveyor/chart/end2endzone/bin2cpp)](https://ci.appveyor.com/project/end2endzone/bin2cpp/branch/master) | [![Statistics](https://buildstats.info/travisci/chart/end2endzone/bin2cpp)](https://travis-ci.org/end2endzone/bin2cpp) | [![Statistics](https://buildstats.info/github/chart/end2endzone/bin2cpp)](https://github.com/end2endzone/bin2cpp/actions/) | - - # Purpose @@ -46,7 +39,7 @@ The generated functions that reads and extracts the embedded content does not re The main features of the project are: -* Easily converts small files as C++ source code for embedding into a C++ executable. +* Easily converts small files to C or C++ source code for embedding into an executable. * Access content with a unique function call for each embedded file. * Supports multiple embedded files at once. * Keep the directory structure when embedding directories. @@ -54,16 +47,16 @@ The main features of the project are: * Makes it harder for resource hacker to modify or steal the embedded files. * No third party libraries required for retrieving the data of the embedded files. * Supports different types of code generator: string, segment, array, win32 resources. -* File's originals `size`, `filename` and `directory` properties available from generated source code. +* File's originals `size`, `filename` and `relative path` properties available from generated source code. * Control generated source code: choose your custom _File_ interface and namespace. * Print a file encoded content to stdout. Useful for scripts and integration with third party application. -* Generated code is C++98 standard-compliant. +* Generated code is C99 or C++98 standard-compliant. ## Use cases -The following list show situations where bin2cpp is useful: +The following list show use cases where bin2cpp is useful: * Embedding default configuration files if none are provided. * Embedding GLSL shaders into the executable. diff --git a/src/bin2cpp/bin2cpp.samples.txt b/src/bin2cpp/bin2cpp.samples.txt index 1790bac..16adca3 100644 --- a/src/bin2cpp/bin2cpp.samples.txt +++ b/src/bin2cpp/bin2cpp.samples.txt @@ -9,10 +9,10 @@ Test all generators: --file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\test\bin2cpp_unittest\generated_files\testHtml100000 --headerfile=_testHtml100000_C.h --override --code=c --generator=win32 Test as much features as possible with all generators: ---file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_tim_testHtml100000.h --identifier=LibFooFOO --chunksize=75 --baseclass=ben --namespace=ray --managerfile=c_tim_filemanager.h --registerfile --override --code=c --generator=array ---file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_jim_testHtml100000.h --identifier=LibBarBAR --chunksize=75 --baseclass=tom --namespace=eva --managerfile=c_jim_filemanager.h --registerfile --override --code=c --generator=segment ---file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_lou_testHtml100000.h --identifier=LibBazBAZ --chunksize=75 --baseclass=sam --namespace=joe --managerfile=c_lou_filemanager.h --registerfile --override --code=c --generator=string ---file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_sue_testHtml100000.h --identifier=LibBobBOB --chunksize=75 --baseclass=leo --namespace=jon --managerfile=c_sue_filemanager.h --registerfile --override --code=c --generator=win32 +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_tim_testHtml100000_array.h --identifier=LibFooFOO --chunksize=75 --baseclass=ben --namespace=ray --managerfile=c_tim_filemanager.h --registerfile --override --code=c --generator=array +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_jim_testHtml100000_segment.h --identifier=LibBarBAR --chunksize=75 --baseclass=tom --namespace=eva --managerfile=c_jim_filemanager.h --registerfile --override --code=c --generator=segment +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_lou_testHtml100000_string.h --identifier=LibBazBAZ --chunksize=75 --baseclass=sam --namespace=joe --managerfile=c_lou_filemanager.h --registerfile --override --code=c --generator=string +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_sue_testHtml100000_win32.h --identifier=LibBobBOB --chunksize=75 --baseclass=leo --namespace=jon --managerfile=c_sue_filemanager.h --registerfile --override --code=c --generator=win32 Test for: * Segment C generator @@ -44,11 +44,17 @@ Test all generators --file=..\..\test\bin2cpp_unittest\generated_files\testGeneratorString10000\testGeneratorString10000.bin --output=..\..\test\bin2cpp_unittest\generated_files\testGeneratorString10000 --headerfile=_testGeneratorString10000.h --identifier=testGeneratorString10000 --chunksize=450 --override --generator=string --file=..\..\test\bin2cpp_unittest\generated_files\testGeneratorWin32\testGeneratorWin32.bin --output=..\..\test\bin2cpp_unittest\generated_files\testGeneratorWin32 --headerfile=_testGeneratorWin32.h --identifier=testGeneratorWin32 --chunksize=450 --override --generator=win32 +Compare all generators: +--file=..\..\test\bin2cpp_unittest\generated_files\testGeneratorSegment10000\testGeneratorSegment10000.bin --output=..\..\temp --headerfile=cpp_tim_testHtml100000_array.h --identifier=LibArray --chunksize=75 --registerfile --override --generator=array +--file=..\..\test\bin2cpp_unittest\generated_files\testGeneratorSegment10000\testGeneratorSegment10000.bin --output=..\..\temp --headerfile=cpp_jim_testHtml100000_segment.h --identifier=LibSegment --chunksize=75 --registerfile --override --generator=segment +--file=..\..\test\bin2cpp_unittest\generated_files\testGeneratorSegment10000\testGeneratorSegment10000.bin --output=..\..\temp --headerfile=cpp_lou_testHtml100000_string.h --identifier=LibString --chunksize=75 --registerfile --override --generator=string +--file=..\..\test\bin2cpp_unittest\generated_files\testGeneratorSegment10000\testGeneratorSegment10000.bin --output=..\..\temp --headerfile=cpp_sue_testHtml100000_win32.h --identifier=LibWin32 --chunksize=75 --registerfile --override --generator=win32 + Test as much features as possible with all generators: ---file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_tim_testHtml100000.h --identifier=LibFooFOO --chunksize=75 --baseclass=ben --namespace=ray --managerfile=cpp_tim_filemanager.h --registerfile --override --code=cpp --generator=array ---file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_jim_testHtml100000.h --identifier=LibBarBAR --chunksize=75 --baseclass=tom --namespace=eva --managerfile=cpp_jim_filemanager.h --registerfile --override --code=cpp --generator=segment ---file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_lou_testHtml100000.h --identifier=LibBazBAZ --chunksize=75 --baseclass=sam --namespace=joe --managerfile=cpp_lou_filemanager.h --registerfile --override --code=cpp --generator=string ---file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_sue_testHtml100000.h --identifier=LibBobBOB --chunksize=75 --baseclass=leo --namespace=jon --managerfile=cpp_sue_filemanager.h --registerfile --override --code=cpp --generator=win32 +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_tim_testHtml100000_array.h --identifier=LibFooFOO --chunksize=75 --baseclass=ben --namespace=ray --managerfile=cpp_tim_filemanager.h --registerfile --override --code=cpp --generator=array +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_jim_testHtml100000_segment.h --identifier=LibBarBAR --chunksize=75 --baseclass=tom --namespace=eva --managerfile=cpp_jim_filemanager.h --registerfile --override --code=cpp --generator=segment +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_lou_testHtml100000_string.h --identifier=LibBazBAZ --chunksize=75 --baseclass=sam --namespace=joe --managerfile=cpp_lou_filemanager.h --registerfile --override --code=cpp --generator=string +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_sue_testHtml100000_win32.h --identifier=LibBobBOB --chunksize=75 --baseclass=leo --namespace=jon --managerfile=cpp_sue_filemanager.h --registerfile --override --code=cpp --generator=win32 Test plain output: --plainoutput --chunksize=75 --file=..\..\test\bin2cpp_unittest\generated_files\testSequential1000\testSequential1000.bin --generator=array From 2e01ed53aa6c31c2eb2dc55e7a55ff7a578f18be Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Thu, 29 May 2025 17:37:27 -0400 Subject: [PATCH 14/26] Renamed some markers in the file templates and methods in the code for clarity. --- src/bin2cpp/ArrayGenerator.cpp | 16 ++++---- src/bin2cpp/BaseGenerator.cpp | 52 +++++++++++++------------- src/bin2cpp/BaseGenerator.h | 6 +-- src/bin2cpp/ManagerGenerator.cpp | 26 ++++++------- src/bin2cpp/SegmentGenerator.cpp | 16 ++++---- src/bin2cpp/StringGenerator.cpp | 16 ++++---- src/bin2cpp/Win32ResourceGenerator.cpp | 16 ++++---- 7 files changed, 74 insertions(+), 74 deletions(-) diff --git a/src/bin2cpp/ArrayGenerator.cpp b/src/bin2cpp/ArrayGenerator.cpp index 2556e77..3dc15b2 100644 --- a/src/bin2cpp/ArrayGenerator.cpp +++ b/src/bin2cpp/ArrayGenerator.cpp @@ -56,7 +56,7 @@ namespace bin2cpp const std::string text = "" "${bin2cpp_output_file_header}" - "#include \"${bin2cpp_cpp_header_include_path}\"\n" + "#include \"${bin2cpp_header_source_file_include_path}\"\n" "#include \n" "#include //for ofstream\n" "namespace ${bin2cpp_namespace}\n" @@ -67,8 +67,8 @@ namespace bin2cpp " ${bin2cpp_classname}() {}\n" " virtual ~${bin2cpp_classname}() {}\n" " virtual size_t getSize() const { return ${bin2cpp_input_file_size}; }\n" - " virtual const char * getFileName() const { ${bin2cpp_cpp_get_file_name_impl} }\n" - " virtual const char * getFilePath() const { ${bin2cpp_cpp_get_file_path_impl} }\n" + " virtual const char * getFileName() const { ${bin2cpp_file_object_file_name_impl} }\n" + " virtual const char * getFilePath() const { ${bin2cpp_file_object_file_path_impl} }\n" " virtual const char * getBuffer() const\n" " {\n" " static const unsigned char buffer[] = {\n${bin2cpp_insert_input_file_as_code}" // INPUT FILE AS CODE HERE @@ -77,7 +77,7 @@ namespace bin2cpp " }\n" "${bin2cpp_cpp_get_save_method_impl}" " };\n" - " const ${bin2cpp_baseclass} & ${bin2cpp_cpp_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" + " const ${bin2cpp_baseclass} & ${bin2cpp_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" "${bin2cpp_cpp_get_file_manager_registration_impl}" "}; //${bin2cpp_namespace}\n"; @@ -111,7 +111,7 @@ namespace bin2cpp "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" "#define _CRT_SECURE_NO_WARNINGS\n" "#endif\n" - "#include \"${bin2cpp_cpp_header_include_path}\"\n" + "#include \"${bin2cpp_header_source_file_include_path}\"\n" "#include // for malloc\n" "#include // for memset\n" "#include // for fopen\n" @@ -159,8 +159,8 @@ namespace bin2cpp " // initialize\n" " ${bin2cpp_baseclass}* file = &${bin2cpp_function_identifier_lowercase}_file;\n" " file->size = ${bin2cpp_input_file_size}ULL;\n" - " file->file_name = \"${bin2cpp_get_file_obj_file_name}\";\n" - " file->file_path = \"${bin2cpp_get_file_obj_file_path}\";\n" + " file->file_name = \"${bin2cpp_file_object_file_name}\";\n" + " file->file_path = \"${bin2cpp_file_object_file_path}\";\n" " file->buffer = NULL;\n" " file->load = ${bin2cpp_function_identifier_lowercase}_load;\n" " file->unload = ${bin2cpp_function_identifier_lowercase}_free;\n" @@ -171,7 +171,7 @@ namespace bin2cpp "${bin2cpp_c_file_manager_registration_post_init_impl}" "}\n" "\n" - "${bin2cpp_baseclass}* ${bin2cpp_cpp_getter_function_name}(void)\n" + "${bin2cpp_baseclass}* ${bin2cpp_getter_function_name}(void)\n" "{\n" " ${bin2cpp_function_identifier_lowercase}_init();\n" " return &${bin2cpp_function_identifier_lowercase}_file;\n" diff --git a/src/bin2cpp/BaseGenerator.cpp b/src/bin2cpp/BaseGenerator.cpp index 3ed80bf..c81f312 100755 --- a/src/bin2cpp/BaseGenerator.cpp +++ b/src/bin2cpp/BaseGenerator.cpp @@ -59,30 +59,30 @@ namespace bin2cpp std::string BaseGenerator::lookupTemplateVariable(const std::string& name) { if ( name == "bin2cpp_output_file_macro_guard" ) return getCppIncludeGuardMacroName(mContext.headerFilename); - if ( name == "bin2cpp_embedded_file_class_macro_guard_prefix" ) return getClassMacroGuardPrefix(); if ( name == "bin2cpp_output_file_header" ) return getHeaderTemplate(); - if ( name == "bin2cpp_filemanager_file_header" ) return getHeaderTemplate(false); + if ( name == "bin2cpp_file_object_macro_guard_prefix" ) return getClassMacroGuardPrefix(); + if ( name == "bin2cpp_file_manager_file_header" ) return getHeaderTemplate(false); if ( name == "bin2cpp_file_manager_header_file_name" ) return mContext.managerHeaderFilename; if ( name == "bin2cpp_file_manager_macro_guard_prefix" ) return getFileManagerMacroGuardPrefix(); if ( name == "bin2cpp_baseclass" ) return mContext.baseClass; if ( name == "bin2cpp_classname" ) return getClassName(); if ( name == "bin2cpp_namespace" ) return mContext.codeNamespace; - if ( name == "bin2cpp_baseclass_uppercase" ) return ra::strings::Uppercase(mContext.baseClass); - if ( name == "bin2cpp_classname_uppercase" ) return ra::strings::Uppercase(getClassName()); - if ( name == "bin2cpp_namespace_uppercase" ) return ra::strings::Lowercase(mContext.codeNamespace); - if ( name == "bin2cpp_baseclass_lowercase" ) return ra::strings::Lowercase(mContext.baseClass); - if ( name == "bin2cpp_classname_lowercase" ) return ra::strings::Lowercase(getClassName()); - if ( name == "bin2cpp_namespace_lowercase" ) return ra::strings::Lowercase(mContext.codeNamespace); + //if ( name == "bin2cpp_baseclass_uppercase" ) return ra::strings::Uppercase(mContext.baseClass); + //if ( name == "bin2cpp_classname_uppercase" ) return ra::strings::Uppercase(getClassName()); + //if ( name == "bin2cpp_namespace_uppercase" ) return ra::strings::Lowercase(mContext.codeNamespace); + //if ( name == "bin2cpp_baseclass_lowercase" ) return ra::strings::Lowercase(mContext.baseClass); + //if ( name == "bin2cpp_classname_lowercase" ) return ra::strings::Lowercase(getClassName()); + //if ( name == "bin2cpp_namespace_lowercase" ) return ra::strings::Lowercase(mContext.codeNamespace); if ( name == "bin2cpp_function_identifier" ) return mContext.functionIdentifier; if ( name == "bin2cpp_function_identifier_lowercase" ) return ra::strings::Lowercase(mContext.functionIdentifier); - if ( name == "bin2cpp_cpp_getter_function_name" ) return getGetterFunctionName(); + if ( name == "bin2cpp_getter_function_name" ) return getGetterFunctionName(); if ( name == "bin2cpp_insert_input_file_as_code" ) return getInputFileDataAsCode(); - if ( name == "bin2cpp_cpp_header_include_path" ) return getCppHeaderIncludePath(); - if ( name == "bin2cpp_cpp_get_file_name_impl" ) return getImplOfGetFileName(); - if ( name == "bin2cpp_cpp_get_file_path_impl" ) return getImplOfGetFilePath(); - if ( name == "bin2cpp_get_file_obj_file_name" ) return getFileClassFileName(); - if ( name == "bin2cpp_get_file_obj_file_path" ) return getFileClassFilePath(); - if ( name == "bin2cpp_cpp_get_save_method_impl" ) return getSaveMethodTemplate(); + if ( name == "bin2cpp_header_source_file_include_path" ) return getCppHeaderIncludePath(); + if ( name == "bin2cpp_file_object_file_name_impl" ) return getFileClassGetFileNameImplementation(); + if ( name == "bin2cpp_file_object_file_path_impl" ) return getFileClassGetFilePathImplementation(); + if ( name == "bin2cpp_file_object_file_name" ) return getFileClassFileName(); + if ( name == "bin2cpp_file_object_file_path" ) return getFileClassFilePath(); + if ( name == "bin2cpp_cpp_get_save_method_impl" ) return getCppSaveMethodTemplate(); if ( name == "bin2cpp_cpp_get_file_manager_registration_impl" && mContext.registerFiles ) return getCppFileManagerRegistrationImplementationTemplate(); if ( name == "bin2cpp_c_file_manager_registration_predeclaration" && mContext.registerFiles ) return getCFileManagerRegistrationPredeclarationImplementation(); if ( name == "bin2cpp_c_file_manager_registration_implementation" && mContext.registerFiles ) return getCFileManagerStaticFileRegistrationImplementation(); @@ -204,7 +204,7 @@ namespace bin2cpp return header; } - std::string BaseGenerator::getSaveMethodTemplate() + std::string BaseGenerator::getCppSaveMethodTemplate() { std::string output; output << " virtual bool save(const char * filename) const\n"; @@ -302,7 +302,7 @@ namespace bin2cpp return output; } - std::string BaseGenerator::getImplOfGetFileName() + std::string BaseGenerator::getFileClassGetFileNameImplementation() { std::string output; @@ -329,7 +329,7 @@ namespace bin2cpp return output; } - std::string BaseGenerator::getImplOfGetFilePath() + std::string BaseGenerator::getFileClassGetFilePathImplementation() { std::string output; @@ -475,8 +475,8 @@ namespace bin2cpp "\n" "namespace ${bin2cpp_namespace}\n" "{\n" - " #ifndef ${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_CLASS\n" - " #define ${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_CLASS\n" + " #ifndef ${bin2cpp_file_object_macro_guard_prefix}_FILE_OBJECT_CLASS\n" + " #define ${bin2cpp_file_object_macro_guard_prefix}_FILE_OBJECT_CLASS\n" " class ${bin2cpp_baseclass}\n" " {\n" " public:\n" @@ -487,8 +487,8 @@ namespace bin2cpp " virtual const char * getBuffer() const = 0;\n" " virtual bool save(const char * filename) const = 0;\n" " };\n" - " #endif //${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_CLASS\n" - " const ${bin2cpp_baseclass} & ${bin2cpp_cpp_getter_function_name}();\n" + " #endif //${bin2cpp_file_object_macro_guard_prefix}_FILE_OBJECT_CLASS\n" + " const ${bin2cpp_baseclass} & ${bin2cpp_getter_function_name}();\n" "}; //${bin2cpp_namespace}\n" "\n" "#endif //${bin2cpp_output_file_macro_guard}\n" @@ -563,8 +563,8 @@ namespace bin2cpp "#include \n" "#include \n" "\n" - "#ifndef ${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_STRUCT\n" - "#define ${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_STRUCT\n" + "#ifndef ${bin2cpp_file_object_macro_guard_prefix}_FILE_OBJECT_STRUCT\n" + "#define ${bin2cpp_file_object_macro_guard_prefix}_FILE_OBJECT_STRUCT\n" "typedef struct ${bin2cpp_baseclass} ${bin2cpp_baseclass};\n" "typedef bool(*${bin2cpp_namespace}_load_func)();\n" "typedef void(*${bin2cpp_namespace}_free_func)();\n" @@ -580,8 +580,8 @@ namespace bin2cpp " ${bin2cpp_namespace}_save_func save;\n" "} ${bin2cpp_baseclass};\n" "typedef ${bin2cpp_baseclass}* ${bin2cpp_baseclass}Ptr;\n" - "#endif //${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_STRUCT\n" - "${bin2cpp_baseclass}* ${bin2cpp_cpp_getter_function_name}(void);\n" + "#endif //${bin2cpp_file_object_macro_guard_prefix}_FILE_OBJECT_STRUCT\n" + "${bin2cpp_baseclass}* ${bin2cpp_getter_function_name}(void);\n" "\n" "#endif //${bin2cpp_output_file_macro_guard}\n" ; diff --git a/src/bin2cpp/BaseGenerator.h b/src/bin2cpp/BaseGenerator.h index 966cf64..6f88f4f 100644 --- a/src/bin2cpp/BaseGenerator.h +++ b/src/bin2cpp/BaseGenerator.h @@ -60,15 +60,15 @@ namespace bin2cpp virtual std::string getCppFilePath(const char * header_file_path); virtual std::string getHeaderTemplate(); virtual std::string getHeaderTemplate(bool include_source_file); - virtual std::string getSaveMethodTemplate(); + virtual std::string getCppSaveMethodTemplate(); virtual std::string getCppFileManagerRegistrationImplementationTemplate(); virtual std::string getCFileManagerRegistrationPredeclarationImplementation(); virtual std::string getCFileManagerStaticFileRegistrationImplementation(); virtual std::string getClassName(); virtual std::string getClassMacroGuardPrefix(); virtual std::string getFileManagerMacroGuardPrefix(); - virtual std::string getImplOfGetFileName(); - virtual std::string getImplOfGetFilePath(); + virtual std::string getFileClassGetFileNameImplementation(); + virtual std::string getFileClassGetFilePathImplementation(); virtual std::string getFileClassFileName(); virtual std::string getFileClassFilePath(); virtual std::string getCppHeaderIncludePath(); diff --git a/src/bin2cpp/ManagerGenerator.cpp b/src/bin2cpp/ManagerGenerator.cpp index 681bfc9..e5825ae 100644 --- a/src/bin2cpp/ManagerGenerator.cpp +++ b/src/bin2cpp/ManagerGenerator.cpp @@ -49,7 +49,7 @@ namespace bin2cpp bool ManagerGenerator::createCppHeaderFile(const char* file_path) { const std::string text = "" - "${bin2cpp_filemanager_file_header}" + "${bin2cpp_file_manager_file_header}" "#ifndef ${bin2cpp_file_manager_macro_guard_prefix}\n" "#define ${bin2cpp_file_manager_macro_guard_prefix}\n" "\n" @@ -58,8 +58,8 @@ namespace bin2cpp "\n" "namespace ${bin2cpp_namespace}\n" "{\n" - " #ifndef ${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_CLASS\n" - " #define ${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_CLASS\n" + " #ifndef ${bin2cpp_file_object_macro_guard_prefix}_FILE_OBJECT_CLASS\n" + " #define ${bin2cpp_file_object_macro_guard_prefix}_FILE_OBJECT_CLASS\n" " class ${bin2cpp_baseclass}\n" " {\n" " public:\n" @@ -70,10 +70,10 @@ namespace bin2cpp " virtual const char * getBuffer() const = 0;\n" " virtual bool save(const char * filename) const = 0;\n" " };\n" - " #endif //${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_CLASS\n" + " #endif //${bin2cpp_file_object_macro_guard_prefix}_FILE_OBJECT_CLASS\n" "\n" - " #ifndef ${bin2cpp_embedded_file_class_macro_guard_prefix}_FILEMANAGER_CLASS\n" - " #define ${bin2cpp_embedded_file_class_macro_guard_prefix}_FILEMANAGER_CLASS\n" + " #ifndef ${bin2cpp_file_object_macro_guard_prefix}_FILEMANAGER_CLASS\n" + " #define ${bin2cpp_file_object_macro_guard_prefix}_FILEMANAGER_CLASS\n" " class FileManager\n" " {\n" " private:\n" @@ -91,7 +91,7 @@ namespace bin2cpp " private:\n" " std::vector functions_;\n" " };\n" - " #endif //${bin2cpp_embedded_file_class_macro_guard_prefix}_FILEMANAGER_CLASS\n" + " #endif //${bin2cpp_file_object_macro_guard_prefix}_FILEMANAGER_CLASS\n" "}; //${bin2cpp_namespace}\n" "\n" "#endif //${bin2cpp_file_manager_macro_guard_prefix}\n" @@ -107,7 +107,7 @@ namespace bin2cpp bool ManagerGenerator::createCppSourceFile(const char* file_path) { const std::string text = "" - "${bin2cpp_filemanager_file_header}" + "${bin2cpp_file_manager_file_header}" "#include \"${bin2cpp_file_manager_header_file_name}\"\n" "#include \n" "#include // strlen\n" @@ -227,15 +227,15 @@ namespace bin2cpp bool ManagerGenerator::createCHeaderFile(const char* file_path) { const std::string text = "" - "${bin2cpp_filemanager_file_header}" + "${bin2cpp_file_manager_file_header}" "#ifndef ${bin2cpp_file_manager_macro_guard_prefix}\n" "#define ${bin2cpp_file_manager_macro_guard_prefix}\n" "\n" "#include \n" "#include \n" "\n" - "#ifndef ${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_STRUCT\n" - "#define ${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_STRUCT\n" + "#ifndef ${bin2cpp_file_object_macro_guard_prefix}_FILE_OBJECT_STRUCT\n" + "#define ${bin2cpp_file_object_macro_guard_prefix}_FILE_OBJECT_STRUCT\n" "typedef struct ${bin2cpp_baseclass} ${bin2cpp_baseclass};\n" "typedef bool(*${bin2cpp_namespace}_load_func)();\n" "typedef void(*${bin2cpp_namespace}_free_func)();\n" @@ -251,7 +251,7 @@ namespace bin2cpp " ${bin2cpp_namespace}_save_func save;\n" "} ${bin2cpp_baseclass};\n" "typedef ${bin2cpp_baseclass}* ${bin2cpp_baseclass}Ptr;\n" - "#endif //${bin2cpp_embedded_file_class_macro_guard_prefix}_EMBEDDEDFILE_STRUCT\n" + "#endif //${bin2cpp_file_object_macro_guard_prefix}_FILE_OBJECT_STRUCT\n" "\n" "size_t ${bin2cpp_namespace}_filemanager_get_file_count();\n" "bool ${bin2cpp_namespace}_filemanager_register_file(${bin2cpp_baseclass}* file);\n" @@ -271,7 +271,7 @@ namespace bin2cpp bool ManagerGenerator::createCSourceFile(const char* file_path) { const std::string text = "" - "${bin2cpp_filemanager_file_header}" + "${bin2cpp_file_manager_file_header}" "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" "#define _CRT_SECURE_NO_WARNINGS\n" "#endif\n" diff --git a/src/bin2cpp/SegmentGenerator.cpp b/src/bin2cpp/SegmentGenerator.cpp index 0e7c633..e36ffaa 100755 --- a/src/bin2cpp/SegmentGenerator.cpp +++ b/src/bin2cpp/SegmentGenerator.cpp @@ -59,7 +59,7 @@ namespace bin2cpp "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" "#define _CRT_SECURE_NO_WARNINGS\n" "#endif\n" - "#include \"${bin2cpp_cpp_header_include_path}\"\n" + "#include \"${bin2cpp_header_source_file_include_path}\"\n" "#include //for std::string\n" "#include \n" "#include //for ofstream\n" @@ -71,8 +71,8 @@ namespace bin2cpp " ${bin2cpp_classname}() { build(); }\n" " virtual ~${bin2cpp_classname}() {}\n" " virtual size_t getSize() const { return ${bin2cpp_input_file_size}; }\n" - " virtual const char * getFileName() const { ${bin2cpp_cpp_get_file_name_impl} }\n" - " virtual const char * getFilePath() const { ${bin2cpp_cpp_get_file_path_impl} }\n" + " virtual const char * getFileName() const { ${bin2cpp_file_object_file_name_impl} }\n" + " virtual const char * getFilePath() const { ${bin2cpp_file_object_file_path_impl} }\n" " virtual const char * getBuffer() const { return mBuffer.c_str(); }\n" " void build()\n" " {\n" @@ -83,7 +83,7 @@ namespace bin2cpp " private:\n" " std::string mBuffer;\n" " };\n" - " const ${bin2cpp_baseclass} & ${bin2cpp_cpp_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" + " const ${bin2cpp_baseclass} & ${bin2cpp_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" "${bin2cpp_cpp_get_file_manager_registration_impl}" "}; //${bin2cpp_namespace}\n"; @@ -105,7 +105,7 @@ namespace bin2cpp "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" "#define _CRT_SECURE_NO_WARNINGS\n" "#endif\n" - "#include \"${bin2cpp_cpp_header_include_path}\"\n" + "#include \"${bin2cpp_header_source_file_include_path}\"\n" "#include // for malloc\n" "#include // for memset\n" "#include // for fopen\n" @@ -159,8 +159,8 @@ namespace bin2cpp " // initialize\n" " ${bin2cpp_baseclass}* file = &${bin2cpp_function_identifier_lowercase}_file;\n" " file->size = ${bin2cpp_input_file_size}ULL;\n" - " file->file_name = \"${bin2cpp_get_file_obj_file_name}\";\n" - " file->file_path = \"${bin2cpp_get_file_obj_file_path}\";\n" + " file->file_name = \"${bin2cpp_file_object_file_name}\";\n" + " file->file_path = \"${bin2cpp_file_object_file_path}\";\n" " file->buffer = NULL;\n" " file->load = ${bin2cpp_function_identifier_lowercase}_load;\n" " file->unload = ${bin2cpp_function_identifier_lowercase}_free;\n" @@ -171,7 +171,7 @@ namespace bin2cpp "${bin2cpp_c_file_manager_registration_post_init_impl}" "}\n" "\n" - "${bin2cpp_baseclass}* ${bin2cpp_cpp_getter_function_name}(void)\n" + "${bin2cpp_baseclass}* ${bin2cpp_getter_function_name}(void)\n" "{\n" " ${bin2cpp_function_identifier_lowercase}_init();\n" " return &${bin2cpp_function_identifier_lowercase}_file;\n" diff --git a/src/bin2cpp/StringGenerator.cpp b/src/bin2cpp/StringGenerator.cpp index 20dea4c..1a2bd5c 100755 --- a/src/bin2cpp/StringGenerator.cpp +++ b/src/bin2cpp/StringGenerator.cpp @@ -56,7 +56,7 @@ namespace bin2cpp const std::string text = "" "${bin2cpp_output_file_header}" - "#include \"${bin2cpp_cpp_header_include_path}\"\n" + "#include \"${bin2cpp_header_source_file_include_path}\"\n" "#include \n" "#include //for ofstream\n" "namespace ${bin2cpp_namespace}\n" @@ -67,8 +67,8 @@ namespace bin2cpp " ${bin2cpp_classname}() {}\n" " virtual ~${bin2cpp_classname}() {}\n" " virtual size_t getSize() const { return ${bin2cpp_input_file_size}; }\n" - " virtual const char * getFileName() const { ${bin2cpp_cpp_get_file_name_impl} }\n" - " virtual const char * getFilePath() const { ${bin2cpp_cpp_get_file_path_impl} }\n" + " virtual const char * getFileName() const { ${bin2cpp_file_object_file_name_impl} }\n" + " virtual const char * getFilePath() const { ${bin2cpp_file_object_file_path_impl} }\n" " virtual const char * getBuffer() const\n" " {\n" " const char * buffer = \n${bin2cpp_insert_input_file_as_code}" // INPUT FILE AS CODE HERE @@ -76,7 +76,7 @@ namespace bin2cpp " }\n" "${bin2cpp_cpp_get_save_method_impl}" " };\n" - " const ${bin2cpp_baseclass} & ${bin2cpp_cpp_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" + " const ${bin2cpp_baseclass} & ${bin2cpp_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" "${bin2cpp_cpp_get_file_manager_registration_impl}" "}; //${bin2cpp_namespace}\n"; @@ -98,7 +98,7 @@ namespace bin2cpp "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" "#define _CRT_SECURE_NO_WARNINGS\n" "#endif\n" - "#include \"${bin2cpp_cpp_header_include_path}\"\n" + "#include \"${bin2cpp_header_source_file_include_path}\"\n" "#include // for malloc\n" "#include // for memset\n" "#include // for fopen\n" @@ -146,8 +146,8 @@ namespace bin2cpp " // initialize\n" " ${bin2cpp_baseclass}* file = &${bin2cpp_function_identifier_lowercase}_file;\n" " file->size = ${bin2cpp_input_file_size}ULL;\n" - " file->file_name = \"${bin2cpp_get_file_obj_file_name}\";\n" - " file->file_path = \"${bin2cpp_get_file_obj_file_path}\";\n" + " file->file_name = \"${bin2cpp_file_object_file_name}\";\n" + " file->file_path = \"${bin2cpp_file_object_file_path}\";\n" " file->buffer = NULL;\n" " file->load = ${bin2cpp_function_identifier_lowercase}_load;\n" " file->unload = ${bin2cpp_function_identifier_lowercase}_free;\n" @@ -158,7 +158,7 @@ namespace bin2cpp "${bin2cpp_c_file_manager_registration_post_init_impl}" "}\n" "\n" - "${bin2cpp_baseclass}* ${bin2cpp_cpp_getter_function_name}(void)\n" + "${bin2cpp_baseclass}* ${bin2cpp_getter_function_name}(void)\n" "{\n" " ${bin2cpp_function_identifier_lowercase}_init();\n" " return &${bin2cpp_function_identifier_lowercase}_file;\n" diff --git a/src/bin2cpp/Win32ResourceGenerator.cpp b/src/bin2cpp/Win32ResourceGenerator.cpp index 14b37b8..42045e8 100755 --- a/src/bin2cpp/Win32ResourceGenerator.cpp +++ b/src/bin2cpp/Win32ResourceGenerator.cpp @@ -64,7 +64,7 @@ namespace bin2cpp const std::string text = "" "${bin2cpp_output_file_header}" - "#include \"${bin2cpp_cpp_header_include_path}\"\n" + "#include \"${bin2cpp_header_source_file_include_path}\"\n" "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" "#define _CRT_SECURE_NO_WARNINGS\n" "#endif\n" @@ -98,8 +98,8 @@ namespace bin2cpp " }\n" " virtual ~${bin2cpp_classname}() { unloadResource(); }\n" " virtual size_t getSize() const { return mBufferSize; }\n" - " virtual const char * getFileName() const { ${bin2cpp_cpp_get_file_name_impl} }\n" - " virtual const char * getFilePath() const { ${bin2cpp_cpp_get_file_path_impl} }\n" + " virtual const char * getFileName() const { ${bin2cpp_file_object_file_name_impl} }\n" + " virtual const char * getFilePath() const { ${bin2cpp_file_object_file_path_impl} }\n" " virtual const char * getBuffer() const { return mBuffer; }\n" " void loadResource()\n" " {\n" @@ -151,7 +151,7 @@ namespace bin2cpp " DWORD mBufferSize;\n" " const char * mBuffer;\n" " };\n" - " const ${bin2cpp_baseclass} & ${bin2cpp_cpp_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" + " const ${bin2cpp_baseclass} & ${bin2cpp_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" "${bin2cpp_cpp_get_file_manager_registration_impl}" "}; //${bin2cpp_namespace}\n"; @@ -178,7 +178,7 @@ namespace bin2cpp "#define _CRT_SECURE_NO_WARNINGS\n" "#endif\n" "\n" - "#include \"${bin2cpp_cpp_header_include_path}\"\n" + "#include \"${bin2cpp_header_source_file_include_path}\"\n" "#include // for malloc\n" "#include // for memset\n" "#include // for fopen\n" @@ -281,8 +281,8 @@ namespace bin2cpp " // initialize\n" " ${bin2cpp_baseclass}* file = &${bin2cpp_function_identifier_lowercase}_file;\n" " file->size = ${bin2cpp_input_file_size}ULL;\n" - " file->file_name = \"${bin2cpp_get_file_obj_file_name}\";\n" - " file->file_path = \"${bin2cpp_get_file_obj_file_path}\";\n" + " file->file_name = \"${bin2cpp_file_object_file_name}\";\n" + " file->file_path = \"${bin2cpp_file_object_file_path}\";\n" " file->buffer = NULL;\n" " file->load = ${bin2cpp_function_identifier_lowercase}_load;\n" " file->unload = ${bin2cpp_function_identifier_lowercase}_free;\n" @@ -293,7 +293,7 @@ namespace bin2cpp "${bin2cpp_c_file_manager_registration_post_init_impl}" "}\n" "\n" - "${bin2cpp_baseclass}* ${bin2cpp_cpp_getter_function_name}(void)\n" + "${bin2cpp_baseclass}* ${bin2cpp_getter_function_name}(void)\n" "{\n" " ${bin2cpp_function_identifier_lowercase}_init();\n" " return &${bin2cpp_function_identifier_lowercase}_file;\n" From d6b310ba9de823b296a4cf0092506c608b867a6a Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Fri, 30 May 2025 21:21:30 -0400 Subject: [PATCH 15/26] Fixed compilation issues. --- test/bin2cpp_unittest/TestExtraction.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/bin2cpp_unittest/TestExtraction.cpp b/test/bin2cpp_unittest/TestExtraction.cpp index dbde3b8..573d7c9 100755 --- a/test/bin2cpp_unittest/TestExtraction.cpp +++ b/test/bin2cpp_unittest/TestExtraction.cpp @@ -63,10 +63,10 @@ #include "testReportedPathFile2/_testReportedPathFile2.h" #include "testReportedPathDir/generated_sources/FileManagerReportedPathDir.h" -#undef BIN2CPP_EMBEDDEDFILE_CLASS +#undef BIN2CPP_FILE_OBJECT_CLASS #include "testNamespace/_testNamespace.h" -#undef BIN2CPP_EMBEDDEDFILE_CLASS +#undef BIN2CPP_FILE_OBJECT_CLASS #include "testBaseClass/_testBaseClass.h" extern "C" From 69297604baca3877a7ac9942f7caedf7a7826500 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sun, 1 Jun 2025 10:07:40 -0400 Subject: [PATCH 16/26] Optimized code performance in BaseGenerator::getInputFileDataAsCode() --- src/bin2cpp/BaseGenerator.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bin2cpp/BaseGenerator.cpp b/src/bin2cpp/BaseGenerator.cpp index c81f312..26cdac4 100755 --- a/src/bin2cpp/BaseGenerator.cpp +++ b/src/bin2cpp/BaseGenerator.cpp @@ -429,6 +429,11 @@ namespace bin2cpp if ( fileSize % mContext.chunkSize > 0 ) chunkCount++; + // Try to optimize the output buffer string. + // Initialize the output buffer to be around twice the size of the input file. + // Most files will output as hexadecimal values which is roughly doubling the number of bytes of the output file. + output.reserve(2 * fileSize); + //create buffer for each chunks from input buffer int numLinePrinted = 0; size_t chunkIndex = 0; From f48617737116a4dbc82526fea08ed7c59b6f2c2b Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sun, 1 Jun 2025 10:10:47 -0400 Subject: [PATCH 17/26] Fixed failing unit test TestExtraction::testIssue50 --- test/bin2cpp_unittest/TestExtraction.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/bin2cpp_unittest/TestExtraction.cpp b/test/bin2cpp_unittest/TestExtraction.cpp index 573d7c9..3e527e6 100755 --- a/test/bin2cpp_unittest/TestExtraction.cpp +++ b/test/bin2cpp_unittest/TestExtraction.cpp @@ -645,7 +645,7 @@ TEST_F(TestExtraction, testIssue50) std::string path = "generated_files/testIssue50/_testIssue50.h"; ra::filesystem::NormalizePath(path); ASSERT_TRUE( ra::filesystem::FileExists(path.c_str()) ) << "File '" << path.c_str() << "' not found!"; - ASSERT_TRUE( ra::testing::FindInFile(path.c_str(), "BIN2CPP50_EMBEDDEDFILE_CLASS", line, index) ); + ASSERT_TRUE( ra::testing::FindInFile(path.c_str(), "BIN2CPP50_FILE_OBJECT_CLASS", line, index) ); } //FileManager50.h @@ -653,7 +653,7 @@ TEST_F(TestExtraction, testIssue50) std::string path = "generated_files/testIssue50/FileManager50.h"; ra::filesystem::NormalizePath(path); ASSERT_TRUE( ra::filesystem::FileExists(path.c_str()) ) << "File '" << path.c_str() << "' not found!"; - ASSERT_TRUE( ra::testing::FindInFile(path.c_str(), "BIN2CPP50_EMBEDDEDFILE_CLASS", line, index) ); + ASSERT_TRUE( ra::testing::FindInFile(path.c_str(), "BIN2CPP50_FILE_OBJECT_CLASS", line, index) ); ASSERT_TRUE( ra::testing::FindInFile(path.c_str(), "BIN2CPP50_FILEMANAGER_CLASS", line, index) ); } } From 94102bcf53a2f18937e5f6b582c4f69f5d2dc382 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sun, 1 Jun 2025 10:21:20 -0400 Subject: [PATCH 18/26] First draft for modifying the TemplateProcessor to support TemplateVariable that are strings or streams. --- TODO.txt | 15 ++ src/bin2cpp/BaseGenerator.cpp | 150 +++++++++++++----- src/bin2cpp/BaseGenerator.h | 11 +- src/bin2cpp/ITemplateVariableLookup.h | 24 ++- src/bin2cpp/TemplateProcessor.cpp | 30 +++- src/bin2cpp/Win32ResourceGenerator.cpp | 25 ++- src/bin2cpp/Win32ResourceGenerator.h | 3 +- src/bin2cpp/enums.h | 7 + src/bin2cpp/types.h | 6 + .../TestTemplateProcessor.cpp | 24 ++- 10 files changed, 234 insertions(+), 61 deletions(-) create mode 100644 TODO.txt diff --git a/TODO.txt b/TODO.txt new file mode 100644 index 0000000..67b53c4 --- /dev/null +++ b/TODO.txt @@ -0,0 +1,15 @@ +Rename the following: + +getFileClassFileName to getFileObjectFileName +getFileClassFilePath to getFileObjectFilePath +getFileClassGetFileNameImplementation to getFileObjectGetFileNameImplementation +getFileClassGetFileNameImplementation to getFileObjectGetFileNameImplementation +bin2cpp_getter_function_name to bin2cpp_file_object_getter_function_name +getGetterFunctionName to getFileObjectGetterFunctionName + +check implementation of the following to see if they could be simplified: +* getFileClassGetFileNameImplementation +* getFileClassGetFilePathImplementation + + +Move TemplateProcessor code to its own static library ? diff --git a/src/bin2cpp/BaseGenerator.cpp b/src/bin2cpp/BaseGenerator.cpp index 26cdac4..a6926f8 100755 --- a/src/bin2cpp/BaseGenerator.cpp +++ b/src/bin2cpp/BaseGenerator.cpp @@ -40,6 +40,31 @@ namespace bin2cpp { BaseGenerator::BaseGenerator() { + // Load existing variables + registerTemplateVariable("bin2cpp_baseclass"); + registerTemplateVariable("bin2cpp_c_file_manager_registration_implementation"); + registerTemplateVariable("bin2cpp_c_file_manager_registration_post_init_impl"); + registerTemplateVariable("bin2cpp_c_file_manager_registration_predeclaration"); + registerTemplateVariable("bin2cpp_classname"); + registerTemplateVariable("bin2cpp_cpp_get_file_manager_registration_impl"); + registerTemplateVariable("bin2cpp_cpp_get_save_method_impl"); + registerTemplateVariable("bin2cpp_file_manager_file_header"); + registerTemplateVariable("bin2cpp_file_manager_header_file_name"); + registerTemplateVariable("bin2cpp_file_manager_macro_guard_prefix"); + registerTemplateVariable("bin2cpp_file_object_file_name_impl"); + registerTemplateVariable("bin2cpp_file_object_file_name"); + registerTemplateVariable("bin2cpp_file_object_file_path_impl"); + registerTemplateVariable("bin2cpp_file_object_file_path"); + registerTemplateVariable("bin2cpp_file_object_macro_guard_prefix"); + registerTemplateVariable("bin2cpp_function_identifier_lowercase"); + registerTemplateVariable("bin2cpp_function_identifier"); + registerTemplateVariable("bin2cpp_getter_function_name"); + registerTemplateVariable("bin2cpp_header_source_file_include_path"); + registerTemplateVariable("bin2cpp_input_file_size"); + registerTemplateVariable("bin2cpp_insert_input_file_as_code"); + registerTemplateVariable("bin2cpp_namespace"); + registerTemplateVariable("bin2cpp_output_file_header"); + registerTemplateVariable("bin2cpp_output_file_macro_guard"); } BaseGenerator::~BaseGenerator() @@ -56,44 +81,79 @@ namespace bin2cpp return mContext; } - std::string BaseGenerator::lookupTemplateVariable(const std::string& name) - { - if ( name == "bin2cpp_output_file_macro_guard" ) return getCppIncludeGuardMacroName(mContext.headerFilename); - if ( name == "bin2cpp_output_file_header" ) return getHeaderTemplate(); - if ( name == "bin2cpp_file_object_macro_guard_prefix" ) return getClassMacroGuardPrefix(); - if ( name == "bin2cpp_file_manager_file_header" ) return getHeaderTemplate(false); - if ( name == "bin2cpp_file_manager_header_file_name" ) return mContext.managerHeaderFilename; - if ( name == "bin2cpp_file_manager_macro_guard_prefix" ) return getFileManagerMacroGuardPrefix(); - if ( name == "bin2cpp_baseclass" ) return mContext.baseClass; - if ( name == "bin2cpp_classname" ) return getClassName(); - if ( name == "bin2cpp_namespace" ) return mContext.codeNamespace; - //if ( name == "bin2cpp_baseclass_uppercase" ) return ra::strings::Uppercase(mContext.baseClass); - //if ( name == "bin2cpp_classname_uppercase" ) return ra::strings::Uppercase(getClassName()); - //if ( name == "bin2cpp_namespace_uppercase" ) return ra::strings::Lowercase(mContext.codeNamespace); - //if ( name == "bin2cpp_baseclass_lowercase" ) return ra::strings::Lowercase(mContext.baseClass); - //if ( name == "bin2cpp_classname_lowercase" ) return ra::strings::Lowercase(getClassName()); - //if ( name == "bin2cpp_namespace_lowercase" ) return ra::strings::Lowercase(mContext.codeNamespace); - if ( name == "bin2cpp_function_identifier" ) return mContext.functionIdentifier; - if ( name == "bin2cpp_function_identifier_lowercase" ) return ra::strings::Lowercase(mContext.functionIdentifier); - if ( name == "bin2cpp_getter_function_name" ) return getGetterFunctionName(); - if ( name == "bin2cpp_insert_input_file_as_code" ) return getInputFileDataAsCode(); - if ( name == "bin2cpp_header_source_file_include_path" ) return getCppHeaderIncludePath(); - if ( name == "bin2cpp_file_object_file_name_impl" ) return getFileClassGetFileNameImplementation(); - if ( name == "bin2cpp_file_object_file_path_impl" ) return getFileClassGetFilePathImplementation(); - if ( name == "bin2cpp_file_object_file_name" ) return getFileClassFileName(); - if ( name == "bin2cpp_file_object_file_path" ) return getFileClassFilePath(); - if ( name == "bin2cpp_cpp_get_save_method_impl" ) return getCppSaveMethodTemplate(); - if ( name == "bin2cpp_cpp_get_file_manager_registration_impl" && mContext.registerFiles ) return getCppFileManagerRegistrationImplementationTemplate(); - if ( name == "bin2cpp_c_file_manager_registration_predeclaration" && mContext.registerFiles ) return getCFileManagerRegistrationPredeclarationImplementation(); - if ( name == "bin2cpp_c_file_manager_registration_implementation" && mContext.registerFiles ) return getCFileManagerStaticFileRegistrationImplementation(); - + TemplateVariableFlags BaseGenerator::getTemplateVariableFlags(const std::string& name) + { + if ( !isRegistedTemplateVariable(name) ) + return TEMPLATE_VARIABLE_FLAG_NONE; + + // Handle streamable-only variables + if ( name == "bin2cpp_insert_input_file_as_code" ) return TEMPLATE_VARIABLE_FLAG_STREAMABLE; + + // All other variables are stringable or streamable + return (TemplateVariableFlags)(TEMPLATE_VARIABLE_FLAG_STRINGNABLE | TEMPLATE_VARIABLE_FLAG_STREAMABLE); + } + + void BaseGenerator::writeTemplateVariable(const std::string& name, std::ostream& output) + { + TemplateVariableFlags flags = getTemplateVariableFlags(name); + if ( (flags & TEMPLATE_VARIABLE_FLAG_STREAMABLE) != TEMPLATE_VARIABLE_FLAG_STREAMABLE ) + return; // Not streamable + + if ( name == "bin2cpp_insert_input_file_as_code" ) output << getInputFileDataAsCode(); return; + + // Other variables are assumed "stringable" + std::string tmp; + writeTemplateVariable(name, tmp); + if ( !tmp.empty() ) + { + output << tmp; + return; + } + } + + void BaseGenerator::writeTemplateVariable(const std::string& name, std::string& output) + { + output.clear(); + TemplateVariableFlags flags = getTemplateVariableFlags(name); + if ( (flags & TEMPLATE_VARIABLE_FLAG_STRINGNABLE) != TEMPLATE_VARIABLE_FLAG_STRINGNABLE ) + return; // not stringable + + if ( name == "bin2cpp_output_file_macro_guard" ) { output = getCppIncludeGuardMacroName(mContext.headerFilename); return; } + if ( name == "bin2cpp_output_file_header" ) { output = getHeaderTemplate(); return; } + if ( name == "bin2cpp_file_object_macro_guard_prefix" ) { output = getClassMacroGuardPrefix(); return; } + if ( name == "bin2cpp_file_manager_file_header" ) { output = getHeaderTemplate(false); return; } + if ( name == "bin2cpp_file_manager_header_file_name" ) { output = mContext.managerHeaderFilename; return; } + if ( name == "bin2cpp_file_manager_macro_guard_prefix" ) { output = getFileManagerMacroGuardPrefix(); return; } + if ( name == "bin2cpp_baseclass" ) { output = mContext.baseClass; return; } + if ( name == "bin2cpp_classname" ) { output = getClassName(); return; } + if ( name == "bin2cpp_namespace" ) { output = mContext.codeNamespace; return; } + //if ( name == "bin2cpp_baseclass_uppercase" ) { output = ra::strings::Uppercase(mContext.baseClass); return; } + //if ( name == "bin2cpp_classname_uppercase" ) { output = ra::strings::Uppercase(getClassName()); return; } + //if ( name == "bin2cpp_namespace_uppercase" ) { output = ra::strings::Lowercase(mContext.codeNamespace); return; } + //if ( name == "bin2cpp_baseclass_lowercase" ) { output = ra::strings::Lowercase(mContext.baseClass); return; } + //if ( name == "bin2cpp_classname_lowercase" ) { output = ra::strings::Lowercase(getClassName()); return; } + //if ( name == "bin2cpp_namespace_lowercase" ) { output = ra::strings::Lowercase(mContext.codeNamespace); return; } + if ( name == "bin2cpp_function_identifier" ) { output = mContext.functionIdentifier; return; } + if ( name == "bin2cpp_function_identifier_lowercase" ) { output = ra::strings::Lowercase(mContext.functionIdentifier); return; } + if ( name == "bin2cpp_getter_function_name" ) { output = getGetterFunctionName(); return; } + if ( name == "bin2cpp_header_source_file_include_path" ) { output = getCppHeaderIncludePath(); return; } + if ( name == "bin2cpp_file_object_file_name_impl" ) { output = getFileClassGetFileNameImplementation(); return; } + if ( name == "bin2cpp_file_object_file_path_impl" ) { output = getFileClassGetFilePathImplementation(); return; } + if ( name == "bin2cpp_file_object_file_name" ) { output = getFileClassFileName(); return; } + if ( name == "bin2cpp_file_object_file_path" ) { output = getFileClassFilePath(); return; } + if ( name == "bin2cpp_cpp_get_save_method_impl" ) { output = getCppSaveMethodTemplate(); return; } + if ( name == "bin2cpp_cpp_get_file_manager_registration_impl" && mContext.registerFiles ) { output = getCppFileManagerRegistrationImplementationTemplate(); return; } + if ( name == "bin2cpp_c_file_manager_registration_predeclaration" && mContext.registerFiles ) { output = getCFileManagerRegistrationPredeclarationImplementation(); return; } + if ( name == "bin2cpp_c_file_manager_registration_implementation" && mContext.registerFiles ) { output = getCFileManagerStaticFileRegistrationImplementation(); return; } + if ( name == "bin2cpp_c_file_manager_registration_post_init_impl" && mContext.registerFiles ) { - std::string output; - output += " \n"; - output += " // register when loaded if static initialisation does not work\n"; - output += " ${bin2cpp_namespace}_filemanager_register_file(file);\n"; - return output; + std::string tmp; + tmp += " \n"; + tmp += " // register when loaded if static initialisation does not work\n"; + tmp += " ${bin2cpp_namespace}_filemanager_register_file(file);\n"; + output = tmp; + return; } if ( name == "bin2cpp_input_file_size" ) @@ -101,20 +161,28 @@ namespace bin2cpp //determine file properties uint32_t file_size = ra::filesystem::GetFileSize(mContext.inputFilePath.c_str()); std::string file_size_str = ra::strings::ToString(file_size); - return file_size_str; + output = file_size_str; + return; } - - // Unknown name - return ""; } //------------------------------- //protected methods //------------------------------- - std::string BaseGenerator::getGetterFunctionName() + void BaseGenerator::registerTemplateVariable(const char* name) { + mTemplateVariableNames.insert(name); + } + + bool BaseGenerator::isRegistedTemplateVariable(const std::string& name) + { + bool found = std::find(mTemplateVariableNames.begin(), mTemplateVariableNames.end(), name) != mTemplateVariableNames.end(); + return found; + } + std::string BaseGenerator::getGetterFunctionName() + { std::string getter; switch ( mContext.code ) { diff --git a/src/bin2cpp/BaseGenerator.h b/src/bin2cpp/BaseGenerator.h index 6f88f4f..cc7f4c0 100644 --- a/src/bin2cpp/BaseGenerator.h +++ b/src/bin2cpp/BaseGenerator.h @@ -26,6 +26,7 @@ #define BASEGENERATOR_H #include "IGenerator.h" +#include "types.h" #include namespace bin2cpp @@ -45,7 +46,9 @@ namespace bin2cpp virtual const Context & getContext() const; //ITemplateVariableLookup methods - virtual std::string lookupTemplateVariable(const std::string& name); + virtual TemplateVariableFlags getTemplateVariableFlags(const std::string& name); + virtual void writeTemplateVariable(const std::string& name, std::ostream& output); + virtual void writeTemplateVariable(const std::string& name, std::string& output); //same header file for all generators virtual bool createCppHeaderFile(const char * header_file_path); @@ -54,7 +57,8 @@ namespace bin2cpp virtual bool createCSourceFile(const char* file_path); protected: - + virtual void registerTemplateVariable(const char* name); + virtual bool isRegistedTemplateVariable(const std::string& name); virtual std::string getGetterFunctionName(); virtual std::string getHeaderFilePath(const char * cpp_file_path); virtual std::string getCppFilePath(const char * header_file_path); @@ -77,6 +81,9 @@ namespace bin2cpp //attributes Context mContext; + + private: + Dictionary mTemplateVariableNames; }; }; //bin2cpp diff --git a/src/bin2cpp/ITemplateVariableLookup.h b/src/bin2cpp/ITemplateVariableLookup.h index 760e9ba..d666b0c 100644 --- a/src/bin2cpp/ITemplateVariableLookup.h +++ b/src/bin2cpp/ITemplateVariableLookup.h @@ -25,8 +25,10 @@ #ifndef ITEMPLATE_VARIABLE_LOOKUP_H #define ITEMPLATE_VARIABLE_LOOKUP_H +#include "enums.h" #include - +#include + namespace bin2cpp { @@ -37,11 +39,25 @@ namespace bin2cpp {} /// - ///Look up the value for a given template variable name. + ///Get the associated flags for the given template variable name. + /// + ///The name of the template variable. + ///Returns the flags for template variable of the given name. + virtual TemplateVariableFlags getTemplateVariableFlags(const std::string& name) = 0; + + /// + ///Write the value of the given template variable name to the output stream. + /// + ///The name of the template variable. + ///The variable where to output the template variable's value. + virtual void writeTemplateVariable(const std::string& name, std::ostream& output) = 0; + + /// + ///Write the value of the given template variable name to the output string. /// ///The name of the template variable. - ///Returns the value of the template variable. Returns an empty string if unknown. - virtual std::string lookupTemplateVariable(const std::string& name) = 0; + ///The variable where to output the template variable's value. + virtual void writeTemplateVariable(const std::string& name, std::string& output) = 0; }; diff --git a/src/bin2cpp/TemplateProcessor.cpp b/src/bin2cpp/TemplateProcessor.cpp index 96d9dee..b105309 100644 --- a/src/bin2cpp/TemplateProcessor.cpp +++ b/src/bin2cpp/TemplateProcessor.cpp @@ -116,17 +116,31 @@ namespace bin2cpp continue; } - // Do the variable expansion - std::string expanded_value = mVariableLookup ? mVariableLookup->lookupTemplateVariable(variable_name) : ""; + // Get variable flags + TemplateVariableFlags flags = TEMPLATE_VARIABLE_FLAG_NONE; + if ( mVariableLookup ) + flags = mVariableLookup->getTemplateVariableFlags(variable_name); - // Add variable to recursion history before expanding - recursion_history.insert(variable_name); + // For string variables, do the variable expansion and recursion + if ( (flags & TEMPLATE_VARIABLE_FLAG_STRINGNABLE) == TEMPLATE_VARIABLE_FLAG_STRINGNABLE ) + { + std::string expanded_value; + mVariableLookup->writeTemplateVariable(variable_name, expanded_value); + + // Add variable to recursion history before expanding + recursion_history.insert(variable_name); - // Recursively process expanded value with updated recursion tracking - processTemplate(output_stream, expanded_value, recursion_history); + // Recursively process expanded value with updated recursion tracking + processTemplate(output_stream, expanded_value, recursion_history); - // Remove variable from recursion history after recursion returns - recursion_history.erase(variable_name); + // Remove variable from recursion history after recursion returns + recursion_history.erase(variable_name); + } + else if ( (flags & TEMPLATE_VARIABLE_FLAG_STREAMABLE) == TEMPLATE_VARIABLE_FLAG_STREAMABLE ) + { + // For streamable-only variables, just stream the output to our output + mVariableLookup->writeTemplateVariable(variable_name, output_stream); + } pos = end_pos + 1; } diff --git a/src/bin2cpp/Win32ResourceGenerator.cpp b/src/bin2cpp/Win32ResourceGenerator.cpp index 42045e8..26e67c8 100755 --- a/src/bin2cpp/Win32ResourceGenerator.cpp +++ b/src/bin2cpp/Win32ResourceGenerator.cpp @@ -41,6 +41,8 @@ namespace bin2cpp { Win32ResourceGenerator::Win32ResourceGenerator() { + registerTemplateVariable("bin2cpp_win32_resource_random_identifier"); + registerTemplateVariable("bin2cpp_win32_local_info_struct_name"); } Win32ResourceGenerator::~Win32ResourceGenerator() @@ -376,13 +378,28 @@ namespace bin2cpp return false; // not supported } - std::string Win32ResourceGenerator::lookupTemplateVariable(const std::string& name) + TemplateVariableFlags Win32ResourceGenerator::getTemplateVariableFlags(const std::string& name) { - if ( name == "bin2cpp_win32_resource_random_identifier" ) return getRandomIdentifier(mContext.inputFilePath.c_str()); - if ( name == "bin2cpp_win32_local_info_struct_name" ) return getLocalInfoStructName(); + if ( name == "bin2cpp_win32_resource_random_identifier" ) return TEMPLATE_VARIABLE_FLAG_STRINGNABLE; + if ( name == "bin2cpp_win32_local_info_struct_name" ) return TEMPLATE_VARIABLE_FLAG_STRINGNABLE; + return BaseGenerator::getTemplateVariableFlags(name); + } + + void Win32ResourceGenerator::writeTemplateVariable(const std::string& name, std::string& output) + { + if ( name == "bin2cpp_win32_resource_random_identifier" ) + { + output = getRandomIdentifier(mContext.inputFilePath.c_str()); + return; + } + if ( name == "bin2cpp_win32_local_info_struct_name" ) + { + output = getLocalInfoStructName(); + return; + } // Unknown name - return this->BaseGenerator::lookupTemplateVariable(name); + return this->BaseGenerator::writeTemplateVariable(name, output); } std::string Win32ResourceGenerator::getLocalInfoStructName() diff --git a/src/bin2cpp/Win32ResourceGenerator.h b/src/bin2cpp/Win32ResourceGenerator.h index c157d6a..1dd2130 100644 --- a/src/bin2cpp/Win32ResourceGenerator.h +++ b/src/bin2cpp/Win32ResourceGenerator.h @@ -44,7 +44,8 @@ namespace bin2cpp virtual bool printFileContent(); //ITemplateVariableLookup methods - virtual std::string lookupTemplateVariable(const std::string& name); + virtual TemplateVariableFlags getTemplateVariableFlags(const std::string& name); + virtual void writeTemplateVariable(const std::string& name, std::string& output); protected: virtual std::string getResourceFilePath(const char * file_path); diff --git a/src/bin2cpp/enums.h b/src/bin2cpp/enums.h index 82a7539..1b36a47 100644 --- a/src/bin2cpp/enums.h +++ b/src/bin2cpp/enums.h @@ -46,6 +46,13 @@ namespace bin2cpp CODE_GENERATION_CPP, CODE_GENERATION_C, }; + + enum TemplateVariableFlags + { + TEMPLATE_VARIABLE_FLAG_NONE = 0, + TEMPLATE_VARIABLE_FLAG_STRINGNABLE = 1, + TEMPLATE_VARIABLE_FLAG_STREAMABLE = 2, + }; }; //bin2cpp diff --git a/src/bin2cpp/types.h b/src/bin2cpp/types.h index 5f3bc09..72cff29 100644 --- a/src/bin2cpp/types.h +++ b/src/bin2cpp/types.h @@ -26,6 +26,7 @@ #define TYPES_H #include +#include #include namespace bin2cpp @@ -36,6 +37,11 @@ namespace bin2cpp /// typedef std::set Dictionary; + /// + ///A vector of strings + /// + typedef std::vector StringVector; + }; //bin2cpp #endif //TYPES_H diff --git a/test/bin2cpp_unittest/TestTemplateProcessor.cpp b/test/bin2cpp_unittest/TestTemplateProcessor.cpp index d7368de..b236e90 100644 --- a/test/bin2cpp_unittest/TestTemplateProcessor.cpp +++ b/test/bin2cpp_unittest/TestTemplateProcessor.cpp @@ -35,7 +35,24 @@ class SampleVariableLookup : public bin2cpp::ITemplateVariableLookup { public: - std::string lookupTemplateVariable(const std::string& name) override + bin2cpp::TemplateVariableFlags getTemplateVariableFlags(const std::string& name) + { + if ( name == "first-name" ) return bin2cpp::TEMPLATE_VARIABLE_FLAG_STRINGNABLE; + if ( name == "last-name" ) return bin2cpp::TEMPLATE_VARIABLE_FLAG_STRINGNABLE; + if ( name == "full-name" ) return bin2cpp::TEMPLATE_VARIABLE_FLAG_STRINGNABLE; + if ( name == "age" ) return bin2cpp::TEMPLATE_VARIABLE_FLAG_STRINGNABLE; + if ( name == "job" ) return bin2cpp::TEMPLATE_VARIABLE_FLAG_STRINGNABLE; + if ( name == "children" ) return bin2cpp::TEMPLATE_VARIABLE_FLAG_STRINGNABLE; + if ( name == "foo" ) return bin2cpp::TEMPLATE_VARIABLE_FLAG_STRINGNABLE; + if ( name == "bar" ) return bin2cpp::TEMPLATE_VARIABLE_FLAG_STRINGNABLE; + if ( name == "baz" ) return bin2cpp::TEMPLATE_VARIABLE_FLAG_STRINGNABLE; + return bin2cpp::TEMPLATE_VARIABLE_FLAG_NONE; + } + + void writeTemplateVariable(const std::string& name, std::ostream& output) + {} + + inline std::string getTemplateVariableAsString(const std::string& name) { if ( name == "first-name" ) return "Luke"; if ( name == "last-name" ) return "Skywalker"; @@ -48,6 +65,11 @@ class SampleVariableLookup : public bin2cpp::ITemplateVariableLookup if ( name == "baz" ) return "baz is ${foo}"; return ""; } + + void writeTemplateVariable(const std::string& name, std::string& output) override + { + output = getTemplateVariableAsString(name); + } }; void TestTemplateProcessor::SetUp() From d5ad856b314616040c9730a054c7bc7b8f399ff2 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sun, 1 Jun 2025 10:28:53 -0400 Subject: [PATCH 19/26] Renamed interface `ITemplateVariableLookup` to `ITemplateVariableHandler`. --- src/bin2cpp/ArrayGenerator.cpp | 4 ++-- src/bin2cpp/BaseGenerator.cpp | 4 ++-- src/bin2cpp/BaseGenerator.h | 2 +- src/bin2cpp/CMakeLists.txt | 2 +- src/bin2cpp/IGenerator.h | 4 ++-- ...ableLookup.h => ITemplateVariableHandler.h} | 10 +++++----- src/bin2cpp/ManagerGenerator.cpp | 8 ++++---- src/bin2cpp/SegmentGenerator.cpp | 4 ++-- src/bin2cpp/StringGenerator.cpp | 4 ++-- src/bin2cpp/TemplateProcessor.cpp | 18 +++++++++--------- src/bin2cpp/TemplateProcessor.h | 8 ++++---- src/bin2cpp/Win32ResourceGenerator.cpp | 4 ++-- src/bin2cpp/Win32ResourceGenerator.h | 2 +- test/bin2cpp_unittest/CMakeLists.txt | 4 ++-- .../bin2cpp_unittest/TestTemplateProcessor.cpp | 14 +++++++------- 15 files changed, 46 insertions(+), 46 deletions(-) rename src/bin2cpp/{ITemplateVariableLookup.h => ITemplateVariableHandler.h} (93%) diff --git a/src/bin2cpp/ArrayGenerator.cpp b/src/bin2cpp/ArrayGenerator.cpp index 3dc15b2..696b441 100644 --- a/src/bin2cpp/ArrayGenerator.cpp +++ b/src/bin2cpp/ArrayGenerator.cpp @@ -82,7 +82,7 @@ namespace bin2cpp "}; //${bin2cpp_namespace}\n"; TemplateProcessor processor(&text); - processor.setTemplateVariableLookup(this); + processor.setTemplateVariableHandler(this); bool write_success = processor.writeFile(file_path); return write_success; @@ -179,7 +179,7 @@ namespace bin2cpp "${bin2cpp_c_file_manager_registration_implementation}"; TemplateProcessor processor(&text); - processor.setTemplateVariableLookup(this); + processor.setTemplateVariableHandler(this); bool write_success = processor.writeFile(file_path); return write_success; diff --git a/src/bin2cpp/BaseGenerator.cpp b/src/bin2cpp/BaseGenerator.cpp index a6926f8..bcf7e3e 100755 --- a/src/bin2cpp/BaseGenerator.cpp +++ b/src/bin2cpp/BaseGenerator.cpp @@ -568,7 +568,7 @@ namespace bin2cpp ; TemplateProcessor processor(&text); - processor.setTemplateVariableLookup(this); + processor.setTemplateVariableHandler(this); bool write_success = processor.writeFile(header_file_path); return write_success; @@ -660,7 +660,7 @@ namespace bin2cpp ; TemplateProcessor processor(&text); - processor.setTemplateVariableLookup(this); + processor.setTemplateVariableHandler(this); bool write_success = processor.writeFile(file_path); return write_success; diff --git a/src/bin2cpp/BaseGenerator.h b/src/bin2cpp/BaseGenerator.h index cc7f4c0..f246f3a 100644 --- a/src/bin2cpp/BaseGenerator.h +++ b/src/bin2cpp/BaseGenerator.h @@ -45,7 +45,7 @@ namespace bin2cpp virtual void setContext(const Context& c); virtual const Context & getContext() const; - //ITemplateVariableLookup methods + //ITemplateVariableHandler methods virtual TemplateVariableFlags getTemplateVariableFlags(const std::string& name); virtual void writeTemplateVariable(const std::string& name, std::ostream& output); virtual void writeTemplateVariable(const std::string& name, std::string& output); diff --git a/src/bin2cpp/CMakeLists.txt b/src/bin2cpp/CMakeLists.txt index c21f1b5..3a84c3e 100644 --- a/src/bin2cpp/CMakeLists.txt +++ b/src/bin2cpp/CMakeLists.txt @@ -22,7 +22,7 @@ add_executable(bin2cpp enums.h IGenerator.h INameProvider.h - ITemplateVariableLookup.h + ITemplateVariableHandler.h LegacyNameProvider.cpp LegacyNameProvider.h main.cpp diff --git a/src/bin2cpp/IGenerator.h b/src/bin2cpp/IGenerator.h index da7ca54..e51e9ac 100644 --- a/src/bin2cpp/IGenerator.h +++ b/src/bin2cpp/IGenerator.h @@ -27,12 +27,12 @@ #include #include "Context.h" -#include "ITemplateVariableLookup.h" +#include "ITemplateVariableHandler.h" namespace bin2cpp { - class IGenerator : public virtual ITemplateVariableLookup + class IGenerator : public virtual ITemplateVariableHandler { public: diff --git a/src/bin2cpp/ITemplateVariableLookup.h b/src/bin2cpp/ITemplateVariableHandler.h similarity index 93% rename from src/bin2cpp/ITemplateVariableLookup.h rename to src/bin2cpp/ITemplateVariableHandler.h index d666b0c..c42c3ab 100644 --- a/src/bin2cpp/ITemplateVariableLookup.h +++ b/src/bin2cpp/ITemplateVariableHandler.h @@ -22,8 +22,8 @@ * SOFTWARE. *********************************************************************************/ -#ifndef ITEMPLATE_VARIABLE_LOOKUP_H -#define ITEMPLATE_VARIABLE_LOOKUP_H +#ifndef ITEMPLATE_VARIABLE_HANDLER_H +#define ITEMPLATE_VARIABLE_HANDLER_H #include "enums.h" #include @@ -32,10 +32,10 @@ namespace bin2cpp { - class ITemplateVariableLookup + class ITemplateVariableHandler { public: - virtual ~ITemplateVariableLookup() + virtual ~ITemplateVariableHandler() {} /// @@ -63,4 +63,4 @@ namespace bin2cpp }; //bin2cpp -#endif //ITEMPLATE_VARIABLE_LOOKUP_H +#endif //ITEMPLATE_VARIABLE_HANDLER_H diff --git a/src/bin2cpp/ManagerGenerator.cpp b/src/bin2cpp/ManagerGenerator.cpp index e5825ae..eeba093 100644 --- a/src/bin2cpp/ManagerGenerator.cpp +++ b/src/bin2cpp/ManagerGenerator.cpp @@ -98,7 +98,7 @@ namespace bin2cpp ; TemplateProcessor processor(&text); - processor.setTemplateVariableLookup(this); + processor.setTemplateVariableHandler(this); bool write_success = processor.writeFile(file_path); return write_success; @@ -218,7 +218,7 @@ namespace bin2cpp ; TemplateProcessor processor(&text); - processor.setTemplateVariableLookup(this); + processor.setTemplateVariableHandler(this); bool write_success = processor.writeFile(file_path); return write_success; @@ -262,7 +262,7 @@ namespace bin2cpp ; TemplateProcessor processor(&text); - processor.setTemplateVariableLookup(this); + processor.setTemplateVariableHandler(this); bool write_success = processor.writeFile(file_path); return write_success; @@ -429,7 +429,7 @@ namespace bin2cpp ; TemplateProcessor processor(&text); - processor.setTemplateVariableLookup(this); + processor.setTemplateVariableHandler(this); bool write_success = processor.writeFile(file_path); return write_success; diff --git a/src/bin2cpp/SegmentGenerator.cpp b/src/bin2cpp/SegmentGenerator.cpp index e36ffaa..59a055a 100755 --- a/src/bin2cpp/SegmentGenerator.cpp +++ b/src/bin2cpp/SegmentGenerator.cpp @@ -88,7 +88,7 @@ namespace bin2cpp "}; //${bin2cpp_namespace}\n"; TemplateProcessor processor(&text); - processor.setTemplateVariableLookup(this); + processor.setTemplateVariableHandler(this); bool write_success = processor.writeFile(file_path); return write_success; @@ -179,7 +179,7 @@ namespace bin2cpp "${bin2cpp_c_file_manager_registration_implementation}"; TemplateProcessor processor(&text); - processor.setTemplateVariableLookup(this); + processor.setTemplateVariableHandler(this); bool write_success = processor.writeFile(file_path); return write_success; diff --git a/src/bin2cpp/StringGenerator.cpp b/src/bin2cpp/StringGenerator.cpp index 1a2bd5c..0372ed4 100755 --- a/src/bin2cpp/StringGenerator.cpp +++ b/src/bin2cpp/StringGenerator.cpp @@ -81,7 +81,7 @@ namespace bin2cpp "}; //${bin2cpp_namespace}\n"; TemplateProcessor processor(&text); - processor.setTemplateVariableLookup(this); + processor.setTemplateVariableHandler(this); bool write_success = processor.writeFile(file_path); return write_success; @@ -166,7 +166,7 @@ namespace bin2cpp "${bin2cpp_c_file_manager_registration_implementation}"; TemplateProcessor processor(&text); - processor.setTemplateVariableLookup(this); + processor.setTemplateVariableHandler(this); bool write_success = processor.writeFile(file_path); return write_success; diff --git a/src/bin2cpp/TemplateProcessor.cpp b/src/bin2cpp/TemplateProcessor.cpp index b105309..2654158 100644 --- a/src/bin2cpp/TemplateProcessor.cpp +++ b/src/bin2cpp/TemplateProcessor.cpp @@ -46,7 +46,7 @@ namespace bin2cpp void TemplateProcessor::reset() { mTemplateText = NULL; - mVariableLookup = NULL; + mVariableHandler = NULL; } void TemplateProcessor::setTemplateText(const std::string* value) @@ -59,14 +59,14 @@ namespace bin2cpp return mTemplateText; } - void TemplateProcessor::setTemplateVariableLookup(ITemplateVariableLookup* lookup) + void TemplateProcessor::setTemplateVariableHandler(ITemplateVariableHandler* handler) { - mVariableLookup = lookup; + mVariableHandler = handler; } - ITemplateVariableLookup* TemplateProcessor::getTemplateVariableLookup() const + ITemplateVariableHandler* TemplateProcessor::getTemplateVariableHandler() const { - return mVariableLookup; + return mVariableHandler; } void TemplateProcessor::writeStream(std::ostream& output_stream) @@ -118,14 +118,14 @@ namespace bin2cpp // Get variable flags TemplateVariableFlags flags = TEMPLATE_VARIABLE_FLAG_NONE; - if ( mVariableLookup ) - flags = mVariableLookup->getTemplateVariableFlags(variable_name); + if ( mVariableHandler ) + flags = mVariableHandler->getTemplateVariableFlags(variable_name); // For string variables, do the variable expansion and recursion if ( (flags & TEMPLATE_VARIABLE_FLAG_STRINGNABLE) == TEMPLATE_VARIABLE_FLAG_STRINGNABLE ) { std::string expanded_value; - mVariableLookup->writeTemplateVariable(variable_name, expanded_value); + mVariableHandler->writeTemplateVariable(variable_name, expanded_value); // Add variable to recursion history before expanding recursion_history.insert(variable_name); @@ -139,7 +139,7 @@ namespace bin2cpp else if ( (flags & TEMPLATE_VARIABLE_FLAG_STREAMABLE) == TEMPLATE_VARIABLE_FLAG_STREAMABLE ) { // For streamable-only variables, just stream the output to our output - mVariableLookup->writeTemplateVariable(variable_name, output_stream); + mVariableHandler->writeTemplateVariable(variable_name, output_stream); } pos = end_pos + 1; diff --git a/src/bin2cpp/TemplateProcessor.h b/src/bin2cpp/TemplateProcessor.h index 32e1d5d..756446e 100644 --- a/src/bin2cpp/TemplateProcessor.h +++ b/src/bin2cpp/TemplateProcessor.h @@ -27,7 +27,7 @@ #include #include -#include "ITemplateVariableLookup.h" +#include "ITemplateVariableHandler.h" namespace bin2cpp { @@ -47,8 +47,8 @@ namespace bin2cpp void setTemplateText(const std::string* value); const std::string* getTemplateText() const; - void setTemplateVariableLookup(ITemplateVariableLookup* lookup); - ITemplateVariableLookup* getTemplateVariableLookup() const; + void setTemplateVariableHandler(ITemplateVariableHandler* handler); + ITemplateVariableHandler* getTemplateVariableHandler() const; virtual void writeStream(std::ostream& output_stream); virtual void writeString(std::string& output); @@ -59,7 +59,7 @@ namespace bin2cpp //attributes const std::string* mTemplateText; - ITemplateVariableLookup* mVariableLookup; + ITemplateVariableHandler* mVariableHandler; }; }; //bin2cpp diff --git a/src/bin2cpp/Win32ResourceGenerator.cpp b/src/bin2cpp/Win32ResourceGenerator.cpp index 26e67c8..3e67ce9 100755 --- a/src/bin2cpp/Win32ResourceGenerator.cpp +++ b/src/bin2cpp/Win32ResourceGenerator.cpp @@ -158,7 +158,7 @@ namespace bin2cpp "}; //${bin2cpp_namespace}\n"; TemplateProcessor processor(&text); - processor.setTemplateVariableLookup(this); + processor.setTemplateVariableHandler(this); bool write_success = processor.writeFile(file_path); return write_success; @@ -303,7 +303,7 @@ namespace bin2cpp "${bin2cpp_c_file_manager_registration_implementation}"; TemplateProcessor processor(&text); - processor.setTemplateVariableLookup(this); + processor.setTemplateVariableHandler(this); bool write_success = processor.writeFile(file_path); return write_success; diff --git a/src/bin2cpp/Win32ResourceGenerator.h b/src/bin2cpp/Win32ResourceGenerator.h index 1dd2130..80a8d9e 100644 --- a/src/bin2cpp/Win32ResourceGenerator.h +++ b/src/bin2cpp/Win32ResourceGenerator.h @@ -43,7 +43,7 @@ namespace bin2cpp virtual bool createCSourceFile(const char* file_path); virtual bool printFileContent(); - //ITemplateVariableLookup methods + //ITemplateVariableHandler methods virtual TemplateVariableFlags getTemplateVariableFlags(const std::string& name); virtual void writeTemplateVariable(const std::string& name, std::string& output); diff --git a/test/bin2cpp_unittest/CMakeLists.txt b/test/bin2cpp_unittest/CMakeLists.txt index c682746..c8c064d 100644 --- a/test/bin2cpp_unittest/CMakeLists.txt +++ b/test/bin2cpp_unittest/CMakeLists.txt @@ -285,7 +285,7 @@ source_group("External Files" FILES ${CMAKE_SOURCE_DIR}/src/bin2cpp/common.h ${CMAKE_SOURCE_DIR}/src/bin2cpp/wildcard.cpp ${CMAKE_SOURCE_DIR}/src/bin2cpp/wildcard.h - ${CMAKE_SOURCE_DIR}/src/bin2cpp/ITemplateVariableLookup.h + ${CMAKE_SOURCE_DIR}/src/bin2cpp/ITemplateVariableHandler.h ${CMAKE_SOURCE_DIR}/src/bin2cpp/TemplateProcessor.cpp ${CMAKE_SOURCE_DIR}/src/bin2cpp/TemplateProcessor.h ) @@ -300,7 +300,7 @@ add_executable(bin2cpp_unittest ${CMAKE_SOURCE_DIR}/src/bin2cpp/common.h ${CMAKE_SOURCE_DIR}/src/bin2cpp/wildcard.cpp ${CMAKE_SOURCE_DIR}/src/bin2cpp/wildcard.h - ${CMAKE_SOURCE_DIR}/src/bin2cpp/ITemplateVariableLookup.h + ${CMAKE_SOURCE_DIR}/src/bin2cpp/ITemplateVariableHandler.h ${CMAKE_SOURCE_DIR}/src/bin2cpp/TemplateProcessor.cpp ${CMAKE_SOURCE_DIR}/src/bin2cpp/TemplateProcessor.h application.cpp diff --git a/test/bin2cpp_unittest/TestTemplateProcessor.cpp b/test/bin2cpp_unittest/TestTemplateProcessor.cpp index b236e90..6a60895 100644 --- a/test/bin2cpp_unittest/TestTemplateProcessor.cpp +++ b/test/bin2cpp_unittest/TestTemplateProcessor.cpp @@ -32,7 +32,7 @@ #include "rapidassist/user.h" // Sample variable lookup implementation -class SampleVariableLookup : public bin2cpp::ITemplateVariableLookup +class SampleVariableLookup : public bin2cpp::ITemplateVariableHandler { public: bin2cpp::TemplateVariableFlags getTemplateVariableFlags(const std::string& name) @@ -84,7 +84,7 @@ TEST_F(TestTemplateProcessor, testBaseSingleVariable) { bin2cpp::TemplateProcessor processor; SampleVariableLookup lookup; - processor.setTemplateVariableLookup(&lookup); + processor.setTemplateVariableHandler(&lookup); const std::string actual_input = "I am ${age} years old."; const std::string expected_output = "I am 53 years old."; @@ -98,7 +98,7 @@ TEST_F(TestTemplateProcessor, testUnknownVariable) { bin2cpp::TemplateProcessor processor; SampleVariableLookup lookup; - processor.setTemplateVariableLookup(&lookup); + processor.setTemplateVariableHandler(&lookup); const std::string actual_input = "My ${father} tried to kill me."; const std::string expected_output = "My tried to kill me."; @@ -112,7 +112,7 @@ TEST_F(TestTemplateProcessor, testCaseSensitive) { bin2cpp::TemplateProcessor processor; SampleVariableLookup lookup; - processor.setTemplateVariableLookup(&lookup); + processor.setTemplateVariableHandler(&lookup); const std::string actual_input = "The variable '${children}' should expand to a value but '${Children}' should be empty."; const std::string expected_output = "The variable '2' should expand to a value but '' should be empty."; @@ -126,7 +126,7 @@ TEST_F(TestTemplateProcessor, testRecursive) { bin2cpp::TemplateProcessor processor; SampleVariableLookup lookup; - processor.setTemplateVariableLookup(&lookup); + processor.setTemplateVariableHandler(&lookup); const std::string actual_input = "My name is ${full-name}. I work as a ${job} now."; const std::string expected_output = "My name is Luke Skywalker. I work as a Jedi Knight now."; @@ -140,7 +140,7 @@ TEST_F(TestTemplateProcessor, testMultipleTwinMarkers) { bin2cpp::TemplateProcessor processor; SampleVariableLookup lookup; - processor.setTemplateVariableLookup(&lookup); + processor.setTemplateVariableHandler(&lookup); const std::string actual_input = "My name is ${first-name} but everyone calls me Lucky-${first-name}."; const std::string expected_output = "My name is Luke but everyone calls me Lucky-Luke."; @@ -154,7 +154,7 @@ TEST_F(TestTemplateProcessor, testCircularReference) { bin2cpp::TemplateProcessor processor; SampleVariableLookup lookup; - processor.setTemplateVariableLookup(&lookup); + processor.setTemplateVariableHandler(&lookup); const std::string actual_input = "${foo}"; const std::string expected_output = "foo is bar is baz is "; From 06af3fb395b20a2a49996922c685f4fa89f4b936 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sun, 1 Jun 2025 10:42:58 -0400 Subject: [PATCH 20/26] Revert "Renamed interface `ITemplateVariableLookup` to `ITemplateVariableHandler`." This reverts commit d5ad856b314616040c9730a054c7bc7b8f399ff2. Revert "First draft for modifying the TemplateProcessor to support TemplateVariable that are strings or streams." This reverts commit 94102bcf53a2f18937e5f6b582c4f69f5d2dc382. --- src/bin2cpp/ArrayGenerator.cpp | 4 +- src/bin2cpp/BaseGenerator.cpp | 154 +++++------------- src/bin2cpp/BaseGenerator.h | 13 +- src/bin2cpp/CMakeLists.txt | 2 +- src/bin2cpp/IGenerator.h | 4 +- ...bleHandler.h => ITemplateVariableLookup.h} | 34 +--- src/bin2cpp/ManagerGenerator.cpp | 8 +- src/bin2cpp/SegmentGenerator.cpp | 4 +- src/bin2cpp/StringGenerator.cpp | 4 +- src/bin2cpp/TemplateProcessor.cpp | 40 ++--- src/bin2cpp/TemplateProcessor.h | 8 +- src/bin2cpp/Win32ResourceGenerator.cpp | 29 +--- src/bin2cpp/Win32ResourceGenerator.h | 5 +- src/bin2cpp/enums.h | 7 - src/bin2cpp/types.h | 6 - test/bin2cpp_unittest/CMakeLists.txt | 4 +- .../TestTemplateProcessor.cpp | 38 +---- 17 files changed, 103 insertions(+), 261 deletions(-) rename src/bin2cpp/{ITemplateVariableHandler.h => ITemplateVariableLookup.h} (55%) diff --git a/src/bin2cpp/ArrayGenerator.cpp b/src/bin2cpp/ArrayGenerator.cpp index 696b441..3dc15b2 100644 --- a/src/bin2cpp/ArrayGenerator.cpp +++ b/src/bin2cpp/ArrayGenerator.cpp @@ -82,7 +82,7 @@ namespace bin2cpp "}; //${bin2cpp_namespace}\n"; TemplateProcessor processor(&text); - processor.setTemplateVariableHandler(this); + processor.setTemplateVariableLookup(this); bool write_success = processor.writeFile(file_path); return write_success; @@ -179,7 +179,7 @@ namespace bin2cpp "${bin2cpp_c_file_manager_registration_implementation}"; TemplateProcessor processor(&text); - processor.setTemplateVariableHandler(this); + processor.setTemplateVariableLookup(this); bool write_success = processor.writeFile(file_path); return write_success; diff --git a/src/bin2cpp/BaseGenerator.cpp b/src/bin2cpp/BaseGenerator.cpp index bcf7e3e..26cdac4 100755 --- a/src/bin2cpp/BaseGenerator.cpp +++ b/src/bin2cpp/BaseGenerator.cpp @@ -40,31 +40,6 @@ namespace bin2cpp { BaseGenerator::BaseGenerator() { - // Load existing variables - registerTemplateVariable("bin2cpp_baseclass"); - registerTemplateVariable("bin2cpp_c_file_manager_registration_implementation"); - registerTemplateVariable("bin2cpp_c_file_manager_registration_post_init_impl"); - registerTemplateVariable("bin2cpp_c_file_manager_registration_predeclaration"); - registerTemplateVariable("bin2cpp_classname"); - registerTemplateVariable("bin2cpp_cpp_get_file_manager_registration_impl"); - registerTemplateVariable("bin2cpp_cpp_get_save_method_impl"); - registerTemplateVariable("bin2cpp_file_manager_file_header"); - registerTemplateVariable("bin2cpp_file_manager_header_file_name"); - registerTemplateVariable("bin2cpp_file_manager_macro_guard_prefix"); - registerTemplateVariable("bin2cpp_file_object_file_name_impl"); - registerTemplateVariable("bin2cpp_file_object_file_name"); - registerTemplateVariable("bin2cpp_file_object_file_path_impl"); - registerTemplateVariable("bin2cpp_file_object_file_path"); - registerTemplateVariable("bin2cpp_file_object_macro_guard_prefix"); - registerTemplateVariable("bin2cpp_function_identifier_lowercase"); - registerTemplateVariable("bin2cpp_function_identifier"); - registerTemplateVariable("bin2cpp_getter_function_name"); - registerTemplateVariable("bin2cpp_header_source_file_include_path"); - registerTemplateVariable("bin2cpp_input_file_size"); - registerTemplateVariable("bin2cpp_insert_input_file_as_code"); - registerTemplateVariable("bin2cpp_namespace"); - registerTemplateVariable("bin2cpp_output_file_header"); - registerTemplateVariable("bin2cpp_output_file_macro_guard"); } BaseGenerator::~BaseGenerator() @@ -81,79 +56,44 @@ namespace bin2cpp return mContext; } - TemplateVariableFlags BaseGenerator::getTemplateVariableFlags(const std::string& name) - { - if ( !isRegistedTemplateVariable(name) ) - return TEMPLATE_VARIABLE_FLAG_NONE; - - // Handle streamable-only variables - if ( name == "bin2cpp_insert_input_file_as_code" ) return TEMPLATE_VARIABLE_FLAG_STREAMABLE; - - // All other variables are stringable or streamable - return (TemplateVariableFlags)(TEMPLATE_VARIABLE_FLAG_STRINGNABLE | TEMPLATE_VARIABLE_FLAG_STREAMABLE); - } - - void BaseGenerator::writeTemplateVariable(const std::string& name, std::ostream& output) - { - TemplateVariableFlags flags = getTemplateVariableFlags(name); - if ( (flags & TEMPLATE_VARIABLE_FLAG_STREAMABLE) != TEMPLATE_VARIABLE_FLAG_STREAMABLE ) - return; // Not streamable - - if ( name == "bin2cpp_insert_input_file_as_code" ) output << getInputFileDataAsCode(); return; - - // Other variables are assumed "stringable" - std::string tmp; - writeTemplateVariable(name, tmp); - if ( !tmp.empty() ) - { - output << tmp; - return; - } - } - - void BaseGenerator::writeTemplateVariable(const std::string& name, std::string& output) - { - output.clear(); - TemplateVariableFlags flags = getTemplateVariableFlags(name); - if ( (flags & TEMPLATE_VARIABLE_FLAG_STRINGNABLE) != TEMPLATE_VARIABLE_FLAG_STRINGNABLE ) - return; // not stringable - - if ( name == "bin2cpp_output_file_macro_guard" ) { output = getCppIncludeGuardMacroName(mContext.headerFilename); return; } - if ( name == "bin2cpp_output_file_header" ) { output = getHeaderTemplate(); return; } - if ( name == "bin2cpp_file_object_macro_guard_prefix" ) { output = getClassMacroGuardPrefix(); return; } - if ( name == "bin2cpp_file_manager_file_header" ) { output = getHeaderTemplate(false); return; } - if ( name == "bin2cpp_file_manager_header_file_name" ) { output = mContext.managerHeaderFilename; return; } - if ( name == "bin2cpp_file_manager_macro_guard_prefix" ) { output = getFileManagerMacroGuardPrefix(); return; } - if ( name == "bin2cpp_baseclass" ) { output = mContext.baseClass; return; } - if ( name == "bin2cpp_classname" ) { output = getClassName(); return; } - if ( name == "bin2cpp_namespace" ) { output = mContext.codeNamespace; return; } - //if ( name == "bin2cpp_baseclass_uppercase" ) { output = ra::strings::Uppercase(mContext.baseClass); return; } - //if ( name == "bin2cpp_classname_uppercase" ) { output = ra::strings::Uppercase(getClassName()); return; } - //if ( name == "bin2cpp_namespace_uppercase" ) { output = ra::strings::Lowercase(mContext.codeNamespace); return; } - //if ( name == "bin2cpp_baseclass_lowercase" ) { output = ra::strings::Lowercase(mContext.baseClass); return; } - //if ( name == "bin2cpp_classname_lowercase" ) { output = ra::strings::Lowercase(getClassName()); return; } - //if ( name == "bin2cpp_namespace_lowercase" ) { output = ra::strings::Lowercase(mContext.codeNamespace); return; } - if ( name == "bin2cpp_function_identifier" ) { output = mContext.functionIdentifier; return; } - if ( name == "bin2cpp_function_identifier_lowercase" ) { output = ra::strings::Lowercase(mContext.functionIdentifier); return; } - if ( name == "bin2cpp_getter_function_name" ) { output = getGetterFunctionName(); return; } - if ( name == "bin2cpp_header_source_file_include_path" ) { output = getCppHeaderIncludePath(); return; } - if ( name == "bin2cpp_file_object_file_name_impl" ) { output = getFileClassGetFileNameImplementation(); return; } - if ( name == "bin2cpp_file_object_file_path_impl" ) { output = getFileClassGetFilePathImplementation(); return; } - if ( name == "bin2cpp_file_object_file_name" ) { output = getFileClassFileName(); return; } - if ( name == "bin2cpp_file_object_file_path" ) { output = getFileClassFilePath(); return; } - if ( name == "bin2cpp_cpp_get_save_method_impl" ) { output = getCppSaveMethodTemplate(); return; } - if ( name == "bin2cpp_cpp_get_file_manager_registration_impl" && mContext.registerFiles ) { output = getCppFileManagerRegistrationImplementationTemplate(); return; } - if ( name == "bin2cpp_c_file_manager_registration_predeclaration" && mContext.registerFiles ) { output = getCFileManagerRegistrationPredeclarationImplementation(); return; } - if ( name == "bin2cpp_c_file_manager_registration_implementation" && mContext.registerFiles ) { output = getCFileManagerStaticFileRegistrationImplementation(); return; } - + std::string BaseGenerator::lookupTemplateVariable(const std::string& name) + { + if ( name == "bin2cpp_output_file_macro_guard" ) return getCppIncludeGuardMacroName(mContext.headerFilename); + if ( name == "bin2cpp_output_file_header" ) return getHeaderTemplate(); + if ( name == "bin2cpp_file_object_macro_guard_prefix" ) return getClassMacroGuardPrefix(); + if ( name == "bin2cpp_file_manager_file_header" ) return getHeaderTemplate(false); + if ( name == "bin2cpp_file_manager_header_file_name" ) return mContext.managerHeaderFilename; + if ( name == "bin2cpp_file_manager_macro_guard_prefix" ) return getFileManagerMacroGuardPrefix(); + if ( name == "bin2cpp_baseclass" ) return mContext.baseClass; + if ( name == "bin2cpp_classname" ) return getClassName(); + if ( name == "bin2cpp_namespace" ) return mContext.codeNamespace; + //if ( name == "bin2cpp_baseclass_uppercase" ) return ra::strings::Uppercase(mContext.baseClass); + //if ( name == "bin2cpp_classname_uppercase" ) return ra::strings::Uppercase(getClassName()); + //if ( name == "bin2cpp_namespace_uppercase" ) return ra::strings::Lowercase(mContext.codeNamespace); + //if ( name == "bin2cpp_baseclass_lowercase" ) return ra::strings::Lowercase(mContext.baseClass); + //if ( name == "bin2cpp_classname_lowercase" ) return ra::strings::Lowercase(getClassName()); + //if ( name == "bin2cpp_namespace_lowercase" ) return ra::strings::Lowercase(mContext.codeNamespace); + if ( name == "bin2cpp_function_identifier" ) return mContext.functionIdentifier; + if ( name == "bin2cpp_function_identifier_lowercase" ) return ra::strings::Lowercase(mContext.functionIdentifier); + if ( name == "bin2cpp_getter_function_name" ) return getGetterFunctionName(); + if ( name == "bin2cpp_insert_input_file_as_code" ) return getInputFileDataAsCode(); + if ( name == "bin2cpp_header_source_file_include_path" ) return getCppHeaderIncludePath(); + if ( name == "bin2cpp_file_object_file_name_impl" ) return getFileClassGetFileNameImplementation(); + if ( name == "bin2cpp_file_object_file_path_impl" ) return getFileClassGetFilePathImplementation(); + if ( name == "bin2cpp_file_object_file_name" ) return getFileClassFileName(); + if ( name == "bin2cpp_file_object_file_path" ) return getFileClassFilePath(); + if ( name == "bin2cpp_cpp_get_save_method_impl" ) return getCppSaveMethodTemplate(); + if ( name == "bin2cpp_cpp_get_file_manager_registration_impl" && mContext.registerFiles ) return getCppFileManagerRegistrationImplementationTemplate(); + if ( name == "bin2cpp_c_file_manager_registration_predeclaration" && mContext.registerFiles ) return getCFileManagerRegistrationPredeclarationImplementation(); + if ( name == "bin2cpp_c_file_manager_registration_implementation" && mContext.registerFiles ) return getCFileManagerStaticFileRegistrationImplementation(); + if ( name == "bin2cpp_c_file_manager_registration_post_init_impl" && mContext.registerFiles ) { - std::string tmp; - tmp += " \n"; - tmp += " // register when loaded if static initialisation does not work\n"; - tmp += " ${bin2cpp_namespace}_filemanager_register_file(file);\n"; - output = tmp; - return; + std::string output; + output += " \n"; + output += " // register when loaded if static initialisation does not work\n"; + output += " ${bin2cpp_namespace}_filemanager_register_file(file);\n"; + return output; } if ( name == "bin2cpp_input_file_size" ) @@ -161,28 +101,20 @@ namespace bin2cpp //determine file properties uint32_t file_size = ra::filesystem::GetFileSize(mContext.inputFilePath.c_str()); std::string file_size_str = ra::strings::ToString(file_size); - output = file_size_str; - return; + return file_size_str; } + + // Unknown name + return ""; } //------------------------------- //protected methods //------------------------------- - void BaseGenerator::registerTemplateVariable(const char* name) - { - mTemplateVariableNames.insert(name); - } - - bool BaseGenerator::isRegistedTemplateVariable(const std::string& name) - { - bool found = std::find(mTemplateVariableNames.begin(), mTemplateVariableNames.end(), name) != mTemplateVariableNames.end(); - return found; - } - std::string BaseGenerator::getGetterFunctionName() { + std::string getter; switch ( mContext.code ) { @@ -568,7 +500,7 @@ namespace bin2cpp ; TemplateProcessor processor(&text); - processor.setTemplateVariableHandler(this); + processor.setTemplateVariableLookup(this); bool write_success = processor.writeFile(header_file_path); return write_success; @@ -660,7 +592,7 @@ namespace bin2cpp ; TemplateProcessor processor(&text); - processor.setTemplateVariableHandler(this); + processor.setTemplateVariableLookup(this); bool write_success = processor.writeFile(file_path); return write_success; diff --git a/src/bin2cpp/BaseGenerator.h b/src/bin2cpp/BaseGenerator.h index f246f3a..6f88f4f 100644 --- a/src/bin2cpp/BaseGenerator.h +++ b/src/bin2cpp/BaseGenerator.h @@ -26,7 +26,6 @@ #define BASEGENERATOR_H #include "IGenerator.h" -#include "types.h" #include namespace bin2cpp @@ -45,10 +44,8 @@ namespace bin2cpp virtual void setContext(const Context& c); virtual const Context & getContext() const; - //ITemplateVariableHandler methods - virtual TemplateVariableFlags getTemplateVariableFlags(const std::string& name); - virtual void writeTemplateVariable(const std::string& name, std::ostream& output); - virtual void writeTemplateVariable(const std::string& name, std::string& output); + //ITemplateVariableLookup methods + virtual std::string lookupTemplateVariable(const std::string& name); //same header file for all generators virtual bool createCppHeaderFile(const char * header_file_path); @@ -57,8 +54,7 @@ namespace bin2cpp virtual bool createCSourceFile(const char* file_path); protected: - virtual void registerTemplateVariable(const char* name); - virtual bool isRegistedTemplateVariable(const std::string& name); + virtual std::string getGetterFunctionName(); virtual std::string getHeaderFilePath(const char * cpp_file_path); virtual std::string getCppFilePath(const char * header_file_path); @@ -81,9 +77,6 @@ namespace bin2cpp //attributes Context mContext; - - private: - Dictionary mTemplateVariableNames; }; }; //bin2cpp diff --git a/src/bin2cpp/CMakeLists.txt b/src/bin2cpp/CMakeLists.txt index 3a84c3e..c21f1b5 100644 --- a/src/bin2cpp/CMakeLists.txt +++ b/src/bin2cpp/CMakeLists.txt @@ -22,7 +22,7 @@ add_executable(bin2cpp enums.h IGenerator.h INameProvider.h - ITemplateVariableHandler.h + ITemplateVariableLookup.h LegacyNameProvider.cpp LegacyNameProvider.h main.cpp diff --git a/src/bin2cpp/IGenerator.h b/src/bin2cpp/IGenerator.h index e51e9ac..da7ca54 100644 --- a/src/bin2cpp/IGenerator.h +++ b/src/bin2cpp/IGenerator.h @@ -27,12 +27,12 @@ #include #include "Context.h" -#include "ITemplateVariableHandler.h" +#include "ITemplateVariableLookup.h" namespace bin2cpp { - class IGenerator : public virtual ITemplateVariableHandler + class IGenerator : public virtual ITemplateVariableLookup { public: diff --git a/src/bin2cpp/ITemplateVariableHandler.h b/src/bin2cpp/ITemplateVariableLookup.h similarity index 55% rename from src/bin2cpp/ITemplateVariableHandler.h rename to src/bin2cpp/ITemplateVariableLookup.h index c42c3ab..760e9ba 100644 --- a/src/bin2cpp/ITemplateVariableHandler.h +++ b/src/bin2cpp/ITemplateVariableLookup.h @@ -22,45 +22,29 @@ * SOFTWARE. *********************************************************************************/ -#ifndef ITEMPLATE_VARIABLE_HANDLER_H -#define ITEMPLATE_VARIABLE_HANDLER_H +#ifndef ITEMPLATE_VARIABLE_LOOKUP_H +#define ITEMPLATE_VARIABLE_LOOKUP_H -#include "enums.h" #include -#include - + namespace bin2cpp { - class ITemplateVariableHandler + class ITemplateVariableLookup { public: - virtual ~ITemplateVariableHandler() + virtual ~ITemplateVariableLookup() {} /// - ///Get the associated flags for the given template variable name. - /// - ///The name of the template variable. - ///Returns the flags for template variable of the given name. - virtual TemplateVariableFlags getTemplateVariableFlags(const std::string& name) = 0; - - /// - ///Write the value of the given template variable name to the output stream. - /// - ///The name of the template variable. - ///The variable where to output the template variable's value. - virtual void writeTemplateVariable(const std::string& name, std::ostream& output) = 0; - - /// - ///Write the value of the given template variable name to the output string. + ///Look up the value for a given template variable name. /// ///The name of the template variable. - ///The variable where to output the template variable's value. - virtual void writeTemplateVariable(const std::string& name, std::string& output) = 0; + ///Returns the value of the template variable. Returns an empty string if unknown. + virtual std::string lookupTemplateVariable(const std::string& name) = 0; }; }; //bin2cpp -#endif //ITEMPLATE_VARIABLE_HANDLER_H +#endif //ITEMPLATE_VARIABLE_LOOKUP_H diff --git a/src/bin2cpp/ManagerGenerator.cpp b/src/bin2cpp/ManagerGenerator.cpp index eeba093..e5825ae 100644 --- a/src/bin2cpp/ManagerGenerator.cpp +++ b/src/bin2cpp/ManagerGenerator.cpp @@ -98,7 +98,7 @@ namespace bin2cpp ; TemplateProcessor processor(&text); - processor.setTemplateVariableHandler(this); + processor.setTemplateVariableLookup(this); bool write_success = processor.writeFile(file_path); return write_success; @@ -218,7 +218,7 @@ namespace bin2cpp ; TemplateProcessor processor(&text); - processor.setTemplateVariableHandler(this); + processor.setTemplateVariableLookup(this); bool write_success = processor.writeFile(file_path); return write_success; @@ -262,7 +262,7 @@ namespace bin2cpp ; TemplateProcessor processor(&text); - processor.setTemplateVariableHandler(this); + processor.setTemplateVariableLookup(this); bool write_success = processor.writeFile(file_path); return write_success; @@ -429,7 +429,7 @@ namespace bin2cpp ; TemplateProcessor processor(&text); - processor.setTemplateVariableHandler(this); + processor.setTemplateVariableLookup(this); bool write_success = processor.writeFile(file_path); return write_success; diff --git a/src/bin2cpp/SegmentGenerator.cpp b/src/bin2cpp/SegmentGenerator.cpp index 59a055a..e36ffaa 100755 --- a/src/bin2cpp/SegmentGenerator.cpp +++ b/src/bin2cpp/SegmentGenerator.cpp @@ -88,7 +88,7 @@ namespace bin2cpp "}; //${bin2cpp_namespace}\n"; TemplateProcessor processor(&text); - processor.setTemplateVariableHandler(this); + processor.setTemplateVariableLookup(this); bool write_success = processor.writeFile(file_path); return write_success; @@ -179,7 +179,7 @@ namespace bin2cpp "${bin2cpp_c_file_manager_registration_implementation}"; TemplateProcessor processor(&text); - processor.setTemplateVariableHandler(this); + processor.setTemplateVariableLookup(this); bool write_success = processor.writeFile(file_path); return write_success; diff --git a/src/bin2cpp/StringGenerator.cpp b/src/bin2cpp/StringGenerator.cpp index 0372ed4..1a2bd5c 100755 --- a/src/bin2cpp/StringGenerator.cpp +++ b/src/bin2cpp/StringGenerator.cpp @@ -81,7 +81,7 @@ namespace bin2cpp "}; //${bin2cpp_namespace}\n"; TemplateProcessor processor(&text); - processor.setTemplateVariableHandler(this); + processor.setTemplateVariableLookup(this); bool write_success = processor.writeFile(file_path); return write_success; @@ -166,7 +166,7 @@ namespace bin2cpp "${bin2cpp_c_file_manager_registration_implementation}"; TemplateProcessor processor(&text); - processor.setTemplateVariableHandler(this); + processor.setTemplateVariableLookup(this); bool write_success = processor.writeFile(file_path); return write_success; diff --git a/src/bin2cpp/TemplateProcessor.cpp b/src/bin2cpp/TemplateProcessor.cpp index 2654158..96d9dee 100644 --- a/src/bin2cpp/TemplateProcessor.cpp +++ b/src/bin2cpp/TemplateProcessor.cpp @@ -46,7 +46,7 @@ namespace bin2cpp void TemplateProcessor::reset() { mTemplateText = NULL; - mVariableHandler = NULL; + mVariableLookup = NULL; } void TemplateProcessor::setTemplateText(const std::string* value) @@ -59,14 +59,14 @@ namespace bin2cpp return mTemplateText; } - void TemplateProcessor::setTemplateVariableHandler(ITemplateVariableHandler* handler) + void TemplateProcessor::setTemplateVariableLookup(ITemplateVariableLookup* lookup) { - mVariableHandler = handler; + mVariableLookup = lookup; } - ITemplateVariableHandler* TemplateProcessor::getTemplateVariableHandler() const + ITemplateVariableLookup* TemplateProcessor::getTemplateVariableLookup() const { - return mVariableHandler; + return mVariableLookup; } void TemplateProcessor::writeStream(std::ostream& output_stream) @@ -116,31 +116,17 @@ namespace bin2cpp continue; } - // Get variable flags - TemplateVariableFlags flags = TEMPLATE_VARIABLE_FLAG_NONE; - if ( mVariableHandler ) - flags = mVariableHandler->getTemplateVariableFlags(variable_name); + // Do the variable expansion + std::string expanded_value = mVariableLookup ? mVariableLookup->lookupTemplateVariable(variable_name) : ""; - // For string variables, do the variable expansion and recursion - if ( (flags & TEMPLATE_VARIABLE_FLAG_STRINGNABLE) == TEMPLATE_VARIABLE_FLAG_STRINGNABLE ) - { - std::string expanded_value; - mVariableHandler->writeTemplateVariable(variable_name, expanded_value); - - // Add variable to recursion history before expanding - recursion_history.insert(variable_name); + // Add variable to recursion history before expanding + recursion_history.insert(variable_name); - // Recursively process expanded value with updated recursion tracking - processTemplate(output_stream, expanded_value, recursion_history); + // Recursively process expanded value with updated recursion tracking + processTemplate(output_stream, expanded_value, recursion_history); - // Remove variable from recursion history after recursion returns - recursion_history.erase(variable_name); - } - else if ( (flags & TEMPLATE_VARIABLE_FLAG_STREAMABLE) == TEMPLATE_VARIABLE_FLAG_STREAMABLE ) - { - // For streamable-only variables, just stream the output to our output - mVariableHandler->writeTemplateVariable(variable_name, output_stream); - } + // Remove variable from recursion history after recursion returns + recursion_history.erase(variable_name); pos = end_pos + 1; } diff --git a/src/bin2cpp/TemplateProcessor.h b/src/bin2cpp/TemplateProcessor.h index 756446e..32e1d5d 100644 --- a/src/bin2cpp/TemplateProcessor.h +++ b/src/bin2cpp/TemplateProcessor.h @@ -27,7 +27,7 @@ #include #include -#include "ITemplateVariableHandler.h" +#include "ITemplateVariableLookup.h" namespace bin2cpp { @@ -47,8 +47,8 @@ namespace bin2cpp void setTemplateText(const std::string* value); const std::string* getTemplateText() const; - void setTemplateVariableHandler(ITemplateVariableHandler* handler); - ITemplateVariableHandler* getTemplateVariableHandler() const; + void setTemplateVariableLookup(ITemplateVariableLookup* lookup); + ITemplateVariableLookup* getTemplateVariableLookup() const; virtual void writeStream(std::ostream& output_stream); virtual void writeString(std::string& output); @@ -59,7 +59,7 @@ namespace bin2cpp //attributes const std::string* mTemplateText; - ITemplateVariableHandler* mVariableHandler; + ITemplateVariableLookup* mVariableLookup; }; }; //bin2cpp diff --git a/src/bin2cpp/Win32ResourceGenerator.cpp b/src/bin2cpp/Win32ResourceGenerator.cpp index 3e67ce9..42045e8 100755 --- a/src/bin2cpp/Win32ResourceGenerator.cpp +++ b/src/bin2cpp/Win32ResourceGenerator.cpp @@ -41,8 +41,6 @@ namespace bin2cpp { Win32ResourceGenerator::Win32ResourceGenerator() { - registerTemplateVariable("bin2cpp_win32_resource_random_identifier"); - registerTemplateVariable("bin2cpp_win32_local_info_struct_name"); } Win32ResourceGenerator::~Win32ResourceGenerator() @@ -158,7 +156,7 @@ namespace bin2cpp "}; //${bin2cpp_namespace}\n"; TemplateProcessor processor(&text); - processor.setTemplateVariableHandler(this); + processor.setTemplateVariableLookup(this); bool write_success = processor.writeFile(file_path); return write_success; @@ -303,7 +301,7 @@ namespace bin2cpp "${bin2cpp_c_file_manager_registration_implementation}"; TemplateProcessor processor(&text); - processor.setTemplateVariableHandler(this); + processor.setTemplateVariableLookup(this); bool write_success = processor.writeFile(file_path); return write_success; @@ -378,28 +376,13 @@ namespace bin2cpp return false; // not supported } - TemplateVariableFlags Win32ResourceGenerator::getTemplateVariableFlags(const std::string& name) + std::string Win32ResourceGenerator::lookupTemplateVariable(const std::string& name) { - if ( name == "bin2cpp_win32_resource_random_identifier" ) return TEMPLATE_VARIABLE_FLAG_STRINGNABLE; - if ( name == "bin2cpp_win32_local_info_struct_name" ) return TEMPLATE_VARIABLE_FLAG_STRINGNABLE; - return BaseGenerator::getTemplateVariableFlags(name); - } - - void Win32ResourceGenerator::writeTemplateVariable(const std::string& name, std::string& output) - { - if ( name == "bin2cpp_win32_resource_random_identifier" ) - { - output = getRandomIdentifier(mContext.inputFilePath.c_str()); - return; - } - if ( name == "bin2cpp_win32_local_info_struct_name" ) - { - output = getLocalInfoStructName(); - return; - } + if ( name == "bin2cpp_win32_resource_random_identifier" ) return getRandomIdentifier(mContext.inputFilePath.c_str()); + if ( name == "bin2cpp_win32_local_info_struct_name" ) return getLocalInfoStructName(); // Unknown name - return this->BaseGenerator::writeTemplateVariable(name, output); + return this->BaseGenerator::lookupTemplateVariable(name); } std::string Win32ResourceGenerator::getLocalInfoStructName() diff --git a/src/bin2cpp/Win32ResourceGenerator.h b/src/bin2cpp/Win32ResourceGenerator.h index 80a8d9e..c157d6a 100644 --- a/src/bin2cpp/Win32ResourceGenerator.h +++ b/src/bin2cpp/Win32ResourceGenerator.h @@ -43,9 +43,8 @@ namespace bin2cpp virtual bool createCSourceFile(const char* file_path); virtual bool printFileContent(); - //ITemplateVariableHandler methods - virtual TemplateVariableFlags getTemplateVariableFlags(const std::string& name); - virtual void writeTemplateVariable(const std::string& name, std::string& output); + //ITemplateVariableLookup methods + virtual std::string lookupTemplateVariable(const std::string& name); protected: virtual std::string getResourceFilePath(const char * file_path); diff --git a/src/bin2cpp/enums.h b/src/bin2cpp/enums.h index 1b36a47..82a7539 100644 --- a/src/bin2cpp/enums.h +++ b/src/bin2cpp/enums.h @@ -46,13 +46,6 @@ namespace bin2cpp CODE_GENERATION_CPP, CODE_GENERATION_C, }; - - enum TemplateVariableFlags - { - TEMPLATE_VARIABLE_FLAG_NONE = 0, - TEMPLATE_VARIABLE_FLAG_STRINGNABLE = 1, - TEMPLATE_VARIABLE_FLAG_STREAMABLE = 2, - }; }; //bin2cpp diff --git a/src/bin2cpp/types.h b/src/bin2cpp/types.h index 72cff29..5f3bc09 100644 --- a/src/bin2cpp/types.h +++ b/src/bin2cpp/types.h @@ -26,7 +26,6 @@ #define TYPES_H #include -#include #include namespace bin2cpp @@ -37,11 +36,6 @@ namespace bin2cpp /// typedef std::set Dictionary; - /// - ///A vector of strings - /// - typedef std::vector StringVector; - }; //bin2cpp #endif //TYPES_H diff --git a/test/bin2cpp_unittest/CMakeLists.txt b/test/bin2cpp_unittest/CMakeLists.txt index c8c064d..c682746 100644 --- a/test/bin2cpp_unittest/CMakeLists.txt +++ b/test/bin2cpp_unittest/CMakeLists.txt @@ -285,7 +285,7 @@ source_group("External Files" FILES ${CMAKE_SOURCE_DIR}/src/bin2cpp/common.h ${CMAKE_SOURCE_DIR}/src/bin2cpp/wildcard.cpp ${CMAKE_SOURCE_DIR}/src/bin2cpp/wildcard.h - ${CMAKE_SOURCE_DIR}/src/bin2cpp/ITemplateVariableHandler.h + ${CMAKE_SOURCE_DIR}/src/bin2cpp/ITemplateVariableLookup.h ${CMAKE_SOURCE_DIR}/src/bin2cpp/TemplateProcessor.cpp ${CMAKE_SOURCE_DIR}/src/bin2cpp/TemplateProcessor.h ) @@ -300,7 +300,7 @@ add_executable(bin2cpp_unittest ${CMAKE_SOURCE_DIR}/src/bin2cpp/common.h ${CMAKE_SOURCE_DIR}/src/bin2cpp/wildcard.cpp ${CMAKE_SOURCE_DIR}/src/bin2cpp/wildcard.h - ${CMAKE_SOURCE_DIR}/src/bin2cpp/ITemplateVariableHandler.h + ${CMAKE_SOURCE_DIR}/src/bin2cpp/ITemplateVariableLookup.h ${CMAKE_SOURCE_DIR}/src/bin2cpp/TemplateProcessor.cpp ${CMAKE_SOURCE_DIR}/src/bin2cpp/TemplateProcessor.h application.cpp diff --git a/test/bin2cpp_unittest/TestTemplateProcessor.cpp b/test/bin2cpp_unittest/TestTemplateProcessor.cpp index 6a60895..d7368de 100644 --- a/test/bin2cpp_unittest/TestTemplateProcessor.cpp +++ b/test/bin2cpp_unittest/TestTemplateProcessor.cpp @@ -32,27 +32,10 @@ #include "rapidassist/user.h" // Sample variable lookup implementation -class SampleVariableLookup : public bin2cpp::ITemplateVariableHandler +class SampleVariableLookup : public bin2cpp::ITemplateVariableLookup { public: - bin2cpp::TemplateVariableFlags getTemplateVariableFlags(const std::string& name) - { - if ( name == "first-name" ) return bin2cpp::TEMPLATE_VARIABLE_FLAG_STRINGNABLE; - if ( name == "last-name" ) return bin2cpp::TEMPLATE_VARIABLE_FLAG_STRINGNABLE; - if ( name == "full-name" ) return bin2cpp::TEMPLATE_VARIABLE_FLAG_STRINGNABLE; - if ( name == "age" ) return bin2cpp::TEMPLATE_VARIABLE_FLAG_STRINGNABLE; - if ( name == "job" ) return bin2cpp::TEMPLATE_VARIABLE_FLAG_STRINGNABLE; - if ( name == "children" ) return bin2cpp::TEMPLATE_VARIABLE_FLAG_STRINGNABLE; - if ( name == "foo" ) return bin2cpp::TEMPLATE_VARIABLE_FLAG_STRINGNABLE; - if ( name == "bar" ) return bin2cpp::TEMPLATE_VARIABLE_FLAG_STRINGNABLE; - if ( name == "baz" ) return bin2cpp::TEMPLATE_VARIABLE_FLAG_STRINGNABLE; - return bin2cpp::TEMPLATE_VARIABLE_FLAG_NONE; - } - - void writeTemplateVariable(const std::string& name, std::ostream& output) - {} - - inline std::string getTemplateVariableAsString(const std::string& name) + std::string lookupTemplateVariable(const std::string& name) override { if ( name == "first-name" ) return "Luke"; if ( name == "last-name" ) return "Skywalker"; @@ -65,11 +48,6 @@ class SampleVariableLookup : public bin2cpp::ITemplateVariableHandler if ( name == "baz" ) return "baz is ${foo}"; return ""; } - - void writeTemplateVariable(const std::string& name, std::string& output) override - { - output = getTemplateVariableAsString(name); - } }; void TestTemplateProcessor::SetUp() @@ -84,7 +62,7 @@ TEST_F(TestTemplateProcessor, testBaseSingleVariable) { bin2cpp::TemplateProcessor processor; SampleVariableLookup lookup; - processor.setTemplateVariableHandler(&lookup); + processor.setTemplateVariableLookup(&lookup); const std::string actual_input = "I am ${age} years old."; const std::string expected_output = "I am 53 years old."; @@ -98,7 +76,7 @@ TEST_F(TestTemplateProcessor, testUnknownVariable) { bin2cpp::TemplateProcessor processor; SampleVariableLookup lookup; - processor.setTemplateVariableHandler(&lookup); + processor.setTemplateVariableLookup(&lookup); const std::string actual_input = "My ${father} tried to kill me."; const std::string expected_output = "My tried to kill me."; @@ -112,7 +90,7 @@ TEST_F(TestTemplateProcessor, testCaseSensitive) { bin2cpp::TemplateProcessor processor; SampleVariableLookup lookup; - processor.setTemplateVariableHandler(&lookup); + processor.setTemplateVariableLookup(&lookup); const std::string actual_input = "The variable '${children}' should expand to a value but '${Children}' should be empty."; const std::string expected_output = "The variable '2' should expand to a value but '' should be empty."; @@ -126,7 +104,7 @@ TEST_F(TestTemplateProcessor, testRecursive) { bin2cpp::TemplateProcessor processor; SampleVariableLookup lookup; - processor.setTemplateVariableHandler(&lookup); + processor.setTemplateVariableLookup(&lookup); const std::string actual_input = "My name is ${full-name}. I work as a ${job} now."; const std::string expected_output = "My name is Luke Skywalker. I work as a Jedi Knight now."; @@ -140,7 +118,7 @@ TEST_F(TestTemplateProcessor, testMultipleTwinMarkers) { bin2cpp::TemplateProcessor processor; SampleVariableLookup lookup; - processor.setTemplateVariableHandler(&lookup); + processor.setTemplateVariableLookup(&lookup); const std::string actual_input = "My name is ${first-name} but everyone calls me Lucky-${first-name}."; const std::string expected_output = "My name is Luke but everyone calls me Lucky-Luke."; @@ -154,7 +132,7 @@ TEST_F(TestTemplateProcessor, testCircularReference) { bin2cpp::TemplateProcessor processor; SampleVariableLookup lookup; - processor.setTemplateVariableHandler(&lookup); + processor.setTemplateVariableLookup(&lookup); const std::string actual_input = "${foo}"; const std::string expected_output = "foo is bar is baz is "; From d06584800015399483e49768c9041155af20de4b Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sun, 1 Jun 2025 11:31:11 -0400 Subject: [PATCH 21/26] Modified ITemplateVariableLookup interface to support "string template variables" and "stream template variables". Stream template variables do not support template variables recursive lookup. This means that a stream that contains entries such as `${foo}` will not be processed and will be output as a literal string `${foo}`. --- src/bin2cpp/BaseGenerator.cpp | 84 +++++++++++-------- src/bin2cpp/BaseGenerator.h | 3 +- src/bin2cpp/ITemplateVariableLookup.h | 21 ++++- src/bin2cpp/TemplateProcessor.cpp | 35 ++++++-- src/bin2cpp/Win32ResourceGenerator.cpp | 8 +- src/bin2cpp/Win32ResourceGenerator.h | 2 +- .../TestTemplateProcessor.cpp | 28 ++++--- 7 files changed, 116 insertions(+), 65 deletions(-) diff --git a/src/bin2cpp/BaseGenerator.cpp b/src/bin2cpp/BaseGenerator.cpp index 26cdac4..f9ce140 100755 --- a/src/bin2cpp/BaseGenerator.cpp +++ b/src/bin2cpp/BaseGenerator.cpp @@ -56,44 +56,44 @@ namespace bin2cpp return mContext; } - std::string BaseGenerator::lookupTemplateVariable(const std::string& name) + bool BaseGenerator::lookupStringTemplateVariable(const std::string& name, std::string& output) { - if ( name == "bin2cpp_output_file_macro_guard" ) return getCppIncludeGuardMacroName(mContext.headerFilename); - if ( name == "bin2cpp_output_file_header" ) return getHeaderTemplate(); - if ( name == "bin2cpp_file_object_macro_guard_prefix" ) return getClassMacroGuardPrefix(); - if ( name == "bin2cpp_file_manager_file_header" ) return getHeaderTemplate(false); - if ( name == "bin2cpp_file_manager_header_file_name" ) return mContext.managerHeaderFilename; - if ( name == "bin2cpp_file_manager_macro_guard_prefix" ) return getFileManagerMacroGuardPrefix(); - if ( name == "bin2cpp_baseclass" ) return mContext.baseClass; - if ( name == "bin2cpp_classname" ) return getClassName(); - if ( name == "bin2cpp_namespace" ) return mContext.codeNamespace; - //if ( name == "bin2cpp_baseclass_uppercase" ) return ra::strings::Uppercase(mContext.baseClass); - //if ( name == "bin2cpp_classname_uppercase" ) return ra::strings::Uppercase(getClassName()); - //if ( name == "bin2cpp_namespace_uppercase" ) return ra::strings::Lowercase(mContext.codeNamespace); - //if ( name == "bin2cpp_baseclass_lowercase" ) return ra::strings::Lowercase(mContext.baseClass); - //if ( name == "bin2cpp_classname_lowercase" ) return ra::strings::Lowercase(getClassName()); - //if ( name == "bin2cpp_namespace_lowercase" ) return ra::strings::Lowercase(mContext.codeNamespace); - if ( name == "bin2cpp_function_identifier" ) return mContext.functionIdentifier; - if ( name == "bin2cpp_function_identifier_lowercase" ) return ra::strings::Lowercase(mContext.functionIdentifier); - if ( name == "bin2cpp_getter_function_name" ) return getGetterFunctionName(); - if ( name == "bin2cpp_insert_input_file_as_code" ) return getInputFileDataAsCode(); - if ( name == "bin2cpp_header_source_file_include_path" ) return getCppHeaderIncludePath(); - if ( name == "bin2cpp_file_object_file_name_impl" ) return getFileClassGetFileNameImplementation(); - if ( name == "bin2cpp_file_object_file_path_impl" ) return getFileClassGetFilePathImplementation(); - if ( name == "bin2cpp_file_object_file_name" ) return getFileClassFileName(); - if ( name == "bin2cpp_file_object_file_path" ) return getFileClassFilePath(); - if ( name == "bin2cpp_cpp_get_save_method_impl" ) return getCppSaveMethodTemplate(); - if ( name == "bin2cpp_cpp_get_file_manager_registration_impl" && mContext.registerFiles ) return getCppFileManagerRegistrationImplementationTemplate(); - if ( name == "bin2cpp_c_file_manager_registration_predeclaration" && mContext.registerFiles ) return getCFileManagerRegistrationPredeclarationImplementation(); - if ( name == "bin2cpp_c_file_manager_registration_implementation" && mContext.registerFiles ) return getCFileManagerStaticFileRegistrationImplementation(); + if ( name == "bin2cpp_output_file_macro_guard" ) { output = getCppIncludeGuardMacroName(mContext.headerFilename); return true; } + if ( name == "bin2cpp_output_file_header" ) { output = getHeaderTemplate(); return true; } + if ( name == "bin2cpp_file_object_macro_guard_prefix" ) { output = getClassMacroGuardPrefix(); return true; } + if ( name == "bin2cpp_file_manager_file_header" ) { output = getHeaderTemplate(false); return true; } + if ( name == "bin2cpp_file_manager_header_file_name" ) { output = mContext.managerHeaderFilename; return true; } + if ( name == "bin2cpp_file_manager_macro_guard_prefix" ) { output = getFileManagerMacroGuardPrefix(); return true; } + if ( name == "bin2cpp_baseclass" ) { output = mContext.baseClass; return true; } + if ( name == "bin2cpp_classname" ) { output = getClassName(); return true; } + if ( name == "bin2cpp_namespace" ) { output = mContext.codeNamespace; return true; } + //if ( name == "bin2cpp_baseclass_uppercase" ) { output = ra::strings::Uppercase(mContext.baseClass); return true; } + //if ( name == "bin2cpp_classname_uppercase" ) { output = ra::strings::Uppercase(getClassName()); return true; } + //if ( name == "bin2cpp_namespace_uppercase" ) { output = ra::strings::Lowercase(mContext.codeNamespace); return true; } + //if ( name == "bin2cpp_baseclass_lowercase" ) { output = ra::strings::Lowercase(mContext.baseClass); return true; } + //if ( name == "bin2cpp_classname_lowercase" ) { output = ra::strings::Lowercase(getClassName()); return true; } + //if ( name == "bin2cpp_namespace_lowercase" ) { output = ra::strings::Lowercase(mContext.codeNamespace); return true; } + if ( name == "bin2cpp_function_identifier" ) { output = mContext.functionIdentifier; return true; } + if ( name == "bin2cpp_function_identifier_lowercase" ) { output = ra::strings::Lowercase(mContext.functionIdentifier); return true; } + if ( name == "bin2cpp_getter_function_name" ) { output = getGetterFunctionName(); return true; } + if ( name == "bin2cpp_header_source_file_include_path" ) { output = getCppHeaderIncludePath(); return true; } + if ( name == "bin2cpp_file_object_file_name_impl" ) { output = getFileClassGetFileNameImplementation(); return true; } + if ( name == "bin2cpp_file_object_file_path_impl" ) { output = getFileClassGetFilePathImplementation(); return true; } + if ( name == "bin2cpp_file_object_file_name" ) { output = getFileClassFileName(); return true; } + if ( name == "bin2cpp_file_object_file_path" ) { output = getFileClassFilePath(); return true; } + if ( name == "bin2cpp_cpp_get_save_method_impl" ) { output = getCppSaveMethodTemplate(); return true; } + if ( name == "bin2cpp_cpp_get_file_manager_registration_impl" && mContext.registerFiles ) { output = getCppFileManagerRegistrationImplementationTemplate(); return true; } + if ( name == "bin2cpp_c_file_manager_registration_predeclaration" && mContext.registerFiles ) { output = getCFileManagerRegistrationPredeclarationImplementation(); return true; } + if ( name == "bin2cpp_c_file_manager_registration_implementation" && mContext.registerFiles ) { output = getCFileManagerStaticFileRegistrationImplementation(); return true; } if ( name == "bin2cpp_c_file_manager_registration_post_init_impl" && mContext.registerFiles ) { - std::string output; - output += " \n"; - output += " // register when loaded if static initialisation does not work\n"; - output += " ${bin2cpp_namespace}_filemanager_register_file(file);\n"; - return output; + std::string tmp; + tmp += " \n"; + tmp += " // register when loaded if static initialisation does not work\n"; + tmp += " ${bin2cpp_namespace}_filemanager_register_file(file);\n"; + output = tmp; + return true; } if ( name == "bin2cpp_input_file_size" ) @@ -101,11 +101,23 @@ namespace bin2cpp //determine file properties uint32_t file_size = ra::filesystem::GetFileSize(mContext.inputFilePath.c_str()); std::string file_size_str = ra::strings::ToString(file_size); - return file_size_str; + output = file_size_str; + return true; } // Unknown name - return ""; + return false; + } + + bool BaseGenerator::lookupStreamTemplateVariable(const std::string& name, std::ostream& output) + { + if ( name == "bin2cpp_insert_input_file_as_code" ) + { + output << getInputFileDataAsCode(); + return true; + } + + return false; } //------------------------------- diff --git a/src/bin2cpp/BaseGenerator.h b/src/bin2cpp/BaseGenerator.h index 6f88f4f..3f43b2f 100644 --- a/src/bin2cpp/BaseGenerator.h +++ b/src/bin2cpp/BaseGenerator.h @@ -45,7 +45,8 @@ namespace bin2cpp virtual const Context & getContext() const; //ITemplateVariableLookup methods - virtual std::string lookupTemplateVariable(const std::string& name); + virtual bool lookupStringTemplateVariable(const std::string& name, std::string& output); + virtual bool lookupStreamTemplateVariable(const std::string& name, std::ostream& output); //same header file for all generators virtual bool createCppHeaderFile(const char * header_file_path); diff --git a/src/bin2cpp/ITemplateVariableLookup.h b/src/bin2cpp/ITemplateVariableLookup.h index 760e9ba..f54d9cf 100644 --- a/src/bin2cpp/ITemplateVariableLookup.h +++ b/src/bin2cpp/ITemplateVariableLookup.h @@ -26,7 +26,8 @@ #define ITEMPLATE_VARIABLE_LOOKUP_H #include - +#include + namespace bin2cpp { @@ -37,11 +38,23 @@ namespace bin2cpp {} /// - ///Look up the value for a given template variable name. + ///Lookup the string value for a given template variable name. + ///String template variables supports recursive lookup. + /// + ///The name of the template variable. + ///The output string for getting the value or the template variable. + ///Returns true when the template variable is handled by the instance. Returns false otherwise. + virtual bool lookupStringTemplateVariable(const std::string& name, std::string& output) = 0; + + /// + ///Lookup the string value for a given template variable name. + ///Stream template variables do not support template variables recursive lookup. + ///If a streams loopup outputs text such as `${foo}`, it will not be processed and will be output as literal string `${foo}`. /// ///The name of the template variable. - ///Returns the value of the template variable. Returns an empty string if unknown. - virtual std::string lookupTemplateVariable(const std::string& name) = 0; + ///The output string for getting the value or the template variable. + ///Returns true when the template variable is handled by the instance. Returns false otherwise. + virtual bool lookupStreamTemplateVariable(const std::string& name, std::ostream& output) = 0; }; diff --git a/src/bin2cpp/TemplateProcessor.cpp b/src/bin2cpp/TemplateProcessor.cpp index 96d9dee..c66b9dc 100644 --- a/src/bin2cpp/TemplateProcessor.cpp +++ b/src/bin2cpp/TemplateProcessor.cpp @@ -116,17 +116,36 @@ namespace bin2cpp continue; } - // Do the variable expansion - std::string expanded_value = mVariableLookup ? mVariableLookup->lookupTemplateVariable(variable_name) : ""; + // Do not crash if no lookup is provided. + // All template variables will be empty. + if ( !mVariableLookup ) + { + pos = end_pos + 1; + continue; + } - // Add variable to recursion history before expanding - recursion_history.insert(variable_name); + // Check if template variable is a string and do the variable expansion + std::string expanded_value; + bool found_as_string = mVariableLookup->lookupStringTemplateVariable(variable_name, expanded_value); - // Recursively process expanded value with updated recursion tracking - processTemplate(output_stream, expanded_value, recursion_history); + // Proceed with the recursive handling + if ( found_as_string ) + { + // Add variable to recursion history before expanding + recursion_history.insert(variable_name); - // Remove variable from recursion history after recursion returns - recursion_history.erase(variable_name); + // Recursively process expanded value with updated recursion tracking + processTemplate(output_stream, expanded_value, recursion_history); + + // Remove variable from recursion history after recursion returns + recursion_history.erase(variable_name); + } + else + { + // Check if template variable is a stream + // Stream based template variables do not support recursive lookup and tracking + bool found_as_stream = mVariableLookup->lookupStreamTemplateVariable(variable_name, output_stream); + } pos = end_pos + 1; } diff --git a/src/bin2cpp/Win32ResourceGenerator.cpp b/src/bin2cpp/Win32ResourceGenerator.cpp index 42045e8..02dbef7 100755 --- a/src/bin2cpp/Win32ResourceGenerator.cpp +++ b/src/bin2cpp/Win32ResourceGenerator.cpp @@ -376,13 +376,13 @@ namespace bin2cpp return false; // not supported } - std::string Win32ResourceGenerator::lookupTemplateVariable(const std::string& name) + bool Win32ResourceGenerator::lookupStringTemplateVariable(const std::string& name, std::string& output) { - if ( name == "bin2cpp_win32_resource_random_identifier" ) return getRandomIdentifier(mContext.inputFilePath.c_str()); - if ( name == "bin2cpp_win32_local_info_struct_name" ) return getLocalInfoStructName(); + if ( name == "bin2cpp_win32_resource_random_identifier" ) { output = getRandomIdentifier(mContext.inputFilePath.c_str()); return true; } + if ( name == "bin2cpp_win32_local_info_struct_name" ) { output = getLocalInfoStructName(); return true; } // Unknown name - return this->BaseGenerator::lookupTemplateVariable(name); + return this->BaseGenerator::lookupStringTemplateVariable(name, output); } std::string Win32ResourceGenerator::getLocalInfoStructName() diff --git a/src/bin2cpp/Win32ResourceGenerator.h b/src/bin2cpp/Win32ResourceGenerator.h index c157d6a..b522da8 100644 --- a/src/bin2cpp/Win32ResourceGenerator.h +++ b/src/bin2cpp/Win32ResourceGenerator.h @@ -44,7 +44,7 @@ namespace bin2cpp virtual bool printFileContent(); //ITemplateVariableLookup methods - virtual std::string lookupTemplateVariable(const std::string& name); + virtual bool lookupStringTemplateVariable(const std::string& name, std::string& output); protected: virtual std::string getResourceFilePath(const char * file_path); diff --git a/test/bin2cpp_unittest/TestTemplateProcessor.cpp b/test/bin2cpp_unittest/TestTemplateProcessor.cpp index d7368de..e128074 100644 --- a/test/bin2cpp_unittest/TestTemplateProcessor.cpp +++ b/test/bin2cpp_unittest/TestTemplateProcessor.cpp @@ -35,19 +35,25 @@ class SampleVariableLookup : public bin2cpp::ITemplateVariableLookup { public: - std::string lookupTemplateVariable(const std::string& name) override + bool lookupStringTemplateVariable(const std::string& name, std::string& output) override { - if ( name == "first-name" ) return "Luke"; - if ( name == "last-name" ) return "Skywalker"; - if ( name == "full-name" ) return "${first-name} ${last-name}"; - if ( name == "age" ) return "53"; - if ( name == "job" ) return "Jedi Knight"; - if ( name == "children" ) return "2"; - if ( name == "foo" ) return "foo is ${bar}"; - if ( name == "bar" ) return "bar is ${baz}"; - if ( name == "baz" ) return "baz is ${foo}"; - return ""; + if ( name == "first-name" ) { output = "Luke"; return true; } + if ( name == "last-name" ) { output = "Skywalker"; return true; } + if ( name == "full-name" ) { output = "${first-name} ${last-name}"; return true; } + if ( name == "age" ) { output = "53"; return true; } + if ( name == "job" ) { output = "Jedi Knight"; return true; } + if ( name == "children" ) { output = "2"; return true; } + if ( name == "foo" ) { output = "foo is ${bar}"; return true; } + if ( name == "bar" ) { output = "bar is ${baz}"; return true; } + if ( name == "baz" ) { output = "baz is ${foo}"; return true; } + return false; } + + bool lookupStreamTemplateVariable(const std::string& name, std::ostream& output) override + { + return false; + } + }; void TestTemplateProcessor::SetUp() From 0ef1a829b25d50520adc66ed9123ad61a9d0e1a0 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sun, 1 Jun 2025 11:45:51 -0400 Subject: [PATCH 22/26] Modified `getInputFileDataAsCode()` and `getInputFileChunkAsCode()` to output data to a stream instead of returning a string --- src/bin2cpp/ArrayGenerator.cpp | 27 ++++++++++++++----------- src/bin2cpp/ArrayGenerator.h | 2 +- src/bin2cpp/BaseGenerator.cpp | 23 ++++++--------------- src/bin2cpp/BaseGenerator.h | 4 ++-- src/bin2cpp/SegmentGenerator.cpp | 34 ++++++++++++++++---------------- src/bin2cpp/SegmentGenerator.h | 2 +- src/bin2cpp/StringGenerator.cpp | 20 +++++++++---------- src/bin2cpp/StringGenerator.h | 2 +- 8 files changed, 54 insertions(+), 60 deletions(-) diff --git a/src/bin2cpp/ArrayGenerator.cpp b/src/bin2cpp/ArrayGenerator.cpp index 3dc15b2..76cd6ba 100644 --- a/src/bin2cpp/ArrayGenerator.cpp +++ b/src/bin2cpp/ArrayGenerator.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include "rapidassist/code_cpp.h" #include "rapidassist/strings.h" @@ -94,8 +95,11 @@ namespace bin2cpp if (!ra::filesystem::FileExists(mContext.inputFilePath.c_str()) ) return false; - std::string output = getInputFileDataAsCode(); - printf("\"%s\"", output.c_str()); + std::ostringstream output_stream; + writeInputFileDataAsCode(output_stream); + std::string str = output_stream.str(); + + printf("\"%s\"", str.c_str()); return true; } @@ -185,7 +189,7 @@ namespace bin2cpp return write_success; } - std::string ArrayGenerator::getInputFileChunkAsCode(const unsigned char * buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk) + void ArrayGenerator::writeInputFileChunkAsCode(const unsigned char * buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk, std::ostream& output) { size_t indentation = 0; @@ -196,18 +200,19 @@ namespace bin2cpp else if ( mContext.code == CodeGenerationEnum::CODE_GENERATION_C ) indentation = 4; - std::string output; + std::string str; if ( indentation ) - output += std::string(indentation, ' '); + str += std::string(indentation, ' '); if ( mContext.plainOutput ) - output += "\""; - output += ra::code::cpp::ToCppCharactersArray(buffer, buffer_size); + str += "\""; + str += ra::code::cpp::ToCppCharactersArray(buffer, buffer_size); if ( mContext.plainOutput ) - output += "\""; + str += "\""; if ( !is_last_chunk ) - output += ","; - output += "\n"; - return output; + str += ","; + str += "\n"; + + output << str; } }; //bin2cpp \ No newline at end of file diff --git a/src/bin2cpp/ArrayGenerator.h b/src/bin2cpp/ArrayGenerator.h index 2d7cb91..7093a9d 100644 --- a/src/bin2cpp/ArrayGenerator.h +++ b/src/bin2cpp/ArrayGenerator.h @@ -43,7 +43,7 @@ namespace bin2cpp virtual bool createCppSourceFile(const char * file_path); virtual bool createCSourceFile(const char * file_path); virtual bool printFileContent(); - virtual std::string getInputFileChunkAsCode(const unsigned char * buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk); + virtual void writeInputFileChunkAsCode(const unsigned char * buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk, std::ostream& output); }; }; //bin2cpp diff --git a/src/bin2cpp/BaseGenerator.cpp b/src/bin2cpp/BaseGenerator.cpp index f9ce140..57ce035 100755 --- a/src/bin2cpp/BaseGenerator.cpp +++ b/src/bin2cpp/BaseGenerator.cpp @@ -113,7 +113,7 @@ namespace bin2cpp { if ( name == "bin2cpp_insert_input_file_as_code" ) { - output << getInputFileDataAsCode(); + writeInputFileDataAsCode(output); return true; } @@ -427,25 +427,18 @@ namespace bin2cpp return mContext.headerFilename; } - std::string BaseGenerator::getInputFileDataAsCode() + void BaseGenerator::writeInputFileDataAsCode(std::ostream& output) { - std::string output; - //check if input file exists FILE* fin = fopen(mContext.inputFilePath.c_str(), "rb"); if ( !fin ) - return ""; + return; uint64_t fileSize = ra::filesystem::GetFileSize64(mContext.inputFilePath.c_str()); size_t chunkCount = fileSize / mContext.chunkSize; if ( fileSize % mContext.chunkSize > 0 ) chunkCount++; - // Try to optimize the output buffer string. - // Initialize the output buffer to be around twice the size of the input file. - // Most files will output as hexadecimal values which is roughly doubling the number of bytes of the output file. - output.reserve(2 * fileSize); - //create buffer for each chunks from input buffer int numLinePrinted = 0; size_t chunkIndex = 0; @@ -459,9 +452,8 @@ namespace bin2cpp if ( readSize > 0 ) { - //output - std::string encoded_chunk = getInputFileChunkAsCode(buffer, readSize, chunkIndex, chunkCount, isLastChunk); - output += encoded_chunk; + //append chunk as code in output stream + writeInputFileChunkAsCode(buffer, readSize, chunkIndex, chunkCount, isLastChunk, output); numLinePrinted++; chunkIndex++; @@ -472,13 +464,10 @@ namespace bin2cpp buffer = NULL; fclose(fin); - - return output; } - std::string BaseGenerator::getInputFileChunkAsCode(const unsigned char* buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk) + void BaseGenerator::writeInputFileChunkAsCode(const unsigned char* buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk, std::ostream& output) { - return ""; } bool BaseGenerator::createCppHeaderFile(const char * header_file_path) diff --git a/src/bin2cpp/BaseGenerator.h b/src/bin2cpp/BaseGenerator.h index 3f43b2f..e8f695a 100644 --- a/src/bin2cpp/BaseGenerator.h +++ b/src/bin2cpp/BaseGenerator.h @@ -73,8 +73,8 @@ namespace bin2cpp virtual std::string getFileClassFileName(); virtual std::string getFileClassFilePath(); virtual std::string getCppHeaderIncludePath(); - virtual std::string getInputFileDataAsCode(); - virtual std::string getInputFileChunkAsCode(const unsigned char * buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk); + virtual void writeInputFileDataAsCode(std::ostream& output); + virtual void writeInputFileChunkAsCode(const unsigned char * buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk, std::ostream& output); //attributes Context mContext; diff --git a/src/bin2cpp/SegmentGenerator.cpp b/src/bin2cpp/SegmentGenerator.cpp index e36ffaa..3ac2fc7 100755 --- a/src/bin2cpp/SegmentGenerator.cpp +++ b/src/bin2cpp/SegmentGenerator.cpp @@ -185,7 +185,7 @@ namespace bin2cpp return write_success; } - std::string SegmentGenerator::getInputFileChunkAsCode(const unsigned char* buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk) + void SegmentGenerator::writeInputFileChunkAsCode(const unsigned char* buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk, std::ostream& output) { size_t indentation = 0; @@ -196,9 +196,9 @@ namespace bin2cpp else if ( mContext.code == CodeGenerationEnum::CODE_GENERATION_C ) indentation = 2; - std::string output; + std::string str; if ( indentation ) - output += std::string(indentation, ' '); + str += std::string(indentation, ' '); //convert to cpp string std::string code; @@ -218,26 +218,26 @@ namespace bin2cpp } else if ( mContext.code == CodeGenerationEnum::CODE_GENERATION_CPP ) { - output += "mBuffer.append(\""; - output += code; - output += "\", "; - output += ra::strings::ToString(buffer_size); - output += ");"; + str += "mBuffer.append(\""; + str += code; + str += "\", "; + str += ra::strings::ToString(buffer_size); + str += ");"; } else if ( mContext.code == CodeGenerationEnum::CODE_GENERATION_C ) { - output += "memcpy(next, \""; - output += code; - output += "\", "; - output += ra::strings::ToString(buffer_size); - output += "); next += "; - output += ra::strings::ToString(buffer_size); - output += ";"; + str += "memcpy(next, \""; + str += code; + str += "\", "; + str += ra::strings::ToString(buffer_size); + str += "); next += "; + str += ra::strings::ToString(buffer_size); + str += ";"; } - output += "\n"; + str += "\n"; - return output; + output << str; } }; //bin2cpp \ No newline at end of file diff --git a/src/bin2cpp/SegmentGenerator.h b/src/bin2cpp/SegmentGenerator.h index d85bab9..d86f896 100644 --- a/src/bin2cpp/SegmentGenerator.h +++ b/src/bin2cpp/SegmentGenerator.h @@ -42,7 +42,7 @@ namespace bin2cpp virtual const char * getName() const; virtual bool createCppSourceFile(const char * file_path); virtual bool createCSourceFile(const char* file_path); - virtual std::string getInputFileChunkAsCode(const unsigned char* buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk); + virtual void writeInputFileChunkAsCode(const unsigned char* buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk, std::ostream& output); }; }; //bin2cpp diff --git a/src/bin2cpp/StringGenerator.cpp b/src/bin2cpp/StringGenerator.cpp index 1a2bd5c..dc20e19 100755 --- a/src/bin2cpp/StringGenerator.cpp +++ b/src/bin2cpp/StringGenerator.cpp @@ -172,7 +172,7 @@ namespace bin2cpp return write_success; } - std::string StringGenerator::getInputFileChunkAsCode(const unsigned char* buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk) + void StringGenerator::writeInputFileChunkAsCode(const unsigned char* buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk, std::ostream& output) { size_t indentation = 0; @@ -183,30 +183,30 @@ namespace bin2cpp else if ( mContext.code == CodeGenerationEnum::CODE_GENERATION_C ) indentation = 4; - std::string output; + std::string str; if ( indentation ) - output += std::string(indentation, ' '); + str += std::string(indentation, ' '); - output += "\""; + str += "\""; //convert to cpp string switch ( mContext.cppEncoder ) { case CPP_ENCODER_HEX: - output += ra::code::cpp::ToHexString(buffer, buffer_size); + str += ra::code::cpp::ToHexString(buffer, buffer_size); break; case CPP_ENCODER_OCT: default: - output += ra::code::cpp::ToOctString(buffer, buffer_size, false); + str += ra::code::cpp::ToOctString(buffer, buffer_size, false); break; }; - output += "\""; + str += "\""; if ( is_last_chunk ) - output += ";"; - output += "\n"; + str += ";"; + str += "\n"; - return output; + output << str; } }; //bin2cpp \ No newline at end of file diff --git a/src/bin2cpp/StringGenerator.h b/src/bin2cpp/StringGenerator.h index b536ea3..2947d45 100644 --- a/src/bin2cpp/StringGenerator.h +++ b/src/bin2cpp/StringGenerator.h @@ -41,7 +41,7 @@ namespace bin2cpp virtual const char * getName() const; virtual bool createCppSourceFile(const char * file_path); virtual bool createCSourceFile(const char* file_path); - virtual std::string getInputFileChunkAsCode(const unsigned char* buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk); + virtual void writeInputFileChunkAsCode(const unsigned char* buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk, std::ostream& output); }; }; //bin2cpp From 4465ae38e0e95d93cbc3575eae7f02ed3b4e73a4 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sun, 1 Jun 2025 11:48:07 -0400 Subject: [PATCH 23/26] Renamed `lookupStringTemplateVariable()` to `lookupStringVariable()`. Renamed `lookupStreamTemplateVariable()` to `lookupStreamVariable()`. --- src/bin2cpp/BaseGenerator.cpp | 4 ++-- src/bin2cpp/BaseGenerator.h | 4 ++-- src/bin2cpp/ITemplateVariableLookup.h | 4 ++-- src/bin2cpp/TemplateProcessor.cpp | 4 ++-- src/bin2cpp/Win32ResourceGenerator.cpp | 4 ++-- src/bin2cpp/Win32ResourceGenerator.h | 2 +- test/bin2cpp_unittest/TestTemplateProcessor.cpp | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/bin2cpp/BaseGenerator.cpp b/src/bin2cpp/BaseGenerator.cpp index 57ce035..1cbada6 100755 --- a/src/bin2cpp/BaseGenerator.cpp +++ b/src/bin2cpp/BaseGenerator.cpp @@ -56,7 +56,7 @@ namespace bin2cpp return mContext; } - bool BaseGenerator::lookupStringTemplateVariable(const std::string& name, std::string& output) + bool BaseGenerator::lookupStringVariable(const std::string& name, std::string& output) { if ( name == "bin2cpp_output_file_macro_guard" ) { output = getCppIncludeGuardMacroName(mContext.headerFilename); return true; } if ( name == "bin2cpp_output_file_header" ) { output = getHeaderTemplate(); return true; } @@ -109,7 +109,7 @@ namespace bin2cpp return false; } - bool BaseGenerator::lookupStreamTemplateVariable(const std::string& name, std::ostream& output) + bool BaseGenerator::lookupStreamVariable(const std::string& name, std::ostream& output) { if ( name == "bin2cpp_insert_input_file_as_code" ) { diff --git a/src/bin2cpp/BaseGenerator.h b/src/bin2cpp/BaseGenerator.h index e8f695a..eafbd1a 100644 --- a/src/bin2cpp/BaseGenerator.h +++ b/src/bin2cpp/BaseGenerator.h @@ -45,8 +45,8 @@ namespace bin2cpp virtual const Context & getContext() const; //ITemplateVariableLookup methods - virtual bool lookupStringTemplateVariable(const std::string& name, std::string& output); - virtual bool lookupStreamTemplateVariable(const std::string& name, std::ostream& output); + virtual bool lookupStringVariable(const std::string& name, std::string& output); + virtual bool lookupStreamVariable(const std::string& name, std::ostream& output); //same header file for all generators virtual bool createCppHeaderFile(const char * header_file_path); diff --git a/src/bin2cpp/ITemplateVariableLookup.h b/src/bin2cpp/ITemplateVariableLookup.h index f54d9cf..33d251b 100644 --- a/src/bin2cpp/ITemplateVariableLookup.h +++ b/src/bin2cpp/ITemplateVariableLookup.h @@ -44,7 +44,7 @@ namespace bin2cpp ///The name of the template variable. ///The output string for getting the value or the template variable. ///Returns true when the template variable is handled by the instance. Returns false otherwise. - virtual bool lookupStringTemplateVariable(const std::string& name, std::string& output) = 0; + virtual bool lookupStringVariable(const std::string& name, std::string& output) = 0; /// ///Lookup the string value for a given template variable name. @@ -54,7 +54,7 @@ namespace bin2cpp ///The name of the template variable. ///The output string for getting the value or the template variable. ///Returns true when the template variable is handled by the instance. Returns false otherwise. - virtual bool lookupStreamTemplateVariable(const std::string& name, std::ostream& output) = 0; + virtual bool lookupStreamVariable(const std::string& name, std::ostream& output) = 0; }; diff --git a/src/bin2cpp/TemplateProcessor.cpp b/src/bin2cpp/TemplateProcessor.cpp index c66b9dc..4a47c6d 100644 --- a/src/bin2cpp/TemplateProcessor.cpp +++ b/src/bin2cpp/TemplateProcessor.cpp @@ -126,7 +126,7 @@ namespace bin2cpp // Check if template variable is a string and do the variable expansion std::string expanded_value; - bool found_as_string = mVariableLookup->lookupStringTemplateVariable(variable_name, expanded_value); + bool found_as_string = mVariableLookup->lookupStringVariable(variable_name, expanded_value); // Proceed with the recursive handling if ( found_as_string ) @@ -144,7 +144,7 @@ namespace bin2cpp { // Check if template variable is a stream // Stream based template variables do not support recursive lookup and tracking - bool found_as_stream = mVariableLookup->lookupStreamTemplateVariable(variable_name, output_stream); + bool found_as_stream = mVariableLookup->lookupStreamVariable(variable_name, output_stream); } pos = end_pos + 1; diff --git a/src/bin2cpp/Win32ResourceGenerator.cpp b/src/bin2cpp/Win32ResourceGenerator.cpp index 02dbef7..5b350ca 100755 --- a/src/bin2cpp/Win32ResourceGenerator.cpp +++ b/src/bin2cpp/Win32ResourceGenerator.cpp @@ -376,13 +376,13 @@ namespace bin2cpp return false; // not supported } - bool Win32ResourceGenerator::lookupStringTemplateVariable(const std::string& name, std::string& output) + bool Win32ResourceGenerator::lookupStringVariable(const std::string& name, std::string& output) { if ( name == "bin2cpp_win32_resource_random_identifier" ) { output = getRandomIdentifier(mContext.inputFilePath.c_str()); return true; } if ( name == "bin2cpp_win32_local_info_struct_name" ) { output = getLocalInfoStructName(); return true; } // Unknown name - return this->BaseGenerator::lookupStringTemplateVariable(name, output); + return this->BaseGenerator::lookupStringVariable(name, output); } std::string Win32ResourceGenerator::getLocalInfoStructName() diff --git a/src/bin2cpp/Win32ResourceGenerator.h b/src/bin2cpp/Win32ResourceGenerator.h index b522da8..e76a96d 100644 --- a/src/bin2cpp/Win32ResourceGenerator.h +++ b/src/bin2cpp/Win32ResourceGenerator.h @@ -44,7 +44,7 @@ namespace bin2cpp virtual bool printFileContent(); //ITemplateVariableLookup methods - virtual bool lookupStringTemplateVariable(const std::string& name, std::string& output); + virtual bool lookupStringVariable(const std::string& name, std::string& output); protected: virtual std::string getResourceFilePath(const char * file_path); diff --git a/test/bin2cpp_unittest/TestTemplateProcessor.cpp b/test/bin2cpp_unittest/TestTemplateProcessor.cpp index e128074..77e4571 100644 --- a/test/bin2cpp_unittest/TestTemplateProcessor.cpp +++ b/test/bin2cpp_unittest/TestTemplateProcessor.cpp @@ -35,7 +35,7 @@ class SampleVariableLookup : public bin2cpp::ITemplateVariableLookup { public: - bool lookupStringTemplateVariable(const std::string& name, std::string& output) override + bool lookupStringVariable(const std::string& name, std::string& output) override { if ( name == "first-name" ) { output = "Luke"; return true; } if ( name == "last-name" ) { output = "Skywalker"; return true; } @@ -49,7 +49,7 @@ class SampleVariableLookup : public bin2cpp::ITemplateVariableLookup return false; } - bool lookupStreamTemplateVariable(const std::string& name, std::ostream& output) override + bool lookupStreamVariable(const std::string& name, std::ostream& output) override { return false; } From fb2d3fc53b3227c259607d7430adcc0bea391198 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sun, 1 Jun 2025 12:17:56 -0400 Subject: [PATCH 24/26] Renamed multiple template variables to more meaningful names. Also renamed multiple methods in BaseGenerator to match their template variable names. --- TODO.txt | 12 ---- src/bin2cpp/ArrayGenerator.cpp | 22 +++--- src/bin2cpp/BaseGenerator.cpp | 98 +++++++++++--------------- src/bin2cpp/BaseGenerator.h | 13 ++-- src/bin2cpp/SegmentGenerator.cpp | 22 +++--- src/bin2cpp/StringGenerator.cpp | 22 +++--- src/bin2cpp/Win32ResourceGenerator.cpp | 24 +++---- src/bin2cpp/common.cpp | 2 +- src/bin2cpp/common.h | 2 +- 9 files changed, 96 insertions(+), 121 deletions(-) diff --git a/TODO.txt b/TODO.txt index 67b53c4..cc547ef 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,15 +1,3 @@ -Rename the following: - -getFileClassFileName to getFileObjectFileName -getFileClassFilePath to getFileObjectFilePath -getFileClassGetFileNameImplementation to getFileObjectGetFileNameImplementation -getFileClassGetFileNameImplementation to getFileObjectGetFileNameImplementation -bin2cpp_getter_function_name to bin2cpp_file_object_getter_function_name -getGetterFunctionName to getFileObjectGetterFunctionName - check implementation of the following to see if they could be simplified: * getFileClassGetFileNameImplementation * getFileClassGetFilePathImplementation - - -Move TemplateProcessor code to its own static library ? diff --git a/src/bin2cpp/ArrayGenerator.cpp b/src/bin2cpp/ArrayGenerator.cpp index 76cd6ba..3124f30 100644 --- a/src/bin2cpp/ArrayGenerator.cpp +++ b/src/bin2cpp/ArrayGenerator.cpp @@ -56,8 +56,8 @@ namespace bin2cpp return false; const std::string text = "" - "${bin2cpp_output_file_header}" - "#include \"${bin2cpp_header_source_file_include_path}\"\n" + "${bin2cpp_output_file_header_template}" + "#include \"${bin2cpp_header_file_include_path}\"\n" "#include \n" "#include //for ofstream\n" "namespace ${bin2cpp_namespace}\n" @@ -76,10 +76,10 @@ namespace bin2cpp " };\n" " return (const char *)buffer;\n" " }\n" - "${bin2cpp_cpp_get_save_method_impl}" + "${bin2cpp_cpp_save_method_template}" " };\n" - " const ${bin2cpp_baseclass} & ${bin2cpp_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" - "${bin2cpp_cpp_get_file_manager_registration_impl}" + " const ${bin2cpp_baseclass} & ${bin2cpp_file_object_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" + "${bin2cpp_file_manager_cpp_registration_implementation}" "}; //${bin2cpp_namespace}\n"; TemplateProcessor processor(&text); @@ -111,18 +111,18 @@ namespace bin2cpp return false; const std::string text = "" - "${bin2cpp_output_file_header}" + "${bin2cpp_output_file_header_template}" "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" "#define _CRT_SECURE_NO_WARNINGS\n" "#endif\n" - "#include \"${bin2cpp_header_source_file_include_path}\"\n" + "#include \"${bin2cpp_header_file_include_path}\"\n" "#include // for malloc\n" "#include // for memset\n" "#include // for fopen\n" "static ${bin2cpp_baseclass} ${bin2cpp_function_identifier_lowercase}_file = { 0 };\n" "static bool ${bin2cpp_function_identifier_lowercase}_initialized = false;\n" "\n" - "${bin2cpp_c_file_manager_registration_predeclaration}" + "${bin2cpp_file_manager_c_registration_predeclaration}" "bool ${bin2cpp_function_identifier_lowercase}_load()\n" "{\n" " if ( ${bin2cpp_function_identifier_lowercase}_file.buffer )\n" @@ -172,15 +172,15 @@ namespace bin2cpp "\n" " // load file by default on init as in c++ implementation\n" " file->load();\n" - "${bin2cpp_c_file_manager_registration_post_init_impl}" + "${bin2cpp_file_manager_c_registration_post_init_implementation}" "}\n" "\n" - "${bin2cpp_baseclass}* ${bin2cpp_getter_function_name}(void)\n" + "${bin2cpp_baseclass}* ${bin2cpp_file_object_getter_function_name}(void)\n" "{\n" " ${bin2cpp_function_identifier_lowercase}_init();\n" " return &${bin2cpp_function_identifier_lowercase}_file;\n" "}\n" - "${bin2cpp_c_file_manager_registration_implementation}"; + "${bin2cpp_file_manager_c_registration_implementation}"; TemplateProcessor processor(&text); processor.setTemplateVariableLookup(this); diff --git a/src/bin2cpp/BaseGenerator.cpp b/src/bin2cpp/BaseGenerator.cpp index 1cbada6..15a416f 100755 --- a/src/bin2cpp/BaseGenerator.cpp +++ b/src/bin2cpp/BaseGenerator.cpp @@ -58,52 +58,29 @@ namespace bin2cpp bool BaseGenerator::lookupStringVariable(const std::string& name, std::string& output) { - if ( name == "bin2cpp_output_file_macro_guard" ) { output = getCppIncludeGuardMacroName(mContext.headerFilename); return true; } - if ( name == "bin2cpp_output_file_header" ) { output = getHeaderTemplate(); return true; } - if ( name == "bin2cpp_file_object_macro_guard_prefix" ) { output = getClassMacroGuardPrefix(); return true; } + if ( name == "bin2cpp_baseclass" ) { output = mContext.baseClass; return true; } + if ( name == "bin2cpp_classname" ) { output = getClassName(); return true; } + if ( name == "bin2cpp_cpp_save_method_template" ) { output = getCppSaveMethodTemplate(); return true; } + if ( name == "bin2cpp_file_manager_c_registration_implementation" && mContext.registerFiles ) { output = getCFileManagerStaticFileRegistrationImplementation(); return true; } + if ( name == "bin2cpp_file_manager_c_registration_post_init_implementation" && mContext.registerFiles ) { output = getCFileManagerRegistrationPostInitImplementation(); return true; } + if ( name == "bin2cpp_file_manager_c_registration_predeclaration" && mContext.registerFiles ) { output = getCFileManagerRegistrationPredeclarationImplementation(); return true; } + if ( name == "bin2cpp_file_manager_cpp_registration_implementation" && mContext.registerFiles ) { output = getCppFileManagerRegistrationImplementationTemplate(); return true; } if ( name == "bin2cpp_file_manager_file_header" ) { output = getHeaderTemplate(false); return true; } if ( name == "bin2cpp_file_manager_header_file_name" ) { output = mContext.managerHeaderFilename; return true; } if ( name == "bin2cpp_file_manager_macro_guard_prefix" ) { output = getFileManagerMacroGuardPrefix(); return true; } - if ( name == "bin2cpp_baseclass" ) { output = mContext.baseClass; return true; } - if ( name == "bin2cpp_classname" ) { output = getClassName(); return true; } - if ( name == "bin2cpp_namespace" ) { output = mContext.codeNamespace; return true; } - //if ( name == "bin2cpp_baseclass_uppercase" ) { output = ra::strings::Uppercase(mContext.baseClass); return true; } - //if ( name == "bin2cpp_classname_uppercase" ) { output = ra::strings::Uppercase(getClassName()); return true; } - //if ( name == "bin2cpp_namespace_uppercase" ) { output = ra::strings::Lowercase(mContext.codeNamespace); return true; } - //if ( name == "bin2cpp_baseclass_lowercase" ) { output = ra::strings::Lowercase(mContext.baseClass); return true; } - //if ( name == "bin2cpp_classname_lowercase" ) { output = ra::strings::Lowercase(getClassName()); return true; } - //if ( name == "bin2cpp_namespace_lowercase" ) { output = ra::strings::Lowercase(mContext.codeNamespace); return true; } - if ( name == "bin2cpp_function_identifier" ) { output = mContext.functionIdentifier; return true; } + if ( name == "bin2cpp_file_object_file_name_impl" ) { output = getFileObjectGetFileNameImplementation(); return true; } + if ( name == "bin2cpp_file_object_file_name" ) { output = getFileObjectFileName(); return true; } + if ( name == "bin2cpp_file_object_file_path_impl" ) { output = getFileObjectGetFilePathImplementation(); return true; } + if ( name == "bin2cpp_file_object_file_path" ) { output = getFileObjectFilePath(); return true; } + if ( name == "bin2cpp_file_object_getter_function_name" ) { output = getFileObjectGetterFunctionName(); return true; } + if ( name == "bin2cpp_file_object_macro_guard_prefix" ) { output = getClassMacroGuardPrefix(); return true; } if ( name == "bin2cpp_function_identifier_lowercase" ) { output = ra::strings::Lowercase(mContext.functionIdentifier); return true; } - if ( name == "bin2cpp_getter_function_name" ) { output = getGetterFunctionName(); return true; } - if ( name == "bin2cpp_header_source_file_include_path" ) { output = getCppHeaderIncludePath(); return true; } - if ( name == "bin2cpp_file_object_file_name_impl" ) { output = getFileClassGetFileNameImplementation(); return true; } - if ( name == "bin2cpp_file_object_file_path_impl" ) { output = getFileClassGetFilePathImplementation(); return true; } - if ( name == "bin2cpp_file_object_file_name" ) { output = getFileClassFileName(); return true; } - if ( name == "bin2cpp_file_object_file_path" ) { output = getFileClassFilePath(); return true; } - if ( name == "bin2cpp_cpp_get_save_method_impl" ) { output = getCppSaveMethodTemplate(); return true; } - if ( name == "bin2cpp_cpp_get_file_manager_registration_impl" && mContext.registerFiles ) { output = getCppFileManagerRegistrationImplementationTemplate(); return true; } - if ( name == "bin2cpp_c_file_manager_registration_predeclaration" && mContext.registerFiles ) { output = getCFileManagerRegistrationPredeclarationImplementation(); return true; } - if ( name == "bin2cpp_c_file_manager_registration_implementation" && mContext.registerFiles ) { output = getCFileManagerStaticFileRegistrationImplementation(); return true; } - - if ( name == "bin2cpp_c_file_manager_registration_post_init_impl" && mContext.registerFiles ) - { - std::string tmp; - tmp += " \n"; - tmp += " // register when loaded if static initialisation does not work\n"; - tmp += " ${bin2cpp_namespace}_filemanager_register_file(file);\n"; - output = tmp; - return true; - } - - if ( name == "bin2cpp_input_file_size" ) - { - //determine file properties - uint32_t file_size = ra::filesystem::GetFileSize(mContext.inputFilePath.c_str()); - std::string file_size_str = ra::strings::ToString(file_size); - output = file_size_str; - return true; - } + if ( name == "bin2cpp_function_identifier" ) { output = mContext.functionIdentifier; return true; } + if ( name == "bin2cpp_header_file_include_path" ) { output = getHeaderFileIncludePath(); return true; } + if ( name == "bin2cpp_input_file_size" ) { output = ra::strings::ToString(ra::filesystem::GetFileSize(mContext.inputFilePath.c_str())); return true; } + if ( name == "bin2cpp_namespace" ) { output = mContext.codeNamespace; return true; } + if ( name == "bin2cpp_output_file_header_template" ) { output = getHeaderTemplate(); return true; } + if ( name == "bin2cpp_output_file_macro_guard" ) { output = getIncludeGuardMacroName(mContext.headerFilename); return true; } // Unknown name return false; @@ -124,7 +101,7 @@ namespace bin2cpp //protected methods //------------------------------- - std::string BaseGenerator::getGetterFunctionName() + std::string BaseGenerator::getFileObjectGetterFunctionName() { std::string getter; @@ -243,7 +220,7 @@ namespace bin2cpp std::string output; output << " typedef const " << mContext.baseClass << " & (*t_func)();\n"; output << " extern bool RegisterFile(t_func iFunctionPointer);\n"; - output << " static bool k" << className << "Registered = " << mContext.codeNamespace << "::RegisterFile(&" << getGetterFunctionName() << ");\n"; + output << " static bool k" << className << "Registered = " << mContext.codeNamespace << "::RegisterFile(&" << getFileObjectGetterFunctionName() << ");\n"; output << " \n"; return output; } @@ -284,6 +261,15 @@ namespace bin2cpp return output; } + std::string BaseGenerator::getCFileManagerRegistrationPostInitImplementation() + { + std::string output; + output += " \n"; + output += " // register when loaded if static initialisation does not work\n"; + output += " ${bin2cpp_namespace}_filemanager_register_file(file);\n"; + return output; + } + std::string BaseGenerator::getClassName() { std::string functionIdentifier = ra::strings::CapitalizeFirstCharacter(mContext.functionIdentifier); @@ -307,14 +293,14 @@ namespace bin2cpp { //define macro guard a macro matching the filename std::string output; - output += getCppIncludeGuardMacroName(mContext.codeNamespace.c_str()); //prefix the custom namespace for the file manager + output += getIncludeGuardMacroName(mContext.codeNamespace.c_str()); //prefix the custom namespace for the file manager if ( !output.empty() ) output += "_"; - output += getCppIncludeGuardMacroName(mContext.managerHeaderFilename); + output += getIncludeGuardMacroName(mContext.managerHeaderFilename); return output; } - std::string BaseGenerator::getFileClassGetFileNameImplementation() + std::string BaseGenerator::getFileObjectGetFileNameImplementation() { std::string output; @@ -341,7 +327,7 @@ namespace bin2cpp return output; } - std::string BaseGenerator::getFileClassGetFilePathImplementation() + std::string BaseGenerator::getFileObjectGetFilePathImplementation() { std::string output; @@ -378,7 +364,7 @@ namespace bin2cpp return output; } - std::string BaseGenerator::getFileClassFileName() + std::string BaseGenerator::getFileObjectFileName() { std::string output; @@ -389,7 +375,7 @@ namespace bin2cpp return output; } - std::string BaseGenerator::getFileClassFilePath() + std::string BaseGenerator::getFileObjectFilePath() { std::string output; @@ -413,7 +399,7 @@ namespace bin2cpp { //if reported path is not specified ? //report the same as getFileName() - output = getFileClassFileName(); + output = getFileObjectFileName(); return output; } @@ -422,7 +408,7 @@ namespace bin2cpp return output; } - std::string BaseGenerator::getCppHeaderIncludePath() + std::string BaseGenerator::getHeaderFileIncludePath() { return mContext.headerFilename; } @@ -473,7 +459,7 @@ namespace bin2cpp bool BaseGenerator::createCppHeaderFile(const char * header_file_path) { const std::string text = "" - "${bin2cpp_output_file_header}" + "${bin2cpp_output_file_header_template}" "#ifndef ${bin2cpp_output_file_macro_guard}\n" "#define ${bin2cpp_output_file_macro_guard}\n" "\n" @@ -494,7 +480,7 @@ namespace bin2cpp " virtual bool save(const char * filename) const = 0;\n" " };\n" " #endif //${bin2cpp_file_object_macro_guard_prefix}_FILE_OBJECT_CLASS\n" - " const ${bin2cpp_baseclass} & ${bin2cpp_getter_function_name}();\n" + " const ${bin2cpp_baseclass} & ${bin2cpp_file_object_getter_function_name}();\n" "}; //${bin2cpp_namespace}\n" "\n" "#endif //${bin2cpp_output_file_macro_guard}\n" @@ -562,7 +548,7 @@ namespace bin2cpp bool BaseGenerator::createCHeaderFile(const char* file_path) { const std::string text = "" - "${bin2cpp_output_file_header}" + "${bin2cpp_output_file_header_template}" "#ifndef ${bin2cpp_output_file_macro_guard}\n" "#define ${bin2cpp_output_file_macro_guard}\n" "\n" @@ -587,7 +573,7 @@ namespace bin2cpp "} ${bin2cpp_baseclass};\n" "typedef ${bin2cpp_baseclass}* ${bin2cpp_baseclass}Ptr;\n" "#endif //${bin2cpp_file_object_macro_guard_prefix}_FILE_OBJECT_STRUCT\n" - "${bin2cpp_baseclass}* ${bin2cpp_getter_function_name}(void);\n" + "${bin2cpp_baseclass}* ${bin2cpp_file_object_getter_function_name}(void);\n" "\n" "#endif //${bin2cpp_output_file_macro_guard}\n" ; diff --git a/src/bin2cpp/BaseGenerator.h b/src/bin2cpp/BaseGenerator.h index eafbd1a..ac05295 100644 --- a/src/bin2cpp/BaseGenerator.h +++ b/src/bin2cpp/BaseGenerator.h @@ -56,7 +56,7 @@ namespace bin2cpp protected: - virtual std::string getGetterFunctionName(); + virtual std::string getFileObjectGetterFunctionName(); virtual std::string getHeaderFilePath(const char * cpp_file_path); virtual std::string getCppFilePath(const char * header_file_path); virtual std::string getHeaderTemplate(); @@ -65,14 +65,15 @@ namespace bin2cpp virtual std::string getCppFileManagerRegistrationImplementationTemplate(); virtual std::string getCFileManagerRegistrationPredeclarationImplementation(); virtual std::string getCFileManagerStaticFileRegistrationImplementation(); + virtual std::string getCFileManagerRegistrationPostInitImplementation(); virtual std::string getClassName(); virtual std::string getClassMacroGuardPrefix(); virtual std::string getFileManagerMacroGuardPrefix(); - virtual std::string getFileClassGetFileNameImplementation(); - virtual std::string getFileClassGetFilePathImplementation(); - virtual std::string getFileClassFileName(); - virtual std::string getFileClassFilePath(); - virtual std::string getCppHeaderIncludePath(); + virtual std::string getFileObjectGetFileNameImplementation(); + virtual std::string getFileObjectGetFilePathImplementation(); + virtual std::string getFileObjectFileName(); + virtual std::string getFileObjectFilePath(); + virtual std::string getHeaderFileIncludePath(); virtual void writeInputFileDataAsCode(std::ostream& output); virtual void writeInputFileChunkAsCode(const unsigned char * buffer, size_t buffer_size, size_t index, size_t count, bool is_last_chunk, std::ostream& output); diff --git a/src/bin2cpp/SegmentGenerator.cpp b/src/bin2cpp/SegmentGenerator.cpp index 3ac2fc7..f600daa 100755 --- a/src/bin2cpp/SegmentGenerator.cpp +++ b/src/bin2cpp/SegmentGenerator.cpp @@ -55,11 +55,11 @@ namespace bin2cpp return false; const std::string text = "" - "${bin2cpp_output_file_header}" + "${bin2cpp_output_file_header_template}" "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" "#define _CRT_SECURE_NO_WARNINGS\n" "#endif\n" - "#include \"${bin2cpp_header_source_file_include_path}\"\n" + "#include \"${bin2cpp_header_file_include_path}\"\n" "#include //for std::string\n" "#include \n" "#include //for ofstream\n" @@ -79,12 +79,12 @@ namespace bin2cpp " mBuffer.clear();\n" " mBuffer.reserve(getSize()); //allocate all required memory at once to prevent reallocations\n${bin2cpp_insert_input_file_as_code}" // INPUT FILE AS CODE HERE " }\n" - "${bin2cpp_cpp_get_save_method_impl}" + "${bin2cpp_cpp_save_method_template}" " private:\n" " std::string mBuffer;\n" " };\n" - " const ${bin2cpp_baseclass} & ${bin2cpp_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" - "${bin2cpp_cpp_get_file_manager_registration_impl}" + " const ${bin2cpp_baseclass} & ${bin2cpp_file_object_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" + "${bin2cpp_file_manager_cpp_registration_implementation}" "}; //${bin2cpp_namespace}\n"; TemplateProcessor processor(&text); @@ -101,18 +101,18 @@ namespace bin2cpp return false; const std::string text = "" - "${bin2cpp_output_file_header}" + "${bin2cpp_output_file_header_template}" "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" "#define _CRT_SECURE_NO_WARNINGS\n" "#endif\n" - "#include \"${bin2cpp_header_source_file_include_path}\"\n" + "#include \"${bin2cpp_header_file_include_path}\"\n" "#include // for malloc\n" "#include // for memset\n" "#include // for fopen\n" "static ${bin2cpp_baseclass} ${bin2cpp_function_identifier_lowercase}_file = { 0 };\n" "static bool ${bin2cpp_function_identifier_lowercase}_initialized = false;\n" "\n" - "${bin2cpp_c_file_manager_registration_predeclaration}" + "${bin2cpp_file_manager_c_registration_predeclaration}" "bool ${bin2cpp_function_identifier_lowercase}_load()\n" "{\n" " if ( ${bin2cpp_function_identifier_lowercase}_file.buffer )\n" @@ -168,15 +168,15 @@ namespace bin2cpp "\n" " // load file by default on init as in c++ implementation\n" " file->load();\n" - "${bin2cpp_c_file_manager_registration_post_init_impl}" + "${bin2cpp_file_manager_c_registration_post_init_implementation}" "}\n" "\n" - "${bin2cpp_baseclass}* ${bin2cpp_getter_function_name}(void)\n" + "${bin2cpp_baseclass}* ${bin2cpp_file_object_getter_function_name}(void)\n" "{\n" " ${bin2cpp_function_identifier_lowercase}_init();\n" " return &${bin2cpp_function_identifier_lowercase}_file;\n" "}\n" - "${bin2cpp_c_file_manager_registration_implementation}"; + "${bin2cpp_file_manager_c_registration_implementation}"; TemplateProcessor processor(&text); processor.setTemplateVariableLookup(this); diff --git a/src/bin2cpp/StringGenerator.cpp b/src/bin2cpp/StringGenerator.cpp index dc20e19..ae79ea4 100755 --- a/src/bin2cpp/StringGenerator.cpp +++ b/src/bin2cpp/StringGenerator.cpp @@ -55,8 +55,8 @@ namespace bin2cpp return false; const std::string text = "" - "${bin2cpp_output_file_header}" - "#include \"${bin2cpp_header_source_file_include_path}\"\n" + "${bin2cpp_output_file_header_template}" + "#include \"${bin2cpp_header_file_include_path}\"\n" "#include \n" "#include //for ofstream\n" "namespace ${bin2cpp_namespace}\n" @@ -74,10 +74,10 @@ namespace bin2cpp " const char * buffer = \n${bin2cpp_insert_input_file_as_code}" // INPUT FILE AS CODE HERE " return buffer;\n" " }\n" - "${bin2cpp_cpp_get_save_method_impl}" + "${bin2cpp_cpp_save_method_template}" " };\n" - " const ${bin2cpp_baseclass} & ${bin2cpp_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" - "${bin2cpp_cpp_get_file_manager_registration_impl}" + " const ${bin2cpp_baseclass} & ${bin2cpp_file_object_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" + "${bin2cpp_file_manager_cpp_registration_implementation}" "}; //${bin2cpp_namespace}\n"; TemplateProcessor processor(&text); @@ -94,18 +94,18 @@ namespace bin2cpp return false; const std::string text = "" - "${bin2cpp_output_file_header}" + "${bin2cpp_output_file_header_template}" "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" "#define _CRT_SECURE_NO_WARNINGS\n" "#endif\n" - "#include \"${bin2cpp_header_source_file_include_path}\"\n" + "#include \"${bin2cpp_header_file_include_path}\"\n" "#include // for malloc\n" "#include // for memset\n" "#include // for fopen\n" "static ${bin2cpp_baseclass} ${bin2cpp_function_identifier_lowercase}_file = { 0 };\n" "static bool ${bin2cpp_function_identifier_lowercase}_initialized = false;\n" "\n" - "${bin2cpp_c_file_manager_registration_predeclaration}" + "${bin2cpp_file_manager_c_registration_predeclaration}" "bool ${bin2cpp_function_identifier_lowercase}_load()\n" "{\n" " if ( ${bin2cpp_function_identifier_lowercase}_file.buffer )\n" @@ -155,15 +155,15 @@ namespace bin2cpp "\n" " // load file by default on init as in c++ implementation\n" " file->load();\n" - "${bin2cpp_c_file_manager_registration_post_init_impl}" + "${bin2cpp_file_manager_c_registration_post_init_implementation}" "}\n" "\n" - "${bin2cpp_baseclass}* ${bin2cpp_getter_function_name}(void)\n" + "${bin2cpp_baseclass}* ${bin2cpp_file_object_getter_function_name}(void)\n" "{\n" " ${bin2cpp_function_identifier_lowercase}_init();\n" " return &${bin2cpp_function_identifier_lowercase}_file;\n" "}\n" - "${bin2cpp_c_file_manager_registration_implementation}"; + "${bin2cpp_file_manager_c_registration_implementation}"; TemplateProcessor processor(&text); processor.setTemplateVariableLookup(this); diff --git a/src/bin2cpp/Win32ResourceGenerator.cpp b/src/bin2cpp/Win32ResourceGenerator.cpp index 5b350ca..eb78b45 100755 --- a/src/bin2cpp/Win32ResourceGenerator.cpp +++ b/src/bin2cpp/Win32ResourceGenerator.cpp @@ -63,8 +63,8 @@ namespace bin2cpp return false; const std::string text = "" - "${bin2cpp_output_file_header}" - "#include \"${bin2cpp_header_source_file_include_path}\"\n" + "${bin2cpp_output_file_header_template}" + "#include \"${bin2cpp_header_file_include_path}\"\n" "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" "#define _CRT_SECURE_NO_WARNINGS\n" "#endif\n" @@ -142,7 +142,7 @@ namespace bin2cpp " hProcess = NULL;\n" " }\n" " }\n" - "${bin2cpp_cpp_get_save_method_impl}" + "${bin2cpp_cpp_save_method_template}" " private:\n" " HANDLE hProcess;\n" " HMODULE hModule;\n" @@ -151,8 +151,8 @@ namespace bin2cpp " DWORD mBufferSize;\n" " const char * mBuffer;\n" " };\n" - " const ${bin2cpp_baseclass} & ${bin2cpp_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" - "${bin2cpp_cpp_get_file_manager_registration_impl}" + " const ${bin2cpp_baseclass} & ${bin2cpp_file_object_getter_function_name}() { static ${bin2cpp_classname} _instance; return _instance; }\n" + "${bin2cpp_file_manager_cpp_registration_implementation}" "}; //${bin2cpp_namespace}\n"; TemplateProcessor processor(&text); @@ -173,12 +173,12 @@ namespace bin2cpp return false; const std::string text = "" - "${bin2cpp_output_file_header}" + "${bin2cpp_output_file_header_template}" "#if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)\n" "#define _CRT_SECURE_NO_WARNINGS\n" "#endif\n" "\n" - "#include \"${bin2cpp_header_source_file_include_path}\"\n" + "#include \"${bin2cpp_header_file_include_path}\"\n" "#include // for malloc\n" "#include // for memset\n" "#include // for fopen\n" @@ -203,7 +203,7 @@ namespace bin2cpp "} ${bin2cpp_win32_local_info_struct_name};\n" "static ${bin2cpp_win32_local_info_struct_name} ${bin2cpp_function_identifier_lowercase}_info = { 0 };\n" "\n" - "${bin2cpp_c_file_manager_registration_predeclaration}" + "${bin2cpp_file_manager_c_registration_predeclaration}" "bool ${bin2cpp_function_identifier_lowercase}_load()\n" "{\n" " if ( ${bin2cpp_function_identifier_lowercase}_file.buffer )\n" @@ -290,15 +290,15 @@ namespace bin2cpp "\n" " // load file by default on init as in c++ implementation\n" " file->load();\n" - "${bin2cpp_c_file_manager_registration_post_init_impl}" + "${bin2cpp_file_manager_c_registration_post_init_implementation}" "}\n" "\n" - "${bin2cpp_baseclass}* ${bin2cpp_getter_function_name}(void)\n" + "${bin2cpp_baseclass}* ${bin2cpp_file_object_getter_function_name}(void)\n" "{\n" " ${bin2cpp_function_identifier_lowercase}_init();\n" " return &${bin2cpp_function_identifier_lowercase}_file;\n" "}\n" - "${bin2cpp_c_file_manager_registration_implementation}"; + "${bin2cpp_file_manager_c_registration_implementation}"; TemplateProcessor processor(&text); processor.setTemplateVariableLookup(this); @@ -350,7 +350,7 @@ namespace bin2cpp std::string Win32ResourceGenerator::getRandomIdentifier(const char * file_path) { - std::string include_guard = getCppIncludeGuardMacroName(file_path); + std::string include_guard = getIncludeGuardMacroName(file_path); //append a CRC32 checksum of the file path to allow storing multiple files with the same name in resources uint32_t checksum = 0; diff --git a/src/bin2cpp/common.cpp b/src/bin2cpp/common.cpp index 796a38e..62c7c01 100755 --- a/src/bin2cpp/common.cpp +++ b/src/bin2cpp/common.cpp @@ -110,7 +110,7 @@ namespace bin2cpp return false; } - std::string getCppIncludeGuardMacroName(const std::string & path) + std::string getIncludeGuardMacroName(const std::string & path) { static const std::string EMPTY_STRING; if (path.empty()) diff --git a/src/bin2cpp/common.h b/src/bin2cpp/common.h index 48aca46..af7eec6 100644 --- a/src/bin2cpp/common.h +++ b/src/bin2cpp/common.h @@ -84,7 +84,7 @@ namespace bin2cpp /// ///An valid file path. ///Returns the macro name for the given c++ header file. - std::string getCppIncludeGuardMacroName(const std::string & path); + std::string getIncludeGuardMacroName(const std::string & path); /// ///Filter a string to only contains the given allowed characters. From 4f50af54978b5e6f3b795fba9b7059b2e1acd7cf Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sun, 1 Jun 2025 12:42:38 -0400 Subject: [PATCH 25/26] Removed `${bin2cpp_file_object_file_name_impl}` and `${bin2cpp_file_object_file_path_impl}` template variables which were way too much complicated and provided poor improvement. Replaced by `${bin2cpp_file_object_file_name}` and `${bin2cpp_file_object_file_path}` which are much simpler. Inspired by c generated code. --- TODO.txt | 3 -- src/bin2cpp/ArrayGenerator.cpp | 4 +- src/bin2cpp/BaseGenerator.cpp | 66 -------------------------- src/bin2cpp/BaseGenerator.h | 2 - src/bin2cpp/SegmentGenerator.cpp | 4 +- src/bin2cpp/StringGenerator.cpp | 4 +- src/bin2cpp/Win32ResourceGenerator.cpp | 4 +- src/bin2cpp/bin2cpp.samples.txt | 16 +++---- 8 files changed, 16 insertions(+), 87 deletions(-) delete mode 100644 TODO.txt diff --git a/TODO.txt b/TODO.txt deleted file mode 100644 index cc547ef..0000000 --- a/TODO.txt +++ /dev/null @@ -1,3 +0,0 @@ -check implementation of the following to see if they could be simplified: -* getFileClassGetFileNameImplementation -* getFileClassGetFilePathImplementation diff --git a/src/bin2cpp/ArrayGenerator.cpp b/src/bin2cpp/ArrayGenerator.cpp index 3124f30..a5c5123 100644 --- a/src/bin2cpp/ArrayGenerator.cpp +++ b/src/bin2cpp/ArrayGenerator.cpp @@ -68,8 +68,8 @@ namespace bin2cpp " ${bin2cpp_classname}() {}\n" " virtual ~${bin2cpp_classname}() {}\n" " virtual size_t getSize() const { return ${bin2cpp_input_file_size}; }\n" - " virtual const char * getFileName() const { ${bin2cpp_file_object_file_name_impl} }\n" - " virtual const char * getFilePath() const { ${bin2cpp_file_object_file_path_impl} }\n" + " virtual const char * getFileName() const { return \"${bin2cpp_file_object_file_name}\"; }\n" + " virtual const char * getFilePath() const { return \"${bin2cpp_file_object_file_path}\"; }\n" " virtual const char * getBuffer() const\n" " {\n" " static const unsigned char buffer[] = {\n${bin2cpp_insert_input_file_as_code}" // INPUT FILE AS CODE HERE diff --git a/src/bin2cpp/BaseGenerator.cpp b/src/bin2cpp/BaseGenerator.cpp index 15a416f..0ea6536 100755 --- a/src/bin2cpp/BaseGenerator.cpp +++ b/src/bin2cpp/BaseGenerator.cpp @@ -68,9 +68,7 @@ namespace bin2cpp if ( name == "bin2cpp_file_manager_file_header" ) { output = getHeaderTemplate(false); return true; } if ( name == "bin2cpp_file_manager_header_file_name" ) { output = mContext.managerHeaderFilename; return true; } if ( name == "bin2cpp_file_manager_macro_guard_prefix" ) { output = getFileManagerMacroGuardPrefix(); return true; } - if ( name == "bin2cpp_file_object_file_name_impl" ) { output = getFileObjectGetFileNameImplementation(); return true; } if ( name == "bin2cpp_file_object_file_name" ) { output = getFileObjectFileName(); return true; } - if ( name == "bin2cpp_file_object_file_path_impl" ) { output = getFileObjectGetFilePathImplementation(); return true; } if ( name == "bin2cpp_file_object_file_path" ) { output = getFileObjectFilePath(); return true; } if ( name == "bin2cpp_file_object_getter_function_name" ) { output = getFileObjectGetterFunctionName(); return true; } if ( name == "bin2cpp_file_object_macro_guard_prefix" ) { output = getClassMacroGuardPrefix(); return true; } @@ -300,70 +298,6 @@ namespace bin2cpp return output; } - std::string BaseGenerator::getFileObjectGetFileNameImplementation() - { - std::string output; - - std::string inputFileName = ra::filesystem::GetFilename(mContext.inputFilePath.c_str()); - - //could we report getFileName() as a substring of getFilePath() ? - const char * reported_path = mContext.reportedFilePath.c_str(); - if (reported_path != NULL && reported_path[0] != '\0') - { - size_t offset = mContext.reportedFilePath.find(inputFileName); - if (offset != std::string::npos) - { - output = "return &getFilePath()["; - output += ra::strings::ToString(offset); - output += "];"; - return output; - } - } - - //return default implementation - output = "return \""; - output += inputFileName; - output += "\";"; - return output; - } - - std::string BaseGenerator::getFileObjectGetFilePathImplementation() - { - std::string output; - - //convert mReportedFilePath string to c++ - std::string path = mContext.reportedFilePath; -#ifdef _WIN32 - //escape backslash characters for c++ - static const std::string BACKSLASH = "\\"; - static const std::string BACKSLASH_ESCAPED = "\\\\"; - ra::strings::Replace(path, BACKSLASH, BACKSLASH_ESCAPED); -#endif - - //is there a reported path specified ? - const char * reported_path = mContext.reportedFilePath.c_str(); - if (reported_path != NULL && reported_path[0] != '\0') - { - output = "return \""; - output += path; - output += "\";"; - return output; - } - else - { - //if reported path is not specified ? - //report the same as getFileName() - output = "return getFileName();"; - return output; - } - - //return default implementation - output = "return \""; - output += path; - output += "\";"; - return output; - } - std::string BaseGenerator::getFileObjectFileName() { std::string output; diff --git a/src/bin2cpp/BaseGenerator.h b/src/bin2cpp/BaseGenerator.h index ac05295..ba9ae4c 100644 --- a/src/bin2cpp/BaseGenerator.h +++ b/src/bin2cpp/BaseGenerator.h @@ -69,8 +69,6 @@ namespace bin2cpp virtual std::string getClassName(); virtual std::string getClassMacroGuardPrefix(); virtual std::string getFileManagerMacroGuardPrefix(); - virtual std::string getFileObjectGetFileNameImplementation(); - virtual std::string getFileObjectGetFilePathImplementation(); virtual std::string getFileObjectFileName(); virtual std::string getFileObjectFilePath(); virtual std::string getHeaderFileIncludePath(); diff --git a/src/bin2cpp/SegmentGenerator.cpp b/src/bin2cpp/SegmentGenerator.cpp index f600daa..d01f52f 100755 --- a/src/bin2cpp/SegmentGenerator.cpp +++ b/src/bin2cpp/SegmentGenerator.cpp @@ -71,8 +71,8 @@ namespace bin2cpp " ${bin2cpp_classname}() { build(); }\n" " virtual ~${bin2cpp_classname}() {}\n" " virtual size_t getSize() const { return ${bin2cpp_input_file_size}; }\n" - " virtual const char * getFileName() const { ${bin2cpp_file_object_file_name_impl} }\n" - " virtual const char * getFilePath() const { ${bin2cpp_file_object_file_path_impl} }\n" + " virtual const char * getFileName() const { return \"${bin2cpp_file_object_file_name}\"; }\n" + " virtual const char * getFilePath() const { return \"${bin2cpp_file_object_file_path}\"; }\n" " virtual const char * getBuffer() const { return mBuffer.c_str(); }\n" " void build()\n" " {\n" diff --git a/src/bin2cpp/StringGenerator.cpp b/src/bin2cpp/StringGenerator.cpp index ae79ea4..214609b 100755 --- a/src/bin2cpp/StringGenerator.cpp +++ b/src/bin2cpp/StringGenerator.cpp @@ -67,8 +67,8 @@ namespace bin2cpp " ${bin2cpp_classname}() {}\n" " virtual ~${bin2cpp_classname}() {}\n" " virtual size_t getSize() const { return ${bin2cpp_input_file_size}; }\n" - " virtual const char * getFileName() const { ${bin2cpp_file_object_file_name_impl} }\n" - " virtual const char * getFilePath() const { ${bin2cpp_file_object_file_path_impl} }\n" + " virtual const char * getFileName() const { return \"${bin2cpp_file_object_file_name}\"; }\n" + " virtual const char * getFilePath() const { return \"${bin2cpp_file_object_file_path}\"; }\n" " virtual const char * getBuffer() const\n" " {\n" " const char * buffer = \n${bin2cpp_insert_input_file_as_code}" // INPUT FILE AS CODE HERE diff --git a/src/bin2cpp/Win32ResourceGenerator.cpp b/src/bin2cpp/Win32ResourceGenerator.cpp index eb78b45..df15057 100755 --- a/src/bin2cpp/Win32ResourceGenerator.cpp +++ b/src/bin2cpp/Win32ResourceGenerator.cpp @@ -98,8 +98,8 @@ namespace bin2cpp " }\n" " virtual ~${bin2cpp_classname}() { unloadResource(); }\n" " virtual size_t getSize() const { return mBufferSize; }\n" - " virtual const char * getFileName() const { ${bin2cpp_file_object_file_name_impl} }\n" - " virtual const char * getFilePath() const { ${bin2cpp_file_object_file_path_impl} }\n" + " virtual const char * getFileName() const { return \"${bin2cpp_file_object_file_name}\"; }\n" + " virtual const char * getFilePath() const { return \"${bin2cpp_file_object_file_path}\"; }\n" " virtual const char * getBuffer() const { return mBuffer; }\n" " void loadResource()\n" " {\n" diff --git a/src/bin2cpp/bin2cpp.samples.txt b/src/bin2cpp/bin2cpp.samples.txt index 16adca3..9c4dd9f 100644 --- a/src/bin2cpp/bin2cpp.samples.txt +++ b/src/bin2cpp/bin2cpp.samples.txt @@ -9,10 +9,10 @@ Test all generators: --file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\test\bin2cpp_unittest\generated_files\testHtml100000 --headerfile=_testHtml100000_C.h --override --code=c --generator=win32 Test as much features as possible with all generators: ---file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_tim_testHtml100000_array.h --identifier=LibFooFOO --chunksize=75 --baseclass=ben --namespace=ray --managerfile=c_tim_filemanager.h --registerfile --override --code=c --generator=array ---file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_jim_testHtml100000_segment.h --identifier=LibBarBAR --chunksize=75 --baseclass=tom --namespace=eva --managerfile=c_jim_filemanager.h --registerfile --override --code=c --generator=segment ---file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_lou_testHtml100000_string.h --identifier=LibBazBAZ --chunksize=75 --baseclass=sam --namespace=joe --managerfile=c_lou_filemanager.h --registerfile --override --code=c --generator=string ---file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_sue_testHtml100000_win32.h --identifier=LibBobBOB --chunksize=75 --baseclass=leo --namespace=jon --managerfile=c_sue_filemanager.h --registerfile --override --code=c --generator=win32 +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_tim_testHtml100000_array.h --identifier=LibFooFOO --chunksize=75 --baseclass=ben --namespace=ray --managerfile=c_tim_filemanager.h --registerfile --reportedfilepath=virtual/folder/testHtml100000.bin --override --code=c --generator=array +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_jim_testHtml100000_segment.h --identifier=LibBarBAR --chunksize=75 --baseclass=tom --namespace=eva --managerfile=c_jim_filemanager.h --registerfile --reportedfilepath=virtual/folder/testHtml100000.bin --override --code=c --generator=segment +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_lou_testHtml100000_string.h --identifier=LibBazBAZ --chunksize=75 --baseclass=sam --namespace=joe --managerfile=c_lou_filemanager.h --registerfile --reportedfilepath=virtual/folder/testHtml100000.bin --override --code=c --generator=string +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=c_sue_testHtml100000_win32.h --identifier=LibBobBOB --chunksize=75 --baseclass=leo --namespace=jon --managerfile=c_sue_filemanager.h --registerfile --reportedfilepath=virtual/folder/testHtml100000.bin --override --code=c --generator=win32 Test for: * Segment C generator @@ -51,10 +51,10 @@ Compare all generators: --file=..\..\test\bin2cpp_unittest\generated_files\testGeneratorSegment10000\testGeneratorSegment10000.bin --output=..\..\temp --headerfile=cpp_sue_testHtml100000_win32.h --identifier=LibWin32 --chunksize=75 --registerfile --override --generator=win32 Test as much features as possible with all generators: ---file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_tim_testHtml100000_array.h --identifier=LibFooFOO --chunksize=75 --baseclass=ben --namespace=ray --managerfile=cpp_tim_filemanager.h --registerfile --override --code=cpp --generator=array ---file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_jim_testHtml100000_segment.h --identifier=LibBarBAR --chunksize=75 --baseclass=tom --namespace=eva --managerfile=cpp_jim_filemanager.h --registerfile --override --code=cpp --generator=segment ---file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_lou_testHtml100000_string.h --identifier=LibBazBAZ --chunksize=75 --baseclass=sam --namespace=joe --managerfile=cpp_lou_filemanager.h --registerfile --override --code=cpp --generator=string ---file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_sue_testHtml100000_win32.h --identifier=LibBobBOB --chunksize=75 --baseclass=leo --namespace=jon --managerfile=cpp_sue_filemanager.h --registerfile --override --code=cpp --generator=win32 +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_tim_testHtml100000_array.h --identifier=LibFooFOO --chunksize=75 --baseclass=ben --namespace=ray --managerfile=cpp_tim_filemanager.h --registerfile --reportedfilepath=virtual/folder/testHtml100000.bin --override --code=cpp --generator=array +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_jim_testHtml100000_segment.h --identifier=LibBarBAR --chunksize=75 --baseclass=tom --namespace=eva --managerfile=cpp_jim_filemanager.h --registerfile --reportedfilepath=virtual/folder/testHtml100000.bin --override --code=cpp --generator=segment +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_lou_testHtml100000_string.h --identifier=LibBazBAZ --chunksize=75 --baseclass=sam --namespace=joe --managerfile=cpp_lou_filemanager.h --registerfile --reportedfilepath=virtual/folder/testHtml100000.bin --override --code=cpp --generator=string +--file=..\..\test\bin2cpp_unittest\generated_files\testHtml100000\testHtml100000.bin --output=..\..\temp --headerfile=cpp_sue_testHtml100000_win32.h --identifier=LibBobBOB --chunksize=75 --baseclass=leo --namespace=jon --managerfile=cpp_sue_filemanager.h --registerfile --reportedfilepath=virtual/folder/testHtml100000.bin --override --code=cpp --generator=win32 Test plain output: --plainoutput --chunksize=75 --file=..\..\test\bin2cpp_unittest\generated_files\testSequential1000\testSequential1000.bin --generator=array From 5671223f35c57b2dde26d8fded0d675a1a7f89cd Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sun, 1 Jun 2025 15:31:08 -0400 Subject: [PATCH 26/26] * Fixed issue #77: Refactor generating code to use full file templates with markers. --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 892bec6..be92adb 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,7 @@ Changes for 3.1.0: * Fixed issue #64: Remove build artifacts of samples from installation packages. * Fixed issue #72: Move the code FileManager class generation code into its own IGenerator implementation. * Fixed issue #74: Invalid generated output file name: index.cpptml.cpp. +* Fixed issue #77: Refactor generating code to use full file templates with markers. Changes for 3.0.1: