From f7e0486d2f9651c956662f667b5e09f0c3ca5d0e Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Tue, 23 Oct 2018 16:58:49 +0200
Subject: [PATCH 001/118] Chain allocate() with empty() constructor
---
src/main/java/at/favre/lib/bytes/Bytes.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/at/favre/lib/bytes/Bytes.java b/src/main/java/at/favre/lib/bytes/Bytes.java
index d320032..f366aeb 100644
--- a/src/main/java/at/favre/lib/bytes/Bytes.java
+++ b/src/main/java/at/favre/lib/bytes/Bytes.java
@@ -98,7 +98,7 @@ public static Bytes allocate(int length) {
* @return new instance
*/
public static Bytes allocate(int length, byte defaultValue) {
- if (length == 0) return EMPTY;
+ if (length == 0) return empty();
byte[] array = new byte[length];
if (defaultValue != 0) {
Arrays.fill(array, defaultValue);
From bafec35ccc94b374ba3e5b60148c364cd039adec Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Tue, 23 Oct 2018 17:00:04 +0200
Subject: [PATCH 002/118] Small typo in readme
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 7cddfbf..ec9a774 100644
--- a/README.md
+++ b/README.md
@@ -250,7 +250,7 @@ import static at.favre.lib.bytes.BytesTransformers.*;
```java
Bytes.wrap(array).transform(hmacSha256(macKey32Byte));
Bytes.wrap(array).transform(hmacSha1(macKey20Byte));
-Bytes.wrap(array).transform(hmac(macKey20Byte,"HmacMd5"));
+Bytes.wrap(array).transform(hmac(macKey16Byte,"HmacMd5"));
```
**Checksum** can be calculated or automatically appended:
From 6ad6e193b9ec1a5bdd8dfb14cb1628157e611404 Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Tue, 23 Oct 2018 17:16:56 +0200
Subject: [PATCH 003/118] Use faster container based build ci config
---
.travis.yml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index 990edbc..6093a6b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,7 @@
# To let the CI execute the maven wrapper, use this command and push the change:
# git update-index --chmod=+x mvnw
+sudo: false # route your build to the container-based infrastructure for a faster build
language: java
install: true
jdk:
@@ -48,4 +49,4 @@ cache:
notifications:
slack:
secure: "PiEdsZoQlBR7ce6IT9LlxWod2XqWjm8HCxs4yP8o9iI5ix7FxEV8NDGQKY1vcDG6D8bz4gcNsBxJrPKASD0G3rLaJpjA4L9MUNhyx+4VCIBBnT1fwV+as+PJmr1tZupqUnlxZJyTdiaqkV8jtjCkHUn3P6TURbNuZws74/ki2rICbi4EebD3mdeQvFtWYKTOsAgZjLecMvPU9q+b7TAwDlaZFbkG7DMFruT8i7tA/EWMOvI48kVaUEM0QPsAxNdr32YFta0s/xJyNuOp1Hp3ZZbnZgXgKc2WvGRcg+9sucnQ+eQsQKj1tbWS2YwxHcy7B3Q7YDmBL2NIJIHbuaWNlbK9fVh3gdk7Knlr8IHpLmVuHvH3HAF6JDcrARjk8ViVP2HafkkDNbQZLupz5LkJ02hj1DMGVOAyuVTt6IpOMt3WTaQ66qtyGupQXhrqvq8tDwvg6FIy1sjPZbWE/Sq1s20PYBbHkVwNvQ3bNaC44nAkcnTv+dAoazvy8G40RIPovTO1ubzriZvuY8Db4THF2ZL1mDbyHEJstA7L9qkObqZOwnFsy5pLp4NfR9C/bTAY8EUcZVGm0spIADafip2H57Hf+n3co4aqw689t+Y453AUh3W+k4ZsC/V1kzX3MVdcluRP7ET8ejtfwduMyh2/jFmUK3g246/teEssyohp6ik="
- email: false
\ No newline at end of file
+ email: false
From c3f7239d0a0a397598e2638584efcfd8d916754d Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Wed, 24 Oct 2018 16:32:18 +0200
Subject: [PATCH 004/118] Add new from() constructor using char[] which accept
offset + length
fixes #24
---
CHANGELOG | 1 +
src/main/java/at/favre/lib/bytes/Bytes.java | 20 ++++++--
src/main/java/at/favre/lib/bytes/Util.java | 51 ++++++++++++++++++-
.../lib/bytes/BytesConstructorTests.java | 2 +
.../java/at/favre/lib/bytes/UtilTest.java | 48 +++++++++++++++++
5 files changed, 115 insertions(+), 7 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index f4da4b9..45d3196 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -6,6 +6,7 @@
* add support for Base32 RFC4648 non-hex alphabet encoding/parsing #21
* add constructor for `IntBuffer` and `CharBuffer`
* `parse()` methods now expect more flexible `CharSequence` instead of `String` #23
+* `from()` constructor reading from `char[]` has new version that accepts offset and length #24
### Breaking
diff --git a/src/main/java/at/favre/lib/bytes/Bytes.java b/src/main/java/at/favre/lib/bytes/Bytes.java
index f366aeb..f053288 100644
--- a/src/main/java/at/favre/lib/bytes/Bytes.java
+++ b/src/main/java/at/favre/lib/bytes/Bytes.java
@@ -199,7 +199,7 @@ public static Bytes fromNullSafe(byte[] byteArrayToCopy) {
* Creates a new instance from a slice of given array
*
* @param array to slice
- * @param offset stat position
+ * @param offset start position
* @param length length
* @return new instance
*/
@@ -520,10 +520,20 @@ public static Bytes from(char[] charArray) {
* @return new instance
*/
public static Bytes from(char[] charArray, Charset charset) {
- ByteBuffer bb = charset.encode(CharBuffer.wrap(charArray));
- byte[] bytes = new byte[bb.remaining()];
- bb.get(bytes);
- return from(bytes);
+ return from(charArray, charset, 0, charArray.length);
+ }
+
+ /**
+ * Creates a new instance from given char array with given range. The array will be handles like an encoded string
+ *
+ * @param charArray to get the internal byte array from
+ * @param charset charset to be used to decode the char array
+ * @param offset start position (from given char array not encoded byte array out)
+ * @param length length in relation to offset (from given char array not encoded byte array out)
+ * @return new instance
+ */
+ public static Bytes from(char[] charArray, Charset charset, int offset, int length) {
+ return from(Util.charToByteArray(charArray, charset, offset, length));
}
/**
diff --git a/src/main/java/at/favre/lib/bytes/Util.java b/src/main/java/at/favre/lib/bytes/Util.java
index a026718..b4aaf61 100644
--- a/src/main/java/at/favre/lib/bytes/Util.java
+++ b/src/main/java/at/favre/lib/bytes/Util.java
@@ -21,11 +21,27 @@
package at.favre.lib.bytes;
-import java.io.*;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInput;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
import java.nio.file.Files;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.Random;
+import java.util.UUID;
/**
* Common Util methods to convert or modify byte arrays
@@ -373,6 +389,37 @@ static byte[] readFromFile(File file) {
}
}
+ /**
+ * Converts a char array to a byte array with given charset and range
+ *
+ * @param charArray to get the byte array from
+ * @param charset charset to be used to decode the char array
+ * @param offset to start reading the char array from (must be smaller than length and gt 0)
+ * @param length from offset (must be between 0 and charArray.length)
+ * @return byte array of encoded chars
+ */
+ static byte[] charToByteArray(char[] charArray, Charset charset, int offset, int length) {
+ if (offset < 0 || offset > charArray.length)
+ throw new IllegalArgumentException("offset must be gt 0 and smaller than array length");
+ if (length < 0 || length > charArray.length)
+ throw new IllegalArgumentException("length must be at least 1 and less than array length");
+ if (offset + length > charArray.length)
+ throw new IllegalArgumentException("length + offset must be smaller than array length");
+
+ if (length == 0) return new byte[0];
+
+ CharBuffer charBuffer = CharBuffer.wrap(charArray);
+
+ if (offset != 0 || length != charBuffer.remaining()) {
+ charBuffer = charBuffer.subSequence(offset, offset + length);
+ }
+
+ ByteBuffer bb = charset.encode(charBuffer);
+ byte[] bytes = new byte[bb.remaining()];
+ bb.get(bytes);
+ return bytes;
+ }
+
/**
* Shows the length and a preview of max 8 bytes of the given byte
*
diff --git a/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java b/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java
index 33f8a81..38f1d88 100644
--- a/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java
+++ b/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java
@@ -294,6 +294,8 @@ public void fromCharArray() {
assertArrayEquals(String.valueOf(s1.toCharArray()).getBytes(StandardCharsets.ISO_8859_1), Bytes.from(s1.toCharArray(), StandardCharsets.ISO_8859_1).array());
assertArrayEquals(String.valueOf(s1.toCharArray()).getBytes(StandardCharsets.UTF_16), Bytes.from(s1.toCharArray(), StandardCharsets.UTF_16).array());
assertArrayEquals(String.valueOf(s1.toCharArray()).getBytes(StandardCharsets.UTF_8), Bytes.from(s1.toCharArray(), StandardCharsets.UTF_8).array());
+ assertArrayEquals(String.valueOf(s1.substring(0, 1).toCharArray()).getBytes(StandardCharsets.UTF_8), Bytes.from(s1.toCharArray(), StandardCharsets.UTF_8, 0, 1).array());
+ assertArrayEquals(String.valueOf(s1.substring(3, 7).toCharArray()).getBytes(StandardCharsets.UTF_8), Bytes.from(s1.toCharArray(), StandardCharsets.UTF_8, 3, 4).array());
assertArrayEquals(Bytes.empty().array(), Bytes.from(CharBuffer.allocate(0)).array());
}
diff --git a/src/test/java/at/favre/lib/bytes/UtilTest.java b/src/test/java/at/favre/lib/bytes/UtilTest.java
index 2ee4302..ba0d15a 100644
--- a/src/test/java/at/favre/lib/bytes/UtilTest.java
+++ b/src/test/java/at/favre/lib/bytes/UtilTest.java
@@ -25,6 +25,8 @@
import org.junit.Test;
import java.math.BigInteger;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
@@ -299,4 +301,50 @@ public void testRightShiftAgainstRefImpl() {
}
}
}
+
+ @Test
+ public void testCharToByteArray() {
+ Charset[] charsets = new Charset[]{StandardCharsets.UTF_8, StandardCharsets.US_ASCII, StandardCharsets.UTF_16};
+ for (Charset charset : charsets) {
+ checkCharArrayToByteArray("".toCharArray(), charset);
+ checkCharArrayToByteArray("A".toCharArray(), charset);
+ checkCharArrayToByteArray("12".toCharArray(), charset);
+ checkCharArrayToByteArray("XYZ".toCharArray(), charset);
+ checkCharArrayToByteArray("abcdefg".toCharArray(), charset);
+ checkCharArrayToByteArray("71oh872gdl2dhp81g".toCharArray(), charset);
+
+ }
+
+ checkCharArrayToByteArray("யe2ாமறிந்தиют убSîne klâwenasd1".toCharArray(), StandardCharsets.UTF_8);
+ }
+
+ private void checkCharArrayToByteArray(char[] subject, Charset charset) {
+ for (int lenI = 1; lenI < subject.length + 1; lenI++) {
+ for (int offsetI = 0; offsetI < subject.length; offsetI++) {
+ if (offsetI + lenI > subject.length) break;
+ byte[] bytes = Util.charToByteArray(subject, charset, offsetI, lenI);
+ assertEquals(Bytes.wrap(bytes), Bytes.wrap(new String(subject).substring(offsetI, offsetI + lenI).getBytes(charset)));
+ }
+ }
+ compareArrayToByteArrayWithoutOffset(subject, charset);
+ }
+
+ private void compareArrayToByteArrayWithoutOffset(char[] subject, Charset charset) {
+ assertArrayEquals(Util.charToByteArray(subject, charset, 0, subject.length), new String(subject).getBytes(charset));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCharToByteArrayIllegalOffset() {
+ Util.charToByteArray("abcdef".toCharArray(), StandardCharsets.UTF_8, -1, 1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCharToByteArrayIllegalLength() {
+ Util.charToByteArray("abcdef".toCharArray(), StandardCharsets.UTF_8, 0, -1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCharToByteArrayIllegalOffsetPlusLength() {
+ Util.charToByteArray("abcdef".toCharArray(), StandardCharsets.UTF_8, 4, 3);
+ }
}
From 1b236d8404558b9dc3a3d8cb86de3a52d5ee85fc Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Wed, 24 Oct 2018 18:05:45 +0200
Subject: [PATCH 005/118] Add `from()` constructor reading file with offset and
length parameter
fixes #25
---
CHANGELOG | 1 +
src/main/java/at/favre/lib/bytes/Bytes.java | 15 +++++++
src/main/java/at/favre/lib/bytes/Util.java | 29 ++++++++++++--
.../lib/bytes/BytesConstructorTests.java | 39 ++++++++++++++++++-
4 files changed, 80 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 45d3196..b800850 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -7,6 +7,7 @@
* add constructor for `IntBuffer` and `CharBuffer`
* `parse()` methods now expect more flexible `CharSequence` instead of `String` #23
* `from()` constructor reading from `char[]` has new version that accepts offset and length #24
+* add `from()` constructor reading file with offset and length parameter #25
### Breaking
diff --git a/src/main/java/at/favre/lib/bytes/Bytes.java b/src/main/java/at/favre/lib/bytes/Bytes.java
index f053288..11bb184 100644
--- a/src/main/java/at/favre/lib/bytes/Bytes.java
+++ b/src/main/java/at/favre/lib/bytes/Bytes.java
@@ -470,6 +470,21 @@ public static Bytes from(File file) {
return wrap(Util.readFromFile(file));
}
+ /**
+ * Reads given file and returns the byte content. Be aware that the whole defined file content will be loaded to
+ * memory, so be careful what to read in. This uses {@link java.io.RandomAccessFile} under the hood.
+ *
+ * @param file to read from
+ * @param offset byte offset from zero position of the file
+ * @param length to read from offset
+ * @return new instance
+ * @throws IllegalArgumentException if file does not exist
+ * @throws IllegalStateException if file could not be read
+ */
+ public static Bytes from(File file, int offset, int length) {
+ return wrap(Util.readFromFile(file, offset, length));
+ }
+
/**
* Creates a new instance from given utf-8 encoded string
*
diff --git a/src/main/java/at/favre/lib/bytes/Util.java b/src/main/java/at/favre/lib/bytes/Util.java
index b4aaf61..8db07d5 100644
--- a/src/main/java/at/favre/lib/bytes/Util.java
+++ b/src/main/java/at/favre/lib/bytes/Util.java
@@ -26,6 +26,7 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
@@ -378,9 +379,7 @@ static byte[] concatVararg(byte firstByte, byte[] moreBytes) {
* @return byte content
*/
static byte[] readFromFile(File file) {
- if (file == null || !file.exists() || !file.isFile()) {
- throw new IllegalArgumentException("file must not be null, has to exist and must be a file (not a directory) " + file);
- }
+ checkFile(file);
try {
return Files.readAllBytes(file.toPath());
@@ -389,6 +388,30 @@ static byte[] readFromFile(File file) {
}
}
+ /**
+ * Reads bytes from file with given offset and max length
+ *
+ * @param file to read bytes from
+ * @param offset to read
+ * @param length from offset
+ * @return byte array with length length
+ */
+ static byte[] readFromFile(File file, int offset, int length) {
+ checkFile(file);
+ try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
+ raf.seek(offset);
+ return readFromDataInput(raf, length);
+ } catch (Exception e) {
+ throw new IllegalStateException("could not read from random access file", e);
+ }
+ }
+
+ private static void checkFile(File file) {
+ if (file == null || !file.exists() || !file.isFile()) {
+ throw new IllegalArgumentException("file must not be null, has to exist and must be a file (not a directory) " + file);
+ }
+ }
+
/**
* Converts a char array to a byte array with given charset and range
*
diff --git a/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java b/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java
index 38f1d88..ff18e35 100644
--- a/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java
+++ b/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java
@@ -456,7 +456,44 @@ public void fromFileCannotRead() throws Exception {
try {
Bytes.from(tempFile);
fail();
- } catch (IllegalStateException e) {
+ } catch (IllegalStateException ignored) {
+ }
+ }
+
+ @Test
+ public void fromFileOffset() throws Exception {
+ File tempFile = testFolder.newFile("out-test2.txt");
+ Bytes bytes = Bytes.wrap(new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18});
+ try (FileOutputStream stream = new FileOutputStream(tempFile)) {
+ stream.write(bytes.array());
+ }
+
+ for (int lenI = 1; lenI < bytes.length() + 1; lenI++) {
+ for (int offsetI = 0; offsetI < bytes.length(); offsetI++) {
+ if (offsetI + lenI > bytes.length()) break;
+ assertEquals(bytes.copy(offsetI, lenI), Bytes.from(tempFile, offsetI, lenI));
+ }
+ }
+ assertEquals(Bytes.from(tempFile), Bytes.from(tempFile, 0, (int) tempFile.length()));
+ }
+
+ @Test
+ public void fromFileOffsetWithIllegalOffsetOrLength() throws Exception {
+ File tempFile = testFolder.newFile("fromFileOffsetWithIllegalOffsetOrLength.txt");
+ try (FileOutputStream stream = new FileOutputStream(tempFile)) {
+ stream.write(new byte[]{0, 1, 2, 3});
+ }
+
+ try {
+ Bytes.from(tempFile, 0, 5);
+ fail();
+ } catch (IllegalStateException ignored) {
+ }
+
+ try {
+ Bytes.from(tempFile, 5, 1);
+ fail();
+ } catch (IllegalStateException ignored) {
}
}
From 9e61b07693b13dd98642810fb9b8c7281bc8adeb Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Wed, 24 Oct 2018 18:35:46 +0200
Subject: [PATCH 006/118] Bump version to 1.0.0
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index c47c5a9..632db64 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
at.favre.libbytes
- 0.8.0
+ 1.0.0jarBytes Utility Library
From 639d91d6e71f1dc958eb87c21e077476d23eb7f4 Mon Sep 17 00:00:00 2001
From: pfavre
Date: Tue, 30 Oct 2018 00:19:52 +0100
Subject: [PATCH 007/118] Add `append()` method supporting multiple byte arrays
fixes #26
---
CHANGELOG | 4 +++
src/main/java/at/favre/lib/bytes/Bytes.java | 33 +++++++++----------
.../favre/lib/bytes/BytesTransformTest.java | 10 ++++++
3 files changed, 29 insertions(+), 18 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index b800850..3c9c66f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,9 @@
# Releases
+## v1.0.0
+
+* add `append()` method supporting multiple byte arrays #26
+
## v0.8.0
* add radix encoding/parsing and fix radix tests #6, #20
diff --git a/src/main/java/at/favre/lib/bytes/Bytes.java b/src/main/java/at/favre/lib/bytes/Bytes.java
index 11bb184..39b376e 100644
--- a/src/main/java/at/favre/lib/bytes/Bytes.java
+++ b/src/main/java/at/favre/lib/bytes/Bytes.java
@@ -21,29 +21,14 @@
package at.favre.lib.bytes;
-import java.io.ByteArrayInputStream;
-import java.io.DataInput;
-import java.io.File;
-import java.io.InputStream;
-import java.io.Serializable;
+import java.io.*;
import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.CharBuffer;
-import java.nio.IntBuffer;
-import java.nio.ReadOnlyBufferException;
+import java.nio.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.text.Normalizer;
-import java.util.Arrays;
-import java.util.BitSet;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Objects;
-import java.util.Random;
-import java.util.UUID;
+import java.util.*;
/**
* Bytes is wrapper class for an byte-array that allows a lot of convenience operations on it:
@@ -777,6 +762,18 @@ public Bytes append(long long8Bytes) {
return append(Bytes.from(long8Bytes));
}
+ /**
+ * Creates a new instance with the current array appended to the provided data (ie. append at the end).
+ * You may use this to append multiple byte arrays without the need for chaining the {@link #append(byte[])} call
+ * and therefore generating intermediate copies of the byte array, making this approach use less memory.
+ *
+ * @param arrays to append
+ * @return appended instance
+ */
+ public Bytes append(byte[]... arrays) {
+ return append(Bytes.from(arrays));
+ }
+
/**
* Creates a new instance with the current array appended to the provided data (ie. append at the end)
*
diff --git a/src/test/java/at/favre/lib/bytes/BytesTransformTest.java b/src/test/java/at/favre/lib/bytes/BytesTransformTest.java
index 82166a3..780929b 100644
--- a/src/test/java/at/favre/lib/bytes/BytesTransformTest.java
+++ b/src/test/java/at/favre/lib/bytes/BytesTransformTest.java
@@ -47,6 +47,16 @@ public void append() {
assertArrayEquals(Util.concat(example_bytes_eight, example_bytes_sixteen), Bytes.from(example_bytes_eight).append(Bytes.from(example_bytes_sixteen)).array());
}
+ @Test
+ public void appendMultipleByteArrays() {
+ assertArrayEquals(new byte[0], Bytes.from(new byte[0]).append(new byte[0], new byte[0]).array());
+ assertArrayEquals(new byte[]{0x0, 0x01, 0x02, 0x03}, Bytes.from(new byte[]{0x0}).append(new byte[]{0x1}, new byte[]{0x2}, new byte[]{0x3}).array());
+ assertArrayEquals(Util.concat(example_bytes_seven, example_bytes_one, example_bytes_sixteen), Bytes.from(example_bytes_seven).append(example_bytes_one, example_bytes_sixteen).array());
+ assertArrayEquals(Util.concat(example_bytes_sixteen, example_bytes_sixteen, example_bytes_sixteen), Bytes.from(example_bytes_sixteen).append(example_bytes_sixteen, example_bytes_sixteen).array());
+ assertArrayEquals(Util.concat(example_bytes_two, example_bytes_seven, example_bytes_twentyfour, example_bytes_eight), Bytes.from(example_bytes_two).append(example_bytes_seven, example_bytes_twentyfour, example_bytes_eight).array());
+ assertArrayEquals(Util.concat(example_bytes_two, example_bytes_seven, example_bytes_twentyfour, example_bytes_one, example_bytes_sixteen), Bytes.from(example_bytes_two).append(example_bytes_seven, example_bytes_twentyfour).append(example_bytes_one, example_bytes_sixteen).array());
+ }
+
@Test
public void appendNullSafe() {
assertArrayEquals(new byte[0], Bytes.from(new byte[0]).appendNullSafe(new byte[0]).array());
From 02c27b5cda80af9fd5cce03c74f0445dd1831b20 Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Wed, 31 Oct 2018 20:55:24 +0100
Subject: [PATCH 008/118] Add `toCharArray()` method which decodes internal
byte array to char[]
---
CHANGELOG | 1 +
src/main/java/at/favre/lib/bytes/Bytes.java | 21 ++++++++
src/main/java/at/favre/lib/bytes/Util.java | 53 ++++++++++++-------
.../lib/bytes/BytesConstructorTests.java | 35 ++++++++++--
4 files changed, 85 insertions(+), 25 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 3c9c66f..3db8817 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,6 +3,7 @@
## v1.0.0
* add `append()` method supporting multiple byte arrays #26
+* add `toCharArray()` method which decodes internal byte array to char[] #27
## v0.8.0
diff --git a/src/main/java/at/favre/lib/bytes/Bytes.java b/src/main/java/at/favre/lib/bytes/Bytes.java
index 39b376e..a7b5f2b 100644
--- a/src/main/java/at/favre/lib/bytes/Bytes.java
+++ b/src/main/java/at/favre/lib/bytes/Bytes.java
@@ -1889,6 +1889,27 @@ public double toDouble() {
return internalBuffer().getDouble();
}
+ /**
+ * Decodes the internal byte array to UTF-8 char array.
+ * This implementation will not internally create a {@link String}.
+ *
+ * @return char array
+ */
+ public char[] toCharArray() {
+ return toCharArray(StandardCharsets.UTF_8);
+ }
+
+ /**
+ * Decodes the internal byte array with given charset to a char array.
+ * This implementation will not internally create a {@link String}.
+ *
+ * @param charset to use for decoding
+ * @return char array
+ */
+ public char[] toCharArray(Charset charset) {
+ return Util.byteToCharArray(internalArray(), charset);
+ }
+
/**
* Compares this bytes instance to another.
*
diff --git a/src/main/java/at/favre/lib/bytes/Util.java b/src/main/java/at/favre/lib/bytes/Util.java
index 8db07d5..ff78531 100644
--- a/src/main/java/at/favre/lib/bytes/Util.java
+++ b/src/main/java/at/favre/lib/bytes/Util.java
@@ -21,28 +21,14 @@
package at.favre.lib.bytes;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInput;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.RandomAccessFile;
+import java.io.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
+import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Objects;
-import java.util.Random;
-import java.util.UUID;
+import java.util.*;
/**
* Common Util methods to convert or modify byte arrays
@@ -438,9 +424,36 @@ static byte[] charToByteArray(char[] charArray, Charset charset, int offset, int
}
ByteBuffer bb = charset.encode(charBuffer);
- byte[] bytes = new byte[bb.remaining()];
- bb.get(bytes);
- return bytes;
+ if (bb.capacity() != bb.limit()) {
+ byte[] bytes = new byte[bb.remaining()];
+ bb.get(bytes);
+ return bytes;
+ }
+ return bb.array();
+ }
+
+ /**
+ * Convert given byte array in given encoding to char array
+ *
+ * @param bytes as data source
+ * @param charset of the byte array
+ * @return char array
+ */
+ static char[] byteToCharArray(byte[] bytes, Charset charset) {
+ Objects.requireNonNull(bytes, "bytes must not be null");
+ Objects.requireNonNull(charset, "charset must not be null");
+
+ try {
+ CharBuffer charBuffer = charset.newDecoder().decode(ByteBuffer.wrap(bytes));
+ if (charBuffer.capacity() != charBuffer.limit()) {
+ char[] compacted = new char[charBuffer.remaining()];
+ charBuffer.get(compacted);
+ return compacted;
+ }
+ return charBuffer.array();
+ } catch (CharacterCodingException e) {
+ throw new IllegalStateException(e);
+ }
}
/**
diff --git a/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java b/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java
index ff18e35..44711af 100644
--- a/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java
+++ b/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java
@@ -26,11 +26,7 @@
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-import java.io.ByteArrayInputStream;
-import java.io.DataInput;
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
+import java.io.*;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -299,6 +295,35 @@ public void fromCharArray() {
assertArrayEquals(Bytes.empty().array(), Bytes.from(CharBuffer.allocate(0)).array());
}
+ @Test
+ public void toCharArray() {
+ String unicodeString = "|µ€@7é8ahslishalsdalöskdḼơᶉëᶆ ȋṕšᶙṁ ḍỡḽǭᵳ ʂǐť ӓṁệẗ, ĉṓɲṩḙċ";
+ assertArrayEquals(Bytes.from(unicodeString.toCharArray()).array(), Bytes.from(Bytes.from(unicodeString).toCharArray()).array());
+
+ checkToCharArray(unicodeString, StandardCharsets.UTF_8);
+ checkToCharArray(unicodeString, StandardCharsets.UTF_16);
+ checkToCharArray(unicodeString, StandardCharsets.UTF_16BE);
+
+ String asciiString = "asciiASCIIString1234$%&";
+
+ checkToCharArray(asciiString, StandardCharsets.UTF_8);
+ checkToCharArray(asciiString, StandardCharsets.UTF_16);
+ checkToCharArray(asciiString, StandardCharsets.US_ASCII);
+ checkToCharArray(asciiString, StandardCharsets.ISO_8859_1);
+ }
+
+ private void checkToCharArray(String string, Charset charset) {
+ byte[] b0 = String.valueOf(string.toCharArray()).getBytes(charset);
+ char[] charArray = Bytes.from(b0).toCharArray(charset);
+ assertEquals(string, new String(charArray));
+ assertArrayEquals(string.toCharArray(), Bytes.from(string.toCharArray(), charset).toCharArray(charset));
+ }
+
+ @Test(expected = NullPointerException.class)
+ public void toCharArrayShouldThroughNullPointer() {
+ Bytes.allocate(4).toCharArray(null);
+ }
+
@Test
public void fromMultipleBytes() {
assertArrayEquals(new byte[]{0x01, 0x02, 0x03}, Bytes.from(Bytes.from((byte) 0x01), Bytes.from((byte) 0x02), Bytes.from((byte) 0x03)).array());
From 8a449bd06b101c5835ac0fcebef4d6ed59c1e2ce Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Thu, 3 Jan 2019 15:17:32 +0100
Subject: [PATCH 009/118] Minor performance improvement en/decoding hex
---
.../at/favre/lib/bytes/BinaryToTextEncoding.java | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/src/main/java/at/favre/lib/bytes/BinaryToTextEncoding.java b/src/main/java/at/favre/lib/bytes/BinaryToTextEncoding.java
index e7aa2a4..8533dcf 100644
--- a/src/main/java/at/favre/lib/bytes/BinaryToTextEncoding.java
+++ b/src/main/java/at/favre/lib/bytes/BinaryToTextEncoding.java
@@ -87,10 +87,12 @@ public String encode(byte[] byteArray, ByteOrder byteOrder) {
StringBuilder sb = new StringBuilder(byteArray.length * 2);
int index;
+ char first4Bit;
+ char last4Bit;
for (int i = 0; i < byteArray.length; i++) {
index = (byteOrder == ByteOrder.BIG_ENDIAN) ? i : byteArray.length - i - 1;
- char first4Bit = Character.forDigit((byteArray[index] >> 4) & 0xF, 16);
- char last4Bit = Character.forDigit((byteArray[index] & 0xF), 16);
+ first4Bit = Character.forDigit((byteArray[index] >> 4) & 0xF, 16);
+ last4Bit = Character.forDigit((byteArray[index] & 0xF), 16);
if (upperCase) {
first4Bit = Character.toUpperCase(first4Bit);
last4Bit = Character.toUpperCase(last4Bit);
@@ -115,9 +117,11 @@ public byte[] decode(CharSequence hexString) {
int len = hexString.length();
byte[] data = new byte[(len - start) / 2];
+ int first4Bits;
+ int second4Bits;
for (int i = start; i < len; i += 2) {
- int first4Bits = Character.digit(hexString.charAt(i), 16);
- int second4Bits = Character.digit(hexString.charAt(i + 1), 16);
+ first4Bits = Character.digit(hexString.charAt(i), 16);
+ second4Bits = Character.digit(hexString.charAt(i + 1), 16);
if (first4Bits == -1 || second4Bits == -1) {
throw new IllegalArgumentException("'" + hexString.charAt(i) + hexString.charAt(i + 1) + "' at index " + i + " is not hex formatted");
From c8f4270d47039bb1441e6bb58dac137dd07cbc36 Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Thu, 3 Jan 2019 16:59:15 +0100
Subject: [PATCH 010/118] Minor refactoring in hex decoder
---
src/main/java/at/favre/lib/bytes/BinaryToTextEncoding.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/main/java/at/favre/lib/bytes/BinaryToTextEncoding.java b/src/main/java/at/favre/lib/bytes/BinaryToTextEncoding.java
index 8533dcf..00ef667 100644
--- a/src/main/java/at/favre/lib/bytes/BinaryToTextEncoding.java
+++ b/src/main/java/at/favre/lib/bytes/BinaryToTextEncoding.java
@@ -104,12 +104,12 @@ public String encode(byte[] byteArray, ByteOrder byteOrder) {
@Override
public byte[] decode(CharSequence hexString) {
- Objects.requireNonNull(hexString, "hex input must not be null");
- if (hexString.length() % 2 != 0)
+ if (Objects.requireNonNull(hexString, "hex input must not be null").length() % 2 != 0)
throw new IllegalArgumentException("invalid hex string, must be mod 2 == 0");
int start;
- if (hexString.toString().startsWith("0x")) {
+ if (hexString.length() > 2 &&
+ hexString.charAt(0) == '0' && hexString.charAt(1) == 'x') {
start = 2;
} else {
start = 0;
From 09cb2cedd376a23f4846250773f0ed476e9e4602 Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Thu, 3 Jan 2019 17:33:32 +0100
Subject: [PATCH 011/118] Add encodeBase64() supporting padding-less encoding
---
CHANGELOG | 1 +
src/main/java/at/favre/lib/bytes/Bytes.java | 28 ++++++++++++++++---
.../lib/bytes/BytesParseAndEncodingTest.java | 21 ++++++++++++++
3 files changed, 46 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 3db8817..ca67720 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,6 +4,7 @@
* add `append()` method supporting multiple byte arrays #26
* add `toCharArray()` method which decodes internal byte array to char[] #27
+* add `encodeBase64()` supporting padding-less encoding
## v0.8.0
diff --git a/src/main/java/at/favre/lib/bytes/Bytes.java b/src/main/java/at/favre/lib/bytes/Bytes.java
index a7b5f2b..384f269 100644
--- a/src/main/java/at/favre/lib/bytes/Bytes.java
+++ b/src/main/java/at/favre/lib/bytes/Bytes.java
@@ -631,7 +631,8 @@ public static Bytes parseBase36(CharSequence base36String) {
}
/**
- * Parsing of base64 encoded byte arrays. Supporting RFC 3548 normal and url safe encoding.
+ * Parsing of base64 encoded byte arrays.
+ * Supporting RFC 4648 normal and url safe encoding, with or without padding.
*
* @param base64String the encoded string
* @return decoded instance
@@ -1624,6 +1625,8 @@ public String encodeBase36() {
/**
* Base64 representation with padding. This is *NOT* the url safe variation. This encoding has a space efficiency of 75%.
+ *
+ * This encoding is RFC 4648 compatible.
*
* Example: SpT9/x6v7Q==
*
@@ -1631,12 +1634,14 @@ public String encodeBase36() {
* @see Base64
*/
public String encodeBase64() {
- return encode(new BinaryToTextEncoding.Base64Encoding(false, true));
+ return encodeBase64(false, true);
}
/**
- * Base64 representation with padding. This is the url safe variation subsitution '+' and '/' with '-' and '_'
+ * Base64 representation with padding. This is the url safe variation substitution '+' and '/' with '-' and '_'
* respectively. This encoding has a space efficiency of 75%.
+ *
+ * This encoding is RFC 4648 compatible.
*
* Example: SpT9_x6v7Q==
*
@@ -1644,7 +1649,22 @@ public String encodeBase64() {
* @see Base64
*/
public String encodeBase64Url() {
- return encode(new BinaryToTextEncoding.Base64Encoding(true, true));
+ return encodeBase64(true, true);
+ }
+
+ /**
+ * Base64 representation with either padding or without and with or without URL and filename safe alphabet.
+ * This encoding is RFC 4648 compatible.
+ *
+ * Example: SpT9/x6v7Q==
+ *
+ * @param urlSafe if true will substitute '+' and '/' with '-' and '_'
+ * @param withPadding if true will add padding the next full byte with '='
+ * @return base64 url safe string
+ * @see Base64
+ */
+ public String encodeBase64(boolean urlSafe, boolean withPadding) {
+ return encode(new BinaryToTextEncoding.Base64Encoding(urlSafe, withPadding));
}
/**
diff --git a/src/test/java/at/favre/lib/bytes/BytesParseAndEncodingTest.java b/src/test/java/at/favre/lib/bytes/BytesParseAndEncodingTest.java
index 68fbcf8..5938c17 100644
--- a/src/test/java/at/favre/lib/bytes/BytesParseAndEncodingTest.java
+++ b/src/test/java/at/favre/lib/bytes/BytesParseAndEncodingTest.java
@@ -61,7 +61,9 @@ public void encodeHex() {
@Test
public void parseBase64() {
assertArrayEquals(encodingExample, Bytes.parseBase64("SpT9/x6v7Q==").array());
+ assertArrayEquals(encodingExample, Bytes.parseBase64("SpT9/x6v7Q").array());
assertArrayEquals(encodingExample, Bytes.parseBase64("SpT9_x6v7Q==").array());
+ assertArrayEquals(encodingExample, Bytes.parseBase64("SpT9_x6v7Q").array());
}
@Test(expected = IllegalArgumentException.class)
@@ -83,6 +85,25 @@ public void encodeBase64Url() {
assertEquals("SpT9_x6v7Q==", Bytes.from(encodingExample).encodeBase64Url());
}
+ @Test
+ public void encodeBase64WithConfig() {
+ assertEquals("", Bytes.from(new byte[0]).encodeBase64(true, true));
+ assertEquals("AA==", Bytes.from(new byte[1]).encodeBase64(true, true));
+ assertEquals("SpT9_x6v7Q==", Bytes.from(encodingExample).encodeBase64(true, true));
+
+ assertEquals("", Bytes.from(new byte[0]).encodeBase64(true, false));
+ assertEquals("AA", Bytes.from(new byte[1]).encodeBase64(true, false));
+ assertEquals("SpT9_x6v7Q", Bytes.from(encodingExample).encodeBase64(true, false));
+
+ assertEquals("", Bytes.from(new byte[0]).encodeBase64(false, true));
+ assertEquals("AA==", Bytes.from(new byte[1]).encodeBase64(false, true));
+ assertEquals("SpT9/x6v7Q==", Bytes.from(encodingExample).encodeBase64(false, true));
+
+ assertEquals("", Bytes.from(new byte[0]).encodeBase64(false, false));
+ assertEquals("AA", Bytes.from(new byte[1]).encodeBase64(false, false));
+ assertEquals("SpT9/x6v7Q", Bytes.from(encodingExample).encodeBase64(false, false));
+ }
+
@Test
public void parseBase32() {
assertArrayEquals(encodingExample, Bytes.parseBase32("JKKP37Y6V7WQ====").array());
From f99baaa732ea7379e0e3763613bd69fade9360b2 Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Sat, 5 Jan 2019 12:29:14 +0100
Subject: [PATCH 012/118] Small refactoring in equals() method
---
src/main/java/at/favre/lib/bytes/Bytes.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/at/favre/lib/bytes/Bytes.java b/src/main/java/at/favre/lib/bytes/Bytes.java
index 384f269..33e97c0 100644
--- a/src/main/java/at/favre/lib/bytes/Bytes.java
+++ b/src/main/java/at/favre/lib/bytes/Bytes.java
@@ -1963,7 +1963,7 @@ public boolean equals(Object o) {
Bytes bytes = (Bytes) o;
if (!Arrays.equals(byteArray, bytes.byteArray)) return false;
- return byteOrder != null ? byteOrder.equals(bytes.byteOrder) : bytes.byteOrder == null;
+ return Objects.equals(byteOrder, bytes.byteOrder);
}
/**
From c7dde7bfab634b616af45c084f3862ee3db3b944 Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Sat, 5 Jan 2019 12:32:11 +0100
Subject: [PATCH 013/118] Remove deprecated toObjectArray()
---
CHANGELOG | 4 ++++
src/main/java/at/favre/lib/bytes/Bytes.java | 11 ++---------
.../favre/lib/bytes/BytesToConvertOtherTypesTest.java | 2 +-
3 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index ca67720..1f4a5a0 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -6,6 +6,10 @@
* add `toCharArray()` method which decodes internal byte array to char[] #27
* add `encodeBase64()` supporting padding-less encoding
+### Breaking
+
+* removed deprecated `toObjectArray()`; use `toBoxedArray()` instead
+
## v0.8.0
* add radix encoding/parsing and fix radix tests #6, #20
diff --git a/src/main/java/at/favre/lib/bytes/Bytes.java b/src/main/java/at/favre/lib/bytes/Bytes.java
index 33e97c0..55c92f8 100644
--- a/src/main/java/at/favre/lib/bytes/Bytes.java
+++ b/src/main/java/at/favre/lib/bytes/Bytes.java
@@ -1733,19 +1733,12 @@ public List toList() {
return Util.toList(internalArray());
}
- /**
- * @return see {@link #toBoxedArray()}
- * @deprecated renamed API, use {@link #toBoxedArray()} instead - will be removed in v1.0+
- */
- @Deprecated
- public Byte[] toObjectArray() {
- return toBoxedArray();
- }
-
/**
* Returns a copy of the internal byte-array as boxed primitive array.
* This requires a time and space complexity of O(n).
*
+ * Note: this method was previously called toObjectArray()
+ *
* @return copy of internal array as object array
*/
public Byte[] toBoxedArray() {
diff --git a/src/test/java/at/favre/lib/bytes/BytesToConvertOtherTypesTest.java b/src/test/java/at/favre/lib/bytes/BytesToConvertOtherTypesTest.java
index 0e18d91..f23f65f 100644
--- a/src/test/java/at/favre/lib/bytes/BytesToConvertOtherTypesTest.java
+++ b/src/test/java/at/favre/lib/bytes/BytesToConvertOtherTypesTest.java
@@ -45,7 +45,7 @@ private void checkArray(byte[] array) {
for (int i = 0; i < array.length; i++) {
assertEquals(byteArray[i], Byte.valueOf(array[i]));
}
- assertArrayEquals(byteArray, Bytes.from(array).toObjectArray());
+ assertArrayEquals(byteArray, Bytes.from(array).toBoxedArray());
}
@Test
From 8cb3a1f690ea09883020acd03acb7ea54f4a6ef7 Mon Sep 17 00:00:00 2001
From: pfavre
Date: Sun, 6 Jan 2019 17:51:23 +0100
Subject: [PATCH 014/118] Some small refactorings and add more little endian
tests
---
src/main/java/at/favre/lib/bytes/Bytes.java | 12 +++++------
src/main/java/at/favre/lib/bytes/Util.java | 9 ++++----
.../at/favre/lib/bytes/BytesMiscTest.java | 21 +++++++++++++++++++
3 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/src/main/java/at/favre/lib/bytes/Bytes.java b/src/main/java/at/favre/lib/bytes/Bytes.java
index 384f269..096e4fa 100644
--- a/src/main/java/at/favre/lib/bytes/Bytes.java
+++ b/src/main/java/at/favre/lib/bytes/Bytes.java
@@ -1324,7 +1324,7 @@ public int unsignedByteAt(int index) {
*/
public char charAt(int index) {
Util.checkIndexBounds(length(), index, 2, "char");
- return ((ByteBuffer) ByteBuffer.wrap(internalArray()).order(byteOrder).position(index)).getChar();
+ return ((ByteBuffer) internalBuffer().position(index)).getChar();
}
/**
@@ -1337,7 +1337,7 @@ public char charAt(int index) {
*/
public short shortAt(int index) {
Util.checkIndexBounds(length(), index, 2, "short");
- return ((ByteBuffer) ByteBuffer.wrap(internalArray()).order(byteOrder).position(index)).getShort();
+ return ((ByteBuffer) internalBuffer().position(index)).getShort();
}
/**
@@ -1350,7 +1350,7 @@ public short shortAt(int index) {
*/
public int intAt(int index) {
Util.checkIndexBounds(length(), index, 4, "int");
- return ((ByteBuffer) ByteBuffer.wrap(internalArray()).order(byteOrder).position(index)).getInt();
+ return ((ByteBuffer) internalBuffer().position(index)).getInt();
}
/**
@@ -1363,7 +1363,7 @@ public int intAt(int index) {
*/
public long longAt(int index) {
Util.checkIndexBounds(length(), index, 8, "long");
- return ((ByteBuffer) ByteBuffer.wrap(internalArray()).order(byteOrder).position(index)).getLong();
+ return ((ByteBuffer) internalBuffer().position(index)).getLong();
}
/**
@@ -1927,7 +1927,7 @@ public char[] toCharArray() {
* @return char array
*/
public char[] toCharArray(Charset charset) {
- return Util.byteToCharArray(internalArray(), charset);
+ return Util.byteToCharArray(internalArray(), charset, byteOrder);
}
/**
@@ -2009,7 +2009,7 @@ public boolean equals(Byte[] anotherArray) {
* @return true if both array have same length and every byte element is the same
*/
public boolean equals(ByteBuffer buffer) {
- return buffer != null && byteOrder == buffer.order() && ByteBuffer.wrap(internalArray()).order(byteOrder).equals(buffer);
+ return buffer != null && byteOrder == buffer.order() && internalBuffer().equals(buffer);
}
/**
diff --git a/src/main/java/at/favre/lib/bytes/Util.java b/src/main/java/at/favre/lib/bytes/Util.java
index ff78531..d598693 100644
--- a/src/main/java/at/favre/lib/bytes/Util.java
+++ b/src/main/java/at/favre/lib/bytes/Util.java
@@ -435,16 +435,17 @@ static byte[] charToByteArray(char[] charArray, Charset charset, int offset, int
/**
* Convert given byte array in given encoding to char array
*
- * @param bytes as data source
- * @param charset of the byte array
+ * @param bytes as data source
+ * @param charset of the byte array
+ * @param byteOrder the order of the bytes array
* @return char array
*/
- static char[] byteToCharArray(byte[] bytes, Charset charset) {
+ static char[] byteToCharArray(byte[] bytes, Charset charset, ByteOrder byteOrder) {
Objects.requireNonNull(bytes, "bytes must not be null");
Objects.requireNonNull(charset, "charset must not be null");
try {
- CharBuffer charBuffer = charset.newDecoder().decode(ByteBuffer.wrap(bytes));
+ CharBuffer charBuffer = charset.newDecoder().decode(ByteBuffer.wrap(bytes).order(byteOrder));
if (charBuffer.capacity() != charBuffer.limit()) {
char[] compacted = new char[charBuffer.remaining()];
charBuffer.get(compacted);
diff --git a/src/test/java/at/favre/lib/bytes/BytesMiscTest.java b/src/test/java/at/favre/lib/bytes/BytesMiscTest.java
index a462875..844e36c 100644
--- a/src/test/java/at/favre/lib/bytes/BytesMiscTest.java
+++ b/src/test/java/at/favre/lib/bytes/BytesMiscTest.java
@@ -62,6 +62,7 @@ public void testHashcode() {
assertNotEquals(0, Bytes.wrap(example2_bytes_seven).hashCode());
}
+ @SuppressWarnings("SimplifiableJUnitAssertion")
@Test
public void testEquals() {
assertTrue(Bytes.wrap(new byte[0]).equals(Bytes.wrap(new byte[0])));
@@ -150,6 +151,7 @@ public void testIsEmpty() {
assertFalse(Bytes.from(example_bytes_seven).isEmpty());
}
+ @SuppressWarnings("SimplifiableJUnitAssertion")
@Test
public void containsTest() {
assertEquals(false, Bytes.allocate(0).contains((byte) 0xFD));
@@ -372,6 +374,15 @@ public void intAt() {
}
}
+ @Test
+ public void intAtLittleEndian() {
+ assertEquals(16777216, Bytes.wrap(new byte[]{0, 0, 0, 1}, ByteOrder.LITTLE_ENDIAN).intAt(0));
+ assertEquals(1, Bytes.wrap(new byte[]{0, 0, 0, 1}, ByteOrder.BIG_ENDIAN).intAt(0));
+ assertEquals(134217728, Bytes.wrap(new byte[]{0, 0, 0, 0b00001000}, ByteOrder.LITTLE_ENDIAN).intAt(0));
+ assertEquals(524288, Bytes.wrap(new byte[]{0, 0, 0b00001000, 0}, ByteOrder.LITTLE_ENDIAN).intAt(0));
+ assertEquals(8388608, Bytes.wrap(new byte[]{0, 0, (byte) 0b10000000, 0}, ByteOrder.LITTLE_ENDIAN).intAt(0));
+ }
+
@Test
public void longAt() {
assertEquals(0, Bytes.allocate(8).longAt(0));
@@ -395,6 +406,16 @@ public void longAt() {
}
}
+ @Test
+ public void longAtLittleEndian() {
+ assertEquals(72057594037927936L, Bytes.wrap(new byte[]{0, 0, 0, 0, 0, 0, 0, 1}, ByteOrder.LITTLE_ENDIAN).longAt(0));
+ assertEquals(1, Bytes.wrap(new byte[]{0, 0, 0, 0, 0, 0, 0, 1}, ByteOrder.BIG_ENDIAN).longAt(0));
+ assertEquals(576460752303423488L, Bytes.wrap(new byte[]{0, 0, 0, 0, 0, 0, 0, 0b00001000}, ByteOrder.LITTLE_ENDIAN).longAt(0));
+ assertEquals(2251799813685248L, Bytes.wrap(new byte[]{0, 0, 0, 0, 0, 0, 0b00001000, 0}, ByteOrder.LITTLE_ENDIAN).longAt(0));
+ assertEquals(36028797018963968L, Bytes.wrap(new byte[]{0, 0, 0, 0, 0, 0, (byte) 0b10000000, 0}, ByteOrder.LITTLE_ENDIAN).longAt(0));
+ assertEquals(549755813888L, Bytes.wrap(new byte[]{0, 0, 0, 0, (byte) 0b10000000, 0, 0, 0}, ByteOrder.LITTLE_ENDIAN).longAt(0));
+ }
+
@Test
public void primitiveAtLittleEndian() {
assertEquals(576460752303423488L, Bytes.wrap(new byte[]{0, 0, 0, 0, 0, 0, 0, 0b00001000}).byteOrder(ByteOrder.LITTLE_ENDIAN).longAt(0)); //2^59
From b7d82d0d8d07136a58d6e26aa82b640acee1b44b Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Sun, 6 Jan 2019 23:41:26 +0100
Subject: [PATCH 015/118] Add toIntArray converter
Supports little and big endian order.
fixes #28
---
CHANGELOG | 1 +
src/main/java/at/favre/lib/bytes/Bytes.java | 25 +++++++++--
src/main/java/at/favre/lib/bytes/Util.java | 38 +++++++++++++++++
.../bytes/BytesToConvertOtherTypesTest.java | 41 +++++++++++++++++++
4 files changed, 102 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 1f4a5a0..006ea88 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,6 +5,7 @@
* add `append()` method supporting multiple byte arrays #26
* add `toCharArray()` method which decodes internal byte array to char[] #27
* add `encodeBase64()` supporting padding-less encoding
+* add `toIntArray()` converter #28
### Breaking
diff --git a/src/main/java/at/favre/lib/bytes/Bytes.java b/src/main/java/at/favre/lib/bytes/Bytes.java
index 55c92f8..0f31a12 100644
--- a/src/main/java/at/favre/lib/bytes/Bytes.java
+++ b/src/main/java/at/favre/lib/bytes/Bytes.java
@@ -1625,7 +1625,7 @@ public String encodeBase36() {
/**
* Base64 representation with padding. This is *NOT* the url safe variation. This encoding has a space efficiency of 75%.
- *
+ *
* Example: SpT9/x6v7Q==
@@ -1640,7 +1640,7 @@ public String encodeBase64() {
/**
* Base64 representation with padding. This is the url safe variation substitution '+' and '/' with '-' and '_'
* respectively. This encoding has a space efficiency of 75%.
- *
+ *
* Example: SpT9_x6v7Q==
@@ -1736,7 +1736,7 @@ public List toList() {
/**
* Returns a copy of the internal byte-array as boxed primitive array.
* This requires a time and space complexity of O(n).
- *
+ *
* Note: this method was previously called toObjectArray()
*
* @return copy of internal array as object array
@@ -1861,6 +1861,25 @@ public int toInt() {
return intAt(0);
}
+ /**
+ * Converts the internal byte array to an int array, that is, every 4 bytes will be packed into a single int.
+ *
+ * E.g. 4 bytes will be packed to a length 1 int array:
+ *
+ * [b1, b2, b3, b4] = [int1]
+ *
+ *
+ * This conversion respects the internal byte order. Will only work if all bytes can be directly mapped to int,
+ * which means the byte array length must be dividable by 4 without rest.
+ *
+ * @return new int[] instance representing this byte array
+ * @throws IllegalArgumentException if internal byte length mod 4 != 0
+ */
+ public int[] toIntArray() {
+ Util.checkModLength(length(), 4, "creating an int array");
+ return Util.toIntArray(internalArray(), byteOrder);
+ }
+
/**
* If the underlying byte array is exactly 8 byte / 64 bit long, return signed two-complement
* representation for a Java signed long integer value. The output is dependent on the set {@link #byteOrder()}.
diff --git a/src/main/java/at/favre/lib/bytes/Util.java b/src/main/java/at/favre/lib/bytes/Util.java
index ff78531..1ae52e1 100644
--- a/src/main/java/at/favre/lib/bytes/Util.java
+++ b/src/main/java/at/favre/lib/bytes/Util.java
@@ -25,6 +25,7 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
+import java.nio.IntBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.file.Files;
@@ -456,6 +457,28 @@ static char[] byteToCharArray(byte[] bytes, Charset charset) {
}
}
+ /**
+ * Converts the byte array to an int array. This will spread 4 bytes into a single int:
+ *
+ *
+ * [b1, b2, b3, b4] = int1
+ *
+ *
+ * @param bytes to convert to int array
+ * @param byteOrder of the byte array
+ * @return int array
+ */
+ static int[] toIntArray(byte[] bytes, ByteOrder byteOrder) {
+ IntBuffer buffer = ByteBuffer.wrap(bytes).order(byteOrder).asIntBuffer();
+ if (buffer.hasArray()) {
+ return buffer.array();
+ } else {
+ int[] array = new int[buffer.remaining()];
+ buffer.get(array);
+ return array;
+ }
+ }
+
/**
* Shows the length and a preview of max 8 bytes of the given byte
*
@@ -590,6 +613,21 @@ static int hashCode(byte[] byteArray, ByteOrder byteOrder) {
return result;
}
+ /**
+ * Checks if given length is divisable by mod factor (with zero rest).
+ * This can be used to check of a byte array can be convertet to an e.g. int array which is
+ * multiples of 4.
+ *
+ * @param length of the byte array
+ * @param modFactor to divide the length
+ * @param errorSubject human readable message of the exact error subject
+ */
+ static void checkModLength(int length, int modFactor, String errorSubject) {
+ if (length % modFactor != 0) {
+ throw new IllegalArgumentException("Illegal length for " + errorSubject + ". Byte array length must be multiple of " + modFactor + ", length was " + length);
+ }
+ }
+
/*
=================================================================================================
Copyright 2011 Twitter, Inc.
diff --git a/src/test/java/at/favre/lib/bytes/BytesToConvertOtherTypesTest.java b/src/test/java/at/favre/lib/bytes/BytesToConvertOtherTypesTest.java
index f23f65f..fe66d61 100644
--- a/src/test/java/at/favre/lib/bytes/BytesToConvertOtherTypesTest.java
+++ b/src/test/java/at/favre/lib/bytes/BytesToConvertOtherTypesTest.java
@@ -23,6 +23,7 @@
import org.junit.Test;
+import java.nio.ByteOrder;
import java.util.List;
import static org.junit.Assert.*;
@@ -235,4 +236,44 @@ public void testToUUIDToShort() {
public void testToUUIDEmpty() {
Bytes.allocate(0).toUUID();
}
+
+ @Test
+ public void testToIntArray() {
+ assertArrayEquals(new int[]{1}, Bytes.wrap(new byte[]{0, 0, 0, 1}).toIntArray());
+ assertArrayEquals(new int[]{257}, Bytes.wrap(new byte[]{0, 0, 1, 1}).toIntArray());
+ assertArrayEquals(new int[]{65_793}, Bytes.wrap(new byte[]{0, 1, 1, 1}).toIntArray());
+ assertArrayEquals(new int[]{16_843_009}, Bytes.wrap(new byte[]{1, 1, 1, 1}).toIntArray());
+ assertArrayEquals(new int[]{571_211_845}, Bytes.wrap(new byte[]{34, 12, 0, 69}).toIntArray());
+ assertArrayEquals(new int[]{1_290_429_439}, Bytes.wrap(new byte[]{76, (byte) 234, 99, (byte) 255}).toIntArray());
+
+ assertArrayEquals(new int[]{1, 1}, Bytes.wrap(new byte[]{0, 0, 0, 1, 0, 0, 0, 1}).toIntArray());
+ assertArrayEquals(new int[]{257, 1}, Bytes.wrap(new byte[]{0, 0, 1, 1, 0, 0, 0, 1}).toIntArray());
+ assertArrayEquals(new int[]{257, 65_793, 1}, Bytes.wrap(new byte[]{0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1}).toIntArray());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testToIntArrayNotMod4Was5Byte() {
+ Bytes.wrap(new byte[]{1, 0, 0, 0, 1}).toIntArray();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testToIntArrayNotMod4Only3Byte() {
+ Bytes.wrap(new byte[]{0, 0, 1}).toIntArray();
+ }
+
+ @Test
+ public void testToIntEmptyArray() {
+ assertArrayEquals(new int[0], Bytes.empty().toIntArray());
+ }
+
+ @Test
+ public void testToIntArrayLittleEndian() {
+ assertArrayEquals(new int[]{1}, Bytes.wrap(new byte[]{1, 0, 0, 0}, ByteOrder.LITTLE_ENDIAN).toIntArray());
+ assertArrayEquals(new int[]{257}, Bytes.wrap(new byte[]{1, 1, 0, 0}, ByteOrder.LITTLE_ENDIAN).toIntArray());
+ assertArrayEquals(new int[]{1_290_429_439}, Bytes.wrap(new byte[]{(byte) 255, 99, (byte) 234, 76}, ByteOrder.LITTLE_ENDIAN).toIntArray());
+
+ assertArrayEquals(new int[]{1, 1}, Bytes.wrap(new byte[]{1, 0, 0, 0, 1, 0, 0, 0}, ByteOrder.LITTLE_ENDIAN).toIntArray());
+ assertArrayEquals(new int[]{257, 1}, Bytes.wrap(new byte[]{1, 1, 0, 0, 1, 0, 0, 0}, ByteOrder.LITTLE_ENDIAN).toIntArray());
+ assertArrayEquals(new int[]{257, 65_793, 1}, Bytes.wrap(new byte[]{1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0}, ByteOrder.LITTLE_ENDIAN).toIntArray());
+ }
}
From ccb6d5c4ce6c0c423249d10fcabdc99945d11ba9 Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Mon, 7 Jan 2019 18:16:52 +0100
Subject: [PATCH 016/118] Refactor Util class to partition features in
sub-classes
---
src/main/java/at/favre/lib/bytes/Bytes.java | 107 +-
.../at/favre/lib/bytes/BytesTransformer.java | 8 +-
.../at/favre/lib/bytes/BytesTransformers.java | 2 +-
.../java/at/favre/lib/bytes/MutableBytes.java | 2 +-
src/main/java/at/favre/lib/bytes/Util.java | 1064 +++++++++--------
.../lib/bytes/BytesConstructorTests.java | 18 +-
.../bytes/BytesSharedDataConverterTest.java | 8 +-
.../favre/lib/bytes/BytesTransformTest.java | 42 +-
.../java/at/favre/lib/bytes/UtilTest.java | 146 +--
9 files changed, 737 insertions(+), 660 deletions(-)
diff --git a/src/main/java/at/favre/lib/bytes/Bytes.java b/src/main/java/at/favre/lib/bytes/Bytes.java
index 1ed0899..6b74102 100644
--- a/src/main/java/at/favre/lib/bytes/Bytes.java
+++ b/src/main/java/at/favre/lib/bytes/Bytes.java
@@ -21,14 +21,29 @@
package at.favre.lib.bytes;
-import java.io.*;
+import java.io.ByteArrayInputStream;
+import java.io.DataInput;
+import java.io.File;
+import java.io.InputStream;
+import java.io.Serializable;
import java.math.BigInteger;
-import java.nio.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.CharBuffer;
+import java.nio.IntBuffer;
+import java.nio.ReadOnlyBufferException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.text.Normalizer;
-import java.util.*;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+import java.util.Random;
+import java.util.UUID;
/**
* Bytes is wrapper class for an byte-array that allows a lot of convenience operations on it:
@@ -202,7 +217,7 @@ public static Bytes from(byte[] array, int offset, int length) {
* @return new instance
*/
public static Bytes from(byte[]... moreArrays) {
- return wrap(Util.concat(moreArrays));
+ return wrap(Util.Byte.concat(moreArrays));
}
/**
@@ -228,7 +243,7 @@ public static Bytes from(Bytes... moreBytes) {
* @return new instance
*/
public static Bytes from(Collection bytesCollection) {
- return wrap(Util.toArray(bytesCollection));
+ return wrap(Util.Converter.toArray(bytesCollection));
}
/**
@@ -238,7 +253,7 @@ public static Bytes from(Collection bytesCollection) {
* @return new instance
*/
public static Bytes from(Byte[] boxedObjectArray) {
- return wrap(Util.toPrimitiveArray(boxedObjectArray));
+ return wrap(Util.Converter.toPrimitiveArray(boxedObjectArray));
}
/**
@@ -260,7 +275,7 @@ public static Bytes from(byte singleByte) {
* @return new instance
*/
public static Bytes from(byte firstByte, byte... moreBytes) {
- return wrap(Util.concatVararg(firstByte, moreBytes));
+ return wrap(Util.Byte.concatVararg(firstByte, moreBytes));
}
/**
@@ -313,7 +328,7 @@ public static Bytes from(int integer4byte) {
* @return new instance
*/
public static Bytes from(int... intArray) {
- return wrap(Util.toByteArray(Objects.requireNonNull(intArray, "must provide at least a single int")));
+ return wrap(Util.Converter.toByteArray(Objects.requireNonNull(intArray, "must provide at least a single int")));
}
/**
@@ -333,7 +348,7 @@ public static Bytes from(long long8byte) {
* @return new instance
*/
public static Bytes from(long... longArray) {
- return wrap(Util.toByteArray(Objects.requireNonNull(longArray, "must provide at least a single long")));
+ return wrap(Util.Converter.toByteArray(Objects.requireNonNull(longArray, "must provide at least a single long")));
}
/**
@@ -416,7 +431,7 @@ public static Bytes from(BigInteger bigInteger) {
* @return new instance
*/
public static Bytes from(InputStream stream) {
- return wrap(Util.readFromStream(stream, -1));
+ return wrap(Util.File.readFromStream(stream, -1));
}
/**
@@ -428,7 +443,7 @@ public static Bytes from(InputStream stream) {
* @return new instance
*/
public static Bytes from(InputStream stream, int maxLength) {
- return wrap(Util.readFromStream(stream, maxLength));
+ return wrap(Util.File.readFromStream(stream, maxLength));
}
/**
@@ -439,7 +454,7 @@ public static Bytes from(InputStream stream, int maxLength) {
* @return new instance
*/
public static Bytes from(DataInput dataInput, int length) {
- return wrap(Util.readFromDataInput(dataInput, length));
+ return wrap(Util.File.readFromDataInput(dataInput, length));
}
/**
@@ -452,7 +467,7 @@ public static Bytes from(DataInput dataInput, int length) {
* @throws IllegalStateException if file could not be read
*/
public static Bytes from(File file) {
- return wrap(Util.readFromFile(file));
+ return wrap(Util.File.readFromFile(file));
}
/**
@@ -467,7 +482,7 @@ public static Bytes from(File file) {
* @throws IllegalStateException if file could not be read
*/
public static Bytes from(File file, int offset, int length) {
- return wrap(Util.readFromFile(file, offset, length));
+ return wrap(Util.File.readFromFile(file, offset, length));
}
/**
@@ -533,7 +548,7 @@ public static Bytes from(char[] charArray, Charset charset) {
* @return new instance
*/
public static Bytes from(char[] charArray, Charset charset, int offset, int length) {
- return from(Util.charToByteArray(charArray, charset, offset, length));
+ return from(Util.Converter.charToByteArray(charArray, charset, offset, length));
}
/**
@@ -544,7 +559,7 @@ public static Bytes from(char[] charArray, Charset charset, int offset, int leng
* @return new instance
*/
public static Bytes from(UUID uuid) {
- return wrap(Util.getBytesFromUUID(Objects.requireNonNull(uuid)).array());
+ return wrap(Util.Converter.toBytesFromUUID(Objects.requireNonNull(uuid)).array());
}
/**
@@ -1235,7 +1250,7 @@ public int indexOf(byte[] subArray) {
* {@code -1} if no such index exists.
*/
public int indexOf(byte[] subArray, int fromIndex) {
- return Util.indexOf(internalArray(), subArray, fromIndex, length());
+ return Util.Byte.indexOf(internalArray(), subArray, fromIndex, length());
}
/**
@@ -1246,7 +1261,7 @@ public int indexOf(byte[] subArray, int fromIndex) {
* @return true if the start of the internal array is eq to given sub array
*/
public boolean startsWith(byte[] subArray) {
- return Util.indexOf(internalArray(), subArray, 0, 1) == 0;
+ return Util.Byte.indexOf(internalArray(), subArray, 0, 1) == 0;
}
/**
@@ -1258,7 +1273,7 @@ public boolean startsWith(byte[] subArray) {
* or {@code -1} if no such index exists.
*/
public int lastIndexOf(byte target) {
- return Util.lastIndexOf(internalArray(), target, 0, length());
+ return Util.Byte.lastIndexOf(internalArray(), target, 0, length());
}
/**
@@ -1270,7 +1285,7 @@ public int lastIndexOf(byte target) {
*/
public boolean endsWith(byte[] subArray) {
int startIndex = length() - subArray.length;
- return startIndex >= 0 && Util.indexOf(internalArray(), subArray, startIndex, startIndex + 1) == startIndex;
+ return startIndex >= 0 && Util.Byte.indexOf(internalArray(), subArray, startIndex, startIndex + 1) == startIndex;
}
/**
@@ -1282,7 +1297,7 @@ public boolean endsWith(byte[] subArray) {
* @throws IndexOutOfBoundsException if the {@code bitIndex} argument is negative or not less than the length of this array in bits.
*/
public boolean bitAt(int bitIndex) {
- Util.checkIndexBounds(lengthBit(), bitIndex, 1, "bit");
+ Util.Validation.checkIndexBounds(lengthBit(), bitIndex, 1, "bit");
return ((byteAt(length() - 1 - (bitIndex / 8)) >>> bitIndex % 8) & 1) != 0;
}
@@ -1296,7 +1311,7 @@ public boolean bitAt(int bitIndex) {
* @throws IndexOutOfBoundsException if the {@code index} argument is negative or not less than the length of this array.
*/
public byte byteAt(int index) {
- Util.checkIndexBounds(length(), index, 1, "byte");
+ Util.Validation.checkIndexBounds(length(), index, 1, "byte");
return internalArray()[index];
}
@@ -1310,7 +1325,7 @@ public byte byteAt(int index) {
* @throws IndexOutOfBoundsException if the {@code index} argument is negative or not less than the length of this array.
*/
public int unsignedByteAt(int index) {
- Util.checkIndexBounds(length(), index, 1, "unsigned byte");
+ Util.Validation.checkIndexBounds(length(), index, 1, "unsigned byte");
return 0xff & internalArray()[index];
}
@@ -1323,7 +1338,7 @@ public int unsignedByteAt(int index) {
* @throws IndexOutOfBoundsException if the {@code index} argument is negative or length is greater than index - 2
*/
public char charAt(int index) {
- Util.checkIndexBounds(length(), index, 2, "char");
+ Util.Validation.checkIndexBounds(length(), index, 2, "char");
return ((ByteBuffer) internalBuffer().position(index)).getChar();
}
@@ -1336,7 +1351,7 @@ public char charAt(int index) {
* @throws IndexOutOfBoundsException if the {@code index} argument is negative or length is greater than index - 2
*/
public short shortAt(int index) {
- Util.checkIndexBounds(length(), index, 2, "short");
+ Util.Validation.checkIndexBounds(length(), index, 2, "short");
return ((ByteBuffer) internalBuffer().position(index)).getShort();
}
@@ -1349,7 +1364,7 @@ public short shortAt(int index) {
* @throws IndexOutOfBoundsException if the {@code int} argument is negative or length is greater than index - 4
*/
public int intAt(int index) {
- Util.checkIndexBounds(length(), index, 4, "int");
+ Util.Validation.checkIndexBounds(length(), index, 4, "int");
return ((ByteBuffer) internalBuffer().position(index)).getInt();
}
@@ -1362,7 +1377,7 @@ public int intAt(int index) {
* @throws IndexOutOfBoundsException if the {@code long} argument is negative or length is greater than index - 8
*/
public long longAt(int index) {
- Util.checkIndexBounds(length(), index, 8, "long");
+ Util.Validation.checkIndexBounds(length(), index, 8, "long");
return ((ByteBuffer) internalBuffer().position(index)).getLong();
}
@@ -1374,7 +1389,7 @@ public long longAt(int index) {
* @return the count of given target in the byte array
*/
public int count(byte target) {
- return Util.countByte(internalArray(), target);
+ return Util.Byte.countByte(internalArray(), target);
}
/**
@@ -1392,7 +1407,7 @@ public int count(byte target) {
* @return the count of given target in the byte array
*/
public int count(byte[] pattern) {
- return Util.countByteArray(internalArray(), pattern);
+ return Util.Byte.countByteArray(internalArray(), pattern);
}
/**
@@ -1730,7 +1745,7 @@ public String encode(BinaryToTextEncoding.Encoder encoder) {
* @return copy of internal array as list
*/
public List toList() {
- return Util.toList(internalArray());
+ return Util.Converter.toList(internalArray());
}
/**
@@ -1742,7 +1757,7 @@ public List toList() {
* @return copy of internal array as object array
*/
public Byte[] toBoxedArray() {
- return Util.toBoxedArray(internalArray());
+ return Util.Converter.toBoxedArray(internalArray());
}
/**
@@ -1797,7 +1812,7 @@ public UUID toUUID() {
* @see Primitive Types
*/
public byte toByte() {
- Util.checkExactLength(length(), 1, "byte");
+ Util.Validation.checkExactLength(length(), 1, "byte");
return internalArray()[0];
}
@@ -1812,7 +1827,7 @@ public byte toByte() {
* @see Primitive Types
*/
public int toUnsignedByte() {
- Util.checkExactLength(length(), 1, "unsigned byte");
+ Util.Validation.checkExactLength(length(), 1, "unsigned byte");
return unsignedByteAt(0);
}
@@ -1827,7 +1842,7 @@ public int toUnsignedByte() {
* @see Primitive Types
*/
public char toChar() {
- Util.checkExactLength(length(), 2, "char");
+ Util.Validation.checkExactLength(length(), 2, "char");
return charAt(0);
}
@@ -1842,7 +1857,7 @@ public char toChar() {
* @see Primitive Types
*/
public short toShort() {
- Util.checkExactLength(length(), 2, "short");
+ Util.Validation.checkExactLength(length(), 2, "short");
return shortAt(0);
}
@@ -1857,7 +1872,7 @@ public short toShort() {
* @see Primitive Types
*/
public int toInt() {
- Util.checkExactLength(length(), 4, "int");
+ Util.Validation.checkExactLength(length(), 4, "int");
return intAt(0);
}
@@ -1876,8 +1891,8 @@ public int toInt() {
* @throws IllegalArgumentException if internal byte length mod 4 != 0
*/
public int[] toIntArray() {
- Util.checkModLength(length(), 4, "creating an int array");
- return Util.toIntArray(internalArray(), byteOrder);
+ Util.Validation.checkModLength(length(), 4, "creating an int array");
+ return Util.Converter.toIntArray(internalArray(), byteOrder);
}
/**
@@ -1891,7 +1906,7 @@ public int[] toIntArray() {
* @see Primitive Types
*/
public long toLong() {
- Util.checkExactLength(length(), 8, "long");
+ Util.Validation.checkExactLength(length(), 8, "long");
return longAt(0);
}
@@ -1904,7 +1919,7 @@ public long toLong() {
* @see Primitive Types
*/
public float toFloat() {
- Util.checkExactLength(length(), 4, "float");
+ Util.Validation.checkExactLength(length(), 4, "float");
return internalBuffer().getFloat();
}
@@ -1917,7 +1932,7 @@ public float toFloat() {
* @see Primitive Types
*/
public double toDouble() {
- Util.checkExactLength(length(), 8, "double");
+ Util.Validation.checkExactLength(length(), 8, "double");
return internalBuffer().getDouble();
}
@@ -1939,7 +1954,7 @@ public char[] toCharArray() {
* @return char array
*/
public char[] toCharArray(Charset charset) {
- return Util.byteToCharArray(internalArray(), charset, byteOrder);
+ return Util.Converter.byteToCharArray(internalArray(), charset, byteOrder);
}
/**
@@ -1999,7 +2014,7 @@ public boolean equals(byte[] anotherArray) {
* @return true if {@link Arrays#equals(byte[], byte[])} returns true on given and internal array
*/
public boolean equalsConstantTime(byte[] anotherArray) {
- return anotherArray != null && Util.constantTimeEquals(internalArray(), anotherArray);
+ return anotherArray != null && Util.Byte.constantTimeEquals(internalArray(), anotherArray);
}
/**
@@ -2010,7 +2025,7 @@ public boolean equalsConstantTime(byte[] anotherArray) {
* @return true if both array have same length and every byte element is the same
*/
public boolean equals(Byte[] anotherArray) {
- return Util.equals(internalArray(), anotherArray);
+ return Util.Obj.equals(internalArray(), anotherArray);
}
/**
@@ -2037,7 +2052,7 @@ public boolean equalsContent(Bytes other) {
@Override
public int hashCode() {
if (hashCodeCache == 0) {
- hashCodeCache = Util.hashCode(internalArray(), byteOrder());
+ hashCodeCache = Util.Obj.hashCode(internalArray(), byteOrder());
}
return hashCodeCache;
}
@@ -2050,7 +2065,7 @@ public int hashCode() {
*/
@Override
public String toString() {
- return Util.toString(this);
+ return Util.Obj.toString(this);
}
@Override
diff --git a/src/main/java/at/favre/lib/bytes/BytesTransformer.java b/src/main/java/at/favre/lib/bytes/BytesTransformer.java
index a9549da..3612505 100644
--- a/src/main/java/at/favre/lib/bytes/BytesTransformer.java
+++ b/src/main/java/at/favre/lib/bytes/BytesTransformer.java
@@ -143,10 +143,10 @@ public byte[] transform(byte[] currentArray, boolean inPlace) {
switch (type) {
case RIGHT_SHIFT:
- return Util.shiftRight(out, shiftCount);
+ return Util.Byte.shiftRight(out, shiftCount);
default:
case LEFT_SHIFT:
- return Util.shiftLeft(out, shiftCount);
+ return Util.Byte.shiftLeft(out, shiftCount);
}
}
@@ -170,7 +170,7 @@ final class ConcatTransformer implements BytesTransformer {
@Override
public byte[] transform(byte[] currentArray, boolean inPlace) {
- return Util.concat(currentArray, secondArray);
+ return Util.Byte.concat(currentArray, secondArray);
}
@Override
@@ -186,7 +186,7 @@ final class ReverseTransformer implements BytesTransformer {
@Override
public byte[] transform(byte[] currentArray, boolean inPlace) {
byte[] out = inPlace ? currentArray : Bytes.from(currentArray).array();
- Util.reverse(out, 0, out.length);
+ Util.Byte.reverse(out, 0, out.length);
return out;
}
diff --git a/src/main/java/at/favre/lib/bytes/BytesTransformers.java b/src/main/java/at/favre/lib/bytes/BytesTransformers.java
index cd67777..64a6ae9 100644
--- a/src/main/java/at/favre/lib/bytes/BytesTransformers.java
+++ b/src/main/java/at/favre/lib/bytes/BytesTransformers.java
@@ -177,7 +177,7 @@ public static final class ShuffleTransformer implements BytesTransformer {
@Override
public byte[] transform(byte[] currentArray, boolean inPlace) {
byte[] out = inPlace ? currentArray : Bytes.from(currentArray).array();
- Util.shuffle(out, random);
+ Util.Byte.shuffle(out, random);
return out;
}
diff --git a/src/main/java/at/favre/lib/bytes/MutableBytes.java b/src/main/java/at/favre/lib/bytes/MutableBytes.java
index 3bd042c..218fd20 100644
--- a/src/main/java/at/favre/lib/bytes/MutableBytes.java
+++ b/src/main/java/at/favre/lib/bytes/MutableBytes.java
@@ -139,7 +139,7 @@ public Bytes immutable() {
@Override
public int hashCode() {
- return Util.hashCode(internalArray(), byteOrder());
+ return Util.Obj.hashCode(internalArray(), byteOrder());
}
@Override
diff --git a/src/main/java/at/favre/lib/bytes/Util.java b/src/main/java/at/favre/lib/bytes/Util.java
index 5969836..ac1b7e3 100644
--- a/src/main/java/at/favre/lib/bytes/Util.java
+++ b/src/main/java/at/favre/lib/bytes/Util.java
@@ -21,7 +21,11 @@
package at.favre.lib.bytes;
-import java.io.*;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInput;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
@@ -29,604 +33,657 @@
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.file.Files;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.Random;
+import java.util.UUID;
/**
* Common Util methods to convert or modify byte arrays
*/
final class Util {
- private static final int BUF_SIZE = 0x1000; // 4K
-
- private Util() {
- }
/**
- * Returns the values from each provided byteArray combined into a single byteArray.
- * For example, {@code append(new byte[] {a, b}, new byte[] {}, new
- * byte[] {c}} returns the byteArray {@code {a, b, c}}.
- *
- * @param arrays zero or more {@code byte} arrays
- * @return a single byteArray containing all the values from the source arrays, in
- * order
+ * Util methods related general purpose byte utility.
*/
- static byte[] concat(byte[]... arrays) {
- int length = 0;
- for (byte[] array : arrays) {
- length += array.length;
- }
- byte[] result = new byte[length];
- int pos = 0;
- for (byte[] array : arrays) {
- System.arraycopy(array, 0, result, pos, array.length);
- pos += array.length;
- }
- return result;
- }
-
- /**
- * Returns the start position of the first occurrence of the specified {@code
- * target} within {@code array}, or {@code -1} if there is no such occurrence.
- *
- *
More formally, returns the lowest index {@code i} such that {@code
- * java.util.Arrays.copyOfRange(array, i, i + target.length)} contains exactly
- * the same elements as {@code target}.
- *
- * @param array the array to search for the sequence {@code target}
- * @param target the array to search for as a sub-sequence of {@code array}
- */
- static int indexOf(byte[] array, byte[] target, int start, int end) {
- Objects.requireNonNull(array, "array must not be null");
- Objects.requireNonNull(target, "target must not be null");
- if (target.length == 0 || start < 0) {
- return -1;
+ static final class Byte {
+ private Byte() {
}
- outer:
- for (int i = start; i < Math.min(end, array.length - target.length + 1); i++) {
- for (int j = 0; j < target.length; j++) {
- if (array[i + j] != target[j]) {
- continue outer;
- }
+ /**
+ * Returns the values from each provided byteArray combined into a single byteArray.
+ * For example, {@code append(new byte[] {a, b}, new byte[] {}, new
+ * byte[] {c}} returns the byteArray {@code {a, b, c}}.
+ *
+ * @param arrays zero or more {@code byte} arrays
+ * @return a single byteArray containing all the values from the source arrays, in
+ * order
+ */
+ static byte[] concat(byte[]... arrays) {
+ int length = 0;
+ for (byte[] array : arrays) {
+ length += array.length;
+ }
+ byte[] result = new byte[length];
+ int pos = 0;
+ for (byte[] array : arrays) {
+ System.arraycopy(array, 0, result, pos, array.length);
+ pos += array.length;
}
- return i;
+ return result;
}
- return -1;
- }
- /**
- * Returns the index of the last appearance of the value {@code target} in
- * {@code array}.
- *
- * @param array an array of {@code byte} values, possibly empty
- * @param target a primitive {@code byte} value
- * @return the greatest index {@code i} for which {@code array[i] == target},
- * or {@code -1} if no such index exists.
- */
- static int lastIndexOf(byte[] array, byte target, int start, int end) {
- for (int i = end - 1; i >= start; i--) {
- if (array[i] == target) {
+ /**
+ * Returns the start position of the first occurrence of the specified {@code
+ * target} within {@code array}, or {@code -1} if there is no such occurrence.
+ *
+ *
More formally, returns the lowest index {@code i} such that {@code
+ * java.util.Arrays.copyOfRange(array, i, i + target.length)} contains exactly
+ * the same elements as {@code target}.
+ *
+ * @param array the array to search for the sequence {@code target}
+ * @param target the array to search for as a sub-sequence of {@code array}
+ */
+ static int indexOf(byte[] array, byte[] target, int start, int end) {
+ Objects.requireNonNull(array, "array must not be null");
+ Objects.requireNonNull(target, "target must not be null");
+ if (target.length == 0 || start < 0) {
+ return -1;
+ }
+
+ outer:
+ for (int i = start; i < Math.min(end, array.length - target.length + 1); i++) {
+ for (int j = 0; j < target.length; j++) {
+ if (array[i + j] != target[j]) {
+ continue outer;
+ }
+ }
return i;
}
+ return -1;
}
- return -1;
- }
- /**
- * Counts the occurrence of target in the the in the subject array
- *
- * @param array to count in
- * @param target to count
- * @return number of times target is in subject
- */
- static int countByte(byte[] array, byte target) {
- int count = 0;
- for (byte b : array) {
- if (b == target) {
- count++;
+ /**
+ * Returns the index of the last appearance of the value {@code target} in
+ * {@code array}.
+ *
+ * @param array an array of {@code byte} values, possibly empty
+ * @param target a primitive {@code byte} value
+ * @return the greatest index {@code i} for which {@code array[i] == target},
+ * or {@code -1} if no such index exists.
+ */
+ static int lastIndexOf(byte[] array, byte target, int start, int end) {
+ for (int i = end - 1; i >= start; i--) {
+ if (array[i] == target) {
+ return i;
+ }
}
+ return -1;
}
- return count;
- }
- /**
- * Counts the times given pattern (ie. an array) can be found in given array
- *
- * @param array to count in
- * @param pattern to match in array
- * @return number of times pattern is in subject
- */
- static int countByteArray(byte[] array, byte[] pattern) {
- Objects.requireNonNull(pattern, "pattern must not be null");
- if (pattern.length == 0 || array.length == 0) {
- return 0;
- }
- int count = 0;
- outer:
- for (int i = 0; i < array.length - pattern.length + 1; i++) {
- for (int j = 0; j < pattern.length; j++) {
- if (array[i + j] != pattern[j]) {
- continue outer;
+ /**
+ * Counts the occurrence of target in the the in the subject array
+ *
+ * @param array to count in
+ * @param target to count
+ * @return number of times target is in subject
+ */
+ static int countByte(byte[] array, byte target) {
+ int count = 0;
+ for (byte b : array) {
+ if (b == target) {
+ count++;
}
}
- count++;
+ return count;
}
- return count;
- }
- /**
- * Copies a collection of {@code Byte} instances into a new array of
- * primitive {@code byte} values.
- *
- *
Elements are copied from the argument collection as if by {@code
- * collection.toArray()}. Calling this method is as thread-safe as calling
- * that method.
- *
- * @param collection a collection of {@code Byte} objects
- * @return an array containing the same values as {@code collection}, in the
- * same order, converted to primitives
- * @throws NullPointerException if {@code collection} or any of its elements
- * is null
- */
- static byte[] toArray(Collection collection) {
- Object[] boxedArray = collection.toArray();
- int len = boxedArray.length;
- byte[] array = new byte[len];
- for (int i = 0; i < len; i++) {
- array[i] = (Byte) boxedArray[i];
- }
- return array;
- }
+ /**
+ * Counts the times given pattern (ie. an array) can be found in given array
+ *
+ * @param array to count in
+ * @param pattern to match in array
+ * @return number of times pattern is in subject
+ */
+ static int countByteArray(byte[] array, byte[] pattern) {
+ Objects.requireNonNull(pattern, "pattern must not be null");
+ if (pattern.length == 0 || array.length == 0) {
+ return 0;
+ }
+ int count = 0;
+ outer:
+ for (int i = 0; i < array.length - pattern.length + 1; i++) {
+ for (int j = 0; j < pattern.length; j++) {
+ if (array[i + j] != pattern[j]) {
+ continue outer;
+ }
+ }
+ count++;
+ }
+ return count;
+ }
- /**
- * Converts given array to list of boxed bytes. Will create a new list
- * and not reuse the array reference.
- *
- * @param array to convert
- * @return list with same length and content as array
- */
- static List toList(byte[] array) {
- List list = new ArrayList<>(array.length);
- for (byte b : array) {
- list.add(b);
+ /**
+ * Simple Durstenfeld shuffle.
+ * This will shuffle given array and will not make a copy, so beware.
+ *
+ * See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm
+ *
+ * @param array to shuffle
+ * @param random used to derive entropy - use {@link java.security.SecureRandom} instance if you want this to be secure
+ */
+ static void shuffle(byte[] array, Random random) {
+ for (int i = array.length - 1; i > 0; i--) {
+ int index = random.nextInt(i + 1);
+ byte a = array[index];
+ array[index] = array[i];
+ array[i] = a;
+ }
}
- return list;
- }
- /**
- * Converts this primitive array to an boxed object array.
- * Will create a new array and not reuse the array reference.
- *
- * @param array to convert
- * @return new array
- */
- static Byte[] toBoxedArray(byte[] array) {
- Byte[] objectArray = new Byte[array.length];
- for (int i = 0; i < array.length; i++) {
- objectArray[i] = array[i];
+ /**
+ * Reverses the elements of {@code array} between {@code fromIndex} inclusive and {@code toIndex}
+ * exclusive. This is equivalent to {@code
+ * Collections.reverse(Bytes.asList(array).subList(fromIndex, toIndex))}, but is likely to be more
+ * efficient.
+ *
+ * @throws IndexOutOfBoundsException if {@code fromIndex < 0}, {@code toIndex > array.length}, or
+ * {@code toIndex > fromIndex}
+ */
+ static void reverse(byte[] array, int fromIndex, int toIndex) {
+ Objects.requireNonNull(array);
+ for (int i = fromIndex, j = toIndex - 1; i < j; i++, j--) {
+ byte tmp = array[i];
+ array[i] = array[j];
+ array[j] = tmp;
+ }
}
- return objectArray;
- }
- /**
- * Converts this object array to an primitives type array.
- * Will create a new array and not reuse the array reference.
- *
- * @param objectArray to convert
- * @return new array
- */
- static byte[] toPrimitiveArray(Byte[] objectArray) {
- byte[] primitivesArray = new byte[objectArray.length];
- for (int i = 0; i < objectArray.length; i++) {
- primitivesArray[i] = objectArray[i];
+ /**
+ * Combines a single argument with a vararg to a single array
+ *
+ * @param firstByte first arg
+ * @param moreBytes varargs
+ * @return array containing all args
+ */
+ static byte[] concatVararg(byte firstByte, byte[] moreBytes) {
+ if (moreBytes == null) {
+ return new byte[]{firstByte};
+ } else {
+ return concat(new byte[]{firstByte}, moreBytes);
+ }
}
- return primitivesArray;
- }
- /**
- * Creates a byte array from given int array.
- * The resulting byte array will have length intArray * 4.
- *
- * @param intArray to convert
- * @return resulting byte array
- */
- static byte[] toByteArray(int[] intArray) {
- byte[] primitivesArray = new byte[intArray.length * 4];
- for (int i = 0; i < intArray.length; i++) {
- byte[] intBytes = ByteBuffer.allocate(4).putInt(intArray[i]).array();
- System.arraycopy(intBytes, 0, primitivesArray, (i * 4), intBytes.length);
+ /**
+ * Light shift of whole byte array by shiftBitCount bits.
+ * This method will alter the input byte array.
+ */
+ static byte[] shiftLeft(byte[] byteArray, int shiftBitCount) {
+ final int shiftMod = shiftBitCount % 8;
+ final byte carryMask = (byte) ((1 << shiftMod) - 1);
+ final int offsetBytes = (shiftBitCount / 8);
+
+ int sourceIndex;
+ for (int i = 0; i < byteArray.length; i++) {
+ sourceIndex = i + offsetBytes;
+ if (sourceIndex >= byteArray.length) {
+ byteArray[i] = 0;
+ } else {
+ byte src = byteArray[sourceIndex];
+ byte dst = (byte) (src << shiftMod);
+ if (sourceIndex + 1 < byteArray.length) {
+ dst |= byteArray[sourceIndex + 1] >>> (8 - shiftMod) & carryMask;
+ }
+ byteArray[i] = dst;
+ }
+ }
+ return byteArray;
}
- return primitivesArray;
- }
- /**
- * Creates a byte array from given long array.
- * The resulting byte array will have length longArray * 8
- *
- * @param longArray to convert
- * @return resulting byte array
- */
- static byte[] toByteArray(long[] longArray) {
- byte[] primitivesArray = new byte[longArray.length * 8];
- for (int i = 0; i < longArray.length; i++) {
- byte[] longBytes = ByteBuffer.allocate(8).putLong(longArray[i]).array();
- System.arraycopy(longBytes, 0, primitivesArray, (i * 8), longBytes.length);
+ /**
+ * Unsigned/logical right shift of whole byte array by shiftBitCount bits.
+ * This method will alter the input byte array.
+ */
+ static byte[] shiftRight(byte[] byteArray, int shiftBitCount) {
+ final int shiftMod = shiftBitCount % 8;
+ final byte carryMask = (byte) (0xFF << (8 - shiftMod));
+ final int offsetBytes = (shiftBitCount / 8);
+
+ int sourceIndex;
+ for (int i = byteArray.length - 1; i >= 0; i--) {
+ sourceIndex = i - offsetBytes;
+ if (sourceIndex < 0) {
+ byteArray[i] = 0;
+ } else {
+ byte src = byteArray[sourceIndex];
+ byte dst = (byte) ((0xff & src) >>> shiftMod);
+ if (sourceIndex - 1 >= 0) {
+ dst |= byteArray[sourceIndex - 1] << (8 - shiftMod) & carryMask;
+ }
+ byteArray[i] = dst;
+ }
+ }
+ return byteArray;
}
- return primitivesArray;
- }
- /**
- * Simple Durstenfeld shuffle
- *
- * See: https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm
- *
- * @param array
- * @param random
- */
- static void shuffle(byte[] array, Random random) {
- for (int i = array.length - 1; i > 0; i--) {
- int index = random.nextInt(i + 1);
- byte a = array[index];
- array[index] = array[i];
- array[i] = a;
+ /**
+ * See https://codahale.com/a-lesson-in-timing-attacks/
+ */
+ static boolean constantTimeEquals(byte[] obj, byte[] anotherArray) {
+ if (anotherArray == null || obj.length != anotherArray.length) return false;
+
+ int result = 0;
+ for (int i = 0; i < obj.length; i++) {
+ result |= obj[i] ^ anotherArray[i];
+ }
+ return result == 0;
}
}
/**
- * Reverses the elements of {@code array} between {@code fromIndex} inclusive and {@code toIndex}
- * exclusive. This is equivalent to {@code
- * Collections.reverse(Bytes.asList(array).subList(fromIndex, toIndex))}, but is likely to be more
- * efficient.
- *
- * @throws IndexOutOfBoundsException if {@code fromIndex < 0}, {@code toIndex > array.length}, or
- * {@code toIndex > fromIndex}
+ * Util method related converting byte arrays to other types.
*/
- static void reverse(byte[] array, int fromIndex, int toIndex) {
- Objects.requireNonNull(array);
- for (int i = fromIndex, j = toIndex - 1; i < j; i++, j--) {
- byte tmp = array[i];
- array[i] = array[j];
- array[j] = tmp;
+ static final class Converter {
+ private Converter() {
}
- }
- /**
- * Read bytes, buffered, from given input stream. Pass -1 to read the whole stream or limit with length
- * parameter.
- *
- * @param inputStream to read from
- * @param maxLengthToRead how many bytes to read from input stream; pass -1 to read whole stream
- * @return all bytes from the stream (possibly limited by maxLengthToRead); output length is never longer than stream size
- */
- static byte[] readFromStream(InputStream inputStream, final int maxLengthToRead) {
- final boolean readWholeStream = maxLengthToRead == -1;
- int remaining = maxLengthToRead;
- try {
- ByteArrayOutputStream out = new ByteArrayOutputStream(readWholeStream ? 32 : maxLengthToRead);
- byte[] buf = new byte[0];
- while (readWholeStream || remaining > 0) {
- int bufSize = Math.min(BUF_SIZE, readWholeStream ? BUF_SIZE : remaining);
- if (buf.length != bufSize) {
- buf = new byte[bufSize];
- }
- int r = inputStream.read(buf);
- if (r == -1) {
- break;
- }
- remaining -= r;
- out.write(buf, 0, r);
+ /**
+ * Copies a collection of {@code Byte} instances into a new array of
+ * primitive {@code byte} values.
+ *
+ *
Elements are copied from the argument collection as if by {@code
+ * collection.toArray()}. Calling this method is as thread-safe as calling
+ * that method.
+ *
+ * @param collection a collection of {@code Byte} objects
+ * @return an array containing the same values as {@code collection}, in the
+ * same order, converted to primitives
+ * @throws NullPointerException if {@code collection} or any of its elements
+ * is null
+ */
+ static byte[] toArray(Collection collection) {
+ Object[] boxedArray = collection.toArray();
+ int len = boxedArray.length;
+ byte[] array = new byte[len];
+ for (int i = 0; i < len; i++) {
+ array[i] = (java.lang.Byte) boxedArray[i];
}
- return out.toByteArray();
- } catch (Exception e) {
- throw new IllegalStateException("could not read from input stream", e);
+ return array;
}
- }
- /**
- * Read all bytes until length from given byte array.
- *
- * @param dataInput to read from
- * @return all bytes from the dataInput
- */
- static byte[] readFromDataInput(DataInput dataInput, int length) {
- ByteArrayOutputStream out = new ByteArrayOutputStream(length);
- try {
- byte[] buf;
- int remaining = length;
- for (int i = 0; i < length; i++) {
- buf = new byte[Math.min(remaining, BUF_SIZE)];
- dataInput.readFully(buf);
- out.write(buf);
- remaining -= buf.length;
- }
- return out.toByteArray();
- } catch (Exception e) {
- throw new IllegalStateException("could not read from data input", e);
+ /**
+ * Converts given array to list of boxed bytes. Will create a new list
+ * and not reuse the array reference.
+ *
+ * @param array to convert
+ * @return list with same length and content as array
+ */
+ static List toList(byte[] array) {
+ List list = new ArrayList<>(array.length);
+ for (byte b : array) {
+ list.add(b);
+ }
+ return list;
}
- }
- /**
- * Combines a single argument with a vararg to a single array
- *
- * @param firstByte first arg
- * @param moreBytes varargs
- * @return array containing all args
- */
- static byte[] concatVararg(byte firstByte, byte[] moreBytes) {
- if (moreBytes == null) {
- return new byte[]{firstByte};
- } else {
- return concat(new byte[]{firstByte}, moreBytes);
+ /**
+ * Converts this primitive array to an boxed object array.
+ * Will create a new array and not reuse the array reference.
+ *
+ * @param array to convert
+ * @return new array
+ */
+ static java.lang.Byte[] toBoxedArray(byte[] array) {
+ java.lang.Byte[] objectArray = new java.lang.Byte[array.length];
+ for (int i = 0; i < array.length; i++) {
+ objectArray[i] = array[i];
+ }
+ return objectArray;
}
- }
-
- /**
- * Reads all bytes from a file
- *
- * @param file the file to read
- * @return byte content
- */
- static byte[] readFromFile(File file) {
- checkFile(file);
- try {
- return Files.readAllBytes(file.toPath());
- } catch (IOException e) {
- throw new IllegalStateException("could not read from file", e);
+ /**
+ * Converts this object array to an primitives type array.
+ * Will create a new array and not reuse the array reference.
+ *
+ * @param objectArray to convert
+ * @return new array
+ */
+ static byte[] toPrimitiveArray(java.lang.Byte[] objectArray) {
+ byte[] primitivesArray = new byte[objectArray.length];
+ for (int i = 0; i < objectArray.length; i++) {
+ primitivesArray[i] = objectArray[i];
+ }
+ return primitivesArray;
}
- }
- /**
- * Reads bytes from file with given offset and max length
- *
- * @param file to read bytes from
- * @param offset to read
- * @param length from offset
- * @return byte array with length length
- */
- static byte[] readFromFile(File file, int offset, int length) {
- checkFile(file);
- try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
- raf.seek(offset);
- return readFromDataInput(raf, length);
- } catch (Exception e) {
- throw new IllegalStateException("could not read from random access file", e);
+ /**
+ * Creates a byte array from given int array.
+ * The resulting byte array will have length intArray * 4.
+ *
+ * @param intArray to convert
+ * @return resulting byte array
+ */
+ static byte[] toByteArray(int[] intArray) {
+ byte[] primitivesArray = new byte[intArray.length * 4];
+ for (int i = 0; i < intArray.length; i++) {
+ byte[] intBytes = ByteBuffer.allocate(4).putInt(intArray[i]).array();
+ System.arraycopy(intBytes, 0, primitivesArray, (i * 4), intBytes.length);
+ }
+ return primitivesArray;
}
- }
- private static void checkFile(File file) {
- if (file == null || !file.exists() || !file.isFile()) {
- throw new IllegalArgumentException("file must not be null, has to exist and must be a file (not a directory) " + file);
+ /**
+ * Creates a byte array from given long array.
+ * The resulting byte array will have length longArray * 8
+ *
+ * @param longArray to convert
+ * @return resulting byte array
+ */
+ static byte[] toByteArray(long[] longArray) {
+ byte[] primitivesArray = new byte[longArray.length * 8];
+ for (int i = 0; i < longArray.length; i++) {
+ byte[] longBytes = ByteBuffer.allocate(8).putLong(longArray[i]).array();
+ System.arraycopy(longBytes, 0, primitivesArray, (i * 8), longBytes.length);
+ }
+ return primitivesArray;
}
- }
- /**
- * Converts a char array to a byte array with given charset and range
- *
- * @param charArray to get the byte array from
- * @param charset charset to be used to decode the char array
- * @param offset to start reading the char array from (must be smaller than length and gt 0)
- * @param length from offset (must be between 0 and charArray.length)
- * @return byte array of encoded chars
- */
- static byte[] charToByteArray(char[] charArray, Charset charset, int offset, int length) {
- if (offset < 0 || offset > charArray.length)
- throw new IllegalArgumentException("offset must be gt 0 and smaller than array length");
- if (length < 0 || length > charArray.length)
- throw new IllegalArgumentException("length must be at least 1 and less than array length");
- if (offset + length > charArray.length)
- throw new IllegalArgumentException("length + offset must be smaller than array length");
+ /**
+ * Converts a char array to a byte array with given charset and range
+ *
+ * @param charArray to get the byte array from
+ * @param charset charset to be used to decode the char array
+ * @param offset to start reading the char array from (must be smaller than length and gt 0)
+ * @param length from offset (must be between 0 and charArray.length)
+ * @return byte array of encoded chars
+ */
+ static byte[] charToByteArray(char[] charArray, Charset charset, int offset, int length) {
+ if (offset < 0 || offset > charArray.length)
+ throw new IllegalArgumentException("offset must be gt 0 and smaller than array length");
+ if (length < 0 || length > charArray.length)
+ throw new IllegalArgumentException("length must be at least 1 and less than array length");
+ if (offset + length > charArray.length)
+ throw new IllegalArgumentException("length + offset must be smaller than array length");
- if (length == 0) return new byte[0];
+ if (length == 0) return new byte[0];
- CharBuffer charBuffer = CharBuffer.wrap(charArray);
+ CharBuffer charBuffer = CharBuffer.wrap(charArray);
- if (offset != 0 || length != charBuffer.remaining()) {
- charBuffer = charBuffer.subSequence(offset, offset + length);
- }
+ if (offset != 0 || length != charBuffer.remaining()) {
+ charBuffer = charBuffer.subSequence(offset, offset + length);
+ }
- ByteBuffer bb = charset.encode(charBuffer);
- if (bb.capacity() != bb.limit()) {
- byte[] bytes = new byte[bb.remaining()];
- bb.get(bytes);
- return bytes;
+ ByteBuffer bb = charset.encode(charBuffer);
+ if (bb.capacity() != bb.limit()) {
+ byte[] bytes = new byte[bb.remaining()];
+ bb.get(bytes);
+ return bytes;
+ }
+ return bb.array();
}
- return bb.array();
- }
- /**
- * Convert given byte array in given encoding to char array
- *
- * @param bytes as data source
- * @param charset of the byte array
- * @param byteOrder the order of the bytes array
- * @return char array
- */
- static char[] byteToCharArray(byte[] bytes, Charset charset, ByteOrder byteOrder) {
- Objects.requireNonNull(bytes, "bytes must not be null");
- Objects.requireNonNull(charset, "charset must not be null");
+ /**
+ * Convert given byte array in given encoding to char array
+ *
+ * @param bytes as data source
+ * @param charset of the byte array
+ * @param byteOrder the order of the bytes array
+ * @return char array
+ */
+ static char[] byteToCharArray(byte[] bytes, Charset charset, ByteOrder byteOrder) {
+ Objects.requireNonNull(bytes, "bytes must not be null");
+ Objects.requireNonNull(charset, "charset must not be null");
- try {
- CharBuffer charBuffer = charset.newDecoder().decode(ByteBuffer.wrap(bytes).order(byteOrder));
- if (charBuffer.capacity() != charBuffer.limit()) {
- char[] compacted = new char[charBuffer.remaining()];
- charBuffer.get(compacted);
- return compacted;
+ try {
+ CharBuffer charBuffer = charset.newDecoder().decode(ByteBuffer.wrap(bytes).order(byteOrder));
+ if (charBuffer.capacity() != charBuffer.limit()) {
+ char[] compacted = new char[charBuffer.remaining()];
+ charBuffer.get(compacted);
+ return compacted;
+ }
+ return charBuffer.array();
+ } catch (CharacterCodingException e) {
+ throw new IllegalStateException(e);
}
- return charBuffer.array();
- } catch (CharacterCodingException e) {
- throw new IllegalStateException(e);
}
- }
- /**
- * Converts the byte array to an int array. This will spread 4 bytes into a single int:
- *
- *
- * [b1, b2, b3, b4] = int1
- *
- *
- * @param bytes to convert to int array
- * @param byteOrder of the byte array
- * @return int array
- */
- static int[] toIntArray(byte[] bytes, ByteOrder byteOrder) {
- IntBuffer buffer = ByteBuffer.wrap(bytes).order(byteOrder).asIntBuffer();
- if (buffer.hasArray()) {
- return buffer.array();
- } else {
- int[] array = new int[buffer.remaining()];
- buffer.get(array);
- return array;
+ /**
+ * Converts the byte array to an int array. This will spread 4 bytes into a single int:
+ *
+ *
+ * [b1, b2, b3, b4] = int1
+ *
+ *
+ * @param bytes to convert to int array
+ * @param byteOrder of the byte array
+ * @return int array
+ */
+ static int[] toIntArray(byte[] bytes, ByteOrder byteOrder) {
+ IntBuffer buffer = ByteBuffer.wrap(bytes).order(byteOrder).asIntBuffer();
+ if (buffer.hasArray()) {
+ return buffer.array();
+ } else {
+ int[] array = new int[buffer.remaining()];
+ buffer.get(array);
+ return array;
+ }
+ }
+
+ /**
+ * Convert UUID to a newly generated 16 byte long array representation. Puts the 8 byte most significant bits and
+ * 8 byte least significant bits into an byte array.
+ *
+ * @param uuid to convert to array
+ * @return buffer containing the 16 bytes
+ */
+ static ByteBuffer toBytesFromUUID(UUID uuid) {
+ ByteBuffer bb = ByteBuffer.allocate(16);
+ bb.putLong(uuid.getMostSignificantBits());
+ bb.putLong(uuid.getLeastSignificantBits());
+ return bb;
}
}
/**
- * Shows the length and a preview of max 8 bytes of the given byte
- *
- * @param bytes to convert to string
- * @return string representation
+ * Util method related to Object class methods.
*/
- static String toString(Bytes bytes) {
- String preview;
- if (bytes.isEmpty()) {
- preview = "";
- } else if (bytes.length() > 8) {
- preview = "(0x" + bytes.copy(0, 4).encodeHex() + "..." + bytes.copy(bytes.length() - 4, 4).encodeHex() + ")";
- } else {
- preview = "(0x" + bytes.encodeHex() + ")";
+ static final class Obj {
+ private Obj() {
}
- return bytes.length() + " " + (bytes.length() == 1 ? "byte" : "bytes") + " " + preview;
- }
+ static boolean equals(byte[] obj, java.lang.Byte[] anotherArray) {
+ if (anotherArray == null) return false;
+ if (obj.length != anotherArray.length) return false;
+ for (int i = 0; i < obj.length; i++) {
+ if (anotherArray[i] == null || obj[i] != anotherArray[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
- /**
- * Light shift of whole byte array by shiftBitCount bits.
- * This method will alter the input byte array.
- */
- static byte[] shiftLeft(byte[] byteArray, int shiftBitCount) {
- final int shiftMod = shiftBitCount % 8;
- final byte carryMask = (byte) ((1 << shiftMod) - 1);
- final int offsetBytes = (shiftBitCount / 8);
-
- int sourceIndex;
- for (int i = 0; i < byteArray.length; i++) {
- sourceIndex = i + offsetBytes;
- if (sourceIndex >= byteArray.length) {
- byteArray[i] = 0;
+ /**
+ * Hashcode implementation for a byte array and given byte order
+ *
+ * @param byteArray to calculate hashCode of
+ * @param byteOrder to calculate hashCode of
+ * @return hashCode
+ */
+ static int hashCode(byte[] byteArray, ByteOrder byteOrder) {
+ int result = Arrays.hashCode(byteArray);
+ result = 31 * result + (byteOrder != null ? byteOrder.hashCode() : 0);
+ return result;
+ }
+
+ /**
+ * Shows the length and a preview of max 8 bytes of the given byte
+ *
+ * @param bytes to convert to string
+ * @return string representation
+ */
+ static String toString(Bytes bytes) {
+ String preview;
+ if (bytes.isEmpty()) {
+ preview = "";
+ } else if (bytes.length() > 8) {
+ preview = "(0x" + bytes.copy(0, 4).encodeHex() + "..." + bytes.copy(bytes.length() - 4, 4).encodeHex() + ")";
} else {
- byte src = byteArray[sourceIndex];
- byte dst = (byte) (src << shiftMod);
- if (sourceIndex + 1 < byteArray.length) {
- dst |= byteArray[sourceIndex + 1] >>> (8 - shiftMod) & carryMask;
- }
- byteArray[i] = dst;
+ preview = "(0x" + bytes.encodeHex() + ")";
}
+
+ return bytes.length() + " " + (bytes.length() == 1 ? "byte" : "bytes") + " " + preview;
}
- return byteArray;
}
/**
- * Unsigned/logical right shift of whole byte array by shiftBitCount bits.
- * This method will alter the input byte array.
+ * Util method related check and validate byte arrays.
*/
- static byte[] shiftRight(byte[] byteArray, int shiftBitCount) {
- final int shiftMod = shiftBitCount % 8;
- final byte carryMask = (byte) (0xFF << (8 - shiftMod));
- final int offsetBytes = (shiftBitCount / 8);
-
- int sourceIndex;
- for (int i = byteArray.length - 1; i >= 0; i--) {
- sourceIndex = i - offsetBytes;
- if (sourceIndex < 0) {
- byteArray[i] = 0;
- } else {
- byte src = byteArray[sourceIndex];
- byte dst = (byte) ((0xff & src) >>> shiftMod);
- if (sourceIndex - 1 >= 0) {
- dst |= byteArray[sourceIndex - 1] << (8 - shiftMod) & carryMask;
- }
- byteArray[i] = dst;
+ static final class Validation {
+ private Validation() {
+ }
+
+ private static void checkFile(java.io.File file) {
+ if (file == null || !file.exists() || !file.isFile()) {
+ throw new IllegalArgumentException("file must not be null, has to exist and must be a file (not a directory) " + file);
}
}
- return byteArray;
- }
- static void checkIndexBounds(int length, int index, int primitiveLength, String type) {
- if (index < 0 || index + primitiveLength > length) {
- throw new IndexOutOfBoundsException("cannot get " + type + " from index out of bounds: " + index);
+ static void checkIndexBounds(int length, int index, int primitiveLength, String type) {
+ if (index < 0 || index + primitiveLength > length) {
+ throw new IndexOutOfBoundsException("cannot get " + type + " from index out of bounds: " + index);
+ }
}
- }
- static void checkExactLength(int length, int expectedLength, String type) {
- if (length != expectedLength) {
- throw new IllegalStateException("cannot convert to " + type + " if length != " + expectedLength + " bytes (was " + length + ")");
+ static void checkExactLength(int length, int expectedLength, String type) {
+ if (length != expectedLength) {
+ throw new IllegalStateException("cannot convert to " + type + " if length != " + expectedLength + " bytes (was " + length + ")");
+ }
}
- }
- static boolean equals(byte[] obj, Byte[] anotherArray) {
- if (anotherArray == null) return false;
- if (obj.length != anotherArray.length) return false;
- for (int i = 0; i < obj.length; i++) {
- if (anotherArray[i] == null || obj[i] != anotherArray[i]) {
- return false;
+ /**
+ * Checks if given length is divisable by mod factor (with zero rest).
+ * This can be used to check of a byte array can be convertet to an e.g. int array which is
+ * multiples of 4.
+ *
+ * @param length of the byte array
+ * @param modFactor to divide the length
+ * @param errorSubject human readable message of the exact error subject
+ */
+ static void checkModLength(int length, int modFactor, String errorSubject) {
+ if (length % modFactor != 0) {
+ throw new IllegalArgumentException("Illegal length for " + errorSubject + ". Byte array length must be multiple of " + modFactor + ", length was " + length);
}
}
- return true;
}
/**
- * See https://codahale.com/a-lesson-in-timing-attacks/
+ * Util method related file operations.
*/
- static boolean constantTimeEquals(byte[] obj, byte[] anotherArray) {
- if (anotherArray == null || obj.length != anotherArray.length) return false;
+ static final class File {
+ private static final int BUF_SIZE = 0x1000; // 4K
- int result = 0;
- for (int i = 0; i < obj.length; i++) {
- result |= obj[i] ^ anotherArray[i];
+ private File() {
}
- return result == 0;
- }
- /**
- * Convert UUID to a newly generated 16 byte long array representation. Puts the 8 byte most significant bits and
- * 8 byte least significant bits into an byte array.
- *
- * @param uuid to convert to array
- * @return buffer containing the 16 bytes
- */
- static ByteBuffer getBytesFromUUID(UUID uuid) {
- ByteBuffer bb = ByteBuffer.allocate(16);
- bb.putLong(uuid.getMostSignificantBits());
- bb.putLong(uuid.getLeastSignificantBits());
- return bb;
- }
+ /**
+ * Read bytes, buffered, from given input stream. Pass -1 to read the whole stream or limit with length
+ * parameter.
+ *
+ * @param inputStream to read from
+ * @param maxLengthToRead how many bytes to read from input stream; pass -1 to read whole stream
+ * @return all bytes from the stream (possibly limited by maxLengthToRead); output length is never longer than stream size
+ */
+ static byte[] readFromStream(InputStream inputStream, final int maxLengthToRead) {
+ final boolean readWholeStream = maxLengthToRead == -1;
+ int remaining = maxLengthToRead;
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream(readWholeStream ? 32 : maxLengthToRead);
+ byte[] buf = new byte[0];
+ while (readWholeStream || remaining > 0) {
+ int bufSize = Math.min(BUF_SIZE, readWholeStream ? BUF_SIZE : remaining);
+ if (buf.length != bufSize) {
+ buf = new byte[bufSize];
+ }
+ int r = inputStream.read(buf);
+ if (r == -1) {
+ break;
+ }
+ remaining -= r;
+ out.write(buf, 0, r);
+ }
+ return out.toByteArray();
+ } catch (Exception e) {
+ throw new IllegalStateException("could not read from input stream", e);
+ }
+ }
- /**
- * Hashcode implementation for a byte array and given byte order
- *
- * @param byteArray to calculate hashCode of
- * @param byteOrder to calculate hashCode of
- * @return hashCode
- */
- static int hashCode(byte[] byteArray, ByteOrder byteOrder) {
- int result = Arrays.hashCode(byteArray);
- result = 31 * result + (byteOrder != null ? byteOrder.hashCode() : 0);
- return result;
- }
+ /**
+ * Read all bytes until length from given byte array.
+ *
+ * @param dataInput to read from
+ * @return all bytes from the dataInput
+ */
+ static byte[] readFromDataInput(DataInput dataInput, int length) {
+ ByteArrayOutputStream out = new ByteArrayOutputStream(length);
+ try {
+ byte[] buf;
+ int remaining = length;
+ for (int i = 0; i < length; i++) {
+ buf = new byte[Math.min(remaining, BUF_SIZE)];
+ dataInput.readFully(buf);
+ out.write(buf);
+ remaining -= buf.length;
+ }
+ return out.toByteArray();
+ } catch (Exception e) {
+ throw new IllegalStateException("could not read from data input", e);
+ }
+ }
- /**
- * Checks if given length is divisable by mod factor (with zero rest).
- * This can be used to check of a byte array can be convertet to an e.g. int array which is
- * multiples of 4.
- *
- * @param length of the byte array
- * @param modFactor to divide the length
- * @param errorSubject human readable message of the exact error subject
- */
- static void checkModLength(int length, int modFactor, String errorSubject) {
- if (length % modFactor != 0) {
- throw new IllegalArgumentException("Illegal length for " + errorSubject + ". Byte array length must be multiple of " + modFactor + ", length was " + length);
+ /**
+ * Reads all bytes from a file
+ *
+ * @param file the file to read
+ * @return byte content
+ */
+ static byte[] readFromFile(java.io.File file) {
+ Validation.checkFile(file);
+
+ try {
+ return Files.readAllBytes(file.toPath());
+ } catch (IOException e) {
+ throw new IllegalStateException("could not read from file", e);
+ }
+ }
+
+ /**
+ * Reads bytes from file with given offset and max length
+ *
+ * @param file to read bytes from
+ * @param offset to read
+ * @param length from offset
+ * @return byte array with length length
+ */
+ static byte[] readFromFile(java.io.File file, int offset, int length) {
+ Validation.checkFile(file);
+ try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
+ raf.seek(offset);
+ return readFromDataInput(raf, length);
+ } catch (Exception e) {
+ throw new IllegalStateException("could not read from random access file", e);
+ }
}
+
+ }
+
+ private Util() {
}
/*
@@ -652,6 +709,7 @@ static void checkModLength(int length, int modFactor, String errorSubject) {
*
* @param
*/
+ @SuppressWarnings("WeakerAccess")
static final class Entropy {
private final Map map = new HashMap<>();
private int total = 0;
@@ -683,7 +741,7 @@ public double entropy() {
/**
* A simple iterator for the bytes class, which does not support remove
*/
- static final class BytesIterator implements Iterator {
+ static final class BytesIterator implements Iterator {
private final byte[] array;
/**
* Index of element to be returned by subsequent call to next.
@@ -700,10 +758,10 @@ public boolean hasNext() {
}
@Override
- public Byte next() {
+ public java.lang.Byte next() {
try {
int i = cursor;
- Byte next = array[i];
+ java.lang.Byte next = array[i];
cursor = i + 1;
return next;
} catch (IndexOutOfBoundsException e) {
diff --git a/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java b/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java
index 44711af..1775301 100644
--- a/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java
+++ b/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java
@@ -26,7 +26,11 @@
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-import java.io.*;
+import java.io.ByteArrayInputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -413,8 +417,8 @@ public void fromList() {
}
private void checkList(byte[] array) {
- Bytes bList = Bytes.from(Util.toList(array));
- Bytes bLinkedList = Bytes.from(new LinkedList<>(Util.toList(array)));
+ Bytes bList = Bytes.from(Util.Converter.toList(array));
+ Bytes bLinkedList = Bytes.from(new LinkedList<>(Util.Converter.toList(array)));
assertArrayEquals(array, bList.array());
assertArrayEquals(array, bLinkedList.array());
}
@@ -431,10 +435,10 @@ public void fromVariousBytes() {
assertArrayEquals(new byte[1], Bytes.from((byte) 0).array());
assertArrayNotEquals(new byte[0], Bytes.from((byte) 1).array());
- assertArrayEquals(Util.concat(example_bytes_one, example_bytes_one, example_bytes_one), Bytes.from(example_bytes_one, example_bytes_one, example_bytes_one).array());
- assertArrayEquals(Util.concat(example_bytes_two, example_bytes_seven), Bytes.from(example_bytes_two, example_bytes_seven).array());
- assertArrayEquals(Util.concat(example_bytes_one, example_bytes_sixteen), Bytes.from(example_bytes_one, example_bytes_sixteen).array());
- assertArrayNotEquals(Util.concat(example_bytes_sixteen, example_bytes_one), Bytes.from(example_bytes_one, example_bytes_sixteen).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_one, example_bytes_one, example_bytes_one), Bytes.from(example_bytes_one, example_bytes_one, example_bytes_one).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_two, example_bytes_seven), Bytes.from(example_bytes_two, example_bytes_seven).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_one, example_bytes_sixteen), Bytes.from(example_bytes_one, example_bytes_sixteen).array());
+ assertArrayNotEquals(Util.Byte.concat(example_bytes_sixteen, example_bytes_one), Bytes.from(example_bytes_one, example_bytes_sixteen).array());
assertArrayEquals(new byte[]{1, 2, 3}, Bytes.from((byte) 1, (byte) 2, (byte) 3).array());
assertArrayEquals(new byte[2], Bytes.from((byte) 0, (byte) 0).array());
diff --git a/src/test/java/at/favre/lib/bytes/BytesSharedDataConverterTest.java b/src/test/java/at/favre/lib/bytes/BytesSharedDataConverterTest.java
index e6882bc..359a96c 100644
--- a/src/test/java/at/favre/lib/bytes/BytesSharedDataConverterTest.java
+++ b/src/test/java/at/favre/lib/bytes/BytesSharedDataConverterTest.java
@@ -71,9 +71,9 @@ public void duplicate() {
@Test
public void inputStream() {
- assertArrayEquals(example_bytes_one, Util.readFromStream(Bytes.from(example_bytes_one).inputStream(), -1));
- assertArrayEquals(example_bytes_two, Util.readFromStream(Bytes.from(example_bytes_two).inputStream(), -1));
- assertArrayEquals(example_bytes_four, Util.readFromStream(Bytes.from(example_bytes_four).inputStream(), -1));
- assertArrayEquals(example_bytes_sixteen, Util.readFromStream(Bytes.from(example_bytes_sixteen).inputStream(), -1));
+ assertArrayEquals(example_bytes_one, Util.File.readFromStream(Bytes.from(example_bytes_one).inputStream(), -1));
+ assertArrayEquals(example_bytes_two, Util.File.readFromStream(Bytes.from(example_bytes_two).inputStream(), -1));
+ assertArrayEquals(example_bytes_four, Util.File.readFromStream(Bytes.from(example_bytes_four).inputStream(), -1));
+ assertArrayEquals(example_bytes_sixteen, Util.File.readFromStream(Bytes.from(example_bytes_sixteen).inputStream(), -1));
}
}
diff --git a/src/test/java/at/favre/lib/bytes/BytesTransformTest.java b/src/test/java/at/favre/lib/bytes/BytesTransformTest.java
index 780929b..dd6feaf 100644
--- a/src/test/java/at/favre/lib/bytes/BytesTransformTest.java
+++ b/src/test/java/at/favre/lib/bytes/BytesTransformTest.java
@@ -41,28 +41,28 @@ public class BytesTransformTest extends ABytesTest {
public void append() {
assertArrayEquals(new byte[0], Bytes.from(new byte[0]).append(new byte[0]).array());
assertArrayEquals(new byte[1], Bytes.from(new byte[0]).append(new byte[1]).array());
- assertArrayEquals(Util.concat(example_bytes_seven, example_bytes_one), Bytes.from(example_bytes_seven).append(example_bytes_one).array());
- assertArrayEquals(Util.concat(example_bytes_seven, example_bytes_two), Bytes.from(example_bytes_seven).append(example_bytes_two).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_seven, example_bytes_one), Bytes.from(example_bytes_seven).append(example_bytes_one).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_seven, example_bytes_two), Bytes.from(example_bytes_seven).append(example_bytes_two).array());
- assertArrayEquals(Util.concat(example_bytes_eight, example_bytes_sixteen), Bytes.from(example_bytes_eight).append(Bytes.from(example_bytes_sixteen)).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_eight, example_bytes_sixteen), Bytes.from(example_bytes_eight).append(Bytes.from(example_bytes_sixteen)).array());
}
@Test
public void appendMultipleByteArrays() {
assertArrayEquals(new byte[0], Bytes.from(new byte[0]).append(new byte[0], new byte[0]).array());
assertArrayEquals(new byte[]{0x0, 0x01, 0x02, 0x03}, Bytes.from(new byte[]{0x0}).append(new byte[]{0x1}, new byte[]{0x2}, new byte[]{0x3}).array());
- assertArrayEquals(Util.concat(example_bytes_seven, example_bytes_one, example_bytes_sixteen), Bytes.from(example_bytes_seven).append(example_bytes_one, example_bytes_sixteen).array());
- assertArrayEquals(Util.concat(example_bytes_sixteen, example_bytes_sixteen, example_bytes_sixteen), Bytes.from(example_bytes_sixteen).append(example_bytes_sixteen, example_bytes_sixteen).array());
- assertArrayEquals(Util.concat(example_bytes_two, example_bytes_seven, example_bytes_twentyfour, example_bytes_eight), Bytes.from(example_bytes_two).append(example_bytes_seven, example_bytes_twentyfour, example_bytes_eight).array());
- assertArrayEquals(Util.concat(example_bytes_two, example_bytes_seven, example_bytes_twentyfour, example_bytes_one, example_bytes_sixteen), Bytes.from(example_bytes_two).append(example_bytes_seven, example_bytes_twentyfour).append(example_bytes_one, example_bytes_sixteen).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_seven, example_bytes_one, example_bytes_sixteen), Bytes.from(example_bytes_seven).append(example_bytes_one, example_bytes_sixteen).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_sixteen, example_bytes_sixteen, example_bytes_sixteen), Bytes.from(example_bytes_sixteen).append(example_bytes_sixteen, example_bytes_sixteen).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_two, example_bytes_seven, example_bytes_twentyfour, example_bytes_eight), Bytes.from(example_bytes_two).append(example_bytes_seven, example_bytes_twentyfour, example_bytes_eight).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_two, example_bytes_seven, example_bytes_twentyfour, example_bytes_one, example_bytes_sixteen), Bytes.from(example_bytes_two).append(example_bytes_seven, example_bytes_twentyfour).append(example_bytes_one, example_bytes_sixteen).array());
}
@Test
public void appendNullSafe() {
assertArrayEquals(new byte[0], Bytes.from(new byte[0]).appendNullSafe(new byte[0]).array());
assertArrayEquals(new byte[1], Bytes.from(new byte[0]).appendNullSafe(new byte[1]).array());
- assertArrayEquals(Util.concat(example_bytes_seven, example_bytes_one), Bytes.from(example_bytes_seven).appendNullSafe(example_bytes_one).array());
- assertArrayEquals(Util.concat(example_bytes_seven, example_bytes_two), Bytes.from(example_bytes_seven).appendNullSafe(example_bytes_two).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_seven, example_bytes_one), Bytes.from(example_bytes_seven).appendNullSafe(example_bytes_one).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_seven, example_bytes_two), Bytes.from(example_bytes_seven).appendNullSafe(example_bytes_two).array());
assertArrayEquals(new byte[0], Bytes.from(new byte[0]).appendNullSafe(null).array());
assertArrayEquals(new byte[1], Bytes.from(new byte[1]).appendNullSafe(null).array());
assertArrayEquals(example_bytes_seven, Bytes.from(example_bytes_seven).appendNullSafe(null).array());
@@ -70,11 +70,11 @@ public void appendNullSafe() {
@Test
public void appendPrimitives() {
- assertArrayEquals(Util.concat(example_bytes_eight, new byte[]{1}), Bytes.from(example_bytes_eight).append((byte) 1).array());
- assertArrayEquals(Util.concat(example_bytes_eight, ByteBuffer.allocate(2).putChar((char) 1423).array()), Bytes.from(example_bytes_eight).append((char) 1423).array());
- assertArrayEquals(Util.concat(example_bytes_eight, ByteBuffer.allocate(2).putShort((short) 4129).array()), Bytes.from(example_bytes_eight).append((short) 4129).array());
- assertArrayEquals(Util.concat(example_bytes_eight, ByteBuffer.allocate(4).putInt(362173671).array()), Bytes.from(example_bytes_eight).append(362173671).array());
- assertArrayEquals(Util.concat(example_bytes_eight, ByteBuffer.allocate(8).putLong(0x6762173671L).array()), Bytes.from(example_bytes_eight).append(0x6762173671L).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_eight, new byte[]{1}), Bytes.from(example_bytes_eight).append((byte) 1).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_eight, ByteBuffer.allocate(2).putChar((char) 1423).array()), Bytes.from(example_bytes_eight).append((char) 1423).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_eight, ByteBuffer.allocate(2).putShort((short) 4129).array()), Bytes.from(example_bytes_eight).append((short) 4129).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_eight, ByteBuffer.allocate(4).putInt(362173671).array()), Bytes.from(example_bytes_eight).append(362173671).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_eight, ByteBuffer.allocate(8).putLong(0x6762173671L).array()), Bytes.from(example_bytes_eight).append(0x6762173671L).array());
}
@Test
@@ -99,7 +99,7 @@ public void appendMulti() {
byte[] oldByteArray = b.copy().array();
Bytes newByte = Bytes.random(i % 16 + 1);
b = b.append(newByte);
- assertArrayEquals(Util.concat(oldByteArray, newByte.copy().array()), b.array());
+ assertArrayEquals(Util.Byte.concat(oldByteArray, newByte.copy().array()), b.array());
}
}
@@ -108,9 +108,9 @@ public void resizeGrowLsb() {
assertArrayEquals(new byte[8], Bytes.from(new byte[0]).resize(8).array());
assertArrayEquals(example_bytes_one, Bytes.from(example_bytes_one).resize(1).array());
assertArrayEquals(example_bytes_one, Bytes.from(example_bytes_one).resize(1).array());
- assertArrayEquals(Util.concat(new byte[7], example_bytes_one), Bytes.from(example_bytes_one).resize(8).array());
- assertArrayEquals(Util.concat(new byte[1], example_bytes_seven), Bytes.from(example_bytes_seven).resize(8).array());
- assertArrayEquals(Util.concat(new byte[1], example_bytes_sixteen), Bytes.from(example_bytes_sixteen).resize(17).array());
+ assertArrayEquals(Util.Byte.concat(new byte[7], example_bytes_one), Bytes.from(example_bytes_one).resize(8).array());
+ assertArrayEquals(Util.Byte.concat(new byte[1], example_bytes_seven), Bytes.from(example_bytes_seven).resize(8).array());
+ assertArrayEquals(Util.Byte.concat(new byte[1], example_bytes_sixteen), Bytes.from(example_bytes_sixteen).resize(17).array());
}
@Test
@@ -118,9 +118,9 @@ public void resizeGrowMsb() {
assertArrayEquals(new byte[8], Bytes.from(new byte[0]).resize(8, BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_ZERO_INDEX).array());
assertArrayEquals(example_bytes_one, Bytes.from(example_bytes_one).resize(1, BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_ZERO_INDEX).array());
assertArrayEquals(example_bytes_one, Bytes.from(example_bytes_one).resize(1, BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_ZERO_INDEX).array());
- assertArrayEquals(Util.concat(example_bytes_one, new byte[7]), Bytes.from(example_bytes_one).resize(8, BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_ZERO_INDEX).array());
- assertArrayEquals(Util.concat(example_bytes_seven, new byte[1]), Bytes.from(example_bytes_seven).resize(8, BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_ZERO_INDEX).array());
- assertArrayEquals(Util.concat(example_bytes_sixteen, new byte[1]), Bytes.from(example_bytes_sixteen).resize(17, BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_ZERO_INDEX).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_one, new byte[7]), Bytes.from(example_bytes_one).resize(8, BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_ZERO_INDEX).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_seven, new byte[1]), Bytes.from(example_bytes_seven).resize(8, BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_ZERO_INDEX).array());
+ assertArrayEquals(Util.Byte.concat(example_bytes_sixteen, new byte[1]), Bytes.from(example_bytes_sixteen).resize(17, BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_ZERO_INDEX).array());
}
@Test
diff --git a/src/test/java/at/favre/lib/bytes/UtilTest.java b/src/test/java/at/favre/lib/bytes/UtilTest.java
index ba0d15a..6758f5e 100644
--- a/src/test/java/at/favre/lib/bytes/UtilTest.java
+++ b/src/test/java/at/favre/lib/bytes/UtilTest.java
@@ -55,36 +55,36 @@ public void testIndexOf() {
}
private int indexOf(byte[] empty, byte b) {
- return Util.indexOf(empty, new byte[]{b}, 0, empty.length);
+ return Util.Byte.indexOf(empty, new byte[]{b}, 0, empty.length);
}
@Test
public void testIndexOf_arrayTarget() {
- assertEquals(-1, Util.indexOf(EMPTY, EMPTY, 0, EMPTY.length));
- assertEquals(-1, Util.indexOf(ARRAY234, EMPTY, 0, ARRAY234.length));
- assertEquals(-1, Util.indexOf(EMPTY, ARRAY234, 0, EMPTY.length));
- assertEquals(-1, Util.indexOf(ARRAY234, ARRAY1, 0, ARRAY234.length));
- assertEquals(-1, Util.indexOf(ARRAY1, ARRAY234, 0, ARRAY1.length));
- assertEquals(0, Util.indexOf(ARRAY1, ARRAY1, 0, ARRAY1.length));
- assertEquals(0, Util.indexOf(ARRAY234, ARRAY234, 0, ARRAY234.length));
- assertEquals(0, Util.indexOf(
+ assertEquals(-1, Util.Byte.indexOf(EMPTY, EMPTY, 0, EMPTY.length));
+ assertEquals(-1, Util.Byte.indexOf(ARRAY234, EMPTY, 0, ARRAY234.length));
+ assertEquals(-1, Util.Byte.indexOf(EMPTY, ARRAY234, 0, EMPTY.length));
+ assertEquals(-1, Util.Byte.indexOf(ARRAY234, ARRAY1, 0, ARRAY234.length));
+ assertEquals(-1, Util.Byte.indexOf(ARRAY1, ARRAY234, 0, ARRAY1.length));
+ assertEquals(0, Util.Byte.indexOf(ARRAY1, ARRAY1, 0, ARRAY1.length));
+ assertEquals(0, Util.Byte.indexOf(ARRAY234, ARRAY234, 0, ARRAY234.length));
+ assertEquals(0, Util.Byte.indexOf(
ARRAY234, new byte[]{(byte) 2, (byte) 3}, 0, 2));
- assertEquals(1, Util.indexOf(
+ assertEquals(1, Util.Byte.indexOf(
ARRAY234, new byte[]{(byte) 3, (byte) 4}, 0, 2));
- assertEquals(1, Util.indexOf(ARRAY234, new byte[]{(byte) 3}, 0, ARRAY234.length));
- assertEquals(2, Util.indexOf(ARRAY234, new byte[]{(byte) 4}, 0, ARRAY234.length));
- assertEquals(1, Util.indexOf(new byte[]{(byte) 2, (byte) 3, (byte) 3, (byte) 3, (byte) 3}, new byte[]{(byte) 3}, 0, 5));
- assertEquals(2, Util.indexOf(
+ assertEquals(1, Util.Byte.indexOf(ARRAY234, new byte[]{(byte) 3}, 0, ARRAY234.length));
+ assertEquals(2, Util.Byte.indexOf(ARRAY234, new byte[]{(byte) 4}, 0, ARRAY234.length));
+ assertEquals(1, Util.Byte.indexOf(new byte[]{(byte) 2, (byte) 3, (byte) 3, (byte) 3, (byte) 3}, new byte[]{(byte) 3}, 0, 5));
+ assertEquals(2, Util.Byte.indexOf(
new byte[]{(byte) 2, (byte) 3, (byte) 2,
(byte) 3, (byte) 4, (byte) 2, (byte) 3},
new byte[]{(byte) 2, (byte) 3, (byte) 4}
, 0, 7));
- assertEquals(1, Util.indexOf(
+ assertEquals(1, Util.Byte.indexOf(
new byte[]{(byte) 2, (byte) 2, (byte) 3,
(byte) 4, (byte) 2, (byte) 3, (byte) 4},
new byte[]{(byte) 2, (byte) 3, (byte) 4}
, 0, 7));
- assertEquals(-1, Util.indexOf(
+ assertEquals(-1, Util.Byte.indexOf(
new byte[]{(byte) 4, (byte) 3, (byte) 2},
new byte[]{(byte) 2, (byte) 3, (byte) 4}
, 0, 2));
@@ -106,47 +106,47 @@ public void testLastIndexOf() {
}
private int lastIndexOf(byte[] empty, byte b) {
- return Util.lastIndexOf(empty, b, 0, empty.length);
+ return Util.Byte.lastIndexOf(empty, b, 0, empty.length);
}
@Test
public void testConcat() {
- assertTrue(Arrays.equals(EMPTY, Util.concat()));
- assertTrue(Arrays.equals(EMPTY, Util.concat(EMPTY)));
- assertTrue(Arrays.equals(EMPTY, Util.concat(EMPTY, EMPTY, EMPTY)));
- assertTrue(Arrays.equals(ARRAY1, Util.concat(ARRAY1)));
- assertNotSame(ARRAY1, Util.concat(ARRAY1));
- assertTrue(Arrays.equals(ARRAY1, Util.concat(EMPTY, ARRAY1, EMPTY)));
+ assertTrue(Arrays.equals(EMPTY, Util.Byte.concat()));
+ assertTrue(Arrays.equals(EMPTY, Util.Byte.concat(EMPTY)));
+ assertTrue(Arrays.equals(EMPTY, Util.Byte.concat(EMPTY, EMPTY, EMPTY)));
+ assertTrue(Arrays.equals(ARRAY1, Util.Byte.concat(ARRAY1)));
+ assertNotSame(ARRAY1, Util.Byte.concat(ARRAY1));
+ assertTrue(Arrays.equals(ARRAY1, Util.Byte.concat(EMPTY, ARRAY1, EMPTY)));
assertTrue(Arrays.equals(
new byte[]{(byte) 1, (byte) 1, (byte) 1},
- Util.concat(ARRAY1, ARRAY1, ARRAY1)));
+ Util.Byte.concat(ARRAY1, ARRAY1, ARRAY1)));
assertTrue(Arrays.equals(
new byte[]{(byte) 1, (byte) 2, (byte) 3, (byte) 4},
- Util.concat(ARRAY1, ARRAY234)));
+ Util.Byte.concat(ARRAY1, ARRAY234)));
}
@Test
public void testToArray() {
// need explicit type parameter to avoid javac warning!?
List none = Arrays.asList();
- assertTrue(Arrays.equals(EMPTY, Util.toArray(none)));
+ assertTrue(Arrays.equals(EMPTY, Util.Converter.toArray(none)));
List one = Arrays.asList((byte) 1);
- assertTrue(Arrays.equals(ARRAY1, Util.toArray(one)));
+ assertTrue(Arrays.equals(ARRAY1, Util.Converter.toArray(one)));
byte[] array = {(byte) 0, (byte) 1, (byte) 0x55};
List three = Arrays.asList((byte) 0, (byte) 1, (byte) 0x55);
- assertTrue(Arrays.equals(array, Util.toArray(three)));
+ assertTrue(Arrays.equals(array, Util.Converter.toArray(three)));
- assertTrue(Arrays.equals(array, Util.toArray(Util.toList(array))));
+ assertTrue(Arrays.equals(array, Util.Converter.toArray(Util.Converter.toList(array))));
}
@Test
public void testToArray_withNull() {
List list = Arrays.asList((byte) 0, (byte) 1, null);
try {
- Util.toArray(list);
+ Util.Converter.toArray(list);
fail();
} catch (NullPointerException expected) {
}
@@ -157,14 +157,14 @@ public void testToArray_withConversion() {
byte[] array = {(byte) 0, (byte) 1, (byte) 2};
List bytes = Arrays.asList((byte) 0, (byte) 1, (byte) 2);
- assertTrue(Arrays.equals(array, Util.toArray(bytes)));
+ assertTrue(Arrays.equals(array, Util.Converter.toArray(bytes)));
}
@Test
public void testAsList_toArray_roundTrip() {
byte[] array = {(byte) 0, (byte) 1, (byte) 2};
- List list = Util.toList(array);
- byte[] newArray = Util.toArray(list);
+ List list = Util.Converter.toList(array);
+ byte[] newArray = Util.Converter.toArray(list);
// Make sure it returned a copy
list.set(0, (byte) 4);
@@ -178,21 +178,21 @@ public void testAsList_toArray_roundTrip() {
// This test stems from a real bug found by andrewk
public void testAsList_subList_toArray_roundTrip() {
byte[] array = {(byte) 0, (byte) 1, (byte) 2, (byte) 3};
- List list = Util.toList(array);
+ List list = Util.Converter.toList(array);
assertTrue(Arrays.equals(new byte[]{(byte) 1, (byte) 2},
- Util.toArray(list.subList(1, 3))));
+ Util.Converter.toArray(list.subList(1, 3))));
assertTrue(Arrays.equals(new byte[]{},
- Util.toArray(list.subList(2, 2))));
+ Util.Converter.toArray(list.subList(2, 2))));
}
@Test(expected = IllegalStateException.class)
public void readFromStream() {
- Util.readFromStream(null, -1);
+ Util.File.readFromStream(null, -1);
}
@Test
public void concatVararg() {
- assertArrayEquals(new byte[]{1}, Util.concatVararg((byte) 1, null));
+ assertArrayEquals(new byte[]{1}, Util.Byte.concatVararg((byte) 1, null));
}
@Test
@@ -216,34 +216,34 @@ public void testReverseIndexed() {
private static void testReverse(byte[] input, byte[] expectedOutput) {
input = Arrays.copyOf(input, input.length);
- Util.reverse(input, 0, input.length);
+ Util.Byte.reverse(input, 0, input.length);
assertTrue(Arrays.equals(expectedOutput, input));
}
private static void testReverse(byte[] input, int fromIndex, int toIndex, byte[] expectedOutput) {
input = Arrays.copyOf(input, input.length);
- Util.reverse(input, fromIndex, toIndex);
+ Util.Byte.reverse(input, fromIndex, toIndex);
assertTrue(Arrays.equals(expectedOutput, input));
}
@Test
public void testLeftShift() {
byte[] test = new byte[]{0, 0, 1, 0};
- assertArrayEquals(new byte[]{0, 1, 0, 0}, Util.shiftLeft(new byte[]{0, 0, -128, 0}, 1));
- assertArrayEquals(new byte[]{0, 1, 0, 0}, Util.shiftLeft(new byte[]{0, 0, 64, 0}, 2));
- assertArrayEquals(new byte[]{1, 1, 1, 0}, Util.shiftLeft(new byte[]{-128, -128, -128, -128}, 1));
- assertArrayEquals(new byte[]{0, 0, 2, 0}, Util.shiftLeft(Bytes.from(test).array(), 1));
- assertArrayEquals(new byte[]{0, 0, 4, 0}, Util.shiftLeft(Bytes.from(test).array(), 2));
- assertArrayEquals(new byte[]{0, 0, 8, 0}, Util.shiftLeft(Bytes.from(test).array(), 3));
- assertArrayEquals(new byte[]{0, 1, 0, 0}, Util.shiftLeft(Bytes.from(test).array(), 8));
- assertArrayEquals(new byte[]{0, 2, 0, 0}, Util.shiftLeft(Bytes.from(test).array(), 9));
- assertArrayEquals(new byte[]{1, 0, 0, 0}, Util.shiftLeft(Bytes.from(test).array(), 16));
- assertArrayEquals(new byte[]{2, 0, 0, 0}, Util.shiftLeft(Bytes.from(test).array(), 17));
- assertArrayEquals(new byte[]{-128, 0, 0, 0}, Util.shiftLeft(Bytes.from(test).array(), 23));
- assertArrayEquals(new byte[]{0, 0, 0, 0}, Util.shiftLeft(Bytes.from(test).array(), 24));
- assertArrayEquals(new byte[]{0, 0, 0, 0}, Util.shiftLeft(Bytes.from(test).array(), 24));
-
- assertSame(test, Util.shiftLeft(test, 1));
+ assertArrayEquals(new byte[]{0, 1, 0, 0}, Util.Byte.shiftLeft(new byte[]{0, 0, -128, 0}, 1));
+ assertArrayEquals(new byte[]{0, 1, 0, 0}, Util.Byte.shiftLeft(new byte[]{0, 0, 64, 0}, 2));
+ assertArrayEquals(new byte[]{1, 1, 1, 0}, Util.Byte.shiftLeft(new byte[]{-128, -128, -128, -128}, 1));
+ assertArrayEquals(new byte[]{0, 0, 2, 0}, Util.Byte.shiftLeft(Bytes.from(test).array(), 1));
+ assertArrayEquals(new byte[]{0, 0, 4, 0}, Util.Byte.shiftLeft(Bytes.from(test).array(), 2));
+ assertArrayEquals(new byte[]{0, 0, 8, 0}, Util.Byte.shiftLeft(Bytes.from(test).array(), 3));
+ assertArrayEquals(new byte[]{0, 1, 0, 0}, Util.Byte.shiftLeft(Bytes.from(test).array(), 8));
+ assertArrayEquals(new byte[]{0, 2, 0, 0}, Util.Byte.shiftLeft(Bytes.from(test).array(), 9));
+ assertArrayEquals(new byte[]{1, 0, 0, 0}, Util.Byte.shiftLeft(Bytes.from(test).array(), 16));
+ assertArrayEquals(new byte[]{2, 0, 0, 0}, Util.Byte.shiftLeft(Bytes.from(test).array(), 17));
+ assertArrayEquals(new byte[]{-128, 0, 0, 0}, Util.Byte.shiftLeft(Bytes.from(test).array(), 23));
+ assertArrayEquals(new byte[]{0, 0, 0, 0}, Util.Byte.shiftLeft(Bytes.from(test).array(), 24));
+ assertArrayEquals(new byte[]{0, 0, 0, 0}, Util.Byte.shiftLeft(Bytes.from(test).array(), 24));
+
+ assertSame(test, Util.Byte.shiftLeft(test, 1));
}
@Test
@@ -254,7 +254,7 @@ public void testLeftShiftAgainstRefImpl() {
Bytes rnd = Bytes.random(4 + new Random().nextInt(14));
byte[] expected = Bytes.from(new BigInteger(rnd.array()).shiftLeft(shift).toByteArray()).resize(rnd.length(), BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_MAX_LENGTH).array();
- byte[] actual = Bytes.from(Util.shiftLeft(rnd.copy().array(), shift)).resize(rnd.length(), BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_MAX_LENGTH).array();
+ byte[] actual = Bytes.from(Util.Byte.shiftLeft(rnd.copy().array(), shift)).resize(rnd.length(), BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_MAX_LENGTH).array();
System.out.println("Original \t" + rnd.encodeBinary() + " << " + shift);
System.out.println("Expected \t" + Bytes.wrap(expected).encodeBinary());
@@ -269,18 +269,18 @@ public void testLeftShiftAgainstRefImpl() {
public void testRightShift() {
byte[] test = new byte[]{0, 0, 16, 0};
assertEquals(0b01111110, 0b11111101 >>> 1);
- assertArrayEquals(new byte[]{0b00101101, (byte) 0b01111110}, Util.shiftRight(new byte[]{0b01011010, (byte) 0b11111101}, 1));
- assertArrayEquals(new byte[]{0, -128, -128, -128}, Util.shiftRight(new byte[]{1, 1, 1, 1}, 1));
- assertArrayEquals(new byte[]{0, -128, 66, 0}, Util.shiftRight(new byte[]{2, 1, 8, 2}, 2));
+ assertArrayEquals(new byte[]{0b00101101, (byte) 0b01111110}, Util.Byte.shiftRight(new byte[]{0b01011010, (byte) 0b11111101}, 1));
+ assertArrayEquals(new byte[]{0, -128, -128, -128}, Util.Byte.shiftRight(new byte[]{1, 1, 1, 1}, 1));
+ assertArrayEquals(new byte[]{0, -128, 66, 0}, Util.Byte.shiftRight(new byte[]{2, 1, 8, 2}, 2));
assertArrayEquals(new byte[]{0, -128, 66, 0}, new BigInteger(new byte[]{2, 1, 8, 2}).shiftRight(2).toByteArray());
- assertArrayEquals(new byte[]{0, 0, 0, -128}, Util.shiftRight(Bytes.from(test).array(), 5));
- assertArrayEquals(new byte[]{0, 0, 0, -128}, Util.shiftRight(new byte[]{0, 0, 1, 0}, 1));
- assertArrayEquals(new byte[]{0, 0, 8, 0}, Util.shiftRight(Bytes.from(test).array(), 1));
- assertArrayEquals(new byte[]{0, 0, 4, 0}, Util.shiftRight(Bytes.from(test).array(), 2));
- assertArrayEquals(new byte[]{0, 0, 2, 0}, Util.shiftRight(Bytes.from(test).array(), 3));
- assertArrayEquals(new byte[]{0, 0, 1, 0}, Util.shiftRight(Bytes.from(test).array(), 4));
-
- assertSame(test, Util.shiftRight(test, 1));
+ assertArrayEquals(new byte[]{0, 0, 0, -128}, Util.Byte.shiftRight(Bytes.from(test).array(), 5));
+ assertArrayEquals(new byte[]{0, 0, 0, -128}, Util.Byte.shiftRight(new byte[]{0, 0, 1, 0}, 1));
+ assertArrayEquals(new byte[]{0, 0, 8, 0}, Util.Byte.shiftRight(Bytes.from(test).array(), 1));
+ assertArrayEquals(new byte[]{0, 0, 4, 0}, Util.Byte.shiftRight(Bytes.from(test).array(), 2));
+ assertArrayEquals(new byte[]{0, 0, 2, 0}, Util.Byte.shiftRight(Bytes.from(test).array(), 3));
+ assertArrayEquals(new byte[]{0, 0, 1, 0}, Util.Byte.shiftRight(Bytes.from(test).array(), 4));
+
+ assertSame(test, Util.Byte.shiftRight(test, 1));
}
@Test
@@ -290,7 +290,7 @@ public void testRightShiftAgainstRefImpl() {
Bytes rnd = Bytes.random(4 + new Random().nextInt(12));
if (!rnd.bitAt(rnd.lengthBit() - 1)) { //only unsigned
byte[] expected = Bytes.from(new BigInteger(rnd.array()).shiftRight(shift).toByteArray()).resize(rnd.length(), BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_MAX_LENGTH).array();
- byte[] actual = Bytes.from(Util.shiftRight(rnd.copy().array(), shift)).resize(rnd.length(), BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_MAX_LENGTH).array();
+ byte[] actual = Bytes.from(Util.Byte.shiftRight(rnd.copy().array(), shift)).resize(rnd.length(), BytesTransformer.ResizeTransformer.Mode.RESIZE_KEEP_FROM_MAX_LENGTH).array();
// System.out.println("Original \t" + rnd.encodeBinary() + " >> " + shift);
// System.out.println("Expected \t" + Bytes.wrap(expected).encodeBinary());
@@ -322,7 +322,7 @@ private void checkCharArrayToByteArray(char[] subject, Charset charset) {
for (int lenI = 1; lenI < subject.length + 1; lenI++) {
for (int offsetI = 0; offsetI < subject.length; offsetI++) {
if (offsetI + lenI > subject.length) break;
- byte[] bytes = Util.charToByteArray(subject, charset, offsetI, lenI);
+ byte[] bytes = Util.Converter.charToByteArray(subject, charset, offsetI, lenI);
assertEquals(Bytes.wrap(bytes), Bytes.wrap(new String(subject).substring(offsetI, offsetI + lenI).getBytes(charset)));
}
}
@@ -330,21 +330,21 @@ private void checkCharArrayToByteArray(char[] subject, Charset charset) {
}
private void compareArrayToByteArrayWithoutOffset(char[] subject, Charset charset) {
- assertArrayEquals(Util.charToByteArray(subject, charset, 0, subject.length), new String(subject).getBytes(charset));
+ assertArrayEquals(Util.Converter.charToByteArray(subject, charset, 0, subject.length), new String(subject).getBytes(charset));
}
@Test(expected = IllegalArgumentException.class)
public void testCharToByteArrayIllegalOffset() {
- Util.charToByteArray("abcdef".toCharArray(), StandardCharsets.UTF_8, -1, 1);
+ Util.Converter.charToByteArray("abcdef".toCharArray(), StandardCharsets.UTF_8, -1, 1);
}
@Test(expected = IllegalArgumentException.class)
public void testCharToByteArrayIllegalLength() {
- Util.charToByteArray("abcdef".toCharArray(), StandardCharsets.UTF_8, 0, -1);
+ Util.Converter.charToByteArray("abcdef".toCharArray(), StandardCharsets.UTF_8, 0, -1);
}
@Test(expected = IllegalArgumentException.class)
public void testCharToByteArrayIllegalOffsetPlusLength() {
- Util.charToByteArray("abcdef".toCharArray(), StandardCharsets.UTF_8, 4, 3);
+ Util.Converter.charToByteArray("abcdef".toCharArray(), StandardCharsets.UTF_8, 4, 3);
}
}
From 8f1f21e8aab94c85ad62979d2ff2b2ab562fce91 Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Mon, 7 Jan 2019 18:33:14 +0100
Subject: [PATCH 017/118] Refactor Util tests and add test for toIntArray()
---
.../java/at/favre/lib/bytes/AUtilTest.java | 7 +
.../{UtilTest.java => UtilByteTest.java} | 137 ++---------------
.../at/favre/lib/bytes/UtilConverterTest.java | 140 ++++++++++++++++++
3 files changed, 159 insertions(+), 125 deletions(-)
create mode 100644 src/test/java/at/favre/lib/bytes/AUtilTest.java
rename src/test/java/at/favre/lib/bytes/{UtilTest.java => UtilByteTest.java} (66%)
create mode 100644 src/test/java/at/favre/lib/bytes/UtilConverterTest.java
diff --git a/src/test/java/at/favre/lib/bytes/AUtilTest.java b/src/test/java/at/favre/lib/bytes/AUtilTest.java
new file mode 100644
index 0000000..ee5112e
--- /dev/null
+++ b/src/test/java/at/favre/lib/bytes/AUtilTest.java
@@ -0,0 +1,7 @@
+package at.favre.lib.bytes;
+
+abstract class AUtilTest {
+ static final byte[] EMPTY = {};
+ static final byte[] ARRAY1 = {(byte) 1};
+ static final byte[] ARRAY234 = {(byte) 2, (byte) 3, (byte) 4};
+}
diff --git a/src/test/java/at/favre/lib/bytes/UtilTest.java b/src/test/java/at/favre/lib/bytes/UtilByteTest.java
similarity index 66%
rename from src/test/java/at/favre/lib/bytes/UtilTest.java
rename to src/test/java/at/favre/lib/bytes/UtilByteTest.java
index 6758f5e..3892269 100644
--- a/src/test/java/at/favre/lib/bytes/UtilTest.java
+++ b/src/test/java/at/favre/lib/bytes/UtilByteTest.java
@@ -25,19 +25,12 @@
import org.junit.Test;
import java.math.BigInteger;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
import java.util.Arrays;
-import java.util.List;
import java.util.Random;
-import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.*;
-public class UtilTest {
- private static final byte[] EMPTY = {};
- private static final byte[] ARRAY1 = {(byte) 1};
- private static final byte[] ARRAY234 = {(byte) 2, (byte) 3, (byte) 4};
+public class UtilByteTest extends AUtilTest {
@Test
public void testIndexOf() {
@@ -111,78 +104,18 @@ private int lastIndexOf(byte[] empty, byte b) {
@Test
public void testConcat() {
- assertTrue(Arrays.equals(EMPTY, Util.Byte.concat()));
- assertTrue(Arrays.equals(EMPTY, Util.Byte.concat(EMPTY)));
- assertTrue(Arrays.equals(EMPTY, Util.Byte.concat(EMPTY, EMPTY, EMPTY)));
- assertTrue(Arrays.equals(ARRAY1, Util.Byte.concat(ARRAY1)));
+ assertArrayEquals(EMPTY, Util.Byte.concat());
+ assertArrayEquals(EMPTY, Util.Byte.concat(EMPTY));
+ assertArrayEquals(EMPTY, Util.Byte.concat(EMPTY, EMPTY, EMPTY));
+ assertArrayEquals(ARRAY1, Util.Byte.concat(ARRAY1));
assertNotSame(ARRAY1, Util.Byte.concat(ARRAY1));
- assertTrue(Arrays.equals(ARRAY1, Util.Byte.concat(EMPTY, ARRAY1, EMPTY)));
- assertTrue(Arrays.equals(
+ assertArrayEquals(ARRAY1, Util.Byte.concat(EMPTY, ARRAY1, EMPTY));
+ assertArrayEquals(
new byte[]{(byte) 1, (byte) 1, (byte) 1},
- Util.Byte.concat(ARRAY1, ARRAY1, ARRAY1)));
- assertTrue(Arrays.equals(
+ Util.Byte.concat(ARRAY1, ARRAY1, ARRAY1));
+ assertArrayEquals(
new byte[]{(byte) 1, (byte) 2, (byte) 3, (byte) 4},
- Util.Byte.concat(ARRAY1, ARRAY234)));
- }
-
- @Test
- public void testToArray() {
- // need explicit type parameter to avoid javac warning!?
- List none = Arrays.asList();
- assertTrue(Arrays.equals(EMPTY, Util.Converter.toArray(none)));
-
- List one = Arrays.asList((byte) 1);
- assertTrue(Arrays.equals(ARRAY1, Util.Converter.toArray(one)));
-
- byte[] array = {(byte) 0, (byte) 1, (byte) 0x55};
-
- List three = Arrays.asList((byte) 0, (byte) 1, (byte) 0x55);
- assertTrue(Arrays.equals(array, Util.Converter.toArray(three)));
-
- assertTrue(Arrays.equals(array, Util.Converter.toArray(Util.Converter.toList(array))));
- }
-
- @Test
- public void testToArray_withNull() {
- List list = Arrays.asList((byte) 0, (byte) 1, null);
- try {
- Util.Converter.toArray(list);
- fail();
- } catch (NullPointerException expected) {
- }
- }
-
- @Test
- public void testToArray_withConversion() {
- byte[] array = {(byte) 0, (byte) 1, (byte) 2};
-
- List bytes = Arrays.asList((byte) 0, (byte) 1, (byte) 2);
- assertTrue(Arrays.equals(array, Util.Converter.toArray(bytes)));
- }
-
- @Test
- public void testAsList_toArray_roundTrip() {
- byte[] array = {(byte) 0, (byte) 1, (byte) 2};
- List list = Util.Converter.toList(array);
- byte[] newArray = Util.Converter.toArray(list);
-
- // Make sure it returned a copy
- list.set(0, (byte) 4);
- assertTrue(Arrays.equals(
- new byte[]{(byte) 0, (byte) 1, (byte) 2}, newArray));
- newArray[1] = (byte) 5;
- assertEquals((byte) 1, (byte) list.get(1));
- }
-
- @Test
- // This test stems from a real bug found by andrewk
- public void testAsList_subList_toArray_roundTrip() {
- byte[] array = {(byte) 0, (byte) 1, (byte) 2, (byte) 3};
- List list = Util.Converter.toList(array);
- assertTrue(Arrays.equals(new byte[]{(byte) 1, (byte) 2},
- Util.Converter.toArray(list.subList(1, 3))));
- assertTrue(Arrays.equals(new byte[]{},
- Util.Converter.toArray(list.subList(2, 2))));
+ Util.Byte.concat(ARRAY1, ARRAY234));
}
@Test(expected = IllegalStateException.class)
@@ -217,13 +150,13 @@ public void testReverseIndexed() {
private static void testReverse(byte[] input, byte[] expectedOutput) {
input = Arrays.copyOf(input, input.length);
Util.Byte.reverse(input, 0, input.length);
- assertTrue(Arrays.equals(expectedOutput, input));
+ assertArrayEquals(expectedOutput, input);
}
private static void testReverse(byte[] input, int fromIndex, int toIndex, byte[] expectedOutput) {
input = Arrays.copyOf(input, input.length);
Util.Byte.reverse(input, fromIndex, toIndex);
- assertTrue(Arrays.equals(expectedOutput, input));
+ assertArrayEquals(expectedOutput, input);
}
@Test
@@ -301,50 +234,4 @@ public void testRightShiftAgainstRefImpl() {
}
}
}
-
- @Test
- public void testCharToByteArray() {
- Charset[] charsets = new Charset[]{StandardCharsets.UTF_8, StandardCharsets.US_ASCII, StandardCharsets.UTF_16};
- for (Charset charset : charsets) {
- checkCharArrayToByteArray("".toCharArray(), charset);
- checkCharArrayToByteArray("A".toCharArray(), charset);
- checkCharArrayToByteArray("12".toCharArray(), charset);
- checkCharArrayToByteArray("XYZ".toCharArray(), charset);
- checkCharArrayToByteArray("abcdefg".toCharArray(), charset);
- checkCharArrayToByteArray("71oh872gdl2dhp81g".toCharArray(), charset);
-
- }
-
- checkCharArrayToByteArray("யe2ாமறிந்தиют убSîne klâwenasd1".toCharArray(), StandardCharsets.UTF_8);
- }
-
- private void checkCharArrayToByteArray(char[] subject, Charset charset) {
- for (int lenI = 1; lenI < subject.length + 1; lenI++) {
- for (int offsetI = 0; offsetI < subject.length; offsetI++) {
- if (offsetI + lenI > subject.length) break;
- byte[] bytes = Util.Converter.charToByteArray(subject, charset, offsetI, lenI);
- assertEquals(Bytes.wrap(bytes), Bytes.wrap(new String(subject).substring(offsetI, offsetI + lenI).getBytes(charset)));
- }
- }
- compareArrayToByteArrayWithoutOffset(subject, charset);
- }
-
- private void compareArrayToByteArrayWithoutOffset(char[] subject, Charset charset) {
- assertArrayEquals(Util.Converter.charToByteArray(subject, charset, 0, subject.length), new String(subject).getBytes(charset));
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testCharToByteArrayIllegalOffset() {
- Util.Converter.charToByteArray("abcdef".toCharArray(), StandardCharsets.UTF_8, -1, 1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testCharToByteArrayIllegalLength() {
- Util.Converter.charToByteArray("abcdef".toCharArray(), StandardCharsets.UTF_8, 0, -1);
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void testCharToByteArrayIllegalOffsetPlusLength() {
- Util.Converter.charToByteArray("abcdef".toCharArray(), StandardCharsets.UTF_8, 4, 3);
- }
}
diff --git a/src/test/java/at/favre/lib/bytes/UtilConverterTest.java b/src/test/java/at/favre/lib/bytes/UtilConverterTest.java
new file mode 100644
index 0000000..9088783
--- /dev/null
+++ b/src/test/java/at/favre/lib/bytes/UtilConverterTest.java
@@ -0,0 +1,140 @@
+package at.favre.lib.bytes;
+
+import org.junit.Test;
+
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class UtilConverterTest extends AUtilTest {
+
+ @Test
+ public void testToArray() {
+ List none = Collections.emptyList();
+ assertArrayEquals(EMPTY, Util.Converter.toArray(none));
+
+ List one = Collections.singletonList((byte) 1);
+ assertArrayEquals(ARRAY1, Util.Converter.toArray(one));
+
+ byte[] array = {(byte) 0, (byte) 1, (byte) 0x55};
+
+ List three = Arrays.asList((byte) 0, (byte) 1, (byte) 0x55);
+ assertArrayEquals(array, Util.Converter.toArray(three));
+
+ assertArrayEquals(array, Util.Converter.toArray(Util.Converter.toList(array)));
+ }
+
+ @Test
+ public void testToArray_withNull() {
+ List list = Arrays.asList((byte) 0, (byte) 1, null);
+ try {
+ Util.Converter.toArray(list);
+ fail();
+ } catch (NullPointerException expected) {
+ }
+ }
+
+ @Test
+ public void testToArray_withConversion() {
+ byte[] array = {(byte) 0, (byte) 1, (byte) 2};
+
+ List bytes = Arrays.asList((byte) 0, (byte) 1, (byte) 2);
+ assertArrayEquals(array, Util.Converter.toArray(bytes));
+ }
+
+ @Test
+ public void testAsList_toArray_roundTrip() {
+ byte[] array = {(byte) 0, (byte) 1, (byte) 2};
+ List list = Util.Converter.toList(array);
+ byte[] newArray = Util.Converter.toArray(list);
+
+ // Make sure it returned a copy
+ list.set(0, (byte) 4);
+ assertArrayEquals(
+ new byte[]{(byte) 0, (byte) 1, (byte) 2}, newArray);
+ newArray[1] = (byte) 5;
+ assertEquals((byte) 1, (byte) list.get(1));
+ }
+
+ @Test
+ // This test stems from a real bug found by andrewk
+ public void testAsList_subList_toArray_roundTrip() {
+ byte[] array = {(byte) 0, (byte) 1, (byte) 2, (byte) 3};
+ List list = Util.Converter.toList(array);
+ assertArrayEquals(new byte[]{(byte) 1, (byte) 2},
+ Util.Converter.toArray(list.subList(1, 3)));
+ assertArrayEquals(new byte[]{},
+ Util.Converter.toArray(list.subList(2, 2)));
+ }
+
+ @Test
+ public void testCharToByteArray() {
+ Charset[] charsets = new Charset[]{StandardCharsets.UTF_8, StandardCharsets.US_ASCII, StandardCharsets.UTF_16};
+ for (Charset charset : charsets) {
+ checkCharArrayToByteArray("".toCharArray(), charset);
+ checkCharArrayToByteArray("A".toCharArray(), charset);
+ checkCharArrayToByteArray("12".toCharArray(), charset);
+ checkCharArrayToByteArray("XYZ".toCharArray(), charset);
+ checkCharArrayToByteArray("abcdefg".toCharArray(), charset);
+ checkCharArrayToByteArray("71oh872gdl2dhp81g".toCharArray(), charset);
+
+ }
+
+ checkCharArrayToByteArray("யe2ாமறிந்தиют убSîne klâwenasd1".toCharArray(), StandardCharsets.UTF_8);
+ }
+
+ private void checkCharArrayToByteArray(char[] subject, Charset charset) {
+ for (int lenI = 1; lenI < subject.length + 1; lenI++) {
+ for (int offsetI = 0; offsetI < subject.length; offsetI++) {
+ if (offsetI + lenI > subject.length) break;
+ byte[] bytes = Util.Converter.charToByteArray(subject, charset, offsetI, lenI);
+ assertEquals(Bytes.wrap(bytes), Bytes.wrap(new String(subject).substring(offsetI, offsetI + lenI).getBytes(charset)));
+ }
+ }
+ compareArrayToByteArrayWithoutOffset(subject, charset);
+ }
+
+ private void compareArrayToByteArrayWithoutOffset(char[] subject, Charset charset) {
+ assertArrayEquals(Util.Converter.charToByteArray(subject, charset, 0, subject.length), new String(subject).getBytes(charset));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCharToByteArrayIllegalOffset() {
+ Util.Converter.charToByteArray("abcdef".toCharArray(), StandardCharsets.UTF_8, -1, 1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCharToByteArrayIllegalLength() {
+ Util.Converter.charToByteArray("abcdef".toCharArray(), StandardCharsets.UTF_8, 0, -1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCharToByteArrayIllegalOffsetPlusLength() {
+ Util.Converter.charToByteArray("abcdef".toCharArray(), StandardCharsets.UTF_8, 4, 3);
+ }
+
+ @Test
+ public void testToIntArray() {
+ assertArrayEquals(new int[]{1}, Util.Converter.toIntArray(new byte[]{0, 0, 0, 1}, ByteOrder.BIG_ENDIAN));
+ assertArrayEquals(new int[]{257}, Util.Converter.toIntArray(new byte[]{0, 0, 1, 1}, ByteOrder.BIG_ENDIAN));
+
+ assertArrayEquals(new int[]{1}, Util.Converter.toIntArray(new byte[]{1, 0, 0, 0}, ByteOrder.LITTLE_ENDIAN));
+ assertArrayEquals(new int[]{257}, Util.Converter.toIntArray(new byte[]{1, 1, 0, 0}, ByteOrder.LITTLE_ENDIAN));
+
+ assertArrayEquals(new int[]{16_843_009}, Util.Converter.toIntArray(new byte[]{1, 1, 1, 1}, ByteOrder.BIG_ENDIAN));
+ assertArrayEquals(new int[]{571_211_845}, Util.Converter.toIntArray(new byte[]{34, 12, 0, 69}, ByteOrder.BIG_ENDIAN));
+ assertArrayEquals(new int[]{1_290_429_439}, Util.Converter.toIntArray(new byte[]{76, (byte) 234, 99, (byte) 255}, ByteOrder.BIG_ENDIAN));
+ assertArrayEquals(new int[]{257, 65_793, 1}, Util.Converter.toIntArray(new byte[]{0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1}, ByteOrder.BIG_ENDIAN));
+
+ assertArrayEquals(new int[]{1_290_429_439}, Util.Converter.toIntArray(new byte[]{(byte) 255, 99, (byte) 234, 76}, ByteOrder.LITTLE_ENDIAN));
+ assertArrayEquals(new int[]{257, 65_793, 1}, Util.Converter.toIntArray(new byte[]{1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0}, ByteOrder.LITTLE_ENDIAN));
+
+ assertArrayEquals(new int[0], Util.Converter.toIntArray(new byte[0], ByteOrder.LITTLE_ENDIAN));
+ assertArrayEquals(new int[0], Util.Converter.toIntArray(new byte[0], ByteOrder.BIG_ENDIAN));
+ }
+}
From c4e0e1b1050e6c08dcb798ee61f830537469bb98 Mon Sep 17 00:00:00 2001
From: pfavre
Date: Mon, 7 Jan 2019 20:21:07 +0100
Subject: [PATCH 018/118] Add `toLongArray()` conversion
fixes #29
---
CHANGELOG | 1 +
README.md | 8 +++
src/main/java/at/favre/lib/bytes/Bytes.java | 40 ++++++++------
src/main/java/at/favre/lib/bytes/Util.java | 55 +++++++++----------
.../bytes/BytesToConvertOtherTypesTest.java | 46 ++++++++++++++++
.../at/favre/lib/bytes/UtilConverterTest.java | 18 ++++++
6 files changed, 121 insertions(+), 47 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 006ea88..767f922 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -6,6 +6,7 @@
* add `toCharArray()` method which decodes internal byte array to char[] #27
* add `encodeBase64()` supporting padding-less encoding
* add `toIntArray()` converter #28
+* add `toLongArray()` converter #29
### Breaking
diff --git a/README.md b/README.md
index ec9a774..b7a7f6a 100644
--- a/README.md
+++ b/README.md
@@ -507,6 +507,13 @@ Bytes.wrap(array).toInt();
Bytes.wrap(array).toDouble();
```
+To primitive arrays
+
+```java
+Bytes.wrap(array).toIntArray(); // of type int[]
+Bytes.wrap(array).toLongArray(); // of type long[]
+```
+
To other collections
```java
@@ -525,6 +532,7 @@ and others
```java
Bytes.wrap(array).toUUID(); // convert 16 byte to UUID
+Bytes.wrap(array).toCharArray(StandardCharsets.UTF-8); // converts to encoded char array
```
### Mutable and Read-Only
diff --git a/src/main/java/at/favre/lib/bytes/Bytes.java b/src/main/java/at/favre/lib/bytes/Bytes.java
index 6b74102..417e38f 100644
--- a/src/main/java/at/favre/lib/bytes/Bytes.java
+++ b/src/main/java/at/favre/lib/bytes/Bytes.java
@@ -21,29 +21,14 @@
package at.favre.lib.bytes;
-import java.io.ByteArrayInputStream;
-import java.io.DataInput;
-import java.io.File;
-import java.io.InputStream;
-import java.io.Serializable;
+import java.io.*;
import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.CharBuffer;
-import java.nio.IntBuffer;
-import java.nio.ReadOnlyBufferException;
+import java.nio.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.text.Normalizer;
-import java.util.Arrays;
-import java.util.BitSet;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Objects;
-import java.util.Random;
-import java.util.UUID;
+import java.util.*;
/**
* Bytes is wrapper class for an byte-array that allows a lot of convenience operations on it:
@@ -1910,6 +1895,25 @@ public long toLong() {
return longAt(0);
}
+ /**
+ * Converts the internal byte array to an long array, that is, every 8 bytes will be packed into a single long.
+ *
+ * E.g. 8 bytes will be packed to a length 1 long array:
+ *
+ * [b1, b2, b3, b4, b5, b6, b7, b8] = [int1]
+ *
+ *
+ * This conversion respects the internal byte order. Will only work if all bytes can be directly mapped to long,
+ * which means the byte array length must be dividable by 8 without rest.
+ *
+ * @return new long[] instance representing this byte array
+ * @throws IllegalArgumentException if internal byte length mod 8 != 0
+ */
+ public long[] toLongArray() {
+ Util.Validation.checkModLength(length(), 8, "creating an long array");
+ return Util.Converter.toLongArray(internalArray(), byteOrder);
+ }
+
/**
* If the underlying byte array is exactly 4 byte / 32 bit long, return the
* representation for a Java float value. The output is dependent on the set {@link #byteOrder()}.
diff --git a/src/main/java/at/favre/lib/bytes/Util.java b/src/main/java/at/favre/lib/bytes/Util.java
index ac1b7e3..ce12cde 100644
--- a/src/main/java/at/favre/lib/bytes/Util.java
+++ b/src/main/java/at/favre/lib/bytes/Util.java
@@ -21,29 +21,12 @@
package at.favre.lib.bytes;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInput;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.CharBuffer;
-import java.nio.IntBuffer;
+import java.io.*;
+import java.nio.*;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Objects;
-import java.util.Random;
-import java.util.UUID;
+import java.util.*;
/**
* Common Util methods to convert or modify byte arrays
@@ -458,22 +441,36 @@ static char[] byteToCharArray(byte[] bytes, Charset charset, ByteOrder byteOrder
* Converts the byte array to an int array. This will spread 4 bytes into a single int:
*
*
*
- * @param bytes to convert to int array
+ * @param bytes to convert to int array, must be % 4 == 0 to work correctly
* @param byteOrder of the byte array
* @return int array
*/
static int[] toIntArray(byte[] bytes, ByteOrder byteOrder) {
IntBuffer buffer = ByteBuffer.wrap(bytes).order(byteOrder).asIntBuffer();
- if (buffer.hasArray()) {
- return buffer.array();
- } else {
- int[] array = new int[buffer.remaining()];
- buffer.get(array);
- return array;
- }
+ int[] array = new int[buffer.remaining()];
+ buffer.get(array);
+ return array;
+ }
+
+ /**
+ * Converts the byte array to an long array. This will spread 8 bytes into a single long:
+ *
+ *
- * This implementation requires O(n) time and space complexity.
+ * This implementation requires O(n) time and O(1) space complexity.
*
* @return entropy value; higher is more entropy (simply: more different values)
* @see Entropy
*/
public double entropy() {
- return new Util.Entropy<>(toList()).entropy();
+ return Util.Byte.entropy(internalArray());
}
/* CONVERTERS POSSIBLY REUSING THE INTERNAL ARRAY ***************************************************************/
diff --git a/src/main/java/at/favre/lib/bytes/Util.java b/src/main/java/at/favre/lib/bytes/Util.java
index ce12cde..b4b1ba8 100644
--- a/src/main/java/at/favre/lib/bytes/Util.java
+++ b/src/main/java/at/favre/lib/bytes/Util.java
@@ -268,6 +268,36 @@ static boolean constantTimeEquals(byte[] obj, byte[] anotherArray) {
}
return result == 0;
}
+
+ /**
+ * Calculates the entropy factor of a byte array.
+ *
+ * This implementation will not create a copy of the internal array and will only internally initialize
+ * a int array with 256 elements as temporary buffer.
+ *
+ * @param array to calculate the entropy from
+ * @return entropy factor, higher means higher entropy
+ */
+ static double entropy(byte[] array) {
+ final int[] buffer = new int[256];
+ Arrays.fill(buffer, -1);
+
+ for (byte element : array) {
+ int unsigned = 0xff & element;
+ if (buffer[unsigned] == -1) {
+ buffer[unsigned] = 0;
+ }
+ buffer[unsigned]++;
+ }
+
+ double entropy = 0;
+ for (int count : buffer) {
+ if (count == -1) continue;
+ double prob = (double) count / array.length;
+ entropy -= prob * (Math.log(prob) / Math.log(2));
+ }
+ return entropy;
+ }
}
/**
@@ -683,58 +713,6 @@ static byte[] readFromFile(java.io.File file, int offset, int length) {
private Util() {
}
- /*
- =================================================================================================
- Copyright 2011 Twitter, Inc.
- -------------------------------------------------------------------------------------------------
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this work except in compliance with the License.
- You may obtain a copy of the License in the LICENSE file, or at:
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- =================================================================================================
- */
-
- /**
- * Class that calculates the entropy factor
- *
- * @param
- */
- @SuppressWarnings("WeakerAccess")
- static final class Entropy {
- private final Map map = new HashMap<>();
- private int total = 0;
-
- public Entropy(Iterable elements) {
- for (T element : elements) {
- if (!map.containsKey(element)) {
- map.put(element, 0);
- }
- map.put(element, map.get(element) + 1);
- total++;
- }
- }
-
- private double Log2(double n) {
- return Math.log(n) / Math.log(2);
- }
-
- public double entropy() {
- double entropy = 0;
- for (int count : map.values()) {
- double prob = (double) count / total;
- entropy -= prob * Log2(prob);
- }
- return entropy;
- }
- }
-
/**
* A simple iterator for the bytes class, which does not support remove
*/
diff --git a/src/test/java/at/favre/lib/bytes/UtilByteTest.java b/src/test/java/at/favre/lib/bytes/UtilByteTest.java
index 3892269..26180ea 100644
--- a/src/test/java/at/favre/lib/bytes/UtilByteTest.java
+++ b/src/test/java/at/favre/lib/bytes/UtilByteTest.java
@@ -234,4 +234,15 @@ public void testRightShiftAgainstRefImpl() {
}
}
}
+
+ @Test
+ public void entropy() {
+ assertEquals(0, Util.Byte.entropy(new byte[0]), 0.1d);
+ assertEquals(0, Util.Byte.entropy(new byte[1]), 0.1d);
+ assertEquals(0, Util.Byte.entropy(new byte[256]), 0.1d);
+ assertEquals(0, Util.Byte.entropy(new byte[]{1}), 0.1d);
+ assertTrue(Util.Byte.entropy(new byte[]{(byte) 0x8E, (byte) 0xD1, (byte) 0xFD, (byte) 0xAA, 0x12, (byte) 0xAF, (byte) 0x78, 0x09, 0x1E, (byte) 0xD1, (byte) 0xFD, (byte) 0xAA, 0x12, (byte) 0xAF, (byte) 0x00, 0x0A, (byte) 0xEE, (byte) 0xD1, (byte) 0xFD, (byte) 0xAA, 0x12, (byte) 0xAF, (byte) 0x78, 0x11}) > 3.5);
+ assertTrue(Util.Byte.entropy(new byte[]{0x4A, (byte) 0x94, (byte) 0xFD, (byte) 0xFF, 0x1E, (byte) 0xAF, (byte) 0xED}) > 2.5);
+ assertTrue(Util.Byte.entropy(new byte[]{0x1A, 0x6F}) > 0.5);
+ }
}
From d85b422d565337e78fbbd717dc63ec4d24129569 Mon Sep 17 00:00:00 2001
From: pfavre
Date: Tue, 8 Jan 2019 09:45:59 +0100
Subject: [PATCH 020/118] Improve toArray() util to not use intermittent array
(ie. less memory complexity)
---
src/main/java/at/favre/lib/bytes/Util.java | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/src/main/java/at/favre/lib/bytes/Util.java b/src/main/java/at/favre/lib/bytes/Util.java
index b4b1ba8..71e2adb 100644
--- a/src/main/java/at/favre/lib/bytes/Util.java
+++ b/src/main/java/at/favre/lib/bytes/Util.java
@@ -322,11 +322,12 @@ private Converter() {
* is null
*/
static byte[] toArray(Collection collection) {
- Object[] boxedArray = collection.toArray();
- int len = boxedArray.length;
- byte[] array = new byte[len];
- for (int i = 0; i < len; i++) {
- array[i] = (java.lang.Byte) boxedArray[i];
+ final int len = collection.size();
+ final byte[] array = new byte[len];
+ int i = 0;
+ for (java.lang.Byte b : collection) {
+ array[i] = b;
+ i++;
}
return array;
}
From 9d29f7b17b3eebf214e836e46de721c9e8fade30 Mon Sep 17 00:00:00 2001
From: pfavre
Date: Tue, 8 Jan 2019 09:46:22 +0100
Subject: [PATCH 021/118] Moving around some methods in Util.java
---
src/main/java/at/favre/lib/bytes/Util.java | 61 +++++++++++-----------
1 file changed, 31 insertions(+), 30 deletions(-)
diff --git a/src/main/java/at/favre/lib/bytes/Util.java b/src/main/java/at/favre/lib/bytes/Util.java
index 71e2adb..9ce1a1a 100644
--- a/src/main/java/at/favre/lib/bytes/Util.java
+++ b/src/main/java/at/favre/lib/bytes/Util.java
@@ -63,6 +63,22 @@ static byte[] concat(byte[]... arrays) {
return result;
}
+
+ /**
+ * Combines a single argument with a vararg to a single array
+ *
+ * @param firstByte first arg
+ * @param moreBytes varargs
+ * @return array containing all args
+ */
+ static byte[] concatVararg(byte firstByte, byte[] moreBytes) {
+ if (moreBytes == null) {
+ return new byte[]{firstByte};
+ } else {
+ return concat(new byte[]{firstByte}, moreBytes);
+ }
+ }
+
/**
* Returns the start position of the first occurrence of the specified {@code
* target} within {@code array}, or {@code -1} if there is no such occurrence.
@@ -189,21 +205,6 @@ static void reverse(byte[] array, int fromIndex, int toIndex) {
}
}
- /**
- * Combines a single argument with a vararg to a single array
- *
- * @param firstByte first arg
- * @param moreBytes varargs
- * @return array containing all args
- */
- static byte[] concatVararg(byte firstByte, byte[] moreBytes) {
- if (moreBytes == null) {
- return new byte[]{firstByte};
- } else {
- return concat(new byte[]{firstByte}, moreBytes);
- }
- }
-
/**
* Light shift of whole byte array by shiftBitCount bits.
* This method will alter the input byte array.
@@ -332,21 +333,6 @@ static byte[] toArray(Collection collection) {
return array;
}
- /**
- * Converts given array to list of boxed bytes. Will create a new list
- * and not reuse the array reference.
- *
- * @param array to convert
- * @return list with same length and content as array
- */
- static List toList(byte[] array) {
- List list = new ArrayList<>(array.length);
- for (byte b : array) {
- list.add(b);
- }
- return list;
- }
-
/**
* Converts this primitive array to an boxed object array.
* Will create a new array and not reuse the array reference.
@@ -362,6 +348,21 @@ static java.lang.Byte[] toBoxedArray(byte[] array) {
return objectArray;
}
+ /**
+ * Converts given array to list of boxed bytes. Will create a new list
+ * and not reuse the array reference.
+ *
+ * @param array to convert
+ * @return list with same length and content as array
+ */
+ static List toList(byte[] array) {
+ List list = new ArrayList<>(array.length);
+ for (byte b : array) {
+ list.add(b);
+ }
+ return list;
+ }
+
/**
* Converts this object array to an primitives type array.
* Will create a new array and not reuse the array reference.
From 84382aeab3fa4ab7b802f388ae213847bafd476a Mon Sep 17 00:00:00 2001
From: pfavre
Date: Wed, 9 Jan 2019 22:46:04 +0100
Subject: [PATCH 022/118] Improve javadoc in Util.Bytes with time & space
complexity analysis
---
src/main/java/at/favre/lib/bytes/Util.java | 128 ++++++++++++++++++++-
1 file changed, 124 insertions(+), 4 deletions(-)
diff --git a/src/main/java/at/favre/lib/bytes/Util.java b/src/main/java/at/favre/lib/bytes/Util.java
index 9ce1a1a..a5fb716 100644
--- a/src/main/java/at/favre/lib/bytes/Util.java
+++ b/src/main/java/at/favre/lib/bytes/Util.java
@@ -45,6 +45,15 @@ private Byte() {
* For example, {@code append(new byte[] {a, b}, new byte[] {}, new
* byte[] {c}} returns the byteArray {@code {a, b, c}}.
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(n)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param arrays zero or more {@code byte} arrays
* @return a single byteArray containing all the values from the source arrays, in
* order
@@ -67,6 +76,15 @@ static byte[] concat(byte[]... arrays) {
/**
* Combines a single argument with a vararg to a single array
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(n)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param firstByte first arg
* @param moreBytes varargs
* @return array containing all args
@@ -87,6 +105,15 @@ static byte[] concatVararg(byte firstByte, byte[] moreBytes) {
* java.util.Arrays.copyOfRange(array, i, i + target.length)} contains exactly
* the same elements as {@code target}.
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n*m)
+ *
Space Complexity: O(1)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param array the array to search for the sequence {@code target}
* @param target the array to search for as a sub-sequence of {@code array}
*/
@@ -113,6 +140,15 @@ static int indexOf(byte[] array, byte[] target, int start, int end) {
* Returns the index of the last appearance of the value {@code target} in
* {@code array}.
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(1)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param array an array of {@code byte} values, possibly empty
* @param target a primitive {@code byte} value
* @return the greatest index {@code i} for which {@code array[i] == target},
@@ -130,6 +166,15 @@ static int lastIndexOf(byte[] array, byte target, int start, int end) {
/**
* Counts the occurrence of target in the the in the subject array
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(1)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param array to count in
* @param target to count
* @return number of times target is in subject
@@ -147,6 +192,15 @@ static int countByte(byte[] array, byte target) {
/**
* Counts the times given pattern (ie. an array) can be found in given array
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n*m)
+ *
Space Complexity: O(1)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param array to count in
* @param pattern to match in array
* @return number of times pattern is in subject
@@ -175,6 +229,15 @@ static int countByteArray(byte[] array, byte[] pattern) {
*
+ *
* @param array to shuffle
* @param random used to derive entropy - use {@link java.security.SecureRandom} instance if you want this to be secure
*/
@@ -193,6 +256,15 @@ static void shuffle(byte[] array, Random random) {
* Collections.reverse(Bytes.asList(array).subList(fromIndex, toIndex))}, but is likely to be more
* efficient.
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(1)
+ *
Alters Parameters: true
+ *
+ *
+ *
* @throws IndexOutOfBoundsException if {@code fromIndex < 0}, {@code toIndex > array.length}, or
* {@code toIndex > fromIndex}
*/
@@ -208,6 +280,19 @@ static void reverse(byte[] array, int fromIndex, int toIndex) {
/**
* Light shift of whole byte array by shiftBitCount bits.
* This method will alter the input byte array.
+ *
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(1)
+ *
Alters Parameters: true
+ *
+ *
+ *
+ * @param byteArray to shift
+ * @param shiftBitCount how many bits to shift
+ * @return shifted byte array
*/
static byte[] shiftLeft(byte[] byteArray, int shiftBitCount) {
final int shiftMod = shiftBitCount % 8;
@@ -234,6 +319,19 @@ static byte[] shiftLeft(byte[] byteArray, int shiftBitCount) {
/**
* Unsigned/logical right shift of whole byte array by shiftBitCount bits.
* This method will alter the input byte array.
+ *
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(1)
+ *
Alters Parameters: true
+ *
+ *
+ *
+ * @param byteArray to shift
+ * @param shiftBitCount how many bits to shift
+ * @return shifted byte array
*/
static byte[] shiftRight(byte[] byteArray, int shiftBitCount) {
final int shiftMod = shiftBitCount % 8;
@@ -259,13 +357,26 @@ static byte[] shiftRight(byte[] byteArray, int shiftBitCount) {
/**
* See https://codahale.com/a-lesson-in-timing-attacks/
+ *
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(1)
+ *
Alters Parameters: false
+ *
+ *
+ *
+ * @param array to check for equals
+ * @param anotherArray to check against array
+ * @return if both arrays have the same length and same length for every index
*/
- static boolean constantTimeEquals(byte[] obj, byte[] anotherArray) {
- if (anotherArray == null || obj.length != anotherArray.length) return false;
+ static boolean constantTimeEquals(byte[] array, byte[] anotherArray) {
+ if (anotherArray == null || array.length != anotherArray.length) return false;
int result = 0;
- for (int i = 0; i < obj.length; i++) {
- result |= obj[i] ^ anotherArray[i];
+ for (int i = 0; i < array.length; i++) {
+ result |= array[i] ^ anotherArray[i];
}
return result == 0;
}
@@ -276,6 +387,15 @@ static boolean constantTimeEquals(byte[] obj, byte[] anotherArray) {
* This implementation will not create a copy of the internal array and will only internally initialize
* a int array with 256 elements as temporary buffer.
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(1)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param array to calculate the entropy from
* @return entropy factor, higher means higher entropy
*/
From 201457e4de9fdec6d18c07243d96ddbbb726fcf1 Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Sat, 12 Jan 2019 13:18:41 +0100
Subject: [PATCH 023/118] Add more javadoc and analysis and some minor
refactoring
---
src/main/java/at/favre/lib/bytes/Util.java | 194 ++++++++++++++++--
.../bytes/BytesToConvertOtherTypesTest.java | 28 +--
2 files changed, 195 insertions(+), 27 deletions(-)
diff --git a/src/main/java/at/favre/lib/bytes/Util.java b/src/main/java/at/favre/lib/bytes/Util.java
index a5fb716..70d35e0 100644
--- a/src/main/java/at/favre/lib/bytes/Util.java
+++ b/src/main/java/at/favre/lib/bytes/Util.java
@@ -436,6 +436,15 @@ private Converter() {
* collection.toArray()}. Calling this method is as thread-safe as calling
* that method.
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(n)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param collection a collection of {@code Byte} objects
* @return an array containing the same values as {@code collection}, in the
* same order, converted to primitives
@@ -457,6 +466,15 @@ static byte[] toArray(Collection collection) {
* Converts this primitive array to an boxed object array.
* Will create a new array and not reuse the array reference.
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(n)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param array to convert
* @return new array
*/
@@ -472,6 +490,15 @@ static java.lang.Byte[] toBoxedArray(byte[] array) {
* Converts given array to list of boxed bytes. Will create a new list
* and not reuse the array reference.
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(n)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param array to convert
* @return list with same length and content as array
*/
@@ -487,6 +514,15 @@ static List toList(byte[] array) {
* Converts this object array to an primitives type array.
* Will create a new array and not reuse the array reference.
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(n)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param objectArray to convert
* @return new array
*/
@@ -502,13 +538,24 @@ static byte[] toPrimitiveArray(java.lang.Byte[] objectArray) {
* Creates a byte array from given int array.
* The resulting byte array will have length intArray * 4.
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(n)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param intArray to convert
* @return resulting byte array
*/
static byte[] toByteArray(int[] intArray) {
byte[] primitivesArray = new byte[intArray.length * 4];
+ ByteBuffer buffer = ByteBuffer.allocate(4);
for (int i = 0; i < intArray.length; i++) {
- byte[] intBytes = ByteBuffer.allocate(4).putInt(intArray[i]).array();
+ buffer.clear();
+ byte[] intBytes = buffer.putInt(intArray[i]).array();
System.arraycopy(intBytes, 0, primitivesArray, (i * 4), intBytes.length);
}
return primitivesArray;
@@ -518,13 +565,24 @@ static byte[] toByteArray(int[] intArray) {
* Creates a byte array from given long array.
* The resulting byte array will have length longArray * 8
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(n)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param longArray to convert
* @return resulting byte array
*/
static byte[] toByteArray(long[] longArray) {
byte[] primitivesArray = new byte[longArray.length * 8];
+ ByteBuffer buffer = ByteBuffer.allocate(8);
for (int i = 0; i < longArray.length; i++) {
- byte[] longBytes = ByteBuffer.allocate(8).putLong(longArray[i]).array();
+ buffer.clear();
+ byte[] longBytes = buffer.putLong(longArray[i]).array();
System.arraycopy(longBytes, 0, primitivesArray, (i * 8), longBytes.length);
}
return primitivesArray;
@@ -533,6 +591,15 @@ static byte[] toByteArray(long[] longArray) {
/**
* Converts a char array to a byte array with given charset and range
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(n)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param charArray to get the byte array from
* @param charset charset to be used to decode the char array
* @param offset to start reading the char array from (must be smaller than length and gt 0)
@@ -567,6 +634,15 @@ static byte[] charToByteArray(char[] charArray, Charset charset, int offset, int
/**
* Convert given byte array in given encoding to char array
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(n)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param bytes as data source
* @param charset of the byte array
* @param byteOrder the order of the bytes array
@@ -596,6 +672,15 @@ static char[] byteToCharArray(byte[] bytes, Charset charset, ByteOrder byteOrder
* [b1, b2, b3, b4] = [int1]
*
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(n)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param bytes to convert to int array, must be % 4 == 0 to work correctly
* @param byteOrder of the byte array
* @return int array
@@ -614,6 +699,15 @@ static int[] toIntArray(byte[] bytes, ByteOrder byteOrder) {
* [b1, b2, b3, b4, b5, b6, b7, b8] = [long1]
*
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(n)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param bytes to convert to long array, must be % 8 == 0 to work correctly
* @param byteOrder of the byte array
* @return long array
@@ -629,6 +723,15 @@ static long[] toLongArray(byte[] bytes, ByteOrder byteOrder) {
* Convert UUID to a newly generated 16 byte long array representation. Puts the 8 byte most significant bits and
* 8 byte least significant bits into an byte array.
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(1)
+ *
Space Complexity: O(1)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param uuid to convert to array
* @return buffer containing the 16 bytes
*/
@@ -647,6 +750,25 @@ static final class Obj {
private Obj() {
}
+ /**
+ * Equals method comparing 2 byte arrays.
+ * This utilizes a quick return of the array differs on any given property so not suitable
+ * for security relevant checks. See {@link Util.Byte#constantTimeEquals(byte[], byte[])}
+ * for that.
+ *
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(1)
+ *
Alters Parameters: false
+ *
+ *
+ *
+ * @param obj subject a
+ * @param anotherArray subject b to compare to a
+ * @return if a.len == b.len and for every 0..len a[i] == b[i]
+ */
static boolean equals(byte[] obj, java.lang.Byte[] anotherArray) {
if (anotherArray == null) return false;
if (obj.length != anotherArray.length) return false;
@@ -661,6 +783,15 @@ static boolean equals(byte[] obj, java.lang.Byte[] anotherArray) {
/**
* Hashcode implementation for a byte array and given byte order
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(1)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param byteArray to calculate hashCode of
* @param byteOrder to calculate hashCode of
* @return hashCode
@@ -674,6 +805,15 @@ static int hashCode(byte[] byteArray, ByteOrder byteOrder) {
/**
* Shows the length and a preview of max 8 bytes of the given byte
*
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(1)
+ *
Space Complexity: O(1)
+ *
Alters Parameters: false
+ *
+ *
+ *
* @param bytes to convert to string
* @return string representation
*/
@@ -698,38 +838,66 @@ static final class Validation {
private Validation() {
}
- private static void checkFile(java.io.File file) {
- if (file == null || !file.exists() || !file.isFile()) {
- throw new IllegalArgumentException("file must not be null, has to exist and must be a file (not a directory) " + file);
- }
- }
-
+ /**
+ * Check if a length of an primitive (e.g. int = 4 byte) fits in given length from given start index.
+ * Throws exception with descriptive exception message.
+ *
+ * @param length of the whole array
+ * @param index to start from array length
+ * @param primitiveLength length of the primitive type to check
+ * @param type for easier debugging the human readable type of the checked primitive
+ * to put in exception message
+ * @throws IndexOutOfBoundsException if index + primitiveLength > length
+ */
static void checkIndexBounds(int length, int index, int primitiveLength, String type) {
if (index < 0 || index + primitiveLength > length) {
throw new IndexOutOfBoundsException("cannot get " + type + " from index out of bounds: " + index);
}
}
+ /**
+ * Check if given length is an expected length.
+ * Throws exception with descriptive exception message.
+ *
+ * @param length of the whole array
+ * @param expectedLength how length is expected
+ * @param type for easier debugging the human readable type of the checked primitive
+ * to put in exception message
+ * @throws IllegalArgumentException if length != expectedLength
+ */
static void checkExactLength(int length, int expectedLength, String type) {
if (length != expectedLength) {
- throw new IllegalStateException("cannot convert to " + type + " if length != " + expectedLength + " bytes (was " + length + ")");
+ throw new IllegalArgumentException("cannot convert to " + type + " if length != " + expectedLength + " bytes (was " + length + ")");
}
}
/**
- * Checks if given length is divisable by mod factor (with zero rest).
- * This can be used to check of a byte array can be convertet to an e.g. int array which is
+ * Checks if given length is divisible by mod factor (with zero rest).
+ * This can be used to check of a byte array can be converted to an e.g. int array which is
* multiples of 4.
*
* @param length of the byte array
* @param modFactor to divide the length
* @param errorSubject human readable message of the exact error subject
+ * @throws IllegalArgumentException if length % modFactor != 0
*/
static void checkModLength(int length, int modFactor, String errorSubject) {
if (length % modFactor != 0) {
throw new IllegalArgumentException("Illegal length for " + errorSubject + ". Byte array length must be multiple of " + modFactor + ", length was " + length);
}
}
+
+ /**
+ * Check if the file exists and is a file.
+ *
+ * @param file to check
+ * @throws IllegalArgumentException if either file is null, does not exists or is not a file
+ */
+ private static void checkFileExists(java.io.File file) {
+ if (file == null || !file.exists() || !file.isFile()) {
+ throw new IllegalArgumentException("file must not be null, has to exist and must be a file (not a directory) " + file);
+ }
+ }
}
/**
@@ -803,7 +971,7 @@ static byte[] readFromDataInput(DataInput dataInput, int length) {
* @return byte content
*/
static byte[] readFromFile(java.io.File file) {
- Validation.checkFile(file);
+ Validation.checkFileExists(file);
try {
return Files.readAllBytes(file.toPath());
@@ -821,7 +989,7 @@ static byte[] readFromFile(java.io.File file) {
* @return byte array with length length
*/
static byte[] readFromFile(java.io.File file, int offset, int length) {
- Validation.checkFile(file);
+ Validation.checkFileExists(file);
try (RandomAccessFile raf = new RandomAccessFile(file, "r")) {
raf.seek(offset);
return readFromDataInput(raf, length);
diff --git a/src/test/java/at/favre/lib/bytes/BytesToConvertOtherTypesTest.java b/src/test/java/at/favre/lib/bytes/BytesToConvertOtherTypesTest.java
index dee19d1..9b7fdea 100644
--- a/src/test/java/at/favre/lib/bytes/BytesToConvertOtherTypesTest.java
+++ b/src/test/java/at/favre/lib/bytes/BytesToConvertOtherTypesTest.java
@@ -86,7 +86,7 @@ public void toByte() {
try {
Bytes.from(example_bytes_two).toByte();
fail();
- } catch (IllegalStateException ignored) {
+ } catch (IllegalArgumentException ignored) {
}
}
@@ -99,7 +99,7 @@ public void toUnsignedByte() {
try {
Bytes.from(example_bytes_two).toUnsignedByte();
fail();
- } catch (IllegalStateException ignored) {
+ } catch (IllegalArgumentException ignored) {
}
}
@@ -112,12 +112,12 @@ public void toChar() {
try {
Bytes.from(new byte[3]).toChar();
fail();
- } catch (IllegalStateException ignored) {
+ } catch (IllegalArgumentException ignored) {
}
try {
Bytes.from(new byte[1]).toChar();
fail();
- } catch (IllegalStateException ignored) {
+ } catch (IllegalArgumentException ignored) {
}
}
@@ -130,12 +130,12 @@ public void toShort() {
try {
Bytes.from(new byte[3]).toShort();
fail();
- } catch (IllegalStateException ignored) {
+ } catch (IllegalArgumentException ignored) {
}
try {
Bytes.from(new byte[1]).toShort();
fail();
- } catch (IllegalStateException ignored) {
+ } catch (IllegalArgumentException ignored) {
}
}
@@ -153,12 +153,12 @@ public void toInt() {
try {
Bytes.from(new byte[5]).toInt();
fail();
- } catch (IllegalStateException ignored) {
+ } catch (IllegalArgumentException ignored) {
}
try {
Bytes.from(new byte[3]).toInt();
fail();
- } catch (IllegalStateException ignored) {
+ } catch (IllegalArgumentException ignored) {
}
}
@@ -173,12 +173,12 @@ public void toLong() {
try {
Bytes.from(new byte[9]).toLong();
fail();
- } catch (IllegalStateException ignored) {
+ } catch (IllegalArgumentException ignored) {
}
try {
Bytes.from(new byte[7]).toLong();
fail();
- } catch (IllegalStateException ignored) {
+ } catch (IllegalArgumentException ignored) {
}
}
@@ -193,12 +193,12 @@ public void toFloat() {
try {
Bytes.from(new byte[5]).toFloat();
fail();
- } catch (IllegalStateException ignored) {
+ } catch (IllegalArgumentException ignored) {
}
try {
Bytes.from(new byte[3]).toFloat();
fail();
- } catch (IllegalStateException ignored) {
+ } catch (IllegalArgumentException ignored) {
}
}
@@ -213,12 +213,12 @@ public void toDouble() {
try {
Bytes.from(new byte[9]).toDouble();
fail();
- } catch (IllegalStateException ignored) {
+ } catch (IllegalArgumentException ignored) {
}
try {
Bytes.from(new byte[7]).toDouble();
fail();
- } catch (IllegalStateException ignored) {
+ } catch (IllegalArgumentException ignored) {
}
}
From 1e3397608e974ab9f41250e4ea9992bfe779591b Mon Sep 17 00:00:00 2001
From: pfavre
Date: Sat, 12 Jan 2019 13:45:58 +0100
Subject: [PATCH 024/118] Fixes various issues found in static code inspection
E.g typos, weaker access, redundant "throws exception"
---
CONTRIBUTING.md | 4 +--
README.md | 2 +-
src/main/java/at/favre/lib/bytes/Bytes.java | 2 +-
.../at/favre/lib/bytes/BytesTransformers.java | 5 ++--
.../at/favre/lib/bytes/BytesValidators.java | 1 +
.../java/at/favre/lib/bytes/ABytesTest.java | 4 +--
.../favre/lib/bytes/BytesByteOrderTest.java | 28 +++++++++----------
.../lib/bytes/BytesConstructorTests.java | 8 ++----
.../at/favre/lib/bytes/BytesMiscTest.java | 6 ++--
.../favre/lib/bytes/BytesValidatorTest.java | 22 +++++++--------
.../otherPackage/BytesTransformTest.java | 4 +--
11 files changed, 42 insertions(+), 44 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c028985..c18fe1f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -2,7 +2,7 @@
We ❤ pull requests from everyone.
-If possible proof features and bugfixes with unit tests.
+If possible proof features and bug fixes with unit tests.
This repo validates against checkstyle (import the xml found in the root to your IDE if possible)
To run the tests (and checkstyle):
@@ -12,4 +12,4 @@ mvn test checkstyle:check
```
Tests are automatically run against branches and pull requests
-via TravisCI, so you can also depend on that.
\ No newline at end of file
+via TravisCI, so you can also depend on that.
diff --git a/README.md b/README.md
index b7a7f6a..f5172f4 100644
--- a/README.md
+++ b/README.md
@@ -54,7 +54,7 @@ Add dependency to your `pom.xml` ([check latest release](https://github.com/patr
{latest-version}
-_Note:_ There is a byte-code optimized version (powerd by [ProGuard](https://www.guardsquare.com/en/products/proguard)) which can be used with [classifier](https://maven.apache.org/pom.html#Maven_Coordinates) 'optimized'. This may have issues so use at your own risk.
+_Note:_ There is a byte-code optimized version (powered by [ProGuard](https://www.guardsquare.com/en/products/proguard)) which can be used with [classifier](https://maven.apache.org/pom.html#Maven_Coordinates) 'optimized'. This may have issues so use at your own risk.
Some simple examples:
diff --git a/src/main/java/at/favre/lib/bytes/Bytes.java b/src/main/java/at/favre/lib/bytes/Bytes.java
index 6710c10..03f77dd 100644
--- a/src/main/java/at/favre/lib/bytes/Bytes.java
+++ b/src/main/java/at/favre/lib/bytes/Bytes.java
@@ -1081,7 +1081,7 @@ public Bytes hash(String algorithm) {
* This transformation might be done in-place (ie. without copying the internal array and overwriting its old state),
* or on a copy of the internal data, depending on the type (e.g. {@link MutableBytes}) and if the operation can be done
* in-place. Therefore the caller has to ensure that certain side-effects, which occur due to the changing of the internal
- * data, do not create bugs in his/her code. Usually immutability is prefered, but when handling many or big byte arrays,
+ * data, do not create bugs in his/her code. Usually immutability is preferred, but when handling many or big byte arrays,
* mutability enables drastically better performance.
*
* @param transformer used to transform this instance
diff --git a/src/main/java/at/favre/lib/bytes/BytesTransformers.java b/src/main/java/at/favre/lib/bytes/BytesTransformers.java
index 64a6ae9..f2ae0c7 100644
--- a/src/main/java/at/favre/lib/bytes/BytesTransformers.java
+++ b/src/main/java/at/favre/lib/bytes/BytesTransformers.java
@@ -18,6 +18,7 @@
/**
* Collection of additional {@link BytesTransformer} for more specific use cases
*/
+@SuppressWarnings("WeakerAccess")
public final class BytesTransformers {
private BytesTransformers() {
@@ -222,7 +223,7 @@ public boolean supportInPlaceTransformation() {
}
/**
- * Converting each byte into unsinged version and comparing it (0...255) vs (-128..127)
+ * Converting each byte into unsigned version and comparing it (0...255) vs (-128..127)
*/
static final class UnsignedByteComparator implements Comparator {
@Override
@@ -246,7 +247,7 @@ public static final class ChecksumTransformer implements BytesTransformer {
ChecksumTransformer(Checksum checksum, Mode mode, int checksumLengthByte) {
if (checksumLengthByte <= 0 || checksumLengthByte > 8)
- throw new IllegalArgumentException("checksumlength must be between 1 and 8 bytes");
+ throw new IllegalArgumentException("checksum length must be between 1 and 8 bytes");
Objects.requireNonNull(checksum, "checksum instance must not be null");
this.checksum = checksum;
diff --git a/src/main/java/at/favre/lib/bytes/BytesValidators.java b/src/main/java/at/favre/lib/bytes/BytesValidators.java
index 479dd18..067822c 100644
--- a/src/main/java/at/favre/lib/bytes/BytesValidators.java
+++ b/src/main/java/at/favre/lib/bytes/BytesValidators.java
@@ -27,6 +27,7 @@
/**
* Util and easy access for {@link BytesValidators}
*/
+@SuppressWarnings("WeakerAccess")
public final class BytesValidators {
private BytesValidators() {
diff --git a/src/test/java/at/favre/lib/bytes/ABytesTest.java b/src/test/java/at/favre/lib/bytes/ABytesTest.java
index e117913..076de64 100644
--- a/src/test/java/at/favre/lib/bytes/ABytesTest.java
+++ b/src/test/java/at/favre/lib/bytes/ABytesTest.java
@@ -27,7 +27,7 @@
import static org.junit.Assert.*;
-public abstract class ABytesTest {
+abstract class ABytesTest {
byte[] example_bytes_empty;
byte[] example_bytes_one;
@@ -55,7 +55,7 @@ public abstract class ABytesTest {
String example_hex_twentyfour;
@Before
- public void setUp() throws Exception {
+ public void setUp() {
example_bytes_empty = new byte[0];
example_bytes_one = new byte[]{0x67};
example_hex_one = "67";
diff --git a/src/test/java/at/favre/lib/bytes/BytesByteOrderTest.java b/src/test/java/at/favre/lib/bytes/BytesByteOrderTest.java
index 663a1a3..71d137f 100644
--- a/src/test/java/at/favre/lib/bytes/BytesByteOrderTest.java
+++ b/src/test/java/at/favre/lib/bytes/BytesByteOrderTest.java
@@ -31,7 +31,7 @@
public class BytesByteOrderTest extends ABytesTest {
@Test
- public void miscInput() throws Exception {
+ public void miscInput() {
testOrder(Bytes.from(350));
testOrder(Bytes.from(172863182736L));
testOrder(Bytes.from(example_bytes_one));
@@ -52,82 +52,82 @@ private void testOrder(Bytes bytes) {
}
@Test
- public void encodeBinary() throws Exception {
+ public void encodeBinary() {
Bytes b = Bytes.from(example_bytes_four);
assertNotEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).encodeBinary(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).encodeBinary());
assertEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).encodeBinary(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).reverse().encodeBinary());
}
@Test
- public void encodeOct() throws Exception {
+ public void encodeOct() {
Bytes b = Bytes.from(example_bytes_four);
assertNotEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).encodeOctal(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).encodeOctal());
assertEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).encodeOctal(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).reverse().encodeOctal());
}
@Test
- public void encodeDec() throws Exception {
+ public void encodeDec() {
Bytes b = Bytes.from(example_bytes_four);
assertNotEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).encodeDec(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).encodeDec());
assertEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).encodeDec(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).reverse().encodeDec());
}
@Test
- public void encodeHex() throws Exception {
+ public void encodeHex() {
Bytes b = Bytes.from(example_bytes_two);
assertNotEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).encodeHex(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).encodeHex());
assertEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).encodeHex(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).reverse().encodeHex());
}
@Test
- public void encodeBase36() throws Exception {
+ public void encodeBase36() {
Bytes b = Bytes.from(example_bytes_four);
assertNotEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).encodeBase36(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).encodeBase36());
assertEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).encodeBase36(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).reverse().encodeBase36());
}
@Test
- public void encodeBase64() throws Exception {
+ public void encodeBase64() {
Bytes b = Bytes.from(example_bytes_four);
assertNotEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).encodeBase64(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).encodeBase64());
assertEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).encodeBase64(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).reverse().encodeBase64());
}
@Test
- public void toByte() throws Exception {
+ public void toByte() {
Bytes b = Bytes.from(example_bytes_one);
assertEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).toByte(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).toByte());
}
@Test
- public void toChar() throws Exception {
+ public void toChar() {
Bytes b = Bytes.from(example_bytes_two);
assertNotEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).toChar(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).toChar());
}
@Test
- public void toShort() throws Exception {
+ public void toShort() {
Bytes b = Bytes.from(example_bytes_two);
assertNotEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).toShort(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).toShort());
}
@Test
- public void toInt() throws Exception {
+ public void toInt() {
Bytes b = Bytes.from(example_bytes_four);
assertNotEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).toInt(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).toInt());
}
@Test
- public void toLong() throws Exception {
+ public void toLong() {
Bytes b = Bytes.from(example_bytes_eight);
assertNotEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).toLong(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).toLong());
}
@Test
- public void bigInteger() throws Exception {
+ public void bigInteger() {
Bytes b = Bytes.from(example_bytes_four);
assertNotEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).toBigInteger(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).toBigInteger());
assertEquals(b.byteOrder(ByteOrder.BIG_ENDIAN).toBigInteger(), b.byteOrder(ByteOrder.LITTLE_ENDIAN).reverse().toBigInteger());
}
-}
\ No newline at end of file
+}
diff --git a/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java b/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java
index 1775301..d08d46f 100644
--- a/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java
+++ b/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java
@@ -26,11 +26,7 @@
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-import java.io.ByteArrayInputStream;
-import java.io.DataInput;
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.FileOutputStream;
+import java.io.*;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -48,7 +44,7 @@
public class BytesConstructorTests extends ABytesTest {
@Rule
- public TemporaryFolder testFolder = new TemporaryFolder();
+ public final TemporaryFolder testFolder = new TemporaryFolder();
@Test
public void wrapTest() {
diff --git a/src/test/java/at/favre/lib/bytes/BytesMiscTest.java b/src/test/java/at/favre/lib/bytes/BytesMiscTest.java
index 844e36c..068a2ec 100644
--- a/src/test/java/at/favre/lib/bytes/BytesMiscTest.java
+++ b/src/test/java/at/favre/lib/bytes/BytesMiscTest.java
@@ -121,14 +121,14 @@ public void testCompareTo() {
assertTrue(-1 >= Bytes.from(b1).compareTo(Bytes.from(b2)));
assertTrue(1 <= Bytes.from(b2).compareTo(Bytes.from(b1)));
- assertTrue(0 == Bytes.from(b1).compareTo(Bytes.from(b1)));
+ assertEquals(0, Bytes.from(b1).compareTo(Bytes.from(b1)));
byte[] bOne = new byte[]{0x01};
byte[] bTwo = new byte[]{0x02};
assertTrue(-1 >= Bytes.from(bOne).compareTo(Bytes.from(bTwo)));
assertTrue(1 <= Bytes.from(bTwo).compareTo(Bytes.from(bOne)));
- assertTrue(0 == Bytes.from(bOne).compareTo(Bytes.from(bOne)));
+ assertEquals(0, Bytes.from(bOne).compareTo(Bytes.from(bOne)));
}
@Test
@@ -507,7 +507,7 @@ public void readOnly() {
try {
Bytes.from(example_bytes_twentyfour).readOnly().array();
fail();
- } catch (ReadOnlyBufferException e) {
+ } catch (ReadOnlyBufferException ignored) {
}
Bytes b = Bytes.from(example_bytes_twentyfour).readOnly();
diff --git a/src/test/java/at/favre/lib/bytes/BytesValidatorTest.java b/src/test/java/at/favre/lib/bytes/BytesValidatorTest.java
index d7174fa..3baf603 100644
--- a/src/test/java/at/favre/lib/bytes/BytesValidatorTest.java
+++ b/src/test/java/at/favre/lib/bytes/BytesValidatorTest.java
@@ -32,7 +32,7 @@
public class BytesValidatorTest extends ABytesTest {
@Test
- public void testOnlyOfValidator() throws Exception {
+ public void testOnlyOfValidator() {
assertFalse(Bytes.allocate(0).validateNotOnlyZeros());
assertFalse(Bytes.allocate(2).validateNotOnlyZeros());
assertTrue(Bytes.wrap(example_bytes_seven).validateNotOnlyZeros());
@@ -50,7 +50,7 @@ public void testOnlyOfValidator() throws Exception {
}
@Test
- public void testLengthValidators() throws Exception {
+ public void testLengthValidators() {
assertFalse(Bytes.allocate(0).validate(atLeast(1)));
assertTrue(Bytes.allocate(1).validate(atLeast(1)));
assertTrue(Bytes.allocate(2).validate(atLeast(1)));
@@ -65,7 +65,7 @@ public void testLengthValidators() throws Exception {
}
@Test
- public void testOrValidation() throws Exception {
+ public void testOrValidation() {
assertTrue(Bytes.allocate(0).validate(or(exactLength(1), exactLength(0))));
assertTrue(Bytes.allocate(2).validate(or(atLeast(3), onlyOf((byte) 0))));
assertTrue(Bytes.allocate(3).validate(or(onlyOf((byte) 1), onlyOf((byte) 0))));
@@ -74,7 +74,7 @@ public void testOrValidation() throws Exception {
}
@Test
- public void testAndValidation() throws Exception {
+ public void testAndValidation() {
assertFalse(Bytes.allocate(5).validate(and(atLeast(3), notOnlyOf((byte) 0))));
assertFalse(Bytes.wrap(new byte[]{1, 0}).validate(and(atLeast(3), notOnlyOf((byte) 0))));
assertTrue(Bytes.wrap(new byte[]{1, 0, 0}).validate(and(atLeast(3), notOnlyOf((byte) 0))));
@@ -82,26 +82,26 @@ public void testAndValidation() throws Exception {
}
@Test
- public void testNotValidation() throws Exception {
+ public void testNotValidation() {
assertEquals(Bytes.allocate(2).validate(not(onlyOf((byte) 0))), Bytes.allocate(2).validate(notOnlyOf((byte) 0)));
assertTrue(Bytes.allocate(2).validate(not(atLeast(16))));
assertFalse(Bytes.allocate(2).validate(not(atMost(16))));
}
@Test(expected = IllegalArgumentException.class)
- public void testLogicalNoElements() throws Exception {
+ public void testLogicalNoElements() {
Bytes.allocate(2).validate(new BytesValidator.Logical(Collections.emptyList(), BytesValidator.Logical.Operator.AND));
}
@Test(expected = IllegalArgumentException.class)
- public void testLogicalTooManyElements() throws Exception {
+ public void testLogicalTooManyElements() {
Bytes.allocate(2).validate(new BytesValidator.Logical(
Arrays.asList(new BytesValidator.Length(2, BytesValidator.Length.Mode.GREATER_OR_EQ_THAN), new BytesValidator.Length(2, BytesValidator.Length.Mode.EXACT))
, BytesValidator.Logical.Operator.NOT));
}
@Test
- public void testNestedValidation() throws Exception {
+ public void testNestedValidation() {
assertTrue(Bytes.allocate(16).validate(
or(and(atLeast(8), not(onlyOf(((byte) 0)))),
or(exactLength(16), exactLength(12)))));
@@ -113,7 +113,7 @@ public void testNestedValidation() throws Exception {
}
@Test
- public void testStartWithValidate() throws Exception {
+ public void testStartWithValidate() {
assertTrue(Bytes.wrap(new byte[]{0, 3, 0}).validate(startsWith((byte) 0, (byte) 3)));
assertFalse(Bytes.wrap(new byte[]{0, 2, 0}).validate(startsWith((byte) 0, (byte) 3)));
assertTrue(Bytes.wrap(new byte[]{0, 2, 0}).validate(startsWith((byte) 0)));
@@ -123,7 +123,7 @@ public void testStartWithValidate() throws Exception {
}
@Test
- public void testEndsWithValidate() throws Exception {
+ public void testEndsWithValidate() {
assertTrue(Bytes.wrap(new byte[]{1, 2, 3}).validate(endsWith((byte) 2, (byte) 3)));
assertFalse(Bytes.wrap(new byte[]{0, 2, 0}).validate(endsWith((byte) 3, (byte) 0)));
assertTrue(Bytes.wrap(new byte[]{0, 2, 0}).validate(endsWith((byte) 0)));
@@ -131,4 +131,4 @@ public void testEndsWithValidate() throws Exception {
assertTrue(Bytes.allocate(16).validate(endsWith((byte) 0)));
assertFalse(Bytes.allocate(16).validate(endsWith(Bytes.allocate(17).array())));
}
-}
\ No newline at end of file
+}
diff --git a/src/test/java/at/favre/lib/bytes/otherPackage/BytesTransformTest.java b/src/test/java/at/favre/lib/bytes/otherPackage/BytesTransformTest.java
index 619c0a4..8756289 100644
--- a/src/test/java/at/favre/lib/bytes/otherPackage/BytesTransformTest.java
+++ b/src/test/java/at/favre/lib/bytes/otherPackage/BytesTransformTest.java
@@ -31,7 +31,7 @@
public class BytesTransformTest {
@Test
- public void testApiVisible() throws Exception {
+ public void testApiVisible() {
assertFalse(BytesTransformers.checksum(new CRC32(), ChecksumTransformer.Mode.TRANSFORM, 4).supportInPlaceTransformation());
}
-}
\ No newline at end of file
+}
From 2ddeebc2b3bb101362734f96a686f5207961d67b Mon Sep 17 00:00:00 2001
From: pfavre
Date: Sat, 12 Jan 2019 13:59:34 +0100
Subject: [PATCH 025/118] Changes some mentions to immutability
---
README.md | 4 ++--
src/main/java/at/favre/lib/bytes/Bytes.java | 2 +-
src/main/java/at/favre/lib/bytes/ReadOnlyBytes.java | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index f5172f4..ada8126 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
Bytes is a utility library that makes it easy to **create**, **parse**, **transform**,
**validate** and **convert** byte arrays in Java. It's main class `Bytes` is
a collections of bytes and the main API. It supports [endianness](https://en.wikipedia.org/wiki/Endianness)
-as well as **immutable** and **mutable** access, so the caller may decide to favor
+as well as **copy-on-write** and **mutable** access, so the caller may decide to favor
performance. This can be seen as combination of the features provided by
[`BigInteger`](https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html),
[`ByteBuffer`](https://docs.oracle.com/javase/7/docs/api/java/nio/ByteBuffer.html) but
@@ -77,7 +77,7 @@ byte[] result = b.array(); //get as byte array
## API Description
-Per default the instance is **immutable**, which means any transformation will
+Per default the instance is **semi-immutable**, which means any transformation will
create a copy of the internal array (it is, however, possible to get and
modify the internal array). There is a **mutable** version which supports
in-place modification for better performance and a **read-only** version which
diff --git a/src/main/java/at/favre/lib/bytes/Bytes.java b/src/main/java/at/favre/lib/bytes/Bytes.java
index 03f77dd..91a1b0d 100644
--- a/src/main/java/at/favre/lib/bytes/Bytes.java
+++ b/src/main/java/at/favre/lib/bytes/Bytes.java
@@ -1440,7 +1440,7 @@ public Bytes byteOrder(ByteOrder byteOrder) {
/**
* Returns a new read-only byte instance. Read-only means, that there is no direct access to the underlying byte
- * array and all transformers will create a copy (ie. immutable)
+ * array and all transformers will create a copy.
*
* @return a new instance if not already readonly, or "this" otherwise
*/
diff --git a/src/main/java/at/favre/lib/bytes/ReadOnlyBytes.java b/src/main/java/at/favre/lib/bytes/ReadOnlyBytes.java
index 4959c64..5baefee 100644
--- a/src/main/java/at/favre/lib/bytes/ReadOnlyBytes.java
+++ b/src/main/java/at/favre/lib/bytes/ReadOnlyBytes.java
@@ -34,7 +34,7 @@
public final class ReadOnlyBytes extends Bytes {
/**
- * Creates a new immutable instance
+ * Creates a new read-only instance
*
* @param byteArray internal byte array
* @param byteOrder the internal byte order - this is used to interpret given array, not to change it
From d1938016dfd305b5179810f3c9bcad79a396ab4b Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Sat, 12 Jan 2019 20:14:00 +0100
Subject: [PATCH 026/118] Update readme
---
README.md | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index f5172f4..7e45db7 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,10 @@ to blindly paste code snippets from
[l](https://stackoverflow.com/questions/4231674/converting-an-array-of-bytes-to-listbyte)
[o](https://stackoverflow.com/questions/28703273/sorting-byte-arrays-in-numeric-order)
[w](https://stackoverflow.com/questions/4385623/bytes-of-a-string-in-java)
-[.com](https://stackoverflow.com/questions/23360692/byte-position-in-java)
+[.](https://stackoverflow.com/questions/23360692/byte-position-in-java)
+[c](https://stackoverflow.com/questions/11437203/byte-array-to-int-array)
+[o](https://stackoverflow.com/a/9670279/774398)
+[m](https://stackoverflow.com/questions/1519736/random-shuffling-of-an-array)
[](https://bintray.com/patrickfav/maven/bytes-java/_latestVersion)
[](https://travis-ci.org/patrickfav/bytes-java)
From 737044aa895f9bbc35b92804b17e3a9cd2d877e6 Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Sat, 12 Jan 2019 20:38:54 +0100
Subject: [PATCH 027/118] Add `AutoCloseable` to MutableBytes interface
---
CHANGELOG | 1 +
README.md | 12 ++++++++++++
.../java/at/favre/lib/bytes/MutableBytes.java | 7 ++++++-
.../at/favre/lib/bytes/MutableBytesTest.java | 16 ++++++++++++++++
4 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 767f922..03267a5 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -7,6 +7,7 @@
* add `encodeBase64()` supporting padding-less encoding
* add `toIntArray()` converter #28
* add `toLongArray()` converter #29
+* add `AutoCloseable` to MutableBytes interface #31
### Breaking
diff --git a/README.md b/README.md
index 7e45db7..a8b97db 100644
--- a/README.md
+++ b/README.md
@@ -580,6 +580,18 @@ Bytes b = Bytes.from(array).mutable().copy();
assertTrue(b.isMutable());
```
+##### AutoClosable for try-with-resources
+
+In security-relevant environments it is best practice to wipe the memory of secret data, such as
+secret keys. This can be used with Java 7 feature try-with-resource like this:
+
+```java
+try (MutableBytes b = Bytes.wrap(aesBytes).mutable()) {
+ SecretKey s = new SecretKeySpec(b.array(), "AES");
+ ...
+}
+```
+
#### Readonly Bytes
On the other hand, if you want a export a instance with limited access,
diff --git a/src/main/java/at/favre/lib/bytes/MutableBytes.java b/src/main/java/at/favre/lib/bytes/MutableBytes.java
index 218fd20..3e40a89 100644
--- a/src/main/java/at/favre/lib/bytes/MutableBytes.java
+++ b/src/main/java/at/favre/lib/bytes/MutableBytes.java
@@ -32,7 +32,7 @@
* Adds additional mutator, which may change the internal array in-place, like {@link #wipe()}
*/
@SuppressWarnings("WeakerAccess")
-public final class MutableBytes extends Bytes {
+public final class MutableBytes extends Bytes implements AutoCloseable {
MutableBytes(byte[] byteArray, ByteOrder byteOrder) {
super(byteArray, byteOrder, new Factory());
@@ -147,6 +147,11 @@ public boolean equals(Object o) {
return super.equals(o);
}
+ @Override
+ public void close() {
+ secureWipe();
+ }
+
/**
* Factory creating mutable byte types
*/
diff --git a/src/test/java/at/favre/lib/bytes/MutableBytesTest.java b/src/test/java/at/favre/lib/bytes/MutableBytesTest.java
index b7167fc..85b98d0 100644
--- a/src/test/java/at/favre/lib/bytes/MutableBytesTest.java
+++ b/src/test/java/at/favre/lib/bytes/MutableBytesTest.java
@@ -23,6 +23,8 @@
import org.junit.Test;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Arrays;
@@ -167,4 +169,18 @@ public void testTransformerShouldBeMutable() {
assertTrue(b.append(3).isMutable());
assertTrue(b.hashSha256().isMutable());
}
+
+ @Test
+ public void testAutoCloseable() {
+ MutableBytes leak;
+
+ try (MutableBytes b = Bytes.wrap(new byte[16]).mutable()) {
+ assertArrayEquals(new byte[16], b.array());
+ SecretKey s = new SecretKeySpec(b.array(), "AES");
+ leak = b;
+ }
+
+ assertArrayNotEquals(new byte[16], leak.array());
+
+ }
}
From 7153117955cf5d1c8a979ce17337710191f0fd14 Mon Sep 17 00:00:00 2001
From: pfavre
Date: Sat, 12 Jan 2019 22:11:31 +0100
Subject: [PATCH 028/118] Minor refactorings
---
src/main/java/at/favre/lib/bytes/MutableBytes.java | 9 +++------
src/test/java/at/favre/lib/bytes/ABytesTest.java | 2 +-
src/test/java/at/favre/lib/bytes/MutableBytesTest.java | 3 ++-
3 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/src/main/java/at/favre/lib/bytes/MutableBytes.java b/src/main/java/at/favre/lib/bytes/MutableBytes.java
index 3e40a89..847fbfa 100644
--- a/src/main/java/at/favre/lib/bytes/MutableBytes.java
+++ b/src/main/java/at/favre/lib/bytes/MutableBytes.java
@@ -51,8 +51,7 @@ public boolean isMutable() {
* @throws IndexOutOfBoundsException if newArray.length > internal length
*/
public MutableBytes overwrite(byte[] newArray) {
- overwrite(newArray, 0);
- return this;
+ return overwrite(newArray, 0);
}
/**
@@ -87,8 +86,7 @@ public MutableBytes setByteAt(int index, byte newByte) {
* @return this instance
*/
public MutableBytes wipe() {
- fill((byte) 0);
- return this;
+ return fill((byte) 0);
}
/**
@@ -108,8 +106,7 @@ public MutableBytes fill(byte fillByte) {
* @return this instance
*/
public MutableBytes secureWipe() {
- secureWipe(new SecureRandom());
- return this;
+ return secureWipe(new SecureRandom());
}
/**
diff --git a/src/test/java/at/favre/lib/bytes/ABytesTest.java b/src/test/java/at/favre/lib/bytes/ABytesTest.java
index 076de64..ce4ab40 100644
--- a/src/test/java/at/favre/lib/bytes/ABytesTest.java
+++ b/src/test/java/at/favre/lib/bytes/ABytesTest.java
@@ -27,7 +27,7 @@
import static org.junit.Assert.*;
-abstract class ABytesTest {
+public abstract class ABytesTest {
byte[] example_bytes_empty;
byte[] example_bytes_one;
diff --git a/src/test/java/at/favre/lib/bytes/MutableBytesTest.java b/src/test/java/at/favre/lib/bytes/MutableBytesTest.java
index 85b98d0..aa3868f 100644
--- a/src/test/java/at/favre/lib/bytes/MutableBytesTest.java
+++ b/src/test/java/at/favre/lib/bytes/MutableBytesTest.java
@@ -106,7 +106,8 @@ public void setByteAtTest() {
for (int i = 0; i < b.length(); i++) {
byte old = b.byteAt(i);
- b.setByteAt(i, (byte) 0);
+ MutableBytes bcopy = b.setByteAt(i, (byte) 0);
+ assertSame(b, bcopy);
if (old != 0) {
assertNotEquals(old, b.byteAt(i));
}
From f762bb465a623a36a753dc84e2a2c927b8ee5a34 Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Mon, 14 Jan 2019 23:05:19 +0100
Subject: [PATCH 029/118] Fix some small issues
---
README.md | 2 +-
src/main/java/at/favre/lib/bytes/Bytes.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index a8b97db..6e8914b 100644
--- a/README.md
+++ b/README.md
@@ -205,7 +205,7 @@ Bytes result = Bytes.wrap(array1).append("some string");
Bytes.wrap(array).xor(array2); // 0010 0011 xor() 1011 1000 = 1001 1011
Bytes.wrap(array).or(array2); // 0010 0011 or() 1101 0100 = 1111 0111
Bytes.wrap(array).and(array2); // 0010 0011 and() 1011 1000 = 0010 0000
-Bytes.wrap(array).negate(); // 0010 0011 negate() = 1101 1100
+Bytes.wrap(array).not(); // 0010 0011 negate() = 1101 1100
Bytes.wrap(array).leftShift(8);
Bytes.wrap(array).rightShift(8);
Bytes.wrap(array).switchBit(3, true);
diff --git a/src/main/java/at/favre/lib/bytes/Bytes.java b/src/main/java/at/favre/lib/bytes/Bytes.java
index 03f77dd..79444c9 100644
--- a/src/main/java/at/favre/lib/bytes/Bytes.java
+++ b/src/main/java/at/favre/lib/bytes/Bytes.java
@@ -108,7 +108,7 @@ public static Bytes empty() {
* @return new instance
*/
public static Bytes wrap(Bytes bytes) {
- return new Bytes(bytes.internalArray(), bytes.byteOrder);
+ return wrap(bytes.internalArray(), bytes.byteOrder);
}
/**
From 7238f6c098047df09855a82e816b3a0e63aa4ab8 Mon Sep 17 00:00:00 2001
From: pfavre
Date: Fri, 8 Mar 2019 18:21:46 +0100
Subject: [PATCH 030/118] Update maven wrapper dist to 0.5.3
---
.mvn/wrapper/MavenWrapperDownloader.java | 49 ++++++++++++++---------
.mvn/wrapper/maven-wrapper.jar | Bin 47774 -> 50709 bytes
.mvn/wrapper/maven-wrapper.properties | 4 +-
mvnw | 27 +++++++++++--
mvnw.cmd | 19 +++++++--
5 files changed, 69 insertions(+), 30 deletions(-)
diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java
index 4978101..b20a55a 100644
--- a/.mvn/wrapper/MavenWrapperDownloader.java
+++ b/.mvn/wrapper/MavenWrapperDownloader.java
@@ -1,20 +1,18 @@
/*
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements. See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership. The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License. You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied. See the License for the
-specific language governing permissions and limitations
-under the License.
-*/
-
+ * Copyright 2007-present the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
import java.net.*;
import java.io.*;
import java.nio.channels.*;
@@ -22,11 +20,12 @@ Licensed to the Apache Software Foundation (ASF) under one
public class MavenWrapperDownloader {
+ private static final String WRAPPER_VERSION = "0.5.3";
/**
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
*/
- private static final String DEFAULT_DOWNLOAD_URL =
- "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar";
+ private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
+ + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + " .jar";
/**
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
@@ -74,13 +73,13 @@ public static void main(String args[]) {
}
}
}
- System.out.println("- Downloading from: : " + url);
+ System.out.println("- Downloading from: " + url);
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
if(!outputFile.getParentFile().exists()) {
if(!outputFile.getParentFile().mkdirs()) {
System.out.println(
- "- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'");
+ "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
}
}
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
@@ -96,6 +95,16 @@ public static void main(String args[]) {
}
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
+ if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
+ String username = System.getenv("MVNW_USERNAME");
+ char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
+ Authenticator.setDefault(new Authenticator() {
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(username, password);
+ }
+ });
+ }
URL website = new URL(urlString);
ReadableByteChannel rbc;
rbc = Channels.newChannel(website.openStream());
diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar
index 41c70a7e0b7da7ecbbcf53b62aacdf8bc81e10b0..e89f07c229cbd97f4e39b0eddba64604d1dca9f6 100644
GIT binary patch
delta 12756
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
delta 10111
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
F{{e1Wd{6)Y
diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties
index c4914b5..1703626 100644
--- a/.mvn/wrapper/maven-wrapper.properties
+++ b/.mvn/wrapper/maven-wrapper.properties
@@ -1,2 +1,2 @@
-distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip
-wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar
+distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip
+wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.3/maven-wrapper-0.5.3.jar
diff --git a/mvnw b/mvnw
index 5551fde..34d9dae 100755
--- a/mvnw
+++ b/mvnw
@@ -114,7 +114,6 @@ if $mingw ; then
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
- # TODO classpath?
fi
if [ -z "$JAVA_HOME" ]; then
@@ -212,7 +211,11 @@ else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
- jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
+ if [ -n "$MVNW_REPOURL" ]; then
+ jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.3/maven-wrapper-0.5.3.jar"
+ else
+ jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.3/maven-wrapper-0.5.3.jar"
+ fi
while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
esac
@@ -221,22 +224,38 @@ else
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
+ if $cygwin; then
+ wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
+ fi
if command -v wget > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
- wget "$jarUrl" -O "$wrapperJarPath"
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ wget "$jarUrl" -O "$wrapperJarPath"
+ else
+ wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
+ fi
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
- curl -o "$wrapperJarPath" "$jarUrl"
+ if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
+ curl -o "$wrapperJarPath" "$jarUrl" -f
+ else
+ curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
+ fi
+
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
+ # For Cygwin, switch paths to Windows format before running javac
+ if $cygwin; then
+ javaClass=`cygpath --path --windows "$javaClass"`
+ fi
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
diff --git a/mvnw.cmd b/mvnw.cmd
index e5cfb0a..77b451d 100644
--- a/mvnw.cmd
+++ b/mvnw.cmd
@@ -120,9 +120,10 @@ SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
-FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
- IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
+set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.3/maven-wrapper-0.5.3.jar"
+
+FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
+ IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@@ -130,9 +131,19 @@ FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-w
if exist %WRAPPER_JAR% (
echo Found %WRAPPER_JAR%
) else (
+ if not "%MVNW_REPOURL%" == "" (
+ SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.3/maven-wrapper-0.5.3.jar"
+ )
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
- powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
+
+ powershell -Command "&{"^
+ "$webclient = new-object System.Net.WebClient;"^
+ "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
+ "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
+ "}"^
+ "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
+ "}"
echo Finished downloading %WRAPPER_JAR%
)
@REM End of extension
From 586c1a8784084cb782567df64a54ffd43bba30a2 Mon Sep 17 00:00:00 2001
From: Konstantin Petrukhnov
Date: Mon, 11 Mar 2019 12:32:17 +0200
Subject: [PATCH 031/118] Allocate methods that return MutableBytes
---
.../java/at/favre/lib/bytes/MutableBytes.java | 21 +++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/src/main/java/at/favre/lib/bytes/MutableBytes.java b/src/main/java/at/favre/lib/bytes/MutableBytes.java
index 847fbfa..8ad8e91 100644
--- a/src/main/java/at/favre/lib/bytes/MutableBytes.java
+++ b/src/main/java/at/favre/lib/bytes/MutableBytes.java
@@ -38,6 +38,27 @@ public final class MutableBytes extends Bytes implements AutoCloseable {
super(byteArray, byteOrder, new Factory());
}
+ /**
+ * Creates a new instance with an empty array filled with zeros.
+ *
+ * @param length of the internal array
+ * @return new instance
+ */
+ public static MutableBytes allocate(int length) {
+ return allocate(length, (byte) 0);
+ }
+
+ /**
+ * Creates a new instance with an empty array filled with given defaultValue
+ *
+ * @param length of the internal array
+ * @param defaultValue to fill with
+ * @return new instance
+ */
+ public static MutableBytes allocate(int length, byte defaultValue) {
+ return Bytes.allocate(length, defaultValue).mutable();
+ }
+
@Override
public boolean isMutable() {
return true;
From 24534d7aecf8e15b4201bf397e2d73e9f2ece82d Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Tue, 12 Mar 2019 08:16:13 +0100
Subject: [PATCH 032/118] Add PR friendly travis ci config
---
.travis.yml | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index 6093a6b..13d8766 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -17,7 +17,8 @@ before_install:
- tar xvf secrets.tar
script:
- - ./mvnw clean install -X -Djarsigner.skip=false checkstyle:check
+ - 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then ./mvnw clean install -X -Djarsigner.skip=true checkstyle:check; fi'
+ - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then ./mvnw clean install -X -Djarsigner.skip=false checkstyle:check; fi'
after_success:
- ./mvnw test jacoco:report coveralls:report
From 6ed1e2b95441caff7b369af318674a8871ed9851 Mon Sep 17 00:00:00 2001
From: Patrick Favre-Bulle
Date: Tue, 12 Mar 2019 08:18:30 +0100
Subject: [PATCH 033/118] Add changelog for latest PR
---
CHANGELOG | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG b/CHANGELOG
index 03267a5..cf96dba 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -8,6 +8,7 @@
* add `toIntArray()` converter #28
* add `toLongArray()` converter #29
* add `AutoCloseable` to MutableBytes interface #31
+* add `allocate()` as mutable byte static constructor (thx @petrukhnov)
### Breaking
From 373750629b2ba23c2f2511031eaf2c10a12e4f49 Mon Sep 17 00:00:00 2001
From: pfavre
Date: Sat, 16 Mar 2019 15:25:43 +0100
Subject: [PATCH 034/118] Update checkstyle to 8.18 to fix CVE-2019-9658
This was brought to my attention by Github's security alert feature.
Link: https://nvd.nist.gov/vuln/detail/CVE-2019-9658
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 632db64..443e9f7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,7 +50,7 @@
com.puppycrawl.toolscheckstyle
- 8.11
+ 8.18
From 04608362f7e9f80bef9ab8941dc250f74e6f33c6 Mon Sep 17 00:00:00 2001
From: pfavre
Date: Thu, 4 Apr 2019 20:20:45 +0200
Subject: [PATCH 035/118] Bump version to 1.1.0
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 443e9f7..ff9836e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
at.favre.libbytes
- 1.0.0
+ 1.1.0jarBytes Utility Library
From 6c79fe31a6564ac398980896b9dd134beb1794b7 Mon Sep 17 00:00:00 2001
From: pfavre
Date: Thu, 4 Apr 2019 20:22:23 +0200
Subject: [PATCH 036/118] Add new unsecureRandom() constructor to create fast
and/or deterministic pseudo random values
---
CHANGELOG | 4 +++
README.md | 8 ++++-
src/main/java/at/favre/lib/bytes/Bytes.java | 29 +++++++++++++++++++
.../lib/bytes/BytesConstructorTests.java | 22 ++++++++++++++
4 files changed, 62 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index cf96dba..e44d4f9 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,9 @@
# Releases
+## v1.1.0
+
+* add `unsecureRandom()` constructor which creates random for e.g. tests or deterministic randoms
+
## v1.0.0
* add `append()` method supporting multiple byte arrays #26
diff --git a/README.md b/README.md
index 67fe2e1..4a48491 100644
--- a/README.md
+++ b/README.md
@@ -145,12 +145,18 @@ Bytes.allocate(4, (byte) 1); //fill with 0x01
Bytes.empty(); //creates zero length byte array
```
-Creating **random** byte arrays for e.g. testing:
+Creating cryptographically secure **random** byte arrays:
```java
Bytes.random(12);
```
+Creating cryptographically unsecure **random** byte arrays for e.g. testing:
+
+```java
+Bytes.unsecureRandom(12, 12345L); // using seed makes it deterministic
+```
+
Reading byte content of encoded `String`s:
```java
diff --git a/src/main/java/at/favre/lib/bytes/Bytes.java b/src/main/java/at/favre/lib/bytes/Bytes.java
index c834e46..f712f00 100644
--- a/src/main/java/at/favre/lib/bytes/Bytes.java
+++ b/src/main/java/at/favre/lib/bytes/Bytes.java
@@ -662,6 +662,35 @@ public static Bytes random(int length) {
return random(length, new SecureRandom());
}
+ /**
+ * A new instance with pseudo random bytes using an unsecure random number generator.
+ * This may be used in e.g. tests. In production code use {@link #random(int)} per default.
+ *
+ * ONLY USE IN NON-SECURITY RELEVANT CONTEXT!
+ *
+ * @param length desired array length
+ * @return random instance
+ */
+ public static Bytes unsecureRandom(int length) {
+ return random(length, new Random());
+ }
+
+ /**
+ * A new instance with pseudo random bytes using an unsecure random number generator.
+ * This may be used in e.g. tests to create predictable numbers.
+ *
+ * In production code use {@link #random(int)} per default.
+ *
+ * ONLY USE IN NON-SECURITY RELEVANT CONTEXT!
+ *
+ * @param length desired array length
+ * @param seed used to seed random number generator - using same seed will generate same numbers
+ * @return random instance
+ */
+ public static Bytes unsecureRandom(int length, long seed) {
+ return random(length, new Random(seed));
+ }
+
/**
* A new instance with random bytes.
*
diff --git a/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java b/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java
index d08d46f..aa4f8c8 100644
--- a/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java
+++ b/src/test/java/at/favre/lib/bytes/BytesConstructorTests.java
@@ -34,6 +34,7 @@
import java.nio.IntBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
+import java.security.SecureRandom;
import java.text.Normalizer;
import java.util.Arrays;
import java.util.BitSet;
@@ -547,4 +548,25 @@ private void testUUID(UUID uuid) {
public void fromUUIDNullArgument() {
Bytes.from((UUID) null);
}
+
+ @Test
+ public void createSecureRandom() {
+ assertNotEquals(Bytes.random(16), Bytes.random(16));
+ }
+
+ @Test
+ public void createSecureRandomWithExplicitSecureRandom() {
+ assertNotEquals(Bytes.random(16, new SecureRandom()), Bytes.random(16, new SecureRandom()));
+ }
+
+ @Test
+ public void createUnsecureRandom() {
+ assertNotEquals(Bytes.unsecureRandom(128), Bytes.unsecureRandom(128));
+ }
+
+ @Test
+ public void createUnsecureRandomWithSeed() {
+ assertEquals(Bytes.unsecureRandom(128, 4L), Bytes.unsecureRandom(128, 4L));
+ assertNotEquals(Bytes.unsecureRandom(4, 3L), Bytes.unsecureRandom(4, 4L));
+ }
}
From 3b55099afbbb18fabe4d25e7bc794431c9452b49 Mon Sep 17 00:00:00 2001
From: pfavre
Date: Tue, 9 Apr 2019 07:36:31 +0200
Subject: [PATCH 037/118] Make BaseEncoding accessible from outside the lib
---
src/main/java/at/favre/lib/bytes/BaseEncoding.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/main/java/at/favre/lib/bytes/BaseEncoding.java b/src/main/java/at/favre/lib/bytes/BaseEncoding.java
index e40076e..8fe8d3e 100644
--- a/src/main/java/at/favre/lib/bytes/BaseEncoding.java
+++ b/src/main/java/at/favre/lib/bytes/BaseEncoding.java
@@ -42,7 +42,8 @@ final class BaseEncoding implements BinaryToTextEncoding.EncoderDecoder {
private final Alphabet alphabet;
private final Character paddingChar;
- BaseEncoding(Alphabet alphabet, Character paddingChar) {
+ @SuppressWarnings("WeakerAccess")
+ public BaseEncoding(Alphabet alphabet, Character paddingChar) {
this.alphabet = Objects.requireNonNull(alphabet);
this.paddingChar = paddingChar;
}
From 7c36da33d47a5d0d3b66ddd1e632a893782daaa6 Mon Sep 17 00:00:00 2001
From: JadePaukkunen <43367473+JadePaukkunen@users.noreply.github.com>
Date: Mon, 15 Apr 2019 18:27:16 +0300
Subject: [PATCH 038/118] =?UTF-8?q?Overwrite-methods=20that=20take=20Bytes?=
=?UTF-8?q?=20as=20parameters.=20Tests=20for=20IndexOutOf=E2=80=A6=20(#35)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Overwrite-methods that take Bytes as parameters. Tests for IndexOutOfBounds-exception when overwritten array exceeds the original size and NullPointerException when the array used to overwrite is null
* add requested changes
---
CHANGELOG | 5 +++
.../java/at/favre/lib/bytes/MutableBytes.java | 29 ++++++++++++
.../at/favre/lib/bytes/MutableBytesTest.java | 45 +++++++++++++++++++
3 files changed, 79 insertions(+)
diff --git a/CHANGELOG b/CHANGELOG
index e44d4f9..173588d 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,10 @@
# Releases
+## Unreleased
+
+* adds overwrite method to Bytes
+* adds tests to NullPointerException and IndexOutOfBoundsException
+
## v1.1.0
* add `unsecureRandom()` constructor which creates random for e.g. tests or deterministic randoms
diff --git a/src/main/java/at/favre/lib/bytes/MutableBytes.java b/src/main/java/at/favre/lib/bytes/MutableBytes.java
index 8ad8e91..0653d28 100644
--- a/src/main/java/at/favre/lib/bytes/MutableBytes.java
+++ b/src/main/java/at/favre/lib/bytes/MutableBytes.java
@@ -71,10 +71,25 @@ public boolean isMutable() {
* @return this instance
* @throws IndexOutOfBoundsException if newArray.length > internal length
*/
+
public MutableBytes overwrite(byte[] newArray) {
+
return overwrite(newArray, 0);
}
+ /**
+ * Uses given Bytes array to overwrite internal array
+ *
+ * @param newBytes used to overwrite internal
+ * @return this instance
+ * @throws IndexOutOfBoundsException if newArray.length > internal length
+ */
+
+ public MutableBytes overwrite(Bytes newBytes) {
+
+ return overwrite(newBytes, 0);
+ }
+
/**
* Uses given array to overwrite internal array.
*
@@ -83,12 +98,26 @@ public MutableBytes overwrite(byte[] newArray) {
* @return this instance
* @throws IndexOutOfBoundsException if newArray.length + offsetInternalArray > internal length
*/
+
public MutableBytes overwrite(byte[] newArray, int offsetInternalArray) {
Objects.requireNonNull(newArray, "must provide non-null array as source");
System.arraycopy(newArray, 0, internalArray(), offsetInternalArray, newArray.length);
return this;
}
+ /**
+ * Uses given Bytes array to overwrite internal array.
+ *
+ * @param newBytes used to overwrite internal
+ * @param offsetInternalArray index of the internal array to start overwriting
+ * @return this instance
+ * @throws IndexOutOfBoundsException if newBytes.length + offsetInternalArray > internal length
+ */
+
+ public MutableBytes overwrite(Bytes newBytes, int offsetInternalArray) {
+ return overwrite(Objects.requireNonNull(newBytes, "must provide non-null array as source").array(), offsetInternalArray);
+ }
+
/**
* Sets new byte to given index
*
diff --git a/src/test/java/at/favre/lib/bytes/MutableBytesTest.java b/src/test/java/at/favre/lib/bytes/MutableBytesTest.java
index aa3868f..831cbfe 100644
--- a/src/test/java/at/favre/lib/bytes/MutableBytesTest.java
+++ b/src/test/java/at/favre/lib/bytes/MutableBytesTest.java
@@ -63,6 +63,50 @@ public void overwritePartialArray2() {
.append(Bytes.wrap(example_bytes_seven).copy(2, example_bytes_seven.length - 2)).array(), b.array());
}
+ @Test
+ public void overwriteBytes() {
+ MutableBytes a = fromAndTest(example_bytes_seven).mutable();
+ MutableBytes b = Bytes.from((byte)0).mutable();
+ MutableBytes c = a.overwrite(b, 0).mutable();
+ MutableBytes d = Bytes.wrap(a).copy(1, a.array().length-1).mutable();
+
+ assertArrayEquals(c.array(), Bytes.from(b).append(d).array());
+ }
+
+ @Test
+ public void overwriteTooBigArrayShouldThrowException() {
+ MutableBytes b = fromAndTest(example_bytes_seven).mutable();
+ try {
+ b.overwrite(new byte[]{(byte) 0xAA, 0x30}, b.length());
+ fail();
+ } catch(IndexOutOfBoundsException ignored) {}
+
+ }
+
+ @Test
+ public void overwriteTooBigBytesShouldThrowException() {
+ MutableBytes b = fromAndTest(example_bytes_seven).mutable();
+ try {
+ b.overwrite(Bytes.from((byte) 0xAA, 0x30), b.length());
+ fail();
+ } catch(IndexOutOfBoundsException ignored) {}
+
+ }
+
+ @Test
+ public void overwriteNullArrayShouldThrowException() {
+ MutableBytes nonsense = null;
+ MutableBytes b = fromAndTest(example_bytes_seven).mutable();
+
+ try{
+ b.overwrite(nonsense);
+ fail();
+ } catch (NullPointerException ignored){}
+
+
+ }
+
+
@Test
public void fill() {
MutableBytes b = fromAndTest(example_bytes_seven).mutable();
@@ -184,4 +228,5 @@ public void testAutoCloseable() {
assertArrayNotEquals(new byte[16], leak.array());
}
+
}
From d7543c573cf37f98b6377a00f096f225e417b54a Mon Sep 17 00:00:00 2001
From: pfavre
Date: Mon, 15 Apr 2019 20:00:18 +0200
Subject: [PATCH 039/118] Fix illegal javadoc characters
---
src/main/java/at/favre/lib/bytes/MutableBytes.java | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/main/java/at/favre/lib/bytes/MutableBytes.java b/src/main/java/at/favre/lib/bytes/MutableBytes.java
index 0653d28..93a92d4 100644
--- a/src/main/java/at/favre/lib/bytes/MutableBytes.java
+++ b/src/main/java/at/favre/lib/bytes/MutableBytes.java
@@ -73,7 +73,6 @@ public boolean isMutable() {
*/
public MutableBytes overwrite(byte[] newArray) {
-
return overwrite(newArray, 0);
}
@@ -82,11 +81,10 @@ public MutableBytes overwrite(byte[] newArray) {
*
* @param newBytes used to overwrite internal
* @return this instance
- * @throws IndexOutOfBoundsException if newArray.length > internal length
+ * @throws IndexOutOfBoundsException if newArray.length > internal length
*/
public MutableBytes overwrite(Bytes newBytes) {
-
return overwrite(newBytes, 0);
}
@@ -111,7 +109,7 @@ public MutableBytes overwrite(byte[] newArray, int offsetInternalArray) {
* @param newBytes used to overwrite internal
* @param offsetInternalArray index of the internal array to start overwriting
* @return this instance
- * @throws IndexOutOfBoundsException if newBytes.length + offsetInternalArray > internal length
+ * @throws IndexOutOfBoundsException if newBytes.length + offsetInternalArray > internal length
*/
public MutableBytes overwrite(Bytes newBytes, int offsetInternalArray) {
From fa7b7cedd6ca8ac861844104ffb0fc785d03709c Mon Sep 17 00:00:00 2001
From: pfavre
Date: Mon, 15 Apr 2019 20:01:32 +0200
Subject: [PATCH 040/118] Update CHANGELOG
---
CHANGELOG | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
index 173588d..783b0f3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,13 +1,9 @@
# Releases
-## Unreleased
-
-* adds overwrite method to Bytes
-* adds tests to NullPointerException and IndexOutOfBoundsException
-
## v1.1.0
* add `unsecureRandom()` constructor which creates random for e.g. tests or deterministic randoms
+* adds overwrite method to Bytes (thx @JadePaukkunen)
## v1.0.0
From b146335916c44433bb967662e0d471c6208bfb90 Mon Sep 17 00:00:00 2001
From: pfavre
Date: Mon, 15 Apr 2019 20:11:58 +0200
Subject: [PATCH 041/118] Make project OSGi compatible
refs #36
---
CHANGELOG | 1 +
README.md | 29 +++++++++++++++++++++++++++++
pom.xml | 8 +++++++-
3 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index 783b0f3..d563706 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -4,6 +4,7 @@
* add `unsecureRandom()` constructor which creates random for e.g. tests or deterministic randoms
* adds overwrite method to Bytes (thx @JadePaukkunen)
+* make project OSGi compatible #36
## v1.0.0
diff --git a/README.md b/README.md
index 4a48491..b35cf00 100644
--- a/README.md
+++ b/README.md
@@ -616,6 +616,35 @@ readOnlyBytes.byteBuffer();
readOnlyBytes.inputStream();
```
+## Download
+
+The artifacts are deployed to [jcenter](https://bintray.com/bintray/jcenter) and [Maven Central](https://search.maven.org/).
+
+### Maven
+
+Add the dependency of the [latest version](https://github.com/patrickfav/bytes/releases) to your `pom.xml`:
+
+
+ at.favre.lib
+ bytes
+ {latest-version}
+
+
+### Gradle
+
+Add to your `build.gradle` module dependencies:
+
+ implementation group: 'at.favre.lib', name: 'bytes', version: '{latest-version}'
+
+### Local Jar Library
+
+[Grab jar from latest release.](https://github.com/patrickfav/bytes/releases/latest)
+
+### OSGi
+
+The library should be prepared to be used with the OSGi framework with the help of the [bundle plugin](http://felix.apache.org/documentation/subprojects/apache-felix-maven-bundle-plugin-bnd.html).
+
+
## Digital Signatures
### Signed Jar
diff --git a/pom.xml b/pom.xml
index ff9836e..c9b5e4d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
at.favre.libbytes1.1.0
- jar
+ bundleBytes Utility LibraryBytes is a utility library that makes it easy to create, parse, transform, validate and convert byte
@@ -37,6 +37,12 @@
+
+ org.apache.felix
+ maven-bundle-plugin
+ 4.2.0
+ true
+ org.apache.maven.pluginsmaven-checkstyle-plugin
From cfb7dce18116e95e933a85f853f984466b36fea4 Mon Sep 17 00:00:00 2001
From: pfavre
Date: Mon, 15 Apr 2019 21:32:03 +0200
Subject: [PATCH 042/118] Add `toFloatArray()` and `toDoubleArray()` converter
refs #30
---
CHANGELOG | 2 +
src/main/java/at/favre/lib/bytes/Bytes.java | 38 ++++++++
src/main/java/at/favre/lib/bytes/Util.java | 54 ++++++++++++
.../bytes/BytesToConvertOtherTypesTest.java | 86 ++++++++++++++++++-
.../at/favre/lib/bytes/UtilConverterTest.java | 38 ++++++++
5 files changed, 217 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG b/CHANGELOG
index d563706..5689827 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,6 +5,8 @@
* add `unsecureRandom()` constructor which creates random for e.g. tests or deterministic randoms
* adds overwrite method to Bytes (thx @JadePaukkunen)
* make project OSGi compatible #36
+* add `toFloatArray()` converter #30
+* add `toDoubleArray()` converter #30
## v1.0.0
diff --git a/src/main/java/at/favre/lib/bytes/Bytes.java b/src/main/java/at/favre/lib/bytes/Bytes.java
index f712f00..d3abbbf 100644
--- a/src/main/java/at/favre/lib/bytes/Bytes.java
+++ b/src/main/java/at/favre/lib/bytes/Bytes.java
@@ -1956,6 +1956,25 @@ public float toFloat() {
return internalBuffer().getFloat();
}
+ /**
+ * Converts the internal byte array to an float array, that is, every 4 bytes will be packed into a single float.
+ *
+ * E.g. 4 bytes will be packed to a length 1 float array:
+ *
+ * [b1, b2, b3, b4] = [float1]
+ *
+ *
+ * This conversion respects the internal byte order. Will only work if all bytes can be directly mapped to float,
+ * which means the byte array length must be dividable by 4 without rest.
+ *
+ * @return new float[] instance representing this byte array
+ * @throws IllegalArgumentException if internal byte length mod 4 != 0
+ */
+ public float[] toFloatArray() {
+ Util.Validation.checkModLength(length(), 4, "creating an float array");
+ return Util.Converter.toFloatArray(internalArray(), byteOrder);
+ }
+
/**
* If the underlying byte array is exactly 8 byte / 64 bit long, return the
* representation for a Java double value. The output is dependent on the set {@link #byteOrder()}.
@@ -1969,6 +1988,25 @@ public double toDouble() {
return internalBuffer().getDouble();
}
+ /**
+ * Converts the internal byte array to an double array, that is, every 8 bytes will be packed into a single double.
+ *
+ * E.g. 8 bytes will be packed to a length 1 double array:
+ *
+ * This conversion respects the internal byte order. Will only work if all bytes can be directly mapped to double,
+ * which means the byte array length must be dividable by 8 without rest.
+ *
+ * @return new double[] instance representing this byte array
+ * @throws IllegalArgumentException if internal byte length mod 8 != 0
+ */
+ public double[] toDoubleArray() {
+ Util.Validation.checkModLength(length(), 8, "creating an double array");
+ return Util.Converter.toDoubleArray(internalArray(), byteOrder);
+ }
+
/**
* Decodes the internal byte array to UTF-8 char array.
* This implementation will not internally create a {@link String}.
diff --git a/src/main/java/at/favre/lib/bytes/Util.java b/src/main/java/at/favre/lib/bytes/Util.java
index 70d35e0..f2419c3 100644
--- a/src/main/java/at/favre/lib/bytes/Util.java
+++ b/src/main/java/at/favre/lib/bytes/Util.java
@@ -719,6 +719,60 @@ static long[] toLongArray(byte[] bytes, ByteOrder byteOrder) {
return array;
}
+ /**
+ * Converts the byte array to an float array. This will spread 4 bytes into a single float:
+ *
+ *
+ * [b1, b2, b3, b4] = [float1]
+ *
+ *
+ *
+ * Analysis
+ *
+ *
Time Complexity: O(n)
+ *
Space Complexity: O(n)
+ *
Alters Parameters: false
+ *
+ *
+ *
+ * @param bytes to convert to float array, must be % 4 == 0 to work correctly
+ * @param byteOrder of the byte array
+ * @return float array
+ */
+ static float[] toFloatArray(byte[] bytes, ByteOrder byteOrder) {
+ FloatBuffer buffer = ByteBuffer.wrap(bytes).order(byteOrder).asFloatBuffer();
+ float[] array = new float[buffer.remaining()];
+ buffer.get(array);
+ return array;
+ }
+
+ /**
+ * Converts the byte array to an double array. This will spread 8 bytes into a single double:
+ *
+ *
+ * REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
+ * why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
+ * experiments, perform baseline and negative tests that provide experimental control, make sure
+ * the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
+ * Do not assume the numbers tell you what you want them to tell.
+ *