1*f5210bb6SBen Tyner #pragma once
2*f5210bb6SBen Tyner 
3*f5210bb6SBen Tyner #include "stream.hpp"
4*f5210bb6SBen Tyner 
5*f5210bb6SBen Tyner #include <cstdint>
6*f5210bb6SBen Tyner 
7*f5210bb6SBen Tyner namespace attn
8*f5210bb6SBen Tyner {
9*f5210bb6SBen Tyner namespace pel
10*f5210bb6SBen Tyner {
11*f5210bb6SBen Tyner 
12*f5210bb6SBen Tyner /**
13*f5210bb6SBen Tyner  * @class SectionHeader
14*f5210bb6SBen Tyner  *
15*f5210bb6SBen Tyner  * @brief This 8-byte header is at the start of every PEL section.
16*f5210bb6SBen Tyner  *
17*f5210bb6SBen Tyner  * |--------+------------+------------+-----------+------------|
18*f5210bb6SBen Tyner  * | length | byte0      | byte1      | byte2     | byte3      |
19*f5210bb6SBen Tyner  * |--------+------------+------------+-----------+------------|
20*f5210bb6SBen Tyner  * | 4      | Section ID              | Section Length         |
21*f5210bb6SBen Tyner  * |--------+------------+-------------------------------------|
22*f5210bb6SBen Tyner  * | 4      | Version    | Sub-type   | Component ID           |
23*f5210bb6SBen Tyner  * |--------+--------------------------------------------------|
24*f5210bb6SBen Tyner  *
25*f5210bb6SBen Tyner  * Section ID:
26*f5210bb6SBen Tyner  * A two-ASCII character field which uniquely identifies the type of section.
27*f5210bb6SBen Tyner  *
28*f5210bb6SBen Tyner  * Section length:
29*f5210bb6SBen Tyner  * Length in bytes of the section, including the entire section header.
30*f5210bb6SBen Tyner  *
31*f5210bb6SBen Tyner  * Section Version:
32*f5210bb6SBen Tyner  * A one byte integer intended to identify differences in header structures.
33*f5210bb6SBen Tyner  *
34*f5210bb6SBen Tyner  * Section sub-type:
35*f5210bb6SBen Tyner  * Optional. Additional identifier describing the section.
36*f5210bb6SBen Tyner  *
37*f5210bb6SBen Tyner  * Component IDs:
38*f5210bb6SBen Tyner  * Optional. By convention the creator's component ID is placed in the
39*f5210bb6SBen Tyner  * component ID field of the Private Header and the committing component
40*f5210bb6SBen Tyner  * ID is placed in the component ID field of the User Header.
41*f5210bb6SBen Tyner  */
42*f5210bb6SBen Tyner struct SectionHeader
43*f5210bb6SBen Tyner {
44*f5210bb6SBen Tyner   public:
45*f5210bb6SBen Tyner     /**
46*f5210bb6SBen Tyner      * @brief Constructor
47*f5210bb6SBen Tyner      */
48*f5210bb6SBen Tyner     SectionHeader() : id(0), size(0), version(0), subType(0), componentID(0) {}
49*f5210bb6SBen Tyner 
50*f5210bb6SBen Tyner     /**
51*f5210bb6SBen Tyner      * @brief Constructor
52*f5210bb6SBen Tyner      *
53*f5210bb6SBen Tyner      * @param[in] id - the ID field
54*f5210bb6SBen Tyner      * @param[in] size - the size field
55*f5210bb6SBen Tyner      * @param[in] version - the version field
56*f5210bb6SBen Tyner      * @param[in] subType - the sub-type field
57*f5210bb6SBen Tyner      * @param[in] componentID - the component ID field
58*f5210bb6SBen Tyner      */
59*f5210bb6SBen Tyner     SectionHeader(uint16_t id, uint16_t size, uint8_t version, uint8_t subType,
60*f5210bb6SBen Tyner                   uint16_t componentID) :
61*f5210bb6SBen Tyner         id(id),
62*f5210bb6SBen Tyner         size(size), version(version), subType(subType), componentID(componentID)
63*f5210bb6SBen Tyner     {}
64*f5210bb6SBen Tyner 
65*f5210bb6SBen Tyner     /**
66*f5210bb6SBen Tyner      * @brief A two character ASCII field which identifies the section type.
67*f5210bb6SBen Tyner      */
68*f5210bb6SBen Tyner     uint16_t id;
69*f5210bb6SBen Tyner 
70*f5210bb6SBen Tyner     /**
71*f5210bb6SBen Tyner      * @brief The size of the section in bytes, including this section header.
72*f5210bb6SBen Tyner      */
73*f5210bb6SBen Tyner     uint16_t size;
74*f5210bb6SBen Tyner 
75*f5210bb6SBen Tyner     /**
76*f5210bb6SBen Tyner      * @brief The section format version.
77*f5210bb6SBen Tyner      */
78*f5210bb6SBen Tyner     uint8_t version;
79*f5210bb6SBen Tyner 
80*f5210bb6SBen Tyner     /**
81*f5210bb6SBen Tyner      * @brief The section sub-type.
82*f5210bb6SBen Tyner      */
83*f5210bb6SBen Tyner     uint8_t subType;
84*f5210bb6SBen Tyner 
85*f5210bb6SBen Tyner     /**
86*f5210bb6SBen Tyner      * @brief The component ID, which has various meanings depending on the
87*f5210bb6SBen Tyner      * section.
88*f5210bb6SBen Tyner      */
89*f5210bb6SBen Tyner     uint16_t componentID;
90*f5210bb6SBen Tyner 
91*f5210bb6SBen Tyner     /**
92*f5210bb6SBen Tyner      * @brief Returns the size of header when flattened into a PEL.
93*f5210bb6SBen Tyner      *
94*f5210bb6SBen Tyner      * @return size_t - the size of the header
95*f5210bb6SBen Tyner      */
96*f5210bb6SBen Tyner     static constexpr size_t flattenedSize()
97*f5210bb6SBen Tyner     {
98*f5210bb6SBen Tyner         return sizeof(id) + sizeof(size) + sizeof(version) + sizeof(subType) +
99*f5210bb6SBen Tyner                sizeof(componentID);
100*f5210bb6SBen Tyner     }
101*f5210bb6SBen Tyner };
102*f5210bb6SBen Tyner 
103*f5210bb6SBen Tyner /**
104*f5210bb6SBen Tyner  * @brief Stream extraction operator for the SectionHeader
105*f5210bb6SBen Tyner  *
106*f5210bb6SBen Tyner  * @param[in] s - the stream
107*f5210bb6SBen Tyner  * @param[out] header - the SectionHeader object
108*f5210bb6SBen Tyner  */
109*f5210bb6SBen Tyner inline Stream& operator>>(Stream& s, SectionHeader& header)
110*f5210bb6SBen Tyner {
111*f5210bb6SBen Tyner     s >> header.id >> header.size >> header.version >> header.subType >>
112*f5210bb6SBen Tyner         header.componentID;
113*f5210bb6SBen Tyner     return s;
114*f5210bb6SBen Tyner }
115*f5210bb6SBen Tyner 
116*f5210bb6SBen Tyner /**
117*f5210bb6SBen Tyner  * @brief Stream insertion operator for the section header
118*f5210bb6SBen Tyner  *
119*f5210bb6SBen Tyner  * @param[out] s - the stream
120*f5210bb6SBen Tyner  * @param[in] header - the SectionHeader object
121*f5210bb6SBen Tyner  */
122*f5210bb6SBen Tyner inline Stream& operator<<(Stream& s, const SectionHeader& header)
123*f5210bb6SBen Tyner {
124*f5210bb6SBen Tyner     s << header.id << header.size << header.version << header.subType
125*f5210bb6SBen Tyner       << header.componentID;
126*f5210bb6SBen Tyner     return s;
127*f5210bb6SBen Tyner }
128*f5210bb6SBen Tyner 
129*f5210bb6SBen Tyner } // namespace pel
130*f5210bb6SBen Tyner } // namespace attn
131