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 (#27314)
  • Loading branch information
vivien-apple authored Jun 20, 2023
1 parent f14855f commit 84e38ee
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 8 deletions.
26 changes: 26 additions & 0 deletions scripts/py_matter_idl/matter_idl/generators/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,3 +412,29 @@ def ParseDataType(data_type: DataType, lookup: TypeLookupContext) -> Union[Basic
"Data type %s is NOT known, but treating it as a generic IDL type." % data_type)

return result


def IsSignedDataType(data_type: DataType) -> bool:
"""
Returns if the data type is a signed type.
Returns if the data type is a signed data type of False if the data type can not be found.
"""
lowercase_name = data_type.name.lower()
sized_type = __CHIP_SIZED_TYPES__.get(lowercase_name, None)
if sized_type is None:
return False

return sized_type.is_signed


def GetDataTypeSizeInBits(data_type: DataType) -> int:

This comment has been minimized.

Copy link
@andy31415

andy31415 Jun 20, 2023

Contributor

type return here is not correct: since we return none, type is Optional[int]

"""
Returns the size in bits for a given data type or None if the data type can not be found.
"""

lowercase_name = data_type.name.lower()
sized_type = __CHIP_SIZED_TYPES__.get(lowercase_name, None)
if sized_type is None:
return None

return sized_type.power_of_two_bits
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
24 changes: 20 additions & 4 deletions scripts/py_matter_idl/matter_idl/zapxml/handlers/parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,23 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from matter_idl.generators.types import GetDataTypeSizeInBits, IsSignedDataType
from matter_idl.matter_idl_types import AccessPrivilege, Attribute, AttributeQuality, DataType, Field, FieldQuality


def ParseInt(value: str) -> int:
"""Convert a string that is a known integer into an actual number.
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'
Supports decimal or hex values prefixed with '0x'
"""
if value.startswith('0x'):
return int(value[2:], 16)
value = int(value[2:], 16)
if data_type and IsSignedDataType(data_type):
bits = GetDataTypeSizeInBits(data_type)
if value & (1 << (bits - 1)):
value -= 1 << bits
return value
else:
return int(value)

Expand Down Expand Up @@ -60,9 +67,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 84e38ee

Please sign in to comment.