4.54. kink/io/INPUT¶
Companion mod for input vals.
4.54.1. type input¶
An input is an input port for bytes and bins from an underlying source of bytes such as files.
An input provides sequential forward access to the underlying source of bytes. It does not provide random access operations such as seek.
Operations on an input may cause IO errors.
4.54.1.1. Input.read(Max_size ...[$config={}])¶
`read` reads bytes till the size reaches Max_size, or reaches the end of the stream.
Precondition:
• Max_size must be a non-negative int num.
• $config, if specified, must be a fun which takes a conf val.
The conf val provides the following methods:
• C.on_present($present_cont) : uses $present_cont as the present cont. If the method is not called, {(:Bin) [Bin] } is used as the default present cont.
• C.on_absent($absent_cont) : uses $absent_cont as the absent cont. If the method is not called, {() [] } is used as the default absent cont.
• C.on_error($error_cont) : uses $error_cont as the error cont. If the method is not called, the default error cont raises an exception when an IO error occurs.
Result:
• If `read` succeeds to read some bytes, it tail-calls the present cont with a bin of the bytes.
• If no bytes are available, `read` tail-calls the absent cont with no args.
• If an IO error occurs, `read` tail-calls the error cont with the error message.
If the present cont and/or the absent cont are not specified, `read` returns a maybe vec of a bin.
:BIN.require_from('kink/')
:BIN_INPUT.require_from('kink/io/')
:In <- BIN_INPUT.new(BIN.of(1 2 3))
:loop <- {(:Vec)
In.read(2).with_just_or(
{(:Bin) loop(Vec + [Bin]) }
{ Vec }
)
}
:Result <- loop([])
stdout.print_line(Result.repr) # => [BIN.of(0x01 0x02) BIN.of(0x03)]
The present cont and the absent cont can be specified by C.on_present and C.on_absent.
:BIN.require_from('kink/')
:BIN_INPUT.require_from('kink/io/')
:In <- BIN_INPUT.new(BIN.of(1 2 3))
:loop <- {(:Vec)
In.read(2){(:C)
C.on_present{(:Bin) loop(Vec + [Bin]) }
C.on_absent{ Vec }
}
}
:Result <- loop([])
stdout.print_line(Result.repr) # => [BIN.of(0x01 0x02) BIN.of(0x03)]
When an error occurs, `read` tail-calls $on_error with an error message, or raises an exception if $on_error is not given.
Example:
:FILE.require_from('kink/io/')
:CONTROL.require_from('kink/')
:In <- FILE.open_to_read('/etc/passwd')
In.close
In.read(10){(:C)
C.on_error{(:Msg)
stderr.print_line(Msg)
}
}
# => java.io.IOException: Stream Clsoed
CONTROL.try(
{ In.read(10) }
{(:R) raise('not here') }
{(:Exc)
stderr.print_line(Exc.message)
}
)
# => Stream_input.read: java.io.IOException: Stream Closed
4.54.1.2. Input.close(...[$config])¶
Input.close closes the underlying source of bytes.
Precondition:
• $config, if specified, must be a fun which takes a conf val.
The conf val provides the following methods.
• C.on_success($success_cont) : uses $success_cont as the success cont. If not called, {} is used as the default success cont.
• C.on_error($error_cont) : uses $error_cont as the error cont. If not called, the default error cont raises an exception when an IO error occurs.
Result:
• When Input.close succeeds to close the source of bytes, it tail-calls the success cont with no args.
• When an IO errro occurs, Input.close tail-calls the errro cont with the errror message.
4.54.2. INPUT.is?(Val)¶
INPUT.is? returns whether the Val is an input.
4.54.3. INPUT.read_all(Input ...[$config={}])¶
`read_all` reads all the remaining bytes from `Input`.
Precondition
• $config, if specified, must be a fun which takes a conf val.
Conf val
The conf val provides the following methods:
• C.on_success($success_cont) : uses $success_cont as the success cont. If the method is not called, uses VAL.identity as the default success cont.
• C.on_error($error_cont) : uses $error_cont as the error cont. If the method is not called, the default error cont raises an exception when an IO error occcurs.
Result
• If read_all succeeds to read some bytes, it tail-calls the success cont with a bin of the bytes.
• If there is no remaining bytes, read_all tail-calls the success cont with an empty bin.
• If an IO error occurs, read_all tail-calls the error cont with an error message.
Example 1
:BIN.require_from('kink/')
:BIN_INPUT.require_from('kink/io/')
:INPUT.require_from('kink/io/')
:In <- BIN_INPUT.new(BIN.of(1 2 3))
stdout.print_line(INPUT.read_all(In).repr) # => BIN.of(0x01 0x02 0x03)
stdout.print_line(INPUT.read_all(In).repr) # => BIN.of()
stdout.print_line(INPUT.read_all(In).repr) # => BIN.of()
Example 2
:FILE.require_from('kink/io/')
:INPUT.require_from('kink/io/')
:CONTROL.require_from('kink/')
:In <- FILE.open_to_read('/etc/passwd')
In.close
INPUT.read_all(In){(:C)
C.on_error{(:Msg) stderr.print_line(Msg) }
}
# => java.io.IOException: Stream Clsoed
CONTROL.try(
{ INPUT.read_all(In) }
{(:R) raise('not here') }
{(:Exc)
stderr.print_line(Exc.message)
}
)
# => Stream_input.read_all: java.io.IOException: Stream Closed