feature support message base function

This commit is contained in:
tqcq 2023-12-02 01:56:16 +08:00
parent b1a44a46da
commit 710ebd83e7
6 changed files with 157 additions and 24 deletions

View File

@ -14,6 +14,7 @@ add_executable(crpc
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
) )
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

@ -10,6 +10,7 @@
#include "plugins/c/c_message_plugin.h" #include "plugins/c/c_message_plugin.h"
#include <stack> #include <stack>
#include <map> #include <map>
#include <unistd.h>
class Listener : public ProtoParserBaseListener { class Listener : public ProtoParserBaseListener {
public: public:
@ -73,6 +74,15 @@ public:
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
// show current working directory
char cwd[1024];
if (getcwd(cwd, sizeof(cwd)) != NULL) {
std::cout << "Current working dir: " << cwd << std::endl;
} else {
perror("getcwd() error");
return 1;
}
std::ifstream ifs; std::ifstream ifs;
ifs.open(argv[1]); ifs.open(argv[1]);
@ -94,7 +104,7 @@ main(int argc, char *argv[])
std::cout << service->ToString() << std::endl; std::cout << service->ToString() << std::endl;
} }
tqcq::CMessagePlugin message_plugin("/tmp/gen"); tqcq::CMessagePlugin message_plugin("./gen/");
message_plugin.Generate(listener.message_map); message_plugin.Generate(listener.message_map);
return 0; return 0;

View File

