Any RxJava experts that can help me figure this one out?
I have a function that returns a Single<ByteArray>
based on some position
parameter.
Basically, I want to keep calling that function, until it returns an empty ByteArray
.
NOTE: The position parameter is supposed to indicate how many bytes where already read. E.g. first time it will be 0, next time it will be how many bytes where retrieved the first time, and so on.
This is what I have now:
fun readBytes(position: Int) : Single<ByteArray>{ ... }
fun readAllLogs() : Single<LogEntry> {
val oldPosition = AtomicInteger(0)
val position = AtomicInteger(0)
Observable.defer {
readBytes(position.get())
}.reduceWith({ LogEntry() }, { log, bytes ->
position.addAndGet(bytes.size)
log += bytes
log
}).repeatUntil {
val canWeStop = position.get() == oldPosition.get()
oldPosition.set(position.get())
canWeStop
}.toObservable()
}
For completeness, here's my LogEntry accumulator
data class LogEntry {
var data: ByteArray = byteArrayOf()
private set
operator fun plusAssign(bytes: ByteArray) {
data += bytes
}
}
Question 1: How can I exit this stream elegantly? E.g. not keeping track of separate variables outside the stream?
Question 2: Any optimizations I can make? I'm going from Single to Observable twice to be able to chain these operators. I'm sure that can be more efficient