| #pragma once |
| |
| /** |
| @file hei_chip_data_stream.hpp |
| @brief Description: The ChipDataStream class |
| |
| ChipDataStream makes it possible to read a buffer of binary data using the |
| stream operators, ">>". |
| |
| Instantiate ChipDataStream class with a pointer to a data buffer |
| and its size in bytes as below: |
| |
| ChipDataStream cds(streamData,552); |
| |
| Use the ">>" stream operator then to read the basic integral types |
| (bool, char, uint8_t, int8_t, uint16_t, int16_t, uint32_t, |
| int32_t, uint64_t, and int64_t). |
| |
| Endian issues are taken care of by template specialization. |
| **/ |
| |
| #include <endian.h> |
| #include <string.h> |
| |
| #include <hei_includes.hpp> |
| |
| namespace libhei |
| { |
| |
| /** |
| * ChipDataStream |
| * ChipDataStream offers convenient stream operator access to binary data. |
| **/ |
| class ChipDataStream |
| { |
| |
| private: |
| /** iv_buffer points to the first address of the Chip Data File |
| buffer. **/ |
| const void* const iv_buffer; |
| /** iv_bufferSize is the size of the data buffer. It is |
| initialized when the ChipDataStream class is instantiated. **/ |
| const size_t iv_bufferSize; |
| /** iv_asyncOffset keeps an offset into the buffer. This |
| offset is incremented appropriately as data is read. **/ |
| size_t iv_asyncOffset; |
| |
| public: |
| /* Constructors */ |
| |
| /** |
| When instantiating the ChipDataStream object a pointer to a |
| data buffer containing all the data and its size is passed |
| into the class. |
| **/ |
| ChipDataStream(void* i_buffer, size_t i_bufferSize) : |
| iv_asyncOffset(0), iv_buffer(i_buffer), iv_bufferSize(i_bufferSize) |
| {} |
| |
| /** Eliminate copy and assignment operator constructors **/ |
| ChipDataStream(const ChipDataStream&) = delete; |
| ChipDataStream& operator=(const ChipDataStream&) = delete; |
| |
| /** Destructor **/ |
| |
| ~ChipDataStream() = default; |
| |
| /** Functions **/ |
| |
| /** |
| *@brief Default case for "operator>>" template. |
| *@param D: A type |
| *@param o_right: A pointer to where the data is stored |
| *@return *this: A pointer to "this" object |
| **/ |
| template <class D> |
| ChipDataStream& operator>>(D& o_right) |
| { |
| read(&o_right, sizeof(D)); |
| return *this; |
| } |
| |
| private: |
| /** |
| *@brief Read does the copy from the buffer |
| *@param o_buf a pointer to the location to copy to |
| *@param i_size the size (in bytes) to copy |
| *@return None\n\n |
| **/ |
| void read(void* o_buf, size_t i_size) |
| { |
| /* Ensure memory is not accessed outside i_buffer */ |
| HEI_ASSERT((iv_asyncOffset + i_size) <= iv_bufferSize); |
| /* Copy appropriate bytes from i_buffer to o_buff */ |
| memcpy(o_buf, (char*)iv_buffer + iv_asyncOffset, i_size); |
| /* Increment asynchronous offset to next piece of data */ |
| iv_asyncOffset = iv_asyncOffset + i_size; |
| } |
| }; |
| |
| /* |
| * Note: The specializations below ensure the big-endian Chip Data File |
| * format is converted into the host format. |
| */ |
| |
| /** |
| * @brief This template extracts a uint16_t data type from the data buffer |
| * @param o_right: A pointer to where the data is stored |
| * @return *this: A pointer to "this" object |
| **/ |
| template <> |
| inline ChipDataStream& ChipDataStream::operator>>(uint16_t& o_right) |
| { |
| read(&o_right, sizeof(o_right)); |
| be16toh(o_right); |
| return *this; |
| } |
| |
| /**@brief This template extracts an int16_t type from the data buffer |
| * @param o_right: A pointer to where the data is stored |
| * @return *this: A pointer to "this" object |
| **/ |
| template <> |
| inline ChipDataStream& ChipDataStream::operator>>(int16_t& o_right) |
| { |
| read(&o_right, sizeof(o_right)); |
| be16toh(o_right); |
| return *this; |
| } |
| |
| /**@brief This template extracts a uint32_t type from the data buffer |
| * @param o_right: A pointer to where the data is stored |
| * @return *this: A pointer to "this" object |
| **/ |
| template <> |
| inline ChipDataStream& ChipDataStream::operator>>(uint32_t& o_right) |
| { |
| read(&o_right, sizeof(o_right)); |
| be32toh(o_right); |
| return *this; |
| } |
| |
| /**@brief This template extracts an int32_t type from the data buffer |
| * @param o_right: A pointer to where the data is stored |
| * @return *this: A pointer to "this" object |
| **/ |
| template <> |
| inline ChipDataStream& ChipDataStream::operator>>(int32_t& o_right) |
| { |
| read(&o_right, sizeof(o_right)); |
| be32toh(o_right); |
| return *this; |
| } |
| |
| /**@brief This template extracts a uint64_t type from the data buffer |
| * @param o_right: A pointer to where the data is stored |
| * @return *this: A pointer to "this" object |
| **/ |
| template <> |
| inline ChipDataStream& ChipDataStream::operator>>(uint64_t& o_right) |
| { |
| read(&o_right, sizeof(o_right)); |
| be64toh(o_right); |
| return *this; |
| } |
| |
| /**@brief This template extracts an int64_t type from the data buffer |
| * @param o_right: A pointer to where the data is stored |
| * @return *this: A pointer to "this" object |
| **/ |
| template <> |
| inline ChipDataStream& ChipDataStream::operator>>(int64_t& o_right) |
| { |
| read(&o_right, sizeof(o_right)); |
| be64toh(o_right); |
| return *this; |
| } |
| |
| } // namespace libhei |