Skip to content

Commit

Permalink
Fix blocking initialization of readers
Browse files Browse the repository at this point in the history
  • Loading branch information
Sven Obser committed Dec 13, 2024
1 parent ea7f0c1 commit fb4152f
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,17 @@ import kotlinx.serialization.csv.config.CsvConfig
/**
* Reader that parses CSV input.
*/
internal class CsvReader(private val source: Source, private val config: CsvConfig) {
internal class CsvReader(source: Source, private val config: CsvConfig) {

private val source: Source by lazy {
source.also {
// Skip Microsoft Excel's byte order marker, should it appear.
// This has to happen lazily to avoid blocking read calls during the initialization of the CsvReader.
if (source.peek() == '\uFEFF') {
source.read()
}
}
}

val offset
get() = source.offset
Expand All @@ -21,11 +31,6 @@ internal class CsvReader(private val source: Source, private val config: CsvConf

private var marks = arrayListOf<Int>()

init {
// Skip Microsoft Excel's byte order marker, should it appear:
read("\uFEFF")
}

/**
* Read value in the next column.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package kotlinx.serialization.csv.decode

import java.io.EOFException
import java.io.Reader

internal class FetchSource(
Expand All @@ -20,18 +21,27 @@ internal class FetchSource(
override var offset: Int = 0
private set

private var next: Char? = getChar()
private var queue = ArrayList<Char>(2048)
private var marks = ArrayList<Int>(2048)
private var queueOffset = 0

private var next: Char? = null
get() {
if (field == null && nextPosition == 0) {
// Reading first char has to happen lazily to avoid blocking read calls
// during the initialization of the FetchSource.
field = getChar()
}
return field
}

private fun nextChar(): Char {
val n = next ?: throw IllegalStateException("Out of characters")
val nextChar = next ?: throw EOFException("No more characters to read.")
next = getChar()
nextPosition++
return n
return nextChar
}

private var queue = ArrayList<Char>(2048)
private var marks = ArrayList<Int>(2048)
private var queueOffset = 0

override fun canRead(): Boolean = offset <= nextPosition

override fun read(): Char? {
Expand Down

0 comments on commit fb4152f

Please sign in to comment.