-
Notifications
You must be signed in to change notification settings - Fork 4
Closed
Description
Hi, I currently use this library in my RSS reader app called Twine. One of the missing things was the ability to stream data to the parser or parse data in chunks rather than loading the entire string into memory. This was causing OOM crashes when there are large strings
Since I receive response as a ByteReadChannel from the Ktor client, I converted it into CharIterator and parsed data in chunks. So far it works well for me in my testing.
I wanted to share my approach, get your thoughts on it, and leave it to anyone looking to do this.
private fun ByteReadChannel.toCharIterator(
context: CoroutineContext = EmptyCoroutineContext
): CharIterator {
return object : CharIterator() {
private val DEFAULT_BUFFER_SIZE = 1024L
private var currentIndex = 0
private var currentBuffer = CharArray(0)
override fun hasNext(): Boolean {
if (currentIndex < currentBuffer.size) return true
if (this@toCharIterator.isClosedForRead) return false
val packet = runBlocking(context) {
this@toCharIterator.readRemaining(DEFAULT_BUFFER_SIZE)
}
currentBuffer = packet.readText().toCharArray()
packet.release()
currentIndex = 0
return currentBuffer.isNotEmpty()
}
override fun nextChar(): Char {
if (!hasNext()) throw NoSuchElementException()
return currentBuffer[currentIndex++]
}
}
}Metadata
Metadata
Assignees
Labels
No labels