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