诸暨麻将添加redis
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

171 lines
3.9 KiB

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include "google/protobuf/message.h"
  5. #include "proto_man.h"
  6. #define MAX_PF_MAP_SIZE 1024
  7. #define CMD_HEADER 8
  8. static int g_proto_type = PROTO_BUF;
  9. static char* g_pf_map[MAX_PF_MAP_SIZE];
  10. static int g_cmd_count = 0;
  11. void
  12. proto_man::init(int proto_type) {
  13. g_proto_type = proto_type;
  14. }
  15. int
  16. proto_man::proto_type() {
  17. return g_proto_type;
  18. }
  19. void
  20. proto_man::register_pf_cmd_map(char** pf_map, int len) {
  21. len = (MAX_PF_MAP_SIZE - g_cmd_count) < len ? ((MAX_PF_MAP_SIZE - g_cmd_count)) : len;
  22. for (int i = 0; i < len; i++) {
  23. g_pf_map[g_cmd_count + i] = strdup(pf_map[i]);
  24. }
  25. g_cmd_count += len;
  26. }
  27. static google::protobuf::Message*
  28. create_message(const char* type_name) {
  29. google::protobuf::Message* message = NULL;
  30. const google::protobuf::Descriptor* descriptor =
  31. google::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName(type_name);
  32. if (descriptor) {
  33. const google::protobuf::Message* prototype =
  34. google::protobuf::MessageFactory::generated_factory()->GetPrototype(descriptor);
  35. if (prototype) {
  36. message = prototype->New();
  37. }
  38. }
  39. return message;
  40. }
  41. static void
  42. release_message(google::protobuf::Message* m) {
  43. delete m;
  44. }
  45. // stype(2 byte) | ctype(2byte) | utag(4byte) | body
  46. bool
  47. proto_man::decode_cmd_msg(unsigned char* cmd, int cmd_len, struct cmd_msg** out_msg) {
  48. *out_msg = NULL;
  49. if (cmd_len < CMD_HEADER) {
  50. return false;
  51. }
  52. struct cmd_msg* msg = (struct cmd_msg*)malloc(sizeof(struct cmd_msg));
  53. msg->stype = cmd[0] | (cmd[1] << 8);
  54. msg->ctype = cmd[2] | (cmd[3] << 8);
  55. msg->utag = cmd[4] | (cmd[5] << 8) | (cmd[6] << 16) | (cmd[7] << 24);
  56. msg->body = NULL;
  57. *out_msg = msg;
  58. if (cmd_len == CMD_HEADER) {
  59. return true;
  60. }
  61. if (g_proto_type == PROTO_JSON) {
  62. int json_len = cmd_len - CMD_HEADER;
  63. char* json_str = (char*)malloc(json_len + 1);
  64. memcpy(json_str, cmd + CMD_HEADER, json_len);
  65. json_str[json_len] = 0;
  66. msg->body = (void*)json_str;
  67. }
  68. else { // protobuf
  69. if (msg->ctype < 0 || msg->ctype >= g_cmd_count || g_pf_map[msg->ctype] == NULL) {
  70. free(msg);
  71. *out_msg = NULL;
  72. return false;
  73. }
  74. google::protobuf::Message* p_m = create_message(g_pf_map[msg->ctype]);
  75. if (p_m == NULL) {
  76. free(msg);
  77. *out_msg = NULL;
  78. return false;
  79. }
  80. if (!p_m->ParseFromArray(cmd + CMD_HEADER, cmd_len - CMD_HEADER)) {
  81. free(msg);
  82. *out_msg = NULL;
  83. release_message(p_m);
  84. return false;
  85. }
  86. msg->body = p_m;
  87. }
  88. return true;
  89. }
  90. void
  91. proto_man::cmd_msg_free(struct cmd_msg* msg) {
  92. if (msg->body) {
  93. if (g_proto_type == PROTO_JSON) {
  94. free(msg->body);
  95. msg->body = NULL;
  96. }
  97. else {
  98. google::protobuf::Message* p_m = (google::protobuf::Message*) msg->body;
  99. delete p_m;
  100. msg->body = NULL;
  101. }
  102. }
  103. free(msg);
  104. }
  105. unsigned char*
  106. proto_man::encode_msg_to_raw(const struct cmd_msg* msg, int* out_len) {
  107. int raw_len = 0;
  108. unsigned char* raw_data = NULL;
  109. *out_len = 0;
  110. if (g_proto_type == PROTO_JSON) {
  111. char* json_str = (char*)msg->body;
  112. int len = strlen(json_str) + 1;
  113. raw_data = (unsigned char*)malloc(CMD_HEADER + len);
  114. memcpy(raw_data + CMD_HEADER, json_str, len - 1);
  115. raw_data[8 + len] = 0;
  116. *out_len = (len + CMD_HEADER);
  117. }
  118. else { // protobuf
  119. google::protobuf::Message* p_m = (google::protobuf::Message*)msg->body;
  120. int pf_len = p_m->ByteSize();
  121. raw_data = (unsigned char*)malloc(CMD_HEADER + pf_len);
  122. if (!p_m->SerializePartialToArray(raw_data + CMD_HEADER, pf_len)) {
  123. free(raw_data);
  124. return NULL;
  125. }
  126. *out_len = (pf_len + CMD_HEADER);
  127. }
  128. // header
  129. raw_data[0] = (msg->stype & 0x000000ff);
  130. raw_data[1] = ((msg->stype & 0x0000ff00) >> 8);
  131. raw_data[2] = (msg->ctype & 0x000000ff);
  132. raw_data[3] = ((msg->ctype & 0x0000ff00) >> 8);
  133. memcpy(raw_data + 4, &msg->utag, 4);
  134. //
  135. return raw_data;
  136. }
  137. void
  138. proto_man::msg_raw_free(unsigned char* raw) {
  139. free(raw);
  140. }