From 0df96d8dad8ad50ff5eff19e933a76f6894d3244 Mon Sep 17 00:00:00 2001 From: Mia Yang <145632982+mia1yang@users.noreply.github.com> Date: Wed, 31 Jul 2024 01:43:54 +0800 Subject: [PATCH] [lib] add little endian methods in utils (#10534) --- src/lib/spinel/multi_frame_buffer.hpp | 30 ++++------- src/lib/spinel/spi_frame.hpp | 30 +++++------ src/lib/utils/endian.hpp | 72 +++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 37 deletions(-) create mode 100644 src/lib/utils/endian.hpp diff --git a/src/lib/spinel/multi_frame_buffer.hpp b/src/lib/spinel/multi_frame_buffer.hpp index 921181f3d..af920fabf 100644 --- a/src/lib/spinel/multi_frame_buffer.hpp +++ b/src/lib/spinel/multi_frame_buffer.hpp @@ -40,6 +40,8 @@ #include +#include "lib/utils/endian.hpp" + namespace ot { namespace Spinel { @@ -263,7 +265,7 @@ public: if (mWriteFrameStart + kHeaderSize + aSkipLength <= GetArrayEnd(mBuffer)) { - LittleEndian::WriteUint16(aSkipLength, mWriteFrameStart + kHeaderSkipLengthOffset); + Lib::Utils::LittleEndian::WriteUint16(aSkipLength, mWriteFrameStart + kHeaderSkipLengthOffset); mWritePointer = GetFrame(); mRemainingLength = static_cast(mBuffer + kSize - mWritePointer); error = OT_ERROR_NONE; @@ -278,7 +280,10 @@ public: * @returns The length (number of bytes) of the reserved buffer. * */ - uint16_t GetSkipLength(void) const { return LittleEndian::ReadUint16(mWriteFrameStart + kHeaderSkipLengthOffset); } + uint16_t GetSkipLength(void) const + { + return Lib::Utils::LittleEndian::ReadUint16(mWriteFrameStart + kHeaderSkipLengthOffset); + } /** * Gets a pointer to the start of the current frame. @@ -316,7 +321,8 @@ public: } else { - LittleEndian::WriteUint16(GetSkipLength() + GetLength(), mWriteFrameStart + kHeaderTotalLengthOffset); + Lib::Utils::LittleEndian::WriteUint16(GetSkipLength() + GetLength(), + mWriteFrameStart + kHeaderTotalLengthOffset); mWriteFrameStart = mWritePointer; IgnoreError(SetSkipLength(0)); } @@ -369,8 +375,8 @@ public: if (HasSavedFrame() && (aFrame != mWriteFrameStart)) { - uint16_t totalLength = LittleEndian::ReadUint16(aFrame + kHeaderTotalLengthOffset); - uint16_t skipLength = LittleEndian::ReadUint16(aFrame + kHeaderSkipLengthOffset); + uint16_t totalLength = Lib::Utils::LittleEndian::ReadUint16(aFrame + kHeaderTotalLengthOffset); + uint16_t skipLength = Lib::Utils::LittleEndian::ReadUint16(aFrame + kHeaderSkipLengthOffset); aLength = totalLength - skipLength; aFrame += kHeaderSize + skipLength; @@ -459,20 +465,6 @@ private: static void IgnoreError(otError aError) { (void)(aError); } - class LittleEndian - { - public: - static uint16_t ReadUint16(const uint8_t *aBuffer) - { - return static_cast((aBuffer[0]) | aBuffer[1] << 8); - } - static void WriteUint16(uint16_t aValue, uint8_t *aBuffer) - { - aBuffer[0] = (aValue >> 0) & 0xff; - aBuffer[1] = (aValue >> 8) & 0xff; - } - }; - uint8_t mBuffer[kSize]; uint8_t *mWriteFrameStart; // Pointer to start of current frame being written. }; diff --git a/src/lib/spinel/spi_frame.hpp b/src/lib/spinel/spi_frame.hpp index 43843bb0f..0d41516d4 100644 --- a/src/lib/spinel/spi_frame.hpp +++ b/src/lib/spinel/spi_frame.hpp @@ -35,6 +35,8 @@ #include +#include "lib/utils/endian.hpp" + namespace ot { namespace Spinel { @@ -193,7 +195,10 @@ public: * @param[in] aAcceptLen The accept length in bytes. * */ - void SetHeaderAcceptLen(uint16_t aAcceptLen) { LittleEndian::WriteUint16(aAcceptLen, mBuffer + kIndexAcceptLen); } + void SetHeaderAcceptLen(uint16_t aAcceptLen) + { + Lib::Utils::LittleEndian::WriteUint16(aAcceptLen, mBuffer + kIndexAcceptLen); + } /** * Gets the "accept len" field in the SPI frame header. @@ -201,7 +206,7 @@ public: * @returns The accept length in bytes. * */ - uint16_t GetHeaderAcceptLen(void) const { return LittleEndian::ReadUint16(mBuffer + kIndexAcceptLen); } + uint16_t GetHeaderAcceptLen(void) const { return Lib::Utils::LittleEndian::ReadUint16(mBuffer + kIndexAcceptLen); } /** * Sets the "data len" field in the SPI frame header. @@ -211,7 +216,10 @@ public: * @param[in] aDataLen The data length in bytes. * */ - void SetHeaderDataLen(uint16_t aDataLen) { LittleEndian::WriteUint16(aDataLen, mBuffer + kIndexDataLen); } + void SetHeaderDataLen(uint16_t aDataLen) + { + Lib::Utils::LittleEndian::WriteUint16(aDataLen, mBuffer + kIndexDataLen); + } /** * Gets the "data len" field in the SPI frame header. @@ -219,7 +227,7 @@ public: * @returns The data length in bytes. * */ - uint16_t GetHeaderDataLen(void) const { return LittleEndian::ReadUint16(mBuffer + kIndexDataLen); } + uint16_t GetHeaderDataLen(void) const { return Lib::Utils::LittleEndian::ReadUint16(mBuffer + kIndexDataLen); } private: enum @@ -233,20 +241,6 @@ private: kFlagPatternMask = 0x03, // Flag byte PATTERN mask. }; - class LittleEndian - { - public: - static uint16_t ReadUint16(const uint8_t *aBuffer) - { - return static_cast((aBuffer[0]) | aBuffer[1] << 8); - } - static void WriteUint16(uint16_t aValue, uint8_t *aBuffer) - { - aBuffer[0] = (aValue >> 0) & 0xff; - aBuffer[1] = (aValue >> 8) & 0xff; - } - }; - uint8_t *mBuffer; }; diff --git a/src/lib/utils/endian.hpp b/src/lib/utils/endian.hpp new file mode 100644 index 000000000..3b990535d --- /dev/null +++ b/src/lib/utils/endian.hpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2024, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file includes definitions for endianness utility functions. + */ + +#ifndef LIB_UTILS_ENDIAN_HPP_ +#define LIB_UTILS_ENDIAN_HPP_ + +#include + +namespace ot { +namespace Lib { +namespace Utils { + +namespace LittleEndian { +/** + * Reads a `uint16_t` value from a given buffer assuming little-endian encoding. + * + * @param[in] aBuffer Pointer to buffer to read from. + * + * @returns The `uint16_t` value read from buffer. + * + */ +inline uint16_t ReadUint16(const uint8_t *aBuffer) { return static_cast(aBuffer[0] | (aBuffer[1] << 8)); } + +/** + * Writes a `uint16_t` value to a given buffer using little-endian encoding. + * + * @param[in] aValue The value to write to buffer. + * @param[out] aBuffer Pointer to buffer where the value will be written. + * + */ +inline void WriteUint16(uint16_t aValue, uint8_t *aBuffer) +{ + aBuffer[0] = (aValue >> 0) & 0xff; + aBuffer[1] = (aValue >> 8) & 0xff; +} + +} // namespace LittleEndian +} // namespace Utils +} // namespace Lib +} // namespace ot + +#endif // LIB_UTILS_ENDIAN_HPP_