diff mbox series

[kms++,3/4] kms++util: Add endian.h

Message ID 20221202131658.434114-4-tomi.valkeinen+renesas@ideasonboard.com (mailing list archive)
State New
Delegated to: Kieran Bingham
Headers show
Series Support Y210 | expand

Commit Message

Tomi Valkeinen Dec. 2, 2022, 1:16 p.m. UTC
Add simple endianness supporting write function, and, for now, only one
shortcut helper, write16le().

Signed-off-by: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
---
 kms++util/inc/kms++util/endian.h | 46 ++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)
 create mode 100644 kms++util/inc/kms++util/endian.h

Comments

Laurent Pinchart Dec. 2, 2022, 11:56 p.m. UTC | #1
Hi Tomi,

Thank you for the patch.

On Fri, Dec 02, 2022 at 03:16:57PM +0200, Tomi Valkeinen wrote:
> Add simple endianness supporting write function, and, for now, only one
> shortcut helper, write16le().
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
> ---
>  kms++util/inc/kms++util/endian.h | 46 ++++++++++++++++++++++++++++++++
>  1 file changed, 46 insertions(+)
>  create mode 100644 kms++util/inc/kms++util/endian.h
> 
> diff --git a/kms++util/inc/kms++util/endian.h b/kms++util/inc/kms++util/endian.h
> new file mode 100644
> index 0000000..ea09065
> --- /dev/null
> +++ b/kms++util/inc/kms++util/endian.h
> @@ -0,0 +1,46 @@
> +#pragma once
> +
> +#include <type_traits>
> +#include <byteswap.h>
> +#include <stdint.h>
> +
> +static_assert((__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) ||
> +	      (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__),
> +	      "Unable to detect endianness");
> +
> +enum class endian {
> +	little = __ORDER_LITTLE_ENDIAN__,
> +	big = __ORDER_BIG_ENDIAN__,
> +	native = __BYTE_ORDER__
> +};
> +
> +template<typename T>
> +constexpr T byteswap(T value) noexcept
> +{
> +	static_assert(std::is_integral<T>(), "Type is not integral");
> +	static_assert(sizeof(T) == 2 ||
> +		      sizeof(T) == 4 ||
> +		      sizeof(T) == 8,
> +		      "Illegal value size");
> +
> +	switch (sizeof(T)) {
> +		case 2: return bswap_16(value);
> +		case 4: return bswap_32(value);
> +		case 8: return bswap_64(value);
> +	}
> +}
> +
> +template<endian E, typename T>
> +static void write_endian(T val, T* dst)

I would have swapped the parameters, common APIs have the destination
first and the source second. Same below, and up to you.

> +{
> +	if constexpr (E != endian::native)
> +		val = byteswap(val);
> +
> +	*dst = val;
> +}
> +
> +[[maybe_unused]]
> +static void write16le(uint16_t val, uint16_t* dst)

I wonder if writing

using write16le = write_endian<endian::little, uint16_t>;

would compile.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> +{
> +	write_endian<endian::little, uint16_t>(val, dst);
> +}
Tomi Valkeinen Dec. 4, 2022, 12:38 p.m. UTC | #2
On 03/12/2022 01:56, Laurent Pinchart wrote:
> Hi Tomi,
> 
> Thank you for the patch.
> 
> On Fri, Dec 02, 2022 at 03:16:57PM +0200, Tomi Valkeinen wrote:
>> Add simple endianness supporting write function, and, for now, only one
>> shortcut helper, write16le().
>>
>> Signed-off-by: Tomi Valkeinen <tomi.valkeinen+renesas@ideasonboard.com>
>> ---
>>   kms++util/inc/kms++util/endian.h | 46 ++++++++++++++++++++++++++++++++
>>   1 file changed, 46 insertions(+)
>>   create mode 100644 kms++util/inc/kms++util/endian.h
>>
>> diff --git a/kms++util/inc/kms++util/endian.h b/kms++util/inc/kms++util/endian.h
>> new file mode 100644
>> index 0000000..ea09065
>> --- /dev/null
>> +++ b/kms++util/inc/kms++util/endian.h
>> @@ -0,0 +1,46 @@
>> +#pragma once
>> +
>> +#include <type_traits>
>> +#include <byteswap.h>
>> +#include <stdint.h>
>> +
>> +static_assert((__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) ||
>> +	      (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__),
>> +	      "Unable to detect endianness");
>> +
>> +enum class endian {
>> +	little = __ORDER_LITTLE_ENDIAN__,
>> +	big = __ORDER_BIG_ENDIAN__,
>> +	native = __BYTE_ORDER__
>> +};
>> +
>> +template<typename T>
>> +constexpr T byteswap(T value) noexcept
>> +{
>> +	static_assert(std::is_integral<T>(), "Type is not integral");
>> +	static_assert(sizeof(T) == 2 ||
>> +		      sizeof(T) == 4 ||
>> +		      sizeof(T) == 8,
>> +		      "Illegal value size");
>> +
>> +	switch (sizeof(T)) {
>> +		case 2: return bswap_16(value);
>> +		case 4: return bswap_32(value);
>> +		case 8: return bswap_64(value);
>> +	}
>> +}
>> +
>> +template<endian E, typename T>
>> +static void write_endian(T val, T* dst)
> 
> I would have swapped the parameters, common APIs have the destination
> first and the source second. Same below, and up to you.

True, I think that makes sense.

>> +{
>> +	if constexpr (E != endian::native)
>> +		val = byteswap(val);
>> +
>> +	*dst = val;
>> +}
>> +
>> +[[maybe_unused]]
>> +static void write16le(uint16_t val, uint16_t* dst)
> 
> I wonder if writing
> 
> using write16le = write_endian<endian::little, uint16_t>;
> 
> would compile.

No, using needs a type.

  Tomi
diff mbox series

Patch

diff --git a/kms++util/inc/kms++util/endian.h b/kms++util/inc/kms++util/endian.h
new file mode 100644
index 0000000..ea09065
--- /dev/null
+++ b/kms++util/inc/kms++util/endian.h
@@ -0,0 +1,46 @@ 
+#pragma once
+
+#include <type_traits>
+#include <byteswap.h>
+#include <stdint.h>
+
+static_assert((__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) ||
+	      (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__),
+	      "Unable to detect endianness");
+
+enum class endian {
+	little = __ORDER_LITTLE_ENDIAN__,
+	big = __ORDER_BIG_ENDIAN__,
+	native = __BYTE_ORDER__
+};
+
+template<typename T>
+constexpr T byteswap(T value) noexcept
+{
+	static_assert(std::is_integral<T>(), "Type is not integral");
+	static_assert(sizeof(T) == 2 ||
+		      sizeof(T) == 4 ||
+		      sizeof(T) == 8,
+		      "Illegal value size");
+
+	switch (sizeof(T)) {
+		case 2: return bswap_16(value);
+		case 4: return bswap_32(value);
+		case 8: return bswap_64(value);
+	}
+}
+
+template<endian E, typename T>
+static void write_endian(T val, T* dst)
+{
+	if constexpr (E != endian::native)
+		val = byteswap(val);
+
+	*dst = val;
+}
+
+[[maybe_unused]]
+static void write16le(uint16_t val, uint16_t* dst)
+{
+	write_endian<endian::little, uint16_t>(val, dst);
+}