void t_php_generator::generate_deserialize_field()

in compiler/cpp/src/thrift/generate/t_php_generator.cc [2109:2233]


void t_php_generator::generate_deserialize_field(ostream& out,
                                                 t_field* tfield,
                                                 string prefix,
                                                 bool inclass) {
  t_type* type = get_true_type(tfield->get_type());

  if (type->is_void()) {
    throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " + prefix + tfield->get_name();
  }

  string name = prefix + tfield->get_name();

  if (type->is_struct() || type->is_xception()) {
    generate_deserialize_struct(out, (t_struct*)type, name);
  } else {

    if (type->is_container()) {
      generate_deserialize_container(out, type, name);
    } else if (type->is_base_type() || type->is_enum()) {

      if (binary_inline_) {
        std::string itrans = (inclass ? "$this->input_" : "$input");

        if (type->is_base_type()) {
          t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
          switch (tbase) {
          case t_base_type::TYPE_VOID:
            throw "compiler error: cannot serialize void field in a struct: " + name;
            break;
          case t_base_type::TYPE_STRING:
            out << indent() << "$len = unpack('N', " << itrans << "->readAll(4));" << '\n'
                << indent() << "$len = $len[1];" << '\n' << indent() << "if ($len > 0x7fffffff) {"
                << '\n' << indent() << "  $len = 0 - (($len - 1) ^ 0xffffffff);" << '\n' << indent()
                << "}" << '\n' << indent() << "$" << name << " = " << itrans << "->readAll($len);"
                << '\n';
            break;
          case t_base_type::TYPE_BOOL:
            out << indent() << "$" << name << " = unpack('c', " << itrans << "->readAll(1));"
                << '\n' << indent() << "$" << name << " = (bool)$" << name << "[1];" << '\n';
            break;
          case t_base_type::TYPE_I8:
            out << indent() << "$" << name << " = unpack('c', " << itrans << "->readAll(1));"
                << '\n' << indent() << "$" << name << " = $" << name << "[1];" << '\n';
            break;
          case t_base_type::TYPE_I16:
            out << indent() << "$val = unpack('n', " << itrans << "->readAll(2));" << '\n'
                << indent() << "$val = $val[1];" << '\n' << indent() << "if ($val > 0x7fff) {"
                << '\n' << indent() << "  $val = 0 - (($val - 1) ^ 0xffff);" << '\n' << indent()
                << "}" << '\n' << indent() << "$" << name << " = $val;" << '\n';
            break;
          case t_base_type::TYPE_I32:
            out << indent() << "$val = unpack('N', " << itrans << "->readAll(4));" << '\n'
                << indent() << "$val = $val[1];" << '\n' << indent() << "if ($val > 0x7fffffff) {"
                << '\n' << indent() << "  $val = 0 - (($val - 1) ^ 0xffffffff);" << '\n' << indent()
                << "}" << '\n' << indent() << "$" << name << " = $val;" << '\n';
            break;
          case t_base_type::TYPE_I64:
            out << indent() << "$arr = unpack('N2', " << itrans << "->readAll(8));" << '\n'
                << indent() << "if ($arr[1] & 0x80000000) {" << '\n' << indent()
                << "  $arr[1] = $arr[1] ^ 0xFFFFFFFF;" << '\n' << indent()
                << "  $arr[2] = $arr[2] ^ 0xFFFFFFFF;" << '\n' << indent() << "  $" << name
                << " = 0 - $arr[1]*4294967296 - $arr[2] - 1;" << '\n' << indent() << "} else {"
                << '\n' << indent() << "  $" << name << " = $arr[1]*4294967296 + $arr[2];" << '\n'
                << indent() << "}" << '\n';
            break;
          case t_base_type::TYPE_DOUBLE:
            out << indent() << "$arr = unpack('d', strrev(" << itrans << "->readAll(8)));" << '\n'
                << indent() << "$" << name << " = $arr[1];" << '\n';
            break;
          default:
            throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase)
                + tfield->get_name();
          }
        } else if (type->is_enum()) {
          out << indent() << "$val = unpack('N', " << itrans << "->readAll(4));" << '\n' << indent()
              << "$val = $val[1];" << '\n' << indent() << "if ($val > 0x7fffffff) {" << '\n'
              << indent() << "  $val = 0 - (($val - 1) ^ 0xffffffff);" << '\n' << indent() << "}"
              << '\n' << indent() << "$" << name << " = $val;" << '\n';
        }
      } else {

        indent(out) << "$xfer += $input->";

        if (type->is_base_type()) {
          t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
          switch (tbase) {
          case t_base_type::TYPE_VOID:
            throw "compiler error: cannot serialize void field in a struct: " + name;
            break;
          case t_base_type::TYPE_STRING:
            out << "readString($" << name << ");";
            break;
          case t_base_type::TYPE_BOOL:
            out << "readBool($" << name << ");";
            break;
          case t_base_type::TYPE_I8:
            out << "readByte($" << name << ");";
            break;
          case t_base_type::TYPE_I16:
            out << "readI16($" << name << ");";
            break;
          case t_base_type::TYPE_I32:
            out << "readI32($" << name << ");";
            break;
          case t_base_type::TYPE_I64:
            out << "readI64($" << name << ");";
            break;
          case t_base_type::TYPE_DOUBLE:
            out << "readDouble($" << name << ");";
            break;
          default:
            throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase);
          }
        } else if (type->is_enum()) {
          out << "readI32($" << name << ");";
        }
        out << '\n';
      }
    } else {
      printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n",
             tfield->get_name().c_str(),
             type->get_name().c_str());
    }
  }
}