feature support server generate

This commit is contained in:
tqcq 2023-12-02 08:45:42 +08:00
parent 710ebd83e7
commit be8fb56962
30 changed files with 863 additions and 101 deletions

View File

@ -7,14 +7,20 @@ set(CMAKE_CXX_STANDARD 17)
FILE(GLOB_RECURSE SRC_LIST ${PROJECT_SOURCE_DIR}/src/*.cpp) FILE(GLOB_RECURSE SRC_LIST ${PROJECT_SOURCE_DIR}/src/*.cpp)
add_executable(crpc add_executable(crpc
${SRC_LIST}
main.cpp main.cpp
src/item.cpp src/item.cpp
src/message.cpp src/message.cpp
${SRC_LIST}
src/rpc.cpp src/rpc.cpp
src/service.cpp src/service.cpp
src/plugins/c/c_message_plugin.cpp src/plugins/c/c_message_plugin.cpp
src/plugins/c/generators/c_item.cpp src/plugins/c/items/c_item.cpp
src/plugins/service_plugin.cpp
src/plugins/plugin.cpp
src/plugins/c/c_service_server_plugin.cpp
src/plugins/c/rpcs/crpc_client.cpp
src/plugins/c/rpcs/crpc.cpp
src/plugins/c/c_service_plugin.cpp
) )
target_link_libraries(crpc PRIVATE antlr4_static) target_link_libraries(crpc PRIVATE antlr4_static)
target_include_directories(crpc PRIVATE /opt/dev/vcpkg/installed/arm64-osx/include/antlr4-runtime) target_include_directories(crpc PRIVATE /opt/dev/vcpkg/installed/arm64-osx/include/antlr4-runtime)

View File

@ -8,6 +8,8 @@
#include "message.h" #include "message.h"
#include "service.h" #include "service.h"
#include "plugins/c/c_message_plugin.h" #include "plugins/c/c_message_plugin.h"
#include "plugins/c/c_service_server_plugin.h"
#include "plugins/c/c_service_client_plugin.h"
#include <stack> #include <stack>
#include <map> #include <map>
#include <unistd.h> #include <unistd.h>
@ -107,5 +109,9 @@ main(int argc, char *argv[])
tqcq::CMessagePlugin message_plugin("./gen/"); tqcq::CMessagePlugin message_plugin("./gen/");
message_plugin.Generate(listener.message_map); message_plugin.Generate(listener.message_map);
tqcq::CServiceServerPlugin service_server_plugin("./gen/");
service_server_plugin.Generate(listener.services);
// tqcq::CServiceClientPlugin service_client_plugin("./gen/");
return 0; return 0;
} }

View File

@ -5,9 +5,9 @@ options{ tokenVocab='gen/ProtoLexer'; language=Cpp; }
program: syntaxStatement baseStatement* EOF; program: syntaxStatement baseStatement* EOF;
syntaxStatement: SYNTAX_TYPE '=' '"' (VERSION2 | VERSION3) '"' ';'; syntaxStatement: SYNTAX_TYPE '=' '"' (VERSION2 | VERSION3) '"' ';';
baseStatement: (messageStatement | serviceStatement | ';'); baseStatement: messageStatement | serviceStatement | ';';
messageStatement: MESSAGE_TYPE ID '{' itemStatement* '}' ';'; messageStatement: MESSAGE_TYPE ID '{' (itemStatement | ';')* '}';
serviceStatement: SERVICE_TYPE ID '{' rpcStatement* '}' ';'; serviceStatement: SERVICE_TYPE ID '{' (rpcStatement | ';')* '}';
itemStatement: (INT32 | STRING) ID '=' NUMBER ';'; itemStatement: (INT32 | STRING) ID '=' NUMBER ';';
rpcStatement: RPC_TYPE ID '(' ID ')' 'returns' '(' ID ')' ';'; rpcStatement: RPC_TYPE ID '(' ID ')' 'returns' '(' ID ')' '{' '}';

View File

@ -6,7 +6,7 @@
#include <sstream> #include <sstream>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include "generators/c_item.h" #include "items/c_item.h"
namespace tqcq { namespace tqcq {
@ -15,7 +15,9 @@ GenerateGuardMacro(std::string id, std::string prefix)
{ {
std::stringstream ss; std::stringstream ss;
ss << prefix << "_" << id << "_H_"; ss << prefix << "_" << id << "_H_";
return ss.str(); auto str = ss.str();
std::for_each(str.begin(), str.end(), [](char &c) { c = std::toupper(c); });
return str;
} }
std::string std::string
@ -39,38 +41,29 @@ CMessagePlugin::CMessagePlugin(std::string generate_path, std::string generate_p
{} {}
void void
CMessagePlugin::GenerateHeader(std::map<std::string, tqcq::Message::Ptr> message_map) CMessagePlugin::GenerateHeader(tqcq::Message::Ptr message)
{ {
for (auto &message : message_map) { std::stringstream ss;
if (!message.second) { ss << GenerateIncludeGuardStart(message);
std::cout << "message " << message.first << " is null" << std::endl; ss << GenerateIncludeFile(message);
continue; ss << GenerateStructStart(message);
} ss << GenerateStructItem(message);
ss << GenerateStructEnd(message);
std::stringstream ss; ss << GenerateFunctionDeclaration(message);
ss << GenerateIncludeGuardStart(message.second); ss << GenerateIncludeGuardEnd(message);
ss << GenerateIncludeFile(message.second); std::ofstream ofs(generate_path() + "/" + GenerateHeaderFileName(message->id()));
ss << GenerateStructStart(message.second); ofs << ss.str();
ss << GenerateStructItem(message.second); std::cout << ss.str() << std::endl;
ss << GenerateStructEnd(message.second);
ss << GenerateFunctionDeclaration(message.second);
ss << GenerateIncludeGuardEnd(message.second);
std::ofstream ofs(generate_path() + "/" + GenerateHeaderFileName(message.second->id()));
ofs << ss.str();
std::cout << ss.str() << std::endl;
}
} }
void void
CMessagePlugin::GenerateSource(std::map<std::string, tqcq::Message::Ptr> message_map) CMessagePlugin::GenerateSource(tqcq::Message::Ptr message)
{ {
for (auto &message : message_map) { std::stringstream ss;
std::stringstream ss; ss << GenerateSourceIncludeFile(message);
ss << GenerateSourceIncludeFile(message.second); ss << GenerateFunctionDefinition(message);
ss << GenerateFunctionDefinition(message.second); std::ofstream ofs(generate_path() + "/" + GenerateSourceFileName(message->id()));
std::ofstream ofs(generate_path() + "/" + GenerateSourceFileName(message.second->id())); ofs << ss.str();
ofs << ss.str();
}
} }
std::string std::string
@ -82,10 +75,6 @@ CMessagePlugin::GenerateIncludeGuardStart(Message::Ptr message)
ss << "#define " << guard_macro << std::endl; ss << "#define " << guard_macro << std::endl;
ss << std::endl; ss << std::endl;
ss << "#ifdef __cplusplus" << std::endl;
ss << "extern \"C\" {" << std::endl;
ss << "#endif" << std::endl;
ss << std::endl;
return ss.str(); return ss.str();
} }
@ -106,6 +95,12 @@ CMessagePlugin::GenerateIncludeFile(Message::Ptr message)
std::stringstream ss; std::stringstream ss;
ss << "#include <stdint.h>" << std::endl; ss << "#include <stdint.h>" << std::endl;
ss << std::endl; ss << std::endl;
ss << "#ifdef __cplusplus" << std::endl;
ss << "extern \"C\" {" << std::endl;
ss << "#endif" << std::endl;
ss << std::endl;
return ss.str(); return ss.str();
} }
@ -180,7 +175,6 @@ CMessagePlugin::GenerateFunctionDefinition(Message::Ptr message)
} }
ss << std::endl; ss << std::endl;
return ss.str(); return ss.str();
} }
@ -194,6 +188,7 @@ CMessagePlugin::GenerateSourceIncludeFile(Message::Ptr message)
ss << std::endl; ss << std::endl;
return ss.str(); return ss.str();
} }
std::string std::string
CMessagePlugin::GenerateFunctionDefinitionSerialize(Message::Ptr message) CMessagePlugin::GenerateFunctionDefinitionSerialize(Message::Ptr message)
{ {

View File

@ -12,10 +12,10 @@ namespace tqcq {
class CMessagePlugin : public MessagePlugin { class CMessagePlugin : public MessagePlugin {
public: public:
static std::string GenerateHeaderFileName(std::string message_id); static std::string GenerateHeaderFileName(std::string message_id);
CMessagePlugin(std::string generate_path, std::string generate_prefix="CRPC"); CMessagePlugin(std::string generate_path, std::string generate_prefix="CMessage");
~CMessagePlugin() override = default; ~CMessagePlugin() override = default;
void GenerateHeader(std::map<std::string, Message::Ptr> message_map) override; void GenerateHeader(Message::Ptr message_map) override;
void GenerateSource(std::map<std::string, Message::Ptr> message_map) override; void GenerateSource(Message::Ptr message_map) override;
private: private:
std::string GenerateIncludeGuardStart(Message::Ptr message); std::string GenerateIncludeGuardStart(Message::Ptr message);
@ -29,18 +29,12 @@ private:
std::string GenerateFunctionDeclaration(Message::Ptr message); std::string GenerateFunctionDeclaration(Message::Ptr message);
std::string GenerateFunctionDefinition(Message::Ptr message); std::string GenerateFunctionDefinition(Message::Ptr message);
std::string GenerateFunctionDefinitionGetter(Message::Ptr message, Item::Ptr item);
std::string GenerateFunctionDefinitionSetter(Message::Ptr message, Item::Ptr item);
std::string GenerateFunctionDefinitionSerialize(Message::Ptr message); std::string GenerateFunctionDefinitionSerialize(Message::Ptr message);
std::string GenerateFunctionDefinitionDeserialize(Message::Ptr message); std::string GenerateFunctionDefinitionDeserialize(Message::Ptr message);
std::string GenerateFunctionDefinitionInit(Message::Ptr message); std::string GenerateFunctionDefinitionInit(Message::Ptr message);
std::string GenerateFunctionDefinitionDestroy(Message::Ptr message); std::string GenerateFunctionDefinitionDestroy(Message::Ptr message);
std::string GenerateSourceIncludeFile(Message::Ptr message); std::string GenerateSourceIncludeFile(Message::Ptr message);
std::string TranslateTypeToCType(Message::Ptr message, Item::Type type);
std::string TranslateTypeToRealType(Message::Ptr message, Item::Type type);
}; };
}// namespace tqcq }// namespace tqcq

View File

@ -0,0 +1,13 @@
//
// Created by tqcq on 2023/12/2.
//
#include "c_service_client_plugin.h"
#include <utility>
namespace tqcq {
CServiceClientPlugin::CServiceClientPlugin(std::string generate_path, std::string generate_prefix)
: CServicePlugin(std::move(generate_path), std::move(generate_prefix))
{}
}// namespace tqcq

View File

@ -0,0 +1,21 @@
//
// Created by tqcq on 2023/12/2.
//
#ifndef CRPC_SRC_PLUGINS_C_C_SERVICE_CLIENT_PLUGIN_H_
#define CRPC_SRC_PLUGINS_C_C_SERVICE_CLIENT_PLUGIN_H_
#include "c_service_plugin.h"
namespace tqcq {
class CServiceClientPlugin : public CServicePlugin {
public:
CServiceClientPlugin(std::string generate_path, std::string generate_prefix = "CService");
virtual ~CServiceClientPlugin() = default;
protected:
};
}// namespace tqcq
#endif//CRPC_SRC_PLUGINS_C_C_SERVICE_CLIENT_PLUGIN_H_

View File

@ -0,0 +1,60 @@
//
// Created by tqcq on 2023/12/2.
//
#include "c_service_plugin.h"
#include <sstream>
#include <fstream>
namespace tqcq {
std::string
GenerateHeaderFileName(std::string id)
{
std::stringstream ss;
ss << id << ".h";
return ss.str();
}
std::string
CServicePlugin::GenerateGuardMacro(std::string id, std::string prefix)
{
std::stringstream ss;
ss << prefix << "_" << id << "_H_";
auto str = ss.str();
std::for_each(str.begin(), str.end(), [](char &c) { c = std::toupper(c); });
return str;
}
CServicePlugin::CServicePlugin(std::string generate_path, std::string generate_prefix)
: ServicePlugin(generate_path, generate_prefix)
{
}
void
CServicePlugin::GenerateHeader(Service::Ptr service)
{
std::stringstream ss;
ss << GenerateHeaderGuardStart(service);
ss << GenerateHeaderIncludeFiles(service);
ss << std::endl;
ss << GenerateHeaderStructStart(service);
ss << GenerateHeaderStructItems(service);
ss << GenerateHeaderStructEnd(service);
ss << std::endl;
ss << GenerateHeaderFunctionDeclaration(service);
ss << std::endl;
ss << GenerateHeaderGuardEnd(service);
std::ofstream ofs(generate_path() + "/" + GenerateHeaderFileName(service->id()));
ofs << ss.str();
}
void
CServicePlugin::GenerateSource(Service::Ptr service)
{
}
}// namespace tqcq

View File

@ -0,0 +1,35 @@
//
// Created by tqcq on 2023/12/2.
//
#ifndef CRPC_SRC_PLUGINS_C_C_SERVICE_PLUGIN_H_
#define CRPC_SRC_PLUGINS_C_C_SERVICE_PLUGIN_H_
#include "plugins/service_plugin.h"
namespace tqcq {
class CServicePlugin : public ServicePlugin {
public:
using Ptr = std::shared_ptr<CServicePlugin>;
static std::string GenerateGuardMacro(std::string id, std::string prefix);
CServicePlugin(std::string generate_path, std::string generate_prefix = "CService");
virtual ~CServicePlugin() = default;
protected:
virtual void GenerateHeader(Service::Ptr service) override;
virtual void GenerateSource(Service::Ptr service) override;
virtual std::string GenerateHeaderGuardStart(Service::Ptr service) = 0;
virtual std::string GenerateHeaderIncludeFiles(Service::Ptr service) = 0;
virtual std::string GenerateHeaderGuardEnd(Service::Ptr service) = 0;
virtual std::string GenerateHeaderStructStart(Service::Ptr service) = 0;
virtual std::string GenerateHeaderStructItems(Service::Ptr service) = 0;
virtual std::string GenerateHeaderStructEnd(Service::Ptr service) = 0;
virtual std::string GenerateHeaderFunctionDeclaration(Service::Ptr service) = 0;
};
}// namespace tqcq
#endif//CRPC_SRC_PLUGINS_C_C_SERVICE_PLUGIN_H_

View File

@ -0,0 +1,96 @@
//
// Created by tqcq on 2023/12/2.
//
#include "c_service_server_plugin.h"
#include <sstream>
#include "rpcs/crpc_server.h"
namespace tqcq {
CServiceServerPlugin::CServiceServerPlugin(std::string generate_path, std::string generate_prefix)
: CServicePlugin(generate_path, generate_prefix)
{}
std::string
CServiceServerPlugin::GenerateHeaderGuardStart(Service::Ptr service)
{
std::stringstream ss;
auto guard_macro = GenerateGuardMacro(service->id(), generate_prefix());
ss << "#ifndef " << guard_macro << std::endl;
ss << "#define " << guard_macro << std::endl;
return ss.str();
}
std::string
CServiceServerPlugin::GenerateHeaderIncludeFiles(Service::Ptr service)
{
std::stringstream ss;
ss << "#include <stdint.h>" << std::endl;
ss << "#include <string.h>" << std::endl;
ss << "#include <stdlib.h>" << std::endl;
ss << "#include <crpc/service.h>" << std::endl;
std::set<std::string> message_set;
for (const auto& rpc : service->rpcs()) {
auto crpc = CRPCServer::Create(rpc);
message_set.insert(crpc->request_id());
message_set.insert(crpc->response_id());
}
for (const auto& message_id : message_set) {
ss << "#include \"" << message_id << ".h\"" << std::endl;
}
ss << std::endl;
ss << "#ifdef __cplusplus" << std::endl;
ss << "extern \"C\" {" << std::endl;
ss << "#endif" << std::endl;
return ss.str();
}
std::string
CServiceServerPlugin::GenerateHeaderGuardEnd(Service::Ptr service)
{
std::stringstream ss;
auto guard_macro = GenerateGuardMacro(service->id(), generate_prefix());
ss << "#ifdef __cplusplus" << std::endl;
ss << "}" << std::endl;
ss << "#endif" << std::endl;
ss << "#endif // " << guard_macro << std::endl;
return ss.str();
}
std::string
CServiceServerPlugin::GenerateHeaderStructStart(Service::Ptr service)
{
std::stringstream ss;
ss << "typedef struct " << "{" << std::endl;
return ss.str();
}
std::string
CServiceServerPlugin::GenerateHeaderStructItems(Service::Ptr service)
{
std::stringstream ss;
for (const auto& rpc : service->rpcs()) {
auto crpc = CRPCServer::Create(rpc);
ss << crpc->GenerateStructDeclareCodeBlock(service->id());
}
return ss.str();
}
std::string
CServiceServerPlugin::GenerateHeaderStructEnd(Service::Ptr service)
{
std::stringstream ss;
ss << "} " << service->id() << ";" << std::endl;
return ss.str();
}
std::string
CServiceServerPlugin::GenerateHeaderFunctionDeclaration(Service::Ptr service)
{
return std::string();
}
}// namespace tqcq

View File

@ -0,0 +1,28 @@
//
// Created by tqcq on 2023/12/2.
//
#ifndef CService_SRC_PLUGINS_C_ITEMS_C_SERVICE_SERVER_PLUGIN_H_
#define CService_SRC_PLUGINS_C_ITEMS_C_SERVICE_SERVER_PLUGIN_H_
#include "c_service_plugin.h"
namespace tqcq {
class CServiceServerPlugin : public CServicePlugin {
public:
CServiceServerPlugin(std::string generate_path, std::string generate_prefix = "CService");
virtual ~CServiceServerPlugin() = default;
protected:
std::string GenerateHeaderGuardStart(Service::Ptr service) override;
std::string GenerateHeaderIncludeFiles(Service::Ptr service) override;
std::string GenerateHeaderGuardEnd(Service::Ptr service) override;
std::string GenerateHeaderStructStart(Service::Ptr service) override;
std::string GenerateHeaderStructItems(Service::Ptr service) override;
std::string GenerateHeaderStructEnd(Service::Ptr service) override;
std::string GenerateHeaderFunctionDeclaration(Service::Ptr service) override;
};
}// namespace tqcq
#endif//CService_SRC_PLUGINS_C_ITEMS_C_SERVICE_SERVER_PLUGIN_H_

View File

@ -0,0 +1,24 @@
//
// Created by tqcq on 2023/12/2.
//
#include "c_item.h"
#include "assert.h"
#include "c_item_int_32.h"
#include "c_item_string.h"
namespace tqcq {
CItem::Ptr
CItem::Create(Item::Ptr item)
{
assert(item);
switch (item->type()) {
case Item::Type::kInt32:
return std::make_shared<CItemInt32>(item);
case Item::Type::kString:
return std::make_shared<CItemString>(item);
default:
assert(false);
}
}
}// namespace tqcq

View File

@ -0,0 +1,39 @@
//
// Created by tqcq on 2023/12/2.
//
#ifndef CRPC_SRC_PLUGINS_C_GENERATORS_C_ITEM_H_
#define CRPC_SRC_PLUGINS_C_GENERATORS_C_ITEM_H_
#include <string>
#include <memory>
#include "item.h"
namespace tqcq {
class CItem : public Item {
public:
using Ptr = std::shared_ptr<CItem>;
static Ptr Create(Item::Ptr item);
CItem() = delete;
CItem(Item::Ptr item) : Item(item->type(), item->id(), item->idx()) {};
~CItem() override = default;
virtual std::string GenerateStructDeclareCodeBlock(std::string message_id) const = 0;
virtual std::string GenerateInitCodeBlock(std::string message_id) const = 0;
virtual std::string GenerateDestroyCodeBlock(std::string message_id) const = 0;
virtual std::string GenerateSetterDeclaration(std::string message_id) const = 0;
virtual std::string GenerateSetterDefinition(std::string message_id) const = 0;
virtual std::string GenerateGetterDefinition(std::string message_id) const = 0;
virtual std::string GenerateGetterDeclaration(std::string message_id) const = 0;
virtual std::string GenerateSerializeCodeBlock(std::string message_id) const = 0;
virtual std::string GenerateDeserializeCodeBlock(std::string message_id) const = 0;
};
}// namespace tqcq
#endif//CRPC_SRC_PLUGINS_C_GENERATORS_C_ITEM_H_

View File

@ -0,0 +1,78 @@
//
// Created by tqcq on 2023/12/2.
//
#include "c_item_int_32.h"
#include <sstream>
namespace tqcq {
CItemInt32::CItemInt32(Item::Ptr item) : CItem(item) {}
std::string
CItemInt32::GenerateStructDeclareCodeBlock(std::string message_id) const
{
return " int32_t " + id() + ";";
}
std::string
CItemInt32::GenerateInitCodeBlock(std::string message_id) const
{
std::stringstream ss;
ss << " " << "message->" << id() << " = 0;";
return ss.str();
}
std::string
CItemInt32::GenerateDestroyCodeBlock(std::string message_id) const
{
return " // do nothing for " + id() + " destroy";
}
std::string
CItemInt32::GenerateSetterDeclaration(std::string message_id) const
{
return "void " + message_id + "_set_" + id() + "(" + message_id + "* message, int32_t " + id() + ");";
}
std::string
CItemInt32::GenerateSetterDefinition(std::string message_id) const
{
std::stringstream ss;
ss << "void " << message_id << "_set_" << id() << "(" << message_id << "* message, int32_t " << id() << ") {" << std::endl;
ss << " message->" << id() << " = " << id() << ";" << std::endl;
ss << "}" << std::endl;
ss << std::endl;
return ss.str();
}
std::string
CItemInt32::GenerateGetterDefinition(std::string message_id) const
{
std::stringstream ss;
ss << "int32_t " << message_id << "_get_" << id() << "(const " << message_id << "* message) {" << std::endl;
ss << " return message->" << id() << ";" << std::endl;
ss << "}" << std::endl;
ss << std::endl;
return ss.str();
}
std::string
CItemInt32::GenerateGetterDeclaration(std::string message_id) const
{
std::stringstream ss;
ss << "int32_t " << message_id << "_get_" << id() << "(const " << message_id << "* message);";
return ss.str();
}
std::string
CItemInt32::GenerateSerializeCodeBlock(std::string message_id) const
{
return " // implement me for " + message_id + "_" + id() + " serialize";
}
std::string
CItemInt32::GenerateDeserializeCodeBlock(std::string message_id) const
{
return " // implement me for " + id() + " deserialize";
}
}// namespace tqcq

View File

@ -0,0 +1,35 @@
//
// Created by tqcq on 2023/12/2.
//
#ifndef CRPC_SRC_PLUGINS_C_GENERATORS_C_ITEM_INT_32_H_
#define CRPC_SRC_PLUGINS_C_GENERATORS_C_ITEM_INT_32_H_
#include "c_item.h"
namespace tqcq {
class CItemInt32 : public CItem {
public:
using Ptr = std::shared_ptr<CItemInt32>;
CItemInt32(Item::Ptr item);
~CItemInt32() override = default;
std::string GenerateStructDeclareCodeBlock(std::string message_id) const override;
std::string GenerateInitCodeBlock(std::string message_id) const override;
std::string GenerateDestroyCodeBlock(std::string message_id) const override;
std::string GenerateSetterDeclaration(std::string message_id) const override;
std::string GenerateSetterDefinition(std::string message_id) const override;
std::string GenerateGetterDefinition(std::string message_id) const override;
std::string GenerateGetterDeclaration(std::string message_id) const override;
std::string GenerateSerializeCodeBlock(std::string message_id) const override;
std::string GenerateDeserializeCodeBlock(std::string message_id) const override;
};
}// namespace tqcq
#endif//CRPC_SRC_PLUGINS_C_GENERATORS_C_ITEM_INT_32_H_

View File

@ -0,0 +1,87 @@
//
// Created by tqcq on 2023/12/2.
//
#include "c_item_string.h"
#include <sstream>
namespace tqcq {
CItemString::CItemString(Item::Ptr item) : CItem(item) {}
std::string
CItemString::GenerateStructDeclareCodeBlock(std::string message_id) const
{
return " char* " + id() + ";";
}
std::string
CItemString::GenerateInitCodeBlock(std::string message_id) const
{
return " message->" + id() + " = NULL;";
}
std::string
CItemString::GenerateDestroyCodeBlock(std::string message_id) const
{
std::stringstream ss;
ss << " if (message->" << id() << ") {" << std::endl;
ss << " free(message->" << id() << ");" << std::endl;
ss << " message->" << id() << " = NULL;" << std::endl;
ss << " }" << std::endl;
return ss.str();
return ss.str();
}
std::string
CItemString::GenerateSetterDeclaration(std::string message_id) const
{
std::stringstream ss;
ss << "void " << message_id << "_set_" << id() << "(" << message_id << "* message, const char* " << id() << ");";
return ss.str();
}
std::string
CItemString::GenerateSetterDefinition(std::string message_id) const
{
std::stringstream ss;
ss << "void " << message_id << "_set_" << id() << "(" << message_id << "* message, const char* " << id() << ") {" << std::endl;
ss << " if (message->" << id() << ") {" << std::endl;
ss << " free(message->" << id() << ");" << std::endl;
ss << " }" << std::endl;
ss << " message->" << id() << " = strdup(" << id() << ");" << std::endl;
ss << "}" << std::endl;
ss << std::endl;
return ss.str();
}
std::string
CItemString::GenerateGetterDefinition(std::string message_id) const
{
std::stringstream ss;
ss << "const char* " << message_id << "_get_" << id() << "(const " << message_id << "* message) {" << std::endl;
ss << " return message->" << id() << ";" << std::endl;
ss << "}" << std::endl;
ss << std::endl;
return ss.str();
}
std::string
CItemString::GenerateGetterDeclaration(std::string message_id) const
{
std::stringstream ss;
ss << "const char* " << message_id << "_get_" << id() << "(const " << message_id << "* message);";
return ss.str();
}
std::string
CItemString::GenerateSerializeCodeBlock(std::string message_id) const
{
return " // not implemented yet for " + id() + " serialize";
}
std::string
CItemString::GenerateDeserializeCodeBlock(std::string message_id) const
{
return " // not implemented yet for " + id() + " deserialize";
}
}// namespace tqcq

View File

@ -0,0 +1,35 @@
//
// Created by tqcq on 2023/12/2.
//
#ifndef CRPC_SRC_PLUGINS_C_GENERATORS_C_ITEM_STRING_H_
#define CRPC_SRC_PLUGINS_C_GENERATORS_C_ITEM_STRING_H_
#include "c_item.h"
namespace tqcq {
class CItemString : public CItem {
public:
using Ptr = std::shared_ptr<CItemString>;
CItemString(Item::Ptr item);
~CItemString() override = default;
std::string GenerateStructDeclareCodeBlock(std::string message_id) const override;
std::string GenerateInitCodeBlock(std::string message_id) const override;
std::string GenerateDestroyCodeBlock(std::string message_id) const override;
std::string GenerateSetterDeclaration(std::string message_id) const override;
std::string GenerateSetterDefinition(std::string message_id) const override;
std::string GenerateGetterDefinition(std::string message_id) const override;
std::string GenerateGetterDeclaration(std::string message_id) const override;
std::string GenerateSerializeCodeBlock(std::string message_id) const override;
std::string GenerateDeserializeCodeBlock(std::string message_id) const override;
};
}// namespace tqcq
#endif//CRPC_SRC_PLUGINS_C_GENERATORS_C_ITEM_STRING_H_

View File

@ -0,0 +1,9 @@
//
// Created by tqcq on 2023/12/2.
//
#include "crpc.h"
namespace tqcq {
CRPC::CRPC(RPC::Ptr rpc) : RPC(rpc->id(), rpc->request_id(), rpc->response_id()) {}
}// namespace tqcq

26
src/plugins/c/rpcs/crpc.h Normal file
View File

@ -0,0 +1,26 @@
//
// Created by tqcq on 2023/12/2.
//
#ifndef CRPC_SRC_PLUGINS_C_RPCS_CRPC_H_
#define CRPC_SRC_PLUGINS_C_RPCS_CRPC_H_
#include <vector>
#include <map>
#include <string>
#include <sstream>
#include "rpc.h"
namespace tqcq {
class CRPC : public RPC {
public:
CRPC(RPC::Ptr rpc);
virtual ~CRPC() = default;
virtual std::string GenerateStructDeclareCodeBlock(std::string service_id) const = 0;
};
}// namespace tqcq
#endif//CRPC_SRC_PLUGINS_C_RPCS_CRPC_H_

View File

@ -0,0 +1,7 @@
//
// Created by tqcq on 2023/12/2.
//
#include "crpc_client.h"
namespace tqcq {}// namespace tqcq

View File

@ -0,0 +1,17 @@
//
// Created by tqcq on 2023/12/2.
//
#ifndef CRPC_SRC_PLUGINS_C_RPCS_CRPC_CLIENT_H_
#define CRPC_SRC_PLUGINS_C_RPCS_CRPC_CLIENT_H_
#include "crpc.h"
namespace tqcq {
class CRPCClient : public CRPC {
};
}// namespace tqcq
#endif//CRPC_SRC_PLUGINS_C_RPCS_CRPC_CLIENT_H_

View File

@ -0,0 +1,25 @@
//
// Created by tqcq on 2023/12/2.
//
#include "crpc_server.h"
#include <sstream>
namespace tqcq {
CRPCServer::Ptr
CRPCServer::Create(RPC::Ptr rpc)
{
return std::make_shared<CRPCServer>(rpc);
}
CRPCServer::CRPCServer(RPC::Ptr rpc) : CRPC(rpc) {}
std::string
CRPCServer::GenerateStructDeclareCodeBlock(std::string service_id) const
{
std::stringstream ss;
ss << " void (*" << id() << ")(Service *service, " << request_id() << " *request, " << response_id() << " **response);\n";
return ss.str();
}
}// namespace tqcq

View File

@ -0,0 +1,25 @@
//
// Created by tqcq on 2023/12/2.
//
#ifndef CRPC_SRC_PLUGINS_C_RPCS_CRPC_SERVER_H_
#define CRPC_SRC_PLUGINS_C_RPCS_CRPC_SERVER_H_
#include "crpc.h"
namespace tqcq {
class CRPCServer : public CRPC {
public:
using Ptr = std::shared_ptr<CRPCServer>;
static Ptr Create(RPC::Ptr rpc);
CRPCServer(RPC::Ptr rpc);
~CRPCServer() override = default;
std::string GenerateStructDeclareCodeBlock(std::string service_id) const override;
};
}// namespace tqcq
#endif//CRPC_SRC_PLUGINS_C_RPCS_CRPC_SERVER_H_

View File

@ -9,46 +9,19 @@
namespace tqcq { namespace tqcq {
static void EnsureDirectoryExist(std::string path)
{
std::string::size_type pos = 0;
while (true) {
pos = path.find('/', pos);
if (pos == std::string::npos) {
break;
}
std::string dir = path.substr(0, pos);
int status = mkdir(dir.c_str(), 0755);
if (status != 0 && errno != EEXIST) {
perror("mkdir");
exit(1);
}
pos++;
}
}
MessagePlugin::MessagePlugin(std::string generate_path, std::string generate_prefix) MessagePlugin::MessagePlugin(std::string generate_path, std::string generate_prefix)
: generate_path_(std::move(generate_path)), generate_prefix_(std::move(generate_prefix)) : Plugin(std::move(generate_path), std::move(generate_prefix))
{ {
EnsureDirectoryExist(generate_path_);
} }
void void
MessagePlugin::Generate(std::map<std::string, Message::Ptr> message_map) MessagePlugin::Generate(std::map<std::string, Message::Ptr> message_map)
{ {
GenerateHeader(message_map); for (auto &pair : message_map) {
GenerateSource(message_map); GenerateHeader(pair.second);
GenerateSource(pair.second);
}
} }
std::string
MessagePlugin::generate_path() const
{
return generate_path_;
}
std::string
MessagePlugin::generate_prefix() const
{
return generate_prefix_;
}
}// namespace tqcq }// namespace tqcq

View File

@ -8,22 +8,18 @@
#include <string> #include <string>
#include <map> #include <map>
#include "message.h" #include "message.h"
#include "plugin.h"
namespace tqcq { namespace tqcq {
class MessagePlugin { class MessagePlugin : public Plugin {
public: public:
MessagePlugin(std::string generate_path, std::string generate_prefix="CRPC"); MessagePlugin(std::string generate_path, std::string generate_prefix="CRPC");
virtual ~MessagePlugin() = default; virtual ~MessagePlugin() = default;
virtual void Generate(std::map<std::string, Message::Ptr> message_map); virtual void Generate(std::map<std::string, Message::Ptr> message_map);
std::string generate_path() const;
std::string generate_prefix() const;
protected: protected:
virtual void GenerateHeader(std::map<std::string, Message::Ptr> message_map) {}; virtual void GenerateHeader(Message::Ptr message) {};
virtual void GenerateSource(std::map<std::string, Message::Ptr> message_map) {}; virtual void GenerateSource(Message::Ptr message) {};
private:
std::string generate_path_;
std::string generate_prefix_;
}; };
}// namespace tqcq }// namespace tqcq

45
src/plugins/plugin.cpp Normal file
View File

@ -0,0 +1,45 @@
//
// Created by tqcq on 2023/12/2.
//
#include "plugin.h"
#include <sys/stat.h>
namespace tqcq {
static void EnsureDirectoryExist(std::string path)
{
std::string::size_type pos = 0;
while (true) {
pos = path.find('/', pos);
if (pos == std::string::npos) {
break;
}
std::string dir = path.substr(0, pos);
int status = mkdir(dir.c_str(), 0755);
if (status != 0 && errno != EEXIST) {
perror("mkdir");
exit(1);
}
pos++;
}
}
Plugin::Plugin(std::string generate_path, std::string generate_prefix)
: generate_path_(std::move(generate_path)), generate_prefix_(std::move(generate_prefix))
{
EnsureDirectoryExist(generate_path_);
}
std::string
Plugin::generate_path() const
{
return generate_path_;
}
std::string
Plugin::generate_prefix() const
{
return generate_prefix_;
}
}// namespace tqcq

25
src/plugins/plugin.h Normal file
View File

@ -0,0 +1,25 @@
//
// Created by tqcq on 2023/12/2.
//
#ifndef CRPC_SRC_PLUGINS_PLUGIN_H_
#define CRPC_SRC_PLUGINS_PLUGIN_H_
#include <string>
namespace tqcq {
class Plugin {
public:
Plugin(std::string generate_path, std::string generate_prefix="CRPC");
virtual ~Plugin() = default;
std::string generate_path() const;
std::string generate_prefix() const;
private:
std::string generate_path_;
std::string generate_prefix_;
};
}// namespace tqcq
#endif//CRPC_SRC_PLUGINS_PLUGIN_H_

View File

@ -0,0 +1,22 @@
//
// Created by tqcq on 2023/12/2.
//
#include "service_plugin.h"
namespace tqcq {
ServicePlugin::ServicePlugin(std::string generate_path, std::string generate_prefix)
: Plugin(generate_path, generate_prefix)
{}
void
ServicePlugin::Generate(std::vector<Service::Ptr> services)
{
for (auto &service : services) {
GenerateHeader(service);
GenerateSource(service);
}
}
}// namespace tqcq

View File

@ -0,0 +1,27 @@
//
// Created by tqcq on 2023/12/2.
//
#ifndef CService_SRC_PLUGINS_SERVICE_PLUGIN_H_
#define CService_SRC_PLUGINS_SERVICE_PLUGIN_H_
#include <vector>
#include <string>
#include "service.h"
#include "plugin.h"
namespace tqcq {
class ServicePlugin : public Plugin {
public:
ServicePlugin(std::string generate_path, std::string generate_prefix = "CService");
virtual ~ServicePlugin() = default;
virtual void Generate(std::vector<Service::Ptr> services);
protected:
virtual void GenerateHeader(Service::Ptr service){};
virtual void GenerateSource(Service::Ptr service){};
};
}// namespace tqcq
#endif//CService_SRC_PLUGINS_SERVICE_PLUGIN_H_

View File

@ -1,16 +1,29 @@
syntax = "proto3"; syntax = "proto3";
message TestMessage { message Empty {
int32 id = 1; }
string name = 2;
};
service TestService { message StatusResponse {
rpc TestMethod(TestMessage) returns (TestMessage); int32 code = 1;
}; string msg = 2;
}
message SearchRequest { message ApplicationPINRequest {
string query = 1; int32 retry_count = 1;
int32 page_number = 2; string admin_pin = 2;
int32 results_per_page = 3; string new_user_pin = 3;
}; string old = 4;
string new = 5;
string pin = 6;
}
service Device {
rpc Init(Empty) returns (StatusResponse) {}
rpc Status(Empty) returns (StatusResponse) {}
rpc Close(Empty) returns (StatusResponse) {}
rpc ClearApp(Empty) returns (Empty) {}
rpc UnlockApplicationPIN(ApplicationPINRequest) returns (StatusResponse) {}
rpc ChangeApplicationPIN(ApplicationPINRequest) returns (StatusResponse) {}
rpc VerifyApplicationPIN(ApplicationPINRequest) returns (StatusResponse) {}
}