package org.openrs2.buffer import io.netty.buffer.ByteBuf import io.netty.buffer.ByteBufAllocator import io.netty.buffer.Unpooled import java.net.http.HttpResponse import java.nio.ByteBuffer import java.util.concurrent.CompletableFuture import java.util.concurrent.CompletionStage import java.util.concurrent.Flow import javax.inject.Inject import javax.inject.Singleton @Singleton public class ByteBufBodyHandler @Inject constructor( private val alloc: ByteBufAllocator ) : HttpResponse.BodyHandler { override fun apply(responseInfo: HttpResponse.ResponseInfo): HttpResponse.BodySubscriber { return object : HttpResponse.BodySubscriber { private val buf = alloc.compositeBuffer() private val future = CompletableFuture() private var len = 0 override fun onSubscribe(subscription: Flow.Subscription) { subscription.request(Long.MAX_VALUE) } override fun onNext(item: List) { for (b in item) { val component = Unpooled.wrappedBuffer(b) buf.addComponent(component) len += component.readableBytes() check(len >= 0) } } override fun onError(throwable: Throwable) { future.completeExceptionally(throwable) buf.release() } override fun onComplete() { buf.writerIndex(len) future.complete(buf) } override fun getBody(): CompletionStage { return future } } } }