Bytesrw adapter for Eio
ocaml codec
1(*--------------------------------------------------------------------------- 2 Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 SPDX-License-Identifier: ISC 4 ---------------------------------------------------------------------------*) 5 6(** Bytesrw adapters for Eio 7 8 This module provides adapters to create {!Bytesrw.Bytes.Reader.t} and 9 {!Bytesrw.Bytes.Writer.t} from Eio flows, mirroring the API of 10 {!Bytesrw_unix} for Eio's effect-based I/O. *) 11 12open Bytesrw 13 14(** Create a [Bytes.Reader.t] from an Eio source flow. 15 16 Reads directly from the flow without intermediate buffering. 17 18 @param slice_length Maximum bytes per slice (default: 65536, which is {!Bytes.Slice.unix_io_buffer_size}) *) 19let bytes_reader_of_flow 20 ?(slice_length = Bytes.Slice.unix_io_buffer_size) 21 (flow : _ Eio.Flow.source) 22 : Bytes.Reader.t = 23 let buf_size = Bytes.Slice.check_length slice_length in 24 let read () = 25 let cstruct = Cstruct.create buf_size in 26 match Eio.Flow.single_read flow cstruct with 27 | 0 -> Bytes.Slice.eod 28 | count -> 29 let data_cs = Cstruct.sub cstruct 0 count in 30 let buf = Cstruct.to_bytes data_cs in 31 Bytes.Slice.make buf ~first:0 ~length:count 32 | exception End_of_file -> Bytes.Slice.eod 33 in 34 Bytes.Reader.make ~slice_length read 35 36(** Create a [Bytes.Writer.t] from an Eio sink flow. 37 38 Writes directly to the flow without intermediate buffering. 39 40 @param slice_length Suggested slice length for upstream (default: 65536, which is {!Bytes.Slice.unix_io_buffer_size}) *) 41let bytes_writer_of_flow 42 ?(slice_length = Bytes.Slice.unix_io_buffer_size) 43 (flow : _ Eio.Flow.sink) 44 : Bytes.Writer.t = 45 let rec write slice = 46 if Bytes.Slice.is_eod slice then () 47 else begin 48 let bytes = Bytes.Slice.bytes slice in 49 let first = Bytes.Slice.first slice in 50 let length = Bytes.Slice.length slice in 51 let cstruct = Cstruct.of_bytes ~off:first ~len:length bytes in 52 match Eio.Flow.single_write flow [cstruct] with 53 | count when count = length -> () 54 | count -> write (Option.get (Bytes.Slice.drop count slice)) 55 end 56 in 57 Bytes.Writer.make ~slice_length write