From e5bed79e648c7caf1d0ca85d8591ecbbb53b11fb Mon Sep 17 00:00:00 2001 From: tqcq <99722391+tqcq@users.noreply.github.com> Date: Sun, 3 Dec 2023 20:05:41 +0800 Subject: [PATCH] feature v0.1.0 --- src/message.cpp | 19 +- src/message.h | 3 + src/plugins/c/c_message_plugin.cpp | 59 +++-- src/plugins/c/c_service_client_plugin.cpp | 265 +++++++++++++++++++--- src/plugins/c/c_service_client_plugin.h | 3 + src/plugins/c/c_service_plugin.cpp | 4 +- src/plugins/c/c_service_server_plugin.cpp | 85 ++++++- src/plugins/c/c_service_server_plugin.h | 4 + src/plugins/c/rpcs/crpc_client.cpp | 203 +++++++++++++---- src/plugins/c/rpcs/crpc_client.h | 2 + src/plugins/c/rpcs/crpc_server.cpp | 49 ++-- src/plugins/plugin.cpp | 3 +- 12 files changed, 588 insertions(+), 111 deletions(-) diff --git a/src/message.cpp b/src/message.cpp index df9721c..4f9cf32 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -4,9 +4,19 @@ #include "message.h" #include +#include namespace tqcq { -Message::Message(std::string id) : id_(id){} + +int unique_id_counter_ = 1; +static std::map id_map; + +Message::Message(std::string id) : id_(id){ + if (id_map.find(id) == id_map.end()) { + id_map[id] = unique_id_counter_++; + } + unique_id_ = id_map[id]; +} std::string Message::id() const @@ -50,4 +60,11 @@ Message::ToString() ss << "};"; return ss.str(); } + +int +Message::unique_id() const +{ + return unique_id_; +} + }// namespace tqcq diff --git a/src/message.h b/src/message.h index 66539fa..c11ee48 100644 --- a/src/message.h +++ b/src/message.h @@ -27,7 +27,10 @@ public: std::set dependencies() const; std::string ToString(); + + int unique_id() const; private: + int unique_id_; std::string id_; std::vector items_; std::set dependencies_; diff --git a/src/plugins/c/c_message_plugin.cpp b/src/plugins/c/c_message_plugin.cpp index 275373c..dbc43ad 100644 --- a/src/plugins/c/c_message_plugin.cpp +++ b/src/plugins/c/c_message_plugin.cpp @@ -118,12 +118,11 @@ std::string CMessagePlugin::GenerateStructItem(Message::Ptr message) { std::stringstream ss; + ss << " int32_t _message_unique_id; /* " << message->unique_id() << " */" << std::endl; + ss << std::endl; for (auto &item : message->items()) { ss << CItem::Create(item)->GenerateStructDeclareCodeBlock(message->id()) << std::endl; } - if (message->items().empty()) { - ss << " char:8; " << std::endl; - } return ss.str(); } @@ -144,12 +143,13 @@ CMessagePlugin::GenerateFunctionDeclaration(Message::Ptr message) ss << "void " << message->id() << "_Destroy(" << message->id() << "* message);" << std::endl; ss << std::endl; - ss << "int32_t " << message->id() << "_Serialize(" << message->id() + ss << "int32_t " << message->id() << "_Serialize(const " << message->id() << "* message, char** buffer, int32_t *buffer_size);" << std::endl; ss << "int32_t " << message->id() << "_Deserialize(" << message->id() - << "* message, char* buffer, int32_t buffer_size);" << std::endl; + << "* message, const char* buffer, int32_t buffer_size);" << std::endl; ss << std::endl; + ss << "int32_t " << message->id() << "_get__message_unique_id(" << message->id() << "* message);" << std::endl; for (auto &item : message->items()) { auto c_item = CItem::Create(item); ss << c_item->GenerateSetterDeclaration(message->id()) << std::endl; @@ -172,6 +172,9 @@ CMessagePlugin::GenerateFunctionDefinition(Message::Ptr message) ss << GenerateFunctionDefinitionDeserialize(message); ss << std::endl; + ss << "int32_t " << message->id() << "_get__message_unique_id(" << message->id() << "* message) {" << std::endl; + ss << " return message->_message_unique_id;" << std::endl; + ss << "}" << std::endl; for (auto &item : message->items()) { auto c_item = CItem::Create(item); ss << c_item->GenerateSetterDefinition(message->id()) << std::endl; @@ -201,7 +204,8 @@ GetTPLMap(std::vector items) { std::stringstream ss; - ss << "A("; + // first i is message_unique_id(int32_t) + ss << "A(i"; for (auto &item : items) { switch (item->type()) { case Item::Type::kInt32: @@ -247,10 +251,11 @@ std::string CMessagePlugin::GenerateFunctionDefinitionSerialize(Message::Ptr message) { std::stringstream ss; - ss << "int32_t " << message->id() << "_Serialize(" << message->id() + ss << "int32_t " << message->id() << "_Serialize(const " << message->id() << "* message, char** buffer, int32_t* buffer_size) {" << std::endl; ss << " int32_t status = 0;" << std::endl; - if (!message->items().empty()) { + // if (!message->items().empty()) { + if (true) { std::string tpl_format = GetTPLMap(message->items()); auto items = message->items(); for (int idx = 0; idx < message->items().size(); idx++) { @@ -294,22 +299,27 @@ CMessagePlugin::GenerateFunctionDefinitionSerialize(Message::Ptr message) } } ss << " } while (0);" << std::endl; + std::string tpl_args = GetTPLArgs(message->items()); + if (!message->items().empty()) { + tpl_args = ", " + tpl_args; + } 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_node* tn = tpl_map(\"" << tpl_format << "\", &message->_message_unique_id" << tpl_args << ");" << std::endl; + ss << " status = tpl_pack(tn, 1);" << std::endl; + ss << " if (status != 0) { break; }" << 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; - } - } +// 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; @@ -322,10 +332,11 @@ 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; + << "* message, const 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()) { + // if (!message->items().empty()) { + if (true) { ss << " do {" << std::endl; ss << " " << message->id() << "_Destroy(message);" << std::endl; ss << " " << message->id() << "_Init(message);" << std::endl; @@ -346,9 +357,14 @@ CMessagePlugin::GenerateFunctionDefinitionDeserialize(Message::Ptr message) 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, 1);" << std::endl; + if (!message->items().empty()) { + tpl_args = ", " + tpl_args; + } + ss << " tpl_node* tn = tpl_map(\"" << tpl_format << "\", &message->_message_unique_id" << tpl_args << ");" << std::endl; + ss << " status = tpl_load(tn, TPL_MEM, buffer, dump_sz);" << std::endl; + ss << " if (status != 0) { break; }" << std::endl; + ss << " status = tpl_unpack(tn, 1);" << std::endl; + ss << " if (status == -1) { break; }" << std::endl; ss << " tpl_free(tn);" << std::endl; ss << std::endl; @@ -391,6 +407,7 @@ CMessagePlugin::GenerateFunctionDefinitionInit(Message::Ptr message) { std::stringstream ss; ss << "void " << message->id() << "_Init(" << message->id() << "* message) {" << std::endl; + ss << " " << "message->_message_unique_id = " << message->unique_id() << ";" << std::endl; for (auto &item : message->items()) { auto c_item = CItem::Create(item); ss << c_item->GenerateInitCodeBlock(message->id()) << std::endl; diff --git a/src/plugins/c/c_service_client_plugin.cpp b/src/plugins/c/c_service_client_plugin.cpp index 82c6432..3b66a00 100644 --- a/src/plugins/c/c_service_client_plugin.cpp +++ b/src/plugins/c/c_service_client_plugin.cpp @@ -11,6 +11,75 @@ #include "plugins/c/rpcs/crpc_client.h" namespace tqcq { +static std::string GenerateCallLock(std::string service_id) +{ + std::stringstream ss; + ss << " " << service_id << "_Client_Priv* call_lock_priv = (" << service_id << "_Client_Priv*)client->priv;" << std::endl; + ss << " pthread_mutex_lock(&call_lock_priv->call_mutex);" << std::endl; + return ss.str(); +} + +static std::string GenerateCallUnlock(std::string service_id) +{ + std::stringstream ss; + ss << " " << service_id << "_Client_Priv* call_unlock_priv = (" << service_id << "_Client_Priv*)client->priv;" << std::endl; + ss << " pthread_mutex_unlock(&call_unlock_priv->call_mutex);" << std::endl; + return ss.str(); +} + +static std::string +GenerateLock(std::string service_id) +{ + std::stringstream ss; + ss << " " << service_id << "_Client_Priv* lock_priv = (" << service_id << "_Client_Priv*)client->priv;" << std::endl; + ss << " pthread_mutex_lock(&lock_priv->mutex);" << std::endl; + return ss.str(); +} +static std::string GenerateUnlock(std::string service_id) +{ + std::stringstream ss; + ss << " " << service_id << "_Client_Priv* unlock_priv = (" << service_id << "_Client_Priv*)client->priv;" << std::endl; + ss << " pthread_mutex_unlock(&unlock_priv->mutex);" << std::endl; + return ss.str(); +} + +static std::string GeneratePrapare(std::string service_id) +{ + std::stringstream ss; + ss << " " << service_id << "_Client_Priv* prepare_priv = (" << service_id << "_Client_Priv*)client->priv;" << std::endl; + ss << " prepare_priv->ok = 0;" << std::endl; + ss << " prepare_priv->response = NULL;" << std::endl; + return ss.str(); +} + +static std::string GenerateWaitOk(std::string service_id) +{ + std::stringstream ss; + ss << " " << service_id << "_Client_Priv* wait_priv = (" << service_id << "_Client_Priv*)client->priv;" << std::endl; + ss << " while (wait_priv->ok == 0) {" << std::endl; + ss << " pthread_cond_wait(&wait_priv->cond, &wait_priv->mutex);" << std::endl; + ss << " }" << std::endl; + return ss.str(); +} + +static std::string GenerateSignalOk(std::string service_id) +{ + std::stringstream ss; + ss << " " << service_id << "_Client_Priv* signal_priv = (" << service_id << "_Client_Priv*)client->priv;" << std::endl; + ss << " signal_priv->ok = 1;" << std::endl; + ss << " pthread_cond_signal(&signal_priv->cond);" << std::endl; + return ss.str(); +} + +static std::string GenerateClientBaseCheck(std::string service_id) +{ + std::stringstream ss; + ss << " assert(client != NULL);" << std::endl; + ss << " assert(client->impl != NULL);" << std::endl; + ss << " assert(client->priv != NULL);" << std::endl; + return ss.str(); +} + CServiceClientPlugin::CServiceClientPlugin(std::string generate_path, std::string generate_prefix) : CServicePlugin(std::move(generate_path), std::move(generate_prefix)) {} @@ -57,17 +126,17 @@ std::string CServiceClientPlugin::GenerateHeaderStructAPIStart(Service::Ptr service) { std::stringstream ss; - for (const auto &rpc : service->rpcs()) { - auto crpc = CRPCClient::Create(rpc); - ss << crpc->GenerateAsyncCallback(service->id()) << std::endl; - } - ss << std::endl; + // for (const auto &rpc : service->rpcs()) { + // auto crpc = CRPCClient::Create(rpc); + // ss << crpc->GenerateAsyncCallback(service->id()) << std::endl; + // } + // ss << std::endl; ss << "typedef struct _" << service->id() << "_Client " << service->id() << "_Client;" << std::endl; ss << std::endl; -// -// ss << "typedef struct " -// << "{" << std::endl; + // + // ss << "typedef struct " + // << "{" << std::endl; return ss.str(); } @@ -76,7 +145,6 @@ CServiceClientPlugin::GenerateHeaderStructAPIItems(Service::Ptr service) { std::stringstream ss; - return ss.str(); } @@ -84,8 +152,8 @@ std::string CServiceClientPlugin::GenerateHeaderStructAPIEnd(Service::Ptr service) { std::stringstream ss; -// ss << "} " << service->id() << "_Client_API" -// << ";" << std::endl; + // ss << "} " << service->id() << "_Client_API" + // << ";" << std::endl; return ss.str(); } @@ -107,13 +175,14 @@ CServiceClientPlugin::GenerateHeaderStructItems(Service::Ptr service) } ss << std::endl; - for (const auto &rpc : service->rpcs()) { - auto crpc = CRPCClient::Create(rpc); - ss << crpc->GenerateStructAPIDeclareAsyncCodeBlock(service->id()); - } - ss << std::endl; + // for (const auto &rpc : service->rpcs()) { + // auto crpc = CRPCClient::Create(rpc); + // ss << crpc->GenerateStructAPIDeclareAsyncCodeBlock(service->id()); + // } + // ss << std::endl; ss << " void* impl;" << std::endl; + ss << " void* priv;" << std::endl; return ss.str(); } @@ -130,9 +199,15 @@ CServiceClientPlugin::GenerateHeaderFunctionDeclaration(Service::Ptr service) { std::stringstream ss; ss << "int32_t " << service->id() << "_Client_Init(" << service->id() << "_Client* client);" << std::endl; - ss << "int32_t " << service->id() << "_Client_Connect(" << service->id() << "_Client* client, const char* format, ...);" << std::endl; + ss << "int32_t " << service->id() << "_Client_Connect(" << service->id() + << "_Client* client, const char* format, ...);" << std::endl; // ss << "int32_t " << service->id() << "_Client_Send(" << service->id() << "_Client* client, const char* msg, int32_t msg_len);" << std::endl; ss << "void " << service->id() << "_Client_Destroy(" << service->id() << "_Client* client);" << std::endl; + + for (const auto &rpc : service->rpcs()) { + auto crpc = CRPCClient::Create(rpc); + ss << crpc->GenerateCallFunctionDeclaration(service->id()); + } return ss.str(); } @@ -142,9 +217,13 @@ CServiceClientPlugin::GenerateSourceIncludeFiles(Service::Ptr service) std::stringstream ss; ss << "#include " << std::endl; ss << "#include " << std::endl; + ss << "#include " << std::endl; ss << "#include " << std::endl; ss << "#include " << std::endl; - ss << "#include " << std::endl; + ss << "#include " << std::endl; + ss << "#include " << std::endl; + ss << "#include " << std::endl; + ss << "#include " << std::endl; ss << "#include \"" << GenerateHeaderFileName(service->id()) << "\"" << std::endl; std::set message_set; for (const auto &rpc : service->rpcs()) { @@ -154,6 +233,16 @@ CServiceClientPlugin::GenerateSourceIncludeFiles(Service::Ptr service) } for (const auto &message_id : message_set) { ss << "#include \"" << message_id << ".h\"" << std::endl; } + + ss << std::endl; + ss << "typedef struct {" << std::endl; + ss << " pthread_mutex_t call_mutex;" << std::endl; + ss << " pthread_mutex_t mutex;" << std::endl; + ss << " pthread_cond_t cond;" << std::endl; + ss << " int32_t ok;" << std::endl; + ss << " void* response;" << std::endl; + ss << "} " << service->id() << "_Client_Priv;" << std::endl; + ss << std::endl; return ss.str(); } @@ -169,10 +258,16 @@ CServiceClientPlugin::GenerateSourceFunctionDefinition(Service::Ptr service) ss << std::endl; + ss << GenerateSourceDispatchFunctionDefinition(service) << std::endl; ss << GenerateSourceInitFunctionDefinition(service) << std::endl; ss << GenerateSourceConnectFunctionDefinition(service) << std::endl; ss << GenerateSourceDestroyFunctionDefinition(service) << std::endl; ss << GenerateSourceSendFunctionDefinition(service) << std::endl; + + for (const auto &rpc : service->rpcs()) { + auto crpc = CRPCClient::Create(rpc); + ss << crpc->GenerateCallFunctionDefinition(service->id()) << std::endl; + } return ss.str(); } @@ -180,17 +275,25 @@ std::string CServiceClientPlugin::GenerateSourceInitFunctionDefinition(Service::Ptr service) { std::stringstream ss; - ss << "int32_t " << service->id() << "_Client_Init(" << service->id() << "_Client* client, " << service->id() - << "_Client_API* api)" << std::endl; + ss << "int32_t " << service->id() << "_Client_Init(" << service->id() << "_Client* client)" << std::endl; ss << "{" << std::endl; ss << " assert(client != NULL);" << std::endl; - ss << " client->impl = Service_New();" << std::endl; - ss << " if (api) {" << std::endl; - ss << " memcpy(&client->api, api, sizeof(" << service->id() << "_Client_API));" << std::endl; - ss << " } else {" << std::endl; - ss << " memset(&client->api, 0, sizeof(" << service->id() << "_Client_API));" << std::endl; - ss << " }" << std::endl; - ss << " if (client->impl == NULL) { return -1; }" << std::endl; + ss << " int32_t status = 0;" << std::endl; + ss << " do {" << std::endl; + ss << " client->impl = Client_New();" << std::endl; + ss << " if (client->impl == NULL) { status = -1; break; }" << std::endl; + ss << std::endl; + ss << " client->priv = malloc(sizeof(" << service->id() << "_Client_Priv));" << std::endl; + ss << " if (client->priv == NULL) { status = -1; break; }" << std::endl; + ss << std::endl; + ss << " " << service->id() << "_Client_Priv* priv = (" << service->id() << "_Client_Priv*)client->priv;" << std::endl; + ss << " pthread_mutex_init(&priv->call_mutex, NULL);" << std::endl; + ss << " pthread_mutex_init(&priv->mutex, NULL);" << std::endl; + ss << " pthread_cond_init(&priv->cond, NULL);" << std::endl; + ss << " priv->ok = 0;" << std::endl; + ss << " priv->response = NULL;" << std::endl; + ss << " } while (0);" << std::endl; + ss << std::endl; ss << " return 0;" << std::endl; ss << "}" << std::endl; return ss.str(); @@ -203,7 +306,17 @@ CServiceClientPlugin::GenerateSourceDestroyFunctionDefinition(Service::Ptr servi ss << "void " << service->id() << "_Client_Destroy(" << service->id() << "_Client* client)" << std::endl; ss << "{" << std::endl; ss << " if (client == NULL) { return; }" << std::endl; - ss << " if (client->impl != NULL) { Service_Free(client->impl); }" << std::endl; + ss << " if (client->impl != NULL) { Client_Free(client->impl); }" << std::endl; + ss << " if (client->priv != NULL) {" << std::endl; + ss << " " << service->id() << "_Client_Priv* priv = (" << service->id() << "_Client_Priv*)client->priv;" << std::endl; + ss << " pthread_mutex_destroy(&priv->call_mutex);" << std::endl; + ss << " pthread_mutex_destroy(&priv->mutex);" << std::endl; + ss << " pthread_cond_destroy(&priv->cond);" << std::endl; + ss << " if (priv->response) {" << std::endl; + ss << " free(priv->response);" << std::endl; + ss << " }" << std::endl; + ss << " free(client->priv);" << std::endl; + ss << " }" << std::endl; ss << "}" << std::endl; return ss.str(); } @@ -212,14 +325,14 @@ std::string CServiceClientPlugin::GenerateSourceSendFunctionDefinition(Service::Ptr service) { std::stringstream ss; - ss << "int32_t " << service->id() << "_Client_Send(" << service->id() << "_Client* client, const char* msg, int32_t msg_len)" << std::endl; + ss << "int32_t " << service->id() << "_Client_Send(" << service->id() + << "_Client* client, const char* msg, int32_t msg_len)" << std::endl; ss << "{" << std::endl; - ss << " assert(client != NULL);" << std::endl; - ss << " assert(client->impl != NULL);" << std::endl; + ss << GenerateClientBaseCheck(service->id()) << std::endl; ss << " assert(msg != NULL || msg_len == 0);" << std::endl; ss << " assert(msg_len > 0);" << std::endl; ss << std::endl; - ss << " return Service_Send(client->impl, msg, msg_len);" << std::endl; + ss << " return Client_Send(client->impl, msg, msg_len);" << std::endl; ss << "}" << std::endl; return ss.str(); } @@ -227,7 +340,93 @@ CServiceClientPlugin::GenerateSourceSendFunctionDefinition(Service::Ptr service) std::string CServiceClientPlugin::GenerateSourceConnectFunctionDefinition(Service::Ptr service) { - return std::string(); + std::stringstream ss; + ss << "int32_t " << service->id() << "_Client_Connect(" << service->id() + << "_Client* client, const char* format, ...)" << std::endl; + ss << "{" << std::endl; + ss << GenerateClientBaseCheck(service->id()) << std::endl; + ss << " assert(format != NULL);" << std::endl; + ss << std::endl; + ss << " int32_t status = 0;" << std::endl; + ss << " char address[1024];" << std::endl; + ss << " va_list args;" << std::endl; + ss << " va_start(args, format);" << std::endl; + ss << " vsnprintf(address, sizeof(address), format, args);" << std::endl; + ss << " va_end(args);" << std::endl; + ss << std::endl; + ss << " status = Client_Connect(client->impl, address);" << std::endl; + ss << " if (status != 0) { return status; }" << std::endl; + ss << std::endl; + ss << " Client_SetCallback(client->impl, " << service->id() << "_Client_Dispatch, client);" << std::endl; + ss << std::endl; + ss << " return 0;" << std::endl; + ss << "}" << std::endl; + return ss.str(); +} + +std::string +CServiceClientPlugin::GenerateSourceDispatchFunctionDefinition(Service::Ptr service) +{ + std::stringstream ss; + ss << "static void " << service->id() << "_Client_Dispatch(char* msg, int32_t msg_len, void* ctx)" << std::endl; + ss << "{" << std::endl; + ss << " assert(msg != NULL);" << std::endl; + ss << " assert(msg_len > 0);" << std::endl; + ss << " assert(ctx != NULL);" << std::endl; + ss << std::endl; + + ss << " " << service->id() << "_Client* client = (" << service->id() << "_Client*)ctx;" << std::endl; + ss << GenerateClientBaseCheck(service->id()) << std::endl; + ss << std::endl; + ss << " int32_t status = 0;" << std::endl; + ss << " char* service_name = NULL;" << std::endl; + ss << " char* base64_msg = NULL;" << std::endl; + ss << " char* real_msg = NULL;" << std::endl; + ss << " int32_t real_msg_len = 0;" << std::endl; + ss << " do {" << std::endl; + ss << " tpl_node* tn = tpl_map(\"A(ss)\", &service_name, &base64_msg);" << std::endl; + ss << " if (tn == NULL) { break; }" << std::endl; + ss << " status = tpl_load(tn, TPL_MEM, msg, msg_len);" << std::endl; + ss << " if (status) { break; }" << std::endl; + ss << " status = tpl_unpack(tn, 1);" << std::endl; + ss << " if (status == -1) { break; }" << std::endl; + ss << " tpl_free(tn);" << std::endl; + ss << std::endl; + ss << " if (service_name == NULL) { status = -1; break; }" << std::endl; + ss << " // if (base64_msg == NULL) { status = -1; break; }" << std::endl; + ss << std::endl; + + ss << " real_msg_len = Base64decode_len(base64_msg);" << std::endl; + ss << " real_msg = (char*)malloc(real_msg_len + 1);" << std::endl; + ss << " real_msg_len = Base64decode(real_msg, base64_msg);" << std::endl; + ss << " if (real_msg == NULL) { status = -1; break; }" << std::endl; + ss << std::endl; + + for (const auto &rpc : service->rpcs()) { + auto crpc = CRPCClient::Create(rpc); + auto service_name = service->id() + "::" + crpc->id(); + ss << " if (strcmp(\"" << service_name << "\", service_name) == 0) {" << std::endl; + ss << " " << crpc->id() << "_Wrapper(client, real_msg, real_msg_len);" << std::endl; + ss << " break;" << std::endl; + ss << " }" << std::endl; + } + ss << " } while (0);" << std::endl; + ss << " free(service_name);" << std::endl; + ss << " free(base64_msg);" << std::endl; + ss << " free(real_msg);" << std::endl; + ss << "}" << std::endl; + + return ss.str(); +} + +std::string +CServiceClientPlugin::GenerateHeaderGuardStart(Service::Ptr service) +{ + std::stringstream ss; + auto guard_macro = GenerateGuardMacro(service->id() + "_Client", generate_prefix()); + ss << "#ifndef " << guard_macro << std::endl; + ss << "#define " << guard_macro << std::endl; + return ss.str(); } }// namespace tqcq diff --git a/src/plugins/c/c_service_client_plugin.h b/src/plugins/c/c_service_client_plugin.h index 1e661a7..00fd0cf 100644 --- a/src/plugins/c/c_service_client_plugin.h +++ b/src/plugins/c/c_service_client_plugin.h @@ -14,6 +14,7 @@ public: CServiceClientPlugin(std::string generate_path, std::string generate_prefix = "CService"); virtual ~CServiceClientPlugin() = default; protected: + std::string GenerateHeaderGuardStart(Service::Ptr service) override; std::string GenerateHeaderFileName(std::string service_id) override; std::string GenerateSourceFileName(std::string service_id) override; @@ -36,6 +37,8 @@ protected: std::string GenerateSourceConnectFunctionDefinition(Service::Ptr service); std::string GenerateSourceDestroyFunctionDefinition(Service::Ptr service); std::string GenerateSourceSendFunctionDefinition(Service::Ptr service); + + std::string GenerateSourceDispatchFunctionDefinition(Service::Ptr service); }; }// namespace tqcq diff --git a/src/plugins/c/c_service_plugin.cpp b/src/plugins/c/c_service_plugin.cpp index 87c4517..abf0446 100644 --- a/src/plugins/c/c_service_plugin.cpp +++ b/src/plugins/c/c_service_plugin.cpp @@ -68,8 +68,8 @@ CServicePlugin::GenerateSource(Service::Ptr service) std::filesystem::path filename(GenerateSourceFileName(service->id())); std::ofstream ofs(path / filename); ofs << ss.str(); - std::cout << ss.str() << std::endl; - std::cout << path / filename << std::endl; + // out << ss.str() << std::endl; + // std::cout << path / filename << std::endl; } std::string diff --git a/src/plugins/c/c_service_server_plugin.cpp b/src/plugins/c/c_service_server_plugin.cpp index d20ce70..a11e759 100644 --- a/src/plugins/c/c_service_server_plugin.cpp +++ b/src/plugins/c/c_service_server_plugin.cpp @@ -126,8 +126,11 @@ CServiceServerPlugin::GenerateSourceIncludeFiles(Service::Ptr service) std::stringstream ss; ss << "#include " << std::endl; ss << "#include " << std::endl; + ss << "#include " << std::endl; ss << "#include " << std::endl; ss << "#include " << std::endl; + ss << "#include " << std::endl; + ss << "#include " << std::endl; ss << "#include " << std::endl; ss << "#include \"" << GenerateHeaderFileName(service->id()) << "\"" << std::endl; std::set message_set; @@ -150,9 +153,10 @@ CServiceServerPlugin::GenerateSourceFunctionDefinition(Service::Ptr service) ss << crpc->GenerateStructAPIWrapper(service->id()); ss << std::endl; } - ss << std::endl; + ss << GenerateSourceDispatchFunctionDefinition(service) << std::endl; + ss << GenerateSourceInitFunctionDefinition(service) << std::endl; ss << GenerateSourceBindFunctionDefinition(service) << std::endl; ss << GenerateSourceListenFunctionDefinition(service) << std::endl; @@ -170,12 +174,13 @@ CServiceServerPlugin::GenerateSourceInitFunctionDefinition(Service::Ptr service) ss << "{" << std::endl; ss << " assert(server != NULL);" << std::endl; ss << " server->impl = Service_New();" << std::endl; + ss << " if (server->impl == NULL) { return -1; }" << std::endl; + ss << " Service_SetCallback(server->impl, " << service->id() << "_Server_Dispatch, server);" << std::endl; ss << " if (api) {" << std::endl; ss << " memcpy(&server->api, api, sizeof(" << service->id() << "_Server_API));" << std::endl; ss << " } else {" << std::endl; ss << " memset(&server->api, 0, sizeof(" << service->id() << "_Server_API));" << std::endl; ss << " }" << std::endl; - ss << " if (server->impl == NULL) { return -1; }" << std::endl; ss << " return 0;" << std::endl; ss << "}" << std::endl; return ss.str(); @@ -245,4 +250,80 @@ CServiceServerPlugin::GenerateSourceSendFunctionDefinition(Service::Ptr service) return ss.str(); } +//int Base64encode_len(int len); +//int Base64encode(char * coded_dst, const char *plain_src,int len_plain_src); +// +//int Base64decode_len(const char * coded_src); +//int Base64decode(char * plain_dst, const char *coded_src); +// +// typedef void (*ServiceCallback)(char* msg, int32_t msg_len, void* ctx); +std::string +CServiceServerPlugin::GenerateSourceDispatchFunctionDefinition(Service::Ptr service) +{ + std::stringstream ss; + ss << "static void " << service->id() << "_Server_Dispatch(char* msg, int32_t msg_len, void* ctx)" << std::endl; + ss << "{" << std::endl; + ss << " assert(msg != NULL);" << std::endl; + ss << " assert(msg_len > 0);" << std::endl; + ss << " assert(ctx != NULL);" << std::endl; + ss << std::endl; + + ss << " " << service->id() << "_Server* server = (" << service->id() << "_Server*)ctx;" << std::endl; + ss << " assert(server != NULL);" << std::endl; + ss << " assert(server->impl != NULL);" << std::endl; + ss << std::endl; + ss << " " << service->id() << "_Server_API* api = &server->api;" << std::endl; + ss << " assert(api != NULL);" << std::endl; + ss << std::endl; + ss << " int32_t status = 0;" << std::endl; + ss << " char* service_name = NULL;" << std::endl; + ss << " char* base64_msg = NULL;" << std::endl; + ss << " char* real_msg = NULL;" << std::endl; + ss << " int32_t real_msg_len = 0;" << std::endl; + ss << " do {" << std::endl; + ss << " tpl_node* tn = tpl_map(\"A(ss)\", &service_name, &base64_msg);" << std::endl; + ss << " if (tn == NULL) { break; }" << std::endl; + ss << " status = tpl_load(tn, TPL_MEM, msg, msg_len);" << std::endl; + ss << " if (status) { break; }" << std::endl; + ss << " status = tpl_unpack(tn, 1);" << std::endl; + ss << " if (status == -1) { break; }" << std::endl; + ss << " tpl_free(tn);" << std::endl; + ss << std::endl; + ss << " if (service_name == NULL) { status = -1; break; }" << std::endl; + ss << " // if (base64_msg == NULL) { status = -1; break; }" << std::endl; + ss << std::endl; + + ss << " real_msg_len = Base64decode_len(base64_msg);" << std::endl; + ss << " real_msg = (char*)malloc(real_msg_len + 1);" << std::endl; + ss << " real_msg_len = Base64decode(real_msg, base64_msg);" << std::endl; + ss << " if (real_msg == NULL) { status = -1; break; }" << std::endl; + ss << std::endl; + + for (const auto &rpc : service->rpcs()) { + auto crpc = CRPCServer::Create(rpc); + auto service_name = service->id() + "::" + crpc->id(); + ss << " if (strcmp(\"" << service_name << "\", service_name) == 0) {" << std::endl; + ss << " " << crpc->id() << "_Wrapper(server, real_msg, real_msg_len);" << std::endl; + ss << " break;" << std::endl; + ss << " }" << std::endl; + } + ss << " } while (0);" << std::endl; + ss << " free(service_name);" << std::endl; + ss << " free(base64_msg);" << std::endl; + ss << " free(real_msg);" << std::endl; + ss << "}" << std::endl; + + return ss.str(); +} + +std::string +CServiceServerPlugin::GenerateHeaderGuardStart(Service::Ptr service) +{ + std::stringstream ss; + auto guard_macro = GenerateGuardMacro(service->id() + "_Server", generate_prefix()); + ss << "#ifndef " << guard_macro << std::endl; + ss << "#define " << guard_macro << std::endl; + return ss.str(); +} + }// namespace tqcq diff --git a/src/plugins/c/c_service_server_plugin.h b/src/plugins/c/c_service_server_plugin.h index d94f530..4eec657 100644 --- a/src/plugins/c/c_service_server_plugin.h +++ b/src/plugins/c/c_service_server_plugin.h @@ -14,6 +14,8 @@ public: CServiceServerPlugin(std::string generate_path, std::string generate_prefix = "CService"); virtual ~CServiceServerPlugin() = default; protected: + std::string GenerateHeaderGuardStart(Service::Ptr service) override; + std::string GenerateHeaderFileName(std::string service_id) override; std::string GenerateSourceFileName(std::string service_id) override; @@ -32,6 +34,8 @@ protected: std::string GenerateSourceIncludeFiles(Service::Ptr service) override; std::string GenerateSourceFunctionDefinition(Service::Ptr service) override; + std::string GenerateSourceDispatchFunctionDefinition(Service::Ptr service); + std::string GenerateSourceInitFunctionDefinition(Service::Ptr service); std::string GenerateSourceBindFunctionDefinition(Service::Ptr service); std::string GenerateSourceListenFunctionDefinition(Service::Ptr service); diff --git a/src/plugins/c/rpcs/crpc_client.cpp b/src/plugins/c/rpcs/crpc_client.cpp index e794796..b30899c 100644 --- a/src/plugins/c/rpcs/crpc_client.cpp +++ b/src/plugins/c/rpcs/crpc_client.cpp @@ -5,6 +5,82 @@ #include "crpc_client.h" namespace tqcq { + +static std::string GenerateCallLock(std::string service_id) +{ + std::stringstream ss; + ss << " // Call lock" << std::endl; + ss << " " << service_id << "_Client_Priv* call_lock_priv = (" << service_id << "_Client_Priv*)client->priv;" << std::endl; + ss << " pthread_mutex_lock(&call_lock_priv->call_mutex);" << std::endl; + return ss.str(); +} + +static std::string GenerateCallUnlock(std::string service_id) +{ + std::stringstream ss; + ss << " // Call unlock" << std::endl; + ss << " " << service_id << "_Client_Priv* call_unlock_priv = (" << service_id << "_Client_Priv*)client->priv;" << std::endl; + ss << " pthread_mutex_unlock(&call_unlock_priv->call_mutex);" << std::endl; + return ss.str(); +} + +static std::string +GenerateLock(std::string service_id) +{ + std::stringstream ss; + ss << " // Lock" << std::endl; + ss << " " << service_id << "_Client_Priv* lock_priv = (" << service_id << "_Client_Priv*)client->priv;" << std::endl; + ss << " pthread_mutex_lock(&lock_priv->mutex);" << std::endl; + return ss.str(); +} +static std::string GenerateUnlock(std::string service_id) +{ + std::stringstream ss; + ss << " // Unlock" << std::endl; + ss << " " << service_id << "_Client_Priv* unlock_priv = (" << service_id << "_Client_Priv*)client->priv;" << std::endl; + ss << " pthread_mutex_unlock(&unlock_priv->mutex);" << std::endl; + return ss.str(); +} + +static std::string GeneratePrapare(std::string service_id) +{ + std::stringstream ss; + ss << " // Prepare" << std::endl; + ss << " " << service_id << "_Client_Priv* prepare_priv = (" << service_id << "_Client_Priv*)client->priv;" << std::endl; + ss << " prepare_priv->ok = 0;" << std::endl; + ss << " prepare_priv->response = NULL;" << std::endl; + return ss.str(); +} + +static std::string GenerateWaitOk(std::string service_id) +{ + std::stringstream ss; + ss << " // Wait ok" << std::endl; + ss << " " << service_id << "_Client_Priv* wait_priv = (" << service_id << "_Client_Priv*)client->priv;" << std::endl; + ss << " while (wait_priv->ok == 0) {" << std::endl; + ss << " pthread_cond_wait(&wait_priv->cond, &wait_priv->mutex);" << std::endl; + ss << " }" << std::endl; + return ss.str(); +} + +static std::string GenerateSignalOk(std::string service_id) +{ + std::stringstream ss; + ss << " " << service_id << "_Client_Priv* signal_priv = (" << service_id << "_Client_Priv*)client->priv;" << std::endl; + ss << " signal_priv->ok = 1;" << std::endl; + ss << " pthread_cond_signal(&signal_priv->cond);" << std::endl; + return ss.str(); +} + +static std::string GenerateClientBaseCheck(std::string service_id) +{ + std::stringstream ss; + ss << " assert(client != NULL);" << std::endl; + ss << " assert(client->impl != NULL);" << std::endl; + ss << " assert(client->priv != NULL);" << std::endl; + return ss.str(); +} + CRPCClient::Ptr CRPCClient::Create(RPC::Ptr rpc) { @@ -17,56 +93,37 @@ std::string CRPCClient::GenerateStructAPIWrapper(std::string service_id) const { std::stringstream ss; - ss << "int32_t " << id() << "_Wrapper(" << service_id << "_Client *client, char *msg, int32_t msg_len)" + ss << "static int32_t " << id() << "_Wrapper(" << service_id << "_Client *client, char *msg, int32_t msg_len)" << std::endl; ss << "{" << std::endl; ss << " assert(client != NULL);" << std::endl; ss << " assert(msg != NULL || msg_len == 0);" << std::endl; - ss << " if (client->api." << id() << " == NULL) { return 0; }" << std::endl; - ss << std::endl; ss << " int32_t status = 0;" << std::endl; - ss << " " << request_id() << " request;" << std::endl; - ss << " " << response_id() << " response;" << std::endl; - ss << std::endl; + ss << " " << response_id() << " *response = NULL;" << std::endl; + ss << " do {" << std::endl; - ss << " " << request_id() << "_Init(&request);" << std::endl; - ss << " status = " << request_id() << "_Deserialize(&request, msg, msg_len);" << std::endl; - ss << " if (status != 0) {" << std::endl; - ss << " " << request_id() << "_Destroy(&request);" << std::endl; + ss << " response = (" << response_id() << " *)malloc(sizeof(" << response_id() << "));" << std::endl; + ss << " if (response == NULL) {" << std::endl; + ss << " status = -1;" << std::endl; ss << " break;" << std::endl; ss << " }" << std::endl; - ss << std::endl; - ss << " " << response_id() << "_Init(&response);" << std::endl; - ss << " " << response_id() << "_set_code(&response, 200);" << std::endl; - ss << " " << response_id() << "_set_msg_string(&response, \"OK\");" << std::endl; - ss << " status = client->api." << id() << "(&request, &response);" << std::endl; + + ss << " " << response_id() << "_Init(response);" << std::endl; + ss << " status = " << response_id() << "_Deserialize(response, msg, msg_len);" << std::endl; ss << " if (status != 0) {" << std::endl; - ss << " printf(\"" << id() << " failed: %d\\n\", status);" << std::endl; - ss << " " << response_id() << "_set_code(&response, 500);" << std::endl; - ss << " " << response_id() << "_set_msg_string(&response, \"Internal Client Error\");" << std::endl; - ss << " }" << std::endl; - ss << std::endl; - ss << " char* response_msg = NULL;" << std::endl; - ss << " int32_t response_msg_len = 0;" << std::endl; - ss << " status = " << response_id() << "_Serialize(&response, &response_msg, &response_msg_len);" - << std::endl; - ss << " if (status < 0) {" << std::endl; - ss << " printf(\"" << id() << " failed: %d\\n\", status);" << std::endl; - ss << " " << response_id() << "_set_code(&response, 500);" << std::endl; - ss << " " << response_id() << "_set_msg_string(&response, \"Internal Client Error\");" << std::endl; - ss << " }" << std::endl; - ss << std::endl; - ss << " int32_t send_result = DeviceService_Client_Send(client, response_msg, response_msg_len);" - << std::endl; - ss << " if (send_result < 0) {" << std::endl; - ss << " printf(\"" << id() << " failed: %d\\n\", status);" << std::endl; + ss << " " << response_id() << "_Destroy(response);" << std::endl; + ss << " response = NULL;" << std::endl; ss << " break;" << std::endl; ss << " }" << std::endl; - ss << " status = 0;" << std::endl; - ss << " } while (0);" << std::endl; - ss << " " << response_id() << "_Destroy(&response);" << std::endl; - ss << " " << request_id() << "_Destroy(&request);" << std::endl; + ss << " } while(0);" << std::endl; + ss << std::endl; + // ss << GenerateLock(service_id) << std::endl; + ss << " " << service_id << "_Client_Priv *priv = (" << service_id << "_Client_Priv *)client->priv;" << std::endl; + ss << " priv->ok = 1;" << std::endl; + ss << " priv->response = response;" << std::endl; + // ss << GenerateSignalOk(service_id) << std::endl; + // enerateUnlock(service_id) << std::endl; ss << " return status;" << std::endl; ss << "}" << std::endl; return ss.str(); @@ -102,4 +159,74 @@ CRPCClient::GenerateAsyncCallback(std::string service_id) const return ss.str(); } +std::string CRPCClient::GenerateCallFunctionDeclaration(std::string service_id) const { + std::stringstream ss; + ss << "int32_t " << service_id << "_Client_Call_" << id() << "("<< service_id << "_Client *client, const " << request_id() << " *request, " << response_id() << " **response);" << std::endl; + return ss.str(); +} + +std::string +CRPCClient::GenerateCallFunctionDefinition(std::string service_id) const +{ + std::stringstream ss; + ss << "int32_t " << service_id << "_Client_Call_" << id() << "("<< service_id << "_Client *client, const " << request_id() << " *request, " << response_id() << " **response)" << std::endl; + ss << "{" << std::endl; + ss << " assert(request != NULL);" << std::endl; + ss << GenerateClientBaseCheck(service_id) << std::endl; + ss << " int32_t status = 0;" << std::endl; + ss << " char *base64_buffer = NULL;" << std::endl; + ss << " int64_t base64_buffer_size = 0;" << std::endl; + ss << " char *request_buffer = NULL;" << std::endl; + ss << " int32_t request_buffer_size = 0;" << std::endl; + ss << " char* dump_buffer = NULL; " << std::endl; + ss << " int32_t dump_sz = 0;" << std::endl; + ss << GenerateCallLock(service_id) << std::endl; + // ss << GenerateLock(service_id) << std::endl; + ss << GeneratePrapare(service_id) << std::endl; + ss << " do {" << std::endl; + ss << " " << request_id() << "_Serialize(request, &request_buffer, &request_buffer_size);" << std::endl; + ss << " if (request_buffer == NULL || request_buffer_size == 0) {" << std::endl; + ss << " break;" << std::endl; + ss << " }" << std::endl; + ss << " base64_buffer_size = Base64encode_len(request_buffer_size + 10);" << std::endl; + ss << " base64_buffer = (char*)malloc(base64_buffer_size);" << std::endl; + ss << " if (base64_buffer == NULL) {" << std::endl; + ss << " break;" << std::endl; + ss << " }" << std::endl; + ss << " Base64encode(base64_buffer, request_buffer, request_buffer_size);" << std::endl; + ss << " const char* service_name = (const char*)strdup(\"" << service_id << "::" << id() << "\");"<< std::endl; + ss << " /* tpl pack A(ss)*/ " << std::endl; + ss << " {" << std::endl; +// ss << " const char* base64_buffer_ptr = strdup(base64_buffer); " << std::endl; + ss << " tpl_node* tn = tpl_map(\"A(ss)\", &service_name, &base64_buffer);" << std::endl; + ss << " status = tpl_pack(tn, 1);" << std::endl; + ss << " if (status == -1) { break; }" << std::endl; + ss << " tpl_dump(tn, TPL_MEM, &dump_buffer, &dump_sz);" << std::endl; + ss << " if (dump_sz < 0) { break; }" << std::endl; + ss << " }" << std::endl; + ss << " status = "<< service_id << "_Client_Send(client, dump_buffer, dump_sz);" << std::endl; + ss << " if (status != 0) {" << std::endl; + ss << " break;" << std::endl; + ss << " }" << std::endl; + // ss << " " << GenerateWaitOk(service_id) << std::endl; + ss << " } while (0);" << std::endl; + ss << std::endl; + ss << " " << service_id << "_Client_Priv *priv = (" << service_id << "_Client_Priv *)client->priv;" << std::endl; + ss << " if (response) {" << std::endl; + ss << " if (priv->ok) {" << std::endl; + ss << " *response = priv->response;" << std::endl; + ss << " } else {" << std::endl; + ss << " *response = NULL;" << std::endl; + ss << " }" << std::endl; + ss << " }" << std::endl; + // ss << GenerateUnlock(service_id) << std::endl; + ss << GenerateCallUnlock(service_id) << std::endl; + ss << " free(request_buffer);" << std::endl; + ss << " free(dump_buffer);" << std::endl; + // ss << " free(base64_buffer);" << std::endl; + ss << " return priv->ok ? 0 : -1;" << std::endl; + ss << "}" << std::endl; + return ss.str(); +} + }// namespace tqcq diff --git a/src/plugins/c/rpcs/crpc_client.h b/src/plugins/c/rpcs/crpc_client.h index 2729c73..6f83886 100644 --- a/src/plugins/c/rpcs/crpc_client.h +++ b/src/plugins/c/rpcs/crpc_client.h @@ -22,6 +22,8 @@ public: std::string GenerateStructAPIDeclareCodeBlock(std::string service_id) const override; std::string GenerateStructAPIDeclareAsyncCodeBlock(std::string service_id) const ; std::string GenerateAsyncCallback(std::string service_id) const; + std::string GenerateCallFunctionDeclaration(std::string service_id) const; + std::string GenerateCallFunctionDefinition(std::string service_id) const; }; }// namespace tqcq diff --git a/src/plugins/c/rpcs/crpc_server.cpp b/src/plugins/c/rpcs/crpc_server.cpp index 775fe45..b422681 100644 --- a/src/plugins/c/rpcs/crpc_server.cpp +++ b/src/plugins/c/rpcs/crpc_server.cpp @@ -32,16 +32,22 @@ std::string CRPCServer::GenerateStructAPIWrapper(std::string service_id) const { std::stringstream ss; - ss << "int32_t " << id() << "_Wrapper(" << service_id << "_Server *server, char *msg, int32_t msg_len)" + ss << "static int32_t " << id() << "_Wrapper(" << service_id << "_Server *server, char *msg, int32_t msg_len)" << std::endl; ss << "{" << std::endl; ss << " assert(server != NULL);" << std::endl; ss << " assert(msg != NULL || msg_len == 0);" << std::endl; - ss << " if (server->api." << id() << " == NULL) { return 0; }" << std::endl; + ss << " // if (server->api." << id() << " == NULL) { return 0; }" << std::endl; ss << std::endl; ss << " int32_t status = 0;" << std::endl; ss << " " << request_id() << " request;" << std::endl; ss << " " << response_id() << " response;" << std::endl; + ss << " char* buffer = NULL; " << std::endl; + ss << " char* base64_buffer = NULL; " << std::endl; + ss << " int32_t buffer_size = 0; " << std::endl; + ss << " int32_t base64_buffer_size = 0; " << std::endl; + ss << " char* response_msg = NULL;" << std::endl; + ss << " int32_t response_msg_len = 0;" << std::endl; ss << std::endl; ss << " do {" << std::endl; @@ -55,24 +61,38 @@ CRPCServer::GenerateStructAPIWrapper(std::string service_id) const ss << " " << response_id() << "_Init(&response);" << std::endl; ss << " " << response_id() << "_set_code(&response, 200);" << std::endl; ss << " " << response_id() << "_set_msg_string(&response, \"OK\");" << std::endl; - ss << " status = server->api." << id() << "(&request, &response);" << std::endl; - ss << " if (status != 0) {" << std::endl; - ss << " printf(\"" << id() << " failed: %d\\n\", status);" << std::endl; - ss << " " << response_id() << "_set_code(&response, 500);" << std::endl; - ss << " " << response_id() << "_set_msg_string(&response, \"Internal Server Error\");" << std::endl; + ss << " if (server->api." << id() << ") {" << std::endl; + ss << " status = server->api." << id() << "(&request, &response);" << std::endl; + ss << " if (status != 0) {" << std::endl; + ss << " printf(\"" << id() << " failed: %d\\n\", status);" << std::endl; + ss << " " << response_id() << "_set_code(&response, 500);" << std::endl; + ss << " " << response_id() << "_set_msg_string(&response, \"Internal Server Error\");" << std::endl; + ss << " }" << std::endl; ss << " }" << std::endl; ss << std::endl; - ss << " char* response_msg = NULL;" << std::endl; - ss << " int32_t response_msg_len = 0;" << std::endl; ss << " status = " << response_id() << "_Serialize(&response, &response_msg, &response_msg_len);" << std::endl; ss << " if (status < 0) {" << std::endl; - ss << " printf(\"" << id() << " failed: %d\\n\", status);" << std::endl; - ss << " " << response_id() << "_set_code(&response, 500);" << std::endl; - ss << " " << response_id() << "_set_msg_string(&response, \"Internal Server Error\");" << std::endl; + ss << " printf(\"" << id() << "-> " << response_id() << "_Serialize failed: %d\\n\", status);" << std::endl; ss << " }" << std::endl; ss << std::endl; - ss << " int32_t send_result = DeviceService_Server_Send(server, response_msg, response_msg_len);" + ss << " base64_buffer_size = Base64encode_len(response_msg_len);" << std::endl; + ss << " base64_buffer = (char*)malloc(base64_buffer_size + 10);" << std::endl; + ss << " if (base64_buffer == NULL) {" << std::endl; + ss << " printf(\"" << id() << " failed: %d\\n\", status);" << std::endl; + ss << " break;" << std::endl; + ss << " }" << std::endl; + ss << " Base64encode(base64_buffer, response_msg, response_msg_len);" << std::endl; + ss << " // pack" << std::endl; + ss << " {" << std::endl; + ss << " const char* service_name = (const char*)strdup(\"" << service_id << "::" << id() << "\");" << std::endl; + // ss << " const char* base64_buffer_ptr = strdup(base64_buffer);" << std::endl; + ss << " tpl_node* tn = tpl_map(\"A(ss)\", &service_name, &base64_buffer);" << 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 << " }" << std::endl; + ss << " int32_t send_result = DeviceService_Server_Send(server, buffer, buffer_size);" << std::endl; ss << " if (send_result < 0) {" << std::endl; ss << " printf(\"" << id() << " failed: %d\\n\", status);" << std::endl; @@ -80,6 +100,9 @@ CRPCServer::GenerateStructAPIWrapper(std::string service_id) const ss << " }" << std::endl; ss << " status = 0;" << std::endl; ss << " } while (0);" << std::endl; + ss << " free(buffer);" << std::endl; + // ss << " free(base64_buffer);" << std::endl; + ss << " free(response_msg);" << std::endl; ss << " " << response_id() << "_Destroy(&response);" << std::endl; ss << " " << request_id() << "_Destroy(&request);" << std::endl; ss << " return status;" << std::endl; diff --git a/src/plugins/plugin.cpp b/src/plugins/plugin.cpp index c304649..cc1943c 100644 --- a/src/plugins/plugin.cpp +++ b/src/plugins/plugin.cpp @@ -12,7 +12,8 @@ static void EnsureDirectoryExist(std::string path) std::string::size_type pos = 0; // create path recursively std::filesystem::path p(path); - if (!std::filesystem::exists(p.parent_path())) { std::filesystem::create_directories(p.parent_path()); } + // auto abs_path = std::filesystem::absolute(p); + if (!std::filesystem::exists(p)) { std::filesystem::create_directories(p); } // bool is_end = false; // while (!is_end) {