blob: c9cbde7c9a621d79978ac006e3ef0a01ed787b57 [file] [log] [blame]
Paul Greenwood31a54882019-08-01 17:05:09 -05001#pragma once
2
Paul Greenwood31a54882019-08-01 17:05:09 -05003#include <endian.h>
Paul Greenwood31a54882019-08-01 17:05:09 -05004#include <string.h>
5
Zane Shelleyca9f6252019-10-25 21:17:30 -05006#include <hei_includes.hpp>
7
Paul Greenwood31a54882019-08-01 17:05:09 -05008namespace libhei
9{
10
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -050011/** @brief A streaming utility to read a Chip Data File buffer. */
Paul Greenwood31a54882019-08-01 17:05:09 -050012class ChipDataStream
13{
Paul Greenwood31a54882019-08-01 17:05:09 -050014 public:
Zane Shelley83da2452019-10-25 15:45:34 -050015 /**
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -050016 * @brief Constructor.
17 * @param i_buffer A pointer to the buffer.
18 * @param i_bufferSize The buffer size.
19 */
Zane Shelleyfe27b652019-10-28 11:33:07 -050020 ChipDataStream(void* i_buffer, size_t i_bufferSize) :
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -050021 iv_buffer(i_buffer), iv_bufferSize(i_bufferSize)
22 {
23 HEI_ASSERT(nullptr != i_buffer);
24 HEI_ASSERT(0 < i_bufferSize);
25 }
Paul Greenwood31a54882019-08-01 17:05:09 -050026
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -050027 /** @brief Destructor. */
Zane Shelley83da2452019-10-25 15:45:34 -050028 ~ChipDataStream() = default;
Paul Greenwood31a54882019-08-01 17:05:09 -050029
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -050030 /** @brief Copy constructor. */
31 ChipDataStream(const ChipDataStream&) = delete;
Paul Greenwood31a54882019-08-01 17:05:09 -050032
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -050033 /** @brief Assignment operator. */
34 ChipDataStream& operator=(const ChipDataStream&) = delete;
35
36 private:
37 /** Pointer to the first address of the Chip Data File buffer. */
38 const void* const iv_buffer;
39
40 /** The Chip Data File buffer size. */
41 const size_t iv_bufferSize;
42
43 /** Current byte index within the buffer. */
44 size_t iv_currentIndex = 0;
45
46 public:
47 /** @brief Output stream operator. */
Zane Shelley83da2452019-10-25 15:45:34 -050048 template <class D>
Zane Shelleyfe27b652019-10-28 11:33:07 -050049 ChipDataStream& operator>>(D& o_right)
Zane Shelley83da2452019-10-25 15:45:34 -050050 {
51 read(&o_right, sizeof(D));
52 return *this;
53 }
Paul Greenwood31a54882019-08-01 17:05:09 -050054
55 private:
Zane Shelley83da2452019-10-25 15:45:34 -050056 /**
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -050057 * @brief Copies the given number of data bytes into the buffer from the
58 * current index and then increments the index.
59 * @param o_buf The output buffer.
60 * @param i_size The number of bytes to copy.
61 */
Zane Shelleyfe27b652019-10-28 11:33:07 -050062 void read(void* o_buf, size_t i_size)
Zane Shelley83da2452019-10-25 15:45:34 -050063 {
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -050064 // Check for buffer overflow.
65 HEI_ASSERT((iv_currentIndex + i_size) <= iv_bufferSize);
66
67 // Copy the buffer.
68 memcpy(o_buf, (char*)iv_buffer + iv_currentIndex, i_size);
69
70 // Increment the curent index for the next piece of data.
71 iv_currentIndex += i_size;
Zane Shelley83da2452019-10-25 15:45:34 -050072 }
Paul Greenwood31a54882019-08-01 17:05:09 -050073};
74
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -050075/** @brief Template specialization for uint16_t. */
Zane Shelley7f7a42d2019-10-28 13:28:31 -050076template <>
77inline ChipDataStream& ChipDataStream::operator>>(uint16_t& o_right)
Zane Shelley83da2452019-10-25 15:45:34 -050078{
79 read(&o_right, sizeof(o_right));
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -050080 o_right = be16toh(o_right); // Chip Data is big-endian
Zane Shelley83da2452019-10-25 15:45:34 -050081 return *this;
82}
Paul Greenwood31a54882019-08-01 17:05:09 -050083
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -050084/** @brief Template specialization for int16_t. */
Zane Shelley7f7a42d2019-10-28 13:28:31 -050085template <>
86inline ChipDataStream& ChipDataStream::operator>>(int16_t& o_right)
Zane Shelley83da2452019-10-25 15:45:34 -050087{
88 read(&o_right, sizeof(o_right));
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -050089 o_right = be16toh(o_right); // Chip Data is big-endian
Zane Shelley83da2452019-10-25 15:45:34 -050090 return *this;
91}
Paul Greenwood31a54882019-08-01 17:05:09 -050092
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -050093/** @brief Template specialization for uint32_t. */
Zane Shelley7f7a42d2019-10-28 13:28:31 -050094template <>
95inline ChipDataStream& ChipDataStream::operator>>(uint32_t& o_right)
Zane Shelley83da2452019-10-25 15:45:34 -050096{
97 read(&o_right, sizeof(o_right));
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -050098 o_right = be32toh(o_right); // Chip Data is big-endian
Zane Shelley83da2452019-10-25 15:45:34 -050099 return *this;
100}
Paul Greenwood31a54882019-08-01 17:05:09 -0500101
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -0500102/** @brief Template specialization for int32_t. */
Zane Shelley7f7a42d2019-10-28 13:28:31 -0500103template <>
104inline ChipDataStream& ChipDataStream::operator>>(int32_t& o_right)
Zane Shelley83da2452019-10-25 15:45:34 -0500105{
106 read(&o_right, sizeof(o_right));
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -0500107 o_right = be32toh(o_right); // Chip Data is big-endian
Zane Shelley83da2452019-10-25 15:45:34 -0500108 return *this;
109}
Paul Greenwood31a54882019-08-01 17:05:09 -0500110
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -0500111/** @brief Template specialization for uint64_t. */
Zane Shelley7f7a42d2019-10-28 13:28:31 -0500112template <>
113inline ChipDataStream& ChipDataStream::operator>>(uint64_t& o_right)
Zane Shelley83da2452019-10-25 15:45:34 -0500114{
115 read(&o_right, sizeof(o_right));
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -0500116 o_right = be64toh(o_right); // Chip Data is big-endian
Zane Shelley83da2452019-10-25 15:45:34 -0500117 return *this;
118}
Paul Greenwood31a54882019-08-01 17:05:09 -0500119
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -0500120/** @brief Template specialization for int64_t. */
Zane Shelley7f7a42d2019-10-28 13:28:31 -0500121template <>
122inline ChipDataStream& ChipDataStream::operator>>(int64_t& o_right)
Zane Shelley83da2452019-10-25 15:45:34 -0500123{
124 read(&o_right, sizeof(o_right));
Zane Shelleyb8b3cdf2020-05-04 13:28:04 -0500125 o_right = be64toh(o_right); // Chip Data is big-endian
Zane Shelley83da2452019-10-25 15:45:34 -0500126 return *this;
127}
Paul Greenwood31a54882019-08-01 17:05:09 -0500128
Zane Shelley83da2452019-10-25 15:45:34 -0500129} // namespace libhei