Skip to content

Commit 02c27b5

Browse files
committed
Add toCharArray() method which decodes internal byte array to char[]
1 parent 639d91d commit 02c27b5

File tree

4 files changed

+85
-25
lines changed

4 files changed

+85
-25
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## v1.0.0
44

55
* add `append()` method supporting multiple byte arrays #26
6+
* add `toCharArray()` method which decodes internal byte array to char[] #27
67

78
## v0.8.0
89

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1889,6 +1889,27 @@ public double toDouble() {
18891889
return internalBuffer().getDouble();
18901890
}
18911891

1892+
/**
1893+
* Decodes the internal byte array to UTF-8 char array.
1894+
* This implementation will not internally create a {@link String}.
1895+
*
1896+
* @return char array
1897+
*/
1898+
public char[] toCharArray() {
1899+
return toCharArray(StandardCharsets.UTF_8);
1900+
}
1901+
1902+
/**
1903+
* Decodes the internal byte array with given charset to a char array.
1904+
* This implementation will not internally create a {@link String}.
1905+
*
1906+
* @param charset to use for decoding
1907+
* @return char array
1908+
*/
1909+
public char[] toCharArray(Charset charset) {
1910+
return Util.byteToCharArray(internalArray(), charset);
1911+
}
1912+
18921913
/**
18931914
* Compares this bytes instance to another.
18941915
* <p>

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

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,28 +21,14 @@
2121

2222
package at.favre.lib.bytes;
2323

24-
import java.io.ByteArrayOutputStream;
25-
import java.io.DataInput;
26-
import java.io.File;
27-
import java.io.IOException;
28-
import java.io.InputStream;
29-
import java.io.RandomAccessFile;
24+
import java.io.*;
3025
import java.nio.ByteBuffer;
3126
import java.nio.ByteOrder;
3227
import java.nio.CharBuffer;
28+
import java.nio.charset.CharacterCodingException;
3329
import java.nio.charset.Charset;
3430
import java.nio.file.Files;
35-
import java.util.ArrayList;
36-
import java.util.Arrays;
37-
import java.util.Collection;
38-
import java.util.HashMap;
39-
import java.util.Iterator;
40-
import java.util.List;
41-
import java.util.Map;
42-
import java.util.NoSuchElementException;
43-
import java.util.Objects;
44-
import java.util.Random;
45-
import java.util.UUID;
31+
import java.util.*;
4632

4733
/**
4834
* Common Util methods to convert or modify byte arrays
@@ -438,9 +424,36 @@ static byte[] charToByteArray(char[] charArray, Charset charset, int offset, int
438424
}
439425

440426
ByteBuffer bb = charset.encode(charBuffer);
441-
byte[] bytes = new byte[bb.remaining()];
442-
bb.get(bytes);
443-
return bytes;
427+
if (bb.capacity() != bb.limit()) {
428+
byte[] bytes = new byte[bb.remaining()];
429+
bb.get(bytes);
430+
return bytes;
431+
}
432+
return bb.array();
433+
}
434+
435+
/**
436+
* Convert given byte array in given encoding to char array
437+
*
438+
* @param bytes as data source
439+
* @param charset of the byte array
440+
* @return char array
441+
*/
442+
static char[] byteToCharArray(byte[] bytes, Charset charset) {
443+
Objects.requireNonNull(bytes, "bytes must not be null");
444+
Objects.requireNonNull(charset, "charset must not be null");
445+
446+
try {
447+
CharBuffer charBuffer = charset.newDecoder().decode(ByteBuffer.wrap(bytes));
448+
if (charBuffer.capacity() != charBuffer.limit()) {
449+
char[] compacted = new char[charBuffer.remaining()];
450+
charBuffer.get(compacted);
451+
return compacted;
452+
}
453+
return charBuffer.array();
454+
} catch (CharacterCodingException e) {
455+
throw new IllegalStateException(e);
456+
}
444457
}
445458

446459
/**

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

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,7 @@
2626
import org.junit.Test;
2727
import org.junit.rules.TemporaryFolder;
2828

29-
import java.io.ByteArrayInputStream;
30-
import java.io.DataInput;
31-
import java.io.DataInputStream;
32-
import java.io.File;
33-
import java.io.FileOutputStream;
29+
import java.io.*;
3430
import java.math.BigInteger;
3531
import java.nio.ByteBuffer;
3632
import java.nio.ByteOrder;
@@ -299,6 +295,35 @@ public void fromCharArray() {
299295
assertArrayEquals(Bytes.empty().array(), Bytes.from(CharBuffer.allocate(0)).array());
300296
}
301297

298+
@Test
299+
public void toCharArray() {
300+
String unicodeString = "|µ€@7é8ahslishalsdalöskdḼơᶉëᶆ ȋṕšᶙṁ ḍỡḽǭᵳ ʂǐť ӓṁệẗ, ĉṓɲṩḙċ";
301+
assertArrayEquals(Bytes.from(unicodeString.toCharArray()).array(), Bytes.from(Bytes.from(unicodeString).toCharArray()).array());
302+
303+
checkToCharArray(unicodeString, StandardCharsets.UTF_8);
304+
checkToCharArray(unicodeString, StandardCharsets.UTF_16);
305+
checkToCharArray(unicodeString, StandardCharsets.UTF_16BE);
306+
307+
String asciiString = "asciiASCIIString1234$%&";
308+
309+
checkToCharArray(asciiString, StandardCharsets.UTF_8);
310+
checkToCharArray(asciiString, StandardCharsets.UTF_16);
311+
checkToCharArray(asciiString, StandardCharsets.US_ASCII);
312+
checkToCharArray(asciiString, StandardCharsets.ISO_8859_1);
313+
}
314+
315+
private void checkToCharArray(String string, Charset charset) {
316+
byte[] b0 = String.valueOf(string.toCharArray()).getBytes(charset);
317+
char[] charArray = Bytes.from(b0).toCharArray(charset);
318+
assertEquals(string, new String(charArray));
319+
assertArrayEquals(string.toCharArray(), Bytes.from(string.toCharArray(), charset).toCharArray(charset));
320+
}
321+
322+
@Test(expected = NullPointerException.class)
323+
public void toCharArrayShouldThroughNullPointer() {
324+
Bytes.allocate(4).toCharArray(null);
325+
}
326+
302327
@Test
303328
public void fromMultipleBytes() {
304329
assertArrayEquals(new byte[]{0x01, 0x02, 0x03}, Bytes.from(Bytes.from((byte) 0x01), Bytes.from((byte) 0x02), Bytes.from((byte) 0x03)).array());

0 commit comments

Comments
 (0)