feature v0.1.0
Some checks failed
build-crpc / build (Release, host.toolchain.cmake) (push) Failing after 4m15s
build-crpc / build (Debug, host.toolchain.cmake) (push) Failing after 10m39s

This commit is contained in:
tqcq 2023-12-03 20:05:41 +08:00
parent b074b331f8
commit e5bed79e64
12 changed files with 588 additions and 111 deletions

View File

@ -4,9 +4,19 @@
#include "message.h" #include "message.h"
#include <sstream> #include <sstream>
#include <map>
namespace tqcq { namespace tqcq {
Message::Message(std::string id) : id_(id){}
int unique_id_counter_ = 1;
static std::map<std::string, int> 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 std::string
Message::id() const Message::id() const
@ -50,4 +60,11 @@ Message::ToString()
ss << "};"; ss << "};";
return ss.str(); return ss.str();
} }
int
Message::unique_id() const
{
return unique_id_;
}
}// namespace tqcq }// namespace tqcq

View File

@ -27,7 +27,10 @@ public:
std::set<std::string> dependencies() const; std::set<std::string> dependencies() const;
std::string ToString(); std::string ToString();
int unique_id() const;
private: private:
int unique_id_;
std::string id_; std::string id_;
std::vector<Item::Ptr> items_; std::vector<Item::Ptr> items_;
std::set<std::string> dependencies_; std::set<std::string> dependencies_;

View File

