diff options
author | Sven Gothel <[email protected]> | 2021-10-05 15:23:44 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2021-10-05 15:23:44 +0200 |
commit | 415f3d5b813aee53c1413949338e7852b2f0eeb2 (patch) | |
tree | a5cfbc6570345e69672b1b5a1ab7be1e33b85ae8 | |
parent | 04af8674886c2bee92966563c48386c1cd8ce195 (diff) |
EUI48Sub: Add required endian conversion for byte stream ctor (C++ and Java)v0.5.0
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | include/jau/byte_util.hpp | 24 | ||||
-rw-r--r-- | include/jau/eui48.hpp | 13 | ||||
-rw-r--r-- | java_base/org/jau/util/BasicTypes.java | 5 | ||||
-rw-r--r-- | java_net/org/jau/net/EUI48.java | 27 | ||||
-rw-r--r-- | java_net/org/jau/net/EUI48Sub.java | 27 | ||||
-rw-r--r-- | src/eui48.cpp | 13 |
7 files changed, 75 insertions, 38 deletions
@@ -122,8 +122,10 @@ Changes * First stable release (TODO) -**0.4.9** +**0.5.0** +* Bump minor version due to API change +* EUI48Sub: Add required endian conversion for byte stream ctor (C++ and Java) * EUI48[Sub]: Add endian awareness, also fixes indexOf() semantics (C++ and Java) * Octets: Enhance API doc * Octets/ringbuffer: Use std method names for sizes diff --git a/include/jau/byte_util.hpp b/include/jau/byte_util.hpp index db310fa..78a0871 100644 --- a/include/jau/byte_util.hpp +++ b/include/jau/byte_util.hpp @@ -98,33 +98,27 @@ namespace jau { #endif } + constexpr void bswap(uint8_t * const sink, uint8_t const * const source, nsize_t const len) { + for(nsize_t i=0; i < len; ++i) { + sink[i] = source[len-1-i]; + } + } + constexpr uint128_t bswap(uint128_t const & source) noexcept { uint128_t dest; - uint8_t const * const s = source.data; - uint8_t * const d = dest.data; - for(nsize_t i=0; i<16; i++) { - d[i] = s[15-i]; - } + bswap(dest.data, source.data, 16); return dest; } constexpr uint192_t bswap(uint192_t const & source) noexcept { uint192_t dest; - uint8_t const * const s = source.data; - uint8_t * const d = dest.data; - for(nsize_t i=0; i<24; i++) { - d[i] = s[23-i]; - } + bswap(dest.data, source.data, 24); return dest; } constexpr uint256_t bswap(uint256_t const & source) noexcept { uint256_t dest; - uint8_t const * const s = source.data; - uint8_t * const d = dest.data; - for(nsize_t i=0; i<32; i++) { - d[i] = s[31-i]; - } + bswap(dest.data, source.data, 32); return dest; } diff --git a/include/jau/eui48.hpp b/include/jau/eui48.hpp index c4ac5c1..0b1d046 100644 --- a/include/jau/eui48.hpp +++ b/include/jau/eui48.hpp @@ -64,11 +64,16 @@ namespace jau { constexpr EUI48Sub() noexcept : b{0}, length{0} { } /** - * Constructor, copying len_ bytes from given b_ in endian::native byte order. + * Copy len_ address bytes from given source and store it in endian::native byte order. + * + * If given address bytes are not in endian::native byte order, + * they are swapped. + * * @param b_ sub address bytes in endian::native byte order * @param len_ length + * @param byte_order endian::little or endian::big byte order */ - EUI48Sub(const uint8_t * b_, const jau::nsize_t len_) noexcept; + EUI48Sub(const uint8_t * b_, const jau::nsize_t len_, const endian byte_order) noexcept; /** * Fills given EUI48Sub instance via given string representation. @@ -210,9 +215,9 @@ namespace jau { constexpr EUI48() noexcept : b{0} { } /** - * Copy address bytes from given source and store it in endian::native order. + * Copy address bytes from given source and store it in endian::native byte order. * - * If given address bytes are not in endian::native order (littleEndian), + * If given address bytes are not in endian::native byte order, * they are swapped. * * @param source address bytes diff --git a/java_base/org/jau/util/BasicTypes.java b/java_base/org/jau/util/BasicTypes.java index 1ab8358..bb0c404 100644 --- a/java_base/org/jau/util/BasicTypes.java +++ b/java_base/org/jau/util/BasicTypes.java @@ -33,6 +33,11 @@ public class BasicTypes { sink[4+sink_pos] = source[1+source_pos]; sink[5+sink_pos] = source[0+source_pos]; } + public static void bswap(final byte[] source, final int source_pos, final byte[] sink, final int sink_pos, final int len) { + for(int i=0; i < len; ++i) { + sink[i+sink_pos] = source[len-1-i+source_pos]; + } + } /** * Produce a lower-case hexadecimal string representation of the given byte values. diff --git a/java_net/org/jau/net/EUI48.java b/java_net/org/jau/net/EUI48.java index c3ef19f..9b11dd5 100644 --- a/java_net/org/jau/net/EUI48.java +++ b/java_net/org/jau/net/EUI48.java @@ -41,11 +41,11 @@ import java.nio.ByteOrder; */ public class EUI48 { /** EUI48 MAC address matching any device, i.e. '0:0:0:0:0:0'. */ - public static final EUI48 ANY_DEVICE = new EUI48( new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }, ByteOrder.nativeOrder() ); + public static final EUI48 ANY_DEVICE = new EUI48( new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }, ByteOrder.LITTLE_ENDIAN ); /** EUI48 MAC address matching all device, i.e. 'ff:ff:ff:ff:ff:ff'. */ - public static final EUI48 ALL_DEVICE = new EUI48( new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }, ByteOrder.nativeOrder() ); + public static final EUI48 ALL_DEVICE = new EUI48( new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }, ByteOrder.LITTLE_ENDIAN ); /** EUI48 MAC address matching local device, i.e. '0:0:0:ff:ff:ff'. */ - public static final EUI48 LOCAL_DEVICE = new EUI48( new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0xff }, ByteOrder.nativeOrder() ); + public static final EUI48 LOCAL_DEVICE = new EUI48( new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0xff }, ByteOrder.LITTLE_ENDIAN ); /** * The 6 byte EUI48 address. @@ -116,7 +116,16 @@ public class EUI48 { } } - /** Construct instance via given source byte array */ + /** + * Copy address bytes from given source and store it in {@link ByteOrder#nativeOrder()} byte order. + * + * If given address bytes are not in {@link ByteOrder#nativeOrder()} byte order, + * they are swapped. + * + * @param stream address bytes + * @param pos position in stream at address + * @param byte_order {@link ByteOrder#LITTLE_ENDIAN} or {@link ByteOrder#BIG_ENDIAN} byte order + */ public EUI48(final byte stream[], final int pos, final ByteOrder byte_order) { if( byte_size > ( stream.length - pos ) ) { throw new IllegalArgumentException("EUI48 stream ( "+stream.length+" - "+pos+" ) < "+byte_size+" bytes"); @@ -129,7 +138,15 @@ public class EUI48 { } } - /** Construct instance using the given address of the byte array */ + /** + * Copy address bytes from given source and store it in {@link ByteOrder#nativeOrder()} byte order. + * + * If given address bytes are not in {@link ByteOrder#nativeOrder()} byte order, + * they are swapped. + * + * @param address address bytes + * @param byte_order {@link ByteOrder#LITTLE_ENDIAN} or {@link ByteOrder#BIG_ENDIAN} byte order + */ public EUI48(final byte address[], final ByteOrder byte_order) { if( byte_size != address.length ) { throw new IllegalArgumentException("EUI48 stream "+address.length+" != "+byte_size+" bytes"); diff --git a/java_net/org/jau/net/EUI48Sub.java b/java_net/org/jau/net/EUI48Sub.java index aacb02d..8c2eee3 100644 --- a/java_net/org/jau/net/EUI48Sub.java +++ b/java_net/org/jau/net/EUI48Sub.java @@ -36,11 +36,11 @@ import org.jau.util.BasicTypes; */ public class EUI48Sub { /** EUI48Sub MAC address matching any device, i.e. '0:0:0:0:0:0'. */ - public static final EUI48Sub ANY_DEVICE = new EUI48Sub( new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }, 0, 6 ); + public static final EUI48Sub ANY_DEVICE = new EUI48Sub( new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00 }, 0, 6, ByteOrder.LITTLE_ENDIAN ); /** EUI48Sub MAC address matching all device, i.e. 'ff:ff:ff:ff:ff:ff'. */ - public static final EUI48Sub ALL_DEVICE = new EUI48Sub( new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }, 0, 6 ); + public static final EUI48Sub ALL_DEVICE = new EUI48Sub( new byte[] { (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff }, 0, 6, ByteOrder.LITTLE_ENDIAN ); /** EUI48Sub MAC address matching local device, i.e. '0:0:0:ff:ff:ff'. */ - public static final EUI48Sub LOCAL_DEVICE = new EUI48Sub( new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0xff }, 0, 6 ); + public static final EUI48Sub LOCAL_DEVICE = new EUI48Sub( new byte[] { (byte)0x00, (byte)0x00, (byte)0x00, (byte)0xff, (byte)0xff, (byte)0xff }, 0, 6, ByteOrder.LITTLE_ENDIAN ); /** * The EUI48 sub-address, always 6 bytes reserved. @@ -137,17 +137,26 @@ public class EUI48Sub { } /** - * Constructor, copying len_ bytes from given b_ in native byte order. - * @param stream sub address bytes in native byte order - * @param pos start position in stream - * @param len_ length + * Copy len_ address bytes from given source and store it in {@link ByteOrder#nativeOrder()} byte order. + * + * If given address bytes are not in {@link ByteOrder#nativeOrder()} byte order, + * they are swapped. + * + * @param stream address bytes + * @param pos position in stream at address + * @param len_ number of address bytes + * @param byte_order {@link ByteOrder#LITTLE_ENDIAN} or {@link ByteOrder#BIG_ENDIAN} byte order */ - public EUI48Sub(final byte stream[], final int pos, final int len_) { + public EUI48Sub(final byte stream[], final int pos, final int len_, final ByteOrder byte_order) { if( len_ > EUI48.byte_size || pos + len_ > stream.length ) { throw new IllegalArgumentException("EUI48 stream ( pos "+pos+", len "+len_+" > EUI48 size "+EUI48.byte_size+" or stream.length "+stream.length); } b = new byte[6]; - System.arraycopy(stream, pos, b, 0, len_); + if( byte_order == ByteOrder.nativeOrder() ) { + System.arraycopy(stream, pos, b, 0, len_); + } else { + BasicTypes.bswap(stream, pos, b, 0, len_); + } length = len_; } diff --git a/src/eui48.cpp b/src/eui48.cpp index e6164a4..1879a53 100644 --- a/src/eui48.cpp +++ b/src/eui48.cpp @@ -112,11 +112,16 @@ EUI48Sub::EUI48Sub(const std::string& str) { } } -EUI48Sub::EUI48Sub(const uint8_t * b_, const jau::nsize_t len_) noexcept { +EUI48Sub::EUI48Sub(const uint8_t * b_, const jau::nsize_t len_, const endian byte_order) noexcept { length = len_; const jau::nsize_t cpsz = std::max<jau::nsize_t>(sizeof(b), len_); const jau::nsize_t bzsz = sizeof(b) - cpsz; - memcpy(b, b_, cpsz); + + if( endian::little == byte_order ) { + memcpy(b, b_, cpsz); + } else { + bswap(b, b_, cpsz); + } if( bzsz > 0 ) { bzero(b+cpsz, bzsz); } @@ -249,8 +254,8 @@ static uint8_t _EUI48_ALL_DEVICE[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; static uint8_t _EUI48_LOCAL_DEVICE[] = {0x00, 0x00, 0x00, 0xff, 0xff, 0xff}; const EUI48Sub jau::EUI48Sub::ANY_DEVICE; // default ctor is zero bytes! -const EUI48Sub jau::EUI48Sub::ALL_DEVICE( _EUI48_ALL_DEVICE, 6); -const EUI48Sub jau::EUI48Sub::LOCAL_DEVICE( _EUI48_LOCAL_DEVICE, 6); +const EUI48Sub jau::EUI48Sub::ALL_DEVICE( _EUI48_ALL_DEVICE, 6, endian::little ); +const EUI48Sub jau::EUI48Sub::LOCAL_DEVICE( _EUI48_LOCAL_DEVICE, 6, endian::little ); const EUI48 jau::EUI48::ANY_DEVICE; // default ctor is zero bytes! const EUI48 jau::EUI48::ALL_DEVICE( _EUI48_ALL_DEVICE, endian::little ); |