diff --git a/CMakeLists.txt b/CMakeLists.txt index 9864a10..2eb6e93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,14 +7,20 @@ set(CMAKE_CXX_STANDARD 17) FILE(GLOB_RECURSE SRC_LIST ${PROJECT_SOURCE_DIR}/src/*.cpp) add_executable(crpc + ${SRC_LIST} main.cpp src/item.cpp src/message.cpp - ${SRC_LIST} src/rpc.cpp src/service.cpp src/plugins/c/c_message_plugin.cpp - src/plugins/c/generators/c_item.cpp + src/plugins/c/items/c_item.cpp + src/plugins/service_plugin.cpp + src/plugins/plugin.cpp + src/plugins/c/c_service_server_plugin.cpp + src/plugins/c/rpcs/crpc_client.cpp + src/plugins/c/rpcs/crpc.cpp + src/plugins/c/c_service_plugin.cpp ) target_link_libraries(crpc PRIVATE antlr4_static) target_include_directories(crpc PRIVATE /opt/dev/vcpkg/installed/arm64-osx/include/antlr4-runtime) diff --git a/main.cpp b/main.cpp index 16b23c9..e90b90c 100644 --- a/main.cpp +++ b/main.cpp @@ -8,6 +8,8 @@ #include "message.h" #include "service.h" #include "plugins/c/c_message_plugin.h" +#include "plugins/c/c_service_server_plugin.h" +#include "plugins/c/c_service_client_plugin.h" #include #include #include @@ -107,5 +109,9 @@ main(int argc, char *argv[]) tqcq::CMessagePlugin message_plugin("./gen/"); message_plugin.Generate(listener.message_map); + tqcq::CServiceServerPlugin service_server_plugin("./gen/"); + service_server_plugin.Generate(listener.services); + // tqcq::CServiceClientPlugin service_client_plugin("./gen/"); + return 0; } diff --git a/src/ProtoParser.g4 b/src/ProtoParser.g4 index 859fc4d..e2ec2da 100644 --- a/src/ProtoParser.g4 +++ b/src/ProtoParser.g4 @@ -5,9 +5,9 @@ options{ tokenVocab='gen/ProtoLexer'; language=Cpp; } program: syntaxStatement baseStatement* EOF; syntaxStatement: SYNTAX_TYPE '=' '"' (VERSION2 | VERSION3) '"' ';'; -baseStatement: (messageStatement | serviceStatement | ';'); -messageStatement: MESSAGE_TYPE ID '{' itemStatement* '}' ';'; -serviceStatement: SERVICE_TYPE ID '{' rpcStatement* '}' ';'; +baseStatement: messageStatement | serviceStatement | ';'; +messageStatement: MESSAGE_TYPE ID '{' (itemStatement | ';')* '}'; +serviceStatement: SERVICE_TYPE ID '{' (rpcStatement | ';')* '}'; itemStatement: (INT32 | STRING) ID '=' NUMBER ';'; -rpcStatement: RPC_TYPE ID '(' ID ')' 'returns' '(' ID ')' ';'; +rpcStatement: RPC_TYPE ID '(' ID ')' 'returns' '(' ID ')' '{' '}'; diff --git a/src/plugins/c/c_message_plugin.cpp b/src/plugins/c/c_message_plugin.cpp index 545c4c3..814b8a4 100644 --- a/src/plugins/c/c_message_plugin.cpp +++ b/src/plugins/c/c_message_plugin.cpp @@ -6,7 +6,7 @@ #include #include #include -#include "generators/c_item.h" +#include "items/c_item.h" namespace tqcq { @@ -15,7 +15,9 @@ GenerateGuardMacro(std::string id, std::string prefix) { std::stringstream ss; ss << prefix << "_" << id << "_H_"; - return ss.str(); + auto str = ss.str(); + std::for_each(str.begin(), str.end(), [](char &c) { c = std::toupper(c); }); + return str; } std::string @@ -39,38 +41,29 @@ CMessagePlugin::CMessagePlugin(std::string generate_path, std::string generate_p {} void -CMessagePlugin::GenerateHeader(std::map message_map) +CMessagePlugin::GenerateHeader(tqcq::Message::Ptr message) { - for (auto &message : message_map) { - if (!message.second) { - std::cout << "message " << message.first << " is null" << std::endl; - continue; - } - - std::stringstream ss; - ss << GenerateIncludeGuardStart(message.second); - ss << GenerateIncludeFile(message.second); - ss << GenerateStructStart(message.second); - ss << GenerateStructItem(message.second); - ss << GenerateStructEnd(message.second); - ss << GenerateFunctionDeclaration(message.second); - ss << GenerateIncludeGuardEnd(message.second); - std::ofstream ofs(generate_path() + "/" + GenerateHeaderFileName(message.second->id())); - ofs << ss.str(); - std::cout << ss.str() << std::endl; - } + std::stringstream ss; + ss << GenerateIncludeGuardStart(message); + ss << GenerateIncludeFile(message); + ss << GenerateStructStart(message); + ss << GenerateStructItem(message); + ss << GenerateStructEnd(message); + ss << GenerateFunctionDeclaration(message); + ss << GenerateIncludeGuardEnd(message); + std::ofstream ofs(generate_path() + "/" + GenerateHeaderFileName(message->id())); + ofs << ss.str(); + std::cout << ss.str() << std::endl; } void -CMessagePlugin::GenerateSource(std::map message_map) +CMessagePlugin::GenerateSource(tqcq::Message::Ptr message) { - for (auto &message : message_map) { - std::stringstream ss; - ss << GenerateSourceIncludeFile(message.second); - ss << GenerateFunctionDefinition(message.second); - std::ofstream ofs(generate_path() + "/" + GenerateSourceFileName(message.second->id())); - ofs << ss.str(); - } + std::stringstream ss; + ss << GenerateSourceIncludeFile(message); + ss << GenerateFunctionDefinition(message); + std::ofstream ofs(generate_path() + "/" + GenerateSourceFileName(message->id())); + ofs << ss.str(); } std::string @@ -82,10 +75,6 @@ CMessagePlugin::GenerateIncludeGuardStart(Message::Ptr message) ss << "#define " << guard_macro << std::endl; ss << std::endl; - ss << "#ifdef __cplusplus" << std::endl; - ss << "extern \"C\" {" << std::endl; - ss << "#endif" << std::endl; - ss << std::endl; return ss.str(); } @@ -106,6 +95,12 @@ CMessagePlugin::GenerateIncludeFile(Message::Ptr message) std::stringstream ss; ss << "#include " << std::endl; ss << std::endl; + + ss << "#ifdef __cplusplus" << std::endl; + ss << "extern \"C\" {" << std::endl; + ss << "#endif" << std::endl; + ss << std::endl; + return ss.str(); } @@ -180,7 +175,6 @@ CMessagePlugin::GenerateFunctionDefinition(Message::Ptr message) } ss << std::endl; - return ss.str(); } @@ -194,6 +188,7 @@ CMessagePlugin::GenerateSourceIncludeFile(Message::Ptr message) ss << std::endl; return ss.str(); } + std::string CMessagePlugin::GenerateFunctionDefinitionSerialize(Message::Ptr message) { diff --git a/src/plugins/c/c_message_plugin.h b/src/plugins/c/c_message_plugin.h index 9a2e14c..5aed4d7 100644 --- a/src/plugins/c/c_message_plugin.h +++ b/src/plugins/c/c_message_plugin.h @@ -12,10 +12,10 @@ namespace tqcq { class CMessagePlugin : public MessagePlugin { public: static std::string GenerateHeaderFileName(std::string message_id); - CMessagePlugin(std::string generate_path, std::string generate_prefix="CRPC"); + CMessagePlugin(std::string generate_path, std::string generate_prefix="CMessage"); ~CMessagePlugin() override = default; - void GenerateHeader(std::map message_map) override; - void GenerateSource(std::map message_map) override; + void GenerateHeader(Message::Ptr message_map) override; + void GenerateSource(Message::Ptr message_map) override; private: std::string GenerateIncludeGuardStart(Message::Ptr message); @@ -29,18 +29,12 @@ private: std::string GenerateFunctionDeclaration(Message::Ptr message); std::string GenerateFunctionDefinition(Message::Ptr message); - std::string GenerateFunctionDefinitionGetter(Message::Ptr message, Item::Ptr item); - std::string GenerateFunctionDefinitionSetter(Message::Ptr message, Item::Ptr item); std::string GenerateFunctionDefinitionSerialize(Message::Ptr message); std::string GenerateFunctionDefinitionDeserialize(Message::Ptr message); std::string GenerateFunctionDefinitionInit(Message::Ptr message); std::string GenerateFunctionDefinitionDestroy(Message::Ptr message); - std::string GenerateSourceIncludeFile(Message::Ptr message); - - std::string TranslateTypeToCType(Message::Ptr message, Item::Type type); - std::string TranslateTypeToRealType(Message::Ptr message, Item::Type type); }; }// namespace tqcq diff --git a/src/plugins/c/c_service_client_plugin.cpp b/src/plugins/c/c_service_client_plugin.cpp new file mode 100644 index 0000000..131d295 --- /dev/null +++ b/src/plugins/c/c_service_client_plugin.cpp @@ -0,0 +1,13 @@ +// +// Created by tqcq on 2023/12/2. +// + +#include "c_service_client_plugin.h" + +#include + +namespace tqcq { +CServiceClientPlugin::CServiceClientPlugin(std::string generate_path, std::string generate_prefix) + : CServicePlugin(std::move(generate_path), std::move(generate_prefix)) +{} +}// namespace tqcq diff --git a/src/plugins/c/c_service_client_plugin.h b/src/plugins/c/c_service_client_plugin.h new file mode 100644 index 0000000..47d1e67 --- /dev/null +++ b/src/plugins/c/c_service_client_plugin.h @@ -0,0 +1,21 @@ +// +// Created by tqcq on 2023/12/2. +// + +#ifndef CRPC_SRC_PLUGINS_C_C_SERVICE_CLIENT_PLUGIN_H_ +#define CRPC_SRC_PLUGINS_C_C_SERVICE_CLIENT_PLUGIN_H_ + +#include "c_service_plugin.h" + +namespace tqcq { + +class CServiceClientPlugin : public CServicePlugin { +public: + CServiceClientPlugin(std::string generate_path, std::string generate_prefix = "CService"); + virtual ~CServiceClientPlugin() = default; +protected: +}; + +}// namespace tqcq + +#endif//CRPC_SRC_PLUGINS_C_C_SERVICE_CLIENT_PLUGIN_H_ diff --git a/src/plugins/c/c_service_plugin.cpp b/src/plugins/c/c_service_plugin.cpp new file mode 100644 index 0000000..5407e20 --- /dev/null +++ b/src/plugins/c/c_service_plugin.cpp @@ -0,0 +1,60 @@ +// +// Created by tqcq on 2023/12/2. +// + +#include "c_service_plugin.h" +#include +#include + +namespace tqcq { + + +std::string +GenerateHeaderFileName(std::string id) +{ + std::stringstream ss; + ss << id << ".h"; + return ss.str(); +} + +std::string +CServicePlugin::GenerateGuardMacro(std::string id, std::string prefix) +{ + std::stringstream ss; + ss << prefix << "_" << id << "_H_"; + auto str = ss.str(); + std::for_each(str.begin(), str.end(), [](char &c) { c = std::toupper(c); }); + return str; +} + +CServicePlugin::CServicePlugin(std::string generate_path, std::string generate_prefix) + : ServicePlugin(generate_path, generate_prefix) +{ +} + +void +CServicePlugin::GenerateHeader(Service::Ptr service) +{ + std::stringstream ss; + ss << GenerateHeaderGuardStart(service); + ss << GenerateHeaderIncludeFiles(service); + ss << std::endl; + + ss << GenerateHeaderStructStart(service); + ss << GenerateHeaderStructItems(service); + ss << GenerateHeaderStructEnd(service); + ss << std::endl; + + ss << GenerateHeaderFunctionDeclaration(service); + ss << std::endl; + + ss << GenerateHeaderGuardEnd(service); + std::ofstream ofs(generate_path() + "/" + GenerateHeaderFileName(service->id())); + ofs << ss.str(); +} + +void +CServicePlugin::GenerateSource(Service::Ptr service) +{ +} +}// namespace tqcq diff --git a/src/plugins/c/c_service_plugin.h b/src/plugins/c/c_service_plugin.h new file mode 100644 index 0000000..51a5b1a --- /dev/null +++ b/src/plugins/c/c_service_plugin.h @@ -0,0 +1,35 @@ +// +// Created by tqcq on 2023/12/2. +// + +#ifndef CRPC_SRC_PLUGINS_C_C_SERVICE_PLUGIN_H_ +#define CRPC_SRC_PLUGINS_C_C_SERVICE_PLUGIN_H_ + +#include "plugins/service_plugin.h" + +namespace tqcq { + +class CServicePlugin : public ServicePlugin { +public: + using Ptr = std::shared_ptr; + static std::string GenerateGuardMacro(std::string id, std::string prefix); + + CServicePlugin(std::string generate_path, std::string generate_prefix = "CService"); + virtual ~CServicePlugin() = default; +protected: + virtual void GenerateHeader(Service::Ptr service) override; + virtual void GenerateSource(Service::Ptr service) override; + + virtual std::string GenerateHeaderGuardStart(Service::Ptr service) = 0; + virtual std::string GenerateHeaderIncludeFiles(Service::Ptr service) = 0; + virtual std::string GenerateHeaderGuardEnd(Service::Ptr service) = 0; + + virtual std::string GenerateHeaderStructStart(Service::Ptr service) = 0; + virtual std::string GenerateHeaderStructItems(Service::Ptr service) = 0; + virtual std::string GenerateHeaderStructEnd(Service::Ptr service) = 0; + virtual std::string GenerateHeaderFunctionDeclaration(Service::Ptr service) = 0; +}; + +}// namespace tqcq + +#endif//CRPC_SRC_PLUGINS_C_C_SERVICE_PLUGIN_H_ diff --git a/src/plugins/c/c_service_server_plugin.cpp b/src/plugins/c/c_service_server_plugin.cpp new file mode 100644 index 0000000..e6f9144 --- /dev/null +++ b/src/plugins/c/c_service_server_plugin.cpp @@ -0,0 +1,96 @@ +// +// Created by tqcq on 2023/12/2. +// + +#include "c_service_server_plugin.h" +#include +#include "rpcs/crpc_server.h" + +namespace tqcq { +CServiceServerPlugin::CServiceServerPlugin(std::string generate_path, std::string generate_prefix) + : CServicePlugin(generate_path, generate_prefix) +{} + +std::string +CServiceServerPlugin::GenerateHeaderGuardStart(Service::Ptr service) +{ + std::stringstream ss; + auto guard_macro = GenerateGuardMacro(service->id(), generate_prefix()); + ss << "#ifndef " << guard_macro << std::endl; + ss << "#define " << guard_macro << std::endl; + + return ss.str(); +} + +std::string +CServiceServerPlugin::GenerateHeaderIncludeFiles(Service::Ptr service) +{ + std::stringstream ss; + ss << "#include " << std::endl; + ss << "#include " << std::endl; + ss << "#include " << std::endl; + ss << "#include " << std::endl; + std::set message_set; + for (const auto& rpc : service->rpcs()) { + auto crpc = CRPCServer::Create(rpc); + message_set.insert(crpc->request_id()); + message_set.insert(crpc->response_id()); + } + for (const auto& message_id : message_set) { + ss << "#include \"" << message_id << ".h\"" << std::endl; + } + ss << std::endl; + + ss << "#ifdef __cplusplus" << std::endl; + ss << "extern \"C\" {" << std::endl; + ss << "#endif" << std::endl; + return ss.str(); +} + +std::string +CServiceServerPlugin::GenerateHeaderGuardEnd(Service::Ptr service) +{ + std::stringstream ss; + auto guard_macro = GenerateGuardMacro(service->id(), generate_prefix()); + ss << "#ifdef __cplusplus" << std::endl; + ss << "}" << std::endl; + ss << "#endif" << std::endl; + ss << "#endif // " << guard_macro << std::endl; + return ss.str(); +} + +std::string +CServiceServerPlugin::GenerateHeaderStructStart(Service::Ptr service) +{ + std::stringstream ss; + ss << "typedef struct " << "{" << std::endl; + return ss.str(); +} + +std::string +CServiceServerPlugin::GenerateHeaderStructItems(Service::Ptr service) +{ + std::stringstream ss; + for (const auto& rpc : service->rpcs()) { + auto crpc = CRPCServer::Create(rpc); + ss << crpc->GenerateStructDeclareCodeBlock(service->id()); + } + return ss.str(); +} + +std::string +CServiceServerPlugin::GenerateHeaderStructEnd(Service::Ptr service) +{ + std::stringstream ss; + ss << "} " << service->id() << ";" << std::endl; + return ss.str(); +} + +std::string +CServiceServerPlugin::GenerateHeaderFunctionDeclaration(Service::Ptr service) +{ + return std::string(); +} + + +}// namespace tqcq diff --git a/src/plugins/c/c_service_server_plugin.h b/src/plugins/c/c_service_server_plugin.h new file mode 100644 index 0000000..f4a6686 --- /dev/null +++ b/src/plugins/c/c_service_server_plugin.h @@ -0,0 +1,28 @@ +// +// Created by tqcq on 2023/12/2. +// + +#ifndef CService_SRC_PLUGINS_C_ITEMS_C_SERVICE_SERVER_PLUGIN_H_ +#define CService_SRC_PLUGINS_C_ITEMS_C_SERVICE_SERVER_PLUGIN_H_ + +#include "c_service_plugin.h" + +namespace tqcq { + +class CServiceServerPlugin : public CServicePlugin { +public: + CServiceServerPlugin(std::string generate_path, std::string generate_prefix = "CService"); + virtual ~CServiceServerPlugin() = default; +protected: + std::string GenerateHeaderGuardStart(Service::Ptr service) override; + std::string GenerateHeaderIncludeFiles(Service::Ptr service) override; + std::string GenerateHeaderGuardEnd(Service::Ptr service) override; + std::string GenerateHeaderStructStart(Service::Ptr service) override; + std::string GenerateHeaderStructItems(Service::Ptr service) override; + std::string GenerateHeaderStructEnd(Service::Ptr service) override; + std::string GenerateHeaderFunctionDeclaration(Service::Ptr service) override; +}; + +}// namespace tqcq + +#endif//CService_SRC_PLUGINS_C_ITEMS_C_SERVICE_SERVER_PLUGIN_H_ diff --git a/src/plugins/c/items/c_item.cpp b/src/plugins/c/items/c_item.cpp new file mode 100644 index 0000000..68333d2 --- /dev/null +++ b/src/plugins/c/items/c_item.cpp @@ -0,0 +1,24 @@ +// +// Created by tqcq on 2023/12/2. +// + +#include "c_item.h" +#include "assert.h" +#include "c_item_int_32.h" +#include "c_item_string.h" + +namespace tqcq { +CItem::Ptr +CItem::Create(Item::Ptr item) +{ + assert(item); + switch (item->type()) { + case Item::Type::kInt32: + return std::make_shared(item); + case Item::Type::kString: + return std::make_shared(item); + default: + assert(false); + } +} +}// namespace tqcq diff --git a/src/plugins/c/items/c_item.h b/src/plugins/c/items/c_item.h new file mode 100644 index 0000000..03ec428 --- /dev/null +++ b/src/plugins/c/items/c_item.h @@ -0,0 +1,39 @@ +// +// Created by tqcq on 2023/12/2. +// + +#ifndef CRPC_SRC_PLUGINS_C_GENERATORS_C_ITEM_H_ +#define CRPC_SRC_PLUGINS_C_GENERATORS_C_ITEM_H_ + +#include +#include +#include "item.h" + +namespace tqcq { + +class CItem : public Item { +public: + using Ptr = std::shared_ptr; + static Ptr Create(Item::Ptr item); + + CItem() = delete; + CItem(Item::Ptr item) : Item(item->type(), item->id(), item->idx()) {}; + ~CItem() override = default; + virtual std::string GenerateStructDeclareCodeBlock(std::string message_id) const = 0; + + virtual std::string GenerateInitCodeBlock(std::string message_id) const = 0; + virtual std::string GenerateDestroyCodeBlock(std::string message_id) const = 0; + + virtual std::string GenerateSetterDeclaration(std::string message_id) const = 0; + virtual std::string GenerateSetterDefinition(std::string message_id) const = 0; + + virtual std::string GenerateGetterDefinition(std::string message_id) const = 0; + virtual std::string GenerateGetterDeclaration(std::string message_id) const = 0; + + virtual std::string GenerateSerializeCodeBlock(std::string message_id) const = 0; + virtual std::string GenerateDeserializeCodeBlock(std::string message_id) const = 0; +}; + +}// namespace tqcq + +#endif//CRPC_SRC_PLUGINS_C_GENERATORS_C_ITEM_H_ diff --git a/src/plugins/c/items/c_item_int_32.cpp b/src/plugins/c/items/c_item_int_32.cpp new file mode 100644 index 0000000..e1a8951 --- /dev/null +++ b/src/plugins/c/items/c_item_int_32.cpp @@ -0,0 +1,78 @@ +// +// Created by tqcq on 2023/12/2. +// + +#include "c_item_int_32.h" +#include + +namespace tqcq { +CItemInt32::CItemInt32(Item::Ptr item) : CItem(item) {} + +std::string +CItemInt32::GenerateStructDeclareCodeBlock(std::string message_id) const +{ + return " int32_t " + id() + ";"; +} + +std::string +CItemInt32::GenerateInitCodeBlock(std::string message_id) const +{ + std::stringstream ss; + ss << " " << "message->" << id() << " = 0;"; + return ss.str(); +} + +std::string +CItemInt32::GenerateDestroyCodeBlock(std::string message_id) const +{ + return " // do nothing for " + id() + " destroy"; +} + +std::string +CItemInt32::GenerateSetterDeclaration(std::string message_id) const +{ + return "void " + message_id + "_set_" + id() + "(" + message_id + "* message, int32_t " + id() + ");"; +} + +std::string +CItemInt32::GenerateSetterDefinition(std::string message_id) const +{ + std::stringstream ss; + ss << "void " << message_id << "_set_" << id() << "(" << message_id << "* message, int32_t " << id() << ") {" << std::endl; + ss << " message->" << id() << " = " << id() << ";" << std::endl; + ss << "}" << std::endl; + ss << std::endl; + return ss.str(); +} + +std::string +CItemInt32::GenerateGetterDefinition(std::string message_id) const +{ + std::stringstream ss; + ss << "int32_t " << message_id << "_get_" << id() << "(const " << message_id << "* message) {" << std::endl; + ss << " return message->" << id() << ";" << std::endl; + ss << "}" << std::endl; + ss << std::endl; + return ss.str(); +} + +std::string +CItemInt32::GenerateGetterDeclaration(std::string message_id) const +{ + std::stringstream ss; + ss << "int32_t " << message_id << "_get_" << id() << "(const " << message_id << "* message);"; + return ss.str(); +} + +std::string +CItemInt32::GenerateSerializeCodeBlock(std::string message_id) const +{ + return " // implement me for " + message_id + "_" + id() + " serialize"; +} + +std::string +CItemInt32::GenerateDeserializeCodeBlock(std::string message_id) const +{ + return " // implement me for " + id() + " deserialize"; +} +}// namespace tqcq diff --git a/src/plugins/c/items/c_item_int_32.h b/src/plugins/c/items/c_item_int_32.h new file mode 100644 index 0000000..10b7c43 --- /dev/null +++ b/src/plugins/c/items/c_item_int_32.h @@ -0,0 +1,35 @@ +// +// Created by tqcq on 2023/12/2. +// + +#ifndef CRPC_SRC_PLUGINS_C_GENERATORS_C_ITEM_INT_32_H_ +#define CRPC_SRC_PLUGINS_C_GENERATORS_C_ITEM_INT_32_H_ + +#include "c_item.h" + +namespace tqcq { + +class CItemInt32 : public CItem { +public: + using Ptr = std::shared_ptr; + + CItemInt32(Item::Ptr item); + ~CItemInt32() override = default; + std::string GenerateStructDeclareCodeBlock(std::string message_id) const override; + + std::string GenerateInitCodeBlock(std::string message_id) const override; + std::string GenerateDestroyCodeBlock(std::string message_id) const override; + + std::string GenerateSetterDeclaration(std::string message_id) const override; + std::string GenerateSetterDefinition(std::string message_id) const override; + + std::string GenerateGetterDefinition(std::string message_id) const override; + std::string GenerateGetterDeclaration(std::string message_id) const override; + + std::string GenerateSerializeCodeBlock(std::string message_id) const override; + std::string GenerateDeserializeCodeBlock(std::string message_id) const override; +}; + +}// namespace tqcq + +#endif//CRPC_SRC_PLUGINS_C_GENERATORS_C_ITEM_INT_32_H_ diff --git a/src/plugins/c/items/c_item_string.cpp b/src/plugins/c/items/c_item_string.cpp new file mode 100644 index 0000000..0741a16 --- /dev/null +++ b/src/plugins/c/items/c_item_string.cpp @@ -0,0 +1,87 @@ +// +// Created by tqcq on 2023/12/2. +// + +#include "c_item_string.h" +#include + +namespace tqcq { +CItemString::CItemString(Item::Ptr item) : CItem(item) {} + +std::string +CItemString::GenerateStructDeclareCodeBlock(std::string message_id) const +{ + return " char* " + id() + ";"; +} + +std::string +CItemString::GenerateInitCodeBlock(std::string message_id) const +{ + return " message->" + id() + " = NULL;"; +} + +std::string +CItemString::GenerateDestroyCodeBlock(std::string message_id) const +{ + std::stringstream ss; + ss << " if (message->" << id() << ") {" << std::endl; + ss << " free(message->" << id() << ");" << std::endl; + ss << " message->" << id() << " = NULL;" << std::endl; + ss << " }" << std::endl; + return ss.str(); + return ss.str(); +} + +std::string +CItemString::GenerateSetterDeclaration(std::string message_id) const +{ + std::stringstream ss; + ss << "void " << message_id << "_set_" << id() << "(" << message_id << "* message, const char* " << id() << ");"; + return ss.str(); +} + +std::string +CItemString::GenerateSetterDefinition(std::string message_id) const +{ + std::stringstream ss; + ss << "void " << message_id << "_set_" << id() << "(" << message_id << "* message, const char* " << id() << ") {" << std::endl; + ss << " if (message->" << id() << ") {" << std::endl; + ss << " free(message->" << id() << ");" << std::endl; + ss << " }" << std::endl; + ss << " message->" << id() << " = strdup(" << id() << ");" << std::endl; + ss << "}" << std::endl; + ss << std::endl; + return ss.str(); +} + +std::string +CItemString::GenerateGetterDefinition(std::string message_id) const +{ + std::stringstream ss; + ss << "const char* " << message_id << "_get_" << id() << "(const " << message_id << "* message) {" << std::endl; + ss << " return message->" << id() << ";" << std::endl; + ss << "}" << std::endl; + ss << std::endl; + return ss.str(); +} + +std::string +CItemString::GenerateGetterDeclaration(std::string message_id) const +{ + std::stringstream ss; + ss << "const char* " << message_id << "_get_" << id() << "(const " << message_id << "* message);"; + return ss.str(); +} + +std::string +CItemString::GenerateSerializeCodeBlock(std::string message_id) const +{ + return " // not implemented yet for " + id() + " serialize"; +} + +std::string +CItemString::GenerateDeserializeCodeBlock(std::string message_id) const +{ + return " // not implemented yet for " + id() + " deserialize"; +} +}// namespace tqcq diff --git a/src/plugins/c/items/c_item_string.h b/src/plugins/c/items/c_item_string.h new file mode 100644 index 0000000..f6c6354 --- /dev/null +++ b/src/plugins/c/items/c_item_string.h @@ -0,0 +1,35 @@ +// +// Created by tqcq on 2023/12/2. +// + +#ifndef CRPC_SRC_PLUGINS_C_GENERATORS_C_ITEM_STRING_H_ +#define CRPC_SRC_PLUGINS_C_GENERATORS_C_ITEM_STRING_H_ + +#include "c_item.h" + +namespace tqcq { + +class CItemString : public CItem { +public: + using Ptr = std::shared_ptr; + + CItemString(Item::Ptr item); + ~CItemString() override = default; + std::string GenerateStructDeclareCodeBlock(std::string message_id) const override; + + std::string GenerateInitCodeBlock(std::string message_id) const override; + std::string GenerateDestroyCodeBlock(std::string message_id) const override; + + std::string GenerateSetterDeclaration(std::string message_id) const override; + std::string GenerateSetterDefinition(std::string message_id) const override; + + std::string GenerateGetterDefinition(std::string message_id) const override; + std::string GenerateGetterDeclaration(std::string message_id) const override; + + std::string GenerateSerializeCodeBlock(std::string message_id) const override; + std::string GenerateDeserializeCodeBlock(std::string message_id) const override; +}; + +}// namespace tqcq + +#endif//CRPC_SRC_PLUGINS_C_GENERATORS_C_ITEM_STRING_H_ diff --git a/src/plugins/c/rpcs/crpc.cpp b/src/plugins/c/rpcs/crpc.cpp new file mode 100644 index 0000000..7a4b26c --- /dev/null +++ b/src/plugins/c/rpcs/crpc.cpp @@ -0,0 +1,9 @@ +// +// Created by tqcq on 2023/12/2. +// + +#include "crpc.h" + +namespace tqcq { +CRPC::CRPC(RPC::Ptr rpc) : RPC(rpc->id(), rpc->request_id(), rpc->response_id()) {} +}// namespace tqcq diff --git a/src/plugins/c/rpcs/crpc.h b/src/plugins/c/rpcs/crpc.h new file mode 100644 index 0000000..87c96a5 --- /dev/null +++ b/src/plugins/c/rpcs/crpc.h @@ -0,0 +1,26 @@ +// +// Created by tqcq on 2023/12/2. +// + +#ifndef CRPC_SRC_PLUGINS_C_RPCS_CRPC_H_ +#define CRPC_SRC_PLUGINS_C_RPCS_CRPC_H_ + +#include +#include +#include +#include +#include "rpc.h" + +namespace tqcq { + +class CRPC : public RPC { +public: + CRPC(RPC::Ptr rpc); + virtual ~CRPC() = default; + + virtual std::string GenerateStructDeclareCodeBlock(std::string service_id) const = 0; +}; + +}// namespace tqcq + +#endif//CRPC_SRC_PLUGINS_C_RPCS_CRPC_H_ diff --git a/src/plugins/c/rpcs/crpc_client.cpp b/src/plugins/c/rpcs/crpc_client.cpp new file mode 100644 index 0000000..1005867 --- /dev/null +++ b/src/plugins/c/rpcs/crpc_client.cpp @@ -0,0 +1,7 @@ +// +// Created by tqcq on 2023/12/2. +// + +#include "crpc_client.h" + +namespace tqcq {}// namespace tqcq diff --git a/src/plugins/c/rpcs/crpc_client.h b/src/plugins/c/rpcs/crpc_client.h new file mode 100644 index 0000000..ec2f8e5 --- /dev/null +++ b/src/plugins/c/rpcs/crpc_client.h @@ -0,0 +1,17 @@ +// +// Created by tqcq on 2023/12/2. +// + +#ifndef CRPC_SRC_PLUGINS_C_RPCS_CRPC_CLIENT_H_ +#define CRPC_SRC_PLUGINS_C_RPCS_CRPC_CLIENT_H_ + +#include "crpc.h" + +namespace tqcq { + +class CRPCClient : public CRPC { +}; + +}// namespace tqcq + +#endif//CRPC_SRC_PLUGINS_C_RPCS_CRPC_CLIENT_H_ diff --git a/src/plugins/c/rpcs/crpc_server.cpp b/src/plugins/c/rpcs/crpc_server.cpp new file mode 100644 index 0000000..a6b92ce --- /dev/null +++ b/src/plugins/c/rpcs/crpc_server.cpp @@ -0,0 +1,25 @@ +// +// Created by tqcq on 2023/12/2. +// + +#include "crpc_server.h" +#include + +namespace tqcq { +CRPCServer::Ptr +CRPCServer::Create(RPC::Ptr rpc) +{ + return std::make_shared(rpc); +} + +CRPCServer::CRPCServer(RPC::Ptr rpc) : CRPC(rpc) {} + +std::string +CRPCServer::GenerateStructDeclareCodeBlock(std::string service_id) const +{ + std::stringstream ss; + ss << " void (*" << id() << ")(Service *service, " << request_id() << " *request, " << response_id() << " **response);\n"; + return ss.str(); +} + +}// namespace tqcq diff --git a/src/plugins/c/rpcs/crpc_server.h b/src/plugins/c/rpcs/crpc_server.h new file mode 100644 index 0000000..e2d8fb0 --- /dev/null +++ b/src/plugins/c/rpcs/crpc_server.h @@ -0,0 +1,25 @@ +// +// Created by tqcq on 2023/12/2. +// + +#ifndef CRPC_SRC_PLUGINS_C_RPCS_CRPC_SERVER_H_ +#define CRPC_SRC_PLUGINS_C_RPCS_CRPC_SERVER_H_ + +#include "crpc.h" + +namespace tqcq { + +class CRPCServer : public CRPC { +public: + using Ptr = std::shared_ptr; + static Ptr Create(RPC::Ptr rpc); + + CRPCServer(RPC::Ptr rpc); + ~CRPCServer() override = default; + + std::string GenerateStructDeclareCodeBlock(std::string service_id) const override; +}; + +}// namespace tqcq + +#endif//CRPC_SRC_PLUGINS_C_RPCS_CRPC_SERVER_H_ diff --git a/src/plugins/message_plugin.cpp b/src/plugins/message_plugin.cpp index 3afe4ea..0088a38 100644 --- a/src/plugins/message_plugin.cpp +++ b/src/plugins/message_plugin.cpp @@ -9,46 +9,19 @@ namespace tqcq { -static void EnsureDirectoryExist(std::string path) -{ - std::string::size_type pos = 0; - while (true) { - pos = path.find('/', pos); - if (pos == std::string::npos) { - break; - } - std::string dir = path.substr(0, pos); - int status = mkdir(dir.c_str(), 0755); - if (status != 0 && errno != EEXIST) { - perror("mkdir"); - exit(1); - } - pos++; - } -} MessagePlugin::MessagePlugin(std::string generate_path, std::string generate_prefix) -: generate_path_(std::move(generate_path)), generate_prefix_(std::move(generate_prefix)) +: Plugin(std::move(generate_path), std::move(generate_prefix)) { - EnsureDirectoryExist(generate_path_); } void MessagePlugin::Generate(std::map message_map) { - GenerateHeader(message_map); - GenerateSource(message_map); + for (auto &pair : message_map) { + GenerateHeader(pair.second); + GenerateSource(pair.second); + } } -std::string -MessagePlugin::generate_path() const -{ - return generate_path_; -} - -std::string -MessagePlugin::generate_prefix() const -{ - return generate_prefix_; -} }// namespace tqcq diff --git a/src/plugins/message_plugin.h b/src/plugins/message_plugin.h index 100682d..4d5de7a 100644 --- a/src/plugins/message_plugin.h +++ b/src/plugins/message_plugin.h @@ -8,22 +8,18 @@ #include #include #include "message.h" +#include "plugin.h" namespace tqcq { -class MessagePlugin { +class MessagePlugin : public Plugin { public: MessagePlugin(std::string generate_path, std::string generate_prefix="CRPC"); virtual ~MessagePlugin() = default; virtual void Generate(std::map message_map); - std::string generate_path() const; - std::string generate_prefix() const; protected: - virtual void GenerateHeader(std::map message_map) {}; - virtual void GenerateSource(std::map message_map) {}; -private: - std::string generate_path_; - std::string generate_prefix_; + virtual void GenerateHeader(Message::Ptr message) {}; + virtual void GenerateSource(Message::Ptr message) {}; }; }// namespace tqcq diff --git a/src/plugins/plugin.cpp b/src/plugins/plugin.cpp new file mode 100644 index 0000000..c79b101 --- /dev/null +++ b/src/plugins/plugin.cpp @@ -0,0 +1,45 @@ +// +// Created by tqcq on 2023/12/2. +// + +#include "plugin.h" +#include + +namespace tqcq { + +static void EnsureDirectoryExist(std::string path) +{ + std::string::size_type pos = 0; + while (true) { + pos = path.find('/', pos); + if (pos == std::string::npos) { + break; + } + std::string dir = path.substr(0, pos); + int status = mkdir(dir.c_str(), 0755); + if (status != 0 && errno != EEXIST) { + perror("mkdir"); + exit(1); + } + pos++; + } +} + +Plugin::Plugin(std::string generate_path, std::string generate_prefix) +: generate_path_(std::move(generate_path)), generate_prefix_(std::move(generate_prefix)) +{ + EnsureDirectoryExist(generate_path_); +} + +std::string +Plugin::generate_path() const +{ + return generate_path_; +} + +std::string +Plugin::generate_prefix() const +{ + return generate_prefix_; +} +}// namespace tqcq diff --git a/src/plugins/plugin.h b/src/plugins/plugin.h new file mode 100644 index 0000000..45ef5e8 --- /dev/null +++ b/src/plugins/plugin.h @@ -0,0 +1,25 @@ +// +// Created by tqcq on 2023/12/2. +// + +#ifndef CRPC_SRC_PLUGINS_PLUGIN_H_ +#define CRPC_SRC_PLUGINS_PLUGIN_H_ + +#include + +namespace tqcq { + +class Plugin { +public: + Plugin(std::string generate_path, std::string generate_prefix="CRPC"); + virtual ~Plugin() = default; + std::string generate_path() const; + std::string generate_prefix() const; +private: + std::string generate_path_; + std::string generate_prefix_; +}; + +}// namespace tqcq + +#endif//CRPC_SRC_PLUGINS_PLUGIN_H_ diff --git a/src/plugins/service_plugin.cpp b/src/plugins/service_plugin.cpp new file mode 100644 index 0000000..ea480c1 --- /dev/null +++ b/src/plugins/service_plugin.cpp @@ -0,0 +1,22 @@ +// +// Created by tqcq on 2023/12/2. +// + +#include "service_plugin.h" + +namespace tqcq { + + +ServicePlugin::ServicePlugin(std::string generate_path, std::string generate_prefix) + : Plugin(generate_path, generate_prefix) +{} + +void +ServicePlugin::Generate(std::vector services) +{ + for (auto &service : services) { + GenerateHeader(service); + GenerateSource(service); + } +} +}// namespace tqcq diff --git a/src/plugins/service_plugin.h b/src/plugins/service_plugin.h new file mode 100644 index 0000000..34821de --- /dev/null +++ b/src/plugins/service_plugin.h @@ -0,0 +1,27 @@ +// +// Created by tqcq on 2023/12/2. +// + +#ifndef CService_SRC_PLUGINS_SERVICE_PLUGIN_H_ +#define CService_SRC_PLUGINS_SERVICE_PLUGIN_H_ +#include +#include +#include "service.h" +#include "plugin.h" + +namespace tqcq { + +class ServicePlugin : public Plugin { +public: + ServicePlugin(std::string generate_path, std::string generate_prefix = "CService"); + virtual ~ServicePlugin() = default; + virtual void Generate(std::vector services); + +protected: + virtual void GenerateHeader(Service::Ptr service){}; + virtual void GenerateSource(Service::Ptr service){}; +}; + +}// namespace tqcq + +#endif//CService_SRC_PLUGINS_SERVICE_PLUGIN_H_ diff --git a/src/test.proto b/src/test.proto index 3e3db1c..401beec 100644 --- a/src/test.proto +++ b/src/test.proto @@ -1,16 +1,29 @@ syntax = "proto3"; -message TestMessage { - int32 id = 1; - string name = 2; -}; +message Empty { +} -service TestService { - rpc TestMethod(TestMessage) returns (TestMessage); -}; +message StatusResponse { + int32 code = 1; + string msg = 2; +} -message SearchRequest { - string query = 1; - int32 page_number = 2; - int32 results_per_page = 3; -}; \ No newline at end of file +message ApplicationPINRequest { + int32 retry_count = 1; + string admin_pin = 2; + string new_user_pin = 3; + string old = 4; + string new = 5; + string pin = 6; +} + +service Device { + rpc Init(Empty) returns (StatusResponse) {} + rpc Status(Empty) returns (StatusResponse) {} + rpc Close(Empty) returns (StatusResponse) {} + rpc ClearApp(Empty) returns (Empty) {} + + rpc UnlockApplicationPIN(ApplicationPINRequest) returns (StatusResponse) {} + rpc ChangeApplicationPIN(ApplicationPINRequest) returns (StatusResponse) {} + rpc VerifyApplicationPIN(ApplicationPINRequest) returns (StatusResponse) {} +} \ No newline at end of file