Esempio n. 1
0
void RpcGenerator::generateSentExternalBlock(const string &variableName,
    const string &channelName, const google::protobuf::Descriptor *descriptor,
    google::protobuf::io::Printer &printer) const
{
  for(int i=0; i< descriptor->field_count(); i++) {
    const FieldDescriptor *field = descriptor->field(i);

    if (field->type() == FieldDescriptor::TYPE_MESSAGE) {
      string messageTypeName = field->message_type()->full_name();

      if (messageTypeName.find("external.") == 0) {
        string externalClass = externalTypeToClass(messageTypeName);

        std::ostringstream stream;
        stream << "obj" << i;
        string var = stream.str();
        printer.Print("if ($variableName$->has_$fieldName$()) {\n",
          "variableName", variableName, "fieldName", field->lowercase_name());
        printer.Indent();
        printer.Print("$externalClass$ *$var$ = ", "externalClass", externalClass, "var", var);
        printer.Print("$variableName$->$fieldName$().get();\n", "variableName",
            variableName, "fieldName", field->lowercase_name());

        printer.Print("if ($var$) {\n", "var", var);
        printer.Indent();

        printer.Print("$externalClass$Serializer serializer($var$);\n",
            "externalClass", externalClass, "var", var);
        printer.Print("size_t size = serializer.size();\n");
        std::map<string, string> variables;
        variables["channelName"] = channelName;
        printer.Print("std::vector<unsigned char> data(size);\n");
        this->generateErrorCheck("serializer.serialize(&data[0], size)", variables,
            printer, "$channelName$->setErrorString(\"Serialization failed\");return;\n");

        variables.clear();
        variables["channelName"] = channelName;

        // Send the size first
        this->generateErrorCheck("$channelName$->send(size)", variables,
                    printer);

        this->generateErrorCheck("$channelName$->send(&data[0], size)", variables,
            printer);
        printer.Outdent();
        printer.Print("}\n");
        printer.Outdent();
        printer.Print("}\n");
      }
    }
  }
}
Esempio n. 2
0
void RpcGenerator::generateReceiveExternalBlock(const string &variableName,
    const string &channelName, const google::protobuf::Descriptor *descriptor,
    google::protobuf::io::Printer &printer) const
{
  bool hasExternalTypes = false;

  string code;
  io::StringOutputStream stream(&code);
  io::Printer tmpPrinter(&stream, '$');

  for(int i=0; i< descriptor->field_count(); i++) {
    const FieldDescriptor *field = descriptor->field(i);

    if (field->type() == FieldDescriptor::TYPE_MESSAGE)
    {
      string messageTypeName = field->message_type()->full_name();

      if (messageTypeName.find("external.") == 0) {
        hasExternalTypes = true;

        string externalClass = externalTypeToClass(messageTypeName);

        std::ostringstream objStream;
        objStream << "obj" << i;
        string objVar = objStream.str();

        std::ostringstream deserializerStream;
        deserializerStream << "deserializer" << i;
        string deserializerVar = deserializerStream.str();

        std::ostringstream dataStream;
        dataStream << "data" << i;
        string dataVar = dataStream.str();

        tmpPrinter.Print("if ($variableName$->has_$fieldName$()) {\n",
          "variableName", "tmp", "fieldName", field->lowercase_name());
        tmpPrinter.Indent();

        tmpPrinter.Print("::ProtoCall::Runtime::RpcVoidData $data$;\n", "data",
                         dataVar);

        std::map<string, string> variables;
        variables["var"] = dataVar;
        variables["channelName"] = channelName;
        this->generateErrorCheck("$channelName$->receive(&$var$)", variables,
                    tmpPrinter);

        tmpPrinter.Print("$externalClass$ *$objVar$ = tmp->$field$().get();\n",
            "externalClass", externalClass, "objVar", objVar, "field", field->lowercase_name());
        tmpPrinter.Print("bool allocated = false;\n");
        tmpPrinter.Print("if (!$objVar$) {\n", "objVar", objVar);
        tmpPrinter.Indent();
        tmpPrinter.Print("$objVar$ = new $externalClass$();\n",
            "objVar", objVar, "externalClass", externalClass);
        tmpPrinter.Print("allocated = true;\n");
        tmpPrinter.Outdent();
        tmpPrinter.Print("}\n");

        tmpPrinter.Print("$externalClass$Deserializer $deserializerVar$($objVar$);\n",
            "externalClass", externalClass, "deserializerVar", deserializerVar,
            "objVar", objVar);
        variables["deserializerVar"] = deserializerVar;
        this->generateErrorCheck("$deserializerVar$.deserialize($var$.data(), $var$.size())", variables,
            tmpPrinter, "$channelName$->setErrorString(\"Deserialization failed\");return;\n");

        variables.clear();
        variables["var"] = objVar;
        variables["channelName"] = channelName;
        variables["objVar"] = objVar;

        tmpPrinter.Print("if (allocated)\n");
        tmpPrinter.Indent();
        tmpPrinter.Print("tmp->mutable_$field$()->set_allocated($objVar$);\n",
            "field", field->lowercase_name(), "objVar", objVar);
        tmpPrinter.Outdent();
        tmpPrinter.Outdent();
        tmpPrinter.Print("}\n");
      }
    }
  }

  if (hasExternalTypes) {
    printer.Print("::google::protobuf::Message *mutableRequest "
        "= const_cast< google::protobuf::Message *>($variableName$);\n",
        "variableName", variableName);
    printer.Print("$inputType$ *tmp ="
        "static_cast<$inputType$ *>(mutableRequest);\n",
        "inputType", descriptor->name());
    printer.Print(code.c_str());
  }
}