Skip to content

Commit b86ae82

Browse files
committed
Creation of int and long array as well as object byte arrays
1 parent 79a9317 commit b86ae82

File tree

9 files changed

+158
-23
lines changed

9 files changed

+158
-23
lines changed

CHANGELOG

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
## v0.3.1
44

55
* better validation and more creation possibilities
6-
* create from bigInteger
6+
* create from bigInteger, int[], long[] and Byte[]
77

88
## v0.3.0
99

README.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ There are 3 basic constructors:
2222
* `from()` which always creates a new internal array reference (i.e. a copy of the passed reference)
2323
* `parse()` which parses from binary-text-encoded strings (see other section)
2424

25-
Here is a simple example to show the difference
25+
Here is a simple example to show the difference:
2626

2727
```java
2828
byte[] myArray = ...
@@ -50,11 +50,12 @@ Bytes.from(array1, array2, array3);
5050
Bytes.from((byte) 0x01, (byte) 0x02, (byte) 0x03);
5151
```
5252

53-
Creating byte arrays from **primitive integer** types:
53+
Creating byte arrays from **primitive integer** types and arrays:
5454

5555
```java
5656
Bytes.from(8); //00000000 00000000 00000000 00001000
5757
Bytes.from(1897621543227L);
58+
Bytes.from(1634, 88903, 77263);
5859
```
5960

6061
Initializing **empty arrays** of arbitrary length:
@@ -93,7 +94,8 @@ For parsing binary-text-encoded strings, see below.
9394
### Transformers
9495

9596
Transformer transform the internal byte array. It is possible to create
96-
a custom transformer if a specific use case is required (see `BytesTransformer`).
97+
custom transformers if a specific feature is not provided by the default
98+
implementation (see `BytesTransformer`).
9799

98100
```java
99101
Bytes result = Bytes.wrap(array1).transform(myCustomTransformer);
@@ -102,8 +104,8 @@ Bytes result = Bytes.wrap(array1).transform(myCustomTransformer);
102104
#### Built-In Transformers
103105

104106
For **appending** byte arrays or primitive integer types to current instances.
105-
Note however, that this will create new copies of byte arrays every time.
106-
For dynamic growing byte arrays see `ByteArrayOutputStream`
107+
*Note:* this will create a new copy of the internal byte array; for dynamically
108+
growing byte arrays see `ByteArrayOutputStream`.
107109

108110
```java
109111
Bytes result = Bytes.wrap(array1).append(array2);
@@ -146,7 +148,7 @@ Bytes result = Bytes.wrap(array).reverse();
146148

147149
### Parser and Encoder for Binary-Text-Encodings
148150

149-
This library can parse and encode a variety of encodings: binary, decimal, ocatal,
151+
This library can parse and encode a variety of encodings: binary, decimal, octal,
150152
hex, base36 and base64. Additionally custom parsers are supported by providing your own
151153
implementation:
152154

@@ -155,7 +157,7 @@ Bytes.parse("8sK;S*j=r", base85Decoder);
155157
Bytes.encode(base85Encoder);
156158
```
157159

158-
**Hex** can be upper and lowercase and also supports `0x` prefix for parsing
160+
**Hex** can be upper and lowercase and also supports `0x` prefix for parsing:
159161

160162
```java
161163
Bytes.parseHex("a0e13eaa1a")

src/main/java/at/favre/lib/bytes/BinaryToTextEncoding.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ public byte[] decode(String hexString) {
114114
}
115115
}
116116

