feature support msg set_data

This commit is contained in:
tqcq 2023-12-02 15:31:16 +08:00
parent 0e45bc72ba
commit 7003f08f3a
11 changed files with 260 additions and 37 deletions

View File

@ -183,19 +183,21 @@ CMessagePlugin::GenerateSourceIncludeFile(Message::Ptr message)
{
std::stringstream ss;
ss << "#include \"" << GenerateHeaderFileName(message->id()) << "\"" << std::endl;
ss << "#include <assert.h>" << std::endl;
ss << "#include <string.h>" << std::endl;
ss << "#include <stdlib.h>" << std::endl;
ss << "#include <tpl.h>" << std::endl;
ss << "#include <base64.h>" << std::endl;
ss << std::endl;
return ss.str();
}
static std::string GetTPLMap(std::vector<Item::Ptr> items)
static std::string
GetTPLMap(std::vector<Item::Ptr> items)
{
std::stringstream ss;
ss << "S(";
ss << "A(";
for (auto &item : items) {
switch (item->type()) {
case Item::Type::kInt32:
@ -214,21 +216,96 @@ static std::string GetTPLMap(std::vector<Item::Ptr> items)
return ss.str();
}
static std::string GetTPLArgs(std::vector<Item::Ptr> items)
{
std::stringstream ss;
for (int idx = 0; idx < items.size(); idx++) {
const auto &item = items[idx];
if (item->type() == Item::Type::kInt32) {
ss << "&item_" << idx;
} else if (item->type() == Item::Type::kString) {
ss << "&item_" << idx;
} else if (item->type() == Item::Type::kMessage) {
// type_name = "char*";
}
if (idx != items.size() - 1) {
ss << ", ";
}
}
return ss.str();
}
// int Base64encode(char *encoded, const char *string, int len)
// int Base64decode(char *bufplain, const char *bufcoded)
// int Base64decode_len(const char *bufcoded)
// int Base64encode_len(int len)
std::string
CMessagePlugin::GenerateFunctionDefinitionSerialize(Message::Ptr message)
{
std::stringstream ss;
ss << "int32_t " << message->id() << "_Serialize(" << message->id()
<< "* message, char** buffer, int32_t* buffer_size) {" << std::endl;
ss << " int32_t status = 0;" << std::endl;
if (!message->items().empty()) {
std::string tpl_format = GetTPLMap(message->items());
auto items = message->items();
for (int idx = 0; idx < message->items().size(); idx++) {
const auto &item = items[idx];
std::string type_name;
std::string default_value;
if (item->type() == Item::Type::kInt32) {
type_name = "int32_t";
default_value = "0";
} else if (item->type() == Item::Type::kString) {
type_name = "char*";
default_value = "NULL";
} else if (item->type() == Item::Type::kMessage) {
// type_name = "char*";
}
ss << " " << type_name << " item_" << idx << " = " << default_value << ";" << std::endl;
}
ss << " do {" << std::endl;
ss << " tpl_node* tn = tpl_map(\"" << tpl_format << "\", message);" << std::endl;
ss << " tpl_pack(tn, 0);" << std::endl;
for (int idx = 0; idx < message->items().size(); idx++) {
const auto &item = items[idx];
std::string type_name;
if (item->type() == Item::Type::kInt32) {
ss << " item_" << idx << " = message->" << item->id() << ";" << std::endl;
ss << std::endl;
} else if (item->type() == Item::Type::kString) {
ss << " // item_" << idx << std::endl;
ss << " {" << std::endl;
ss << " int32_t base64_size = Base64encode_len(message->" << item->id() << "_len);" << std::endl;
ss << " item_" << idx << " = (char*)malloc(base64_size + 1);" << std::endl;
ss << " if (item_" << idx << " == NULL) { " << std::endl;
ss << " status = -1;" << std::endl;
ss << " break;" << std::endl;
ss << " }" << std::endl;
ss << " int32_t encoded_len = Base64encode(item_" << idx << ", message->" << item->id() << ", message->" << item->id() << "_len);" << std::endl;
ss << " assert(encoded_len == base64_size);" << std::endl;
ss << " item_" << idx << "[encoded_len] = '\\0';" << std::endl;
ss << " }" << std::endl;
ss << std::endl;
} else if (item->type() == Item::Type::kMessage) {
// type_name = "char*";
}
}
ss << " } while (0);" << std::endl;
ss << " do {" << std::endl;
ss << " if (status != 0) { break; }" << std::endl;
ss << " tpl_node* tn = tpl_map(\"" << tpl_format << "\"," << GetTPLArgs(message->items())<< ");" << std::endl;
ss << " tpl_pack(tn, 1);" << std::endl;
ss << " tpl_dump(tn, TPL_MEM, buffer, buffer_size);" << std::endl;
ss << " tpl_free(tn);" << std::endl;
ss << " return *buffer_size; " << std::endl;
ss << " } while (0);" << std::endl;
for (int idx = 0; idx < message->items().size(); idx++) {
const auto &item = items[idx];
if (item->type() == Item::Type::kString) {
ss << " if (item_" << idx << ") { free(item_" << idx << "); }" << std::endl;
}
}
}
ss << " return 0; " << std::endl;
ss << "}" << std::endl;
@ -242,16 +319,62 @@ CMessagePlugin::GenerateFunctionDefinitionDeserialize(Message::Ptr message)
std::stringstream ss;
ss << "int32_t " << message->id() << "_Deserialize(" << message->id()
<< "* message, char* buffer, int32_t buffer_size) {" << std::endl;
ss << " int32_t status = 0;" << std::endl;
ss << " size_t dump_sz = buffer_size;" << std::endl;
if (!message->items().empty()) {
std::string tpl_format = GetTPLMap(message->items());
ss << " do {" << std::endl;
ss << " " << message->id() << "_Destroy(message);" << std::endl;
ss << " size_t dump_sz = buffer_size;" << std::endl;
ss << " tpl_node* tn = tpl_map(\"" << tpl_format << "\", message);" << std::endl;
ss << " " << message->id() << "_Init(message);" << std::endl;
auto items = message->items();
for (int idx = 0; idx < message->items().size(); idx++) {
const auto &item = items[idx];
std::string type_name;
if (item->type() == Item::Type::kInt32) {
ss << " int32_t item_" << idx << ";" << std::endl;
} else if (item->type() == Item::Type::kString) {
ss << " char* item_" << idx << " = NULL;" << std::endl;
} else if (item->type() == Item::Type::kMessage) {
// type_name = "char*";
}
}
ss << std::endl;
std::string tpl_format = GetTPLMap(message->items());
std::string tpl_args = GetTPLArgs(message->items());
ss << " tpl_node* tn = tpl_map(\"" << tpl_format << "\", " << tpl_args << ");" << std::endl;
ss << " tpl_load(tn, TPL_MEM, buffer, dump_sz);" << std::endl;
ss << " tpl_unpack(tn, 0);" << std::endl;
ss << " tpl_unpack(tn, 1);" << std::endl;
ss << " tpl_free(tn);" << std::endl;
ss << " return dump_sz; " << std::endl;
ss << std::endl;
for (int idx = 0; idx < message->items().size(); idx++) {
const auto &item = items[idx];
std::string type_name;
std::string item_name = "item_" + std::to_string(idx);
if (item->type() == Item::Type::kInt32) {
ss << " " << message->id() << "_set_" << item->id() << "(message, item_" << idx << ");" << std::endl;
} else if (item->type() == Item::Type::kString) {
ss << " // item_" << idx << std::endl;
ss << " {" << std::endl;
ss << " int32_t decoded_len = " << item_name << " == NULL ? 0 : Base64decode_len(" << item_name << ");" << std::endl;
ss << " char* tmp_str" << " = (char*)malloc(decoded_len + 1);" << std::endl;
ss << " if (item_" << idx << " == NULL) { " << std::endl;
ss << " status = -1;" << std::endl;
ss << " break;" << std::endl;
ss << " }" << std::endl;
// ss << " item_" << idx << "[data_len] = '\\0';" << std::endl;
ss << " int32_t data_len = Base64decode(tmp_str, item_" << idx << ");" << std::endl;
ss << " " << message->id() << "_set_" << item->id() << "_data(message, tmp_str, data_len);" << std::endl;
ss << " free(tmp_str);" << std::endl;
ss << " }" << std::endl;
} else if (item->type() == Item::Type::kMessage) {
// type_name = "char*";
}
}
ss << " } while (0);" << std::endl;
}
ss << " return 0; " << std::endl;

View File

@ -9,14 +9,6 @@
namespace tqcq {
std::string
GenerateHeaderFileName(std::string id)
{
std::stringstream ss;
ss << id << ".h";
return ss.str();
}
std::string
CServicePlugin::GenerateGuardMacro(std::string id, std::string prefix)
{
@ -45,6 +37,11 @@ CServicePlugin::GenerateHeader(Service::Ptr service)
ss << GenerateHeaderStructEnd(service);
ss << std::endl;
ss << GenerateHeaderStructAPIStart(service);
ss << GenerateHeaderStructAPIItems(service);
ss << GenerateHeaderStructAPIEnd(service);
ss << std::endl;
ss << GenerateHeaderFunctionDeclaration(service);
ss << std::endl;

View File

@ -17,6 +17,9 @@ public:
CServicePlugin(std::string generate_path, std::string generate_prefix = "CService");
virtual ~CServicePlugin() = default;
protected:
virtual std::string GenerateHeaderFileName(std::string service_id) = 0;
virtual std::string GenerateSourceFileName(std::string service_id) = 0;
virtual void GenerateHeader(Service::Ptr service) override;
virtual void GenerateSource(Service::Ptr service) override;
@ -27,6 +30,11 @@ protected:
virtual std::string GenerateHeaderStructStart(Service::Ptr service) = 0;
virtual std::string GenerateHeaderStructItems(Service::Ptr service) = 0;
virtual std::string GenerateHeaderStructEnd(Service::Ptr service) = 0;
virtual std::string GenerateHeaderStructAPIStart(Service::Ptr service) = 0;
virtual std::string GenerateHeaderStructAPIItems(Service::Ptr service) = 0;
virtual std::string GenerateHeaderStructAPIEnd(Service::Ptr service) = 0;
virtual std::string GenerateHeaderFunctionDeclaration(Service::Ptr service) = 0;
};

View File

@ -4,11 +4,12 @@
#include "c_service_server_plugin.h"
#include <sstream>
#include <utility>
#include "rpcs/crpc_server.h"
namespace tqcq {
CServiceServerPlugin::CServiceServerPlugin(std::string generate_path, std::string generate_prefix)
: CServicePlugin(generate_path, generate_prefix)
: CServicePlugin(std::move(generate_path), std::move(generate_prefix))
{}
std::string
@ -60,7 +61,7 @@ CServiceServerPlugin::GenerateHeaderGuardEnd(Service::Ptr service)
}
std::string
CServiceServerPlugin::GenerateHeaderStructStart(Service::Ptr service)
CServiceServerPlugin::GenerateHeaderStructAPIStart(Service::Ptr service)
{
std::stringstream ss;
ss << "typedef struct " << "{" << std::endl;
@ -68,7 +69,7 @@ CServiceServerPlugin::GenerateHeaderStructStart(Service::Ptr service)
}
std::string
CServiceServerPlugin::GenerateHeaderStructItems(Service::Ptr service)
CServiceServerPlugin::GenerateHeaderStructAPIItems(Service::Ptr service)
{
std::stringstream ss;
for (const auto& rpc : service->rpcs()) {
@ -79,18 +80,52 @@ CServiceServerPlugin::GenerateHeaderStructItems(Service::Ptr service)
}
std::string
CServiceServerPlugin::GenerateHeaderStructEnd(Service::Ptr service)
CServiceServerPlugin::GenerateHeaderStructAPIEnd(Service::Ptr service)
{
std::stringstream ss;
ss << "} " << service->id() << ";" << std::endl;
ss << "} " << service->id() << "_API" << ";" << std::endl;
return ss.str();
}
std::string
CServiceServerPlugin::GenerateHeaderFunctionDeclaration(Service::Ptr service)
{
std::stringstream ss;
return ss.str();
}
std::string
CServiceServerPlugin::GenerateHeaderFileName(std::string service_id)
{
std::stringstream ss;
ss << service_id << "_Server.h";
return ss.str();
}
std::string
CServiceServerPlugin::GenerateSourceFileName(std::string service_id)
{
std::stringstream ss;
ss << service_id << "_Server.c";
return ss.str();
}
std::string
CServiceServerPlugin::GenerateHeaderStructStart(Service::Ptr service)
{
return std::string();
}
std::string
CServiceServerPlugin::GenerateHeaderStructItems(Service::Ptr service)
{
return std::string();
}
std::string
CServiceServerPlugin::GenerateHeaderStructEnd(Service::Ptr service)
{
return std::string();
}
}// namespace tqcq

View File

@ -14,12 +14,20 @@ public:
CServiceServerPlugin(std::string generate_path, std::string generate_prefix = "CService");
virtual ~CServiceServerPlugin() = default;
protected:
std::string GenerateHeaderFileName(std::string service_id) override;
std::string GenerateSourceFileName(std::string service_id) override;
std::string GenerateHeaderGuardStart(Service::Ptr service) override;
std::string GenerateHeaderIncludeFiles(Service::Ptr service) override;
std::string GenerateHeaderGuardEnd(Service::Ptr service) override;
std::string GenerateHeaderStructStart(Service::Ptr service) override;
std::string GenerateHeaderStructItems(Service::Ptr service) override;
std::string GenerateHeaderStructEnd(Service::Ptr service) override;
std::string GenerateHeaderStructAPIStart(Service::Ptr service) override;
std::string GenerateHeaderStructAPIItems(Service::Ptr service) override;
std::string GenerateHeaderStructAPIEnd(Service::Ptr service) override;
std::string GenerateHeaderFunctionDeclaration(Service::Ptr service) override;
};

View File

@ -11,13 +11,19 @@ CItemString::CItemString(Item::Ptr item) : CItem(item) {}
std::string
CItemString::GenerateStructDeclareCodeBlock(std::string message_id) const
{
return " char* " + id() + ";";
std::stringstream ss;
ss << " int32_t " << id() << "_len;" << std::endl;
ss << " char* " << id() << ";" << std::endl;
return ss.str();
}
std::string
CItemString::GenerateInitCodeBlock(std::string message_id) const
{
return " message->" + id() + " = NULL;";
std::stringstream ss;
ss << " message->" << id() << "_len = 0;" << std::endl;
ss << " message->" << id() << " = NULL;" << std::endl;
return ss.str();
}
std::string
@ -29,14 +35,16 @@ CItemString::GenerateDestroyCodeBlock(std::string message_id) const
ss << " message->" << id() << " = NULL;" << std::endl;
ss << " }" << std::endl;
return ss.str();
return ss.str();
}
std::string
CItemString::GenerateSetterDeclaration(std::string message_id) const
{
std::stringstream ss;
ss << "void " << message_id << "_set_" << id() << "(" << message_id << "* message, const char* " << id() << ");";
ss << "void " << message_id << "_set_" << id() << "_string(" << message_id << "* message, const char* " << id() << ");";
ss << std::endl;
ss << "void " << message_id << "_set_" << id() << "_data(" << message_id << "* message, const char* " << id() << ", int32_t " << id() << "_len);";
ss << std::endl;
return ss.str();
}
@ -44,13 +52,27 @@ std::string
CItemString::GenerateSetterDefinition(std::string message_id) const
{
std::stringstream ss;
ss << "void " << message_id << "_set_" << id() << "(" << message_id << "* message, const char* " << id() << ") {" << std::endl;
// set_xxx_data
ss << "void " << message_id << "_set_" << id() << "_data(" << message_id << "* message, const char* " << id() << ", int32_t " << id() << "_len) {" << std::endl;
ss << " char* new_" << id() << " = (char*)malloc(" << id() << "_len + 1);" << std::endl;
ss << " if (new_" << id() << " == NULL) { return; }" << std::endl;
ss << " memcpy(new_" << id() << ", " << id() << ", " << id() << "_len);" << std::endl;
ss << " new_" << id() << "[" << id() << "_len] = '\\0';" << std::endl;
ss << " if (message->" << id() << ") {" << std::endl;
ss << " free(message->" << id() << ");" << std::endl;
ss << " }" << std::endl;
ss << " message->" << id() << " = strdup(" << id() << ");" << std::endl;
ss << " message->" << id() << " = new_" << id() << ";" << std::endl;
ss << " message->" << id() << "_len = " << id() << "_len;" << std::endl;
ss << "}" << std::endl;
ss << std::endl;
// set_xxx_string
ss << "void " << message_id << "_set_" << id() << "_string(" << message_id << "* message, const char* " << id() << ") {" << std::endl;
ss << " int32_t " << id() << "_len = strlen(" << id() << ");" << std::endl;
ss << " " << message_id << "_set_" << id() << "_data(message, " << id() << ", " << id() << "_len);" << std::endl;
ss << "}" << std::endl;
ss << std::endl;
return ss.str();
}
@ -58,10 +80,10 @@ std::string
CItemString::GenerateGetterDefinition(std::string message_id) const
{
std::stringstream ss;
ss << "const char* " << message_id << "_get_" << id() << "(const " << message_id << "* message) {" << std::endl;
ss << "const char* " << message_id << "_get_" << id() << "_data(const " << message_id << "* message) {" << std::endl;
ss << " return message->" << id() << ";" << std::endl;
ss << "}" << std::endl;
ss << std::endl;
return ss.str();
}
@ -69,7 +91,9 @@ std::string
CItemString::GenerateGetterDeclaration(std::string message_id) const
{
std::stringstream ss;
ss << "const char* " << message_id << "_get_" << id() << "(const " << message_id << "* message);";
ss << "const char* " << message_id << "_get_" << id() << "_data(const " << message_id << "* message);";
ss << std::endl;
ss << "const char* " << message_id << "_get_" << id() << "_len(const " << message_id << "* message);";
return ss.str();
}

View File

@ -19,6 +19,7 @@ public:
virtual ~CRPC() = default;
virtual std::string GenerateStructDeclareCodeBlock(std::string service_id) const = 0;
virtual std::string GenerateStructAPIDeclareCodeBlock(std::string service_id) const = 0;
};
}// namespace tqcq

