1 Star 0 Fork 0

genrwoody / genrwoody

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
fake-gcc.cpp 13.08 KB
一键复制 编辑 原始数据 按行查看 历史
genrwoody 提交于 2021-08-08 17:39 . add fake-gcc.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <windows.h>
#include "server.pb.h"
// 获取可执行程序的真实路径
const char *get_realpath()
{
char buff[MAX_PATH + 1] = { 0 };
DWORD size = GetModuleFileNameA(NULL, buff, MAX_PATH);
if (size == 0) return nullptr;
for (DWORD i = size; i > 0; --i) {
if (buff[i - 1] == '/' || buff[i - 1] == '\\') break;
buff[i - 1] = '\0';
}
return buff;
}
enum ServerType
{
HTTP = 0,
MAIL = 1
};
struct Session
{
std::string uuid;
uint64_t userid;
};
struct UserInfo
{
std::string key;
std::string name;
};
struct Server
{
int32_t iflag;
bool running;
std::vector<int32_t> address;
std::string hostname;
ServerType type;
struct InternalSession {
std::string key;
Session value;
};
std::vector<InternalSession> internal;
std::map<std::string, Session> sessions;
std::vector<UserInfo> users;
};
using google::protobuf::Message;
using google::protobuf::Descriptor;
using google::protobuf::FieldDescriptor;
// conflict with window message
#ifdef GetMessage
#undef GetMessage
#endif
static bool StructToProtoInternal(const uint8_t *&bytes, Message &msg);
static bool ProtoToStructInternal(uint8_t *&bytes, const Message &msg);
template<typename Ty>
inline int GetFieldSize(const FieldDescriptor &field)
{
return field.is_repeated() ? sizeof(std::vector<Ty>) : sizeof(Ty);
}
// 获取message所对应的结构体的size
static int GetMessageStructSize(const Descriptor *desc)
{
static_assert(
sizeof(std::vector<char>) == sizeof(std::vector<char[8]>),
"sizeof std::vector is variable, can not use this function.");
static_assert(
sizeof(std::map<char, char>) == sizeof(std::map<char[8], char[8]>),
"sizeof std::map is variable, can not use this function.");
int size = 0;
int count = desc->field_count();
for (int i = 0; i < count; ++i) {
auto field = desc->field(i);
switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32:
case FieldDescriptor::CPPTYPE_UINT32:
case FieldDescriptor::CPPTYPE_FLOAT:
size += GetFieldSize<int32_t>(*field);
break;
case FieldDescriptor::CPPTYPE_INT64:
case FieldDescriptor::CPPTYPE_UINT64:
case FieldDescriptor::CPPTYPE_DOUBLE:
size += GetFieldSize<int64_t>(*field);
break;
case FieldDescriptor::CPPTYPE_BOOL:
size += GetFieldSize<bool>(*field);
break;
case FieldDescriptor::CPPTYPE_ENUM:
size += GetFieldSize<int>(*field);
break;
case FieldDescriptor::CPPTYPE_STRING:
size += GetFieldSize<std::string>(*field);
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
{
if (field->is_map()) {
size += sizeof(std::map<int, int>);
} else if (field->is_repeated()) {
size += sizeof(std::vector<int>);
} else {
size += GetMessageStructSize(field->message_type());
}
break;
}
default:
return 0;
}
}
return size;
}
#define SetProtoValue(type, Type) \
do { if (field->is_repeated()) { \
auto &values = *(const std::vector<type>*)bytes; \
for (const type &value : values) { \
refl->Add ## Type(&msg, field, value); \
} \
bytes += sizeof(std::vector<type>); \
} else { \
refl->Set ## Type(&msg, field, *(const type*)bytes); \
bytes += sizeof(type); \
}} while(0)
static bool StructToProtoInternal(const uint8_t *&bytes, Message &msg)
{
auto refl = msg.GetReflection();
auto desc = msg.GetDescriptor();
for (int i = 0; i < desc->field_count(); ++i) {
auto field = desc->field(i);
switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32:
SetProtoValue(int32_t, Int32);
break;
case FieldDescriptor::CPPTYPE_INT64:
SetProtoValue(int64_t, Int64);
break;
case FieldDescriptor::CPPTYPE_UINT32:
SetProtoValue(uint32_t, UInt32);
break;
case FieldDescriptor::CPPTYPE_UINT64:
SetProtoValue(uint64_t, UInt64);
break;
case FieldDescriptor::CPPTYPE_DOUBLE:
SetProtoValue(double, Double);
break;
case FieldDescriptor::CPPTYPE_FLOAT:
SetProtoValue(float, Float);
break;
case FieldDescriptor::CPPTYPE_BOOL:
SetProtoValue(bool, Bool);
break;
case FieldDescriptor::CPPTYPE_ENUM:
SetProtoValue(int, EnumValue);
break;
case FieldDescriptor::CPPTYPE_STRING:
SetProtoValue(std::string, String);
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
{
int size = GetMessageStructSize(field->message_type());
if (field->is_map()) {
auto &values = *(std::map<std::string, uint8_t>*)bytes;
for (auto &pair : values) {
auto submsg = refl->AddMessage(&msg, field);
auto data = (const uint8_t *)&pair;
if (!StructToProtoInternal(data, *submsg)) return false;
}
bytes += sizeof(std::map<std::string, uint8_t>);
} else if (field->is_repeated()) {
auto &values = *(std::vector<uint8_t>*)bytes;
const uint8_t *data = values.data();
if (values.size() % size) return false;
int count = (int)values.size() / size;
for (int i = 0; i < count; ++i) {
auto submsg = refl->AddMessage(&msg, field);
if (!StructToProtoInternal(data, *submsg)) return false;
}
bytes += sizeof(std::vector<uint8_t>);
} else {
auto submsg = refl->MutableMessage(&msg, field);
if (!StructToProtoInternal(bytes, *submsg)) return false;
}
break;
}
default:
return false; // never reach;
}
}
return true;
}
#define SetStructValue(type, Type) \
do { if (field->is_repeated()) { \
auto &values = *(std::vector<type>*)bytes; \
int count = refl->FieldSize(msg, field); \
for (int i = 0; i < count; ++i) { \
values.push_back(refl->GetRepeated ## Type(msg, field, i)); \
} \
bytes += sizeof(std::vector<type>); \
} else { \
*(type*)bytes = refl->Get ## Type(msg, field); \
bytes += sizeof(type); \
}} while(0)
template<int size>
bool SetStructMap(uint8_t *bytes, const Message &msg, const FieldDescriptor *field)
{
auto refl = msg.GetReflection();
struct holder { uint8_t member[size]; };
auto &map = *(std::map<std::string, holder>*)bytes;
std::pair<std::string, holder> pair;
int count = refl->FieldSize(msg, field);
for (int i = 0; i < count; ++i) {
auto &submsg = refl->GetRepeatedMessage(msg, field, i);
auto data = (uint8_t*)&pair;
if (!ProtoToStructInternal(data, submsg)) return false;
map[pair.first] = pair.second;
}
return true;
}
static bool ProtoToStructInternal(uint8_t *&bytes, const Message &msg)
{
auto refl = msg.GetReflection();
auto desc = msg.GetDescriptor();
for (int i = 0; i < desc->field_count(); ++i) {
auto field = desc->field(i);
switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32:
SetStructValue(int32_t, Int32);
break;
case FieldDescriptor::CPPTYPE_INT64:
SetStructValue(int64_t, Int64);
break;
case FieldDescriptor::CPPTYPE_UINT32:
SetStructValue(uint32_t, UInt32);
break;
case FieldDescriptor::CPPTYPE_UINT64:
SetStructValue(uint64_t, UInt64);
break;
case FieldDescriptor::CPPTYPE_DOUBLE:
SetStructValue(double, Double);
break;
case FieldDescriptor::CPPTYPE_FLOAT:
SetStructValue(float, Float);
break;
case FieldDescriptor::CPPTYPE_BOOL:
SetStructValue(bool, Bool);
break;
case FieldDescriptor::CPPTYPE_ENUM:
SetStructValue(int, EnumValue);
break;
case FieldDescriptor::CPPTYPE_STRING:
SetStructValue(std::string, String);
break;
case FieldDescriptor::CPPTYPE_MESSAGE:
{
int size = GetMessageStructSize(field->message_type());
if (field->is_map()) {
if (size <= 8) {
if (!SetStructMap<8>(bytes, msg, field)) return false;
} else if (size <= 16) {
if (!SetStructMap<16>(bytes, msg, field)) return false;
} else if (size <= 32) {
if (!SetStructMap<32>(bytes, msg, field)) return false;
} else if (size <= 64) {
if (!SetStructMap<64>(bytes, msg, field)) return false;
} else if (size <= 128) {
if (!SetStructMap<128>(bytes, msg, field)) return false;
} else if (size <= 256) {
if (!SetStructMap<256>(bytes, msg, field)) return false;
} else if (size <= 512) {
if (!SetStructMap<512>(bytes, msg, field)) return false;
} else if (size <= 1024) {
if (!SetStructMap<1024>(bytes, msg, field)) return false;
} else if (size <= 2048) {
if (!SetStructMap<2048>(bytes, msg, field)) return false;
} else if (size <= 4096) {
if (!SetStructMap<4096>(bytes, msg, field)) return false;
} else if (size <= 8192) {
if (!SetStructMap<8192>(bytes, msg, field)) return false;
} else {
throw google::protobuf::FatalException(__FILE__, __LINE__,
"The struct is too big, see define of field.");
return false;
}
bytes += sizeof(std::map<std::string, uint8_t>);
} else if (field->is_repeated()) {
auto &values = *(std::vector<uint8_t>*)bytes;
int count = refl->FieldSize(msg, field);
values.resize(count * size);
auto data = (uint8_t*)values.data();
for (int i = 0; i < count; ++i) {
auto &submsg = refl->GetRepeatedMessage(msg, field, i);
if (!ProtoToStructInternal(data, submsg)) return false;
}
bytes += sizeof(std::vector<uint8_t>);
} else {
auto &submsg = refl->GetMessage(msg, field);
if (!ProtoToStructInternal(bytes, submsg)) return false;
}
break;
}
default:
break;
}
}
return true;
}
template<typename STRUCT, typename PROTO>
bool StructToProto(const STRUCT &in, PROTO &out)
{
int size = GetMessageStructSize(out.GetDescriptor());
if (size != sizeof(STRUCT)) return false;
auto bytes = (const uint8_t*)&in;
return StructToProtoInternal(bytes, out);
}
template<typename PROTO, typename STRUCT>
bool ProtoToStruct(const PROTO &in, STRUCT &out)
{
int size = GetMessageStructSize(in.GetDescriptor());
if (size != sizeof(STRUCT)) return false;
auto bytes = (uint8_t*)&out;
return ProtoToStructInternal(bytes, in);
}
int main(int argc, char *argv[])
{
Server server;
server.iflag = 99;
server.running = true;
server.address.push_back(12345678);
server.address.push_back(87654321);
server.type = ServerType::MAIL;
server.internal.push_back(Server::InternalSession{ "asjdifasdflkjasdkfa", Session{ "erererererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "bsjdifasdflkjasdkfa", Session{ "erererererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "csjdifasdflkjasdkfa", Session{ "erererererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "dsjdifasdflkjasdkfa", Session{ "erererererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "isjdifasdflkjasdkfa", Session{ "erererrerqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "dsjdifasdflkjasdkfa", Session{ "erererererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "jsjdifasdflkjasdkfa", Session{ "erereererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "fasdifasdflkjasdkfa", Session{ "erererererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "asjdifasdflkjasdkfa", Session{ "ererersererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "asjDIFASDFLKJASDKFA", Session{ "erererererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "asjijjikfslkjasdkfa", Session{ "erererererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "asjdifasFJKJjasdkfa", Session{ "erererererweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "asjdifasdflkjasdkfa", Session{ "erererererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "asjdifa32323jasdkfa", Session{ "erererererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "asjdifasdfl89809kfa", Session{ "erererererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "asjdifasdflkjasdkfa", Session{ "erererererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "asjdifasdflkjasdkfa", Session{ "erererererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "asjdiflkjasdkfa", Session{ "erererererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "asjdijasdkfa", Session{ "erererererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "asjdidkfa", Session{ "erererererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "asjdsdflkjasdkfa", Session{ "erererererqweqwe", 239283 } });
server.internal.push_back(Server::InternalSession{ "asjdifasdflkjasdkfa", Session{ "erererererqweqwe", 239283 } });
server.sessions.emplace("ff", Session{ "gg", 123 });
server.sessions.emplace("kk", Session{ "aa", 345 });
server.users.emplace_back(UserInfo{ "ijij", "jiok" });
server.users.emplace_back(UserInfo{ "ao0f", "8558" });
server.users.emplace_back(UserInfo{ "fsajflkdsjaflksdjflkasdfjlkasdjflkasdjflaksdfao0f", "8fasdfjalksdfjlaksdjfkalsdjflaksjkdfajsldf558" });
server.users.emplace_back(UserInfo{ "fsajflkcvnakjsdhfaehfoifjlkasdjflkasdjflaksdfao0f", "8vndkfahefhaejlaksdjfkalsdjflaksjkdfajsldf558" });
com::woody::Server proto;
if (StructToProto(server, proto)) {
printf("success, %s\n", proto.sessions().at("ff").uuid().c_str());
} else {
printf("failed\n");
}
Server server2;
if (ProtoToStruct(proto, server2)) {
printf("success, %s\n", proto.sessions().at("ff").uuid().c_str());
} else {
printf("failed\n");
}
return 0;
}
HTML
1
https://gitee.com/genrwoody/genrwoody.git
git@gitee.com:genrwoody/genrwoody.git
genrwoody
genrwoody
genrwoody
master

搜索帮助