Advertisement
Guest User

Untitled

a guest
Mar 7th, 2015
333
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.74 KB | None | 0 0
  1. std::string to_json(
  2.     const google::protobuf::Message& m,
  3.     std::function<std::string (const std::string&)> name_filter) {
  4.   std::vector<std::pair<std::string, std::string>> key_value_pairs;
  5.  
  6.   auto refl = m.GetReflection();
  7.   std::vector<const google::protobuf::FieldDescriptor*> field_descriptors;
  8.   refl->ListFields(m, &field_descriptors);
  9.  
  10.   for (auto fd : field_descriptors) {
  11.     if (!refl->HasField(m, fd)) {
  12.       continue;
  13.     }
  14.  
  15.     string value;
  16.  
  17.     if (fd->is_repeated()) {
  18.       const int n = refl->FieldSize(m, fd);
  19.       std::vector<std::string> vals(n);
  20.  
  21.       for (int i = 0; i < n; i++) {
  22.         switch (fd->type()) {
  23.           case google::protobuf::FieldDescriptor::TYPE_DOUBLE:
  24.             vals.push_back(std::to_string(refl->GetRepeatedDouble(m, fd, i)));
  25.             break;
  26.           case google::protobuf::FieldDescriptor::TYPE_FLOAT:
  27.             vals.push_back(std::to_string(refl->GetRepeatedFloat(m, fd, i)));
  28.             break;
  29.           case google::protobuf::FieldDescriptor::TYPE_INT64:
  30.             vals.push_back(std::to_string(refl->GetRepeatedInt64(m, fd, i)));
  31.             break;
  32.           case google::protobuf::FieldDescriptor::TYPE_UINT64:
  33.             vals.push_back(std::to_string(refl->GetRepeatedUInt64(m, fd, i)));
  34.             break;
  35.           case google::protobuf::FieldDescriptor::TYPE_INT32:
  36.             vals.push_back(std::to_string(refl->GetRepeatedInt32(m, fd, i)));
  37.             break;
  38.           case google::protobuf::FieldDescriptor::TYPE_FIXED64:
  39.             vals.push_back(std::to_string(refl->GetRepeatedInt64(m, fd, i)));
  40.             break;
  41.           case google::protobuf::FieldDescriptor::TYPE_FIXED32:
  42.             vals.push_back(std::to_string(refl->GetRepeatedInt32(m, fd, i)));
  43.             break;
  44.           case google::protobuf::FieldDescriptor::TYPE_BOOL:
  45.             vals.push_back(std::to_string(refl->GetRepeatedBool(m, fd, i)));
  46.             break;
  47.           case google::protobuf::FieldDescriptor::TYPE_STRING:
  48.             vals.push_back(refl->GetRepeatedString(m, fd, i));
  49.             break;
  50.           case google::protobuf::FieldDescriptor::TYPE_GROUP:
  51.             throw "Groups support not implemented.";
  52.             break;
  53.           case google::protobuf::FieldDescriptor::TYPE_MESSAGE:
  54.             vals.push_back(
  55.                 to_json(refl->GetRepeatedMessage(m, fd, i), name_filter));
  56.             break;
  57.           case google::protobuf::FieldDescriptor::TYPE_BYTES:
  58.             throw "Can't serialize binary to json.";
  59.             break;
  60.           case google::protobuf::FieldDescriptor::TYPE_UINT32:
  61.             vals.push_back(std::to_string(refl->GetRepeatedUInt32(m, fd, i)));
  62.             break;
  63.           case google::protobuf::FieldDescriptor::TYPE_ENUM:
  64.             throw "Can't serialize enums to json.";
  65.             break;
  66.           case google::protobuf::FieldDescriptor::TYPE_SFIXED32:
  67.             vals.push_back(std::to_string(refl->GetRepeatedInt32(m, fd, i)));
  68.             break;
  69.           case google::protobuf::FieldDescriptor::TYPE_SFIXED64:
  70.             vals.push_back(std::to_string(refl->GetRepeatedInt64(m, fd, i)));
  71.             break;
  72.           case google::protobuf::FieldDescriptor::TYPE_SINT32:
  73.             vals.push_back(std::to_string(refl->GetRepeatedInt32(m, fd, i)));
  74.             break;
  75.           case google::protobuf::FieldDescriptor::TYPE_SINT64:
  76.             vals.push_back(std::to_string(refl->GetRepeatedInt64(m, fd, i)));
  77.             break;
  78.           default:
  79.             break;
  80.         }
  81.  
  82.         value += '[';
  83.         for (const auto& v : vals) {
  84.           value += v;
  85.           value += ',';
  86.         }
  87.         if (value[value.length() - 1] == ',') {
  88.           value[value.length() - 1] = ']';
  89.         } else {
  90.           value += ']';
  91.         }
  92.       }
  93.     } else {
  94.       switch (fd->type()) {
  95.         case google::protobuf::FieldDescriptor::TYPE_DOUBLE:
  96.           value = std::to_string(refl->GetDouble(m, fd));
  97.           break;
  98.         case google::protobuf::FieldDescriptor::TYPE_FLOAT:
  99.           value = std::to_string(refl->GetFloat(m, fd));
  100.           break;
  101.         case google::protobuf::FieldDescriptor::TYPE_INT64:
  102.           value = std::to_string(refl->GetInt64(m, fd));
  103.           break;
  104.         case google::protobuf::FieldDescriptor::TYPE_UINT64:
  105.           value = std::to_string(refl->GetUInt64(m, fd));
  106.           break;
  107.         case google::protobuf::FieldDescriptor::TYPE_INT32:
  108.           value = std::to_string(refl->GetInt32(m, fd));
  109.           break;
  110.         case google::protobuf::FieldDescriptor::TYPE_FIXED64:
  111.           value = std::to_string(refl->GetInt64(m, fd));
  112.           break;
  113.         case google::protobuf::FieldDescriptor::TYPE_FIXED32:
  114.           value = std::to_string(refl->GetInt32(m, fd));
  115.           break;
  116.         case google::protobuf::FieldDescriptor::TYPE_BOOL:
  117.           value = std::to_string(refl->GetBool(m, fd));
  118.           break;
  119.         case google::protobuf::FieldDescriptor::TYPE_STRING:
  120.           value += '"';
  121.           value += refl->GetString(m, fd);
  122.           value += '"';
  123.           break;
  124.         case google::protobuf::FieldDescriptor::TYPE_GROUP:
  125.           throw "Groups support not implemented.";
  126.           break;
  127.         case google::protobuf::FieldDescriptor::TYPE_MESSAGE:
  128.           value += '"';
  129.           value += to_json(refl->GetMessage(m, fd), name_filter);
  130.           value += '"';
  131.           break;
  132.         case google::protobuf::FieldDescriptor::TYPE_BYTES:
  133.           throw "Can't serialize binary to json.";
  134.           break;
  135.         case google::protobuf::FieldDescriptor::TYPE_UINT32:
  136.           value = std::to_string(refl->GetUInt32(m, fd));
  137.           break;
  138.         case google::protobuf::FieldDescriptor::TYPE_ENUM:
  139.           throw "Can't serialize enums to json.";
  140.           break;
  141.         case google::protobuf::FieldDescriptor::TYPE_SFIXED32:
  142.           value = std::to_string(refl->GetInt32(m, fd));
  143.           break;
  144.         case google::protobuf::FieldDescriptor::TYPE_SFIXED64:
  145.           value = std::to_string(refl->GetInt64(m, fd));
  146.           break;
  147.         case google::protobuf::FieldDescriptor::TYPE_SINT32:
  148.           value = std::to_string(refl->GetInt32(m, fd));
  149.           break;
  150.         case google::protobuf::FieldDescriptor::TYPE_SINT64:
  151.           value = std::to_string(refl->GetInt64(m, fd));
  152.           break;
  153.         default:
  154.           break;
  155.       }
  156.     }
  157.  
  158.     key_value_pairs.push_back(std::make_pair(name_filter(fd->name()), value));
  159.   }
  160.  
  161.   string ret = "{";
  162.   for (const auto& p : key_value_pairs) {
  163.     ret += '"';
  164.     ret += p.first;
  165.     ret += "\":";
  166.     ret += p.second;
  167.     ret += ',';
  168.   }
  169.  
  170.   if (ret[ret.length() - 1] == ',') {
  171.     ret[ret.length() - 1] = '}';
  172.   } else {
  173.     ret += '}';
  174.   }
  175.  
  176.   return ret;
  177. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement