From 7003f08f3a7895c02e41064523627da9a48ebc24 Mon Sep 17 00:00:00 2001 From: tqcq <99722391+tqcq@users.noreply.github.com> Date: Sat, 2 Dec 2023 15:31:16 +0800 Subject: [PATCH] feature support msg set_data --- src/plugins/c/c_message_plugin.cpp | 145 ++++++++++++++++++++-- src/plugins/c/c_service_plugin.cpp | 13 +- src/plugins/c/c_service_plugin.h | 8 ++ src/plugins/c/c_service_server_plugin.cpp | 45 ++++++- src/plugins/c/c_service_server_plugin.h | 8 ++ src/plugins/c/items/c_item_string.cpp | 42 +++++-- src/plugins/c/rpcs/crpc.h | 1 + src/plugins/c/rpcs/crpc_server.cpp | 8 +- src/plugins/c/rpcs/crpc_server.h | 1 + src/plugins/service_plugin.cpp | 3 +- src/test.proto | 23 +++- 11 files changed, 260 insertions(+), 37 deletions(-) diff --git a/src/plugins/c/c_message_plugin.cpp b/src/plugins/c/c_message_plugin.cpp index 743d423..bac64a1 100644 --- a/src/plugins/c/c_message_plugin.cpp +++ b/src/plugins/c/c_message_plugin.cpp @@ -183,21 +183,23 @@ CMessagePlugin::GenerateSourceIncludeFile(Message::Ptr message) { std::stringstream ss; ss << "#include \"" << GenerateHeaderFileName(message->id()) << "\"" << std::endl; + ss << "#include " << std::endl; ss << "#include " << std::endl; ss << "#include " << std::endl; ss << "#include " << std::endl; + ss << "#include " << std::endl; ss << std::endl; return ss.str(); } - -static std::string GetTPLMap(std::vector items) +static std::string +GetTPLMap(std::vector items) { std::stringstream ss; - ss << "S("; + ss << "A("; for (auto &item : items) { - switch(item->type()) { + switch (item->type()) { case Item::Type::kInt32: ss << "i"; break; @@ -214,21 +216,96 @@ static std::string GetTPLMap(std::vector items) return ss.str(); } +static std::string GetTPLArgs(std::vector items) +{ + std::stringstream ss; + for (int idx = 0; idx < items.size(); idx++) { + const auto &item = items[idx]; + if (item->type() == Item::Type::kInt32) { + ss << "&item_" << idx; + } else if (item->type() == Item::Type::kString) { + ss << "&item_" << idx; + } else if (item->type() == Item::Type::kMessage) { + // type_name = "char*"; + } + if (idx != items.size() - 1) { + ss << ", "; + } + } + return ss.str(); +} + +// int Base64encode(char *encoded, const char *string, int len) +// int Base64decode(char *bufplain, const char *bufcoded) +// int Base64decode_len(const char *bufcoded) +// int Base64encode_len(int len) std::string CMessagePlugin::GenerateFunctionDefinitionSerialize(Message::Ptr message) { std::stringstream ss; ss << "int32_t " << message->id() << "_Serialize(" << message->id() << "* message, char** buffer, int32_t* buffer_size) {" << std::endl; + ss << " int32_t status = 0;" << std::endl; if (!message->items().empty()) { std::string tpl_format = GetTPLMap(message->items()); + auto items = message->items(); + for (int idx = 0; idx < message->items().size(); idx++) { + const auto &item = items[idx]; + std::string type_name; + std::string default_value; + if (item->type() == Item::Type::kInt32) { + type_name = "int32_t"; + default_value = "0"; + } else if (item->type() == Item::Type::kString) { + type_name = "char*"; + default_value = "NULL"; + } else if (item->type() == Item::Type::kMessage) { + // type_name = "char*"; + } + ss << " " << type_name << " item_" << idx << " = " << default_value << ";" << std::endl; + } ss << " do {" << std::endl; - ss << " tpl_node* tn = tpl_map(\"" << tpl_format << "\", message);" << std::endl; - ss << " tpl_pack(tn, 0);" << std::endl; + for (int idx = 0; idx < message->items().size(); idx++) { + const auto &item = items[idx]; + std::string type_name; + if (item->type() == Item::Type::kInt32) { + ss << " item_" << idx << " = message->" << item->id() << ";" << std::endl; + ss << std::endl; + } else if (item->type() == Item::Type::kString) { + ss << " // item_" << idx << std::endl; + ss << " {" << std::endl; + ss << " int32_t base64_size = Base64encode_len(message->" << item->id() << "_len);" << std::endl; + ss << " item_" << idx << " = (char*)malloc(base64_size + 1);" << std::endl; + ss << " if (item_" << idx << " == NULL) { " << std::endl; + ss << " status = -1;" << std::endl; + ss << " break;" << std::endl; + ss << " }" << std::endl; + ss << " int32_t encoded_len = Base64encode(item_" << idx << ", message->" << item->id() << ", message->" << item->id() << "_len);" << std::endl; + ss << " assert(encoded_len == base64_size);" << std::endl; + ss << " item_" << idx << "[encoded_len] = '\\0';" << std::endl; + ss << " }" << std::endl; + ss << std::endl; + } else if (item->type() == Item::Type::kMessage) { + // type_name = "char*"; + } + } + ss << " } while (0);" << std::endl; + + ss << " do {" << std::endl; + ss << " if (status != 0) { break; }" << std::endl; + ss << " tpl_node* tn = tpl_map(\"" << tpl_format << "\"," << GetTPLArgs(message->items())<< ");" << std::endl; + ss << " tpl_pack(tn, 1);" << std::endl; ss << " tpl_dump(tn, TPL_MEM, buffer, buffer_size);" << std::endl; ss << " tpl_free(tn);" << std::endl; ss << " return *buffer_size; " << std::endl; ss << " } while (0);" << std::endl; + + for (int idx = 0; idx < message->items().size(); idx++) { + const auto &item = items[idx]; + if (item->type() == Item::Type::kString) { + ss << " if (item_" << idx << ") { free(item_" << idx << "); }" << std::endl; + } + } } ss << " return 0; " << std::endl; ss << "}" << std::endl; @@ -242,16 +319,62 @@ CMessagePlugin::GenerateFunctionDefinitionDeserialize(Message::Ptr message) std::stringstream ss; ss << "int32_t " << message->id() << "_Deserialize(" << message->id() << "* message, char* buffer, int32_t buffer_size) {" << std::endl; + ss << " int32_t status = 0;" << std::endl; + ss << " size_t dump_sz = buffer_size;" << std::endl; if (!message->items().empty()) { - std::string tpl_format = GetTPLMap(message->items()); ss << " do {" << std::endl; ss << " " << message->id() << "_Destroy(message);" << std::endl; - ss << " size_t dump_sz = buffer_size;" << std::endl; - ss << " tpl_node* tn = tpl_map(\"" << tpl_format << "\", message);" << std::endl; + ss << " " << message->id() << "_Init(message);" << std::endl; + auto items = message->items(); + + for (int idx = 0; idx < message->items().size(); idx++) { + const auto &item = items[idx]; + std::string type_name; + if (item->type() == Item::Type::kInt32) { + ss << " int32_t item_" << idx << ";" << std::endl; + } else if (item->type() == Item::Type::kString) { + ss << " char* item_" << idx << " = NULL;" << std::endl; + } else if (item->type() == Item::Type::kMessage) { + // type_name = "char*"; + } + } + ss << std::endl; + + std::string tpl_format = GetTPLMap(message->items()); + std::string tpl_args = GetTPLArgs(message->items()); + ss << " tpl_node* tn = tpl_map(\"" << tpl_format << "\", " << tpl_args << ");" << std::endl; ss << " tpl_load(tn, TPL_MEM, buffer, dump_sz);" << std::endl; - ss << " tpl_unpack(tn, 0);" << std::endl; + ss << " tpl_unpack(tn, 1);" << std::endl; ss << " tpl_free(tn);" << std::endl; - ss << " return dump_sz; " << std::endl; + + ss << std::endl; + + for (int idx = 0; idx < message->items().size(); idx++) { + const auto &item = items[idx]; + std::string type_name; + std::string item_name = "item_" + std::to_string(idx); + if (item->type() == Item::Type::kInt32) { + ss << " " << message->id() << "_set_" << item->id() << "(message, item_" << idx << ");" << std::endl; + } else if (item->type() == Item::Type::kString) { + ss << " // item_" << idx << std::endl; + ss << " {" << std::endl; + ss << " int32_t decoded_len = " << item_name << " == NULL ? 0 : Base64decode_len(" << item_name << ");" << std::endl; + ss << " char* tmp_str" << " = (char*)malloc(decoded_len + 1);" << std::endl; + ss << " if (item_" << idx << " == NULL) { " << std::endl; + ss << " status = -1;" << std::endl; + ss << " break;" << std::endl; + ss << " }" << std::endl; + // ss << " item_" << idx << "[data_len] = '\\0';" << std::endl; + ss << " int32_t data_len = Base64decode(tmp_str, item_" << idx << ");" << std::endl; + ss << " " << message->id() << "_set_" << item->id() << "_data(message, tmp_str, data_len);" << std::endl; + ss << " free(tmp_str);" << std::endl; + ss << " }" << std::endl; + } else if (item->type() == Item::Type::kMessage) { + // type_name = "char*"; + } + } + + ss << " } while (0);" << std::endl; } ss << " return 0; " << std::endl; diff --git a/src/plugins/c/c_service_plugin.cpp b/src/plugins/c/c_service_plugin.cpp index 5407e20..a20cb88 100644 --- a/src/plugins/c/c_service_plugin.cpp +++ b/src/plugins/c/c_service_plugin.cpp @@ -9,14 +9,6 @@ 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) { @@ -45,6 +37,11 @@ CServicePlugin::GenerateHeader(Service::Ptr service) ss << GenerateHeaderStructEnd(service); ss << std::endl; + ss << GenerateHeaderStructAPIStart(service); + ss << GenerateHeaderStructAPIItems(service); + ss << GenerateHeaderStructAPIEnd(service); + ss << std::endl; + ss << GenerateHeaderFunctionDeclaration(service); ss << std::endl; diff --git a/src/plugins/c/c_service_plugin.h b/src/plugins/c/c_service_plugin.h index 51a5b1a..24ef206 100644 --- a/src/plugins/c/c_service_plugin.h +++ b/src/plugins/c/c_service_plugin.h @@ -17,6 +17,9 @@ public: CServicePlugin(std::string generate_path, std::string generate_prefix = "CService"); virtual ~CServicePlugin() = default; protected: + virtual std::string GenerateHeaderFileName(std::string service_id) = 0; + virtual std::string GenerateSourceFileName(std::string service_id) = 0; + virtual void GenerateHeader(Service::Ptr service) override; virtual void GenerateSource(Service::Ptr service) override; @@ -27,6 +30,11 @@ protected: 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 GenerateHeaderStructAPIStart(Service::Ptr service) = 0; + virtual std::string GenerateHeaderStructAPIItems(Service::Ptr service) = 0; + virtual std::string GenerateHeaderStructAPIEnd(Service::Ptr service) = 0; + virtual std::string GenerateHeaderFunctionDeclaration(Service::Ptr service) = 0; }; diff --git a/src/plugins/c/c_service_server_plugin.cpp b/src/plugins/c/c_service_server_plugin.cpp index e6f9144..1087bc6 100644 --- a/src/plugins/c/c_service_server_plugin.cpp +++ b/src/plugins/c/c_service_server_plugin.cpp @@ -4,11 +4,12 @@ #include "c_service_server_plugin.h" #include +#include #include "rpcs/crpc_server.h" namespace tqcq { CServiceServerPlugin::CServiceServerPlugin(std::string generate_path, std::string generate_prefix) - : CServicePlugin(generate_path, generate_prefix) + : CServicePlugin(std::move(generate_path), std::move(generate_prefix)) {} std::string @@ -60,7 +61,7 @@ CServiceServerPlugin::GenerateHeaderGuardEnd(Service::Ptr service) } std::string -CServiceServerPlugin::GenerateHeaderStructStart(Service::Ptr service) +CServiceServerPlugin::GenerateHeaderStructAPIStart(Service::Ptr service) { std::stringstream ss; ss << "typedef struct " << "{" << std::endl; @@ -68,7 +69,7 @@ CServiceServerPlugin::GenerateHeaderStructStart(Service::Ptr service) } std::string -CServiceServerPlugin::GenerateHeaderStructItems(Service::Ptr service) +CServiceServerPlugin::GenerateHeaderStructAPIItems(Service::Ptr service) { std::stringstream ss; for (const auto& rpc : service->rpcs()) { @@ -79,18 +80,52 @@ CServiceServerPlugin::GenerateHeaderStructItems(Service::Ptr service) } std::string -CServiceServerPlugin::GenerateHeaderStructEnd(Service::Ptr service) +CServiceServerPlugin::GenerateHeaderStructAPIEnd(Service::Ptr service) { std::stringstream ss; - ss << "} " << service->id() << ";" << std::endl; + ss << "} " << service->id() << "_API" << ";" << std::endl; return ss.str(); } std::string CServiceServerPlugin::GenerateHeaderFunctionDeclaration(Service::Ptr service) +{ + std::stringstream ss; + return ss.str(); +} + +std::string +CServiceServerPlugin::GenerateHeaderFileName(std::string service_id) +{ + std::stringstream ss; + ss << service_id << "_Server.h"; + return ss.str(); +} + +std::string +CServiceServerPlugin::GenerateSourceFileName(std::string service_id) +{ + std::stringstream ss; + ss << service_id << "_Server.c"; + return ss.str(); +} + +std::string +CServiceServerPlugin::GenerateHeaderStructStart(Service::Ptr service) { return std::string(); } +std::string +CServiceServerPlugin::GenerateHeaderStructItems(Service::Ptr service) +{ + return std::string(); +} + +std::string +CServiceServerPlugin::GenerateHeaderStructEnd(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 index f4a6686..e13496b 100644 --- a/src/plugins/c/c_service_server_plugin.h +++ b/src/plugins/c/c_service_server_plugin.h @@ -14,12 +14,20 @@ public: CServiceServerPlugin(std::string generate_path, std::string generate_prefix = "CService"); virtual ~CServiceServerPlugin() = default; protected: + std::string GenerateHeaderFileName(std::string service_id) override; + std::string GenerateSourceFileName(std::string service_id) override; 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 GenerateHeaderStructAPIStart(Service::Ptr service) override; + std::string GenerateHeaderStructAPIItems(Service::Ptr service) override; + std::string GenerateHeaderStructAPIEnd(Service::Ptr service) override; + std::string GenerateHeaderFunctionDeclaration(Service::Ptr service) override; }; diff --git a/src/plugins/c/items/c_item_string.cpp b/src/plugins/c/items/c_item_string.cpp index 0741a16..f8c61b7 100644 --- a/src/plugins/c/items/c_item_string.cpp +++ b/src/plugins/c/items/c_item_string.cpp @@ -11,13 +11,19 @@ CItemString::CItemString(Item::Ptr item) : CItem(item) {} std::string CItemString::GenerateStructDeclareCodeBlock(std::string message_id) const { - return " char* " + id() + ";"; + std::stringstream ss; + ss << " int32_t " << id() << "_len;" << std::endl; + ss << " char* " << id() << ";" << std::endl; + return ss.str(); } std::string CItemString::GenerateInitCodeBlock(std::string message_id) const { - return " message->" + id() + " = NULL;"; + std::stringstream ss; + ss << " message->" << id() << "_len = 0;" << std::endl; + ss << " message->" << id() << " = NULL;" << std::endl; + return ss.str(); } std::string @@ -29,14 +35,16 @@ CItemString::GenerateDestroyCodeBlock(std::string message_id) const 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() << ");"; + ss << "void " << message_id << "_set_" << id() << "_string(" << message_id << "* message, const char* " << id() << ");"; + ss << std::endl; + ss << "void " << message_id << "_set_" << id() << "_data(" << message_id << "* message, const char* " << id() << ", int32_t " << id() << "_len);"; + ss << std::endl; return ss.str(); } @@ -44,13 +52,27 @@ 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; + // set_xxx_data + ss << "void " << message_id << "_set_" << id() << "_data(" << message_id << "* message, const char* " << id() << ", int32_t " << id() << "_len) {" << std::endl; + ss << " char* new_" << id() << " = (char*)malloc(" << id() << "_len + 1);" << std::endl; + ss << " if (new_" << id() << " == NULL) { return; }" << std::endl; + ss << " memcpy(new_" << id() << ", " << id() << ", " << id() << "_len);" << std::endl; + ss << " new_" << id() << "[" << id() << "_len] = '\\0';" << 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 << " message->" << id() << " = new_" << id() << ";" << std::endl; + ss << " message->" << id() << "_len = " << id() << "_len;" << std::endl; ss << "}" << std::endl; ss << std::endl; + + // set_xxx_string + ss << "void " << message_id << "_set_" << id() << "_string(" << message_id << "* message, const char* " << id() << ") {" << std::endl; + ss << " int32_t " << id() << "_len = strlen(" << id() << ");" << std::endl; + ss << " " << message_id << "_set_" << id() << "_data(message, " << id() << ", " << id() << "_len);" << std::endl; + ss << "}" << std::endl; + ss << std::endl; + return ss.str(); } @@ -58,10 +80,10 @@ 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 << "const char* " << message_id << "_get_" << id() << "_data(const " << message_id << "* message) {" << std::endl; ss << " return message->" << id() << ";" << std::endl; ss << "}" << std::endl; - ss << std::endl; + return ss.str(); } @@ -69,7 +91,9 @@ std::string CItemString::GenerateGetterDeclaration(std::string message_id) const { std::stringstream ss; - ss << "const char* " << message_id << "_get_" << id() << "(const " << message_id << "* message);"; + ss << "const char* " << message_id << "_get_" << id() << "_data(const " << message_id << "* message);"; + ss << std::endl; + ss << "const char* " << message_id << "_get_" << id() << "_len(const " << message_id << "* message);"; return ss.str(); } diff --git a/src/plugins/c/rpcs/crpc.h b/src/plugins/c/rpcs/crpc.h index 87c96a5..fd99b12 100644 --- a/src/plugins/c/rpcs/crpc.h +++ b/src/plugins/c/rpcs/crpc.h @@ -19,6 +19,7 @@ public: virtual ~CRPC() = default; virtual std::string GenerateStructDeclareCodeBlock(std::string service_id) const = 0; + virtual std::string GenerateStructAPIDeclareCodeBlock(std::string service_id) const = 0; }; }// namespace tqcq diff --git a/src/plugins/c/rpcs/crpc_server.cpp b/src/plugins/c/rpcs/crpc_server.cpp index a6b92ce..890c940 100644 --- a/src/plugins/c/rpcs/crpc_server.cpp +++ b/src/plugins/c/rpcs/crpc_server.cpp @@ -14,11 +14,17 @@ CRPCServer::Create(RPC::Ptr rpc) CRPCServer::CRPCServer(RPC::Ptr rpc) : CRPC(rpc) {} +std::string +CRPCServer::GenerateStructAPIDeclareCodeBlock(std::string service_id) const +{ + return std::string(); +} + std::string CRPCServer::GenerateStructDeclareCodeBlock(std::string service_id) const { std::stringstream ss; - ss << " void (*" << id() << ")(Service *service, " << request_id() << " *request, " << response_id() << " **response);\n"; + ss << " int32_t (*" << id() << ")(" << request_id() << " *request, " << response_id() << " **response);\n"; return ss.str(); } diff --git a/src/plugins/c/rpcs/crpc_server.h b/src/plugins/c/rpcs/crpc_server.h index e2d8fb0..c8186a4 100644 --- a/src/plugins/c/rpcs/crpc_server.h +++ b/src/plugins/c/rpcs/crpc_server.h @@ -18,6 +18,7 @@ public: ~CRPCServer() override = default; std::string GenerateStructDeclareCodeBlock(std::string service_id) const override; + std::string GenerateStructAPIDeclareCodeBlock(std::string service_id) const override; }; }// namespace tqcq diff --git a/src/plugins/service_plugin.cpp b/src/plugins/service_plugin.cpp index ea480c1..837171c 100644 --- a/src/plugins/service_plugin.cpp +++ b/src/plugins/service_plugin.cpp @@ -3,12 +3,13 @@ // #include "service_plugin.h" +#include namespace tqcq { ServicePlugin::ServicePlugin(std::string generate_path, std::string generate_prefix) - : Plugin(generate_path, generate_prefix) + : Plugin(std::move(generate_path), std::move(generate_prefix)) {} void diff --git a/src/test.proto b/src/test.proto index af6dcd6..87adb45 100644 --- a/src/test.proto +++ b/src/test.proto @@ -13,11 +13,28 @@ message ApplicationPINRequest { string admin_pin = 2; string new_user_pin = 3; string old = 4; - string new = 5; + string new_data = 5; string pin = 6; } -service Device { +message GenerateRandomRequest { + int32 length = 1; +} + +message GenerateHashRequest { + int32 length = 1; + string data = 2; +} + +message BaseResponse{ + int32 code = 1; + string msg = 2; + + int32 length = 3; + string data = 4; +} + +service DeviceService { rpc Init(Empty) returns (StatusResponse) {} rpc Status(Empty) returns (StatusResponse) {} rpc Close(Empty) returns (StatusResponse) {} @@ -26,4 +43,6 @@ service Device { rpc UnlockApplicationPIN(ApplicationPINRequest) returns (StatusResponse) {} rpc ChangeApplicationPIN(ApplicationPINRequest) returns (StatusResponse) {} rpc VerifyApplicationPIN(ApplicationPINRequest) returns (StatusResponse) {} + + rpc GenerateRandom(GenerateRandomRequest) returns (BaseResponse) {} }