From 306271563d3c09bf840d81c6c219a0cb592056dc Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sat, 26 Apr 2025 10:46:20 -0400 Subject: [PATCH 1/9] First draft for the Context class. --- src/bin2cpp/CMakeLists.txt | 2 + src/bin2cpp/Context.cpp | 218 +++++++++++++++++++++++++++++++++++++ src/bin2cpp/Context.h | 115 +++++++++++++++++++ 3 files changed, 335 insertions(+) create mode 100644 src/bin2cpp/Context.cpp create mode 100644 src/bin2cpp/Context.h diff --git a/src/bin2cpp/CMakeLists.txt b/src/bin2cpp/CMakeLists.txt index d3689e1..fcf443e 100644 --- a/src/bin2cpp/CMakeLists.txt +++ b/src/bin2cpp/CMakeLists.txt @@ -15,6 +15,8 @@ add_executable(bin2cpp bin2cpp.samples.txt common.cpp common.h + Context.cpp + Context.h crc32.cpp crc32.h IGenerator.h diff --git a/src/bin2cpp/Context.cpp b/src/bin2cpp/Context.cpp new file mode 100644 index 0000000..2358cc1 --- /dev/null +++ b/src/bin2cpp/Context.cpp @@ -0,0 +1,218 @@ +/********************************************************************************** + * 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 "Context.h" + +namespace bin2cpp +{ + Context::Context() + { + reset(); + } + + Context::~Context() + { + } + + void Context::reset() + { + mHasInputFile = false; + mHasInputDir = false; + mHasOutputDir = false; + mHasReportedFilePath = false; + mHasManagerFile = false; + mChunkSize = 0; + mCppEncoder = IGenerator::CppEncoderEnum::CPP_ENCODER_HEX; + + memset(mFlags, 0, sizeof(mFlags)); + } + + bool Context::hasInputFileSet() const + { + return mHasInputFile; + } + + bool Context::hasInputDirSet() const + { + return mHasInputDir; + } + + bool Context::hasOutputDirSet() const + { + return mHasOutputDir; + } + + bool Context::hasReportedFilePath() const + { + return mHasReportedFilePath; + } + + void Context::setFlag(const Flags& flag, bool value) + { + if ( flag > 0 && flag < FLAG_COUNT ) + mFlags[flag] = value; + } + + bool Context::isFlagSet(const Flags& flag) const + { + if ( flag > 0 && flag < FLAG_COUNT ) + return mFlags[flag]; + return false; + } + + void Context::setInputFilePath(const char* path) + { + if ( path ) + { + mInputFilePath = path; + mHasInputFile = true; + } + } + + const std::string & Context::getInputFilePath() const + { + return mInputFilePath; + } + + void Context::setInputDirPath(const char* path) + { + if ( path ) + { + mInputDirPath = path; + mHasInputDir = true; + } + } + + const std::string & Context::getInputDirPath() const + { + return mInputDirPath; + } + + void Context::setOutputDirPath(const char* path) + { + if ( path ) + { + mOutputDirPath = path; + mHasOutputDir = true; + } + } + + const std::string & Context::getOutputDirPath() const + { + return mOutputDirPath; + } + + void Context::setHeaderFilename(const char* path) + { + if ( path ) + mHeaderFilename = path; + } + + const std::string & Context::getHeaderFilename() const + { + return mHeaderFilename; + } + + void Context::setFunctionIdentifier(const char* function_identifier) + { + if ( function_identifier ) + mFunctionIdentifier = function_identifier; + } + + const std::string & Context::getFunctionIdentifier() const + { + return mFunctionIdentifier; + } + + void Context::setReportedFilePath(const char* path) + { + if ( path ) + mReportedFilePath = path; + } + + const std::string & Context::getReportedFilePath() const + { + return mReportedFilePath; + } + + void Context::setChunkSize(size_t chunk_size) + { + mChunkSize = chunk_size; + } + + size_t Context::getChunkSize() const + { + return mChunkSize; + } + + void Context::setNamespace(const char* name) + { + if ( name ) + mNamespace = name; + } + + const std::string & Context::getNamespace() const + { + return mNamespace; + } + + void Context::setBaseClass(const char* name) + { + if ( name ) + mBaseClass = name; + } + + const std::string & Context::getBaseClass() const + { + return mBaseClass; + } + + void Context::setManagerHeaderFilename(const char* manager_file) + { + if ( manager_file ) + mManagerHeaderFilename = manager_file; + } + + const std::string & Context::getManagerHeaderFilename() const + { + return mManagerHeaderFilename; + } + + void Context::setCppEncoder(const IGenerator::CppEncoderEnum& cpp_encoder) + { + mCppEncoder = cpp_encoder; + } + + IGenerator::CppEncoderEnum Context::getCppEncoder() const + { + return mCppEncoder; + } + + + //------------------------------- + //protected methods + //------------------------------- + + +}; //bin2cpp \ No newline at end of file diff --git a/src/bin2cpp/Context.h b/src/bin2cpp/Context.h new file mode 100644 index 0000000..f749c27 --- /dev/null +++ b/src/bin2cpp/Context.h @@ -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. + *********************************************************************************/ + +#ifndef CONTEXT_H +#define CONTEXT_H + +#include +#include "IGenerator.h" + +namespace bin2cpp +{ + + /// + ///This is the command line context for generating code. + /// + class Context + { + public: + Context(); + virtual ~Context(); + + enum Flags + { + KEEP_DIRECTORY_STRUCTURE = 0, // true if the output files must have the same directory structure as the input files. Valid only when --dir is used. + PLAIN_OUTPUT, + OVERRIDE_EXISTING, + REGISTER_FILE, + + FLAG_COUNT + }; + + void reset(); + + bool hasInputFileSet() const; + bool hasInputDirSet() const; + bool hasOutputDirSet() const; + bool hasReportedFilePath() const; + bool hasManagerFile() const; + + void setFlag(const Flags & flag, bool value); + bool isFlagSet(const Flags& flag) const; + + void setInputFilePath(const char* path); + const std::string& getInputFilePath() const; + void setInputDirPath(const char* path); + const std::string& getInputDirPath() const; + void setOutputDirPath(const char* path); + const std::string& getOutputDirPath() const; + void setHeaderFilename(const char* path); + const std::string& getHeaderFilename() const; + void setFunctionIdentifier(const char* function_identifier); + const std::string& getFunctionIdentifier() const; + void setReportedFilePath(const char* path); + const std::string& getReportedFilePath() const; + void setChunkSize(size_t chunk_size); + size_t getChunkSize() const; + void setNamespace(const char* name); + const std::string& getNamespace() const; + void setBaseClass(const char* name); + const std::string& getBaseClass() const; + void setManagerHeaderFilename(const char* manager_file); + const std::string& getManagerHeaderFilename() const; + void setCppEncoder(const IGenerator::CppEncoderEnum& cpp_encoder); + IGenerator::CppEncoderEnum getCppEncoder() const; + + + protected: + + //attributes + bool mHasInputFile; // true if 'mInputFilePath' is set. + bool mHasInputDir; // true if 'mInputDirPath' is set. + bool mHasOutputDir; // true if 'mOutputDirPath' is set. + bool mHasReportedFilePath; // true if 'mReportedFilePath' is set. + bool mHasManagerFile; // true if 'mManagerHeaderFilename' is set. + + bool mFlags[Flags::FLAG_COUNT]; + + std::string mInputFilePath; // path of the input binary file + std::string mInputDirPath; + std::string mOutputDirPath; + std::string mHeaderFilename; + std::string mFunctionIdentifier; + std::string mReportedFilePath; // path reported in the public api when calling getFilePath(); + size_t mChunkSize; + std::string mNamespace; + std::string mBaseClass; + std::string mManagerHeaderFilename; + IGenerator::CppEncoderEnum mCppEncoder; + std::string mGeneratorName; + }; + +}; //bin2cpp + +#endif //BASEGENERATOR_H From 3372492b67ec842ddbed0123615a9d8c15ee12e2 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sat, 26 Apr 2025 12:20:40 -0400 Subject: [PATCH 2/9] Created enums.h file. --- src/bin2cpp/CMakeLists.txt | 1 + src/bin2cpp/enums.h | 46 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 src/bin2cpp/enums.h diff --git a/src/bin2cpp/CMakeLists.txt b/src/bin2cpp/CMakeLists.txt index fcf443e..fa15db7 100644 --- a/src/bin2cpp/CMakeLists.txt +++ b/src/bin2cpp/CMakeLists.txt @@ -19,6 +19,7 @@ add_executable(bin2cpp Context.h crc32.cpp crc32.h + enums.h IGenerator.h main.cpp SegmentGenerator.cpp diff --git a/src/bin2cpp/enums.h b/src/bin2cpp/enums.h new file mode 100644 index 0000000..a5398aa --- /dev/null +++ b/src/bin2cpp/enums.h @@ -0,0 +1,46 @@ +/********************************************************************************** + * 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 ENUMS_H +#define ENUMS_H + +#include +#include "Context.h" + +namespace bin2cpp +{ + + /// + ///Defines the different type of cpp encoding. + ///See setCppEncoder() and getCppEncoder() functions. + /// + enum CppEncoderEnum + { + CPP_ENCODER_OCT, + CPP_ENCODER_HEX, + }; + +}; //bin2cpp + +#endif //IGENERATOR_H From 2e1afb5b573976068b6909e1a212607bcedbd827 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sat, 26 Apr 2025 12:29:54 -0400 Subject: [PATCH 3/9] Created Context class for holding generation parameters. Moved from a inherited methods in the BaseGenerator design (inheritance) to a composition design where the Context is given to the generator. --- src/bin2cpp/ArrayGenerator.cpp | 32 ++-- src/bin2cpp/BaseGenerator.cpp | 177 ++++-------------- src/bin2cpp/BaseGenerator.h | 33 +--- src/bin2cpp/Context.cpp | 215 +++++---------------- src/bin2cpp/Context.h | 90 +++------ src/bin2cpp/IGenerator.h | 137 +------------- src/bin2cpp/SegmentGenerator.cpp | 30 +-- src/bin2cpp/StringGenerator.cpp | 30 +-- src/bin2cpp/Win32ResourceGenerator.cpp | 24 +-- src/bin2cpp/main.cpp | 248 +++++++++++-------------- 10 files changed, 293 insertions(+), 723 deletions(-) diff --git a/src/bin2cpp/ArrayGenerator.cpp b/src/bin2cpp/ArrayGenerator.cpp index c585552..0ed05f0 100644 --- a/src/bin2cpp/ArrayGenerator.cpp +++ b/src/bin2cpp/ArrayGenerator.cpp @@ -50,12 +50,12 @@ namespace bin2cpp bool ArrayGenerator::createCppSourceFile(const char * cpp_file_path) { //check if input file exists - FILE * input = fopen(getInputFilePath(), "rb"); + FILE * input = fopen(mContext.inputFilePath.c_str(), "rb"); if (!input) return false; //Uppercase function identifier - std::string functionIdentifier = ra::strings::CapitalizeFirstCharacter(mFunctionIdentifier); + std::string functionIdentifier = ra::strings::CapitalizeFirstCharacter(getContext().functionIdentifier); //Build header and cpp file path std::string headerPath = getHeaderFilePath(cpp_file_path); @@ -71,7 +71,7 @@ namespace bin2cpp //determine file properties uint32_t fileSize = ra::filesystem::GetFileSize(input); - std::string filename = ra::filesystem::GetFilename(getInputFilePath()); + std::string filename = ra::filesystem::GetFilename(mContext.inputFilePath.c_str()); //Build class name std::string className = getClassName(); @@ -81,12 +81,12 @@ namespace bin2cpp //write cpp file heading fprintf(cpp, "%s", getHeaderTemplate().c_str()); - fprintf(cpp, "#include \"%s\"\n", getHeaderFilename() ); + fprintf(cpp, "#include \"%s\"\n", mContext.headerFilename.c_str() ); fprintf(cpp, "#include \n"); fprintf(cpp, "#include //for ofstream\n"); - fprintf(cpp, "namespace %s\n", mNamespace.c_str()); + fprintf(cpp, "namespace %s\n", getContext().codeNamespace.c_str()); fprintf(cpp, "{\n"); - fprintf(cpp, " class %s : public virtual %s::%s\n", className.c_str(), mNamespace.c_str(), mBaseClass.c_str()); + 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()); @@ -100,13 +100,13 @@ namespace bin2cpp //create buffer for each chunks from input buffer int numLinePrinted = 0; - unsigned char * buffer = new unsigned char[mChunkSize]; + unsigned char * buffer = new unsigned char[getContext().chunkSize]; while(!feof(input)) { //read a chunk of the file - size_t readSize = fread(buffer, 1, mChunkSize, input); + size_t readSize = fread(buffer, 1, getContext().chunkSize, input); - bool isLastChunk = !(readSize == mChunkSize); + bool isLastChunk = !(readSize == getContext().chunkSize); if (readSize > 0) { @@ -136,13 +136,13 @@ namespace bin2cpp fprintf(cpp, " }\n"); fprintf(cpp, "%s", getSaveMethodTemplate().c_str()); fprintf(cpp, " };\n"); - fprintf(cpp, " const %s & %s() { static %s _instance; return _instance; }\n", mBaseClass.c_str(), getterFunctionName.c_str(), className.c_str()); - if (isRegisterFileEnabled()) + 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 = getFileManagerRegistrationTemplate(); fprintf(cpp, "%s", fileManagerTemplate.c_str()); } - fprintf(cpp, "}; //%s\n", mNamespace.c_str()); + fprintf(cpp, "}; //%s\n", getContext().codeNamespace.c_str()); fclose(input); fclose(cpp); @@ -153,7 +153,7 @@ namespace bin2cpp bool ArrayGenerator::printFileContent() { //check if input file exists - FILE * input = fopen(getInputFilePath(), "rb"); + FILE * input = fopen(mContext.inputFilePath.c_str(), "rb"); if (!input) return false; @@ -162,13 +162,13 @@ namespace bin2cpp //create buffer for each chunks from input buffer int numLinePrinted = 0; - unsigned char * buffer = new unsigned char[mChunkSize]; + unsigned char * buffer = new unsigned char[getContext().chunkSize]; while(!feof(input)) { //read a chunk of the file - size_t readSize = fread(buffer, 1, mChunkSize, input); + size_t readSize = fread(buffer, 1, getContext().chunkSize, input); - bool isLastChunk = !(readSize == mChunkSize); + bool isLastChunk = !(readSize == getContext().chunkSize); if (readSize > 0) { diff --git a/src/bin2cpp/BaseGenerator.cpp b/src/bin2cpp/BaseGenerator.cpp index f477ccf..aff0295 100755 --- a/src/bin2cpp/BaseGenerator.cpp +++ b/src/bin2cpp/BaseGenerator.cpp @@ -37,9 +37,7 @@ namespace bin2cpp { - BaseGenerator::BaseGenerator() : - mCppEncoder(IGenerator::CPP_ENCODER_OCT), - mManagerEnabled(false) + BaseGenerator::BaseGenerator() { } @@ -47,111 +45,14 @@ namespace bin2cpp { } - void BaseGenerator::setInputFilePath(const char * path) + void BaseGenerator::setContext(const Context& c) { - if (path) - mInputFilePath = path; + mContext = c; } - const char * BaseGenerator::getInputFilePath() const + const Context& BaseGenerator::getContext() const { - return mInputFilePath.c_str(); - } - - void BaseGenerator::setHeaderFilename(const char * path) - { - if (path) - mHeaderFilename = path; - } - - const char * BaseGenerator::getHeaderFilename() const - { - return mHeaderFilename.c_str(); - } - - void BaseGenerator::setFunctionIdentifier(const char * function_identifier) - { - if (function_identifier) - mFunctionIdentifier = function_identifier; - } - - const char * BaseGenerator::getFunctionIdentifier() const - { - return mFunctionIdentifier.c_str(); - } - - void BaseGenerator::setReportedFilePath(const char * path) - { - if (path) - mReportedFilePath = path; - } - - const char * BaseGenerator::getReportedFilePath() const - { - return mReportedFilePath.c_str(); - } - - void BaseGenerator::setChunkSize(size_t chunk_size) - { - mChunkSize = chunk_size; - } - - size_t BaseGenerator::getChunkSize() const - { - return mChunkSize; - } - - void BaseGenerator::setNamespace(const char * name) - { - if (name) - mNamespace = name; - } - - const char * BaseGenerator::getNamespace() const - { - return mNamespace.c_str(); - } - - void BaseGenerator::setBaseClass(const char * name) - { - if (name) - mBaseClass = name; - } - - const char * BaseGenerator::getBaseClass() const - { - return mBaseClass.c_str(); - } - - void BaseGenerator::setCppEncoder(const IGenerator::CppEncoderEnum & cpp_encoder) - { - mCppEncoder = cpp_encoder; - } - - IGenerator::CppEncoderEnum BaseGenerator::getCppEncoder() const - { - return mCppEncoder; - } - - void BaseGenerator::setManagerHeaderFilename(const char * manager_file) - { - if (manager_file) - mManagerHeaderFilename = manager_file; - } - - const char * BaseGenerator::getManagerHeaderFilename() const - { - return mManagerHeaderFilename.c_str(); - } - - void BaseGenerator::setRegisterFileEnabled(bool register_file_enabled) - { - mManagerEnabled = register_file_enabled; - } - - bool BaseGenerator::isRegisterFileEnabled() const - { - return mManagerEnabled; + return mContext; } //------------------------------- @@ -161,7 +62,7 @@ namespace bin2cpp std::string BaseGenerator::getGetterFunctionName() { //Uppercase function identifier - std::string functionIdentifier = ra::strings::CapitalizeFirstCharacter(mFunctionIdentifier); + std::string functionIdentifier = ra::strings::CapitalizeFirstCharacter(mContext.functionIdentifier); std::string getter; getter.append("get"); @@ -201,8 +102,8 @@ namespace bin2cpp header << " * bin2cpp is open source software, see http://github.com/end2endzone/bin2cpp\n"; if (include_source_file) { - std::string filename = ra::filesystem::GetFilename(mInputFilePath.c_str()); - uint64_t lastModifiedDate = ra::filesystem::GetFileModifiedDate(mInputFilePath); + std::string filename = ra::filesystem::GetFilename(mContext.inputFilePath.c_str()); + uint64_t lastModifiedDate = ra::filesystem::GetFileModifiedDate(mContext.inputFilePath); header << " * Source code for file '" << filename << "', last modified " << lastModifiedDate << ".\n"; } header << " * Do not modify this file.\n"; @@ -228,22 +129,22 @@ namespace bin2cpp std::string BaseGenerator::getFileManagerRegistrationTemplate() { - if (!this->isRegisterFileEnabled()) + if (!mContext.registerFiles) return std::string(); //Build class name std::string className = getClassName(); std::string output; - output << " typedef const " << mBaseClass << " & (*t_func)();\n"; + output << " typedef const " << mContext.baseClass << " & (*t_func)();\n"; output << " extern bool RegisterFile(t_func iFunctionPointer);\n"; - output << " static bool k" << className << "Registered = " << mNamespace << "::RegisterFile(&" << getGetterFunctionName() << ");\n"; + output << " static bool k" << className << "Registered = " << mContext.codeNamespace << "::RegisterFile(&" << getGetterFunctionName() << ");\n"; return output; } std::string BaseGenerator::getClassName() { - std::string functionIdentifier = ra::strings::CapitalizeFirstCharacter(mFunctionIdentifier); + std::string functionIdentifier = ra::strings::CapitalizeFirstCharacter(mContext.functionIdentifier); std::string className; className.append(functionIdentifier.c_str()); className.append("File"); @@ -252,7 +153,7 @@ namespace bin2cpp std::string BaseGenerator::getClassMacroGuardPrefix() { - std::string macroGuardPrefix = ra::strings::Uppercase(mNamespace); + std::string macroGuardPrefix = ra::strings::Uppercase(mContext.codeNamespace); //remove namespace separators ra::strings::Replace(macroGuardPrefix, "::", "_"); @@ -264,13 +165,13 @@ namespace bin2cpp { std::string output; - std::string inputFileName = ra::filesystem::GetFilename(getInputFilePath()); + std::string inputFileName = ra::filesystem::GetFilename(mContext.inputFilePath.c_str()); //could we report getFileName() as a substring of getFilePath() ? - const char * reported_path = getReportedFilePath(); + const char * reported_path = mContext.reportedFilePath.c_str(); if (reported_path != NULL && reported_path[0] != '\0') { - size_t offset = mReportedFilePath.find(inputFileName); + size_t offset = mContext.reportedFilePath.find(inputFileName); if (offset != std::string::npos) { output = "return &getFilePath()["; @@ -292,7 +193,7 @@ namespace bin2cpp std::string output; //convert mReportedFilePath string to c++ - std::string path = mReportedFilePath; + std::string path = mContext.reportedFilePath; #ifdef _WIN32 //escape backslash characters for c++ static const std::string BACKSLASH = "\\"; @@ -301,7 +202,7 @@ namespace bin2cpp #endif //is there a reported path specified ? - const char * reported_path = getReportedFilePath(); + const char * reported_path = mContext.reportedFilePath.c_str(); if (reported_path != NULL && reported_path[0] != '\0') { output = "return \""; @@ -342,11 +243,11 @@ namespace bin2cpp fprintf(header, "\n"); fprintf(header, "#include \n"); fprintf(header, "\n"); - fprintf(header, "namespace %s\n", mNamespace.c_str()); + 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", mBaseClass.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"); @@ -357,8 +258,8 @@ namespace bin2cpp 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", mBaseClass.c_str(), getGetterFunctionName().c_str()); - fprintf(header, "}; //%s\n", mNamespace.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()); @@ -375,7 +276,7 @@ namespace bin2cpp //define macro guard a macro matching the filename std::string macroGuard; - macroGuard += getCppIncludeGuardMacroName(mNamespace.c_str()); //prefix the custom namespace for the file manager + macroGuard += getCppIncludeGuardMacroName(mContext.codeNamespace.c_str()); //prefix the custom namespace for the file manager if (!macroGuard.empty()) macroGuard += "_"; macroGuard += getCppIncludeGuardMacroName(header_file_path); @@ -390,11 +291,11 @@ namespace bin2cpp fprintf(header, "#include \n"); fprintf(header, "#include \n"); fprintf(header, "\n"); - fprintf(header, "namespace %s\n", mNamespace.c_str()); + 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", mBaseClass.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"); @@ -414,11 +315,11 @@ namespace bin2cpp fprintf(header, " FileManager();\n"); fprintf(header, " ~FileManager();\n"); fprintf(header, " public:\n"); - fprintf(header, " typedef const %s & (*t_func)();\n", mBaseClass.c_str()); + 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", mBaseClass.c_str()); + 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"); @@ -426,7 +327,7 @@ namespace bin2cpp fprintf(header, " std::vector functions_;\n"); fprintf(header, " };\n"); fprintf(header, " #endif //%s_FILEMANAGER_CLASS\n", classMacroGuardPrefix.c_str()); - fprintf(header, "}; //%s\n", mNamespace.c_str()); + fprintf(header, "}; //%s\n", mContext.codeNamespace.c_str()); fprintf(header, "\n"); fprintf(header, "#endif //%s\n", macroGuard.c_str()); @@ -448,7 +349,7 @@ namespace bin2cpp std::string fileHeader = getHeaderTemplate(false); fprintf(cpp, "%s", fileHeader.c_str()); - fprintf(cpp, "#include \"%s\"\n", getManagerHeaderFilename()); + fprintf(cpp, "#include \"%s\"\n", mContext.managerHeaderFilename.c_str()); fprintf(cpp, "#include \n"); fprintf(cpp, "#include // strlen\n"); fprintf(cpp, "#include // stat\n"); @@ -469,7 +370,7 @@ namespace bin2cpp fprintf(cpp, "#define PATH_SEPARATOR_STR \"/\"\n"); fprintf(cpp, "#endif\n"); fprintf(cpp, "\n"); - fprintf(cpp, "namespace %s\n", mNamespace.c_str()); + fprintf(cpp, "namespace %s\n", mContext.codeNamespace.c_str()); fprintf(cpp, "{\n"); fprintf(cpp, " bool RegisterFile(FileManager::t_func functionPointer)\n"); fprintf(cpp, " {\n"); @@ -488,7 +389,7 @@ namespace bin2cpp 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", mNamespace.c_str()); + 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"); @@ -554,7 +455,7 @@ namespace bin2cpp fprintf(cpp, " path_copy.append(1,PATH_SEPARATOR_CHAR);\n"); fprintf(cpp, " return createParentDirectories(path_copy.c_str());\n"); fprintf(cpp, " }\n"); - fprintf(cpp, "}; //%s\n", mNamespace.c_str()); + fprintf(cpp, "}; //%s\n", mContext.codeNamespace.c_str()); fclose(cpp); @@ -564,7 +465,7 @@ namespace bin2cpp bool BaseGenerator::printFileContent() { //check if input file exists - FILE * input = fopen(getInputFilePath(), "rb"); + FILE * input = fopen(mContext.inputFilePath.c_str(), "rb"); if (!input) return false; @@ -573,13 +474,13 @@ namespace bin2cpp //create buffer for each chunks from input buffer int numLinePrinted = 0; - unsigned char * buffer = new unsigned char[mChunkSize]; + unsigned char * buffer = new unsigned char[mContext.chunkSize]; while(!feof(input)) { //read a chunk of the file - size_t readSize = fread(buffer, 1, mChunkSize, input); + size_t readSize = fread(buffer, 1, mContext.chunkSize, input); - bool isLastChunk = !(readSize == mChunkSize); + bool isLastChunk = !(readSize == mContext.chunkSize); if (readSize > 0) { @@ -591,12 +492,12 @@ namespace bin2cpp //output std::string text; - switch(mCppEncoder) + switch(mContext.cppEncoder) { - case IGenerator::CPP_ENCODER_HEX: + case CPP_ENCODER_HEX: text = ra::code::cpp::ToHexString(buffer, readSize); break; - case IGenerator::CPP_ENCODER_OCT: + case CPP_ENCODER_OCT: default: text = ra::code::cpp::ToOctString(buffer, readSize, false); break; diff --git a/src/bin2cpp/BaseGenerator.h b/src/bin2cpp/BaseGenerator.h index 33db9cd..12ad081 100644 --- a/src/bin2cpp/BaseGenerator.h +++ b/src/bin2cpp/BaseGenerator.h @@ -40,26 +40,8 @@ namespace bin2cpp virtual ~BaseGenerator(); //IGenerator methods - virtual void setInputFilePath(const char * path); - virtual const char * getInputFilePath() const; - virtual void setHeaderFilename(const char * path); - virtual const char * getHeaderFilename() const; - virtual void setFunctionIdentifier(const char * function_identifier); - virtual const char * getFunctionIdentifier() const; - virtual void setReportedFilePath(const char * path); - virtual const char * getReportedFilePath() const; - virtual void setChunkSize(size_t chunk_size); - virtual size_t getChunkSize() const; - virtual void setNamespace(const char * name); - virtual const char * getNamespace() const; - virtual void setBaseClass(const char * name); - virtual const char * getBaseClass() const; - virtual void setCppEncoder(const CppEncoderEnum & cpp_encoder); - virtual CppEncoderEnum getCppEncoder() const; - virtual void setManagerHeaderFilename(const char * manager_file); - virtual const char * getManagerHeaderFilename() const; - virtual void setRegisterFileEnabled(bool register_file_enabled); - virtual bool isRegisterFileEnabled() const; + virtual void setContext(const Context& c); + virtual const Context & getContext() const; //same header file for all generators virtual bool createCppHeaderFile(const char * header_file_path); @@ -82,16 +64,7 @@ namespace bin2cpp virtual std::string getImplOfGetFilePath(); //attributes - std::string mInputFilePath; - std::string mHeaderFilename; - std::string mReportedFilePath; - std::string mFunctionIdentifier; - size_t mChunkSize; - std::string mNamespace; - std::string mBaseClass; - std::string mManagerHeaderFilename; - IGenerator::CppEncoderEnum mCppEncoder; - bool mManagerEnabled; + Context mContext; }; }; //bin2cpp diff --git a/src/bin2cpp/Context.cpp b/src/bin2cpp/Context.cpp index 2358cc1..ba8f69e 100644 --- a/src/bin2cpp/Context.cpp +++ b/src/bin2cpp/Context.cpp @@ -31,185 +31,70 @@ namespace bin2cpp reset(); } - Context::~Context() - { - } - - void Context::reset() - { - mHasInputFile = false; - mHasInputDir = false; - mHasOutputDir = false; - mHasReportedFilePath = false; - mHasManagerFile = false; - mChunkSize = 0; - mCppEncoder = IGenerator::CppEncoderEnum::CPP_ENCODER_HEX; - - memset(mFlags, 0, sizeof(mFlags)); - } - - bool Context::hasInputFileSet() const - { - return mHasInputFile; - } - - bool Context::hasInputDirSet() const - { - return mHasInputDir; - } - - bool Context::hasOutputDirSet() const - { - return mHasOutputDir; - } - - bool Context::hasReportedFilePath() const - { - return mHasReportedFilePath; - } - - void Context::setFlag(const Flags& flag, bool value) - { - if ( flag > 0 && flag < FLAG_COUNT ) - mFlags[flag] = value; - } - - bool Context::isFlagSet(const Flags& flag) const - { - if ( flag > 0 && flag < FLAG_COUNT ) - return mFlags[flag]; - return false; - } - - void Context::setInputFilePath(const char* path) - { - if ( path ) - { - mInputFilePath = path; - mHasInputFile = true; - } - } - - const std::string & Context::getInputFilePath() const - { - return mInputFilePath; - } - - void Context::setInputDirPath(const char* path) + Context::Context(const Context& other) { - if ( path ) - { - mInputDirPath = path; - mHasInputDir = true; - } + (*this) = other; } - const std::string & Context::getInputDirPath() const + Context::~Context() { - return mInputDirPath; } - void Context::setOutputDirPath(const char* path) + Context& Context::operator=(const Context& other) { - if ( path ) + if ( this != &other ) { - mOutputDirPath = path; - mHasOutputDir = true; + this->hasInputFile = other.hasInputFile ; + this->hasInputDir = other.hasInputDir ; + this->hasOutputDir = other.hasOutputDir ; + this->hasReportedFilePath = other.hasReportedFilePath ; + this->hasManagerFile = other.hasManagerFile ; + this->keepDirectoryStructure = other.keepDirectoryStructure ; + this->overrideExistingFiles = other.overrideExistingFiles ; + this->registerFiles = other.registerFiles ; + this->plainOutput = other.plainOutput ; + this->inputFilePath = other.inputFilePath ; + this->inputDirPath = other.inputDirPath ; + this->outputDirPath = other.outputDirPath ; + this->headerFilename = other.headerFilename ; + this->functionIdentifier = other.functionIdentifier ; + this->reportedFilePath = other.reportedFilePath ; + this->chunkSize = other.chunkSize ; + this->codeNamespace = other.codeNamespace ; + this->baseClass = other.baseClass ; + this->managerHeaderFilename = other.managerHeaderFilename ; + this->cppEncoder = other.cppEncoder ; + this->generatorName = other.generatorName ; } + return *this; } - const std::string & Context::getOutputDirPath() const - { - return mOutputDirPath; - } - - void Context::setHeaderFilename(const char* path) - { - if ( path ) - mHeaderFilename = path; - } - - const std::string & Context::getHeaderFilename() const - { - return mHeaderFilename; - } - - void Context::setFunctionIdentifier(const char* function_identifier) - { - if ( function_identifier ) - mFunctionIdentifier = function_identifier; - } - - const std::string & Context::getFunctionIdentifier() const - { - return mFunctionIdentifier; - } - - void Context::setReportedFilePath(const char* path) - { - if ( path ) - mReportedFilePath = path; - } - - const std::string & Context::getReportedFilePath() const - { - return mReportedFilePath; - } - - void Context::setChunkSize(size_t chunk_size) - { - mChunkSize = chunk_size; - } - - size_t Context::getChunkSize() const - { - return mChunkSize; - } - - void Context::setNamespace(const char* name) - { - if ( name ) - mNamespace = name; - } - - const std::string & Context::getNamespace() const - { - return mNamespace; - } - - void Context::setBaseClass(const char* name) - { - if ( name ) - mBaseClass = name; - } - - const std::string & Context::getBaseClass() const - { - return mBaseClass; - } - - void Context::setManagerHeaderFilename(const char* manager_file) - { - if ( manager_file ) - mManagerHeaderFilename = manager_file; - } - - const std::string & Context::getManagerHeaderFilename() const - { - return mManagerHeaderFilename; - } - - void Context::setCppEncoder(const IGenerator::CppEncoderEnum& cpp_encoder) - { - mCppEncoder = cpp_encoder; - } - - IGenerator::CppEncoderEnum Context::getCppEncoder() const + void Context::reset() { - return mCppEncoder; + hasInputFile = false; + hasInputDir = false; + hasOutputDir = false; + hasReportedFilePath = false; + hasManagerFile = false; + keepDirectoryStructure = false; + overrideExistingFiles = false; + registerFiles = false; + plainOutput = false; + + inputFilePath.clear(); + inputDirPath.clear(); + outputDirPath.clear(); + headerFilename.clear(); + functionIdentifier.clear(); + reportedFilePath.clear(); + chunkSize = 0; + codeNamespace.clear(); + baseClass.clear(); + managerHeaderFilename.clear(); + cppEncoder = CppEncoderEnum::CPP_ENCODER_HEX; + generatorName.clear(); } - //------------------------------- //protected methods //------------------------------- diff --git a/src/bin2cpp/Context.h b/src/bin2cpp/Context.h index f749c27..d17ac1b 100644 --- a/src/bin2cpp/Context.h +++ b/src/bin2cpp/Context.h @@ -26,7 +26,7 @@ #define CONTEXT_H #include -#include "IGenerator.h" +#include "enums.h" namespace bin2cpp { @@ -38,76 +38,42 @@ namespace bin2cpp { public: Context(); + Context(const Context & other); virtual ~Context(); - enum Flags - { - KEEP_DIRECTORY_STRUCTURE = 0, // true if the output files must have the same directory structure as the input files. Valid only when --dir is used. - PLAIN_OUTPUT, - OVERRIDE_EXISTING, - REGISTER_FILE, - - FLAG_COUNT - }; + Context& operator=(const Context& other); + + // flags + bool hasInputFile; // true if 'inputFilePath' is set. + bool hasInputDir; // true if 'inputDirPath' is set. + bool hasOutputDir; // true if 'outputDirPath' is set. + bool hasReportedFilePath; // true if 'reportedFilePath' is set. + bool hasManagerFile; // true if 'managerHeaderFilename' is set. + bool keepDirectoryStructure; // true if the output files must have the same directory structure as the input files. Valid only when --dir is used. + bool overrideExistingFiles; + bool registerFiles; + bool plainOutput; + + // public attributes + std::string inputFilePath; // The path of the input file (resource) to embeded as C++ source code. + std::string inputDirPath; + std::string outputDirPath; + std::string headerFilename; // The path of the input file (resource) to embeded as C++ source code. + std::string functionIdentifier; + std::string reportedFilePath; // path reported in the public api when calling getFilePath(); + size_t chunkSize; + std::string codeNamespace; + std::string baseClass; + std::string managerHeaderFilename; + CppEncoderEnum cppEncoder; + std::string generatorName; void reset(); - bool hasInputFileSet() const; - bool hasInputDirSet() const; - bool hasOutputDirSet() const; - bool hasReportedFilePath() const; - bool hasManagerFile() const; - - void setFlag(const Flags & flag, bool value); - bool isFlagSet(const Flags& flag) const; - - void setInputFilePath(const char* path); - const std::string& getInputFilePath() const; - void setInputDirPath(const char* path); - const std::string& getInputDirPath() const; - void setOutputDirPath(const char* path); - const std::string& getOutputDirPath() const; - void setHeaderFilename(const char* path); - const std::string& getHeaderFilename() const; - void setFunctionIdentifier(const char* function_identifier); - const std::string& getFunctionIdentifier() const; - void setReportedFilePath(const char* path); - const std::string& getReportedFilePath() const; - void setChunkSize(size_t chunk_size); - size_t getChunkSize() const; - void setNamespace(const char* name); - const std::string& getNamespace() const; - void setBaseClass(const char* name); - const std::string& getBaseClass() const; - void setManagerHeaderFilename(const char* manager_file); - const std::string& getManagerHeaderFilename() const; - void setCppEncoder(const IGenerator::CppEncoderEnum& cpp_encoder); - IGenerator::CppEncoderEnum getCppEncoder() const; - - protected: //attributes - bool mHasInputFile; // true if 'mInputFilePath' is set. - bool mHasInputDir; // true if 'mInputDirPath' is set. - bool mHasOutputDir; // true if 'mOutputDirPath' is set. - bool mHasReportedFilePath; // true if 'mReportedFilePath' is set. - bool mHasManagerFile; // true if 'mManagerHeaderFilename' is set. - - bool mFlags[Flags::FLAG_COUNT]; - std::string mInputFilePath; // path of the input binary file - std::string mInputDirPath; - std::string mOutputDirPath; - std::string mHeaderFilename; - std::string mFunctionIdentifier; - std::string mReportedFilePath; // path reported in the public api when calling getFilePath(); - size_t mChunkSize; - std::string mNamespace; - std::string mBaseClass; - std::string mManagerHeaderFilename; - IGenerator::CppEncoderEnum mCppEncoder; - std::string mGeneratorName; }; }; //bin2cpp diff --git a/src/bin2cpp/IGenerator.h b/src/bin2cpp/IGenerator.h index b99e22d..824c5bf 100644 --- a/src/bin2cpp/IGenerator.h +++ b/src/bin2cpp/IGenerator.h @@ -26,6 +26,7 @@ #define IGENERATOR_H #include +#include "Context.h" namespace bin2cpp { @@ -35,140 +36,16 @@ namespace bin2cpp public: /// - ///Get the name of the generator. + ///Sets the current context for the generator. /// - ///Returns the name of the generator - virtual const char * getName() const = 0; + ///The new context. + virtual void setContext(const Context& c) = 0; /// - ///Defines the path of the binary input file. + ///Get the current context set for the generator. /// - ///The path of the input file (resource) to embeded as C++ source code. - virtual void setInputFilePath(const char * path) = 0; - - /// - ///Provides the path of the binary input file. - /// - ///Returns the path of the binary input file. Returns an empty string if not defined. - virtual const char * getInputFilePath() const = 0; - - /// - ///Defines the filename of the generated header. - /// - ///The path of the input file (resource) to embeded as C++ source code. - virtual void setHeaderFilename(const char * path) = 0; - - /// - ///Provides the filename of the generated header. - /// - ///Returns the path of the binary input file. Returns an empty string if not defined. - virtual const char * getHeaderFilename() const = 0; - - /// - ///Defines the unique identifier name for the File class getter function. - /// - ///The unique identifier name for the File class getter function. - virtual void setFunctionIdentifier(const char * function_identifier) = 0; - - /// - ///Provides the unique identifier name for the File class getter function. - /// - ///Returns the unique identifier name for the File class getter function. Returns an empty string if not defined. - virtual const char * getFunctionIdentifier() const = 0; - - /// - ///Defines the path reported by the getFilePath() method of the File class. - /// - ///The path of the input file (resource) to embeded as C++ source code. - virtual void setReportedFilePath(const char * path) = 0; - - /// - ///Provides the path reported by the getFilePath() method of the File class. - /// - ///The path reported by the getFilePath() method of the File class. Returns an empty string if not defined. - virtual const char * getReportedFilePath() const = 0; - - /// - ///Defines the size in bytes of each chunk of data. - /// - ///The size in bytes of each chunk of data. - virtual void setChunkSize(size_t chunk_size) = 0; - - /// - ///Provides the size in bytes of each chunk of data. - /// - ///Returns the unique identifier name for the File class getter function. Returns an empty string if not defined. - virtual size_t getChunkSize() const = 0; - - /// - ///Defines the namespace of the generated code. - /// - ///The name of the namespace of the generated code. - virtual void setNamespace(const char * name) = 0; - - /// - ///Provides the namespace of the generated code. - /// - ///Returns the name of the namespace of the generated code. Returns an empty string if not defined. - virtual const char * getNamespace() const = 0; - - /// - ///Defines the base class of the generated code. - /// - ///The name of the base class of the generated code. - virtual void setBaseClass(const char * name) = 0; - - /// - ///Provides the base class of the generated code. - /// - ///Returns the name of the base class of the generated code. Returns an empty string if not defined. - virtual const char * getBaseClass() const = 0; - - /// - ///Defines the filename of the FileManager generated header. - /// - ///The path of the FileManager output file. - virtual void setManagerHeaderFilename(const char * path) = 0; - - /// - ///Provides the filename of the FileManager generated header. - /// - ///Returns the path of the FileManager output file. Returns an empty string if not defined. - virtual const char * getManagerHeaderFilename() const = 0; - - /// - ///Enable or disable the registration of the generated file to the FileManager. - /// - ///The new value of the flag. - virtual void setRegisterFileEnabled(bool register_file_enabled) = 0; - - /// - ///Returns true if the generated file should be registated FileManager should be used in generated code. - /// - ///Returns true if the FileManager should be used in generated code. Returns false otherwise. - virtual bool isRegisterFileEnabled() const = 0; - - /// - ///Defines the different type of cpp encoding. - ///See setCppEncoder() and getCppEncoder() functions. - /// - enum CppEncoderEnum - { - CPP_ENCODER_OCT, - CPP_ENCODER_HEX, - }; - - /// - ///Defines the type of cpp encoder to use. See CppEncoderEnum for details. - /// - ///The type of cpp encoder to use - virtual void setCppEncoder(const CppEncoderEnum & cpp_encoder) = 0; - - /// - ///Provides the type of cpp encoder to use. See CppEncoderEnum for details. - /// - ///Returns the type of cpp encoder to use. - virtual CppEncoderEnum getCppEncoder() const = 0; + ///Returns the current context set for the generator. + virtual const Context& getContext() const = 0; /// ///Creates a header file for embedding a given file into C++ source code. diff --git a/src/bin2cpp/SegmentGenerator.cpp b/src/bin2cpp/SegmentGenerator.cpp index c82d869..8099bbd 100755 --- a/src/bin2cpp/SegmentGenerator.cpp +++ b/src/bin2cpp/SegmentGenerator.cpp @@ -50,12 +50,12 @@ namespace bin2cpp bool SegmentGenerator::createCppSourceFile(const char * cpp_file_path) { //check if input file exists - FILE * input = fopen(getInputFilePath(), "rb"); + FILE * input = fopen(mContext.inputFilePath.c_str(), "rb"); if (!input) return false; //Uppercase function identifier - std::string functionIdentifier = ra::strings::CapitalizeFirstCharacter(mFunctionIdentifier); + std::string functionIdentifier = ra::strings::CapitalizeFirstCharacter(getContext().functionIdentifier); //Build header and cpp file path std::string headerPath = getHeaderFilePath(cpp_file_path); @@ -71,7 +71,7 @@ namespace bin2cpp //determine file properties uint32_t fileSize = ra::filesystem::GetFileSize(input); - std::string filename = ra::filesystem::GetFilename(getInputFilePath()); + 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); @@ -82,20 +82,20 @@ namespace bin2cpp std::string getterFunctionName = getGetterFunctionName(); //Build FileManager class template - std::string manager = getManagerHeaderFilename(); + 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", getHeaderFilename() ); + 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", mNamespace.c_str()); + fprintf(cpp, "namespace %s\n", getContext().codeNamespace.c_str()); fprintf(cpp, "{\n"); - fprintf(cpp, " class %s : public virtual %s::%s\n", className.c_str(), mNamespace.c_str(), mBaseClass.c_str()); + 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()); @@ -110,11 +110,11 @@ namespace bin2cpp 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[mChunkSize]; + unsigned char * buffer = new unsigned char[getContext().chunkSize]; while(!feof(input)) { //read a chunk of the file - size_t readSize = fread(buffer, 1, mChunkSize, input); + size_t readSize = fread(buffer, 1, getContext().chunkSize, input); //bool isLastChunk = !(readSize == chunk_size); @@ -123,12 +123,12 @@ namespace bin2cpp //convert to cpp string std::string cppEncoder; - switch(mCppEncoder) + switch(getContext().cppEncoder) { - case IGenerator::CPP_ENCODER_HEX: + case CPP_ENCODER_HEX: cppEncoder = ra::code::cpp::ToHexString(buffer, readSize); break; - case IGenerator::CPP_ENCODER_OCT: + case CPP_ENCODER_OCT: default: cppEncoder = ra::code::cpp::ToOctString(buffer, readSize, false); break; @@ -146,13 +146,13 @@ namespace bin2cpp fprintf(cpp, " private:\n"); fprintf(cpp, " std::string mBuffer;\n"); fprintf(cpp, " };\n"); - fprintf(cpp, " const %s & %s() { static %s _instance; return _instance; }\n", mBaseClass.c_str(), getterFunctionName.c_str(), className.c_str()); - if (isRegisterFileEnabled()) + 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 = getFileManagerRegistrationTemplate(); fprintf(cpp, "%s", fileManagerTemplate.c_str()); } - fprintf(cpp, "}; //%s\n", mNamespace.c_str()); + fprintf(cpp, "}; //%s\n", getContext().codeNamespace.c_str()); fclose(input); fclose(cpp); diff --git a/src/bin2cpp/StringGenerator.cpp b/src/bin2cpp/StringGenerator.cpp index fdf6601..77aaa0a 100755 --- a/src/bin2cpp/StringGenerator.cpp +++ b/src/bin2cpp/StringGenerator.cpp @@ -50,12 +50,12 @@ namespace bin2cpp bool StringGenerator::createCppSourceFile(const char * cpp_file_path) { //check if input file exists - FILE * input = fopen(getInputFilePath(), "rb"); + FILE * input = fopen(mContext.inputFilePath.c_str(), "rb"); if (!input) return false; //Uppercase function identifier - std::string functionIdentifier = ra::strings::CapitalizeFirstCharacter(mFunctionIdentifier); + std::string functionIdentifier = ra::strings::CapitalizeFirstCharacter(getContext().functionIdentifier); //Build header and cpp file path std::string headerPath = getHeaderFilePath(cpp_file_path); @@ -71,7 +71,7 @@ namespace bin2cpp //determine file properties uint32_t fileSize = ra::filesystem::GetFileSize(input); - std::string filename = ra::filesystem::GetFilename(getInputFilePath()); + std::string filename = ra::filesystem::GetFilename(mContext.inputFilePath.c_str()); //Build class name std::string className = getClassName(); @@ -81,12 +81,12 @@ namespace bin2cpp //write cpp file heading fprintf(cpp, "%s", getHeaderTemplate().c_str()); - fprintf(cpp, "#include \"%s\"\n", getHeaderFilename() ); + fprintf(cpp, "#include \"%s\"\n", mContext.headerFilename.c_str() ); fprintf(cpp, "#include \n"); fprintf(cpp, "#include //for ofstream\n"); - fprintf(cpp, "namespace %s\n", mNamespace.c_str()); + fprintf(cpp, "namespace %s\n", getContext().codeNamespace.c_str()); fprintf(cpp, "{\n"); - fprintf(cpp, " class %s : public virtual %s::%s\n", className.c_str(), mNamespace.c_str(), mBaseClass.c_str()); + 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()); @@ -100,13 +100,13 @@ namespace bin2cpp //create buffer for each chunks from input buffer int numLinePrinted = 0; - unsigned char * buffer = new unsigned char[mChunkSize]; + unsigned char * buffer = new unsigned char[getContext().chunkSize]; while(!feof(input)) { //read a chunk of the file - size_t readSize = fread(buffer, 1, mChunkSize, input); + size_t readSize = fread(buffer, 1, getContext().chunkSize, input); - bool isLastChunk = !(readSize == mChunkSize); + bool isLastChunk = !(readSize == getContext().chunkSize); if (readSize > 0) { @@ -118,12 +118,12 @@ namespace bin2cpp //convert to cpp string std::string cppEncoder; - switch(mCppEncoder) + switch(getContext().cppEncoder) { - case IGenerator::CPP_ENCODER_HEX: + case CPP_ENCODER_HEX: cppEncoder = ra::code::cpp::ToHexString(buffer, readSize); break; - case IGenerator::CPP_ENCODER_OCT: + case CPP_ENCODER_OCT: default: cppEncoder = ra::code::cpp::ToOctString(buffer, readSize, false); break; @@ -148,13 +148,13 @@ namespace bin2cpp fprintf(cpp, " }\n"); fprintf(cpp, "%s", getSaveMethodTemplate().c_str()); fprintf(cpp, " };\n"); - fprintf(cpp, " const %s & %s() { static %s _instance; return _instance; }\n", mBaseClass.c_str(), getterFunctionName.c_str(), className.c_str()); - if (isRegisterFileEnabled()) + 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 = getFileManagerRegistrationTemplate(); fprintf(cpp, "%s", fileManagerTemplate.c_str()); } - fprintf(cpp, "}; //%s\n", mNamespace.c_str()); + fprintf(cpp, "}; //%s\n", getContext().codeNamespace.c_str()); fclose(input); fclose(cpp); diff --git a/src/bin2cpp/Win32ResourceGenerator.cpp b/src/bin2cpp/Win32ResourceGenerator.cpp index a22c61f..5db6091 100755 --- a/src/bin2cpp/Win32ResourceGenerator.cpp +++ b/src/bin2cpp/Win32ResourceGenerator.cpp @@ -58,12 +58,12 @@ namespace bin2cpp return false; //check if input file exists - FILE * input = fopen(getInputFilePath(), "rb"); + FILE * input = fopen(mContext.inputFilePath.c_str(), "rb"); if (!input) return false; //Uppercase function identifier - std::string functionIdentifier = ra::strings::CapitalizeFirstCharacter(mFunctionIdentifier); + std::string functionIdentifier = ra::strings::CapitalizeFirstCharacter(getContext().functionIdentifier); //Build header and cpp file path std::string headerPath = getHeaderFilePath(cpp_file_path); @@ -79,7 +79,7 @@ namespace bin2cpp //determine file properties //uint32_t fileSize = ra::filesystem::GetFileSize(input); - std::string filename = ra::filesystem::GetFilename(getInputFilePath()); + std::string filename = ra::filesystem::GetFilename(mContext.inputFilePath.c_str()); //Build class name std::string className = getClassName(); @@ -89,7 +89,7 @@ namespace bin2cpp //write cpp file heading fprintf(cpp, "%s", getHeaderTemplate().c_str()); - fprintf(cpp, "#include \"%s\"\n", getHeaderFilename() ); + fprintf(cpp, "#include \"%s\"\n", mContext.headerFilename.c_str() ); fprintf(cpp, "#include \n"); fprintf(cpp, "#include \n"); fprintf(cpp, "#include //for ofstream\n"); @@ -103,9 +103,9 @@ namespace bin2cpp fprintf(cpp, "#pragma comment( lib, \"psapi.lib\" )\n"); fprintf(cpp, "\n"); - fprintf(cpp, "namespace %s\n", mNamespace.c_str()); + fprintf(cpp, "namespace %s\n", getContext().codeNamespace.c_str()); fprintf(cpp, "{\n"); - fprintf(cpp, " class %s : public virtual %s::%s\n", className.c_str(), mNamespace.c_str(), mBaseClass.c_str()); + 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()); @@ -134,7 +134,7 @@ namespace bin2cpp fprintf(cpp, " if ( EnumProcessModules( hProcess, &hModule, sizeof(hModule), &cbNeeded) )\n"); fprintf(cpp, " {\n"); fprintf(cpp, " //Retrieve the resource\n"); - fprintf(cpp, " hResourceInfoBlock = FindResource(hModule, \"%s\", \"CUSTOM\");\n", getRandomIdentifier(getInputFilePath()).c_str()); + fprintf(cpp, " hResourceInfoBlock = FindResource(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"); @@ -173,13 +173,13 @@ namespace bin2cpp 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", mBaseClass.c_str(), getterFunctionName.c_str(), className.c_str()); - if (isRegisterFileEnabled()) + 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 = getFileManagerRegistrationTemplate(); fprintf(cpp, "%s", fileManagerTemplate.c_str()); } - fprintf(cpp, "}; //%s\n", mNamespace.c_str()); + fprintf(cpp, "}; //%s\n", getContext().codeNamespace.c_str()); fclose(input); fclose(cpp); @@ -207,12 +207,12 @@ namespace bin2cpp return false; } - std::string filename = ra::filesystem::GetFilename(getInputFilePath()); + std::string filename = ra::filesystem::GetFilename(mContext.inputFilePath.c_str()); //write res file heading fprintf(res, "%s", getHeaderTemplate().c_str()); fprintf(res, "#include \n"); - fprintf(res, "%s CUSTOM \"%s\"\n", getRandomIdentifier(getInputFilePath()).c_str(), filename.c_str()); + fprintf(res, "%s CUSTOM \"%s\"\n", getRandomIdentifier(mContext.inputFilePath.c_str()).c_str(), filename.c_str()); fclose(res); diff --git a/src/bin2cpp/main.cpp b/src/bin2cpp/main.cpp index 1c751f3..4bbf213 100755 --- a/src/bin2cpp/main.cpp +++ b/src/bin2cpp/main.cpp @@ -29,6 +29,7 @@ #include "StringGenerator.h" #include "ArrayGenerator.h" #include "Win32ResourceGenerator.h" +#include "Context.h" #include #include @@ -69,7 +70,7 @@ enum FILE_UPDATE_MODE static const size_t DEFAULT_CHUNK_SIZE = 200; static const char * DEFAULT_NAMESPACE = "bin2cpp"; static const char * DEFAULT_BASECLASSNAME = "File"; -static const IGenerator::CppEncoderEnum DEFAULT_ENCODING = IGenerator::CPP_ENCODER_OCT; +static const CppEncoderEnum DEFAULT_ENCODING = CPP_ENCODER_OCT; static Dictionary identifiers_dictionary; // unique values for identifiers static Dictionary output_files_dictionary; // unique values for output file names @@ -129,37 +130,18 @@ struct ARGUMENTS bool noheader; bool quiet; bool version; - bool hasFile; // true if 'inputFilePath' is set. - bool hasDir; // true if 'inputDirPath' is set. - bool hasReportedFilePath; // true if 'reportedFilePath' is set. - bool hasManagerFile; // true if 'managerHeaderFilename' is set. - bool keepDirectoryStructure; // true if the output files must have the same directory structure as the input files. Valid only when --dir is used. - std::string inputFilePath; // path of the input binary file - std::string inputDirPath; - std::string outputDirPath; - std::string headerFilename; - std::string functionIdentifier; - std::string reportedFilePath; // path reported in the public api when calling getFilePath(); - size_t chunkSize; - bool plainOutput; - bool overrideExisting; - std::string codeNamespace; - std::string baseClass; - std::string managerHeaderFilename; - bool registerfile; - IGenerator::CppEncoderEnum encoding; std::string generatorName; }; //pre-declarations -bool generateFile(const ARGUMENTS & args, const std::string & output_file_path, bin2cpp::IGenerator * generator); -bool generateManagerFile(const ARGUMENTS & args, const std::string & output_file_path, bin2cpp::IGenerator * generator); -APP_ERROR_CODES processInputFile(const ARGUMENTS & args, bin2cpp::IGenerator * generator); -APP_ERROR_CODES processInputDirectory(const ARGUMENTS & args, bin2cpp::IGenerator * generator); -APP_ERROR_CODES processManagerFiles(const ARGUMENTS & args, bin2cpp::IGenerator * generator); -APP_ERROR_CODES processPlainOutput(const ARGUMENTS & args, bin2cpp::IGenerator * generator); -std::string getDefaultFunctionIdentifier(const ARGUMENTS & args, Dictionary & identifiers_dictionary); -std::string getDefaultHeaderFile(const ARGUMENTS & args); +bool generateFile(const ARGUMENTS & args, const Context & c, const std::string & output_file_path, bin2cpp::IGenerator * generator); +bool generateManagerFile(const ARGUMENTS & args, const Context & c, const std::string & output_file_path, bin2cpp::IGenerator * generator); +APP_ERROR_CODES processInputFile(const ARGUMENTS & args, const Context & c, bin2cpp::IGenerator * generator); +APP_ERROR_CODES processInputDirectory(const ARGUMENTS & args, const Context & c, bin2cpp::IGenerator * generator); +APP_ERROR_CODES processManagerFiles(const ARGUMENTS & args, const Context & c, bin2cpp::IGenerator * generator); +APP_ERROR_CODES processPlainOutput(const ARGUMENTS & args, const Context & c, bin2cpp::IGenerator * generator); +std::string getDefaultFunctionIdentifier(const ARGUMENTS & args, const Context & c, Dictionary & identifiers_dictionary); +std::string getDefaultHeaderFile(const ARGUMENTS & args, const Context & c); void printHeader() { @@ -222,15 +204,8 @@ int main(int argc, char* argv[]) args.noheader = false; args.quiet = false; args.version = false; - args.hasFile = false; - args.hasDir = false; - args.hasReportedFilePath = false; - args.hasManagerFile = false; - args.keepDirectoryStructure = false; - args.chunkSize = 0; - args.plainOutput = false; - args.overrideExisting = false; - args.registerfile = false; + + Context c; std::string dummy; @@ -250,8 +225,8 @@ int main(int argc, char* argv[]) args.quiet = ra::cli::ParseArgument("quiet", dummy, argc, argv); //force quiet and noheader if plain output - args.plainOutput = ra::cli::ParseArgument("plainoutput", dummy, argc, argv); - if (args.plainOutput) + c.plainOutput = ra::cli::ParseArgument("plainoutput", dummy, argc, argv); + if ( c.plainOutput ) { args.quiet = true; args.noheader = true; @@ -276,12 +251,12 @@ int main(int argc, char* argv[]) printHeader(); //mandatory arguments - args.hasFile = ra::cli::ParseArgument("file", args.inputFilePath, argc, argv); - args.hasDir = ra::cli::ParseArgument("dir", args.inputDirPath, argc, argv); - args.hasManagerFile = ra::cli::ParseArgument("managerfile", args.managerHeaderFilename, argc, argv); + c.hasInputFile = ra::cli::ParseArgument("file", c.inputFilePath, argc, argv); + c.hasInputDir = ra::cli::ParseArgument("dir", c.inputDirPath, argc, argv); + c.hasManagerFile = ra::cli::ParseArgument("managerfile", c.managerHeaderFilename, argc, argv); //if no mandatory args is specified - if (!args.hasFile && !args.hasDir && !args.hasManagerFile && !args.plainOutput) + if (!c.hasInputFile && !c.hasInputDir && !c.hasManagerFile && !c.plainOutput) { //file, dir, managerfile or plainoutput must be specified APP_ERROR_CODES error = APP_ERROR_MISSINGARGUMENTS; @@ -289,7 +264,7 @@ int main(int argc, char* argv[]) printUsage(); return error; } - else if (args.hasFile && args.hasDir) + else if (c.hasInputFile && c.hasInputDir) { //file OR dir must be specified, not both APP_ERROR_CODES error = APP_ERROR_TOOMANYARGUMENTS; @@ -299,9 +274,10 @@ int main(int argc, char* argv[]) } //if output args is mandatory - if (args.hasDir || (args.hasFile && !args.plainOutput) || args.hasManagerFile) + if (c.hasInputDir || (c.hasInputFile && !c.plainOutput) || c.hasManagerFile) { - if (!ra::cli::ParseArgument("output", args.outputDirPath, argc, argv)) + c.hasOutputDir = ra::cli::ParseArgument("output", c.outputDirPath, argc, argv); + if (!c.hasOutputDir ) { APP_ERROR_CODES error = APP_ERROR_MISSINGARGUMENTS; ra::logging::Log(ra::logging::LOG_ERROR, "%s (output)", getErrorCodeDescription(error)); @@ -311,9 +287,9 @@ int main(int argc, char* argv[]) } // if headerfile should not be specified - if (args.hasDir) + if (c.hasInputDir) { - if (ra::cli::ParseArgument("headerfile", args.headerFilename, argc, argv)) + if (ra::cli::ParseArgument("headerfile", c.headerFilename, argc, argv)) { //headerfile not supported with dir argument APP_ERROR_CODES error = APP_ERROR_TOOMANYARGUMENTS; @@ -324,9 +300,9 @@ int main(int argc, char* argv[]) } // if identifier should not be specified - if (args.hasDir) + if (c.hasInputDir) { - if (ra::cli::ParseArgument("identifier", args.functionIdentifier, argc, argv)) + if (ra::cli::ParseArgument("identifier", c.functionIdentifier, argc, argv)) { //identifier not supported with dir argument APP_ERROR_CODES error = APP_ERROR_TOOMANYARGUMENTS; @@ -338,52 +314,52 @@ int main(int argc, char* argv[]) //optional arguments - if (args.hasFile) + if (c.hasInputFile) { //identifier - if (!ra::cli::ParseArgument("identifier", args.functionIdentifier, argc, argv)) + if (!ra::cli::ParseArgument("identifier", c.functionIdentifier, argc, argv)) { //identifier is not manually specified. - args.functionIdentifier = getDefaultFunctionIdentifier(args, identifiers_dictionary); + c.functionIdentifier = getDefaultFunctionIdentifier(args, c, identifiers_dictionary); } //headerfile - if (!ra::cli::ParseArgument("headerfile", args.headerFilename, argc, argv)) + if (!ra::cli::ParseArgument("headerfile", c.headerFilename, argc, argv)) { //use the file name without extension as 'headerfile'. - args.headerFilename = getDefaultHeaderFile(args); + c.headerFilename = getDefaultHeaderFile(args, c); } } size_t tmpChunkSize = 0; - args.chunkSize = DEFAULT_CHUNK_SIZE; + c.chunkSize = DEFAULT_CHUNK_SIZE; if (ra::cli::ParseArgument("chunksize", tmpChunkSize, argc, argv)) { - args.chunkSize = tmpChunkSize; + c.chunkSize = tmpChunkSize; } - args.overrideExisting = ra::cli::ParseArgument("override", dummy, argc, argv); + c.overrideExistingFiles = ra::cli::ParseArgument("override", dummy, argc, argv); - if (!ra::cli::ParseArgument("namespace", args.codeNamespace, argc, argv)) + if (!ra::cli::ParseArgument("namespace", c.codeNamespace, argc, argv)) { - args.codeNamespace = DEFAULT_NAMESPACE; + c.codeNamespace = DEFAULT_NAMESPACE; } - if (!ra::cli::ParseArgument("baseclass", args.baseClass, argc, argv)) + if (!ra::cli::ParseArgument("baseclass", c.baseClass, argc, argv)) { - args.baseClass = DEFAULT_BASECLASSNAME; + c.baseClass = DEFAULT_BASECLASSNAME; } - args.registerfile = ra::cli::ParseArgument("registerfile", dummy, argc, argv); + c.registerFiles = ra::cli::ParseArgument("registerfile", dummy, argc, argv); //force registerfile if managerfile is specified - if (args.hasManagerFile) + if (c.hasManagerFile) { - args.registerfile = true; + c.registerFiles = true; } - args.hasReportedFilePath = ra::cli::ParseArgument("reportedfilepath", args.reportedFilePath, argc, argv); - if (args.hasReportedFilePath && args.hasDir) + c.hasReportedFilePath = ra::cli::ParseArgument("reportedfilepath", c.reportedFilePath, argc, argv); + if (c.hasReportedFilePath && c.hasInputDir) { APP_ERROR_CODES error = APP_ERROR_TOOMANYARGUMENTS; ra::logging::Log(ra::logging::LOG_ERROR, "%s (reportedfilepath)", getErrorCodeDescription(error)); @@ -391,15 +367,15 @@ int main(int argc, char* argv[]) return error; } - args.keepDirectoryStructure = ra::cli::ParseArgument("keepdirs", dummy, argc, argv); + c.keepDirectoryStructure = ra::cli::ParseArgument("keepdirs", dummy, argc, argv); std::string encodingStr; if (ra::cli::ParseArgument("encoding", encodingStr, argc, argv)) { if (ra::strings::Uppercase(encodingStr) == "OCT") - args.encoding = IGenerator::CPP_ENCODER_OCT; + c.cppEncoder = CPP_ENCODER_OCT; else if (ra::strings::Uppercase(encodingStr) == "HEX") - args.encoding = IGenerator::CPP_ENCODER_HEX; + c.cppEncoder = CPP_ENCODER_HEX; else { APP_ERROR_CODES error = APP_ERROR_MISSINGARGUMENTS; @@ -410,7 +386,7 @@ int main(int argc, char* argv[]) } else { - args.encoding = DEFAULT_ENCODING; + c.cppEncoder = DEFAULT_ENCODING; } //select generator @@ -450,7 +426,7 @@ int main(int argc, char* argv[]) } //win32 generator does not support plain output - if (args.generatorName == "win32" && args.plainOutput) + if (args.generatorName == "win32" && c.plainOutput) { APP_ERROR_CODES error = AAP_ERROR_NOTSUPPORTED; ra::logging::Log(ra::logging::LOG_ERROR, "%s.", getErrorCodeDescription(error)); @@ -464,27 +440,27 @@ int main(int argc, char* argv[]) } //process file, directory or plain format - if (args.plainOutput) + if (c.plainOutput) { - APP_ERROR_CODES error = processPlainOutput(args, generator); + APP_ERROR_CODES error = processPlainOutput(args, c, generator); if (error != APP_ERROR_SUCCESS) { ra::logging::Log(ra::logging::LOG_ERROR, "%s.", getErrorCodeDescription(error)); return error; } } - else if (args.hasFile) + else if (c.hasInputFile) { - APP_ERROR_CODES error = processInputFile(args, generator); + APP_ERROR_CODES error = processInputFile(args, c, generator); if (error != APP_ERROR_SUCCESS) { ra::logging::Log(ra::logging::LOG_ERROR, "%s.", getErrorCodeDescription(error)); return error; } } - else if (args.hasDir) + else if (c.hasInputDir) { - APP_ERROR_CODES error = processInputDirectory(args, generator); + APP_ERROR_CODES error = processInputDirectory(args, c, generator); if (error != APP_ERROR_SUCCESS) { ra::logging::Log(ra::logging::LOG_ERROR, "%s.", getErrorCodeDescription(error)); @@ -493,9 +469,9 @@ int main(int argc, char* argv[]) } //should we also generate the FileManager class? - if (args.hasManagerFile) + if (c.hasManagerFile) { - APP_ERROR_CODES error = processManagerFiles(args, generator); + APP_ERROR_CODES error = processManagerFiles(args, c, generator); if (error != APP_ERROR_SUCCESS) { ra::logging::Log(ra::logging::LOG_ERROR, "%s.", getErrorCodeDescription(error)); @@ -506,77 +482,69 @@ int main(int argc, char* argv[]) return APP_ERROR_SUCCESS; } -std::string getDefaultFunctionIdentifier(const ARGUMENTS & args, Dictionary & identifiers_dictionary) +std::string getDefaultFunctionIdentifier(const ARGUMENTS & args, const Context & c, Dictionary & identifiers_dictionary) { std::string output; //use the file name without extension as 'identifier'. - output = getUniqueFunctionIdentifierFromPath(args.inputFilePath.c_str(), identifiers_dictionary); + output = getUniqueFunctionIdentifierFromPath(c.inputFilePath.c_str(), identifiers_dictionary); output = ra::strings::CapitalizeFirstCharacter(output); return output; } -std::string getDefaultHeaderFile(const ARGUMENTS & args) +std::string getDefaultHeaderFile(const ARGUMENTS & args, const Context & c) { std::string output; //use the file name without extension as 'headerfile'. - output = ra::filesystem::GetFilenameWithoutExtension(args.inputFilePath.c_str()); + output = ra::filesystem::GetFilenameWithoutExtension(c.inputFilePath.c_str()); output += ".h"; return output; } -APP_ERROR_CODES processInputFile(const ARGUMENTS & args, bin2cpp::IGenerator * generator) +APP_ERROR_CODES processInputFile(const ARGUMENTS & args, const Context & c, bin2cpp::IGenerator * generator) { // printing info std::string info; - info << "Embedding \"" << args.inputFilePath << "\""; - if (args.chunkSize != DEFAULT_CHUNK_SIZE) + info << "Embedding \"" << c.inputFilePath << "\""; + if (c.chunkSize != DEFAULT_CHUNK_SIZE) { info << " using chunks of "; - info << ra::strings::ToString(args.chunkSize); + info << ra::strings::ToString(c.chunkSize); info << " bytes"; } - if (args.overrideExisting) + if (c.overrideExistingFiles) info << " overriding existing files"; info << "..."; ra::logging::Log(ra::logging::LOG_INFO, info.c_str()); //check if input file exists - if (!ra::filesystem::FileExists(args.inputFilePath.c_str())) + if (!ra::filesystem::FileExists(c.inputFilePath.c_str())) return APP_ERROR_INPUTFILENOTFOUND; ARGUMENTS argsCopy = args; + Context cCopy = c; //prepare output files path - std::string cppFilename = argsCopy.headerFilename; + std::string cppFilename = cCopy.headerFilename; ra::strings::Replace(cppFilename, ".hpp", ".cpp"); ra::strings::Replace(cppFilename, ".h", ".cpp"); //build unique output relative file paths - argsCopy.headerFilename = bin2cpp::getUniqueFilePath(argsCopy.headerFilename, output_files_dictionary); + cCopy.headerFilename = bin2cpp::getUniqueFilePath(cCopy.headerFilename, output_files_dictionary); cppFilename = bin2cpp::getUniqueFilePath(cppFilename, output_files_dictionary); //build full absolute paths - std::string outputHeaderPath = argsCopy.outputDirPath + ra::filesystem::GetPathSeparatorStr() + argsCopy.headerFilename; - std::string outputCppPath = argsCopy.outputDirPath + ra::filesystem::GetPathSeparatorStr() + cppFilename; + std::string outputHeaderPath = cCopy.outputDirPath + ra::filesystem::GetPathSeparatorStr() + cCopy.headerFilename; + std::string outputCppPath = cCopy.outputDirPath + ra::filesystem::GetPathSeparatorStr() + cppFilename; //configure the generator - generator->setInputFilePath(argsCopy.inputFilePath.c_str()); - generator->setHeaderFilename(argsCopy.headerFilename.c_str()); - generator->setFunctionIdentifier(argsCopy.functionIdentifier.c_str()); - generator->setReportedFilePath(argsCopy.reportedFilePath.c_str()); - generator->setChunkSize(argsCopy.chunkSize); - generator->setNamespace(argsCopy.codeNamespace.c_str()); - generator->setBaseClass(argsCopy.baseClass.c_str()); - generator->setCppEncoder(argsCopy.encoding); - generator->setManagerHeaderFilename(argsCopy.managerHeaderFilename.c_str()); - generator->setRegisterFileEnabled(argsCopy.registerfile); + generator->setContext(c); //build the output directory structure if required - if (argsCopy.keepDirectoryStructure) + if (cCopy.keepDirectoryStructure) { std::string parent_directory = ra::filesystem::GetParentPath(outputHeaderPath); if (!parent_directory.empty() && !ra::filesystem::DirectoryExists(parent_directory.c_str())) @@ -592,11 +560,11 @@ APP_ERROR_CODES processInputFile(const ARGUMENTS & args, bin2cpp::IGenerator * g } //process files - bool headerResult = generateFile(args, outputHeaderPath, generator); + bool headerResult = generateFile(args, c, outputHeaderPath, generator); if (!headerResult) return APP_ERROR_UNABLETOCREATEOUTPUTFILES; - bool cppResult = generateFile(args, outputCppPath, generator); + bool cppResult = generateFile(args, c, outputCppPath, generator); if (!cppResult) return APP_ERROR_UNABLETOCREATEOUTPUTFILES; @@ -604,23 +572,23 @@ APP_ERROR_CODES processInputFile(const ARGUMENTS & args, bin2cpp::IGenerator * g return APP_ERROR_SUCCESS; } -APP_ERROR_CODES processInputDirectory(const ARGUMENTS & args, bin2cpp::IGenerator * generator) +APP_ERROR_CODES processInputDirectory(const ARGUMENTS & args, const Context& c, bin2cpp::IGenerator * generator) { //check if input dir exists - if (!ra::filesystem::DirectoryExists(args.inputDirPath.c_str())) + if (!ra::filesystem::DirectoryExists(c.inputDirPath.c_str())) { APP_ERROR_CODES error = APP_ERROR_INPUTDIRNOTFOUND; - ra::logging::Log(ra::logging::LOG_ERROR, "%s (%s)", getErrorCodeDescription(error), args.inputDirPath.c_str()); + ra::logging::Log(ra::logging::LOG_ERROR, "%s (%s)", getErrorCodeDescription(error), c.inputDirPath.c_str()); return error; } //search all files in the directory ra::strings::StringVector files; - bool found = ra::filesystem::FindFiles(files, args.inputDirPath.c_str()); + bool found = ra::filesystem::FindFiles(files, c.inputDirPath.c_str()); if (!found) { APP_ERROR_CODES error = APP_ERROR_INPUTDIRNOTFOUND; - ra::logging::Log(ra::logging::LOG_ERROR, "%s (%s)", getErrorCodeDescription(error), args.inputDirPath.c_str()); + ra::logging::Log(ra::logging::LOG_ERROR, "%s (%s)", getErrorCodeDescription(error), c.inputDirPath.c_str()); return error; } @@ -645,28 +613,29 @@ APP_ERROR_CODES processInputDirectory(const ARGUMENTS & args, bin2cpp::IGenerato //build a 'headerfile' and 'identifier' argument for this file... ARGUMENTS argsCopy = args; + Context cCopy = c; //replace 'dir' input by current file input - argsCopy.hasDir = false; - argsCopy.hasFile = true; - argsCopy.inputFilePath = file; + cCopy.hasInputDir = false; + cCopy.hasInputFile = true; + cCopy.inputFilePath = file; //use the file name without extension as 'headerfile'. - argsCopy.headerFilename = getDefaultHeaderFile(argsCopy); + cCopy.headerFilename = getDefaultHeaderFile(argsCopy, cCopy); //use the file name without extension as 'identifier'. - argsCopy.functionIdentifier = getDefaultFunctionIdentifier(argsCopy, identifiers_dictionary); + cCopy.functionIdentifier = getDefaultFunctionIdentifier(argsCopy, cCopy, identifiers_dictionary); //build a relative file path std::string relative_file_path = file; - relative_file_path.erase(0, argsCopy.inputDirPath.size() + 1 ); // convert absolute path to relative path. +1 to remove first \ character + relative_file_path.erase(0, cCopy.inputDirPath.size() + 1 ); // convert absolute path to relative path. +1 to remove first \ character ra::filesystem::NormalizePath(relative_file_path); //automatically build a reported path with --dir mode. - argsCopy.hasReportedFilePath = true; - argsCopy.reportedFilePath = relative_file_path; + cCopy.hasReportedFilePath = true; + cCopy.reportedFilePath = relative_file_path; - if (args.keepDirectoryStructure) + if (c.keepDirectoryStructure) { // To keep the directory structure, we need to // make headerFilename a relative path @@ -681,11 +650,11 @@ APP_ERROR_CODES processInputDirectory(const ARGUMENTS & args, bin2cpp::IGenerato relative_header_file_path += "h"; } - argsCopy.headerFilename = relative_header_file_path; + cCopy.headerFilename = relative_header_file_path; } //process this file... - APP_ERROR_CODES error = processInputFile(argsCopy, generator); + APP_ERROR_CODES error = processInputFile(argsCopy, cCopy, generator); if (error != APP_ERROR_SUCCESS) return error; @@ -717,9 +686,9 @@ FILE_UPDATE_MODE getFileUpdateMode(const std::string & input_file_path, const st return UPDATING; } -bool generateFile(const ARGUMENTS & args, const std::string & output_file_path, bin2cpp::IGenerator * generator) +bool generateFile(const ARGUMENTS & args, const Context & c, const std::string & output_file_path, bin2cpp::IGenerator * generator) { - FILE_UPDATE_MODE mode = getFileUpdateMode(args.inputFilePath, output_file_path, args.overrideExisting); + FILE_UPDATE_MODE mode = getFileUpdateMode(c.inputFilePath, output_file_path, c.overrideExistingFiles); //writing message ra::logging::Log(ra::logging::LOG_INFO, "%s file \"%s\"...", getUpdateModeText(mode), output_file_path.c_str()); @@ -748,10 +717,10 @@ bool generateFile(const ARGUMENTS & args, const std::string & output_file_path, return result; } -bool generateManagerFile(const ARGUMENTS & args, const std::string & output_file_path, bin2cpp::IGenerator * generator) +bool generateManagerFile(const ARGUMENTS & args, const Context & c, const std::string & output_file_path, bin2cpp::IGenerator * generator) { std::string processPath = ra::process::GetCurrentProcessPath(); - FILE_UPDATE_MODE mode = getFileUpdateMode(processPath, output_file_path, args.overrideExisting); + FILE_UPDATE_MODE mode = getFileUpdateMode(processPath, output_file_path, c.overrideExistingFiles); //writing message ra::logging::Log(ra::logging::LOG_INFO, "%s file \"%s\"...", getUpdateModeText(mode), output_file_path.c_str()); @@ -779,29 +748,29 @@ bool generateManagerFile(const ARGUMENTS & args, const std::string & output_file return result; } -APP_ERROR_CODES processManagerFiles(const ARGUMENTS & args, bin2cpp::IGenerator * generator) +APP_ERROR_CODES processManagerFiles(const ARGUMENTS & args, const Context & c, bin2cpp::IGenerator * generator) { // printing info std::string info; - info << "Generating \"" << args.managerHeaderFilename << "\""; - if (args.overrideExisting) + info << "Generating \"" << c.managerHeaderFilename << "\""; + if (c.overrideExistingFiles) info << " overriding existing files"; info << "..."; ra::logging::Log(ra::logging::LOG_INFO, info.c_str()); //prepare output files path - std::string cppFilename = args.managerHeaderFilename; + std::string cppFilename = c.managerHeaderFilename; ra::strings::Replace(cppFilename, ".hpp", ".cpp"); ra::strings::Replace(cppFilename, ".h", ".cpp"); - std::string outputHeaderPath = args.outputDirPath + ra::filesystem::GetPathSeparatorStr() + args.managerHeaderFilename; - std::string outputCppPath = args.outputDirPath + ra::filesystem::GetPathSeparatorStr() + cppFilename; + std::string outputHeaderPath = c.outputDirPath + ra::filesystem::GetPathSeparatorStr() + c.managerHeaderFilename; + std::string outputCppPath = c.outputDirPath + ra::filesystem::GetPathSeparatorStr() + cppFilename; //process files - bool headerResult = generateManagerFile(args, outputHeaderPath, generator); + bool headerResult = generateManagerFile(args, c, outputHeaderPath, generator); if (!headerResult) return APP_ERROR_UNABLETOCREATEOUTPUTFILES; - bool cppResult = generateManagerFile(args, outputCppPath, generator); + bool cppResult = generateManagerFile(args, c, outputCppPath, generator); if (!cppResult) return APP_ERROR_UNABLETOCREATEOUTPUTFILES; @@ -809,18 +778,17 @@ APP_ERROR_CODES processManagerFiles(const ARGUMENTS & args, bin2cpp::IGenerator return APP_ERROR_SUCCESS; } -APP_ERROR_CODES processPlainOutput(const ARGUMENTS & args, bin2cpp::IGenerator * generator) +APP_ERROR_CODES processPlainOutput(const ARGUMENTS & args, const Context & c, bin2cpp::IGenerator * generator) { //check if input file exists - if (!ra::filesystem::FileExists(args.inputFilePath.c_str())) + if (!ra::filesystem::FileExists(c.inputFilePath.c_str())) return APP_ERROR_INPUTFILENOTFOUND; ARGUMENTS argsCopy = args; + Context cCopy = c; //configure the generator - generator->setInputFilePath(argsCopy.inputFilePath.c_str()); - generator->setChunkSize(argsCopy.chunkSize); - generator->setCppEncoder(argsCopy.encoding); + generator->setContext(cCopy); //process file bool result = generator->printFileContent(); From 5b5848103a53d785757dc548b2e4ef923753b7e8 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sun, 27 Apr 2025 08:18:05 -0400 Subject: [PATCH 4/9] Code cleanup --- src/bin2cpp/bin2cpp.samples.txt | 3 ++ src/bin2cpp/main.cpp | 61 ++++++++++++++++----------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/bin2cpp/bin2cpp.samples.txt b/src/bin2cpp/bin2cpp.samples.txt index d8ff769..3429199 100644 --- a/src/bin2cpp/bin2cpp.samples.txt +++ b/src/bin2cpp/bin2cpp.samples.txt @@ -26,3 +26,6 @@ --file=..\..\test\bin2cpp_unittest\generated_files\testText1000\testText1000.bin --output=. --override --noheader --dir=..\..\test\bin2cpp_unittest\generated_files\testIssue56a\input_files --output=..\..\test\bin2cpp_unittest\generated_files\testIssue56a\compiled_sources --chunksize=200 --managerfile=FileManager56a.h --registerfile --namespace=issue56a --override + + +--plainoutput --file=..\..\test\bin2cpp_unittest\generated_files\testSequential1000\testSequential1000.bin diff --git a/src/bin2cpp/main.cpp b/src/bin2cpp/main.cpp index 4bbf213..7e1ca09 100755 --- a/src/bin2cpp/main.cpp +++ b/src/bin2cpp/main.cpp @@ -134,14 +134,14 @@ struct ARGUMENTS }; //pre-declarations -bool generateFile(const ARGUMENTS & args, const Context & c, const std::string & output_file_path, bin2cpp::IGenerator * generator); -bool generateManagerFile(const ARGUMENTS & args, const Context & c, const std::string & output_file_path, bin2cpp::IGenerator * generator); -APP_ERROR_CODES processInputFile(const ARGUMENTS & args, const Context & c, bin2cpp::IGenerator * generator); -APP_ERROR_CODES processInputDirectory(const ARGUMENTS & args, const Context & c, bin2cpp::IGenerator * generator); -APP_ERROR_CODES processManagerFiles(const ARGUMENTS & args, const Context & c, bin2cpp::IGenerator * generator); -APP_ERROR_CODES processPlainOutput(const ARGUMENTS & args, const Context & c, bin2cpp::IGenerator * generator); -std::string getDefaultFunctionIdentifier(const ARGUMENTS & args, const Context & c, Dictionary & identifiers_dictionary); -std::string getDefaultHeaderFile(const ARGUMENTS & args, const Context & c); +bool generateFile(const Context & c, const std::string & output_file_path, bin2cpp::IGenerator * generator); +bool generateManagerFile(const Context & c, const std::string & output_file_path, bin2cpp::IGenerator * generator); +APP_ERROR_CODES processInputFile(const Context & c, bin2cpp::IGenerator * generator); +APP_ERROR_CODES processInputDirectory(const Context & c, bin2cpp::IGenerator * generator); +APP_ERROR_CODES processManagerFiles(const Context & c, bin2cpp::IGenerator * generator); +APP_ERROR_CODES processPlainOutput(const Context & c, bin2cpp::IGenerator * generator); +std::string getDefaultFunctionIdentifier(const Context & c, Dictionary & identifiers_dictionary); +std::string getDefaultHeaderFile(const Context & c); void printHeader() { @@ -320,14 +320,14 @@ int main(int argc, char* argv[]) if (!ra::cli::ParseArgument("identifier", c.functionIdentifier, argc, argv)) { //identifier is not manually specified. - c.functionIdentifier = getDefaultFunctionIdentifier(args, c, identifiers_dictionary); + c.functionIdentifier = getDefaultFunctionIdentifier(c, identifiers_dictionary); } //headerfile if (!ra::cli::ParseArgument("headerfile", c.headerFilename, argc, argv)) { //use the file name without extension as 'headerfile'. - c.headerFilename = getDefaultHeaderFile(args, c); + c.headerFilename = getDefaultHeaderFile(c); } } @@ -442,7 +442,7 @@ int main(int argc, char* argv[]) //process file, directory or plain format if (c.plainOutput) { - APP_ERROR_CODES error = processPlainOutput(args, c, generator); + APP_ERROR_CODES error = processPlainOutput(c, generator); if (error != APP_ERROR_SUCCESS) { ra::logging::Log(ra::logging::LOG_ERROR, "%s.", getErrorCodeDescription(error)); @@ -451,7 +451,7 @@ int main(int argc, char* argv[]) } else if (c.hasInputFile) { - APP_ERROR_CODES error = processInputFile(args, c, generator); + APP_ERROR_CODES error = processInputFile(c, generator); if (error != APP_ERROR_SUCCESS) { ra::logging::Log(ra::logging::LOG_ERROR, "%s.", getErrorCodeDescription(error)); @@ -460,7 +460,7 @@ int main(int argc, char* argv[]) } else if (c.hasInputDir) { - APP_ERROR_CODES error = processInputDirectory(args, c, generator); + APP_ERROR_CODES error = processInputDirectory(c, generator); if (error != APP_ERROR_SUCCESS) { ra::logging::Log(ra::logging::LOG_ERROR, "%s.", getErrorCodeDescription(error)); @@ -471,7 +471,7 @@ int main(int argc, char* argv[]) //should we also generate the FileManager class? if (c.hasManagerFile) { - APP_ERROR_CODES error = processManagerFiles(args, c, generator); + APP_ERROR_CODES error = processManagerFiles(c, generator); if (error != APP_ERROR_SUCCESS) { ra::logging::Log(ra::logging::LOG_ERROR, "%s.", getErrorCodeDescription(error)); @@ -482,7 +482,7 @@ int main(int argc, char* argv[]) return APP_ERROR_SUCCESS; } -std::string getDefaultFunctionIdentifier(const ARGUMENTS & args, const Context & c, Dictionary & identifiers_dictionary) +std::string getDefaultFunctionIdentifier(const Context & c, Dictionary & identifiers_dictionary) { std::string output; @@ -493,7 +493,7 @@ std::string getDefaultFunctionIdentifier(const ARGUMENTS & args, const Context & return output; } -std::string getDefaultHeaderFile(const ARGUMENTS & args, const Context & c) +std::string getDefaultHeaderFile(const Context & c) { std::string output; @@ -504,7 +504,7 @@ std::string getDefaultHeaderFile(const ARGUMENTS & args, const Context & c) return output; } -APP_ERROR_CODES processInputFile(const ARGUMENTS & args, const Context & c, bin2cpp::IGenerator * generator) +APP_ERROR_CODES processInputFile(const Context & c, bin2cpp::IGenerator * generator) { // printing info std::string info; @@ -524,7 +524,6 @@ APP_ERROR_CODES processInputFile(const ARGUMENTS & args, const Context & c, bin2 if (!ra::filesystem::FileExists(c.inputFilePath.c_str())) return APP_ERROR_INPUTFILENOTFOUND; - ARGUMENTS argsCopy = args; Context cCopy = c; //prepare output files path @@ -560,11 +559,11 @@ APP_ERROR_CODES processInputFile(const ARGUMENTS & args, const Context & c, bin2 } //process files - bool headerResult = generateFile(args, c, outputHeaderPath, generator); + bool headerResult = generateFile(c, outputHeaderPath, generator); if (!headerResult) return APP_ERROR_UNABLETOCREATEOUTPUTFILES; - bool cppResult = generateFile(args, c, outputCppPath, generator); + bool cppResult = generateFile(c, outputCppPath, generator); if (!cppResult) return APP_ERROR_UNABLETOCREATEOUTPUTFILES; @@ -572,7 +571,7 @@ APP_ERROR_CODES processInputFile(const ARGUMENTS & args, const Context & c, bin2 return APP_ERROR_SUCCESS; } -APP_ERROR_CODES processInputDirectory(const ARGUMENTS & args, const Context& c, bin2cpp::IGenerator * generator) +APP_ERROR_CODES processInputDirectory(const Context& c, bin2cpp::IGenerator * generator) { //check if input dir exists if (!ra::filesystem::DirectoryExists(c.inputDirPath.c_str())) @@ -612,7 +611,6 @@ APP_ERROR_CODES processInputDirectory(const ARGUMENTS & args, const Context& c, const std::string & file = files[i]; //build a 'headerfile' and 'identifier' argument for this file... - ARGUMENTS argsCopy = args; Context cCopy = c; //replace 'dir' input by current file input @@ -621,10 +619,10 @@ APP_ERROR_CODES processInputDirectory(const ARGUMENTS & args, const Context& c, cCopy.inputFilePath = file; //use the file name without extension as 'headerfile'. - cCopy.headerFilename = getDefaultHeaderFile(argsCopy, cCopy); + cCopy.headerFilename = getDefaultHeaderFile(cCopy); //use the file name without extension as 'identifier'. - cCopy.functionIdentifier = getDefaultFunctionIdentifier(argsCopy, cCopy, identifiers_dictionary); + cCopy.functionIdentifier = getDefaultFunctionIdentifier(cCopy, identifiers_dictionary); //build a relative file path std::string relative_file_path = file; @@ -654,7 +652,7 @@ APP_ERROR_CODES processInputDirectory(const ARGUMENTS & args, const Context& c, } //process this file... - APP_ERROR_CODES error = processInputFile(argsCopy, cCopy, generator); + APP_ERROR_CODES error = processInputFile(cCopy, generator); if (error != APP_ERROR_SUCCESS) return error; @@ -686,7 +684,7 @@ FILE_UPDATE_MODE getFileUpdateMode(const std::string & input_file_path, const st return UPDATING; } -bool generateFile(const ARGUMENTS & args, const Context & c, const std::string & output_file_path, bin2cpp::IGenerator * generator) +bool generateFile(const Context & c, const std::string & output_file_path, bin2cpp::IGenerator * generator) { FILE_UPDATE_MODE mode = getFileUpdateMode(c.inputFilePath, output_file_path, c.overrideExistingFiles); @@ -717,7 +715,7 @@ bool generateFile(const ARGUMENTS & args, const Context & c, const std::string & return result; } -bool generateManagerFile(const ARGUMENTS & args, const Context & c, const std::string & output_file_path, bin2cpp::IGenerator * generator) +bool generateManagerFile(const Context & c, const std::string & output_file_path, bin2cpp::IGenerator * generator) { std::string processPath = ra::process::GetCurrentProcessPath(); FILE_UPDATE_MODE mode = getFileUpdateMode(processPath, output_file_path, c.overrideExistingFiles); @@ -748,7 +746,7 @@ bool generateManagerFile(const ARGUMENTS & args, const Context & c, const std::s return result; } -APP_ERROR_CODES processManagerFiles(const ARGUMENTS & args, const Context & c, bin2cpp::IGenerator * generator) +APP_ERROR_CODES processManagerFiles(const Context & c, bin2cpp::IGenerator * generator) { // printing info std::string info; @@ -766,11 +764,11 @@ APP_ERROR_CODES processManagerFiles(const ARGUMENTS & args, const Context & c, b std::string outputCppPath = c.outputDirPath + ra::filesystem::GetPathSeparatorStr() + cppFilename; //process files - bool headerResult = generateManagerFile(args, c, outputHeaderPath, generator); + bool headerResult = generateManagerFile(c, outputHeaderPath, generator); if (!headerResult) return APP_ERROR_UNABLETOCREATEOUTPUTFILES; - bool cppResult = generateManagerFile(args, c, outputCppPath, generator); + bool cppResult = generateManagerFile(c, outputCppPath, generator); if (!cppResult) return APP_ERROR_UNABLETOCREATEOUTPUTFILES; @@ -778,13 +776,12 @@ APP_ERROR_CODES processManagerFiles(const ARGUMENTS & args, const Context & c, b return APP_ERROR_SUCCESS; } -APP_ERROR_CODES processPlainOutput(const ARGUMENTS & args, const Context & c, bin2cpp::IGenerator * generator) +APP_ERROR_CODES processPlainOutput(const Context & c, bin2cpp::IGenerator * generator) { //check if input file exists if (!ra::filesystem::FileExists(c.inputFilePath.c_str())) return APP_ERROR_INPUTFILENOTFOUND; - ARGUMENTS argsCopy = args; Context cCopy = c; //configure the generator From a0d0cd9b4c195fb77f6779e6a622307eacb7ca3d Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sun, 27 Apr 2025 09:00:54 -0400 Subject: [PATCH 5/9] Updated command line samples with a plainoutput example. --- src/bin2cpp/bin2cpp.samples.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin2cpp/bin2cpp.samples.txt b/src/bin2cpp/bin2cpp.samples.txt index 3429199..e912fdc 100644 --- a/src/bin2cpp/bin2cpp.samples.txt +++ b/src/bin2cpp/bin2cpp.samples.txt @@ -28,4 +28,4 @@ --noheader --dir=..\..\test\bin2cpp_unittest\generated_files\testIssue56a\input_files --output=..\..\test\bin2cpp_unittest\generated_files\testIssue56a\compiled_sources --chunksize=200 --managerfile=FileManager56a.h --registerfile --namespace=issue56a --override ---plainoutput --file=..\..\test\bin2cpp_unittest\generated_files\testSequential1000\testSequential1000.bin +--plainoutput --chunksize=9999 --file=..\..\test\bin2cpp_unittest\generated_files\testSequential1000\testSequential1000.bin From 538b79b4c43d3ba653d94196ff1fd59b52bf1e35 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sun, 27 Apr 2025 09:03:55 -0400 Subject: [PATCH 6/9] Move FileManager class generating code from main.cpp to a dedicated ManagerGenerator class which is now an IGenerator implementation. --- src/bin2cpp/BaseGenerator.cpp | 194 ------------------------ src/bin2cpp/BaseGenerator.h | 2 - src/bin2cpp/CMakeLists.txt | 2 + src/bin2cpp/IGenerator.h | 14 -- src/bin2cpp/ManagerGenerator.cpp | 247 +++++++++++++++++++++++++++++++ src/bin2cpp/ManagerGenerator.h | 49 ++++++ src/bin2cpp/main.cpp | 19 ++- 7 files changed, 310 insertions(+), 217 deletions(-) create mode 100644 src/bin2cpp/ManagerGenerator.cpp create mode 100644 src/bin2cpp/ManagerGenerator.h diff --git a/src/bin2cpp/BaseGenerator.cpp b/src/bin2cpp/BaseGenerator.cpp index aff0295..46d0c19 100755 --- a/src/bin2cpp/BaseGenerator.cpp +++ b/src/bin2cpp/BaseGenerator.cpp @@ -268,200 +268,6 @@ namespace bin2cpp return true; } - bool BaseGenerator::createManagerHeaderFile(const char * header_file_path) - { - FILE * header = fopen(header_file_path, "w"); - if (!header) - return false; - - //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); - - 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; - } - - bool BaseGenerator::createManagerSourceFile(const char * cpp_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; iReturns true when the file was created. Returns false otherwise. virtual bool createCppSourceFile(const char * cpp_file_path) = 0; - /// - ///Creates a FileManager header file. - /// - ///The path of the header file (*.h). - ///Returns true when the file was created. Returns false otherwise. - virtual bool createManagerHeaderFile(const char * header_file_path) = 0; - - /// - ///Creates a FileManager cpp file. - /// - ///The path of the cpp file (*.h). - ///Returns true when the file was created. Returns false otherwise. - virtual bool createManagerSourceFile(const char * cpp_file_path) = 0; - /// ///Print the encoded file content to stdout /// diff --git a/src/bin2cpp/ManagerGenerator.cpp b/src/bin2cpp/ManagerGenerator.cpp new file mode 100644 index 0000000..72a8126 --- /dev/null +++ b/src/bin2cpp/ManagerGenerator.cpp @@ -0,0 +1,247 @@ +/********************************************************************************** + * 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 "ManagerGenerator.h" +#include +#include +#include +#include + +#include "common.h" + +namespace bin2cpp +{ + ManagerGenerator::ManagerGenerator() + { + } + + ManagerGenerator::~ManagerGenerator() + { + } + + const char * ManagerGenerator::getName() const + { + return "manager"; + } + + bool ManagerGenerator::createCppHeaderFile(const char* header_file_path) + { + FILE* header = fopen(header_file_path, "w"); + if ( !header ) + return false; + + //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); + + 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; + } + + bool ManagerGenerator::createCppSourceFile(const char* cpp_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 + ///This generator generate the File Manager class files. + /// + class ManagerGenerator : public BaseGenerator + { + public: + 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 printFileContent(); + }; + +}; //bin2cpp + +#endif //ARRAYGENERATOR_H diff --git a/src/bin2cpp/main.cpp b/src/bin2cpp/main.cpp index 7e1ca09..8f85ded 100755 --- a/src/bin2cpp/main.cpp +++ b/src/bin2cpp/main.cpp @@ -29,6 +29,7 @@ #include "StringGenerator.h" #include "ArrayGenerator.h" #include "Win32ResourceGenerator.h" +#include "ManagerGenerator.h" #include "Context.h" #include @@ -138,7 +139,7 @@ bool generateFile(const Context & c, const std::string & output_file_path, bin2c bool generateManagerFile(const Context & c, const std::string & output_file_path, bin2cpp::IGenerator * generator); APP_ERROR_CODES processInputFile(const Context & c, bin2cpp::IGenerator * generator); APP_ERROR_CODES processInputDirectory(const Context & c, bin2cpp::IGenerator * generator); -APP_ERROR_CODES processManagerFiles(const Context & c, bin2cpp::IGenerator * generator); +APP_ERROR_CODES processManagerFiles(const Context & c); APP_ERROR_CODES processPlainOutput(const Context & c, bin2cpp::IGenerator * generator); std::string getDefaultFunctionIdentifier(const Context & c, Dictionary & identifiers_dictionary); std::string getDefaultHeaderFile(const Context & c); @@ -471,7 +472,7 @@ int main(int argc, char* argv[]) //should we also generate the FileManager class? if (c.hasManagerFile) { - APP_ERROR_CODES error = processManagerFiles(c, generator); + APP_ERROR_CODES error = processManagerFiles(c); if (error != APP_ERROR_SUCCESS) { ra::logging::Log(ra::logging::LOG_ERROR, "%s.", getErrorCodeDescription(error)); @@ -731,12 +732,12 @@ bool generateManagerFile(const Context & c, const std::string & output_file_path if (isCppHeaderFile(output_file_path)) { //generate header - result = generator->createManagerHeaderFile(output_file_path.c_str()); + result = generator->createCppHeaderFile(output_file_path.c_str()); } else { //generate cpp - result = generator->createManagerSourceFile(output_file_path.c_str()); + result = generator->createCppSourceFile(output_file_path.c_str()); } if (!result) { @@ -746,7 +747,7 @@ bool generateManagerFile(const Context & c, const std::string & output_file_path return result; } -APP_ERROR_CODES processManagerFiles(const Context & c, bin2cpp::IGenerator * generator) +APP_ERROR_CODES processManagerFiles(const Context & c) { // printing info std::string info; @@ -763,12 +764,16 @@ APP_ERROR_CODES processManagerFiles(const Context & c, bin2cpp::IGenerator * gen std::string outputHeaderPath = c.outputDirPath + ra::filesystem::GetPathSeparatorStr() + c.managerHeaderFilename; std::string outputCppPath = c.outputDirPath + ra::filesystem::GetPathSeparatorStr() + cppFilename; + //init generator + ManagerGenerator generator; + generator.setContext(c); + //process files - bool headerResult = generateManagerFile(c, outputHeaderPath, generator); + bool headerResult = generateManagerFile(c, outputHeaderPath, &generator); if (!headerResult) return APP_ERROR_UNABLETOCREATEOUTPUTFILES; - bool cppResult = generateManagerFile(c, outputCppPath, generator); + bool cppResult = generateManagerFile(c, outputCppPath, &generator); if (!cppResult) return APP_ERROR_UNABLETOCREATEOUTPUTFILES; From 131fc32a51f99e06016bf675fe715bde39ec1740 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sun, 27 Apr 2025 09:14:24 -0400 Subject: [PATCH 7/9] Deleted function `generateManagerFile()` in bin2cpp's main.cpp. The implementation is now identical to `generateFile()`. --- src/bin2cpp/main.cpp | 36 ++---------------------------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/src/bin2cpp/main.cpp b/src/bin2cpp/main.cpp index 8f85ded..ad8b578 100755 --- a/src/bin2cpp/main.cpp +++ b/src/bin2cpp/main.cpp @@ -136,7 +136,6 @@ struct ARGUMENTS //pre-declarations bool generateFile(const Context & c, const std::string & output_file_path, bin2cpp::IGenerator * generator); -bool generateManagerFile(const Context & c, const std::string & output_file_path, bin2cpp::IGenerator * generator); APP_ERROR_CODES processInputFile(const Context & c, bin2cpp::IGenerator * generator); APP_ERROR_CODES processInputDirectory(const Context & c, bin2cpp::IGenerator * generator); APP_ERROR_CODES processManagerFiles(const Context & c); @@ -716,37 +715,6 @@ bool generateFile(const Context & c, const std::string & output_file_path, bin2c return result; } -bool generateManagerFile(const Context & c, const std::string & output_file_path, bin2cpp::IGenerator * generator) -{ - std::string processPath = ra::process::GetCurrentProcessPath(); - FILE_UPDATE_MODE mode = getFileUpdateMode(processPath, output_file_path, c.overrideExistingFiles); - - //writing message - ra::logging::Log(ra::logging::LOG_INFO, "%s file \"%s\"...", getUpdateModeText(mode), output_file_path.c_str()); - - if (mode == SKIPPING) - return true; //skipping is success - - //generate file - bool result = false; - if (isCppHeaderFile(output_file_path)) - { - //generate header - result = generator->createCppHeaderFile(output_file_path.c_str()); - } - else - { - //generate cpp - result = generator->createCppSourceFile(output_file_path.c_str()); - } - if (!result) - { - //there was an error generating file - ra::logging::Log(ra::logging::LOG_ERROR, "%s failed!", getUpdateModeText(mode)); - } - return result; -} - APP_ERROR_CODES processManagerFiles(const Context & c) { // printing info @@ -769,11 +737,11 @@ APP_ERROR_CODES processManagerFiles(const Context & c) generator.setContext(c); //process files - bool headerResult = generateManagerFile(c, outputHeaderPath, &generator); + bool headerResult = generateFile(c, outputHeaderPath, &generator); if (!headerResult) return APP_ERROR_UNABLETOCREATEOUTPUTFILES; - bool cppResult = generateManagerFile(c, outputCppPath, &generator); + bool cppResult = generateFile(c, outputCppPath, &generator); if (!cppResult) return APP_ERROR_UNABLETOCREATEOUTPUTFILES; From 12964a056246b5f806a5a018b3680ad0612f9ed7 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sun, 27 Apr 2025 09:28:52 -0400 Subject: [PATCH 8/9] Fixed a bug in `processInputFile()` where the generator was initialized with the "original" Context instead of the copy. The copy is updated to prevent multiple output files to have the same name. --- src/bin2cpp/main.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/bin2cpp/main.cpp b/src/bin2cpp/main.cpp index ad8b578..53e53c4 100755 --- a/src/bin2cpp/main.cpp +++ b/src/bin2cpp/main.cpp @@ -524,13 +524,16 @@ APP_ERROR_CODES processInputFile(const Context & c, bin2cpp::IGenerator * genera if (!ra::filesystem::FileExists(c.inputFilePath.c_str())) return APP_ERROR_INPUTFILENOTFOUND; - Context cCopy = c; - //prepare output files path - std::string cppFilename = cCopy.headerFilename; + std::string cppFilename = c.headerFilename; ra::strings::Replace(cppFilename, ".hpp", ".cpp"); ra::strings::Replace(cppFilename, ".h", ".cpp"); + //create a copy of the context. + //we may have already generated files from a previous call to processInputFile(). + //make sure the file paths are unique. + Context cCopy = c; + //build unique output relative file paths cCopy.headerFilename = bin2cpp::getUniqueFilePath(cCopy.headerFilename, output_files_dictionary); cppFilename = bin2cpp::getUniqueFilePath(cppFilename, output_files_dictionary); @@ -540,7 +543,7 @@ APP_ERROR_CODES processInputFile(const Context & c, bin2cpp::IGenerator * genera std::string outputCppPath = cCopy.outputDirPath + ra::filesystem::GetPathSeparatorStr() + cppFilename; //configure the generator - generator->setContext(c); + generator->setContext(cCopy); //build the output directory structure if required if (cCopy.keepDirectoryStructure) @@ -732,8 +735,9 @@ APP_ERROR_CODES processManagerFiles(const Context & c) std::string outputHeaderPath = c.outputDirPath + ra::filesystem::GetPathSeparatorStr() + c.managerHeaderFilename; std::string outputCppPath = c.outputDirPath + ra::filesystem::GetPathSeparatorStr() + cppFilename; - //init generator ManagerGenerator generator; + + //configure the generator generator.setContext(c); //process files @@ -755,10 +759,8 @@ APP_ERROR_CODES processPlainOutput(const Context & c, bin2cpp::IGenerator * gene if (!ra::filesystem::FileExists(c.inputFilePath.c_str())) return APP_ERROR_INPUTFILENOTFOUND; - Context cCopy = c; - //configure the generator - generator->setContext(cCopy); + generator->setContext(c); //process file bool result = generator->printFileContent(); From 85fe48f7b5e320925c3f94502afa8b8e0c5ea9b2 Mon Sep 17 00:00:00 2001 From: Antoine Beauchamp Date: Sun, 27 Apr 2025 13:08:17 -0400 Subject: [PATCH 9/9] * Fixed issue #63: Context class redesign. Move arguments handling into a Context class. * Fixed issue #72: Move the code FileManager class generation code into its own IGenerator implementation. --- CHANGES | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES b/CHANGES index 3383d2d..8f89842 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ Changes for 3.1.0: +* Fixed issue #63: Context class redesign. Move arguments handling into a Context class. * 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. Changes for 3.0.1: