Loading tools/pdl/doc/reference.md +5 −3 Original line number Diff line number Diff line Loading @@ -563,11 +563,13 @@ packet CRCedBrew { > padding_field:\ > `_padding_` `[` [INTEGER](#integer) `]` A *\_padding\_* field adds a number of **octet** of padding. A *\_padding\_* field immediately following an array field pads the array field with `0`s to the specified number of **octets**. ``` packet Padded { _padding_[1] // 1 octet/8bit of padding packet PaddedCoffee { additions: CoffeeAddition[], _padding_[100] } ``` Loading tools/pdl/scripts/generate_python_backend.py +19 −1 Original line number Diff line number Diff line Loading @@ -177,6 +177,8 @@ class FieldParser: """Parse the selected array field.""" array_size = core.get_array_field_size(field) element_width = core.get_array_element_size(field) padded_size = field.padded_size if element_width: if element_width % 8 != 0: raise Exception('Array element size is not a multiple of 8') Loading @@ -202,6 +204,12 @@ class FieldParser: if field.size_modifier and size: self.append_(f"{size} = {size} - {field.size_modifier}") # Parse from the padded array if padding is present. if padded_size: self.check_size_(padded_size) self.append_(f"remaining_span = span[{padded_size}:]") self.append_(f"span = span[:{padded_size}]") # The element width is not known, but the array full octet size # is known by size field. Parse elements item by item as a vector. if element_width is None and size is not None: Loading Loading @@ -263,6 +271,10 @@ class FieldParser: if size is not None: self.append_(f"span = span[{size}:]") # Drop the padding if padded_size: self.append_(f"span = remaining_span") def parse_bit_field_(self, field: ast.Field): """Parse the selected field as a bit field. The field is added to the current chunk. When a byte boundary Loading Loading @@ -346,7 +358,7 @@ class FieldParser: if self.shift != 0: raise Exception('Padding field does not start on an octet boundary') self.offset += field.width self.offset += field.size def parse_payload_field_(self, field: Union[ast.BodyField, ast.PayloadField]): """Parse body and payload fields.""" Loading Loading @@ -535,6 +547,9 @@ class FieldSerializer: def serialize_array_field_(self, field: ast.ArrayField): """Serialize the selected array field.""" if field.padded_size: self.append_(f"_{field.id}_start = len(_span)") if field.width == 8: self.append_(f"_span.extend(self.{field.id})") else: Loading @@ -543,6 +558,9 @@ class FieldSerializer: self.serialize_array_element_(field) self.unindent_() if field.padded_size: self.append_(f"_span.extend([0] * ({field.padded_size} - len(_span) + _{field.id}_start))") def serialize_bit_field_(self, field: ast.Field): """Serialize the selected field as a bit field. The field is added to the current chunk. When a byte boundary Loading tools/pdl/scripts/pdl/ast.py +2 −1 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ class ChecksumField(Field): @node('padding_field') class PaddingField(Field): width: int size: int @node('size_field') Loading Loading @@ -109,6 +109,7 @@ class ArrayField(Field): type_id: Optional[str] size_modifier: Optional[str] size: Optional[int] padded_size: Optional[int] = field(init=False, default=None) @property def type(self) -> Optional['Declaration']: Loading tools/pdl/scripts/pdl/core.py +8 −3 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ from typing import Optional, List, Dict, Union, Tuple from .ast import * def desugar_field_(field: Field, constraints: Dict[str, Constraint]) -> List[Field]: def desugar_field_(field: Field, previous: Field, constraints: Dict[str, Constraint]) -> List[Field]: """Inline group and constrained fields. Constrained fields are transformed into fixed fields. Group fields are inlined and recursively desugared.""" Loading @@ -13,6 +13,10 @@ def desugar_field_(field: Field, constraints: Dict[str, Constraint]) -> List[Fie fixed.parent = field.parent return [fixed] elif isinstance(field, PaddingField): previous.padded_size = field.size return [] elif isinstance(field, TypedefField) and field.id in constraints: tag_id = constraints[field.id].tag_id fixed = FixedField(kind='fixed_field', loc=field.loc, enum_id=field.type_id, tag_id=tag_id) Loading @@ -24,7 +28,8 @@ def desugar_field_(field: Field, constraints: Dict[str, Constraint]) -> List[Fie constraints = dict([(c.id, c) for c in field.constraints]) fields = [] for f in group.fields: fields.extend(desugar_field_(f, constraints)) fields.extend(desugar_field_(f, previous, constraints)) previous = f return fields else: Loading @@ -45,7 +50,7 @@ def desugar(file: File): if isinstance(d, (PacketDeclaration, StructDeclaration)): fields = [] for f in d.fields: fields.extend(desugar_field_(f, {})) fields.extend(desugar_field_(f, fields[-1] if len(fields) > 0 else None, {})) d.fields = fields declarations.append(d) Loading tools/pdl/src/ast.rs +1 −1 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ pub enum Field { #[serde(rename = "checksum_field")] Checksum { loc: SourceRange, field_id: String }, #[serde(rename = "padding_field")] Padding { loc: SourceRange, width: usize }, Padding { loc: SourceRange, size: usize }, #[serde(rename = "size_field")] Size { loc: SourceRange, field_id: String, width: usize }, #[serde(rename = "count_field")] Loading Loading
tools/pdl/doc/reference.md +5 −3 Original line number Diff line number Diff line Loading @@ -563,11 +563,13 @@ packet CRCedBrew { > padding_field:\ > `_padding_` `[` [INTEGER](#integer) `]` A *\_padding\_* field adds a number of **octet** of padding. A *\_padding\_* field immediately following an array field pads the array field with `0`s to the specified number of **octets**. ``` packet Padded { _padding_[1] // 1 octet/8bit of padding packet PaddedCoffee { additions: CoffeeAddition[], _padding_[100] } ``` Loading
tools/pdl/scripts/generate_python_backend.py +19 −1 Original line number Diff line number Diff line Loading @@ -177,6 +177,8 @@ class FieldParser: """Parse the selected array field.""" array_size = core.get_array_field_size(field) element_width = core.get_array_element_size(field) padded_size = field.padded_size if element_width: if element_width % 8 != 0: raise Exception('Array element size is not a multiple of 8') Loading @@ -202,6 +204,12 @@ class FieldParser: if field.size_modifier and size: self.append_(f"{size} = {size} - {field.size_modifier}") # Parse from the padded array if padding is present. if padded_size: self.check_size_(padded_size) self.append_(f"remaining_span = span[{padded_size}:]") self.append_(f"span = span[:{padded_size}]") # The element width is not known, but the array full octet size # is known by size field. Parse elements item by item as a vector. if element_width is None and size is not None: Loading Loading @@ -263,6 +271,10 @@ class FieldParser: if size is not None: self.append_(f"span = span[{size}:]") # Drop the padding if padded_size: self.append_(f"span = remaining_span") def parse_bit_field_(self, field: ast.Field): """Parse the selected field as a bit field. The field is added to the current chunk. When a byte boundary Loading Loading @@ -346,7 +358,7 @@ class FieldParser: if self.shift != 0: raise Exception('Padding field does not start on an octet boundary') self.offset += field.width self.offset += field.size def parse_payload_field_(self, field: Union[ast.BodyField, ast.PayloadField]): """Parse body and payload fields.""" Loading Loading @@ -535,6 +547,9 @@ class FieldSerializer: def serialize_array_field_(self, field: ast.ArrayField): """Serialize the selected array field.""" if field.padded_size: self.append_(f"_{field.id}_start = len(_span)") if field.width == 8: self.append_(f"_span.extend(self.{field.id})") else: Loading @@ -543,6 +558,9 @@ class FieldSerializer: self.serialize_array_element_(field) self.unindent_() if field.padded_size: self.append_(f"_span.extend([0] * ({field.padded_size} - len(_span) + _{field.id}_start))") def serialize_bit_field_(self, field: ast.Field): """Serialize the selected field as a bit field. The field is added to the current chunk. When a byte boundary Loading
tools/pdl/scripts/pdl/ast.py +2 −1 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ class ChecksumField(Field): @node('padding_field') class PaddingField(Field): width: int size: int @node('size_field') Loading Loading @@ -109,6 +109,7 @@ class ArrayField(Field): type_id: Optional[str] size_modifier: Optional[str] size: Optional[int] padded_size: Optional[int] = field(init=False, default=None) @property def type(self) -> Optional['Declaration']: Loading
tools/pdl/scripts/pdl/core.py +8 −3 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ from typing import Optional, List, Dict, Union, Tuple from .ast import * def desugar_field_(field: Field, constraints: Dict[str, Constraint]) -> List[Field]: def desugar_field_(field: Field, previous: Field, constraints: Dict[str, Constraint]) -> List[Field]: """Inline group and constrained fields. Constrained fields are transformed into fixed fields. Group fields are inlined and recursively desugared.""" Loading @@ -13,6 +13,10 @@ def desugar_field_(field: Field, constraints: Dict[str, Constraint]) -> List[Fie fixed.parent = field.parent return [fixed] elif isinstance(field, PaddingField): previous.padded_size = field.size return [] elif isinstance(field, TypedefField) and field.id in constraints: tag_id = constraints[field.id].tag_id fixed = FixedField(kind='fixed_field', loc=field.loc, enum_id=field.type_id, tag_id=tag_id) Loading @@ -24,7 +28,8 @@ def desugar_field_(field: Field, constraints: Dict[str, Constraint]) -> List[Fie constraints = dict([(c.id, c) for c in field.constraints]) fields = [] for f in group.fields: fields.extend(desugar_field_(f, constraints)) fields.extend(desugar_field_(f, previous, constraints)) previous = f return fields else: Loading @@ -45,7 +50,7 @@ def desugar(file: File): if isinstance(d, (PacketDeclaration, StructDeclaration)): fields = [] for f in d.fields: fields.extend(desugar_field_(f, {})) fields.extend(desugar_field_(f, fields[-1] if len(fields) > 0 else None, {})) d.fields = fields declarations.append(d) Loading
tools/pdl/src/ast.rs +1 −1 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ pub enum Field { #[serde(rename = "checksum_field")] Checksum { loc: SourceRange, field_id: String }, #[serde(rename = "padding_field")] Padding { loc: SourceRange, width: usize }, Padding { loc: SourceRange, size: usize }, #[serde(rename = "size_field")] Size { loc: SourceRange, field_id: String, width: usize }, #[serde(rename = "count_field")] Loading