@ -13,6 +13,7 @@ namespace tqcq {
class Item { class Item {
public: public:
enum class Type { enum class Type {
kMessage,
kInt32, kInt32,
kString kString
}; };

View File

@ -6,24 +6,28 @@
#include <sstream> #include <sstream>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include "generators/c_item.h"
namespace tqcq { namespace tqcq {
static std::string GenerateGuardMacro(std::string id, std::string prefix) static std::string
GenerateGuardMacro(std::string id, std::string prefix)
{ {
std::stringstream ss; std::stringstream ss;
ss << prefix << "_" << id << "_H_"; ss << prefix << "_" << id << "_H_";
return ss.str(); return ss.str();
} }
static std::string GenerateHeaderFileName(std::string id) std::string
CMessagePlugin::GenerateHeaderFileName(std::string id)
{ {
std::stringstream ss; std::stringstream ss;
ss << id << ".h"; ss << id << ".h";
return ss.str(); return ss.str();
} }
std::string GenerateSourceFileName(std::string id) std::string
GenerateSourceFileName(std::string id)
{ {
std::stringstream ss; std::stringstream ss;
ss << id << ".c"; ss << id << ".c";
@ -77,6 +81,11 @@ CMessagePlugin::GenerateIncludeGuardStart(Message::Ptr message)
ss << "#ifndef " << guard_macro << std::endl; ss << "#ifndef " << guard_macro << std::endl;
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();
} }
@ -84,6 +93,9 @@ std::string
CMessagePlugin::GenerateIncludeGuardEnd(Message::Ptr message) CMessagePlugin::GenerateIncludeGuardEnd(Message::Ptr message)
{ {
std::stringstream ss; std::stringstream ss;
ss << "#ifdef __cplusplus" << std::endl;
ss << "}" << std::endl;
ss << "#endif" << std::endl;
ss << "#endif //" << GenerateGuardMacro(message->id(), generate_prefix()) << std::endl; ss << "#endif //" << GenerateGuardMacro(message->id(), generate_prefix()) << std::endl;
return ss.str(); return ss.str();
} }
@ -101,7 +113,8 @@ std::string
CMessagePlugin::GenerateStructStart(Message::Ptr message) CMessagePlugin::GenerateStructStart(Message::Ptr message)
{ {
std::stringstream ss; std::stringstream ss;
ss << "typedef struct " << " {" << std::endl; ss << "typedef struct "
<< " {" << std::endl;
return ss.str(); return ss.str();
} }
@ -110,8 +123,7 @@ CMessagePlugin::GenerateStructItem(Message::Ptr message)
{ {
std::stringstream ss; std::stringstream ss;
for (auto &item : message->items()) { for (auto &item : message->items()) {
auto type_name = TranslateTypeToCType(item->type()); ss << CItem::Create(item)->GenerateStructDeclareCodeBlock(message->id()) << std::endl;
ss << " " << type_name << " " << item->id() << ";" << std::endl;
} }
return ss.str(); return ss.str();
} }
@ -128,13 +140,48 @@ CMessagePlugin::GenerateStructEnd(Message::Ptr message)
std::string std::string
CMessagePlugin::GenerateFunctionDeclaration(Message::Ptr message) CMessagePlugin::GenerateFunctionDeclaration(Message::Ptr message)
{ {
return std::string(); std::stringstream ss;
ss << "void " << message->id() << "_Init(" << message->id() << "* message);" << std::endl;
ss << "void " << message->id() << "_Destroy(" << message->id() << "* message);" << std::endl;
ss << std::endl;
ss << "int32_t " << message->id() << "_Serialize(" << message->id()
<< "* message, char* buffer, int32_t buffer_size);" << std::endl;
ss << "int32_t " << message->id() << "_Deserialize(" << message->id()
<< "* message, char* buffer, int32_t buffer_size);" << std::endl;
ss << std::endl;
for (auto &item : message->items()) {
auto c_item = CItem::Create(item);
ss << c_item->GenerateSetterDeclaration(message->id()) << std::endl;
ss << c_item->GenerateGetterDeclaration(message->id()) << std::endl;
}
ss << std::endl;
return ss.str();
} }
std::string std::string
CMessagePlugin::GenerateFunctionDefinition(Message::Ptr message) CMessagePlugin::GenerateFunctionDefinition(Message::Ptr message)
{ {
return std::string(); std::stringstream ss;
ss << GenerateFunctionDefinitionInit(message);
ss << GenerateFunctionDefinitionDestroy(message);
ss << std::endl;
ss << GenerateFunctionDefinitionSerialize(message);
ss << GenerateFunctionDefinitionDeserialize(message);
ss << std::endl;
for (auto &item : message->items()) {
auto c_item = CItem::Create(item);
ss << c_item->GenerateSetterDefinition(message->id()) << std::endl;
ss << c_item->GenerateGetterDefinition(message->id()) << std::endl;
}
ss << std::endl;
return ss.str();
} }
std::string std::string
@ -142,29 +189,70 @@ CMessagePlugin::GenerateSourceIncludeFile(Message::Ptr message)
{ {
std::stringstream ss; std::stringstream ss;
ss << "#include \"" << GenerateHeaderFileName(message->id()) << "\"" << std::endl; ss << "#include \"" << GenerateHeaderFileName(message->id()) << "\"" << std::endl;
ss << "#include <string.h>" << std::endl;
ss << "#include <stdlib.h>" << std::endl;
ss << std::endl;
return ss.str();
}
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 offset = 0;" << std::endl;
for (auto &item : message->items()) {
auto c_item = CItem::Create(item);
ss << c_item->GenerateSerializeCodeBlock(message->id()) << std::endl;
}
ss << " return offset;" << std::endl;
ss << "}" << std::endl;
ss << std::endl; ss << std::endl;
return ss.str(); return ss.str();
} }
std::string std::string
CMessagePlugin::TranslateTypeToCType(Item::Type type) CMessagePlugin::GenerateFunctionDefinitionDeserialize(Message::Ptr message)
{ {
switch(type) { std::stringstream ss;
case Item::Type::kInt32: ss << "int32_t " << message->id() << "_Deserialize(" << message->id()
return "int32_t"; << "* message, char* buffer, int32_t buffer_size) {" << std::endl;
case Item::Type::kString: ss << " int32_t offset = 0;" << std::endl;
return "char*"; for (auto &item : message->items()) {
auto c_item = CItem::Create(item);
ss << c_item->GenerateDeserializeCodeBlock(message->id()) << std::endl;
} }
ss << " return offset;" << std::endl;
ss << "}" << std::endl;
ss << std::endl;
return ss.str();
} }
std::string std::string
CMessagePlugin::TranslateTypeToRealType(Item::Type type) CMessagePlugin::GenerateFunctionDefinitionInit(Message::Ptr message)
{ {
switch(type) { std::stringstream ss;
case Item::Type::kInt32: ss << "void " << message->id() << "_Init(" << message->id() << "* message) {" << std::endl;
return "int32_t"; for (auto &item : message->items()) {
case Item::Type::kString: auto c_item = CItem::Create(item);
return "char*"; ss << c_item->GenerateInitCodeBlock(message->id()) << std::endl;
} }
ss << "}" << std::endl;
ss << std::endl;
return ss.str();
}
std::string
CMessagePlugin::GenerateFunctionDefinitionDestroy(Message::Ptr message)
{
std::stringstream ss;
ss << "void " << message->id() << "_Destroy(" << message->id() << "* message) {" << std::endl;
for (auto &item : message->items()) {
auto c_item = CItem::Create(item);
ss << c_item->GenerateDestroyCodeBlock(message->id()) << std::endl;
}
ss << "}" << std::endl;
ss << std::endl;
return ss.str();
} }
}// namespace tqcq }// namespace tqcq

View File

@ -11,6 +11,7 @@ namespace tqcq {
class CMessagePlugin : public MessagePlugin { class CMessagePlugin : public MessagePlugin {
public: public:
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="CRPC");
~CMessagePlugin() override = default; ~CMessagePlugin() override = default;
void GenerateHeader(std::map<std::string, Message::Ptr> message_map) override; void GenerateHeader(std::map<std::string, Message::Ptr> message_map) override;
@ -28,10 +29,18 @@ 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 GenerateFunctionDefinitionDeserialize(Message::Ptr message);
std::string GenerateFunctionDefinitionInit(Message::Ptr message);
std::string GenerateFunctionDefinitionDestroy(Message::Ptr message);
std::string GenerateSourceIncludeFile(Message::Ptr message); std::string GenerateSourceIncludeFile(Message::Ptr message);
std::string TranslateTypeToCType(Item::Type type); std::string TranslateTypeToCType(Message::Ptr message, Item::Type type);
std::string TranslateTypeToRealType(Item::Type type); std::string TranslateTypeToRealType(Message::Ptr message, Item::Type type);
}; };
}// namespace tqcq }// namespace tqcq

View File

@ -3,11 +3,35 @@
// //
#include "message_plugin.h" #include "message_plugin.h"
#include <fstream>
#include <unistd.h>
#include <sys/stat.h>
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)) : generate_path_(std::move(generate_path)), generate_prefix_(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)