@ -118,12 +118,11 @@ std::string
CMessagePlugin::GenerateStructItem(Message::Ptr message) CMessagePlugin::GenerateStructItem(Message::Ptr message)
{ {
std::stringstream ss; std::stringstream ss;
ss << " int32_t _message_unique_id; /* " << message->unique_id() << " */" << std::endl;
ss << std::endl;
for (auto &item : message->items()) { for (auto &item : message->items()) {
ss << CItem::Create(item)->GenerateStructDeclareCodeBlock(message->id()) << std::endl; ss << CItem::Create(item)->GenerateStructDeclareCodeBlock(message->id()) << std::endl;
} }
if (message->items().empty()) {
ss << " char:8; " << std::endl;
}
return ss.str(); return ss.str();
} }
@ -144,12 +143,13 @@ CMessagePlugin::GenerateFunctionDeclaration(Message::Ptr message)
ss << "void " << message->id() << "_Destroy(" << message->id() << "* message);" << std::endl; ss << "void " << message->id() << "_Destroy(" << message->id() << "* message);" << std::endl;
ss << 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; << "* message, char** buffer, int32_t *buffer_size);" << std::endl;
ss << "int32_t " << message->id() << "_Deserialize(" << message->id() 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 << std::endl;
ss << "int32_t " << message->id() << "_get__message_unique_id(" << message->id() << "* message);" << std::endl;
for (auto &item : message->items()) { for (auto &item : message->items()) {
auto c_item = CItem::Create(item); auto c_item = CItem::Create(item);
ss << c_item->GenerateSetterDeclaration(message->id()) << std::endl; ss << c_item->GenerateSetterDeclaration(message->id()) << std::endl;
@ -172,6 +172,9 @@ CMessagePlugin::GenerateFunctionDefinition(Message::Ptr message)
ss << GenerateFunctionDefinitionDeserialize(message); ss << GenerateFunctionDefinitionDeserialize(message);
ss << std::endl; 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()) { for (auto &item : message->items()) {
auto c_item = CItem::Create(item); auto c_item = CItem::Create(item);
ss << c_item->GenerateSetterDefinition(message->id()) << std::endl; ss << c_item->GenerateSetterDefinition(message->id()) << std::endl;
@ -201,7 +204,8 @@ GetTPLMap(std::vector<Item::Ptr> items)
{ {
std::stringstream ss; std::stringstream ss;
ss << "A("; // first i is message_unique_id(int32_t)
ss << "A(i";
for (auto &item : items) { for (auto &item : items) {
switch (item->type()) { switch (item->type()) {
case Item::Type::kInt32: case Item::Type::kInt32:
@ -247,10 +251,11 @@ std::string
CMessagePlugin::GenerateFunctionDefinitionSerialize(Message::Ptr message) CMessagePlugin::GenerateFunctionDefinitionSerialize(Message::Ptr message)
{ {
std::stringstream ss; 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; << "* message, char** buffer, int32_t* buffer_size) {" << std::endl;
ss << " int32_t status = 0;" << 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()); std::string tpl_format = GetTPLMap(message->items());
auto items = message->items(); auto items = message->items();
for (int idx = 0; idx < message->items().size(); idx++) { for (int idx = 0; idx < message->items().size(); idx++) {
@ -294,22 +299,27 @@ CMessagePlugin::GenerateFunctionDefinitionSerialize(Message::Ptr message)
} }
} }
ss << " } while (0);" << std::endl; 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 << " do {" << std::endl;
ss << " if (status != 0) { break; }" << std::endl; ss << " if (status != 0) { break; }" << std::endl;
ss << " tpl_node* tn = tpl_map(\"" << tpl_format << "\"," << GetTPLArgs(message->items())<< ");" << std::endl; ss << " tpl_node* tn = tpl_map(\"" << tpl_format << "\", &message->_message_unique_id" << tpl_args << ");" << std::endl;
ss << " tpl_pack(tn, 1);" << 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_dump(tn, TPL_MEM, buffer, buffer_size);" << std::endl;
ss << " tpl_free(tn);" << std::endl; ss << " tpl_free(tn);" << std::endl;
ss << " return *buffer_size; " << std::endl; ss << " return *buffer_size; " << std::endl;
ss << " } while (0);" << std::endl; ss << " } while (0);" << std::endl;
for (int idx = 0; idx < message->items().size(); idx++) { // for (int idx = 0; idx < message->items().size(); idx++) {
const auto &item = items[idx]; // const auto &item = items[idx];
if (item->type() == Item::Type::kString) { // if (item->type() == Item::Type::kString) {
ss << " if (item_" << idx << ") { free(item_" << idx << "); }" << std::endl; // ss << " if (item_" << idx << ") { free(item_" << idx << "); }" << std::endl;
} // }
} // }
} }
ss << " return 0; " << std::endl; ss << " return 0; " << std::endl;
ss << "}" << std::endl; ss << "}" << std::endl;
@ -322,10 +332,11 @@ CMessagePlugin::GenerateFunctionDefinitionDeserialize(Message::Ptr message)
std::stringstream ss; std::stringstream ss;
ss << "int32_t " << message->id() << "_Deserialize(" << message->id() 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 << " int32_t status = 0;" << std::endl;
ss << " size_t dump_sz = buffer_size;" << 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 << " do {" << std::endl;
ss << " " << message->id() << "_Destroy(message);" << std::endl; ss << " " << message->id() << "_Destroy(message);" << std::endl;
ss << " " << message->id() << "_Init(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_format = GetTPLMap(message->items());
std::string tpl_args = GetTPLArgs(message->items()); std::string tpl_args = GetTPLArgs(message->items());
ss << " tpl_node* tn = tpl_map(\"" << tpl_format << "\", " << tpl_args << ");" << std::endl; if (!message->items().empty()) {
ss << " tpl_load(tn, TPL_MEM, buffer, dump_sz);" << std::endl; tpl_args = ", " + tpl_args;
ss << " tpl_unpack(tn, 1);" << std::endl; }
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 << " tpl_free(tn);" << std::endl;
ss << std::endl; ss << std::endl;
@ -391,6 +407,7 @@ CMessagePlugin::GenerateFunctionDefinitionInit(Message::Ptr message)
{ {
std::stringstream ss; std::stringstream ss;
ss << "void " << message->id() << "_Init(" << message->id() << "* message) {" << std::endl; 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()) { for (auto &item : message->items()) {
auto c_item = CItem::Create(item); auto c_item = CItem::Create(item);
ss << c_item->GenerateInitCodeBlock(message->id()) << std::endl; ss << c_item->GenerateInitCodeBlock(message->id()) << std::endl;

View File

@ -11,6 +11,75 @@
#include "plugins/c/rpcs/crpc_client.h" #include "plugins/c/rpcs/crpc_client.h"
namespace tqcq { 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) CServiceClientPlugin::CServiceClientPlugin(std::string generate_path, std::string generate_prefix)
: CServicePlugin(std::move(generate_path), std::move(generate_prefix)) : CServicePlugin(std::move(generate_path), std::move(generate_prefix))
{} {}
@ -57,17 +126,17 @@ std::string
CServiceClientPlugin::GenerateHeaderStructAPIStart(Service::Ptr service) CServiceClientPlugin::GenerateHeaderStructAPIStart(Service::Ptr service)
{ {
std::stringstream ss; std::stringstream ss;
for (const auto &rpc : service->rpcs()) { // for (const auto &rpc : service->rpcs()) {
auto crpc = CRPCClient::Create(rpc); // auto crpc = CRPCClient::Create(rpc);
ss << crpc->GenerateAsyncCallback(service->id()) << std::endl; // ss << crpc->GenerateAsyncCallback(service->id()) << std::endl;
} // }
ss << std::endl; // ss << std::endl;
ss << "typedef struct _" << service->id() << "_Client " << service->id() << "_Client;" << std::endl; ss << "typedef struct _" << service->id() << "_Client " << service->id() << "_Client;" << std::endl;
ss << std::endl; ss << std::endl;
// //
// ss << "typedef struct " // ss << "typedef struct "
// << "{" << std::endl; // << "{" << std::endl;
return ss.str(); return ss.str();
} }
@ -76,7 +145,6 @@ CServiceClientPlugin::GenerateHeaderStructAPIItems(Service::Ptr service)
{ {
std::stringstream ss; std::stringstream ss;
return ss.str(); return ss.str();
} }
@ -84,8 +152,8 @@ std::string
CServiceClientPlugin::GenerateHeaderStructAPIEnd(Service::Ptr service) CServiceClientPlugin::GenerateHeaderStructAPIEnd(Service::Ptr service)
{ {
std::stringstream ss; std::stringstream ss;
// ss << "} " << service->id() << "_Client_API" // ss << "} " << service->id() << "_Client_API"
// << ";" << std::endl; // << ";" << std::endl;
return ss.str(); return ss.str();
} }
@ -107,13 +175,14 @@ CServiceClientPlugin::GenerateHeaderStructItems(Service::Ptr service)
} }
ss << std::endl; ss << std::endl;
for (const auto &rpc : service->rpcs()) { // for (const auto &rpc : service->rpcs()) {
auto crpc = CRPCClient::Create(rpc); // auto crpc = CRPCClient::Create(rpc);
ss << crpc->GenerateStructAPIDeclareAsyncCodeBlock(service->id()); // ss << crpc->GenerateStructAPIDeclareAsyncCodeBlock(service->id());
} // }
ss << std::endl; // ss << std::endl;
ss << " void* impl;" << std::endl; ss << " void* impl;" << std::endl;
ss << " void* priv;" << std::endl;
return ss.str(); return ss.str();
} }
@ -130,9 +199,15 @@ CServiceClientPlugin::GenerateHeaderFunctionDeclaration(Service::Ptr service)
{ {
std::stringstream ss; std::stringstream ss;
ss << "int32_t " << service->id() << "_Client_Init(" << service->id() << "_Client* client);" << std::endl; 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 << "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; 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(); return ss.str();
} }
@ -142,9 +217,13 @@ CServiceClientPlugin::GenerateSourceIncludeFiles(Service::Ptr service)
std::stringstream ss; std::stringstream ss;
ss << "#include <assert.h>" << std::endl; ss << "#include <assert.h>" << std::endl;
ss << "#include <stdint.h>" << std::endl; ss << "#include <stdint.h>" << std::endl;
ss << "#include <string.h>" << std::endl;
ss << "#include <stdarg.h>" << std::endl; ss << "#include <stdarg.h>" << std::endl;
ss << "#include <stdio.h>" << std::endl; ss << "#include <stdio.h>" << std::endl;
ss << "#include <crpc/service.h>" << std::endl; ss << "#include <base64.h>" << std::endl;
ss << "#include <tpl.h>" << std::endl;
ss << "#include <pthread.h>" << std::endl;
ss << "#include <crpc/client.h>" << std::endl;
ss << "#include \"" << GenerateHeaderFileName(service->id()) << "\"" << std::endl; ss << "#include \"" << GenerateHeaderFileName(service->id()) << "\"" << std::endl;
std::set<std::string> message_set; std::set<std::string> message_set;
for (const auto &rpc : service->rpcs()) { 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; } 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(); return ss.str();
} }
@ -169,10 +258,16 @@ CServiceClientPlugin::GenerateSourceFunctionDefinition(Service::Ptr service)
ss << std::endl; ss << std::endl;
ss << GenerateSourceDispatchFunctionDefinition(service) << std::endl;
ss << GenerateSourceInitFunctionDefinition(service) << std::endl; ss << GenerateSourceInitFunctionDefinition(service) << std::endl;
ss << GenerateSourceConnectFunctionDefinition(service) << std::endl; ss << GenerateSourceConnectFunctionDefinition(service) << std::endl;
ss << GenerateSourceDestroyFunctionDefinition(service) << std::endl; ss << GenerateSourceDestroyFunctionDefinition(service) << std::endl;
ss << GenerateSourceSendFunctionDefinition(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(); return ss.str();
} }
@ -180,17 +275,25 @@ std::string
CServiceClientPlugin::GenerateSourceInitFunctionDefinition(Service::Ptr service) CServiceClientPlugin::GenerateSourceInitFunctionDefinition(Service::Ptr service)
{ {
std::stringstream ss; std::stringstream ss;
ss << "int32_t " << service->id() << "_Client_Init(" << service->id() << "_Client* client, " << service->id() ss << "int32_t " << service->id() << "_Client_Init(" << service->id() << "_Client* client)" << std::endl;
<< "_Client_API* api)" << std::endl;
ss << "{" << std::endl; ss << "{" << std::endl;
ss << " assert(client != NULL);" << std::endl; ss << " assert(client != NULL);" << std::endl;
ss << " client->impl = Service_New();" << std::endl; ss << " int32_t status = 0;" << std::endl;
ss << " if (api) {" << std::endl; ss << " do {" << std::endl;
ss << " memcpy(&client->api, api, sizeof(" << service->id() << "_Client_API));" << std::endl; ss << " client->impl = Client_New();" << std::endl;
ss << " } else {" << std::endl; ss << " if (client->impl == NULL) { status = -1; break; }" << std::endl;
ss << " memset(&client->api, 0, sizeof(" << service->id() << "_Client_API));" << std::endl; ss << std::endl;
ss << " }" << std::endl; ss << " client->priv = malloc(sizeof(" << service->id() << "_Client_Priv));" << std::endl;
ss << " if (client->impl == NULL) { return -1; }" << 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 << " return 0;" << std::endl;
ss << "}" << std::endl; ss << "}" << std::endl;
return ss.str(); 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 << "void " << service->id() << "_Client_Destroy(" << service->id() << "_Client* client)" << std::endl;
ss << "{" << std::endl; ss << "{" << std::endl;
ss << " if (client == NULL) { return; }" << 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; ss << "}" << std::endl;
return ss.str(); return ss.str();
} }
@ -212,14 +325,14 @@ std::string
CServiceClientPlugin::GenerateSourceSendFunctionDefinition(Service::Ptr service) CServiceClientPlugin::GenerateSourceSendFunctionDefinition(Service::Ptr service)
{ {
std::stringstream ss; 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 << "{" << std::endl;
ss << " assert(client != NULL);" << std::endl; ss << GenerateClientBaseCheck(service->id()) << std::endl;
ss << " assert(client->impl != NULL);" << std::endl;
ss << " assert(msg != NULL || msg_len == 0);" << std::endl; ss << " assert(msg != NULL || msg_len == 0);" << std::endl;
ss << " assert(msg_len > 0);" << std::endl; ss << " assert(msg_len > 0);" << std::endl;
ss << 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; ss << "}" << std::endl;
return ss.str(); return ss.str();
} }
@ -227,7 +340,93 @@ CServiceClientPlugin::GenerateSourceSendFunctionDefinition(Service::Ptr service)
std::string std::string
CServiceClientPlugin::GenerateSourceConnectFunctionDefinition(Service::Ptr service) 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 }// namespace tqcq

View File

@ -14,6 +14,7 @@ public:
CServiceClientPlugin(std::string generate_path, std::string generate_prefix = "CService"); CServiceClientPlugin(std::string generate_path, std::string generate_prefix = "CService");
virtual ~CServiceClientPlugin() = default; virtual ~CServiceClientPlugin() = default;
protected: protected:
std::string GenerateHeaderGuardStart(Service::Ptr service) override;
std::string GenerateHeaderFileName(std::string service_id) override; std::string GenerateHeaderFileName(std::string service_id) override;
std::string GenerateSourceFileName(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 GenerateSourceConnectFunctionDefinition(Service::Ptr service);
std::string GenerateSourceDestroyFunctionDefinition(Service::Ptr service); std::string GenerateSourceDestroyFunctionDefinition(Service::Ptr service);
std::string GenerateSourceSendFunctionDefinition(Service::Ptr service); std::string GenerateSourceSendFunctionDefinition(Service::Ptr service);
std::string GenerateSourceDispatchFunctionDefinition(Service::Ptr service);
}; };
}// namespace tqcq }// namespace tqcq