View File

@ -14,11 +14,17 @@ CRPCServer::Create(RPC::Ptr rpc)
CRPCServer::CRPCServer(RPC::Ptr rpc) : CRPC(rpc) {}
std::string
CRPCServer::GenerateStructAPIDeclareCodeBlock(std::string service_id) const
{
return std::string();
}
std::string
CRPCServer::GenerateStructDeclareCodeBlock(std::string service_id) const
{
std::stringstream ss;
ss << " void (*" << id() << ")(Service *service, " << request_id() << " *request, " << response_id() << " **response);\n";
ss << " int32_t (*" << id() << ")(" << request_id() << " *request, " << response_id() << " **response);\n";
return ss.str();
}

View File

@ -18,6 +18,7 @@ public:
~CRPCServer() override = default;
std::string GenerateStructDeclareCodeBlock(std::string service_id) const override;
std::string GenerateStructAPIDeclareCodeBlock(std::string service_id) const override;
};
}// namespace tqcq

View File

@ -3,12 +3,13 @@
//
#include "service_plugin.h"
#include <memory>
namespace tqcq {
ServicePlugin::ServicePlugin(std::string generate_path, std::string generate_prefix)
: Plugin(generate_path, generate_prefix)
: Plugin(std::move(generate_path), std::move(generate_prefix))
{}
void

View File

@ -13,11 +13,28 @@ message ApplicationPINRequest {
string admin_pin = 2;
string new_user_pin = 3;
string old = 4;
string new = 5;
string new_data = 5;
string pin = 6;
}
service Device {
message GenerateRandomRequest {
int32 length = 1;
}
message GenerateHashRequest {
int32 length = 1;
string data = 2;
}
message BaseResponse{
int32 code = 1;
string msg = 2;
int32 length = 3;
string data = 4;
}
service DeviceService {
rpc Init(Empty) returns (StatusResponse) {}
rpc Status(Empty) returns (StatusResponse) {}
rpc Close(Empty) returns (StatusResponse) {}
@ -26,4 +43,6 @@ service Device {
rpc UnlockApplicationPIN(ApplicationPINRequest) returns (StatusResponse) {}
rpc ChangeApplicationPIN(ApplicationPINRequest) returns (StatusResponse) {}
rpc VerifyApplicationPIN(ApplicationPINRequest) returns (StatusResponse) {}
rpc GenerateRandom(GenerateRandomRequest) returns (BaseResponse) {}
}