Skip to content

Commit

Permalink
target: Add Target.read_tree_values_flat(decode=None) parameter
Browse files Browse the repository at this point in the history
Allow not decoding the values and keep them as bytestring, for when e.g.
sysfs files have binary content (e.g. exposed from device tree)

True decodes the bytestring, None attempts to decode and False does not
decode.
  • Loading branch information
douglas-raillard-arm committed Apr 8, 2022
1 parent 783fb6d commit 3f513d7
Showing 1 changed file with 25 additions and 14 deletions.
39 changes: 25 additions & 14 deletions devlib/target.py
Original file line number Diff line number Diff line change
Expand Up @@ -1363,7 +1363,7 @@ async def read_tree_tar_flat(self, path, depth=1, check_exit_code=True,
# if it is a file and not a folder
if content_f:
content = content_f.read()
if decode_unicode:
if decode_unicode in (True, None):
try:
content = content.decode('utf-8').strip()
if strip_null_chars:
Expand All @@ -1377,27 +1377,37 @@ async def read_tree_tar_flat(self, path, depth=1, check_exit_code=True,
return result

@asyn.asyncf
async def read_tree_values_flat(self, path, depth=1, check_exit_code=True):
async def read_tree_values_flat(self, path, depth=1, check_exit_code=True, decode=None):
self.async_manager.track_access(
asyn.PathAccess(namespace='target', path=path, mode='r')
)
command = 'read_tree_values {} {}'.format(quote(path), depth)
output = await self._execute_util.asyn(command, as_root=self.is_rooted,
check_exit_code=check_exit_code)

check_exit_code=check_exit_code, decode=False)
accumulator = defaultdict(list)
for entry in output.strip().split('\n'):
if ':' not in entry:
for entry in output.strip().splitlines():
if b':' not in entry:
continue
path, value = entry.strip().split(':', 1)
path, value = entry.strip().split(b':', 1)
accumulator[path].append(value)

result = {k: '\n'.join(v).strip() for k, v in accumulator.items()}
if decode is None:
def do_decode(b):
try:
return b.decode()
except UnicodeDecodeError:
return b
elif decode:
do_decode = lambda b: b.decode()
else:
do_decode = lambda b: b

result = {k.decode(): do_decode(b'\n'.join(v).strip()) for k, v in accumulator.items()}
return result

@asyn.asyncf
async def read_tree_values(self, path, depth=1, dictcls=dict,
check_exit_code=True, tar=False, decode_unicode=True,
check_exit_code=True, tar=False, decode_unicode=None,
strip_null_chars=True):
"""
Reads the content of all files under a given tree
Expand All @@ -1415,7 +1425,7 @@ async def read_tree_values(self, path, depth=1, dictcls=dict,
:returns: a tree-like dict with the content of files as leafs
"""
if not tar:
value_map = await self.read_tree_values_flat.asyn(path, depth, check_exit_code)
value_map = await self.read_tree_values_flat.asyn(path, depth, check_exit_code, decode=decode_unicode)
else:
value_map = await self.read_tree_tar_flat.asyn(path, depth, check_exit_code,
decode_unicode,
Expand Down Expand Up @@ -1455,14 +1465,15 @@ async def _setup_shutils(self):

@asyn.asyncf
@call_conn
async def _execute_util(self, command, timeout=None, check_exit_code=True, as_root=False):
async def _execute_util(self, command, timeout=None, check_exit_code=True, as_root=False, decode=True):
command = '{} {}'.format(quote(self.shutils), command)
return await self.execute.asyn(
command,
stdout, stderr = await self.execute_raw.asyn(
command=command,
timeout=timeout,
check_exit_code=check_exit_code,
as_root=as_root
as_root=as_root,
)
return stdout.decode() if decode else stdout

async def _extract_archive(self, path, cmd, dest=None):
cmd = '{} ' + cmd # busybox
Expand Down

0 comments on commit 3f513d7

Please sign in to comment.