1 #pragma once
2 
3 #include "section.hpp"
4 #include "stream.hpp"
5 
6 namespace openpower
7 {
8 namespace pels
9 {
10 
11 /**
12  * @class UserData
13  *
14  * This represents the User Data section in a PEL.  It is free form data
15  * that the creator knows the contents of.  The component ID, version,
16  * and sub-type fields in the section header are used to identify the
17  * format.
18  *
19  * The Section base class handles the section header structure that every
20  * PEL section has at offset zero.
21  */
22 class UserData : public Section
23 {
24   public:
25     UserData() = delete;
26     ~UserData() = default;
27     UserData(const UserData&) = default;
28     UserData& operator=(const UserData&) = default;
29     UserData(UserData&&) = default;
30     UserData& operator=(UserData&&) = default;
31 
32     /**
33      * @brief Constructor
34      *
35      * Fills in this class's data fields from the stream.
36      *
37      * @param[in] pel - the PEL data stream
38      */
39     explicit UserData(Stream& pel);
40 
41     /**
42      * @brief Constructor
43      *
44      * Create a valid UserData object with the passed in data.
45      *
46      * The component ID, subtype, and version are used to identify
47      * the data to know which parser to call.
48      *
49      * @param[in] componentID - Component ID of the creator
50      * @param[in] subType - The type of user data
51      * @param[in] version - The version of the data
52      */
53     UserData(uint16_t componentID, uint8_t subType, uint8_t version,
54              const std::vector<uint8_t>& data);
55 
56     /**
57      * @brief Flatten the section into the stream
58      *
59      * @param[in] stream - The stream to write to
60      */
61     void flatten(Stream& stream) const override;
62 
63     /**
64      * @brief Returns the size of this section when flattened into a PEL
65      *
66      * @return size_t - the size of the section
67      */
68     size_t flattenedSize()
69     {
70         return Section::flattenedSize() + _data.size();
71     }
72 
73     /**
74      * @brief Returns the raw section data
75      *
76      * @return std::vector<uint8_t>&
77      */
78     const std::vector<uint8_t>& data() const
79     {
80         return _data;
81     }
82 
83     /**
84      * @brief Get the section contents in JSON
85      * @param[in] creatorID - Creator Subsystem ID from Private Header
86      * @param[in] plugins - Vector of strings of plugins found in filesystem
87      * @return The JSON as a string if a parser was found,
88      *         otherwise std::nullopt.
89      */
90     std::optional<std::string>
91         getJSON(uint8_t creatorID,
92                 const std::vector<std::string>& plugins) const override;
93 
94     /**
95      * @brief Shrink the section
96      *
97      * The new size must be between the current size and the minimum
98      * size, which is 12 bytes.  If it isn't a 4 byte aligned value
99      * the code will do the aligning before the resize takes place.
100      *
101      * @param[in] newSize - The new size in bytes
102      *
103      * @return bool - true if successful, false else.
104      */
105     bool shrink(size_t newSize) override;
106 
107   private:
108     /**
109      * @brief Fills in the object from the stream data
110      *
111      * @param[in] stream - The stream to read from
112      */
113     void unflatten(Stream& stream);
114 
115     /**
116      * @brief Validates the section contents
117      *
118      * Updates _valid (in Section) with the results.
119      */
120     void validate() override;
121 
122     /**
123      * @brief The section data
124      */
125     std::vector<uint8_t> _data;
126 };
127 
128 } // namespace pels
129 } // namespace openpower
130