View File

@ -68,8 +68,8 @@ CServicePlugin::GenerateSource(Service::Ptr service)
std::filesystem::path filename(GenerateSourceFileName(service->id())); std::filesystem::path filename(GenerateSourceFileName(service->id()));
std::ofstream ofs(path / filename); std::ofstream ofs(path / filename);
ofs << ss.str(); ofs << ss.str();
std::cout << ss.str() << std::endl; // out << ss.str() << std::endl;
std::cout << path / filename << std::endl; // std::cout << path / filename << std::endl;
} }
std::string std::string

View File

@ -126,8 +126,11 @@ CServiceServerPlugin::GenerateSourceIncludeFiles(Service::Ptr service)
std::stringstream ss; std::stringstream ss;
ss << "#include <assert.h>" << std::endl; ss << "#include <assert.h>" << std::endl;
ss << "#include <stdint.h>" << std::endl; ss << "#include <stdint.h>" << std::endl;
ss << "#include <string.h>" << std::endl;
ss << "#include <stdarg.h>" << std::endl; ss << "#include <stdarg.h>" << std::endl;
ss << "#include <stdio.h>" << std::endl; ss << "#include <stdio.h>" << std::endl;
ss << "#include <base64.h>" << std::endl;
ss << "#include <tpl.h>" << std::endl;
ss << "#include <crpc/service.h>" << std::endl; ss << "#include <crpc/service.h>" << std::endl;
ss << "#include \"" << GenerateHeaderFileName(service->id()) << "\"" << std::endl; ss << "#include \"" << GenerateHeaderFileName(service->id()) << "\"" << std::endl;
std::set<std::string> message_set; std::set<std::string> message_set;
@ -150,9 +153,10 @@ CServiceServerPlugin::GenerateSourceFunctionDefinition(Service::Ptr service)
ss << crpc->GenerateStructAPIWrapper(service->id()); ss << crpc->GenerateStructAPIWrapper(service->id());
ss << std::endl; ss << std::endl;
} }
ss << std::endl; ss << std::endl;
ss << GenerateSourceDispatchFunctionDefinition(service) << std::endl;
ss << GenerateSourceInitFunctionDefinition(service) << std::endl; ss << GenerateSourceInitFunctionDefinition(service) << std::endl;
ss << GenerateSourceBindFunctionDefinition(service) << std::endl; ss << GenerateSourceBindFunctionDefinition(service) << std::endl;
ss << GenerateSourceListenFunctionDefinition(service) << std::endl; ss << GenerateSourceListenFunctionDefinition(service) << std::endl;
@ -170,12 +174,13 @@ CServiceServerPlugin::GenerateSourceInitFunctionDefinition(Service::Ptr service)
ss << "{" << std::endl; ss << "{" << std::endl;
ss << " assert(server != NULL);" << std::endl; ss << " assert(server != NULL);" << std::endl;
ss << " server->impl = Service_New();" << 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 << " if (api) {" << std::endl;
ss << " memcpy(&server->api, api, sizeof(" << service->id() << "_Server_API));" << std::endl; ss << " memcpy(&server->api, api, sizeof(" << service->id() << "_Server_API));" << std::endl;
ss << " } else {" << std::endl; ss << " } else {" << std::endl;
ss << " memset(&server->api, 0, sizeof(" << service->id() << "_Server_API));" << std::endl; ss << " memset(&server->api, 0, sizeof(" << service->id() << "_Server_API));" << std::endl;
ss << " }" << std::endl; ss << " }" << std::endl;
ss << " if (server->impl == NULL) { return -1; }" << std::endl;
ss << " return 0;" << std::endl; ss << " return 0;" << std::endl;
ss << "}" << std::endl; ss << "}" << std::endl;
return ss.str(); return ss.str();
@ -245,4 +250,80 @@ CServiceServerPlugin::GenerateSourceSendFunctionDefinition(Service::Ptr service)
return ss.str(); 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 }// namespace tqcq

