in compiler/cpp/src/thrift/generate/t_java_generator.cc [1797:2019]
void t_java_generator::generate_java_struct_parcelable(ostream& out, t_struct* tstruct) {
string tname = tstruct->get_name();
const vector<t_field*>& members = tstruct->get_members();
vector<t_field*>::const_iterator m_iter;
out << indent() << java_override_annotation() << '\n'
<< indent() << "public void writeToParcel(android.os.Parcel out, int flags) {" << '\n';
indent_up();
string bitsetPrimitiveType = "";
switch (needs_isset(tstruct, &bitsetPrimitiveType)) {
case ISSET_NONE:
break;
case ISSET_PRIMITIVE:
indent(out) << "//primitive bitfield of type: " << bitsetPrimitiveType << '\n';
if (bitsetPrimitiveType == "byte") {
indent(out) << "out.writeByte(__isset_bitfield);" << '\n';
} else if (bitsetPrimitiveType == "short") {
indent(out) << "out.writeInt(new Short(__isset_bitfield).intValue());" << '\n';
} else if (bitsetPrimitiveType == "int") {
indent(out) << "out.writeInt(__isset_bitfield);" << '\n';
} else if (bitsetPrimitiveType == "long") {
indent(out) << "out.writeLong(__isset_bitfield);" << '\n';
}
out << '\n';
break;
case ISSET_BITSET:
indent(out) << "//BitSet" << '\n';
indent(out) << "out.writeSerializable(__isset_bit_vector);" << '\n';
out << '\n';
break;
}
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
t_type* t = get_true_type((*m_iter)->get_type());
string name = (*m_iter)->get_name();
if (t->is_struct()) {
indent(out) << "out.writeParcelable(" << name << ", flags);" << '\n';
} else if (type_name(t) == "float") {
indent(out) << "out.writeFloat(" << name << ");" << '\n';
} else if (t->is_enum()) {
indent(out) << "out.writeInt(" << name << " != null ? " << name << ".getValue() : -1);"
<< '\n';
} else if (t->is_list()) {
if (((t_list*)t)->get_elem_type()->get_true_type()->is_struct()) {
indent(out) << "out.writeTypedList(" << name << ");" << '\n';
} else {
indent(out) << "out.writeList(" << name << ");" << '\n';
}
} else if (t->is_map()) {
indent(out) << "out.writeMap(" << name << ");" << '\n';
} else if (t->is_base_type()) {
if (t->is_binary()) {
indent(out) << "out.writeInt(" << name << "!=null ? 1 : 0);" << '\n';
indent(out) << "if(" << name << " != null) { " << '\n';
indent_up();
indent(out) << "out.writeByteArray(" << name << ".array(), " << name << ".position() + "
<< name << ".arrayOffset(), " << name << ".limit() - " << name
<< ".position() );" << '\n';
scope_down(out);
} else {
switch (((t_base_type*)t)->get_base()) {
case t_base_type::TYPE_I16:
indent(out) << "out.writeInt(new Short(" << name << ").intValue());" << '\n';
break;
case t_base_type::TYPE_UUID:
indent(out) << "out.writeUuid(" << name << ");" << '\n';
break;
case t_base_type::TYPE_I32:
indent(out) << "out.writeInt(" << name << ");" << '\n';
break;
case t_base_type::TYPE_I64:
indent(out) << "out.writeLong(" << name << ");" << '\n';
break;
case t_base_type::TYPE_BOOL:
indent(out) << "out.writeInt(" << name << " ? 1 : 0);" << '\n';
break;
case t_base_type::TYPE_I8:
indent(out) << "out.writeByte(" << name << ");" << '\n';
break;
case t_base_type::TYPE_DOUBLE:
indent(out) << "out.writeDouble(" << name << ");" << '\n';
break;
case t_base_type::TYPE_STRING:
indent(out) << "out.writeString(" << name << ");" << '\n';
break;
case t_base_type::TYPE_VOID:
break;
default:
throw "compiler error: unhandled type";
}
}
}
}
scope_down(out);
out << '\n';
out << indent() << java_override_annotation() << '\n'
<< indent() << "public int describeContents() {" << '\n';
indent_up();
out << indent() << "return 0;" << '\n';
scope_down(out);
out << '\n';
indent(out) << "public " << tname << "(android.os.Parcel in) {" << '\n';
indent_up();
// read in the required bitfield
switch (needs_isset(tstruct, &bitsetPrimitiveType)) {
case ISSET_NONE:
break;
case ISSET_PRIMITIVE:
indent(out) << "//primitive bitfield of type: " << bitsetPrimitiveType << '\n';
if (bitsetPrimitiveType == "byte") {
indent(out) << "__isset_bitfield = in.readByte();" << '\n';
} else if (bitsetPrimitiveType == "short") {
indent(out) << "__isset_bitfield = (short) in.readInt();" << '\n';
} else if (bitsetPrimitiveType == "int") {
indent(out) << "__isset_bitfield = in.readInt();" << '\n';
} else if (bitsetPrimitiveType == "long") {
indent(out) << "__isset_bitfield = in.readLong();" << '\n';
}
out << '\n';
break;
case ISSET_BITSET:
indent(out) << "//BitSet" << '\n';
indent(out) << "__isset_bit_vector = (java.util.BitSet) in.readSerializable();" << '\n';
out << '\n';
break;
}
// read all the fields
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
t_type* t = get_true_type((*m_iter)->get_type());
string name = (*m_iter)->get_name();
string prefix = "this." + name;
if (t->is_struct()) {
indent(out) << prefix << "= in.readParcelable(" << tname << ".class.getClassLoader());"
<< '\n';
} else if (t->is_enum()) {
indent(out) << prefix << " = " << type_name(t) << ".findByValue(in.readInt());" << '\n';
} else if (t->is_list()) {
t_list* list = (t_list*)t;
indent(out) << prefix << " = new " << type_name(t, false, true) << "();" << '\n';
if (list->get_elem_type()->get_true_type()->is_struct()) {
indent(out) << "in.readTypedList(" << prefix << ", " << type_name(list->get_elem_type())
<< ".CREATOR);" << '\n';
} else {
indent(out) << "in.readList(" << prefix << ", " << tname << ".class.getClassLoader());"
<< '\n';
}
} else if (t->is_map()) {
indent(out) << prefix << " = new " << type_name(t, false, true) << "();" << '\n';
indent(out) << " in.readMap(" << prefix << ", " << tname << ".class.getClassLoader());"
<< '\n';
} else if (type_name(t) == "float") {
indent(out) << prefix << " = in.readFloat();" << '\n';
} else if (t->is_base_type()) {
t_base_type* bt = (t_base_type*)t;
if (bt->is_binary()) {
indent(out) << "if(in.readInt()==1) {" << '\n';
indent_up();
indent(out) << prefix << " = java.nio.ByteBuffer.wrap(in.createByteArray());" << '\n';
scope_down(out);
} else {
switch (bt->get_base()) {
case t_base_type::TYPE_I8:
indent(out) << prefix << " = in.readByte();" << '\n';
break;
case t_base_type::TYPE_I16:
indent(out) << prefix << " = (short) in.readInt();" << '\n';
break;
case t_base_type::TYPE_I32:
indent(out) << prefix << " = in.readInt();" << '\n';
break;
case t_base_type::TYPE_I64:
indent(out) << prefix << " = in.readLong();" << '\n';
break;
case t_base_type::TYPE_UUID:
indent(out) << prefix << " = in.readUuid();" << '\n';
break;
case t_base_type::TYPE_BOOL:
indent(out) << prefix << " = (in.readInt()==1);" << '\n';
break;
case t_base_type::TYPE_DOUBLE:
indent(out) << prefix << " = in.readDouble();" << '\n';
break;
case t_base_type::TYPE_STRING:
indent(out) << prefix << "= in.readString();" << '\n';
break;
case t_base_type::TYPE_VOID:
break;
default:
throw "compiler error: unhandled type";
}
}
}
}
scope_down(out);
out << '\n';
indent(out) << "public static final android.os.Parcelable.Creator<" << tname
<< "> CREATOR = new android.os.Parcelable.Creator<" << tname << ">() {" << '\n';
indent_up();
indent(out) << java_override_annotation() << '\n'
<< indent() << "public " << tname << "[] newArray(int size) {" << '\n';
indent_up();
indent(out) << "return new " << tname << "[size];" << '\n';
scope_down(out);
out << '\n';
indent(out) << java_override_annotation() << '\n'
<< indent() << "public " << tname << " createFromParcel(android.os.Parcel in) {"
<< '\n';
indent_up();
indent(out) << "return new " << tname << "(in);" << '\n';
scope_down(out);
indent_down();
indent(out) << "};" << '\n';
out << '\n';
}