From cff15c172434d810b33d157874a1dc3e82effc31 Mon Sep 17 00:00:00 2001 From: Myles Watson Date: Fri, 19 Jul 2019 16:07:36 -0700 Subject: [PATCH] PDL: Extract CustomFieldFixedSize Test: bluetooth_packet_parser_test Change-Id: Ia93442ca1cc173d0b6c813a45c722f14d2f34fa0 --- gd/packet/parser/Android.bp | 1 + gd/packet/parser/custom_field_def.cc | 6 ++- gd/packet/parser/custom_field_def.h | 1 + gd/packet/parser/fields/all_fields.h | 1 + gd/packet/parser/fields/custom_field.cc | 57 ++++----------------- gd/packet/parser/fields/custom_field.h | 5 +- gd/packet/parser/fields/custom_field_fixed_size.cc | 59 ++++++++++++++++++++++ gd/packet/parser/fields/custom_field_fixed_size.h | 41 +++++++++++++++ 8 files changed, 118 insertions(+), 53 deletions(-) create mode 100644 gd/packet/parser/fields/custom_field_fixed_size.cc create mode 100644 gd/packet/parser/fields/custom_field_fixed_size.h diff --git a/gd/packet/parser/Android.bp b/gd/packet/parser/Android.bp index 55a983b96..63aaa7ade 100644 --- a/gd/packet/parser/Android.bp +++ b/gd/packet/parser/Android.bp @@ -7,6 +7,7 @@ cc_binary_host { "fields/checksum_start_field.cc", "fields/count_field.cc", "fields/custom_field.cc", + "fields/custom_field_fixed_size.cc", "fields/enum_field.cc", "fields/fixed_enum_field.cc", "fields/fixed_field.cc", diff --git a/gd/packet/parser/custom_field_def.cc b/gd/packet/parser/custom_field_def.cc index 1ac677965..5dc9316bb 100644 --- a/gd/packet/parser/custom_field_def.cc +++ b/gd/packet/parser/custom_field_def.cc @@ -28,7 +28,11 @@ CustomFieldDef::CustomFieldDef(std::string name, std::string include, int size) } PacketField* CustomFieldDef::GetNewField(const std::string& name, ParseLocation loc) const { - return new CustomField(name, name_, size_, loc); + if (size_ == -1) { + return new CustomField(name, name_, loc); + } else { + return new CustomFieldFixedSize(name, name_, size_, loc); + } } TypeDef::Type CustomFieldDef::GetDefinitionType() const { diff --git a/gd/packet/parser/custom_field_def.h b/gd/packet/parser/custom_field_def.h index d14c4376e..62cf363d1 100644 --- a/gd/packet/parser/custom_field_def.h +++ b/gd/packet/parser/custom_field_def.h @@ -19,6 +19,7 @@ #include #include "fields/custom_field.h" +#include "fields/custom_field_fixed_size.h" #include "parse_location.h" #include "type_def.h" diff --git a/gd/packet/parser/fields/all_fields.h b/gd/packet/parser/fields/all_fields.h index 37ffe98af..579707655 100644 --- a/gd/packet/parser/fields/all_fields.h +++ b/gd/packet/parser/fields/all_fields.h @@ -22,6 +22,7 @@ #include "fields/checksum_start_field.h" #include "fields/count_field.h" #include "fields/custom_field.h" +#include "fields/custom_field_fixed_size.h" #include "fields/enum_field.h" #include "fields/fixed_enum_field.h" #include "fields/fixed_scalar_field.h" diff --git a/gd/packet/parser/fields/custom_field.cc b/gd/packet/parser/fields/custom_field.cc index 9ff1e86e3..5a098e6bd 100644 --- a/gd/packet/parser/fields/custom_field.cc +++ b/gd/packet/parser/fields/custom_field.cc @@ -19,24 +19,20 @@ const std::string CustomField::kFieldType = "CustomField"; -CustomField::CustomField(std::string name, std::string type_name, int size, ParseLocation loc) - : PacketField(name, loc), type_name_(type_name), size_(size) {} +CustomField::CustomField(std::string name, std::string type_name, ParseLocation loc) + : PacketField(name, loc), type_name_(type_name) {} const std::string& CustomField::GetFieldType() const { return CustomField::kFieldType; } Size CustomField::GetSize() const { - return size_; + return Size(); } Size CustomField::GetBuilderSize() const { - if (size_ != -1) { - return size_; - } else { - std::string ret = "(" + GetName() + "_.size() * 8) "; - return ret; - } + std::string ret = "(" + GetName() + "_.size() * 8) "; + return ret; } std::string CustomField::GetDataType() const { @@ -52,42 +48,11 @@ void CustomField::GenExtractor(std::ostream& s, Size start_offset, Size end_offs } void CustomField::GenGetter(std::ostream& s, Size start_offset, Size end_offset) const { - if (size_ != -1) { - s << GetDataType(); - } else { - s << "std::vector<" << GetDataType() << ">"; - } + s << "std::vector<" << GetDataType() << ">"; s << " Get" << util::UnderscoreToCamelCase(GetName()) << "() const {"; - s << "auto it = "; - if (!start_offset.empty()) { - // Default to start if available. - if (start_offset.bits() % 8 != 0) { - ERROR(this) << "Custom field must be byte aligned. start_offset.bits = " << start_offset.bits(); - } - s << "begin() + (" << start_offset << ") / 8;"; - } else if (size_ != -1) { - // If the size of the custom field is already known, we can determine it's offset based on end(). - if (!end_offset.empty()) { - if (end_offset.bits() % 8) { - ERROR(this) << "Custom field must be byte aligned. end_offset.bits = " << end_offset.bits(); - } - - s << "end() - (" << size_ << " + " << end_offset << ") / 8;"; - } else { - ERROR(this) << "Ambiguous offset for fixed size custom field."; - } - } else { - ERROR(this) << "Custom Field offset can not be determined from begin()."; - } - - if (size_ != -1) { - s << "return it.extract<" << GetDataType() << ">();"; - } else { - s << "std::vector<" << GetDataType() << "> to_return;"; - s << GetDataType() << "::Parse(to_return, it);"; - s << "return to_return;"; - } + GenExtractor(s, start_offset, end_offset); + s << "return vec;"; s << "}\n"; } @@ -105,11 +70,7 @@ void CustomField::GenParameterValidator(std::ostream&) const { } void CustomField::GenInserter(std::ostream& s) const { - if (size_ != -1) { - s << "insert(" << GetName() << "_, i);"; - } else { - s << GetName() << "_.Serialize(i);"; - } + s << GetName() << "_.Serialize(i);"; } void CustomField::GenValidator(std::ostream&) const { diff --git a/gd/packet/parser/fields/custom_field.h b/gd/packet/parser/fields/custom_field.h index d54db0a44..86fefd21f 100644 --- a/gd/packet/parser/fields/custom_field.h +++ b/gd/packet/parser/fields/custom_field.h @@ -21,7 +21,7 @@ class CustomField : public PacketField { public: - CustomField(std::string name, std::string type_name, int size, ParseLocation loc); + CustomField(std::string name, std::string type_name, ParseLocation loc); static const std::string kFieldType; @@ -49,7 +49,4 @@ class CustomField : public PacketField { private: std::string type_name_; - - public: - const int size_{-1}; }; diff --git a/gd/packet/parser/fields/custom_field_fixed_size.cc b/gd/packet/parser/fields/custom_field_fixed_size.cc new file mode 100644 index 000000000..08d3a0e30 --- /dev/null +++ b/gd/packet/parser/fields/custom_field_fixed_size.cc @@ -0,0 +1,59 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fields/custom_field_fixed_size.h" +#include "util.h" + +const std::string CustomFieldFixedSize::kFieldType = "CustomField"; + +CustomFieldFixedSize::CustomFieldFixedSize(std::string name, std::string type_name, int size, ParseLocation loc) + : ScalarField(name, size, loc), type_name_(type_name) {} + +const std::string& CustomFieldFixedSize::GetFieldType() const { + return CustomFieldFixedSize::kFieldType; +} + +std::string CustomFieldFixedSize::GetDataType() const { + return type_name_; +} + +void CustomFieldFixedSize::GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const { + int field_size = GetSize().bits(); + + if (!start_offset.empty()) { + // Default to start if available. + s << "auto it = begin_it + (" << start_offset << ") / 8;"; + } else if (!end_offset.empty()) { + Size byte_offset = Size(field_size) + end_offset; + s << "auto it = end_it - (" << byte_offset << ") / 8;"; + } else { + ERROR(this) << "Ambiguous offset for field."; + } + + s << GetDataType() << " value = it.extract<" << GetDataType() << ">();"; +} + +bool CustomFieldFixedSize::HasParameterValidator() const { + return false; +} + +void CustomFieldFixedSize::GenParameterValidator(std::ostream&) const { + // Do nothing. +} + +void CustomFieldFixedSize::GenValidator(std::ostream&) const { + // Do nothing. +} diff --git a/gd/packet/parser/fields/custom_field_fixed_size.h b/gd/packet/parser/fields/custom_field_fixed_size.h new file mode 100644 index 000000000..5a11c0d94 --- /dev/null +++ b/gd/packet/parser/fields/custom_field_fixed_size.h @@ -0,0 +1,41 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "fields/scalar_field.h" +#include "parse_location.h" + +class CustomFieldFixedSize : public ScalarField { + public: + CustomFieldFixedSize(std::string name, std::string type_name, int size, ParseLocation loc); + + static const std::string kFieldType; + + virtual const std::string& GetFieldType() const override; + + virtual std::string GetDataType() const override; + + virtual void GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const override; + + virtual bool HasParameterValidator() const override; + + virtual void GenParameterValidator(std::ostream&) const override; + + virtual void GenValidator(std::ostream&) const override; + + std::string type_name_; +}; -- 2.11.0