View File

@ -14,6 +14,8 @@ public:
CServiceServerPlugin(std::string generate_path, std::string generate_prefix = "CService"); CServiceServerPlugin(std::string generate_path, std::string generate_prefix = "CService");
virtual ~CServiceServerPlugin() = default; virtual ~CServiceServerPlugin() = default;
protected: protected:
std::string GenerateHeaderGuardStart(Service::Ptr service) override;
std::string GenerateHeaderFileName(std::string service_id) override; std::string GenerateHeaderFileName(std::string service_id) override;
std::string GenerateSourceFileName(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 GenerateSourceIncludeFiles(Service::Ptr service) override;
std::string GenerateSourceFunctionDefinition(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 GenerateSourceInitFunctionDefinition(Service::Ptr service);
std::string GenerateSourceBindFunctionDefinition(Service::Ptr service); std::string GenerateSourceBindFunctionDefinition(Service::Ptr service);
std::string GenerateSourceListenFunctionDefinition(Service::Ptr service); std::string GenerateSourceListenFunctionDefinition(Service::Ptr service);

View File

@ -5,6 +5,82 @@
#include "crpc_client.h" #include "crpc_client.h"
namespace tqcq { 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::Ptr
CRPCClient::Create(RPC::Ptr rpc) CRPCClient::Create(RPC::Ptr rpc)
{ {
@ -17,56 +93,37 @@ std::string
CRPCClient::GenerateStructAPIWrapper(std::string service_id) const CRPCClient::GenerateStructAPIWrapper(std::string service_id) const
{ {
std::stringstream ss; 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; << std::endl;
ss << "{" << std::endl; ss << "{" << std::endl;
ss << " assert(client != NULL);" << std::endl; ss << " assert(client != NULL);" << std::endl;
ss << " assert(msg != NULL || msg_len == 0);" << 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 << " int32_t status = 0;" << std::endl;
ss << " " << request_id() << " request;" << std::endl; ss << " " << response_id() << " *response = NULL;" << std::endl;
ss << " " << response_id() << " response;" << std::endl;
ss << std::endl;
ss << " do {" << std::endl; ss << " do {" << std::endl;
ss << " " << request_id() << "_Init(&request);" << std::endl; ss << " response = (" << response_id() << " *)malloc(sizeof(" << response_id() << "));" << std::endl;
ss << " status = " << request_id() << "_Deserialize(&request, msg, msg_len);" << std::endl; ss << " if (response == NULL) {" << std::endl;
ss << " if (status != 0) {" << std::endl; ss << " status = -1;" << std::endl;
ss << " " << request_id() << "_Destroy(&request);" << std::endl;
ss << " break;" << std::endl; ss << " break;" << std::endl;
ss << " }" << std::endl; ss << " }" << std::endl;
ss << std::endl;
ss << " " << response_id() << "_Init(&response);" << std::endl; ss << " " << response_id() << "_Init(response);" << std::endl;
ss << " " << response_id() << "_set_code(&response, 200);" << std::endl; ss << " status = " << response_id() << "_Deserialize(response, msg, msg_len);" << std::endl;
ss << " " << response_id() << "_set_msg_string(&response, \"OK\");" << std::endl;
ss << " status = client->api." << id() << "(&request, &response);" << std::endl;
ss << " if (status != 0) {" << std::endl; ss << " if (status != 0) {" << std::endl;
ss << " printf(\"" << id() << " failed: %d\\n\", status);" << std::endl; ss << " " << response_id() << "_Destroy(response);" << std::endl;
ss << " " << response_id() << "_set_code(&response, 500);" << std::endl; ss << " response = NULL;" << 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 << " break;" << std::endl; ss << " break;" << std::endl;
ss << " }" << std::endl; ss << " }" << std::endl;
ss << " status = 0;" << std::endl; ss << " } while(0);" << std::endl;
ss << " } while (0);" << std::endl; ss << std::endl;
ss << " " << response_id() << "_Destroy(&response);" << std::endl; // ss << GenerateLock(service_id) << std::endl;
ss << " " << request_id() << "_Destroy(&request);" << 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 << " return status;" << std::endl;
ss << "}" << std::endl; ss << "}" << std::endl;
return ss.str(); return ss.str();
@ -102,4 +159,74 @@ CRPCClient::GenerateAsyncCallback(std::string service_id) const
return ss.str(); 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 }// namespace tqcq

View File

@ -22,6 +22,8 @@ public:
std::string GenerateStructAPIDeclareCodeBlock(std::string service_id) const override; std::string GenerateStructAPIDeclareCodeBlock(std::string service_id) const override;
std::string GenerateStructAPIDeclareAsyncCodeBlock(std::string service_id) const ; std::string GenerateStructAPIDeclareAsyncCodeBlock(std::string service_id) const ;
std::string GenerateAsyncCallback(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 }// namespace tqcq

View File

@ -32,16 +32,22 @@ std::string
CRPCServer::GenerateStructAPIWrapper(std::string service_id) const CRPCServer::GenerateStructAPIWrapper(std::string service_id) const
{ {
std::stringstream ss; 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; << std::endl;
ss << "{" << std::endl; ss << "{" << std::endl;
ss << " assert(server != NULL);" << std::endl; ss << " assert(server != NULL);" << std::endl;
ss << " assert(msg != NULL || msg_len == 0);" << 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 << std::endl;
ss << " int32_t status = 0;" << std::endl; ss << " int32_t status = 0;" << std::endl;
ss << " " << request_id() << " request;" << std::endl; ss << " " << request_id() << " request;" << std::endl;
ss << " " << response_id() << " response;" << 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 << std::endl;
ss << " do {" << 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() << "_Init(&response);" << std::endl;
ss << " " << response_id() << "_set_code(&response, 200);" << std::endl; ss << " " << response_id() << "_set_code(&response, 200);" << std::endl;
ss << " " << response_id() << "_set_msg_string(&response, \"OK\");" << std::endl; ss << " " << response_id() << "_set_msg_string(&response, \"OK\");" << std::endl;
ss << " if (server->api." << id() << ") {" << std::endl;
ss << " status = server->api." << id() << "(&request, &response);" << std::endl; ss << " status = server->api." << id() << "(&request, &response);" << std::endl;
ss << " if (status != 0) {" << std::endl; ss << " if (status != 0) {" << std::endl;
ss << " printf(\"" << id() << " failed: %d\\n\", status);" << std::endl; ss << " printf(\"" << id() << " failed: %d\\n\", status);" << std::endl;
ss << " " << response_id() << "_set_code(&response, 500);" << std::endl; ss << " " << response_id() << "_set_code(&response, 500);" << std::endl;
ss << " " << response_id() << "_set_msg_string(&response, \"Internal Server Error\");" << std::endl; ss << " " << response_id() << "_set_msg_string(&response, \"Internal Server Error\");" << std::endl;
ss << " }" << std::endl; ss << " }" << 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);" ss << " status = " << response_id() << "_Serialize(&response, &response_msg, &response_msg_len);"
<< std::endl; << std::endl;
ss << " if (status < 0) {" << std::endl; ss << " if (status < 0) {" << std::endl;
ss << " printf(\"" << id() << " failed: %d\\n\", status);" << std::endl; ss << " printf(\"" << id() << "-> " << response_id() << "_Serialize 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 << 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; << std::endl;
ss << " if (send_result < 0) {" << std::endl; ss << " if (send_result < 0) {" << std::endl;
ss << " printf(\"" << id() << " failed: %d\\n\", status);" << 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 << " }" << std::endl;
ss << " status = 0;" << std::endl; ss << " status = 0;" << std::endl;
ss << " } while (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 << " " << response_id() << "_Destroy(&response);" << std::endl;
ss << " " << request_id() << "_Destroy(&request);" << std::endl; ss << " " << request_id() << "_Destroy(&request);" << std::endl;
ss << " return status;" << std::endl; ss << " return status;" << std::endl;

View File

@ -12,7 +12,8 @@ static void EnsureDirectoryExist(std::string path)
std::string::size_type pos = 0; std::string::size_type pos = 0;
// create path recursively // create path recursively
std::filesystem::path p(path); 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; // bool is_end = false;
// while (!is_end) { // while (!is_end) {