1# SPDX-License-Identifier: GPL-2.0+
2# Copyright 2021 Google LLC
3# Written by Simon Glass <sjg@chromium.org>
4#
5
6# Support for a collection of entries from other parts of an image
7
8from collections import OrderedDict
9import os
10
11from binman.entry import Entry
12from dtoc import fdt_util
13
14class Entry_collection(Entry):
15    """An entry which contains a collection of other entries
16
17    Properties / Entry arguments:
18        - content: List of phandles to entries to include
19
20    This allows reusing the contents of other entries. The contents of the
21    listed entries are combined to form this entry. This serves as a useful
22    base class for entry types which need to process data from elsewhere in
23    the image, not necessarily child entries.
24    """
25    def __init__(self, section, etype, node):
26        super().__init__(section, etype, node)
27        self.content = fdt_util.GetPhandleList(self._node, 'content')
28        if not self.content:
29            self.Raise("Collection must have a 'content' property")
30
31    def GetContents(self, required):
32        """Get the contents of this entry
33
34        Args:
35            required: True if the data must be present, False if it is OK to
36                return None
37
38        Returns:
39            bytes content of the entry
40        """
41        # Join up all the data
42        self.Info('Getting contents, required=%s' % required)
43        data = b''
44        for entry_phandle in self.content:
45            entry_data = self.section.GetContentsByPhandle(entry_phandle, self,
46                                                           required)
47            if not required and entry_data is None:
48                self.Info('Contents not available yet')
49                # Data not available yet
50                return None
51            data += entry_data
52
53        self.Info('Returning contents size %x' % len(data))
54
55        return data
56
57    def ObtainContents(self):
58        data = self.GetContents(False)
59        if data is None:
60            return False
61        self.SetContents(data)
62        return True
63
64    def ProcessContents(self):
65        # The blob may have changed due to WriteSymbols()
66        data = self.GetContents(True)
67        return self.ProcessContentsUpdate(data)
68