On Wed, Jun 06, 2018 at 03:37:06PM -0600, Simon Glass wrote: > It is common to want to set a property to a nul-terminated string in a > device tree. Add python methods to handle this. > > Signed-off-by: Simon Glass <sjg@xxxxxxxxxxxx> > --- > > Changes in v2: > - Add support for unicode strings > - Check for invalid embedded nul characters in as_str() > - Check for nul termination in as_str() > - Make the as_str() function a non-member of Property > > pylibfdt/libfdt.i | 30 ++++++++++++++++++++++++++++++ > tests/pylibfdt_tests.py | 27 +++++++++++++++++++++++++++ > 2 files changed, 57 insertions(+) > > diff --git a/pylibfdt/libfdt.i b/pylibfdt/libfdt.i > index 0eefc5a..ae63263 100644 > --- a/pylibfdt/libfdt.i > +++ b/pylibfdt/libfdt.i > @@ -170,6 +170,14 @@ def as_uint64(bytes): > def as_int64(bytes): > return as_cell(bytes, 'q') > > +def as_str(self): > + """Unicode is supposed by decoding from UTF-8""" > + if self[-1] != 0: > + raise ValueError('Property lacks nul termination') > + if 0 in self[:-1]: > + raise ValueError('Property contains embedded nul characters') > + return self[:-1].decode('utf-8') As mentioned elsehwere, I've changed my mind and I think this would be better as a Property method. > > class Fdt: > """Device tree class, supporting all operations > @@ -601,6 +609,28 @@ class Fdt: > return check_err(fdt_setprop_u64(self._fdt, nodeoffset, prop_name, val), > quiet) > > + def setprop_str(self, nodeoffset, prop_name, val, quiet=()): > + """Set the string value of a property > + > + The property is set to the string, with a nul terminator added > + > + Args: > + nodeoffset: Node offset containing the property to create/update > + prop_name: Name of property > + val: Value to write (string without nul terminator). Unicode is > + supposed by encoding to UTF-8 > + quiet: Errors to ignore (empty to raise on all errors) > + > + Returns: > + Error code, or 0 if OK > + > + Raises: > + FdtException if no parent found or other error occurs > + """ > + val = (val + '\0').encode('utf-8') Logically, adding the \0 should be done *after* the utf-8 encoding. > + return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name, > + val, len(val)), quiet) > + > def delprop(self, nodeoffset, prop_name): > """Delete a property from a node > > diff --git a/tests/pylibfdt_tests.py b/tests/pylibfdt_tests.py > index 2badef2..738210f 100644 > --- a/tests/pylibfdt_tests.py > +++ b/tests/pylibfdt_tests.py > @@ -68,6 +68,8 @@ TEST_VALUE64_1L = 0x01abcdef > TEST_VALUE64_1 = (TEST_VALUE64_1H << 32) | TEST_VALUE64_1L > > TEST_STRING_1 = 'hello world' > +TEST_STRING_2 = 'hi world' > +TEST_STRING_3 = u'unicode ' + unichr(467) > > > def get_err(err_code): > @@ -441,6 +443,31 @@ class PyLibfdtTests(unittest.TestCase): > self.assertEquals(struct.pack('>Q', TEST_VALUE64_1), > self.fdt.getprop(node, prop)) > > + def testSetPropStr(self): > + """Test that we can set a property to a particular string""" > + node = 0 > + prop = 'prop-str' > + self.assertEquals(TEST_STRING_1, > + libfdt.as_str(self.fdt.getprop(node, prop))) > + self.fdt.setprop_str(node, prop, TEST_STRING_2) > + self.assertEquals(TEST_STRING_2, > + libfdt.as_str(self.fdt.getprop(node, prop))) > + with self.assertRaises(ValueError) as e: > + libfdt.as_str(self.fdt.getprop(node, 'prop-int')) > + self.assertIn('lacks nul termination', str(e.exception)) > + > + node2 = self.fdt.path_offset('/subnode@1/subsubnode') > + with self.assertRaises(ValueError) as e: > + libfdt.as_str(self.fdt.getprop(node2, 'compatible')) > + self.assertIn('embedded nul', str(e.exception)) > + > + # Expand the device tree so we now have room > + self.fdt.resize(self.fdt.totalsize() + 50) > + prop = 'prop-unicode' > + self.fdt.setprop_str(node, prop, TEST_STRING_3) > + self.assertEquals(TEST_STRING_3, > + libfdt.as_str(self.fdt.getprop(node, prop))) > + > > if __name__ == "__main__": > unittest.main() -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
Attachment:
signature.asc
Description: PGP signature