Skip to content

Commit

Permalink
[matter_idl] Add min_value/max_value/min_length supports when parsing…
Browse files Browse the repository at this point in the history
… the xml files
  • Loading branch information
vivien-apple committed Jun 19, 2023
1 parent f5c4621 commit 23c12ed
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 6 deletions.
5 changes: 5 additions & 0 deletions scripts/py_matter_idl/matter_idl/matter_idl_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,13 @@ class DataType:
name: str

# Applies for strings (char or binary)
min_length: Optional[int] = None
max_length: Optional[int] = None

# Applies for numbers
min_value: Optional[int] = None
max_value: Optional[int] = None


@dataclass
class Field:
Expand Down
25 changes: 21 additions & 4 deletions scripts/py_matter_idl/matter_idl/test_xml_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ def testCluster(self):
<code>0x1234</code>
<description>Test</description>
<attribute side="server" code="10" type="CHAR_STRING" minLength="2" length="10" isNullable="true" \
reportable="true" writable="false">SomeCharStringAttribute</attribute>
<attribute side="server" code="11" type="INT32U" min="0" max="2" isNullable="true" \
reportable="true" writable="false">SomeIntAttribute</attribute>
Expand Down Expand Up @@ -93,15 +96,26 @@ def testCluster(self):
description="Test",
attributes=[
Attribute(definition=Field(
data_type=DataType(name='INT32U'),
data_type=DataType(
name='CHAR_STRING', min_length=2, max_length=10),
code=10,
name='SomeCharStringAttribute',
qualities=FieldQuality.NULLABLE),
qualities=AttributeQuality.READABLE,
readacl=AccessPrivilege.VIEW, writeacl=AccessPrivilege.OPERATE),

Attribute(definition=Field(
data_type=DataType(
name='INT32U', min_value=0, max_value=2),
code=11,
name='SomeIntAttribute',
qualities=FieldQuality.NULLABLE),
qualities=AttributeQuality.READABLE,
readacl=AccessPrivilege.VIEW, writeacl=AccessPrivilege.OPERATE),

Attribute(definition=Field(
data_type=DataType(name='INT8U'),
data_type=DataType(
name='INT8U', min_value=0, max_value=10),
code=22, name='AttributeWithAccess',
qualities=FieldQuality.OPTIONAL),
qualities=AttributeQuality.READABLE | AttributeQuality.WRITABLE,
Expand Down Expand Up @@ -214,7 +228,10 @@ def testFabricScopedAndSensitive(self):
name='Field3',
qualities=FieldQuality.FABRIC_SENSITIVE),
Field(data_type=DataType(name='int32u',
max_length=None),
min_length=None,
max_length=None,
min_value=None,
max_value=None),
code=10,
name='Field10')],
qualities=StructQuality.FABRIC_SCOPED)],
Expand Down Expand Up @@ -369,7 +386,7 @@ def testSkipsNotProcessedFields(self):
Attribute(
definition=Field(
data_type=DataType(
name='Type'),
name='Type', min_value=0, max_value=9),
code=0,
name='Type',
),
Expand Down
34 changes: 32 additions & 2 deletions scripts/py_matter_idl/matter_idl/zapxml/handlers/parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,35 @@

from matter_idl.matter_idl_types import AccessPrivilege, Attribute, AttributeQuality, DataType, Field, FieldQuality

SIGNED_INTEGER_TYPES = {
'int8s': 1,
'int16s': 2,
'int24s': 4,
'int32s': 4,
'int40s': 8,
'int48s': 8,
'int56s': 8,
'int64s': 8,
'temperature': 2,
}

def ParseInt(value: str) -> int:

def IsSignedType(data_type: DataType) -> bool:
return data_type and data_type.name.lower() in SIGNED_INTEGER_TYPES.keys()


def ParseInt(value: str, data_type: DataType = None) -> int:
"""Convert a string that is a known integer into an actual number.
Supports decimal or hex values prefixed with '0x'
"""
if value.startswith('0x'):
return int(value[2:], 16)
value = int(value[2:], 16)
if IsSignedType(data_type):
bits = SIGNED_INTEGER_TYPES[data_type.name.lower()] * 8
if value & (1 << (bits - 1)):
value -= 1 << bits
return value
else:
return int(value)

Expand Down Expand Up @@ -60,9 +81,18 @@ def AttrsToAttribute(attrs) -> Attribute:
else:
data_type = DataType(name=attrs['type'])

if 'minLength' in attrs:
data_type.min_length = ParseInt(attrs['minLength'])

if 'length' in attrs:
data_type.max_length = ParseInt(attrs['length'])

if 'min' in attrs:
data_type.min_value = ParseInt(attrs['min'], data_type)

if 'max' in attrs:
data_type.max_value = ParseInt(attrs['max'], data_type)

field = Field(
data_type=data_type,
code=ParseInt(attrs['code']),
Expand Down

0 comments on commit 23c12ed

Please sign in to comment.