aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2021-10-05 15:23:44 +0200
committerSven Gothel <[email protected]>2021-10-05 15:23:44 +0200
commit415f3d5b813aee53c1413949338e7852b2f0eeb2 (patch)
treea5cfbc6570345e69672b1b5a1ab7be1e33b85ae8
parent04af8674886c2bee92966563c48386c1cd8ce195 (diff)
EUI48Sub: Add required endian conversion for byte stream ctor (C++ and Java)v0.5.0
-rw-r--r--README.md4
-rw-r--r--include/jau/byte_util.hpp24
-rw-r--r--include/jau/eui48.hpp13
-rw-r--r--java_base/org/jau/util/BasicTypes.java5
-rw-r--r--java_net/org/jau/net/EUI48.java27
-rw-r--r--java_net/org/jau/net/EUI48Sub.java27
-rw-r--r--src/eui48.cpp13
7 files changed, 75 insertions, 38 deletions
diff --git a/README.md b/README.md
index a771ff4..b45fb1e 100644
--- a/README.md
+++ b/README.md
@@ -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 );