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