117+
/**
118+
* Simple Base64 encoder
119+
*/
117120
class Base64Encoding implements Encoder, Decoder {
118121
@Override
119122
public String encode(byte[] array, ByteOrder byteOrder) {
@@ -126,6 +129,9 @@ public byte[] decode(String encoded) {
126129
}
127130
}
128131

132+
/**
133+
* Simple radix encoder which internally uses {@link BigInteger#toString(int)}
134+
*/
129135
class BaseRadix implements Encoder, Decoder {
130136
private final int radix;
131137

src/main/java/at/favre/lib/bytes/Bytes.java

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,18 @@ public static Bytes wrap(byte[] array, ByteOrder byteOrder) {
129129
return new Bytes(array, byteOrder);
130130
}
131131

132+
/**
133+
* Creates a new instance from given collections of single bytes.
134+
* This will create a copy of given bytes and will not directly use given bytes or byte array.
135+
*
136+
* @param byteArrayToCopy must not be null and will not be used directly, but a copy
137+
* @return new instance
138+
*/
139+
public static Bytes from(byte[] byteArrayToCopy) {
140+
Objects.requireNonNull(byteArrayToCopy, "must at least pass a single byte");
141+
return wrap(Arrays.copyOf(byteArrayToCopy, byteArrayToCopy.length));
142+
}
143+
132144
/**
133145
* Creates a new instance from a slice of given array
134146
*
@@ -181,25 +193,23 @@ public static Bytes from(Collection<Byte> bytesCollection) {
181193
}
182194

183195
/**
184-
* Creates a new single array element array instance from given byte
196+
* Creates a new instance from given object byte array. Will copy and unbox every element.
185197
*
186-
* @param singleByte to create from
198+
* @param objectArray to create from
187199
* @return new instance
188200
*/
189-
public static Bytes from(byte singleByte) {
190-
return wrap(new byte[]{singleByte});
201+
public static Bytes from(Byte[] objectArray) {
202+
return wrap(Util.toPrimitiveArray(objectArray));
191203
}
192204

193205
/**
194-
* Creates a new instance from given collections of single bytes.
195-
* This will create a copy of given bytes and will not directly use given bytes or byte array.
206+
* Creates a new single array element array instance from given byte
196207
*
197-
* @param byteArrayToCopy must not be null and will not be used directly, but a copy
208+
* @param singleByte to create from
198209
* @return new instance
199210
*/
200-
public static Bytes from(byte[] byteArrayToCopy) {
201-
Objects.requireNonNull(byteArrayToCopy, "must at least pass a single byte");
202-
return wrap(Arrays.copyOf(byteArrayToCopy, byteArrayToCopy.length));
211+
public static Bytes from(byte singleByte) {
212+
return wrap(new byte[]{singleByte});
203213
}
204214

205215
/**
@@ -244,6 +254,17 @@ public static Bytes from(int integer4byte) {
244254
return wrap(ByteBuffer.allocate(4).putInt(integer4byte).array());
245255
}
246256

257+
/**
258+
* Creates a new instance from given 4 byte integer array.
259+
*
260+
* @param intArray to create from
261+
* @return new instance
262+
*/
263+
public static Bytes from(int... intArray) {
264+
Objects.requireNonNull(intArray, "must provide at least a single int");
265+
return wrap(Util.toByteArray(intArray));
266+
}
267+
247268
/**
248269
* Creates a new instance from given 8 byte long.
249270
*
@@ -254,6 +275,17 @@ public static Bytes from(long long8byte) {
254275
return wrap(ByteBuffer.allocate(8).putLong(long8byte).array());
255276
}
256277

278+
/**
279+
* Creates a new instance from given 8 byte long array.
280+
*
281+
* @param longArray to create from
282+
* @return new instance
283+
*/
284+
public static Bytes from(long... longArray) {
285+
Objects.requireNonNull(longArray, "must provide at least a single long");
286+
return wrap(Util.toByteArray(longArray));
287+
}
288+
257289
/**
258290
* Creates a new instance from given ByteBuffer.
259291
* Will use the same backing byte array and honour the buffer's byte order.
@@ -677,7 +709,7 @@ public Bytes copy(int offset, int length) {
677709
}
678710

679711
/**
680-
* Reverses the internal byte array.
712+
* Reverses the internal bytes in the array (not bits in each byte)
681713
* <p>
682714
* See the considerations about possible in-place operation in {@link #transform(BytesTransformer)}.
683715
*
@@ -1359,6 +1391,9 @@ public String toString() {
13591391
return length() + " bytes " + preview;
13601392
}
13611393

1394+
/**
1395+
* Internal factory for {@link Bytes} instances
1396+
*/
13621397
private static class Factory implements BytesFactory {
13631398
@Override
13641399
public Bytes wrap(byte[] array, ByteOrder byteOrder) {

src/main/java/at/favre/lib/bytes/BytesFactory.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,17 @@
2323

2424
import java.nio.ByteOrder;
2525

26+
/**
27+
* Simple factory for creating {@link Bytes} instances
28+
*/
2629
public interface BytesFactory {
30+
31+
/**
32+
* Create an instance with given array and order
33+
*
34+
* @param array to directly us
35+
* @param byteOrder the array is in
36+
* @return a new instance
37+
*/
2738
Bytes wrap(byte[] array, ByteOrder byteOrder);
2839
}

src/main/java/at/favre/lib/bytes/MutableBytes.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import java.util.Objects;
2828

2929
/**
30-
* Mutable version of {@link Bytes}. If possible, all transformations are done in place, without creating a copy.
30+
* Mutable version of {@link Bytes} created by calling {@link #mutable()}. If possible, all transformations are done in place, without creating a copy.
3131
* <p>
3232
* Adds additional mutator, which may change the internal array in-place, like {@link #wipe()}
3333
*/

src/main/java/at/favre/lib/bytes/ReadOnlyBytes.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@
2424
import java.nio.ByteOrder;
2525
import java.nio.ReadOnlyBufferException;
2626

27+
/**
28+
* The read-only version of {@link Bytes} created by calling {@link #readOnly()}.
29+
* <p>
30+
* Read-only Bytes does not have access to the internal byte array ({@link #array()}
31+
* will throw an exception). Transformers will always create a copy and keep the
32+
* read-only status.
33+
*/
2734
public final class ReadOnlyBytes extends Bytes {
2835

2936
/**

src/main/java/at/favre/lib/bytes/Util.java

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.io.File;
2626
import java.io.IOException;
2727
import java.io.InputStream;
28+
import java.nio.ByteBuffer;
2829
import java.nio.file.Files;
2930
import java.util.*;
3031

@@ -164,8 +165,8 @@ static List<Byte> toList(byte[] array) {
164165
}
165166

166167
/**
167-
* Converts this primitive array to an boxed object array. Will create a new array
168-
* and not reuse the array reference.
168+
* Converts this primitive array to an boxed object array.
169+
* Will create a new array and not reuse the array reference.
169170
*
170171
* @param array to convert
171172
* @return new array
@@ -178,6 +179,57 @@ static Byte[] toObjectArray(byte[] array) {
178179
return objectArray;
179180
}
180181

182+
/**
183+
* Converts this object array to an primitives type array.
184+
* Will create a new array and not reuse the array reference.
185+
*
186+
* @param objectArray to convert
187+
* @return new array
188+
*/
189+
static byte[] toPrimitiveArray(Byte[] objectArray) {
190+
byte[] primitivesArray = new byte[objectArray.length];
191+
for (int i = 0; i < objectArray.length; i++) {
192+
primitivesArray[i] = objectArray[i];
193+
}
194+
return primitivesArray;
195+
}
196+
197+
/**
198+
* Creates a byte array from given int array.
199+
* The resulting byte array will have length intArray * 4.
200+
*
201+
* @param intArray to convert
202+
* @return resulting byte array
203+
*/
204+
static byte[] toByteArray(int[] intArray) {
205+
byte[] primitivesArray = new byte[intArray.length * 4];
206+
for (int i = 0; i < intArray.length; i++) {
207+
byte[] intBytes = ByteBuffer.allocate(4).putInt(intArray[i]).array();
208+
for (int j = 0; j < intBytes.length; j++) {
209+
primitivesArray[(i * 4) + j] = intBytes[j];
210+
}
211+
}
212+
return primitivesArray;
213+
}
214+
215+
/**
216+
* Creates a byte array from given long array.
217+
* The resulting byte array will have length longArray * 8
218+
*
219+
* @param longArray to convert
220+
* @return resulting byte array
221+
*/
222+
static byte[] toByteArray(long[] longArray) {
223+
byte[] primitivesArray = new byte[longArray.length * 8];
224+
for (int i = 0; i < longArray.length; i++) {
225+
byte[] longBytes = ByteBuffer.allocate(8).putLong(longArray[i]).array();
226+
for (int j = 0; j < longBytes.length; j++) {
227+
primitivesArray[(i * 8) + j] = longBytes[j];
228+
}
229+
}
230+
return primitivesArray;
231+
}
232+
181233
/**
182234
* Simple Durstenfeld shuffle
183235
* <p>
@@ -251,7 +303,6 @@ static byte[] readFromFile(File file) {
251303
} catch (IOException e) {
252304
throw new IllegalStateException("could not read from file", e);
253305
}
254-
255306
}
256307

257308
/*

src/test/java/at/favre/lib/bytes/BytesConstructorTests.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,14 @@ public void fromInt() throws Exception {
145145
assertEquals(test, Bytes.from(test).toInt());
146146
}
147147

148+
@Test
149+
public void fromIntArray() throws Exception {
150+
assertArrayEquals(new byte[]{0, 0, 0, 1, 0, 0, 0, 2}, Bytes.from(1, 2).array());
151+
assertArrayEquals(Bytes.from(Bytes.from(871193), Bytes.from(6761), Bytes.from(-917656)).array(), Bytes.from(871193, 6761, -917656).array());
152+
assertArrayEquals(Bytes.from(Bytes.from(1678), Bytes.from(-223), Bytes.from(11114)).array(), Bytes.from(1678, -223, 11114).array());
153+
assertArrayEquals(new byte[]{0, 11, 30, 55, 0, 0, 35, 53, 0, 0, 0, 0, 0, 0, 56, -70}, Bytes.from(728631, 9013, 0, 14522).array());
154+
}
155+
148156
@Test
149157
public void fromLong() throws Exception {
150158
long test = 172283719283L;
@@ -154,6 +162,14 @@ public void fromLong() throws Exception {
154162
assertEquals(test, Bytes.from(test).toLong());
155163
}
156164

165+
@Test
166+
public void fromLongArray() throws Exception {
167+
assertArrayEquals(new byte[]{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2}, Bytes.from(new long[]{1, 2}).array());
168+
assertArrayEquals(Bytes.from(Bytes.from(871193L), Bytes.from(6761L), Bytes.from(-917656L)).array(), Bytes.from(new long[]{871193, 6761, -917656}).array());
169+
assertArrayEquals(Bytes.from(Bytes.from(1678L), Bytes.from(-223L), Bytes.from(11114L)).array(), Bytes.from(1678L, -223L, 11114L).array());
170+
assertArrayEquals(Bytes.from(Bytes.from(1273612831678L), Bytes.from(-72639123786223L)).array(), Bytes.from(1273612831678L, -72639123786223L).array());
171+
}
172+
157173
@Test
158174
public void fromByteBuffer() throws Exception {
159175
checkByteBuffer(example_bytes_empty);
@@ -273,4 +289,11 @@ public void fromFile() throws Exception {
273289

274290
assertArrayEquals(randomBytes.array(), Bytes.from(tempFile).array());
275291
}
292+
293+
@Test
294+
public void fromObjectArray() throws Exception {
295+
Byte[] objectArray = new Byte[]{0x01, 0x02, 0x03, 0x04};
296+
Bytes b = Bytes.from(objectArray);
297+
assertArrayEquals(new byte[]{0x01, 0x02, 0x03, 0x04}, b.array());
298+
}
276299
}

0 commit comments

Comments
 (0)