*/
#include "fields/array_field.h"
+
#include "util.h"
const std::string ArrayField::kFieldType = "ArrayField";
-ArrayField::ArrayField(std::string name, int element_size, int fixed_size, ParseLocation loc)
- : PacketField(name, loc), element_size_(element_size), fixed_size_(fixed_size) {
- if (element_size_ > 64 || element_size_ < 0)
- ERROR(this) << __func__ << ": Not implemented for element size = " << element_size_;
- // Make sure the element_size is a multiple of 8.
+ArrayField::ArrayField(std::string name, int element_size, int array_size, ParseLocation loc)
+ : PacketField(name, loc), element_field_(new ScalarField("val", element_size, loc)), element_size_(element_size),
+ array_size_(array_size) {
+ if (element_size > 64 || element_size < 0)
+ ERROR(this) << __func__ << ": Not implemented for element size = " << element_size;
if (element_size % 8 != 0) {
ERROR(this) << "Can only have arrays with elements that are byte aligned (" << element_size << ")";
}
}
-ArrayField::ArrayField(std::string name, TypeDef* type_def, int fixed_size, ParseLocation loc)
- : PacketField(name, loc), element_size_(type_def->size_), type_def_(type_def), fixed_size_(fixed_size) {
- // If the element type is not variable sized, make sure that it is byte aligned.
- if (type_def_->size_ != -1 && type_def_->size_ % 8 != 0) {
- ERROR(this) << "Can only have arrays with elements that are byte aligned (" << type_def_->size_ << ")";
+ArrayField::ArrayField(std::string name, TypeDef* type_def, int array_size, ParseLocation loc)
+ : PacketField(name, loc), element_field_(type_def->GetNewField("val", loc)),
+ element_size_(element_field_->GetSize()), array_size_(array_size) {
+ if (!element_size_.empty() && element_size_.bits() % 8 != 0) {
+ ERROR(this) << "Can only have arrays with elements that are byte aligned (" << element_size_ << ")";
}
}
}
Size ArrayField::GetSize() const {
- if (element_size_ != -1) {
- return Size(fixed_size_ * element_size_);
+ if (!element_size_.empty() && !element_size_.has_dynamic()) {
+ return Size(array_size_ * element_size_.bits());
}
return Size();
}
Size ArrayField::GetBuilderSize() const {
- if (element_size_ != -1) {
- std::string ret = "(" + std::to_string(fixed_size_) + " * " + std::to_string(element_size_) + ")";
- return ret;
+ if (!element_size_.empty() && !element_size_.has_dynamic()) {
+ return GetSize();
} else {
std::string ret = "[this](){ size_t length = 0; for (const auto& elem : " + GetName() +
"_) { length += elem.size() * 8; } return length; }()";
}
std::string ArrayField::GetDataType() const {
- if (type_def_ != nullptr) {
- return "std::array<" + type_def_->name_ + "," + std::to_string(fixed_size_) + ">";
- }
- return "std::array<" + util::GetTypeForSize(element_size_) + "," + std::to_string(fixed_size_) + ">";
+ return "std::array<" + element_field_->GetDataType() + "," + std::to_string(array_size_) + ">";
}
-void ArrayField::GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const {
- GenBounds(s, start_offset, end_offset, GetSize());
-
- s << "auto it = begin_it + field_begin;";
-
- s << GetDataType() << " value;";
- std::string type = (type_def_ != nullptr) ? type_def_->name_ : util::GetTypeForSize(element_size_);
- s << GetDataType() << "::iterator ret_it = value.begin();";
- if (element_size_ != -1) {
- s << "while (it + sizeof(" << type << ") <= begin_it + field_end && ret_it < value.end()) {";
- s << "*ret_it = it.extract<" << type << ">();";
+void ArrayField::GenExtractor(std::ostream& s, int num_leading_bits) const {
+ s << GetDataType() << "::iterator ret_it = " << GetName() << "_ptr->begin();";
+ s << "auto " << element_field_->GetName() << "_it = " << GetName() << "_it;";
+ if (!element_size_.empty() && !element_size_.has_dynamic()) {
+ s << "while (" << element_field_->GetName() << "_it.NumBytesRemaining() >= " << element_size_.bytes();
+ s << " && ret_it < " << GetName() << "_ptr->end()) {";
} else {
- s << "while (it < begin_it + field_end && ret_it < value.end()) {";
- s << "it = " << type_def_->name_ << "::Parse(ret_it, it);";
+ s << "while (" << element_field_->GetName() << "_it.NumBytesRemaining() > 0 ";
+ s << " && ret_it < " << GetName() << "_ptr->end()) {";
}
+ s << element_field_->GetDataType() << "* " << element_field_->GetName() << "_ptr = ret_it;";
+ element_field_->GenExtractor(s, num_leading_bits);
s << "ret_it++;";
s << "}";
}
s << " Get" << util::UnderscoreToCamelCase(GetName()) << "() {";
s << "ASSERT(was_validated_);";
s << "size_t end_index = size();";
- s << "auto begin_it = begin();";
+ s << "auto to_bound = begin();";
- GenExtractor(s, start_offset, end_offset);
+ int num_leading_bits = GenBounds(s, start_offset, end_offset);
+ s << GetDataType() << " " << GetName() << "_value;";
+ s << GetDataType() << "* " << GetName() << "_ptr = &" << GetName() << "_value;";
+ GenExtractor(s, num_leading_bits);
- s << "return value;";
+ s << "return " << GetName() << "_value;";
s << "}\n";
}
bool ArrayField::GenBuilderParameter(std::ostream& s) const {
- if (type_def_ != nullptr) {
- s << "const std::array<" << type_def_->GetTypeName() << "," << fixed_size_ << ">& " << GetName();
- } else {
- s << "const std::array<" << util::GetTypeForSize(element_size_) << "," << fixed_size_ << ">& " << GetName();
- }
+ s << "const std::array<" << element_field_->GetDataType() << "," << array_size_ << ">& " << GetName();
return true;
}
bool ArrayField::GenBuilderMember(std::ostream& s) const {
- if (type_def_ != nullptr) {
- s << "std::array<" << type_def_->GetTypeName() << "," << fixed_size_ << "> " << GetName();
- } else {
- s << "std::array<" << util::GetTypeForSize(element_size_) << "," << fixed_size_ << "> " << GetName();
- }
+ s << "std::array<" << element_field_->GetDataType() << "," << array_size_ << "> " << GetName();
return true;
}
}
void ArrayField::GenInserter(std::ostream& s) const {
- s << "for (const auto& val : " << GetName() << "_) {";
- if (IsEnumArray()) {
- s << "insert(static_cast<" << util::GetTypeForSize(type_def_->size_) << ">(val), i, " << type_def_->size_ << ");";
- } else if (IsCustomFieldArray()) {
- if (type_def_->size_ == -1) {
- s << "val.Serialize(i);";
- } else {
- s << "insert(val, i);";
- }
- } else if (IsStructArray()) {
- s << "val.Serialize(i);";
- } else {
- s << "insert(val, i, " << element_size_ << ");";
- }
+ s << "for (const auto& val_ : " << GetName() << "_) {";
+ element_field_->GenInserter(s);
s << "}\n";
}
// Other than that there is nothing that arrays need to be validated on other than length so nothing needs to
// be done here.
}
-
-bool ArrayField::IsEnumArray() const {
- return type_def_ != nullptr && type_def_->GetDefinitionType() == TypeDef::Type::ENUM;
-}
-
-bool ArrayField::IsCustomFieldArray() const {
- return type_def_ != nullptr && type_def_->GetDefinitionType() == TypeDef::Type::CUSTOM;
-}
-
-bool ArrayField::IsStructArray() const {
- return type_def_ != nullptr && type_def_->GetDefinitionType() == TypeDef::Type::STRUCT;
-}
#pragma once
-#include "custom_field_def.h"
-#include "enum_def.h"
-#include "fields/count_field.h"
-#include "fields/packet_field.h"
-#include "fields/size_field.h"
+#include "fields/all_fields.h"
#include "parse_location.h"
+#include "type_def.h"
class ArrayField : public PacketField {
public:
virtual std::string GetDataType() const override;
- virtual void GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const override;
+ virtual void GenExtractor(std::ostream& s, int num_leading_bits) const override;
virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const override;
virtual void GenValidator(std::ostream&) const override;
- bool IsEnumArray() const;
-
- bool IsCustomFieldArray() const;
-
- bool IsStructArray() const;
-
const std::string name_;
- const int element_size_{-1}; // in bits
- const TypeDef* type_def_{nullptr};
+ const PacketField* element_field_{nullptr};
+
+ const Size element_size_{};
- // Fixed size array or dynamic size, size is always in bytes, unless it is count.
- const int fixed_size_{-1};
+ const int array_size_{-1};
};
return "BodyType";
}
-void BodyField::GenExtractor(std::ostream&, Size, Size) const {}
+void BodyField::GenExtractor(std::ostream&, int) const {}
void BodyField::GenGetter(std::ostream&, Size, Size) const {}
virtual std::string GetDataType() const override;
- virtual void GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const override;
+ virtual void GenExtractor(std::ostream& s, int num_leading_bits) const override;
virtual void GenGetter(std::ostream&, Size, Size) const override;
return type_name_;
}
-void ChecksumField::GenExtractor(std::ostream&, Size, Size) const {}
+void ChecksumField::GenExtractor(std::ostream&, int) const {}
void ChecksumField::GenGetter(std::ostream&, Size, Size) const {}
virtual std::string GetDataType() const override;
- virtual void GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const override;
+ virtual void GenExtractor(std::ostream& s, int) const override;
virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const override;
return "There's no type for Checksum Start fields";
}
-void ChecksumStartField::GenExtractor(std::ostream&, Size, Size) const {}
+void ChecksumStartField::GenExtractor(std::ostream&, int) const {}
void ChecksumStartField::GenGetter(std::ostream&, Size, Size) const {}
virtual std::string GetDataType() const override;
- virtual void GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const override;
+ virtual void GenExtractor(std::ostream& s, int num_leading_bits) const override;
virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const override;
return type_name_;
}
-void CustomField::GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const {
- GenBounds(s, start_offset, end_offset, Size());
- s << "auto it = begin_it.Subrange(field_begin, field_end - field_begin);";
- s << "std::unique_ptr<" << GetDataType() << "> ptr = std::make_unique<" << GetDataType() << ">();";
- s << GetDataType() << "::Parse(ptr.get(), it);";
+void CustomField::GenExtractor(std::ostream& s, int) const {
+ s << GetName() << "_it = ";
+ s << GetDataType() << "::Parse( " << GetName() << "_ptr, " << GetName() << "_it);";
}
void CustomField::GenGetter(std::ostream& s, Size start_offset, Size end_offset) const {
s << "std::unique_ptr<" << GetDataType() << "> Get" << util::UnderscoreToCamelCase(GetName()) << "() const {";
s << "ASSERT(was_validated_);";
s << "size_t end_index = size();";
- s << "auto begin_it = begin();";
+ s << "auto to_bound = begin();";
- GenExtractor(s, start_offset, end_offset);
- s << "return ptr;";
+ int num_leading_bits = GenBounds(s, start_offset, end_offset);
+ s << "std::unique_ptr<" << GetDataType() << "> " << GetName() << "_value";
+ s << " = std::make_unique<" << GetDataType() << ">();";
+ s << GetDataType() << "* " << GetName() << "_ptr = " << GetName() << "_value.get();";
+ GenExtractor(s, num_leading_bits);
+ s << "return " << GetName() << "_value;";
s << "}\n";
}
virtual std::string GetDataType() const override;
- virtual void GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const override;
+ virtual void GenExtractor(std::ostream& s, int num_leading_bits) const override;
virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const override;
return type_name_;
}
-void CustomFieldFixedSize::GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const {
- int field_size = GetSize().bits();
-
+int CustomFieldFixedSize::GenBounds(std::ostream& s, Size start_offset, Size end_offset) const {
if (!start_offset.empty()) {
// Default to start if available.
- s << "auto it = begin_it + (" << start_offset << ") / 8;";
+ s << "auto " << GetName() << "_it = to_bound + (" << start_offset << ") / 8;";
} else if (!end_offset.empty()) {
- Size byte_offset = Size(field_size) + end_offset;
- s << "auto it = end_it - (" << byte_offset << ") / 8;";
+ Size byte_offset = GetSize() + end_offset;
+ s << "auto " << GetName() << "_it = to_bound (+ to_bound.NumBytesRemaining() - (" << byte_offset << ") / 8);";
} else {
ERROR(this) << "Ambiguous offset for field.";
}
+ return 0; // num_leading_bits
+}
- s << GetDataType() << " value = it.extract<" << GetDataType() << ">();";
+void CustomFieldFixedSize::GenExtractor(std::ostream& s, int) const {
+ s << "*" << GetName() << "_ptr = " << GetName() << "_it.extract<" << GetDataType() << ">();";
}
bool CustomFieldFixedSize::HasParameterValidator() const {
virtual std::string GetDataType() const override;
- virtual void GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const override;
+ virtual int GenBounds(std::ostream& s, Size start_offset, Size end_offset) const override;
+
+ virtual void GenExtractor(std::ostream& s, int num_leading_bits) const override;
virtual bool HasParameterValidator() const override;
return "";
}
-void GroupField::GenExtractor(std::ostream&, Size, Size) const {
+void GroupField::GenExtractor(std::ostream&, int) const {
ERROR(this) << "GenExtractor should never be called.";
}
virtual std::string GetDataType() const override;
- virtual void GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const override;
+ virtual void GenExtractor(std::ostream& s, int num_leading_bits) const override;
virtual void GenGetter(std::ostream&, Size, Size) const override;
return GetSize();
}
-void PacketField::GenBounds(std::ostream& s, Size start_offset, Size end_offset, Size field_size) const {
+int PacketField::GenBounds(std::ostream& s, Size start_offset, Size end_offset) const {
// In order to find field_begin and field_end, we must have two of the three Sizes.
- if ((start_offset.empty() && field_size.empty()) || (start_offset.empty() && end_offset.empty()) ||
- (end_offset.empty() && field_size.empty())) {
- ERROR(this) << "GenBounds called without enough information. " << start_offset << end_offset << field_size;
+ if ((start_offset.empty() && GetSize().empty()) || (start_offset.empty() && end_offset.empty()) ||
+ (end_offset.empty() && GetSize().empty())) {
+ ERROR(this) << "GenBounds called without enough information. " << start_offset << end_offset << GetSize();
}
if (start_offset.bits() % 8 != 0 || end_offset.bits() % 8 != 0) {
if (!start_offset.empty()) {
s << "size_t field_begin = (" << start_offset << ") / 8;";
} else {
- s << "size_t field_begin = end_index - (" << end_offset << " + " << field_size << ") / 8;";
+ s << "size_t field_begin = end_index - (" << end_offset << " + " << GetSize() << ") / 8;";
}
if (!end_offset.empty()) {
s << "size_t field_end = end_index - (" << end_offset << ") / 8;";
// If the field has a known size, use the minimum for the end
- if (!field_size.empty()) {
- s << "size_t field_sized_end = field_begin + (" << field_size << ") / 8;";
+ if (!GetSize().empty()) {
+ s << "size_t field_sized_end = field_begin + (" << GetSize() << ") / 8;";
s << "if (field_sized_end < field_end) { field_end = field_sized_end; }";
}
} else {
- s << "size_t field_end = field_begin + (" << field_size << ") / 8;";
+ s << "size_t field_end = field_begin + (" << GetSize() << ") / 8;";
s << "if (field_end > end_index) { field_end = end_index; }";
}
+ s << "auto " << name_ << "_it = to_bound.Subrange(field_begin, field_end - field_begin); ";
+ return 0; // num_leading_bits
}
bool PacketField::GenBuilderMember(std::ostream& s) const {
// variables.
virtual std::string GetDataType() const = 0;
- // Given an iterator it, extract the type.
- virtual void GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const = 0;
+ // Given an iterator {name}_it, extract the type.
+ virtual void GenExtractor(std::ostream& s, int num_leading_bits) const = 0;
- // Calculate field_begin and field_end using the given offsets and size.
- virtual void GenBounds(std::ostream& s, Size start_offset, Size end_offset, Size field_size) const;
+ // Calculate field_begin and field_end using the given offsets and size, return the number of leading bits
+ virtual int GenBounds(std::ostream& s, Size start_offset, Size end_offset) const;
// Get parser getter definition. Start_offset points to the first bit of the
// field. end_offset is the first bit after the field. If an offset is empty
return "PacketView";
}
-void PayloadField::GenExtractor(std::ostream&, Size, Size) const {
+void PayloadField::GenExtractor(std::ostream&, int) const {
ERROR(this) << __func__ << " should never be called. ";
}
s << "PacketView<kLittleEndian> GetPayload() const {";
s << "ASSERT(was_validated_);";
s << "size_t end_index = size();";
- GenBounds(s, start_offset, end_offset, GetSize());
+ s << "auto to_bound = begin();";
+ GenBounds(s, start_offset, end_offset);
s << "return GetLittleEndianSubview(field_begin, field_end);";
s << "}\n\n";
s << "PacketView<!kLittleEndian> GetPayloadBigEndian() const {";
s << "ASSERT(was_validated_);";
s << "size_t end_index = size();";
- GenBounds(s, start_offset, end_offset, GetSize());
+ s << "auto to_bound = begin();";
+ GenBounds(s, start_offset, end_offset);
s << "return GetBigEndianSubview(field_begin, field_end);";
s << "}\n";
}
virtual std::string GetDataType() const override;
- virtual void GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const override;
+ virtual void GenExtractor(std::ostream& s, int num_leading_bits) const override;
virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const override;
return util::GetTypeForSize(size_);
}
-void ReservedField::GenExtractor(std::ostream&, Size, Size) const {}
+void ReservedField::GenExtractor(std::ostream&, int) const {}
void ReservedField::GenGetter(std::ostream&, Size, Size) const {
// There is no Getter for a reserved field
virtual std::string GetDataType() const override;
- virtual void GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const override;
+ virtual void GenExtractor(std::ostream& s, int num_leading_bits) const override;
virtual void GenGetter(std::ostream&, Size, Size) const override;
}
}
-void ScalarField::GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const {
+int ScalarField::GenBounds(std::ostream& s, Size start_offset, Size end_offset) const {
int num_leading_bits = 0;
- int field_size = GetSize().bits();
if (!start_offset.empty()) {
// Default to start if available.
num_leading_bits = start_offset.bits() % 8;
- s << "auto it = begin_it + (" << start_offset << ") / 8;";
+ s << "auto " << GetName() << "_it = to_bound + (" << start_offset << ") / 8;";
} else if (!end_offset.empty()) {
- num_leading_bits = GetShiftBits(end_offset.bits() + field_size);
- Size byte_offset = Size(num_leading_bits + field_size) + end_offset;
- s << "auto it = end_it - (" << byte_offset << ") / 8;";
+ num_leading_bits = GetShiftBits(end_offset.bits() + GetSize().bits());
+ Size byte_offset = Size(num_leading_bits + GetSize().bits()) + end_offset;
+ s << "auto " << GetName() << "_it = to_bound + (to_bound.NumBytesRemaining() - (" << byte_offset << ") / 8);";
} else {
ERROR(this) << "Ambiguous offset for field.";
}
+ return num_leading_bits;
+}
+void ScalarField::GenExtractor(std::ostream& s, int num_leading_bits) const {
// Extract the correct number of bytes. The return type could be different
// from the extract type if an earlier field causes the beginning of the
// current field to start in the middle of a byte.
- std::string extract_type = util::GetTypeForSize(field_size + num_leading_bits);
- s << "auto extracted_value = it.extract<" << extract_type << ">();";
+ std::string extract_type = util::GetTypeForSize(GetSize().bits() + num_leading_bits);
+ s << "auto extracted_value = " << GetName() << "_it.extract<" << extract_type << ">();";
// Right shift the result to remove leading bits.
if (num_leading_bits != 0) {
s << "extracted_value >>= " << num_leading_bits << ";";
}
-
// Mask the result if necessary.
- if (util::RoundSizeUp(field_size) != field_size) {
+ if (util::RoundSizeUp(GetSize().bits()) != GetSize().bits()) {
uint64_t mask = 0;
- for (int i = 0; i < field_size; i++) {
+ for (int i = 0; i < GetSize().bits(); i++) {
mask <<= 1;
mask |= 1;
}
s << "extracted_value &= 0x" << std::hex << mask << std::dec << ";";
}
- s << GetDataType() << " value = static_cast<" << GetDataType() << ">(extracted_value);";
+ s << "*" << GetName() << "_ptr = static_cast<" << GetDataType() << ">(extracted_value);";
}
void ScalarField::GenGetter(std::ostream& s, Size start_offset, Size end_offset) const {
s << GetDataType();
s << " Get" << util::UnderscoreToCamelCase(GetName()) << "() const {";
s << "ASSERT(was_validated_);";
-
- if (!start_offset.empty()) {
- s << "auto begin_it = begin();";
- } else {
- s << "auto end_it = end();";
- }
- GenExtractor(s, start_offset, end_offset);
- s << "\n";
- s << "return value;";
+ s << "auto to_bound = begin();";
+ int num_leading_bits = GenBounds(s, start_offset, end_offset);
+ s << GetDataType() << " " << GetName() << "_value;";
+ s << GetDataType() << "* " << GetName() << "_ptr = &" << GetName() << "_value;";
+ GenExtractor(s, num_leading_bits);
+ s << "return " << GetName() << "_value;";
s << "}";
}
virtual std::string GetDataType() const override;
- virtual void GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const override;
+ virtual int GenBounds(std::ostream& s, Size start_offset, Size end_offset) const override;
+
+ virtual void GenExtractor(std::ostream& s, int num_leading_bits) const override;
virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const override;
virtual void GenValidator(std::ostream&) const override;
private:
- int size_;
+ const int size_;
};
return size_;
}
-Size StructField::GetBuilderSize() const {
- if (size_ != -1) {
- return size_;
- } else {
- std::string ret = "(" + GetName() + "_.size() * 8) ";
- return ret;
- }
-}
-
std::string StructField::GetDataType() const {
return type_name_;
}
-void StructField::GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const {
- if (size_ != -1) {
- GenBounds(s, start_offset, end_offset, Size(size_));
- } else {
- GenBounds(s, start_offset, end_offset, Size());
- }
- s << "auto it = begin_it.Subrange(field_begin, field_end - field_begin); ";
- s << "std::unique_ptr<" << GetDataType() << "> one = std::make_unique<" << GetDataType() << ">();";
- s << GetDataType() << "::Parse(one.get(), it);";
+void StructField::GenExtractor(std::ostream& s, int) const {
+ s << GetName() << "_it = ";
+ s << GetDataType() << "::Parse(" << GetName() << "_ptr, " << GetName() << "_it);";
}
void StructField::GenGetter(std::ostream& s, Size start_offset, Size end_offset) const {
- if (size_ != -1) {
- s << GetDataType() << " Get" << util::UnderscoreToCamelCase(GetName()) << "() const {";
- } else {
- s << "std::unique_ptr<" << GetDataType() << "> Get" << util::UnderscoreToCamelCase(GetName()) << "() const {";
- }
+ s << GetDataType() << " Get" << util::UnderscoreToCamelCase(GetName()) << "() const {";
s << "ASSERT(was_validated_);";
s << "size_t end_index = size();";
- s << "auto begin_it = begin();";
- GenExtractor(s, start_offset, end_offset);
+ s << "auto to_bound = begin();";
+ int num_leading_bits = GenBounds(s, start_offset, end_offset);
+ s << GetDataType() << " " << GetName() << "_value;";
+ s << GetDataType() << "* " << GetName() << "_ptr = &" << GetName() << "_value;";
+ GenExtractor(s, num_leading_bits);
- if (size_ != -1) {
- s << "return *one;";
- } else {
- s << "return one;";
- }
+ s << "return " << GetName() << "_value;";
s << "}\n";
}
virtual Size GetSize() const override;
- virtual Size GetBuilderSize() const override;
-
virtual std::string GetDataType() const override;
- virtual void GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const override;
+ virtual void GenExtractor(std::ostream& s, int num_leading_bits) const override;
virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const override;
std::string type_name_;
public:
- const int size_{-1};
+ const Size size_{};
};
*/
#include "fields/vector_field.h"
+
+#include "fields/count_field.h"
#include "util.h"
const std::string VectorField::kFieldType = "VectorField";
VectorField::VectorField(std::string name, int element_size, std::string size_modifier, ParseLocation loc)
- : PacketField(name, loc), element_size_(element_size), size_modifier_(size_modifier) {
- if (element_size_ > 64 || element_size_ < 0)
- ERROR(this) << __func__ << ": Not implemented for element size = " << element_size_;
- // Make sure the element_size is a multiple of 8.
+ : PacketField(name, loc), element_field_(new ScalarField("val", element_size, loc)), element_size_(element_size),
+ size_modifier_(size_modifier) {
+ if (element_size > 64 || element_size < 0)
+ ERROR(this) << __func__ << ": Not implemented for element size = " << element_size;
if (element_size % 8 != 0) {
ERROR(this) << "Can only have arrays with elements that are byte aligned (" << element_size << ")";
}
}
VectorField::VectorField(std::string name, TypeDef* type_def, std::string size_modifier, ParseLocation loc)
- : PacketField(name, loc), element_size_(type_def->size_), type_def_(type_def), size_modifier_(size_modifier) {
- // If the element type is not variable sized, make sure that it is byte aligned.
- if (type_def_->size_ != -1 && type_def_->size_ % 8 != 0) {
- ERROR(this) << "Can only have arrays with elements that are byte aligned (" << type_def_->size_ << ")";
+ : PacketField(name, loc), element_field_(type_def->GetNewField("val", loc)),
+ element_size_(element_field_->GetSize()), size_modifier_(size_modifier) {
+ if (!element_size_.empty() && element_size_.bits() % 8 != 0) {
+ ERROR(this) << "Can only have arrays with elements that are byte aligned (" << element_size_ << ")";
}
}
return ret;
}
- // size_field_ is of type COUNT and it is a scalar array
- if (type_def_ == nullptr) {
- return "(Get" + util::UnderscoreToCamelCase(size_field_->GetName()) + "() * " + std::to_string(element_size_) + ")";
- }
-
- if (IsCustomFieldArray() || IsStructArray()) {
- if (type_def_->size_ != -1) {
- return "(Get" + util::UnderscoreToCamelCase(size_field_->GetName()) + "() * " + std::to_string(type_def_->size_) +
- ")";
- } else {
- return Size();
- }
+ // size_field_ is of type COUNT and elements have a fixed size
+ if (!element_size_.empty() && !element_size_.has_dynamic()) {
+ return "(Get" + util::UnderscoreToCamelCase(size_field_->GetName()) + "() * " +
+ std::to_string(element_size_.bits()) + ")";
}
- // size_field_ is of type COUNT and it is an enum array
- return "(Get" + util::UnderscoreToCamelCase(size_field_->GetName()) + "() * " + std::to_string(type_def_->size_) +
- ")";
+ return Size();
}
Size VectorField::GetBuilderSize() const {
- if (element_size_ != -1) {
- std::string ret = "(" + GetName() + "_.size() * " + std::to_string(element_size_) + ")";
+ if (!element_size_.empty() && !element_size_.has_dynamic()) {
+ std::string ret = "(" + GetName() + "_.size() * " + std::to_string(element_size_.bits()) + ")";
return ret;
} else {
std::string ret = "[this](){ size_t length = 0; for (const auto& elem : " + GetName() +
}
std::string VectorField::GetDataType() const {
- if (type_def_ != nullptr) {
- return "std::vector<" + type_def_->name_ + ">";
- }
- return "std::vector<" + util::GetTypeForSize(element_size_) + ">";
+ return "std::vector<" + element_field_->GetDataType() + ">";
}
-void VectorField::GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const {
- GenBounds(s, start_offset, end_offset, GetSize());
-
- s << "auto it = begin_it.Subrange(field_begin, field_end - field_begin);";
-
- s << GetDataType() << " ret;";
- if (element_size_ != -1) {
- std::string type = (type_def_ != nullptr) ? type_def_->name_ : util::GetTypeForSize(element_size_);
- s << "while (it.NumBytesRemaining() >= sizeof(" << type << ")) {";
- s << "ret.push_back(it.extract<" << type << ">());";
- s << "}";
+void VectorField::GenExtractor(std::ostream& s, int num_leading_bits) const {
+ s << "auto " << element_field_->GetName() << "_it = " << GetName() << "_it;";
+ if (!element_size_.empty() && !element_size_.has_dynamic()) {
+ s << "while (" << element_field_->GetName() << "_it.NumBytesRemaining() >= " << element_size_.bytes() << ") {";
} else {
- s << "while (it.NumBytesRemaining() > 0) {";
- s << type_def_->name_ << " instance;";
- s << "it = " << type_def_->name_ << "::Parse(&instance, it);";
- s << "ret.push_back(instance);";
- s << "}";
+ s << "while (" << element_field_->GetName() << "_it.NumBytesRemaining() > 0) {";
}
+ s << element_field_->GetDataType() << " " << element_field_->GetName() << "_value;";
+ s << element_field_->GetDataType() << "* " << element_field_->GetName() << "_ptr = &" << element_field_->GetName()
+ << "_value;";
+ element_field_->GenExtractor(s, num_leading_bits);
+ s << GetName() << "_ptr->push_back(" << element_field_->GetName() << "_value);";
+ s << "}";
}
void VectorField::GenGetter(std::ostream& s, Size start_offset, Size end_offset) const {
s << " Get" << util::UnderscoreToCamelCase(GetName()) << "() {";
s << "ASSERT(was_validated_);";
s << "size_t end_index = size();";
- s << "auto begin_it = begin();";
+ s << "auto to_bound = begin();";
- GenExtractor(s, start_offset, end_offset);
+ int num_leading_bits = GenBounds(s, start_offset, end_offset);
+ s << GetDataType() << " " << GetName() << "_value;";
+ s << GetDataType() << "* " << GetName() << "_ptr = &" << GetName() << "_value;";
+ GenExtractor(s, num_leading_bits);
- s << "return ret;";
+ s << "return " << GetName() << "_value;";
s << "}\n";
}
bool VectorField::GenBuilderParameter(std::ostream& s) const {
- if (type_def_ != nullptr) {
- s << "const std::vector<" << type_def_->GetTypeName() << ">& " << GetName();
- } else {
- s << "const std::vector<" << util::GetTypeForSize(element_size_) << ">& " << GetName();
- }
+ s << "const std::vector<" << element_field_->GetDataType() << ">& " << GetName();
return true;
}
bool VectorField::GenBuilderMember(std::ostream& s) const {
- if (type_def_ != nullptr) {
- s << "const std::vector<" << type_def_->GetTypeName() << "> " << GetName();
- } else {
- s << "const std::vector<" << util::GetTypeForSize(element_size_) << "> " << GetName();
- }
+ s << "const std::vector<" << element_field_->GetDataType() << "> " << GetName();
return true;
}
}
void VectorField::GenInserter(std::ostream& s) const {
- s << "for (const auto& val : " << GetName() << "_) {";
- if (IsEnumArray()) {
- s << "insert(static_cast<" << util::GetTypeForSize(type_def_->size_) << ">(val), i, " << type_def_->size_ << ");";
- } else if (IsCustomFieldArray()) {
- if (type_def_->size_ == -1) {
- s << "val.Serialize(i);";
- } else {
- s << "insert(val, i);";
- }
- } else if (IsStructArray()) {
- s << "val.Serialize(i);";
- } else {
- s << "insert(val, i, " << element_size_ << ");";
- }
+ s << "for (const auto& val_ : " << GetName() << "_) {";
+ element_field_->GenInserter(s);
s << "}\n";
}
// be done here.
}
-bool VectorField::IsEnumArray() const {
- return type_def_ != nullptr && type_def_->GetDefinitionType() == TypeDef::Type::ENUM;
-}
-
-bool VectorField::IsCustomFieldArray() const {
- return type_def_ != nullptr && type_def_->GetDefinitionType() == TypeDef::Type::CUSTOM;
-}
-
-bool VectorField::IsStructArray() const {
- return type_def_ != nullptr && type_def_->GetDefinitionType() == TypeDef::Type::STRUCT;
-}
-
void VectorField::SetSizeField(const SizeField* size_field) {
if (size_field->GetFieldType() == CountField::kFieldType && !size_modifier_.empty()) {
ERROR(this, size_field) << "Can not use count field to describe array with a size modifier."
#pragma once
-#include "custom_field_def.h"
-#include "enum_def.h"
-#include "fields/count_field.h"
#include "fields/packet_field.h"
#include "fields/size_field.h"
#include "parse_location.h"
+#include "type_def.h"
class VectorField : public PacketField {
public:
virtual std::string GetDataType() const override;
- virtual void GenExtractor(std::ostream& s, Size start_offset, Size end_offset) const override;
+ virtual void GenExtractor(std::ostream& s, int num_leading_bits) const override;
virtual void GenGetter(std::ostream& s, Size start_offset, Size end_offset) const override;
virtual void GenValidator(std::ostream&) const override;
- bool IsEnumArray() const;
-
- bool IsCustomFieldArray() const;
-
- bool IsStructArray() const;
-
void SetSizeField(const SizeField* size_field);
const std::string& GetSizeModifier() const;
const std::string name_;
- const int element_size_{-1}; // in bits
- const TypeDef* type_def_{nullptr};
+ const PacketField* element_field_{nullptr};
+
+ const Size element_size_{};
// Fixed size array or dynamic size, size is always in bytes, unless it is count.
const SizeField* size_field_{nullptr};
const auto& vector_name = field_name + "_";
const VectorField* vector = (VectorField*)sized_field;
s << "size_t " << vector_name + "bytes = 0;";
- if (vector->element_size_ == -1) {
+ if (vector->element_size_.empty()) {
s << "for (auto elem : " << vector_name << ") {";
s << vector_name + "bytes += elem.size(); }";
} else {
s << vector_name + "bytes = ";
- s << vector_name << ".size() * (" << vector->element_size_ << " / 8);";
+ s << vector_name << ".size() * ((" << vector->element_size_ << ") / 8);";
}
s << "ASSERT(" << vector_name + "bytes < (1 << " << field->GetSize().bits() << "));";
s << "insert(" << vector_name << "bytes";
iterator = "Iterator<!kLittleEndian>";
}
s << "static " << iterator << " Parse(" << name_ << "* to_return, " << iterator << " struct_it) {";
- s << "auto begin_it = struct_it;";
+ s << "auto to_bound = struct_it;";
s << "size_t end_index = struct_it.NumBytesRemaining();";
s << "if (end_index < " << GetSize().bytes() << ") { return struct_it.Subrange(0,0);}";
Size field_offset = Size(0);
field->GetFieldType() != ChecksumStartField::kFieldType && field->GetFieldType() != ChecksumField::kFieldType &&
field->GetFieldType() != CountField::kFieldType) {
s << "{";
- field->GenExtractor(s, field_offset, next_field_offset);
- s << "to_return->" << field->GetName() << "_ = value;";
+ int num_leading_bits = field->GenBounds(s, field_offset, next_field_offset);
+ s << "auto " << field->GetName() << "_ptr = &to_return->" << field->GetName() << "_;";
+ field->GenExtractor(s, num_leading_bits);
s << "}";
}
field_offset = next_field_offset;