null
on EOF or timeoutReturns unicode replacement character '�' if an invalid byte sequence is read.
read_char
may block if:
# Reads a character. Returns `null` on EOF or timeout
#
# Returns unicode replacement character '�' if an
# invalid byte sequence is read.
#
# `read_char` may block if:
#
# * No byte could be read from the current buffer
# * An incomplete char is partially read, and more bytes are
# required for full decoding.
fun read_char: nullable Char do
if eof then return null
var cod = codec
var codet_sz = cod.codet_size
var lk = lookahead
var llen = lookahead_length
if llen < codet_sz then
llen += raw_read_bytes(lk.fast_cstring(llen), codet_sz - llen)
end
if llen < codet_sz then
lookahead_length = 0
return 0xFFFD.code_point
end
var ret = cod.is_valid_char(lk, codet_sz)
var max_llen = cod.max_lookahead
while ret == 1 and llen < max_llen do
var rd = raw_read_bytes(lk.fast_cstring(llen), codet_sz)
if rd < codet_sz then
llen -= codet_sz
if llen > 0 then
lookahead.lshift(codet_sz, llen, codet_sz)
end
lookahead_length = llen.max(0)
return 0xFFFD.code_point
end
llen += codet_sz
ret = cod.is_valid_char(lk, llen)
end
if ret == 0 then
var c = cod.decode_char(lk)
var clen = c.u8char_len
llen -= clen
if llen > 0 then
lookahead.lshift(clen, llen, clen)
end
lookahead_length = llen
return c
end
if ret == 2 or ret == 1 then
llen -= codet_sz
if llen > 0 then
lookahead.lshift(codet_sz, llen, codet_sz)
end
lookahead_length = llen
return 0xFFFD.code_point
end
# Should not happen if the decoder works properly
var arr = new Array[Object]
arr.push "Decoder error: could not decode nor recover from byte sequence ["
for i in [0 .. llen[ do
arr.push lk[i]
arr.push ", "
end
arr.push "]"
var err = new IOError(arr.plain_to_s)
err.cause = last_error
last_error = err
return 0xFFFD.code_point
end
lib/core/stream.nit:131,2--199,4