Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 49363e4d authored by Zach Johnson's avatar Zach Johnson
Browse files

rusty-gd: move write_to logic to parent_def

this way it can be shared between struct & packet

Bug: 171749953
Tag: #gd-refactor
Test: gd/cert/run --rhost
Change-Id: I58d1972a28127ad28f2c1cbc51301a97027016e4
parent 35b390d0
Loading
Loading
Loading
Loading
+1 −57
Original line number Original line Diff line number Diff line
@@ -999,63 +999,7 @@ void PacketDef::GenRustStructImpls(std::ostream& s) const {


  // write_to function
  // write_to function
  s << "fn write_to(&self, buffer: &mut BytesMut) {";
  s << "fn write_to(&self, buffer: &mut BytesMut) {";

  GenRustWriteToFields(s);
  fields = fields_.GetFieldsWithoutTypes({
      BodyField::kFieldType,
      CountField::kFieldType,
      PaddingField::kFieldType,
      ReservedField::kFieldType,
      FixedScalarField::kFieldType,
  });

  for (auto const& field : fields) {
    auto start_field_offset = GetOffsetForField(field->GetName(), false);
    auto end_field_offset = GetOffsetForField(field->GetName(), true);

    if (start_field_offset.empty() && end_field_offset.empty()) {
      ERROR(field) << "Field location for " << field->GetName() << " is ambiguous, "
                   << "no method exists to determine field location from begin() or end().\n";
    }

    if (field->GetFieldType() == SizeField::kFieldType) {
      const auto& field_name = ((SizeField*)field)->GetSizedFieldName();
      const auto& sized_field = fields_.GetField(field_name);
      if (sized_field == nullptr) {
        ERROR(field) << __func__ << ": Can't find sized field named " << field_name;
      }
      if (sized_field->GetFieldType() == PayloadField::kFieldType) {
        std::string modifier = ((PayloadField*)sized_field)->size_modifier_;
        if (modifier != "") {
          ERROR(field) << __func__ << ": size modifiers not implemented yet for " << field_name;
        }

        s << "let " << field->GetName() << " = " << field->GetRustDataType()
          << "::try_from(self.child.get_total_size()).expect(\"payload size did not fit\");";
      } else if (sized_field->GetFieldType() == BodyField::kFieldType) {
        s << "let " << field->GetName() << " = " << field->GetRustDataType()
          << "::try_from(self.get_total_size() - self.get_size()).expect(\"payload size did not fit\");";
      } else if (sized_field->GetFieldType() == VectorField::kFieldType) {
        const auto& vector_name = field_name + "_bytes";
        const VectorField* vector = (VectorField*)sized_field;
        if (vector->element_size_.empty() || vector->element_size_.has_dynamic()) {
          s << "let " << vector_name + " = self." << field_name << ".iter().fold(0, |acc, x| acc + x.get_size());";
        } else {
          s << "let " << vector_name + " = self." << field_name << ".len() * ((" << vector->element_size_ << ") / 8);";
        }
        std::string modifier = vector->GetSizeModifier();
        if (modifier != "") {
          ERROR(field) << __func__ << ": size modifiers not implemented yet for " << field_name;
        }

        s << "let " << field->GetName() << " = " << field->GetRustDataType() << "::try_from(" << vector_name
          << ").expect(\"payload size did not fit\");";
      } else {
        ERROR(field) << __func__ << ": Unhandled sized field type for " << field_name;
      }
    }

    field->GenRustWriter(s, start_field_offset, end_field_offset);
  }


  if (HasChildEnums()) {
  if (HasChildEnums()) {
    s << "match &self.child {";
    s << "match &self.child {";
+59 −0
Original line number Original line Diff line number Diff line
@@ -569,3 +569,62 @@ std::vector<const ParentDef*> ParentDef::FindPathToDescendant(std::string descen
bool ParentDef::HasChildEnums() const {
bool ParentDef::HasChildEnums() const {
  return !children_.empty() || fields_.HasPayload();
  return !children_.empty() || fields_.HasPayload();
}
}

void ParentDef::GenRustWriteToFields(std::ostream& s) const {
  auto fields = fields_.GetFieldsWithoutTypes({
      BodyField::kFieldType,
      CountField::kFieldType,
      PaddingField::kFieldType,
      ReservedField::kFieldType,
      FixedScalarField::kFieldType,
  });

  for (auto const& field : fields) {
    auto start_field_offset = GetOffsetForField(field->GetName(), false);
    auto end_field_offset = GetOffsetForField(field->GetName(), true);

    if (start_field_offset.empty() && end_field_offset.empty()) {
      ERROR(field) << "Field location for " << field->GetName() << " is ambiguous, "
                   << "no method exists to determine field location from begin() or end().\n";
    }

    if (field->GetFieldType() == SizeField::kFieldType) {
      const auto& field_name = ((SizeField*)field)->GetSizedFieldName();
      const auto& sized_field = fields_.GetField(field_name);
      if (sized_field == nullptr) {
        ERROR(field) << __func__ << ": Can't find sized field named " << field_name;
      }
      if (sized_field->GetFieldType() == PayloadField::kFieldType) {
        std::string modifier = ((PayloadField*)sized_field)->size_modifier_;
        if (modifier != "") {
          ERROR(field) << __func__ << ": size modifiers not implemented yet for " << field_name;
        }

        s << "let " << field->GetName() << " = " << field->GetRustDataType()
          << "::try_from(self.child.get_total_size()).expect(\"payload size did not fit\");";
      } else if (sized_field->GetFieldType() == BodyField::kFieldType) {
        s << "let " << field->GetName() << " = " << field->GetRustDataType()
          << "::try_from(self.get_total_size() - self.get_size()).expect(\"payload size did not fit\");";
      } else if (sized_field->GetFieldType() == VectorField::kFieldType) {
        const auto& vector_name = field_name + "_bytes";
        const VectorField* vector = (VectorField*)sized_field;
        if (vector->element_size_.empty() || vector->element_size_.has_dynamic()) {
          s << "let " << vector_name + " = self." << field_name << ".iter().fold(0, |acc, x| acc + x.get_size());";
        } else {
          s << "let " << vector_name + " = self." << field_name << ".len() * ((" << vector->element_size_ << ") / 8);";
        }
        std::string modifier = vector->GetSizeModifier();
        if (modifier != "") {
          s << "let " << vector_name << " = " << vector_name << " + (" << modifier.substr(1) << ") / 8;";
        }

        s << "let " << field->GetName() << " = " << field->GetRustDataType() << "::try_from(" << vector_name
          << ").expect(\"payload size did not fit\");";
      } else {
        ERROR(field) << __func__ << ": Unhandled sized field type for " << field_name;
      }
    }

    field->GenRustWriter(s, start_field_offset, end_field_offset);
  }
}
+2 −0
Original line number Original line Diff line number Diff line
@@ -87,4 +87,6 @@ class ParentDef : public TypeDef {
  bool is_little_endian_;
  bool is_little_endian_;


  bool HasChildEnums() const;
  bool HasChildEnums() const;

  void GenRustWriteToFields(std::ostream& s) const;
};
};
+1 −41
Original line number Original line Diff line number Diff line
@@ -379,27 +379,6 @@ void StructDef::GenRustDeclarations(std::ostream& s) const {


void StructDef::GenRustImpls(std::ostream& s) const {
void StructDef::GenRustImpls(std::ostream& s) const {
  s << "impl " << name_ << "{";
  s << "impl " << name_ << "{";
  /*s << "pub fn new(";
  GenRustFieldNameAndType(s, false);
  s << ") -> Self { Self {";
  auto fields = fields_.GetFieldsWithoutTypes({
      BodyField::kFieldType,
      CountField::kFieldType,
      PaddingField::kFieldType,
      ReservedField::kFieldType,
      SizeField::kFieldType,
  });
  for (const auto& field : fields) {
    if (field->GetFieldType() == FixedScalarField::kFieldType) {
      s << field->GetName() << ": ";
      static_cast<FixedScalarField*>(field)->GenValue(s);
    } else {
      s << field->GetName();
    }
    s << ", ";
  }
  s << "}}";*/

  s << "pub fn parse(bytes: &[u8]) -> Result<Self> {";
  s << "pub fn parse(bytes: &[u8]) -> Result<Self> {";
  auto fields = fields_.GetFieldsWithoutTypes({
  auto fields = fields_.GetFieldsWithoutTypes({
      BodyField::kFieldType,
      BodyField::kFieldType,
@@ -439,26 +418,7 @@ void StructDef::GenRustImpls(std::ostream& s) const {


  // write_to function
  // write_to function
  s << "fn write_to(&self, buffer: &mut BytesMut) {";
  s << "fn write_to(&self, buffer: &mut BytesMut) {";
  fields = fields_.GetFieldsWithoutTypes({
  GenRustWriteToFields(s);
      BodyField::kFieldType,
      CountField::kFieldType,
      PaddingField::kFieldType,
      ReservedField::kFieldType,
      SizeField::kFieldType,
  });

  for (auto const& field : fields) {
    auto start_field_offset = GetOffsetForField(field->GetName(), false);
    auto end_field_offset = GetOffsetForField(field->GetName(), true);

    if (start_field_offset.empty() && end_field_offset.empty()) {
      ERROR(field) << "Field location for " << field->GetName() << " is ambiguous, "
                   << "no method exists to determine field location from begin() or end().\n";
    }

    field->GenRustWriter(s, start_field_offset, end_field_offset);
  }

  s << "}\n";
  s << "}\n";


  if (fields.size() > 0) {
  if (fields.size() > 0) {