Skip to content

Instantly share code, notes, and snippets.

@InsulaVentus
Last active March 12, 2020 12:31
Show Gist options
  • Save InsulaVentus/a446628bed8b1110a102783b52b99caa to your computer and use it in GitHub Desktop.
Save InsulaVentus/a446628bed8b1110a102783b52b99caa to your computer and use it in GitHub Desktop.
package com.github.insulaventus.bytes;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
public class Bytes {
public static List<byte[]> split(byte[] input, byte[] delimiter) {
List<byte[]> byteArrays = new LinkedList<>();
if (delimiter.length == 0) {
byteArrays.add(input);
return byteArrays;
}
int startOfSplit = 0;
int index = 0;
boolean lookForNextSplit = true;
while (index <= input.length) {
if (lookForNextSplit) {
if (isStartOfDelimiter(index, input, delimiter)) {
index = index + delimiter.length;
} else { //Found next split
startOfSplit = index;
lookForNextSplit = false;
index++;
}
} else { //Look for end of split
if (isStartOfDelimiter(index, input, delimiter) || index == input.length) { //Found end of split
byteArrays.add(Arrays.copyOfRange(input, startOfSplit, index));
lookForNextSplit = true;
index = index + delimiter.length;
} else {
index++;
}
}
}
return byteArrays;
}
private static boolean isStartOfDelimiter(int pos, byte[] input, byte[] delimiter) {
if (delimiter.length > input.length - pos) { //Delimiter is longer than the remaining bytes
return false;
}
for (int i = 0; i < delimiter.length; i++) {
if (input[pos + i] != delimiter[i]) {
return false;
}
}
return true;
}
}
package com.github.insulaventus.bytes;
import org.junit.jupiter.api.Test;
import java.nio.ByteBuffer;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
class BytesTest {
@Test
void thatSplitWorksWhenInputStartsWithDelimiter() {
byte[] delimiter = {(byte) 0x1A, (byte) 0x00, (byte) 0x00, (byte) 0x00};
byte[] split = {(byte) 0x30, (byte) 0x31};
byte[] input = new byte[0];
input = append(input, delimiter);
input = append(input, split);
input = append(input, delimiter);
input = append(input, split);
input = append(input, delimiter);
List<byte[]> bytes = Bytes.split(input, delimiter);
assertThat(bytes).containsExactly(split, split);
}
@Test
void thatSplitWorksWhenInputStartsWithSplit() {
byte[] delimiter = {(byte) 0x1A, (byte) 0x00, (byte) 0x00, (byte) 0x00};
byte[] split = {(byte) 0x30, (byte) 0x31};
byte[] input = new byte[0];
input = append(input, split);
input = append(input, delimiter);
input = append(input, split);
input = append(input, delimiter);
List<byte[]> bytes = Bytes.split(input, delimiter);
assertThat(bytes).containsExactly(split, split);
}
@Test
void thatSplitWorksWhenInputEndsWithSplit() {
byte[] delimiter = {(byte) 0x1A, (byte) 0x00, (byte) 0x00, (byte) 0x00};
byte[] split = {(byte) 0x30, (byte) 0x31};
byte[] input = new byte[0];
input = append(input, delimiter);
input = append(input, split);
input = append(input, delimiter);
input = append(input, split);
List<byte[]> bytes = Bytes.split(input, delimiter);
assertThat(bytes).containsExactly(split, split);
}
@Test
void thatSplitWorksWhenInputEndsWithDelimiter() {
byte[] delimiter = {(byte) 0x1A, (byte) 0x00, (byte) 0x00, (byte) 0x00};
byte[] split = {(byte) 0x30, (byte) 0x31};
byte[] input = new byte[0];
input = append(input, delimiter);
input = append(input, split);
input = append(input, delimiter);
List<byte[]> bytes = Bytes.split(input, delimiter);
assertThat(bytes).containsExactly(split);
}
@Test
void thatSplitWorksWhenInputHasSeveralConsecutiveDelimiters() {
byte[] delimiter = {(byte) 0x1A, (byte) 0x00, (byte) 0x00, (byte) 0x00};
byte[] split = {(byte) 0x30, (byte) 0x31};
byte[] input = new byte[0];
input = append(input, delimiter);
input = append(input, delimiter);
input = append(input, split);
input = append(input, delimiter);
input = append(input, delimiter);
input = append(input, split);
List<byte[]> bytes = Bytes.split(input, delimiter);
assertThat(bytes).containsExactly(split, split);
}
@Test
void thatSplitWorksWhenSplitAndDelimiterHaveLengthOne() {
byte[] delimiter = {(byte) 0x1A};
byte[] split = {(byte) 0x30};
byte[] input = new byte[0];
input = append(input, delimiter);
input = append(input, split);
input = append(input, delimiter);
List<byte[]> bytes = Bytes.split(input, delimiter);
assertThat(bytes).containsExactly(split);
}
@Test
void thatSplitWorksWhenInputContainsOneOfEach() {
byte[] delimiter = {(byte) 0x1A};
byte[] split = {(byte) 0x30, (byte) 0x31};
byte[] input = new byte[0];
input = append(input, split);
input = append(input, delimiter);
List<byte[]> bytes = Bytes.split(input, delimiter);
assertThat(bytes).containsExactly(split);
}
@Test
void thatSplitWorksWhenDelimiterIsEmpty() {
byte[] input = {(byte) 0x30, (byte) 0x31};
List<byte[]> bytes = Bytes.split(input, new byte[0]);
assertThat(bytes).containsExactly(input);
}
@Test
void thatSplitWorksWhenInputIsEmpty() {
byte[] delimiter = {(byte) 0x1A};
List<byte[]> bytes = Bytes.split(new byte[0], delimiter);
assertThat(bytes).hasSize(0);
}
@Test
void thatSplitWorksWhenBothInputAndDelimiterAreEmpty() {
List<byte[]> bytes = Bytes.split(new byte[0], new byte[0]);
assertThat(bytes).containsExactly(new byte[0]);
}
private static byte[] append(byte[] a, byte[] values) {
return ByteBuffer.allocate(a.length + values.length).put(a).put(values).array();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment