Add DataBufferUtils.matcher and split

Added two methods to DataBufferUtils:

* matcher(byte[]), which returns a Matcher object that can be used to
  find a delimiter in a data buffer.
* split(Publisher<DataBuffer>, byte[] delimiter), which splits a given
  stream of data buffers around a given delimiter.
This commit is contained in:
Arjen Poutsma
2019-05-06 16:32:47 +02:00
parent b74c09d12e
commit f747ba282a
2 changed files with 324 additions and 3 deletions

View File

@@ -49,9 +49,7 @@ import org.springframework.core.io.Resource;
import org.springframework.core.io.buffer.support.DataBufferTestUtils;
import static org.junit.Assert.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.anyLong;
import static org.mockito.Mockito.isA;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
/**
@@ -750,6 +748,142 @@ public class DataBufferUtilsTests extends AbstractDataBufferAllocatingTestCase {
.verify();
}
@Test
public void matcher() {
DataBuffer foo = stringBuffer("foo");
DataBuffer bar = stringBuffer("bar");
byte[] delims = "ooba".getBytes(StandardCharsets.UTF_8);
DataBufferUtils.Matcher matcher = DataBufferUtils.matcher(delims);
int result = matcher.match(foo);
assertEquals(-1, result);
result = matcher.match(bar);
assertEquals(1, result);
release(foo, bar);
}
@Test
public void matcher2() {
DataBuffer foo = stringBuffer("fooobar");
byte[] delims = "oo".getBytes(StandardCharsets.UTF_8);
DataBufferUtils.Matcher matcher = DataBufferUtils.matcher(delims);
int result = matcher.match(foo);
assertEquals(2, result);
foo.readPosition(2);
result = matcher.match(foo);
assertEquals(3, result);
foo.readPosition(3);
result = matcher.match(foo);
assertEquals(-1, result);
release(foo);
}
@Test
public void split() {
Mono<DataBuffer> source =
deferStringBuffer("--foo--bar--baz--");
byte[] delimiter = "--".getBytes(StandardCharsets.UTF_8);
Flux<DataBuffer> result = DataBufferUtils.split(source, delimiter);
StepVerifier.create(result)
.consumeNextWith(stringConsumer(""))
.consumeNextWith(stringConsumer("foo"))
.consumeNextWith(stringConsumer("bar"))
.consumeNextWith(stringConsumer("baz"))
.verifyComplete();
}
@Test
public void splitIncludeDelimiter() {
Mono<DataBuffer> source =
deferStringBuffer("--foo--bar--baz--");
byte[] delimiter = "--".getBytes(StandardCharsets.UTF_8);
Flux<DataBuffer> result = DataBufferUtils.split(source, delimiter, false);
StepVerifier.create(result)
.consumeNextWith(stringConsumer("--"))
.consumeNextWith(stringConsumer("foo--"))
.consumeNextWith(stringConsumer("bar--"))
.consumeNextWith(stringConsumer("baz--"))
.verifyComplete();
}
@Test
public void splitErrors() {
Flux<DataBuffer> source = Flux.concat(
deferStringBuffer("foo--"),
deferStringBuffer("bar--"),
Mono.error(new RuntimeException())
);
byte[] delimiter = "--".getBytes(StandardCharsets.UTF_8);
Flux<DataBuffer> result = DataBufferUtils.split(source, delimiter);
StepVerifier.create(result)
.consumeNextWith(stringConsumer("foo"))
.consumeNextWith(stringConsumer("bar"))
.expectError(RuntimeException.class)
.verify();
}
@Test
public void splitCanceled() {
Flux<DataBuffer> source = Flux.concat(
deferStringBuffer("foo--"),
deferStringBuffer("bar--"),
deferStringBuffer("baz")
);
byte[] delimiter = "--".getBytes(StandardCharsets.UTF_8);
Flux<DataBuffer> result = DataBufferUtils.split(source, delimiter);
StepVerifier.create(result)
.thenCancel()
.verify();
}
@Test
public void splitWithoutDemand() {
Flux<DataBuffer> source = Flux.concat(
deferStringBuffer("foo--"),
deferStringBuffer("bar--")
);
byte[] delimiter = "--".getBytes(StandardCharsets.UTF_8);
Flux<DataBuffer> result = DataBufferUtils.split(source, delimiter);
BaseSubscriber<DataBuffer> subscriber = new ZeroDemandSubscriber();
result.subscribe(subscriber);
subscriber.cancel();
}
@Test
public void splitAcrossBuffer() {
Flux<DataBuffer> source = Flux.concat(
deferStringBuffer("foo-"),
deferStringBuffer("-bar-"),
deferStringBuffer("-baz"));
byte[] delimiter = "--".getBytes(StandardCharsets.UTF_8);
Flux<DataBuffer> result = DataBufferUtils.split(source, delimiter);
StepVerifier.create(result)
.consumeNextWith(stringConsumer("foo"))
.consumeNextWith(stringConsumer("bar"))
.consumeNextWith(stringConsumer("baz"))
.verifyComplete();
}
private static class ZeroDemandSubscriber extends BaseSubscriber<DataBuffer> {